Input Text
depends on font_awesome_flutter for icons.
How to use?
You will need controller so initialize it first
final TextEditingController controller = TextEditingController();
Simple Default Input
InputText(label: 'Default', controller: controller),
Enable/ Disable Input Field, by default field is enabled
InputText(
label: 'Disabled',
isEnabled: false,
controller: controller,
),
Validate input
final GlobalKey<FormState> formKey = GlobalKey<FormState>();
return Form(
key: formKey,
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
InputText(
label: 'Invalid',
validator: (value) {
if (value!.isEmpty) {
return 'Field is empty';
}
return null;
},
),
verticalMargin8,
ElevatedButton(
onPressed: () => formKey.currentState?.validate(),
child: const Text('Validate'),
),
],
),
);
Change size of Input field, We have five sizes for inputs
// Available sizes
enum InputSize { extraSmall, small, medium, large, extraLarge }
const InputText(size: InputSize.small, label: 'Small'),
const InputText(size: InputSize.medium, label: 'Medium'),
const InputText(size: InputSize.large, label: 'Large'),
Use Prefix and Suffix icons, Note: we need to pass IconData which can be interpreted by FaIcon
. You can check documentation here and you can check which icons are available here.
Prefix icon
const InputText(
label: 'User Prefix Icon',
prefixOnTap: () {
print(content: 'Prefix icon onTap');
},
prefixIcon: FontAwesomeIcons.user,
),
Suffix icon
const InputText(
label: 'User Suffix Icon',
suffixOnTap: () {
print(content: 'Suffix icon onTap');
},
suffixIcon: FontAwesomeIcons.user,
),
Change icon colors
const InputText(
label: 'Search',
prefixIcon: FontAwesomeIcons.user,
prefixIconColor: AppTheme.colors['primary'],
suffixIcon: FontAwesomeIcons.magnifyingGlass,
suffixIconColor: AppTheme.colors['primary'],
),
Use custom padding for text input
const InputText(
label: 'Search',
padding: horizontalPadding16 + verticalPadding8,
),
Use custom padding for text input
const InputText(
label: 'Search',
padding: horizontalPadding16 + verticalPadding8,
),
Use onChanged function to execute action when value is changed
InputText(
label: 'Test',
onChanged: (value) {
print(value);
},
),
Change validation mode
const InputText(
label: 'Test',
autoValidateMode: AutovalidateMode.always,
),
Change keyboard type for field
const InputText(
label: 'Test',
keyboardType: TextInputType.number,
),
Use input formatters to restrcit/ allow special kind of values. You might have to hide TextInput from service.
import 'package:flutter/services.dart' hide TextInput;
InputText(
label: 'Digits Only',
keyboardType: TextInputType.number,
inputFormatters: [FilteringTextInputFormatter.digitsOnly],
),
Use minLines and maxLines to set lines visibility.
InputText(
label: 'Address',
minLines: 3,
maxLines: 3,
),
Source Code
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:team/vaahextendflutter/app_theme.dart';
import 'package:team/vaahextendflutter/helpers/constants.dart';
import 'package:team/vaahextendflutter/helpers/enums.dart';
class InputText extends StatelessWidget {
final String? label;
final EdgeInsets padding;
final double borderRadius;
final bool isEnabled;
final InputSize size;
final TextEditingController? controller;
final Function(String)? onChanged;
final String? Function(String?)? validator;
final AutovalidateMode? autoValidateMode;
final TextInputType? keyboardType;
final List<TextInputFormatter>? inputFormatters;
final IconData? prefixIcon;
final Color? prefixIconColor;
final Function()? prefixOnTap;
final IconData? suffixIcon;
final Color? suffixIconColor;
final Function()? suffixOnTap;
final int? minLines;
final int? maxLines;
const InputText({
super.key,
this.label,
this.padding = allPadding12,
this.borderRadius = defaultPadding / 2,
this.isEnabled = true,
this.size = InputSize.medium,
this.controller,
this.onChanged,
this.autoValidateMode,
this.validator,
this.keyboardType,
this.inputFormatters,
this.prefixIcon,
this.prefixIconColor,
this.prefixOnTap,
this.suffixIcon,
this.suffixIconColor,
this.suffixOnTap,
this.minLines,
this.maxLines,
});
@override
Widget build(BuildContext context) {
return TextFormField(
decoration: InputDecoration(
contentPadding: padding,
border: border(AppTheme.colors['black']!.shade400),
enabledBorder: border(AppTheme.colors['black']!.shade400),
disabledBorder: border(AppTheme.colors['black']!.shade300),
focusedBorder: border(AppTheme.colors['black']!.shade400),
errorBorder: border(AppTheme.colors['danger']!.shade400),
focusedErrorBorder: border(AppTheme.colors['danger']!.shade400),
errorStyle: TextStyle(color: AppTheme.colors['danger']!.shade400),
hintText: label,
hintStyle: TextStyle(
fontSize: getFontSize(),
color:
isEnabled ? AppTheme.colors['black']!.shade400 : AppTheme.colors['black']!.shade300,
),
prefixIcon: prefixIcon != null
? InkWell(
onTap: prefixOnTap,
child: Center(
child: Container(
margin: horizontalPadding4,
child: FaIcon(
prefixIcon,
size: getFontSize() * 1.15,
color: prefixIconColor ?? AppTheme.colors['black']!.shade400,
),
),
),
)
: null,
prefixIconConstraints: BoxConstraints(
maxWidth: getFontSize() * 2.3,
maxHeight: getFontSize() * 2.3,
),
suffixIcon: suffixIcon != null
? InkWell(
onTap: suffixOnTap,
child: Center(
child: Container(
margin: horizontalPadding4,
child: FaIcon(
suffixIcon,
size: getFontSize() * 1.15,
color: suffixIconColor ?? AppTheme.colors['black']!.shade400,
),
),
),
)
: null,
suffixIconConstraints: BoxConstraints(
maxWidth: getFontSize() * 2.3,
maxHeight: getFontSize() * 2.3,
),
),
keyboardType: keyboardType,
inputFormatters: inputFormatters,
validator: validator,
controller: controller,
onChanged: onChanged,
style: TextStyle(
fontSize: getFontSize(),
color: AppTheme.colors['black']!.shade400,
),
enabled: isEnabled,
autovalidateMode: autoValidateMode,
minLines: minLines,
maxLines: maxLines,
);
}
OutlineInputBorder border(Color color) {
return OutlineInputBorder(
borderRadius: BorderRadius.circular(borderRadius),
borderSide: BorderSide(
width: 1,
color: color,
),
);
}
double getFontSize() {
switch (size) {
case InputSize.extraSmall:
return AppTheme.extraSmall;
case InputSize.small:
return AppTheme.small;
case InputSize.large:
return AppTheme.large;
case InputSize.extraLarge:
return AppTheme.extraLarge;
default:
return AppTheme.medium;
}
}
}