flexi_form_field (v4.0.2)
A flexible and highly customizable Flutter form widget suite with built-in validation, rich styling options, and a consistent theming system. Drop-in replacements for common Flutter form UI with minimal boilerplate.
๐ผ Showcase
| Form Demo | Text Fields | Auto-Complete | Date Pickers | Components |
|---|---|---|---|---|
![]() |
![]() |
![]() |
![]() |
![]() |
Widgets
| Widget | Category | Description |
|---|---|---|
FlexiFormField |
Input | Customizable text input with built-in validators and formatters |
FlexiMultiSelectDropdown |
Selection | (New) Tag-based multi-select with search and animations |
FlexiImageSlider |
Media | (New) Full-screen premium carousel for remote/local images |
FlexiText |
Utility | (New) Intelligent text with automatic marquee/scrolling |
FlexiFilePicker |
Media | (New) Standardized file selection with Android 13+ support |
FlexiImagePicker |
Media | (New) Camera/Gallery selection dialog with premium styling |
FlexiSwitch |
Toggle | (New) Animated toggle switch with integrated On/Off labels |
FlexiTabBar & FlexiTabView |
Navigation | (New) Integrated tabs system with "Swipe to Change" support |
FlexiRadioButton |
Selection | (New) Accessible and stylish radio buttons |
FlexiCheckBox |
Selection | (New) Premium high-contrast checkboxes |
FlexiScreenLoader |
Utility | (New) Platform-aware loaders (Cupertino/Material) |
FlexiDeleteDialog |
Dialog | (New) Stylized confirmation dialog for deletions |
FlexiLogoutDialog |
Dialog | (New) Branded logout confirmation dialog |
FlexiDropDown<T> |
Selection | Generic type-safe dropdown selector |
FlexiDatePicker |
Pickers | Date picker with formatted output |
FlexiTimePicker |
Pickers | Material time picker |
FlexiDateTimePicker |
Pickers | Combined date + time selection |
FlexiAutoComplete<T> |
Selection | Generic searchable autocomplete field |
FlexiButton |
Action | Customizable button with gradient and shadows |
FlexiStepper |
Navigation | Horizontal animated stepper with auto-scroll |
FlexiTimer |
Utility | Functional timer with playback controls |
Installation
Add to your pubspec.yaml:
dependencies:
flexi_form_field: ^4.0.2
Important
Minimum SDK Requirements:
This package requires Dart SDK ^3.10.0 to support the latest dependency versions (including device_info_plus v13). Ensure your Flutter environment is up-to-date.
Then run:
flutter pub get
Import in your Dart file:
import 'package:flexi_form_field/flexi_form_field.dart';
Theming
All widgets accept an optional FlexiFormTheme to maintain a consistent look across your form.
final myTheme = FlexiFormTheme(
primaryColor: Colors.indigo,
borderRadius: BorderRadius.all(Radius.circular(12)),
labelStyle: TextStyle(color: Colors.black87),
errorStyle: TextStyle(color: Colors.red),
fillColor: Colors.grey[100],
);
FlexiFormTheme Properties
| Property | Type | Default | Description |
|---|---|---|---|
primaryColor |
Color |
Colors.black |
Active border, cursor, and highlight color |
borderRadius |
BorderRadius |
10 radius |
Applied to borders and card wrappers |
labelStyle |
TextStyle |
Black87 | Style for labels and input text |
errorStyle |
TextStyle |
Red | Style for validation error messages |
fillColor |
Color? |
null |
Background fill color for input fields |
Enums
FlexiFieldStyle โ Border style
| Value | Description |
|---|---|
outline |
Standard outline border (default) |
filled |
Filled background, no border |
underline |
Underline only |
rounded |
Fully rounded border (radius 30) |
minimal |
No border |
FlexiFieldLayout โ Label position
| Value | Description |
|---|---|
floating |
Floating label inside border (Material default) |
labelAbove |
Label placed above the input |
labelInline |
Label inline with the field |
FlexiFieldWrapper โ Container style
| Value | Description |
|---|---|
none |
No wrapper (default) |
card |
Wrapped in a Material Card |
outlined |
Wrapped in an outlined Container |
FlexiFormField
A powerful text input widget with built-in validators and input formatters.
FlexiFormField(
label: "Email Address",
hint: "you@example.com",
prefixIcon: Icon(Icons.alternate_email_rounded, size: 20),
isEmail: true,
isMandatory: true,
theme: myTheme,
)
Properties
| Property | Type | Default | Description |
|---|---|---|---|
label |
String? |
โ | Floating / inline label |
externalLabel |
String? |
โ | Label displayed above the field |
hint |
String? |
โ | Hint/placeholder text |
controller |
TextEditingController? |
โ | Controller for reading/setting value |
fieldStyle |
FlexiFieldStyle |
outline |
Border style |
fieldLayout |
FlexiFieldLayout |
floating |
Label layout |
wrapper |
FlexiFieldWrapper |
none |
Container wrapper |
theme |
FlexiFormTheme? |
โ | Custom theme override |
isMandatory |
bool |
false |
Marks field required, shows * |
isEmail |
bool |
false |
Validates email format |
isMobile |
bool |
false |
Validates 10-digit mobile number |
isPinCode |
bool |
false |
Validates 6-digit pin code |
isGST |
bool |
false |
Validates GST number format |
isNumber |
bool |
false |
Restricts input to integers |
isDouble |
bool |
false |
Restricts input to decimal numbers |
isPercentage |
bool |
false |
Restricts input to percentage values |
uppercaseOnly |
bool |
false |
Forces uppercase input |
lowercaseOnly |
bool |
false |
Forces lowercase input |
denySpace |
bool |
false |
Prevents whitespace characters |
autoValidate |
bool |
false |
Validates on every change |
obscureText |
bool |
false |
Hides text (passwords) |
enabled |
bool |
true |
Enables or disables the field |
readOnly |
bool |
false |
Makes the field read-only |
maxLines |
int |
1 |
Maximum number of lines |
maxLength |
int? |
โ | Maximum character count |
keyboardType |
TextInputType? |
โ | Keyboard type |
inputFormatters |
List<TextInputFormatter>? |
โ | Custom input formatters |
prefixIcon |
Widget? |
โ | Widget shown at the start |
suffixIcon |
Widget? |
โ | Widget shown at the end |
validator |
String? Function(String?)? |
โ | Custom validation function |
onChanged |
ValueChanged<String>? |
โ | Called on text change |
onTap |
VoidCallback? |
โ | Called on field tap |
fillColor |
Color? |
โ | Background fill color override |
borderRadius |
double? |
โ | Border radius override |
cursorColor |
Color? |
โ | Cursor color override |
cursorHeight |
double? |
โ | Cursor height override |
fontSize |
double? |
โ | Text font size override |
style |
TextStyle? |
โ | Full input text style override |
labelStyle |
TextStyle? |
โ | Label text style override |
hintStyle |
TextStyle? |
โ | Hint text style override |
contentPadding |
EdgeInsetsGeometry? |
โ | Internal padding |
margin |
EdgeInsetsGeometry? |
โ | Outer margin |
Examples
Email field with mandatory validation:
FlexiFormField(
label: "Email",
isEmail: true,
isMandatory: true,
prefixIcon: Icon(Icons.email_outlined, size: 20),
theme: myTheme,
)
Filled-style password field:
FlexiFormField(
label: "Password",
fieldStyle: FlexiFieldStyle.filled,
obscureText: true,
isMandatory: true,
fillColor: Colors.grey[100],
)
Numbers-only field with external label:
FlexiFormField(
externalLabel: "Phone Number",
hint: "Enter 10-digit number",
isMobile: true,
isMandatory: true,
keyboardType: TextInputType.phone,
)
Multiline text area:
FlexiFormField(
label: "Notes",
maxLines: 5,
fieldStyle: FlexiFieldStyle.outline,
)
FlexiDropDown<T>
A generic type-safe dropdown built on the same styling system.
FlexiDropDown<String>(
label: "Gender",
hint: "Choose...",
isMandatory: true,
items: const [
DropdownMenuItem(value: "M", child: Text("Male")),
DropdownMenuItem(value: "F", child: Text("Female")),
DropdownMenuItem(value: "O", child: Text("Other")),
],
onChanged: (value) => print(value),
theme: myTheme,
)
Shares the same fieldStyle, fieldLayout, wrapper, theme, isMandatory, prefixIcon, suffixIcon, label, externalLabel, hint, fillColor, borderRadius, fontSize, and style override properties as FlexiFormField.
FlexiMultiSelectDropdown
A highly customizable multi-select dropdown with animated tag-based selection.
List<String> _selectedItems = [];
FlexiMultiSelectDropdown(
label: "Interests",
hint: "Select your hobbies",
items: const ["Coding", "Reading", "Hiking", "Gaming", "Cooking"],
selectedItems: _selectedItems,
onChanged: (values) {
setState(() => _selectedItems = values);
},
theme: myTheme,
isMandatory: true,
)
FlexiRadioButton<T>
Stylish and accessible radio buttons with interactive labels.
String _gender = "Male";
Row(
children: [
FlexiRadioButton<String>(
label: "Male",
value: "Male",
groupValue: _gender,
onChanged: (v) => setState(() => _gender = v!),
theme: myTheme,
),
FlexiRadioButton<String>(
label: "Female",
value: "Female",
groupValue: _gender,
onChanged: (v) => setState(() => _gender = v!),
theme: myTheme,
),
],
)
FlexiDatePicker
Opens the Material date dialog on tap and writes the formatted date to the controller.
final dateController = TextEditingController();
FlexiDatePicker(
controller: dateController,
label: "Date of Birth",
hint: "Select a date",
dateFormat: 'dd-MM-yyyy', // Default
isMandatory: true,
showClearButton: true,
firstDate: DateTime(1900),
lastDate: DateTime.now(),
prefixIcon: Icon(Icons.calendar_today_rounded, size: 20),
onSelect: (DateTime? date, String formatted) {
print('Selected: $formatted');
},
theme: myTheme,
)
Key Properties
| Property | Type | Default | Description |
|---|---|---|---|
controller |
TextEditingController |
required | Receives the formatted date string |
dateFormat |
String |
'dd-MM-yyyy' |
Any intl date format pattern |
firstDate |
DateTime? |
DateTime(1900) |
Earliest selectable date |
lastDate |
DateTime? |
DateTime(2100) |
Latest selectable date |
initialDate |
DateTime? |
DateTime.now() |
Initially highlighted date |
showClearButton |
bool |
true |
Shows ร button when value is set |
onSelect |
Function(DateTime?, String)? |
โ | Callback with both the parsed and formatted values |
focusNode / nextFocusNode |
FocusNode? |
โ | Focus navigation support |
FlexiTimePicker
Opens the Material time dialog on tap.
final timeController = TextEditingController();
FlexiTimePicker(
controller: timeController,
label: "Meeting Time",
hint: "Select a time",
isMandatory: true,
showClearButton: true,
initialTime: TimeOfDay(hour: 9, minute: 0),
prefixIcon: Icon(Icons.access_time_rounded, size: 20),
onSelect: (TimeOfDay? time, String? formatted) {
print('Selected: $formatted');
},
theme: myTheme,
)
FlexiDateTimePicker
Chains a date picker immediately followed by a time picker in a single tap.
final dtController = TextEditingController();
FlexiDateTimePicker(
controller: dtController,
label: "Appointment",
hint: "Select date & time",
dateFormat: 'dd-MM-yyyy HH:mm', // Default
isMandatory: true,
prefixIcon: Icon(Icons.calendar_month_rounded, size: 20),
onSelect: (DateTime? dt, String formatted) {
print('Appointment: $formatted');
},
theme: myTheme,
)
FlexiAutoComplete<T>
A generic searchable autocomplete backed by flutter_typeahead.
final searchController = TextEditingController();
final List<String> countries = ["India", "USA", "Germany", "Japan"];
FlexiAutoComplete<String>(
controller: searchController,
label: "Country",
hint: "Start typing...",
options: countries,
itemLabelBuilder: (country) => country,
isMandatory: true,
prefixIcon: Icon(Icons.public_rounded, size: 20),
onSelected: (String? selected) {
print('Selected: $selected');
},
onChanged: (String? value, String text) {},
theme: myTheme,
)
Key Properties
| Property | Type | Description |
|---|---|---|
options |
List<T> |
Full list of suggestions |
itemLabelBuilder |
String Function(T) |
Converts item to display string |
onSelected |
Function(T?)? |
Called when a suggestion is tapped |
onChanged |
Function(T?, String)? |
Called on every text change |
showClearButton |
bool? |
Show clear icon when text is present |
hideEmptyListBanner |
bool? |
Hides the "no results" banner |
numberOnly |
bool? |
Restricts input to numeric characters |
isDouble |
bool? |
Restricts input to decimal numbers |
isMobileNumber |
bool? |
Restricts to mobile-style numeric input |
FlexiButton
A highly customizable button with gradient, shadow, animation, and shape support.
FlexiButton(
width: double.infinity,
height: 52,
onTap: () => submitForm(),
child: Text("SUBMIT"),
)
Gradient button:
FlexiButton(
width: double.infinity,
gradient: LinearGradient(
colors: [Colors.purple, Colors.deepPurple],
),
borderRadius: 16,
onTap: () {},
child: Text("GET STARTED"),
)
Outlined button:
FlexiButton(
color: Colors.transparent,
border: Border.all(color: Colors.black, width: 1.5),
textColor: Colors.black,
onTap: () {},
child: Text("SECONDARY"),
)
Properties
| Property | Type | Default | Description |
|---|---|---|---|
onTap |
VoidCallback |
required | Tap handler |
child |
Widget |
required | Button content (typically Text) |
width |
double? |
โ | Button width (double.infinity for full width) |
height |
double? |
48 |
Button height |
color |
Color? |
Theme-aware | Background color |
gradient |
Gradient? |
โ | Gradient background (overrides color) |
border |
Border? |
โ | Custom border |
boxShadow |
List<BoxShadow>? |
โ | Shadow list |
borderRadius |
double? |
12 |
Corner radius |
shape |
BoxShape |
rectangle |
rectangle or circle |
elevation |
double |
0 |
Material elevation |
textColor |
Color? |
Theme-aware | Default text color for child |
fontSize |
double? |
16 |
Default font size for child |
animate |
bool |
true |
Enables 200ms press animation |
padding |
EdgeInsetsGeometry? |
โ | Internal padding |
margin |
EdgeInsetsGeometry? |
โ | Outer margin |
alignment |
AlignmentGeometry? |
center |
Content alignment |
FlexiStepper
A horizontal scrollable stepper that auto-scrolls to the active step.
int _currentStep = 0;
FlexiStepper(
currentStep: _currentStep,
stepTitles: ["Basic Info", "Contact", "Address", "Review"],
onStepChange: (index) => setState(() => _currentStep = index),
borderRadius: 12,
margin: EdgeInsets.symmetric(horizontal: 16, vertical: 8),
)
Properties
| Property | Type | Default | Description |
|---|---|---|---|
currentStep |
int |
required | Index of the active step |
stepTitles |
List<String> |
required | Labels for each step |
onStepChange |
Function(int)? |
โ | Called when a step chip is tapped |
activeColor |
Color? |
Theme-aware | Background of active step chip |
inactiveColor |
Color? |
Theme-aware | Border color of inactive chips |
activeTextColor |
Color? |
Theme-aware | Text color of active chip |
inactiveTextColor |
Color? |
Theme-aware | Text color of inactive chips |
height |
double |
36 |
Height of the stepper row |
borderRadius |
double? |
12 |
Chip corner radius |
scrollDuration |
Duration |
500ms |
Auto-scroll animation duration |
scrollCurve |
Curve |
easeInOut |
Auto-scroll animation curve |
textStyle |
TextStyle? |
โ | Text style for step labels |
padding / margin |
EdgeInsetsGeometry? |
โ | Spacing |
FlexiTabBar
An animated segmented control for switching between views.
int _tab = 0;
FlexiTabBar(
tabs: ["Active", "Completed", "Archived"],
currentIndex: _tab,
onChanged: (index) => setState(() => _tab = index),
borderRadius: 12,
)
With gradient active indicator:
FlexiTabBar(
tabs: ["Day", "Week", "Month"],
currentIndex: _tab,
onChanged: (i) => setState(() => _tab = i),
activeGradient: LinearGradient(
colors: [Colors.purple, Colors.deepPurple],
),
)
Properties
| Property | Type | Default | Description |
|---|---|---|---|
tabs |
List<String> |
required | Tab labels |
currentIndex |
int |
required | Active tab index |
onChanged |
Function(int) |
required | Called when a tab is tapped |
activeColor |
Color? |
Theme-aware | Active tab background color |
backgroundColor |
Color? |
Theme-aware | Container background color |
activeTextColor |
Color? |
Theme-aware | Active tab text color |
inactiveTextColor |
Color? |
Theme-aware | Inactive tab text color |
activeGradient |
Gradient? |
โ | Gradient for active indicator (overrides activeColor) |
borderRadius |
double? |
12 |
Corner radius |
height |
double? |
โ | Fixed height |
fontSize |
double? |
14 |
Tab label font size |
padding / margin |
EdgeInsetsGeometry? |
โ | Spacing |
FlexiTimer
A self-contained countdown-style timer with start, pause, resume, and stop controls.
FlexiTimer(
borderRadius: 16,
startLabel: "Start",
pauseLabel: "Pause",
resumeLabel: "Resume",
stopLabel: "Stop",
)
Properties
| Property | Type | Default | Description |
|---|---|---|---|
buttonColor |
Color? |
โ | Override for all button colors |
buttonTextColor |
Color? |
โ | Override for all button text colors |
timerStyle |
TextStyle? |
54px thin | Style for the time display |
startLabel |
String |
"Start" |
Start button label |
pauseLabel |
String |
"Pause" |
Pause button label |
resumeLabel |
String |
"Resume" |
Resume button label |
stopLabel |
String |
"Stop" |
Stop button label |
borderRadius |
double? |
16 |
Container corner radius |
padding / margin |
EdgeInsetsGeometry? |
โ | Spacing |
Dependencies
| Package | Purpose |
|---|---|
intl: ^0.20.2 |
Date formatting |
flutter_typeahead: ^6.0.0 |
Autocomplete engine |
animated_custom_dropdown: ^3.1.1 |
Multi-select engine |
carousel_slider: ^5.1.2 |
Image carousel |
marquee: ^2.3.0 |
Text scrolling |
flutter_switch: ^0.3.2 |
Animated toggles |
image_picker: ^1.2.1 |
Camera/Gallery access |
file_picker: ^11.0.2 |
File system access |
permission_manager: ^2.0.9 |
Permission handling |
device_info_plus: ^13.1.0 |
Device information |
Platform Support
Android ยท iOS ยท macOS ยท Windows ยท Linux ยท Web
License
MIT License โ see LICENSE for details.
Changelog
See CHANGELOG.md for a full version history.
Repository
github.com/manojprajapati1999/flexi_form_field
๐จโ๐ป Author
Manoj Patadiya ๐ง Email: patadiyamanoj4@gmail.com
Libraries
- flexi_form_field
- Exports the primary form-field toolkit of the package, including all core widgets, validators, input formatters, and utilities.




