smart_multi_form_fields 1.1.0
smart_multi_form_fields: ^1.1.0 copied to clipboard
A single, production-grade Flutter form field widget rendering text, password, phone, OTP, date, dropdown, and file inputs via sealed configurations.
Smart Form Field (smart_multi_form_fields) #
A production-grade, type-safe Flutter form field package that provides a single public widget (SmartFormField) capable of rendering multiple input types through a sealed configuration hierarchy.
Implementation Status #
| Type | Config | Status |
|---|---|---|
| Text | SmartTextConfig |
✅ Complete |
| Password | SmartPasswordConfig |
✅ Complete |
| Phone | SmartPhoneConfig |
⏳ Stub |
| OTP | SmartOtpConfig |
⏳ Stub |
| Date | SmartDateConfig |
⏳ Stub |
| Dropdown | SmartDropdownConfig |
⏳ Stub |
| File | SmartFileConfig |
⏳ Stub |
Features #
- 📱 Supported Platforms: Tested and officially supported on Android & iOS.
- 🎯 Single Public Widget:
SmartFormField(config: ...)for every input type. - 🔒 Type-Safe Sealed Configs:
SmartFieldConfigis sealed — compile-time safety, zero dead properties. - 🛡️ Built-in Validation: Required check,
minLength,maxLength, custom validator chain (SmartValidators.email). - 🔑 Password Strength & Custom Scoring: Animated 4-segment strength meter, custom scoring algorithms, custom meter UI, obscuring character selection (
•,*), custom eye icons. - 🔄 Confirm Password Matching: Real-time exact string match validation via
confirmPasswordController. - ✍️ Formatting & Capitalization:
autoCapitalizeWords, custominputFormatters, auto-trimming. - 🔌 External Controller: Optional
controllerproperty — you own disposal if provided, package handles it if omitted. - 🎨 Automatic Theming: Seamlessly inherits app
InputDecorationThemeand light/darkColorScheme. - ⏱ Debounced & Async Search:
SmartTextConfig.search()with race-condition-safe async execution. - 🔑 Programmatic Control: Validate, reset, read values via
GlobalKey<SmartBaseShellState>.
Installation #
dependencies:
smart_multi_form_fields: ^1.1.0
Usage Examples #
import 'package:smart_multi_form_fields/smart_multi_form_fields.dart';
SmartTextFormField Preview #
Section 1: Text Input (SmartTextConfig) #
1. Basic Text Input & Validation
SmartFormField(
config: SmartTextConfig(
label: 'Full Name',
hint: 'John Doe',
isRequired: true,
autoCapitalizeWords: true,
prefixIcon: const Icon(Icons.person),
validators: [
(value) => value!.length < 3 ? 'Name must be at least 3 characters' : null,
],
),
)
2. Email Field with Built-in Validator
SmartFormField(
config: SmartTextConfig(
label: 'Email Address',
hint: 'user@example.com',
isRequired: true,
validators: [SmartValidators.email],
prefixIcon: const Icon(Icons.email),
),
)
3. Multiline & Character Counter (Bio / Notes)
SmartFormField(
config: SmartTextConfig(
label: 'Bio',
hint: 'Write a short bio...',
minLength: 10,
maxLength: 200,
maxLines: 4,
minLines: 2,
prefixIcon: const Icon(Icons.info),
),
)
4. Auto-Clear Button & Icons
SmartFormField(
config: SmartTextConfig(
label: 'Address',
hint: 'Enter your address',
showClearButton: true, // Auto-shows (×) clear icon when non-empty
prefixIcon: const Icon(Icons.location_on),
),
)
5. Async Search Field with Debounce
SmartFormField(
config: SmartTextConfig.search(
label: 'Search Products',
hint: 'Type product name...',
debounce: const Duration(milliseconds: 400),
onSearchAsync: (query, isCurrent) async {
final results = await myApi.searchProducts(query);
if (isCurrent()) { // Ensures older, slower API responses don't overwrite newer results
setState(() => _searchResults = results);
}
},
),
)
6. External Controller & Focus Traversal
final _nameController = TextEditingController();
final _nextFocus = FocusNode();
SmartFormField(
config: SmartTextConfig(
label: 'First Name',
controller: _nameController,
nextFocusNode: _nextFocus,
textInputAction: TextInputAction.next,
),
)
// Read or pre-fill value anytime:
_nameController.text = 'Pre-filled';
7. Programmatic Validation via GlobalKey
final _formKey = GlobalKey<SmartBaseShellState>();
SmartFormField(
key: _formKey,
config: SmartTextConfig(label: 'Username', isRequired: true),
)
// On submit button click:
void onSubmit() {
final error = _formKey.currentState?.validate();
if (error == null) {
final value = _formKey.currentState?.value;
print('Valid value: $value');
}
}
SmartTextFormField Preview #
Section 2: Password Input (SmartPasswordConfig) #
1. Password with Strength Meter
SmartFormField(
config: SmartPasswordConfig(
label: 'Password',
hint: 'Enter your password',
isRequired: true,
minPasswordLength: 8,
showStrengthMeter: true, // Animated 4-segment strength bar
),
)
2. Strict Password with Complexity Rules
SmartFormField(
config: SmartPasswordConfig(
label: 'Strong Password',
isRequired: true,
minPasswordLength: 8,
requireUppercase: true, // Must include A-Z
requireLowercase: true, // Must include a-z
requireDigit: true, // Must include 0-9
requireSpecialChar: true, // Must include !@#$%^&*
),
)
3. Confirm Password Match Validation
final _passwordController = TextEditingController();
// Original password field
SmartFormField(
config: SmartPasswordConfig(
label: 'Password',
controller: _passwordController,
isRequired: true,
),
)
// Confirm password field — compares value against original field
SmartFormField(
config: SmartPasswordConfig(
label: 'Confirm Password',
confirmPasswordController: _passwordController,
confirmMismatchMessage: 'Passwords do not match',
showStrengthMeter: false,
isRequired: true,
),
)
4. Custom Obscuring Character & Custom Toggle Icon
SmartFormField(
config: SmartPasswordConfig(
label: 'Custom Password',
obscuringCharacter: '*', // Mask symbol (* instead of default •)
toggleIconBuilder: (isObscured) => Icon(
isObscured ? Icons.lock_outline : Icons.lock_open_outlined,
color: Colors.blue,
size: 20,
),
),
)
5. Custom Strength Scorer & Custom Strength UI Builder
SmartFormField(
config: SmartPasswordConfig(
label: 'Custom Policy Password',
// Custom scoring algorithm
customStrengthScorer: (password, minLength) {
if (password.length < minLength) return PasswordStrength.weak;
if (password.contains('123456')) return PasswordStrength.weak;
return PasswordStrengthScorer.score(password, minLength: minLength);
},
// Custom strength meter UI replacement
strengthMeterBuilder: (context, strength) {
return Text('Strength: ${strength.label}', style: TextStyle(color: strength.color));
},
),
)
SmartTextConfig Property Reference #
| Property | Type | Description |
|---|---|---|
label |
String? |
Field label header shown above input |
hint |
String? |
Placeholder text inside input |
helperText |
String? |
Supporting text shown below field |
isRequired |
bool |
Adds * asterisk and runs empty validation |
validators |
List<SmartValidator> |
Custom validation functions chain |
minLength |
int? |
Minimum character length constraint |
maxLength |
int? |
Maximum character length constraint (renders counter) |
maxLines |
int? |
Maximum lines for multiline input |
minLines |
int? |
Minimum lines for multiline input |
autoCapitalizeWords |
bool |
Automatically capitalizes first letter of every word |
showClearButton |
bool |
Renders (×) clear button when text is non-empty |
prefixIcon |
Widget? |
Icon displayed at the start of input |
suffixIcon |
Widget? |
Icon displayed at the end of input |
onSuffixIconTap |
VoidCallback? |
Tap handler for suffixIcon |
readOnly |
bool |
Focusable and selectable but prevents editing |
enabled |
bool |
Disables field interactions and dims colors |
controller |
TextEditingController? |
External controller override |
focusNode |
FocusNode? |
External focus node override |
nextFocusNode |
FocusNode? |
Focus node to request on keyboard submit |
debounce |
Duration |
Delay for debounced callbacks (default: 300ms) |
onDebouncedChanged |
ValueChanged<String>? |
Sync callback invoked after debounce delay |
onSearchAsync |
Future<void> Function(query, isCurrent)? |
Async search callback with stale response checker |
showSearchLoadingIndicator |
bool |
Auto-swaps suffix icon to spinner during async search |
SmartPasswordConfig Property Reference #
| Property | Type | Description |
|---|---|---|
label |
String? |
Field label header shown above input |
hint |
String? |
Placeholder text inside input |
helperText |
String? |
Supporting text shown below field |
isRequired |
bool |
Adds * asterisk and runs empty validation |
obscuringCharacter |
String |
Mask symbol used when obscured (default: '•') |
showToggleIcon |
bool |
Renders visibility eye icon toggle (default: true) |
toggleIconBuilder |
Widget Function(bool isObscured)? |
Builder for custom visibility toggle icon |
showStrengthMeter |
bool |
Renders animated 4-segment password strength bar (default: true) |
strengthMeterBuilder |
Widget Function(BuildContext, PasswordStrength)? |
Builder for replacing default strength meter UI |
customStrengthScorer |
PasswordStrength Function(String, int)? |
Custom algorithm function for password strength scoring |
minPasswordLength |
int |
Minimum password length requirement & strength threshold baseline (default: 8) |
requireUppercase |
bool |
Requires at least one uppercase letter [A-Z] |
requireLowercase |
bool |
Requires at least one lowercase letter [a-z] |
requireDigit |
bool |
Requires at least one numeric digit [0-9] |
requireSpecialChar |
bool |
Requires at least one special character [!@#$%^&*...] |
confirmPasswordController |
TextEditingController? |
Controller of original password field for match validation |
confirmMismatchMessage |
String? |
Custom error message when confirm password does not match |
License #
MIT License.