import 'package:eva_icons_flutter/eva_icons_flutter.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; class NumberTextInputFormatter extends TextInputFormatter { @override TextEditingValue formatEditUpdate(TextEditingValue oldValue, TextEditingValue newValue) { final int newTextLength = newValue.text.length; int selectionIndex = newValue.selection.end; int usedSubstringIndex = 0; final StringBuffer newText = StringBuffer(); if (newTextLength >= 1) { newText.write('('); if (newValue.selection.end >= 1) selectionIndex++; } if (newTextLength >= 4) { newText.write(newValue.text.substring(0, usedSubstringIndex = 3) + ') '); if (newValue.selection.end >= 3) selectionIndex += 2; } if (newTextLength >= 7) { newText.write(newValue.text.substring(3, usedSubstringIndex = 6) + '-'); if (newValue.selection.end >= 6) selectionIndex++; } if (newTextLength >= 11) { newText.write(newValue.text.substring(6, usedSubstringIndex = 10) + ' '); if (newValue.selection.end >= 10) selectionIndex++; } // Dump the rest. if (newTextLength >= usedSubstringIndex) newText.write(newValue.text.substring(usedSubstringIndex)); return TextEditingValue( text: newText.toString(), selection: TextSelection.collapsed(offset: selectionIndex), ); } } final _mobileFormatter = NumberTextInputFormatter(); class TextFields extends StatefulWidget { TextFields({ Key? key, this.type, this.hintText, this.suffixIcon, this.autoFocus, this.onChanged, this.initialValue, this.minLines, this.maxLines, this.inputFormatters, this.padding, this.focus = false, this.maxLengthEnforced = true, this.suffixIconColor, this.inputAction = TextInputAction.done, this.onSubmit, this.keepPadding = true, this.textCapitalization = TextCapitalization.none, this.controller, this.keyboardType, this.validator, this.borderOnlyError = false, this.onSaved, this.onSuffixTap, this.readOnly = false, this.maxLength, this.prefixIcon, this.bare = false, this.onTap, this.fontSize = 16.0, this.fontWeight = FontWeight.w700, this.autoValidate = false, this.fillColor, this.hintColor, this.hasBorder = true, this.onTapTextFields, this.hasLabelText = false, this.showLabelText = false, this.borderRadius = 8.0, this.borderColor, this.borderWidth = 1, }) : super(key: key); final String? hintText; final String? initialValue; final String? type; final bool? autoFocus; final IconData? suffixIcon; final Color? suffixIconColor; final Icon? prefixIcon; final VoidCallback? onTap; final Function()? onTapTextFields; final TextEditingController? controller; final TextInputType? keyboardType; final FormFieldValidator? validator; final Function(String? val)? onSaved; final Function()? onSuffixTap; final Function(String val)? onChanged; final Function()? onSubmit; final bool? readOnly; final int? maxLength; final int? minLines; final int? maxLines; final bool maxLengthEnforced; final bool bare; final TextInputAction inputAction; final double fontSize; final FontWeight fontWeight; final bool keepPadding; final TextCapitalization textCapitalization; final List? inputFormatters; final bool autoValidate; final EdgeInsets? padding; final bool focus; final bool borderOnlyError; final Color? hintColor; final Color? fillColor; final bool hasBorder; final bool showLabelText; Color? borderColor; final double borderRadius; final double borderWidth; bool hasLabelText; @override _TextFieldsState createState() => _TextFieldsState(); } class _TextFieldsState extends State { final FocusNode _focusNode = FocusNode(); bool focus = false; bool view = false; @override void initState() { super.initState(); _focusNode.addListener(() { setState(() { focus = _focusNode.hasFocus; }); }); } @override void didUpdateWidget(TextFields oldWidget) { if (widget.focus) _focusNode.requestFocus(); super.didUpdateWidget(oldWidget); } @override void dispose() { _focusNode.dispose(); super.dispose(); } Widget _buildSuffixIcon() { switch (widget.type) { case "password": { return Padding( padding: const EdgeInsets.only(right: 8.0), child: view ? InkWell( onTap: () { this.setState(() { view = false; }); }, child: Icon(EvaIcons.eye, size: 24.0, color: Color.fromRGBO(78, 62, 253, 1.0))) : InkWell( onTap: () { this.setState(() { view = true; }); }, child: Icon(EvaIcons.eyeOff, size: 24.0, color: Colors.grey[500]))); } break; default: if (widget.suffixIcon != null) return InkWell(onTap: widget.onSuffixTap, child: Icon(widget.suffixIcon, size: 22.0, color: widget.suffixIconColor != null ? widget.suffixIconColor : Colors.grey[500])); else return SizedBox(); } } bool _determineReadOnly() { if (widget.readOnly != null && widget.readOnly!) { _focusNode.unfocus(); return true; } else { return false; } } @override Widget build(BuildContext context) { widget.borderColor = widget.borderColor ?? Colors.grey; return (AnimatedContainer( duration: Duration(milliseconds: 300), decoration: widget.bare ? null : BoxDecoration(boxShadow: [ // BoxShadow( // color: Color.fromRGBO(70, 68, 167, focus ? 0.20 : 0), // offset: Offset(0.0, 13.0), // blurRadius: focus ? 34.0 : 12.0) BoxShadow(color: Color.fromRGBO(110, 68, 80, focus ? 0.20 : 0), offset: Offset(0.0, 13.0), blurRadius: focus ? 34.0 : 12.0) ]), child: Column( children: [ TextFormField( onTap: widget.onTapTextFields, keyboardAppearance: Theme.of(context).brightness, scrollPhysics: BouncingScrollPhysics(), // autovalidate: widget.autoValidate, textCapitalization: widget.textCapitalization, onFieldSubmitted: widget.inputAction == TextInputAction.next ? (widget.onSubmit != null ? widget.onSubmit!() : (val) { _focusNode.nextFocus(); }) : widget.onSubmit, textInputAction: widget.inputAction, minLines: widget.minLines ?? 1, maxLines: widget.maxLines ?? 1, //maxLengthEnforced: widget.maxLengthEnforced, initialValue: widget.initialValue, onChanged: (value) { if (widget.showLabelText) { if ((value == null || value == '')) { setState(() { widget.hasLabelText = false; }); } else { setState(() { widget.hasLabelText = true; }); } } if (widget.onChanged != null) widget.onChanged!(value); }, focusNode: _focusNode, maxLength: widget.maxLength ?? null, controller: widget.controller, keyboardType: widget.keyboardType, readOnly: _determineReadOnly(), obscureText: widget.type == "password" && !view ? true : false, autofocus: widget.autoFocus ?? false, validator: widget.validator, onSaved: widget.onSaved, style: Theme.of(context).textTheme.bodySmall!.copyWith(fontSize: widget.fontSize, fontWeight: widget.fontWeight), inputFormatters: widget.keyboardType == TextInputType.phone ? [ // WhitelistingTextInputFormatter.digitsOnly, _mobileFormatter, ] : widget.inputFormatters, decoration: InputDecoration( labelText: widget.hasLabelText ? widget.hintText : null, labelStyle: TextStyle( fontSize: widget.fontSize, fontWeight: widget.fontWeight, color: widget.hintColor ?? Theme.of(context).hintColor, ), counterText: "", hintText: widget.hintText, hintStyle: TextStyle( fontSize: widget.fontSize, fontWeight: widget.fontWeight, color: widget.hintColor ?? Theme.of(context).hintColor, ), contentPadding: widget.padding != null ? widget.padding : EdgeInsets.symmetric(vertical: (widget.bare && !widget.keepPadding) ? 0.0 : 10.0, horizontal: 16.0), filled: true, // fillColor: widget.bare ? Colors.transparent : Theme.of(context).backgroundColor, suffixIcon: _buildSuffixIcon(), prefixIcon: widget.prefixIcon, errorStyle: TextStyle(fontSize: 12.0, fontWeight: widget.fontWeight, height: widget.borderOnlyError ? 0.0 : null), errorBorder: OutlineInputBorder( borderSide: widget.hasBorder ? BorderSide(color:Colors.red.withOpacity(widget.bare ? 0.0 : 0.5), width: 1.0) : BorderSide(color: Colors.transparent, width: 0), borderRadius: widget.hasBorder ? BorderRadius.circular(widget.bare ? 0.0 : widget.borderRadius) : BorderRadius.circular(0.0), ), focusedErrorBorder: OutlineInputBorder( borderSide: widget.hasBorder ? BorderSide(color: Colors.red.withOpacity(widget.bare ? 0.0 : 0.5), width: 1.0) : BorderSide(color: Colors.transparent, width: 0), borderRadius: BorderRadius.circular(widget.bare ? 0.0 : widget.borderRadius)), focusedBorder: OutlineInputBorder( borderSide: widget.hasBorder ? BorderSide(color: widget.borderColor!, width: widget.borderWidth) : BorderSide(color: Colors.transparent, width: 0), borderRadius: widget.hasBorder ? BorderRadius.circular(widget.bare ? 0.0 : widget.borderRadius) : BorderRadius.circular(0.0), ), disabledBorder: OutlineInputBorder( borderSide: widget.hasBorder ? BorderSide(color: widget.borderColor!, width: widget.borderWidth) : BorderSide(color: Colors.transparent, width: 0), borderRadius: widget.hasBorder ? BorderRadius.circular(widget.bare ? 0.0 : widget.borderRadius) : BorderRadius.circular(0.0)), enabledBorder: OutlineInputBorder( borderSide: widget.hasBorder ? BorderSide(color: widget.borderColor!, width: widget.borderWidth) : BorderSide(color: Colors.transparent, width: 0), borderRadius: widget.hasBorder ? BorderRadius.circular(widget.bare ? 0.0 : widget.borderRadius) : BorderRadius.circular(0.0), ), ), ), ], ), )); } }