import 'package:farm_tpf/themes/app_dimension.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_svg/svg.dart'; import '../../../themes/app_colors.dart'; import '../../../themes/styles_text.dart'; import '../../../utils/app_images.dart'; import '../../../utils/validators.dart'; class TextFieldNormal extends StatefulWidget { final TextEditingController controller; final Function(String)? onFieldSubmitted; final Function(String)? onChanged; final FormFieldValidator? validator; final String hint; final FocusNode? focusNode; final TextInputType? keyboardType; final TextInputAction? textInputAction; final List? inputFormatters; final bool? obscureText; final String? errorText; final Color? borderColor; final bool? isPasswordField; final Widget? prefixIcon; final String? prefixText; final int? maxLength; final bool? disabled; final TextCapitalization? textCapitalization; final String? suffixText; final HexColor? disableColor; final InputBorder? customBorder; final int? maxLines; final bool? autofocus; final EdgeInsetsGeometry? contentPadding; final Color? fillColor; final Color? hintColor; final TextStyle? inputStyle; final Widget? suffixIcon; final TextAlign textAlign; final VoidCallback? onTap; final bool readOnly; TextFieldNormal({ required this.controller, required this.hint, this.validator, this.onFieldSubmitted, this.focusNode, this.keyboardType, this.textInputAction, this.inputFormatters, this.obscureText, this.errorText, this.onChanged, this.borderColor, this.isPasswordField, this.prefixIcon, this.maxLength, this.disabled, this.textCapitalization, this.suffixText, this.disableColor, this.prefixText, this.customBorder, this.maxLines, this.autofocus, this.contentPadding, this.fillColor, this.hintColor, this.inputStyle, this.suffixIcon, this.textAlign = TextAlign.start, this.onTap, this.readOnly = false, }); @override _TextFieldNormalState createState() => _TextFieldNormalState(); } class _TextFieldNormalState extends State { var isObscureText = false; late HexColor disableColor; final _errorMessage = ValueNotifier(''); @override void initState() { super.initState(); isObscureText = widget.isPasswordField ?? false; disableColor = widget.disableColor ?? AppColors.white; } @override Widget build(BuildContext context) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ TextFormField( textAlign: widget.textAlign, keyboardType: widget.keyboardType ?? TextInputType.text, textInputAction: widget.textInputAction ?? TextInputAction.done, inputFormatters: widget.inputFormatters, obscureText: isObscureText, controller: widget.controller, validator: onValidator, readOnly: widget.readOnly, onTap: widget.onTap, onFieldSubmitted: widget.onFieldSubmitted, focusNode: widget.focusNode, autocorrect: false, autofocus: widget.autofocus ?? false, onChanged: widget.onChanged, maxLength: widget.maxLength, style: widget.inputStyle ?? StylesText.body6, maxLines: widget.maxLines ?? 1, autovalidateMode: AutovalidateMode.disabled, enabled: widget.disabled != true, textCapitalization: widget.textCapitalization ?? TextCapitalization.none, decoration: InputDecoration( contentPadding: widget.contentPadding ?? const EdgeInsets.symmetric(horizontal: 12, vertical: 16), isDense: true, counterText: '', suffixText: widget.suffixText, prefixIconConstraints: const BoxConstraints(maxHeight: 20), suffixIconConstraints: const BoxConstraints(maxHeight: 20), prefixIcon: widget.prefixIcon, suffixIcon: widget.isPasswordField != null ? Padding( padding: const EdgeInsetsDirectional.only(end: 20.0), child: InkWell( onTap: () { setState( () { isObscureText = !isObscureText; }, ); }, child: isObscureText ? SizedBox( width: 20.w, height: 20.h, child: SvgPicture.asset( AssetSVG.eye, ), ) : SizedBox( width: 20.w, height: 20.h, child: SvgPicture.asset( AssetSVG.eyeOff, ), ), ), ) : widget.suffixIcon, enabledBorder: widget.customBorder ?? OutlineInputBorder( borderRadius: BorderRadius.circular(12), borderSide: BorderSide( color: widget.borderColor ?? AppColors.neutral4, width: 1, ), ), focusedBorder: widget.customBorder ?? OutlineInputBorder( borderRadius: BorderRadius.circular(12), borderSide: BorderSide( color: widget.borderColor ?? AppColors.neutral4, width: 1, ), ), errorBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(12), borderSide: BorderSide( color: widget.borderColor ?? AppColors.semantic6, width: 1, ), ), focusedErrorBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(12), borderSide: BorderSide( color: widget.borderColor ?? AppColors.semantic6, width: 1, ), ), disabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(12), borderSide: BorderSide( color: widget.borderColor ?? AppColors.neutral4, width: 1, ), ), hintText: widget.hint, hintStyle: StylesText.body6.copyWith( color: widget.hintColor ?? AppColors.neutral3, ), errorStyle: const TextStyle(fontSize: 0, height: 0), fillColor: (widget.disabled ?? false) ? (widget.disableColor ?? AppColors.background1.withOpacity(0.1)) : (widget.fillColor ?? Colors.white), filled: true, ), ), ValueListenableBuilder( valueListenable: _errorMessage, builder: (context, message, _) { if (Validators.stringNotNullOrEmpty(message)) { return Padding( padding: const EdgeInsets.only(top: 0.0), child: Row( children: [ SvgPicture.asset(AssetSVG.icWarning), const SizedBox( width: 4, ), Text( message, style: StylesText.caption3.copyWith( color: AppColors.semantic6, ), ), ], ), ); } else { return const SizedBox.shrink(); } }, ), ], ); } String? onValidator(String? value) { if (widget.validator != null) { _errorMessage.value = widget.validator!(value!) ?? ''; return widget.validator!(value); } else { _errorMessage.value = ''; return null; } } }