/// Phone Input Field Widget /// /// Custom text field for Vietnamese phone number input. /// Supports formats: 0xxx xxx xxx, +84xxx xxx xxx, 84xxx xxx xxx library; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:worker/core/constants/ui_constants.dart'; import 'package:worker/core/theme/colors.dart'; /// Phone Input Field /// /// A custom text field widget specifically designed for Vietnamese phone number input. /// Features: /// - Phone icon prefix /// - Numeric keyboard /// - Phone number formatting /// - Vietnamese phone validation support /// /// Usage: /// ```dart /// PhoneInputField( /// controller: phoneController, /// validator: Validators.phone, /// onChanged: (value) { /// // Handle phone number change /// }, /// ) /// ``` class PhoneInputField extends StatelessWidget { /// Creates a phone input field const PhoneInputField({ super.key, required this.controller, this.focusNode, this.validator, this.onChanged, this.onFieldSubmitted, this.enabled = true, this.autofocus = false, }); /// Text editing controller final TextEditingController controller; /// Focus node for keyboard focus management final FocusNode? focusNode; /// Form field validator final String? Function(String?)? validator; /// Callback when text changes final void Function(String)? onChanged; /// Callback when field is submitted final void Function(String)? onFieldSubmitted; /// Whether the field is enabled final bool enabled; /// Whether the field should auto-focus final bool autofocus; @override Widget build(BuildContext context) { return TextFormField( controller: controller, focusNode: focusNode, autofocus: autofocus, enabled: enabled, keyboardType: TextInputType.phone, textInputAction: TextInputAction.next, inputFormatters: [ // Allow digits, spaces, +, and parentheses FilteringTextInputFormatter.allow(RegExp(r'[0-9+\s()]')), // Limit to reasonable phone length LengthLimitingTextInputFormatter(15), ], style: const TextStyle( fontSize: InputFieldSpecs.fontSize, color: AppColors.grey900, ), decoration: InputDecoration( labelText: 'Số điện thoại', labelStyle: const TextStyle( fontSize: InputFieldSpecs.labelFontSize, color: AppColors.grey500, ), hintText: 'Nhập số điện thoại', hintStyle: const TextStyle( fontSize: InputFieldSpecs.hintFontSize, color: AppColors.grey500, ), prefixIcon: const Icon( Icons.phone, color: AppColors.primaryBlue, size: AppIconSize.md, ), filled: true, fillColor: AppColors.white, contentPadding: InputFieldSpecs.contentPadding, border: OutlineInputBorder( borderRadius: BorderRadius.circular(InputFieldSpecs.borderRadius), borderSide: const BorderSide(color: AppColors.grey100, width: 1.0), ), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(InputFieldSpecs.borderRadius), borderSide: const BorderSide(color: AppColors.grey100, width: 1.0), ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(InputFieldSpecs.borderRadius), borderSide: const BorderSide( color: AppColors.primaryBlue, width: 2.0, ), ), errorBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(InputFieldSpecs.borderRadius), borderSide: const BorderSide(color: AppColors.danger, width: 1.0), ), focusedErrorBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(InputFieldSpecs.borderRadius), borderSide: const BorderSide(color: AppColors.danger, width: 2.0), ), errorStyle: const TextStyle(fontSize: 12.0, color: AppColors.danger), ), validator: validator, onChanged: onChanged, onFieldSubmitted: onFieldSubmitted, ); } }