import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import '../../../../../application/auth/check_phone_form/check_phone_form_bloc.dart'; import '../../../../../common/theme/theme.dart'; import '../../../../components/field/field.dart'; class LoginPhoneField extends StatefulWidget { const LoginPhoneField({super.key}); @override State createState() => _LoginPhoneFieldState(); } class _LoginPhoneFieldState extends State { final TextEditingController _controller = TextEditingController(); final FocusNode _focusNode = FocusNode(); bool _hasFocus = false; @override void initState() { super.initState(); _focusNode.addListener(() { setState(() { _hasFocus = _focusNode.hasFocus; }); }); } @override void dispose() { _controller.dispose(); _focusNode.dispose(); super.dispose(); } void _clearText() { _controller.clear(); context.read().add( const CheckPhoneFormEvent.phoneNumberChanged(''), ); setState(() {}); } @override Widget build(BuildContext context) { return AppTextFormField( title: 'Masukkan no telepon', hintText: '8712671212', helperText: 'Harus diawali angka 8', controller: _controller, focusNode: _focusNode, keyboardType: TextInputType.phone, inputFormatters: [_PhoneAfterCountryCodeFormatter()], validator: (value) { final phoneNumber = context.read().state.phoneNumber; if (phoneNumber.isEmpty) { return 'Masukkan no telepon'; } if (!phoneNumber.startsWith('8')) { return 'No telepon harus diawali angka 8'; } return null; }, prefixIcon: Padding( padding: const EdgeInsets.symmetric(horizontal: 12), child: Text( '+62', style: AppStyle.md.copyWith( color: AppColor.textPrimary, fontWeight: FontWeight.w500, ), ), ), suffixIcon: (_hasFocus && _controller.text.isNotEmpty) ? IconButton( onPressed: _clearText, icon: Icon(Icons.close, color: AppColor.primary, size: 20), constraints: const BoxConstraints(), padding: const EdgeInsets.all(8), ) : null, onChanged: (value) { context.read().add( CheckPhoneFormEvent.phoneNumberChanged(value), ); }, ); } } /// Prefix +62 sudah tampil di field, jadi input harus langsung diawali 8. /// Ketikan `0`/`6` di awal ditolak; tempelan `08…`, `62…`, atau `+62…` /// dirapikan jadi `8…`. class _PhoneAfterCountryCodeFormatter extends TextInputFormatter { @override TextEditingValue formatEditUpdate( TextEditingValue oldValue, TextEditingValue newValue, ) { var digits = newValue.text.replaceAll(RegExp(r'\D'), ''); if (digits.startsWith('62')) digits = digits.substring(2); digits = digits.replaceFirst(RegExp(r'^0+'), ''); if (digits.isEmpty) return const TextEditingValue(); if (!digits.startsWith('8')) return oldValue; if (digits == newValue.text) return newValue; return TextEditingValue( text: digits, selection: TextSelection.collapsed(offset: digits.length), ); } }