import 'package:flutter/material.dart';
enum CustomTextFieldType {
singleLineTextField,
multiLineTextField,
passwordField,
searchField,
}
class CustomTextField extends StatelessWidget {
final CustomTextFieldType type;
final String? labelText;
final TextEditingController? controller;
final String? errorText;
final IconData? prefixIcon;
final IconData? suffixIcon;
final bool obscureText;
final Color? borderColor;
final Color? labelColor;
final Color? errorColor;
final Color? textColor;
final TextStyle? textStyle;
final int? maxLines;
final VoidCallback? onSuffixIconTap;
final EdgeInsetsGeometry? padding;
CustomTextField({
required this.type,
this.labelText,
this.controller,
this.errorText,
this.prefixIcon,
this.suffixIcon,
this.obscureText = false,
this.borderColor,
this.labelColor,
this.errorColor,
this.textColor,
this.textStyle,
this.maxLines,
this.onSuffixIconTap,
this.padding,
});
@override
Widget build(BuildContext context) {
switch (type) {
case CustomTextFieldType.singleLineTextField:
return _buildSingleLineTextField(context);
case CustomTextFieldType.multiLineTextField:
return _buildMultiLineTextField(context);
case CustomTextFieldType.passwordField:
return _buildPasswordField(context);
case CustomTextFieldType.searchField:
return _buildSearchField(context);
default:
return _buildDefaultTextField(context);
}
}
Widget _buildSingleLineTextField(BuildContext context) {
return _buildTextField(context, maxLines: 1);
}
Widget _buildMultiLineTextField(BuildContext context) {
return _buildTextField(context, maxLines: maxLines ?? 5);
}
Widget _buildPasswordField(BuildContext context) {
return _buildTextField(context, obscureText: true);
}
Widget _buildSearchField(BuildContext context) {
return _buildTextField(
context,
prefixIcon: prefixIcon ?? Icons.search,
suffixIcon: suffixIcon,
onSuffixIconTap: onSuffixIconTap,
);
}
Widget _buildDefaultTextField(BuildContext context) {
return _buildTextField(context);
}
Widget _buildTextField(
BuildContext context, {
int? maxLines,
bool? obscureText,
IconData? prefixIcon,
IconData? suffixIcon,
VoidCallback? onSuffixIconTap,
}) {
return Padding(
padding: _getPadding(),
child: TextField(
controller: controller,
obscureText: obscureText ?? this.obscureText,
maxLines: maxLines ?? 1,
style: _getTextStyle(),
decoration: InputDecoration(
labelText: labelText,
labelStyle: TextStyle(color: _getLabelColor(context)),
errorText: errorText,
errorStyle: TextStyle(color: _getErrorColor(context)),
prefixIcon: prefixIcon != null ? Icon(prefixIcon) : null,
suffixIcon: suffixIcon != null
? GestureDetector(
onTap: onSuffixIconTap,
child: Icon(suffixIcon, color: _getErrorColor(context)),
)
: null,
enabledBorder: _getBorder(context),
focusedBorder: _getBorder(context),
errorBorder: _getErrorBorder(context),
focusedErrorBorder: _getErrorBorder(context),
),
),
);
}
// Method to get the border with the specified color
InputBorder _getBorder(BuildContext context) {
return UnderlineInputBorder(
borderSide: BorderSide(color: _getBorderColor(context)),
);
}
// Method to get the error border with the specified color
InputBorder _getErrorBorder(BuildContext context) {
return UnderlineInputBorder(
borderSide: BorderSide(color: _getErrorColor(context)),
);
}
// Method to get the border color or a default value
Color _getBorderColor(BuildContext context) {
return borderColor ?? Theme.of(context).primaryColor;
}
// Method to get the label color or a default value
Color _getLabelColor(BuildContext context) {
return labelColor ?? Theme.of(context).primaryColor;
}
// Method to get the error color or a default value
Color _getErrorColor(BuildContext context) {
return errorColor ?? Colors.red;
}
// Method to get the text color or a default value
Color _getTextColor(BuildContext context) {
return textColor ?? Theme.of(context).primaryColor;
}
// Method to get the text style or a default style
TextStyle _getTextStyle() {
return textStyle ?? TextStyle(fontSize: 16, color: _getTextColor(context));
}
// Method to get the padding or a default value
EdgeInsetsGeometry _getPadding() {
return padding ?? EdgeInsets.all(8.0);
}
}
class TextFieldExamples extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('TextField Examples')),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
CustomTextField(
type: CustomTextFieldType.singleLineTextField,
labelText: 'Single Line TextField',
controller: TextEditingController(),
borderColor: Colors.blue,
),
SizedBox(height: 20),
CustomTextField(
type: CustomTextFieldType.multiLineTextField,
labelText: 'Multi-line TextField',
controller: TextEditingController(),
maxLines: 4,
borderColor: Colors.green,
),
SizedBox(height: 20),
CustomTextField(
type: CustomTextFieldType.passwordField,
labelText: 'Password Field',
controller: TextEditingController(),
borderColor: Colors.red,
suffixIcon: Icons.visibility_off,
onSuffixIconTap: () {
print('Toggle Password Visibility');
},
obscureText: true,
),
SizedBox(height: 20),
CustomTextField(
type: CustomTextFieldType.searchField,
labelText: 'Search Field',
controller: TextEditingController(),
prefixIcon: Icons.search,
suffixIcon: Icons.clear,
onSuffixIconTap: () {
print('Clear Search Field');
},
borderColor: Colors.orange,
),
],
),
),
);
}
}