add auth, format
This commit is contained in:
133
lib/features/auth/presentation/widgets/phone_input_field.dart
Normal file
133
lib/features/auth/presentation/widgets/phone_input_field.dart
Normal file
@@ -0,0 +1,133 @@
|
||||
/// 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,
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user