Skip to content

Instantly share code, notes, and snippets.

@mortezanazari-hub
Created January 23, 2025 13:15
Show Gist options
  • Select an option

  • Save mortezanazari-hub/cc3baf24bcd57dfd7ed69aa537f6b556 to your computer and use it in GitHub Desktop.

Select an option

Save mortezanazari-hub/cc3baf24bcd57dfd7ed69aa537f6b556 to your computer and use it in GitHub Desktop.
/// {@template app_text_field}
/// یک ویجت فیلد متن قابل تنظیم با گزینه‌های سفارشی‌سازی مختلف.
/// A customizable text field widget with various customization options.
/// {@endtemplate}
class AppTextField extends StatelessWidget {
/// {@macro app_text_field}
const AppTextField({
super.key,
this.controller,
this.labelText,
this.enabled = true,
this.obscureText = false,
this.onChanged,
this.autovalidateMode = AutovalidateMode.onUserInteraction,
this.validator,
this.helperText,
this.errorText,
this.suffixIcon,
this.suffixIconConstraints =
const BoxConstraints(minHeight: 24, minWidth: 40),
this.prefixIcon,
this.prefixIconConstraints =
const BoxConstraints(minHeight: 24, minWidth: 40),
this.autofillHints,
this.onEditingComplete,
this.inputFormatters,
this.keyboardType,
this.maxLines = 1,
});
/// کنترلر برای فیلد متن.
/// The controller for the text field.
final TextEditingController? controller;
/// متن برچسب برای فیلد متن.
/// The label text for the text field.
final String? labelText;
/// اینکه آیا فیلد متن فعال است یا خیر.
/// Whether the text field is enabled.
final bool enabled;
/// اینکه آیا فیلد متن مبهم است یا خیر (برای رمز عبور).
/// Whether the text field is obscured.
final bool obscureText;
/// هنگامی که مقدار فیلد متن تغییر می‌کند، فراخوانی می‌شود.
/// Called when the text field value changes.
final ValueChanged<String>? onChanged;
/// حالت اعتبارسنجی خودکار برای فیلد متن.
/// The autovalidate mode for the text field.
final AutovalidateMode autovalidateMode;
/// اعتبارسنج برای فیلد متن.
/// The validator for the text field.
final FormFieldValidator<String>? validator;
/// متن راهنما برای فیلد متن.
/// The helper text for the text field.
final String? helperText;
/// متن خطا برای فیلد متن.
/// The error text for the text field.
final String? errorText;
/// آیکون انتهایی برای فیلد متن.
/// The suffix icon for the text field.
final Widget? suffixIcon;
/// محدودیت‌ها برای آیکون انتهایی.
/// The constraints for the suffix icon.
final BoxConstraints? suffixIconConstraints;
/// آیکون ابتدایی برای فیلد متن.
/// The prefix icon for the text field.
final Widget? prefixIcon;
/// محدودیت‌ها برای آیکون ابتدایی.
/// The constraints for the prefix icon.
final BoxConstraints? prefixIconConstraints;
/// راهنمایی‌های تکمیل خودکار برای فیلد متن برنامه.
/// The autofillhints for app text field.
final Iterable<String>? autofillHints;
/// هنگامی که مقدار فیلد متن کامل می‌شود، فراخوانی می‌شود.
/// Called when the text field value completed.
final VoidCallback? onEditingComplete;
/// قالب‌بندی‌های ورودی برای فیلد متن.
/// The input formatters for the text field.
final List<TextInputFormatter>? inputFormatters;
/// نوع کیبورد برای فیلد متن.
/// The keyboard type for the text field.
final TextInputType? keyboardType;
/// حداکثر خطوط موجود در فیلد متن.
/// the maximum lines available in text field.
final int maxLines;
}
@override
Widget build(BuildContext context) {
return TextFormField(
keyboardType: keyboardType,
inputFormatters: inputFormatters,
onEditingComplete: onEditingComplete,
autofillHints: autofillHints,
controller: controller,
enabled: enabled,
obscureText: obscureText,
onChanged: onChanged,
autovalidateMode: autovalidateMode,
validator: validator,
maxLines: maxLines,
style: WidgetStateTextStyle.resolveWith(
(states) {
late final Color textColor;
if (states.contains(WidgetState.error)) {
textColor = context.inputTheme.focusedTextDefault;
} else if (states.contains(WidgetState.focused)) {
textColor = context.inputTheme.focusedTextDefault;
} else if (states.contains(WidgetState.disabled)) {
textColor = context.inputTheme.disabledText;
} else {
textColor = context.inputTheme.defaultText;
}
return context.typography.inputPlaceHolder.copyWith(
color: textColor,
);
},
),
cursorColor: context.inputTheme.focusedTextDefault,
cursorHeight: 16,
decoration: InputDecoration(
labelText: labelText,
labelStyle: WidgetStateTextStyle.resolveWith(
(states) {
late final Color textColor;
if (states.contains(WidgetState.error)) {
textColor = context.inputTheme.errorTextDefault;
} else if (states.contains(WidgetState.focused)) {
textColor = context.inputTheme.focusedOnBrand;
} else if (states.contains(WidgetState.disabled)) {
textColor = context.inputTheme.disabledText;
} else {
textColor = context.inputTheme.defaultText;
}
return context.typography.inputPlaceHolder.copyWith(
color: textColor,
);
},
),
floatingLabelStyle: WidgetStateTextStyle.resolveWith(
(states) {
late final Color textColor;
if (states.contains(WidgetState.error)) {
textColor = context.inputTheme.errorTextDefault;
} else if (states.contains(WidgetState.focused)) {
textColor = context.inputTheme.focusedOnBrand;
} else {
textColor = context.inputTheme.defaultText;
}
return context.typography.inputLabel.copyWith(
color: textColor,
);
},
),
filled: true,
fillColor: enabled
? context.inputTheme.defaultColor
: context.inputTheme.disabledColor,
border: MaterialStateOutlineInputBorder.resolveWith(
(states) {
late final Color borderColor;
if (states.contains(WidgetState.error)) {
borderColor = context.inputTheme.borderError;
} else if (states.contains(WidgetState.focused)) {
borderColor = context.inputTheme.borderFocused;
} else if (states.contains(WidgetState.disabled)) {
borderColor = context.inputTheme.borderDisabled;
} else if (states.contains(WidgetState.hovered)) {
borderColor = context.inputTheme.borderHover;
} else {
borderColor = context.inputTheme.borderDefault;
}
return OutlineInputBorder(
borderRadius: const BorderRadius.all(AppRadius.md),
borderSide: BorderSide(
color: borderColor,
),
);
},
),
hoverColor: Colors.transparent,
focusColor: Colors.transparent,
helperText: helperText,
helperStyle: WidgetStateTextStyle.resolveWith(
(states) {
late final Color textColor;
if (states.contains(WidgetState.error)) {
textColor = context.inputTheme.errorTextDefault;
} else if (states.contains(WidgetState.focused)) {
textColor = context.inputTheme.focusedOnBrand;
} else if (states.contains(WidgetState.disabled)) {
textColor = context.inputTheme.disabledText;
} else {
textColor = context.inputTheme.defaultText;
}
return context.typography.inputHint.copyWith(
color: textColor,
);
},
),
errorText: errorText,
errorStyle: context.typography.inputHint.copyWith(
color: context.inputTheme.errorTextDefault,
),
suffixIcon: suffixIcon,
prefixIcon: prefixIcon,
suffixIconConstraints: suffixIconConstraints,
prefixIconConstraints: prefixIconConstraints,
),
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment