137 lines
4.3 KiB
Dart
137 lines
4.3 KiB
Dart
/// 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:font_awesome_flutter/font_awesome_flutter.dart';
|
|
import 'package:worker/core/constants/ui_constants.dart';
|
|
import 'package:worker/core/theme/colors.dart'; // For AppColors.danger
|
|
|
|
/// 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) {
|
|
final colorScheme = Theme.of(context).colorScheme;
|
|
|
|
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: TextStyle(
|
|
fontSize: InputFieldSpecs.fontSize,
|
|
color: colorScheme.onSurface,
|
|
),
|
|
decoration: InputDecoration(
|
|
labelText: 'Số điện thoại',
|
|
labelStyle: TextStyle(
|
|
fontSize: InputFieldSpecs.labelFontSize,
|
|
color: colorScheme.onSurfaceVariant,
|
|
),
|
|
hintText: 'Nhập số điện thoại',
|
|
hintStyle: TextStyle(
|
|
fontSize: InputFieldSpecs.hintFontSize,
|
|
color: colorScheme.onSurfaceVariant,
|
|
),
|
|
prefixIcon: Icon(
|
|
FontAwesomeIcons.phone,
|
|
color: colorScheme.primary,
|
|
size: AppIconSize.md,
|
|
),
|
|
filled: true,
|
|
fillColor: colorScheme.surface,
|
|
contentPadding: InputFieldSpecs.contentPadding,
|
|
border: OutlineInputBorder(
|
|
borderRadius: BorderRadius.circular(InputFieldSpecs.borderRadius),
|
|
borderSide: BorderSide(color: colorScheme.surfaceContainerHighest, width: 1.0),
|
|
),
|
|
enabledBorder: OutlineInputBorder(
|
|
borderRadius: BorderRadius.circular(InputFieldSpecs.borderRadius),
|
|
borderSide: BorderSide(color: colorScheme.surfaceContainerHighest, width: 1.0),
|
|
),
|
|
focusedBorder: OutlineInputBorder(
|
|
borderRadius: BorderRadius.circular(InputFieldSpecs.borderRadius),
|
|
borderSide: BorderSide(
|
|
color: colorScheme.primary,
|
|
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,
|
|
);
|
|
}
|
|
}
|