import 'dart:ui'; import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_form_builder/flutter_form_builder.dart'; import 'package:get/get.dart'; import '../core/constants/translation_keys.dart'; import '../res/app_colors.dart'; import '../res/app_theme.dart'; import 'custom_text.dart'; @immutable class CustomInputFieldCustom extends GetView { final FormFieldValidator? validator; GlobalKey? refKey; String labelText = ""; String hint = ""; RxString errorTextMessage = "".obs; String errorText = ""; bool isRequired = true; final bool enabled; final AutovalidateMode autovalidateMode; final String? restorationId; InputDecoration? decoration; TextEditingController? controller; TextInputType keyboardType; EdgeInsets? padding = EdgeInsets.zero; final TextInputAction? textInputAction; final TextCapitalization textCapitalization; final TextStyle? style; final StrutStyle? strutStyle; TextAlign textAlign; final TextAlignVertical? textAlignVertical; final TextDirection? textDirection; final bool autofocus; final String obscuringCharacter; bool isPassword = false; bool requiredPasswordIcon = false; bool autocorrect = false; final SmartDashesType? smartDashesType; final SmartQuotesType? smartQuotesType; final bool enableSuggestions; int maxLines; int minLines; bool expands; TextStyle? labelStyle; final int? maxLength; final MaxLengthEnforcement? maxLengthEnforcement; final VoidCallback? onEditingComplete; final ValueChanged? onSubmitted; final List? inputFormatters; bool showCursor = true; double cursorWidth = 5.0; double cursorHeight = 15.0; Radius cursorRadius = const Radius.circular(10.0); Color cursorColor = AppThemeData.inputTextColor; final BoxHeightStyle selectionHeightStyle; final BoxWidthStyle selectionWidthStyle; final Brightness? keyboardAppearance; final EdgeInsets scrollPadding; final bool enableInteractiveSelection; final DragStartBehavior dragStartBehavior; final GestureTapCallback? onTap; final TapRegionCallback? onTapOutside; final MouseCursor? mouseCursor; final InputCounterWidgetBuilder? buildCounter; final ScrollPhysics? scrollPhysics; final ScrollController? scrollController; final Iterable? autofillHints; final TextMagnifierConfiguration? magnifierConfiguration; final bool readOnly; final ContentInsertionConfiguration? contentInsertionConfiguration; SpellCheckConfiguration? spellCheckConfiguration; final Rx fillColor = Rx(Colors.transparent); final Rx inputErrorColor = Rx(Colors.black); final Rx inputErrorBorderColor = Rx(Colors.black); RxBool isError = false.obs; RxBool passwordVisible = false.obs; CustomInputFieldCustom({ this.refKey, this.controller, this.labelText = "", this.hint = "", this.errorText = "", this.isRequired = true, this.validator, this.labelStyle, this.decoration, this.padding, this.enabled = true, this.requiredPasswordIcon = false, this.autovalidateMode = AutovalidateMode.disabled, this.restorationId, this.readOnly = false, this.isPassword = false, this.textCapitalization = TextCapitalization.none, this.scrollPadding = const EdgeInsets.all(20.0), this.enableInteractiveSelection = true, this.maxLengthEnforcement, this.textAlign = TextAlign.start, this.autofocus = false, this.autocorrect = false, this.cursorWidth = 5.0, this.cursorHeight = 20.0, this.cursorRadius = const Radius.circular(10.0), this.keyboardType = TextInputType.text, this.style, this.textInputAction, this.strutStyle, this.textDirection, this.maxLength, this.onEditingComplete, this.onSubmitted, this.inputFormatters, this.cursorColor = AppThemeData.inputTextColor, this.keyboardAppearance, this.buildCounter, this.expands = false, this.minLines = 1, this.maxLines = 4, this.showCursor = true, this.onTap, this.onTapOutside, this.enableSuggestions = true, this.textAlignVertical, this.dragStartBehavior = DragStartBehavior.start, this.scrollController, this.scrollPhysics, this.selectionWidthStyle = BoxWidthStyle.tight, this.smartDashesType, this.smartQuotesType, this.selectionHeightStyle = BoxHeightStyle.tight, this.autofillHints, this.obscuringCharacter = '•', this.mouseCursor, this.magnifierConfiguration, this.contentInsertionConfiguration, this.spellCheckConfiguration, }) : errorTextMessage = "".obs { errorText = errorTextMessage.value; } void setError(String errorMessage) { inputErrorBorderColor.value = AppThemeData.inputErrorBorderColor; inputErrorColor.value = AppThemeData.inputErrorColor; fillColor.value = AppThemeData.inputErrorColor; errorTextMessage.value = errorMessage; isError.value = true; } void markFieldAsValid() { inputErrorBorderColor.value = AppThemeData.inputBackgroundColor; inputErrorColor.value = AppThemeData.inputErrorColor; errorTextMessage.value = ""; fillColor.value = Colors.transparent; isError.value = false; } void markFieldAsInvalid() { inputErrorBorderColor.value = AppThemeData.inputErrorBorderColor; inputErrorColor.value = AppThemeData.inputErrorColor; fillColor.value = AppThemeData.inputErrorColor; errorTextMessage.value = TranslationKeys.makeTranslation(TranslationKeys.textErrorRequired); isError.value = true; } bool validate(String value) { if (isRequired) { if (value.isEmpty) { markFieldAsInvalid(); return false; } markFieldAsValid(); return true; } markFieldAsValid(); return true; } @override Widget build(BuildContext context) { return Obx(() { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Visibility( visible: labelText.isNotEmpty, child: Column( children: [ CustomText( labelText, style: labelStyle ?? AppThemeData.labelStyle, ), const SizedBox(height: 8), ], ), ), FormBuilderTextField( key: refKey, name: "", decoration: InputDecoration( filled: true, suffixIcon: Visibility( visible: requiredPasswordIcon, child: Container( width: 30, height: 30, margin: const EdgeInsets.all(5), child: IconButton( icon: Icon( size: 18, passwordVisible.value ? Icons.visibility : Icons.visibility_off_rounded), onPressed: () { passwordVisible.value = !passwordVisible.value; }, ), ), ), fillColor: AppColors.colorGrey50, isDense: true, contentPadding: padding ?? const EdgeInsets.symmetric(horizontal: 12, vertical: 8), labelText: null, errorStyle: AppThemeData.errorStyle .copyWith(color: inputErrorColor.value), enabledBorder: OutlineInputBorder( borderSide: const BorderSide( color: AppThemeData.inputEnabledBorderColor), borderRadius: BorderRadius.circular(50)), focusedBorder: OutlineInputBorder( borderSide: const BorderSide( color: AppThemeData.inputFocusedBorderColor), borderRadius: BorderRadius.circular(50)), border: OutlineInputBorder( borderSide: const BorderSide(color: AppThemeData.inputBorderColor), borderRadius: BorderRadius.circular(50), ), errorBorder: OutlineInputBorder( borderSide: const BorderSide( color: AppThemeData.inputErrorBorderColor), borderRadius: BorderRadius.circular(50)), errorText: errorTextMessage.value.isEmpty ? null : errorTextMessage.value, hintText: hint, hintStyle: AppThemeData.hintStyle, ), enabled: enabled, autovalidateMode: autovalidateMode, restorationId: restorationId, readOnly: readOnly, validator: (value) { validate(value!); return null; }, onChanged: (value) { if (value!.isNotEmpty) { markFieldAsValid(); } }, textCapitalization: textCapitalization, scrollPadding: scrollPadding, enableInteractiveSelection: enableInteractiveSelection, maxLengthEnforcement: maxLengthEnforcement, textAlign: textAlign, autofocus: autofocus, autocorrect: autocorrect, keyboardType: keyboardType, style: AppThemeData.inputStyle.copyWith(height: 1), controller: controller, textInputAction: textInputAction, strutStyle: strutStyle, textDirection: textDirection, maxLength: maxLength, onEditingComplete: onEditingComplete, onSubmitted: onSubmitted, inputFormatters: inputFormatters, cursorColor: cursorColor, cursorWidth: 1.5, cursorHeight: 15, cursorRadius: const Radius.circular(10.0), keyboardAppearance: keyboardAppearance, buildCounter: buildCounter, expands: expands, maxLines: isPassword ? maxLines = 1 : maxLines, obscureText: isPassword && passwordVisible.value, minLines: isPassword ? minLines = 1 : minLines, showCursor: showCursor, onTap: onTap, onTapOutside: onTapOutside, enableSuggestions: enableSuggestions, textAlignVertical: textAlignVertical, dragStartBehavior: dragStartBehavior, scrollController: scrollController, scrollPhysics: scrollPhysics, selectionWidthStyle: selectionWidthStyle, smartDashesType: smartDashesType, smartQuotesType: smartQuotesType, selectionHeightStyle: selectionHeightStyle, autofillHints: autofillHints, obscuringCharacter: obscuringCharacter, mouseCursor: mouseCursor, magnifierConfiguration: magnifierConfiguration, contentInsertionConfiguration: contentInsertionConfiguration, spellCheckConfiguration: spellCheckConfiguration, ), ], ); }); } String getText() { return controller!.text; } void clear() { controller!.clear(); } }