@@ -5,25 +5,27 @@ import 'package:flutter/services.dart';
5
5
6
6
import '../../../zeta_flutter.dart' ;
7
7
8
+ import '../../interfaces/form_field.dart' ;
8
9
import '../text_input/hint_text.dart' ;
9
10
import '../text_input/input_label.dart' ;
10
11
import '../text_input/text_input.dart' ;
11
12
import 'countries.dart' ;
12
13
13
14
/// ZetaPhoneInput allows entering phone numbers.
14
- class ZetaPhoneInput extends ZetaStatefulWidget {
15
+ class ZetaPhoneInput extends ZetaFormField < String > {
15
16
/// Constructor for [ZetaPhoneInput] .
16
17
const ZetaPhoneInput ({
17
18
super .key,
18
19
super .rounded,
20
+ super .initialValue,
21
+ super .onChange,
22
+ super .requirementLevel = ZetaFormFieldRequirement .none,
19
23
this .label,
20
24
this .hintText,
21
- this .disabled = false ,
25
+ super .disabled = false ,
22
26
this .hasError = false ,
23
27
this .errorText,
24
- this .onChanged,
25
- this .countryDialCode,
26
- this .phoneNumber,
28
+ this .initialCountry,
27
29
this .countries,
28
30
this .countrySearchHint,
29
31
this .size = ZetaWidgetSize .medium,
@@ -35,9 +37,6 @@ class ZetaPhoneInput extends ZetaStatefulWidget {
35
37
/// If provided, displays a hint below the input field.
36
38
final String ? hintText;
37
39
38
- /// Determines if the inputs should be enabled (default) or disabled.
39
- final bool disabled;
40
-
41
40
/// Determines if the input field should be displayed in error style.
42
41
/// Default is `false` .
43
42
/// If `enabled` is `false` , this has no effect.
@@ -47,14 +46,8 @@ class ZetaPhoneInput extends ZetaStatefulWidget {
47
46
/// to be displayed below the input field.
48
47
final String ? errorText;
49
48
50
- /// A callback, which provides the entered phone number.
51
- final void Function (Map <String , String >? )? onChanged;
52
-
53
- /// The initial value for the country dial code including leading +
54
- final String ? countryDialCode;
55
-
56
- /// The initial value for the phone number
57
- final String ? phoneNumber;
49
+ /// The initial value for the selected country.
50
+ final String ? initialCountry;
58
51
59
52
/// List of countries ISO 3166-1 alpha-2 codes
60
53
final List <String >? countries;
@@ -63,6 +56,9 @@ class ZetaPhoneInput extends ZetaStatefulWidget {
63
56
/// Default is `Search by name or dial code` .
64
57
final String ? countrySearchHint;
65
58
59
+ /// The size of the input.
60
+ ///
61
+ /// Setting this to small will have no effect.
66
62
final ZetaWidgetSize size;
67
63
68
64
@override
@@ -77,11 +73,10 @@ class ZetaPhoneInput extends ZetaStatefulWidget {
77
73
..add (DiagnosticsProperty <bool >('rounded' , rounded))
78
74
..add (DiagnosticsProperty <bool >('hasError' , hasError))
79
75
..add (StringProperty ('errorText' , errorText))
80
- ..add (ObjectFlagProperty <void Function (Map <String , String >? p1)?>.has ('onChanged' , onChanged))
81
- ..add (StringProperty ('countryDialCode' , countryDialCode))
82
- ..add (StringProperty ('phoneNumber' , phoneNumber))
76
+ ..add (StringProperty ('countryDialCode' , initialCountry))
83
77
..add (IterableProperty <String >('countries' , countries))
84
- ..add (StringProperty ('countrySearchHint' , countrySearchHint));
78
+ ..add (StringProperty ('countrySearchHint' , countrySearchHint))
79
+ ..add (EnumProperty <ZetaWidgetSize >('size' , size));
85
80
}
86
81
}
87
82
@@ -91,11 +86,31 @@ class _ZetaPhoneInputState extends State<ZetaPhoneInput> {
91
86
late Country _selectedCountry;
92
87
late String _phoneNumber;
93
88
94
- final FocusNode inputFocusNode = FocusNode ();
89
+ final FocusNode _inputFocusNode = FocusNode ();
90
+
91
+ ZetaWidgetSize get _size => widget.size == ZetaWidgetSize .small ? ZetaWidgetSize .medium : widget.size;
95
92
96
93
@override
97
94
void initState () {
98
95
super .initState ();
96
+ _setCountries ();
97
+ _setInitialCountry ();
98
+ _setDropdownItems ();
99
+ }
100
+
101
+ @override
102
+ void didUpdateWidget (ZetaPhoneInput oldWidget) {
103
+ if (oldWidget.countries != widget.countries) {
104
+ _setCountries ();
105
+ setState (_setDropdownItems);
106
+ }
107
+ if (oldWidget.initialCountry != widget.initialCountry) {
108
+ setState (_setInitialCountry);
109
+ }
110
+ super .didUpdateWidget (oldWidget);
111
+ }
112
+
113
+ void _setCountries () {
99
114
_countries = widget.countries? .isEmpty ?? true
100
115
? Countries .list
101
116
: Countries .list.where ((country) => widget.countries! .contains (country.isoCode)).toList ();
@@ -107,21 +122,14 @@ class _ZetaPhoneInputState extends State<ZetaPhoneInput> {
107
122
);
108
123
}
109
124
if (_countries.isEmpty) _countries = Countries .list;
125
+ }
126
+
127
+ void _setInitialCountry () {
110
128
_selectedCountry = _countries.firstWhereOrNull (
111
- (country) => country.dialCode == widget.countryDialCode ,
129
+ (country) => country.isoCode == widget.initialCountry ,
112
130
) ??
113
131
_countries.first;
114
- _phoneNumber = widget.phoneNumber ?? '' ;
115
-
116
- _setDropdownItems ();
117
- }
118
-
119
- @override
120
- void didUpdateWidget (ZetaPhoneInput oldWidget) {
121
- if (oldWidget.countries != widget.countries) {
122
- setState (_setDropdownItems);
123
- }
124
- super .didUpdateWidget (oldWidget);
132
+ _phoneNumber = widget.initialValue ?? '' ;
125
133
}
126
134
127
135
void _setDropdownItems () {
@@ -147,14 +155,7 @@ class _ZetaPhoneInputState extends State<ZetaPhoneInput> {
147
155
if (selectedCountry != null ) _selectedCountry = selectedCountry;
148
156
if (phoneNumber != null ) _phoneNumber = phoneNumber;
149
157
});
150
- widget.onChanged? .call (
151
- _phoneNumber.isEmpty
152
- ? {}
153
- : {
154
- 'countryDialCode' : _selectedCountry.dialCode,
155
- 'phoneNumber' : _phoneNumber,
156
- },
157
- );
158
+ widget.onChange? .call ('${_selectedCountry .dialCode }$_phoneNumber ' );
158
159
}
159
160
160
161
@override
@@ -167,7 +168,7 @@ class _ZetaPhoneInputState extends State<ZetaPhoneInput> {
167
168
if (widget.label != null ) ...[
168
169
ZetaInputLabel (
169
170
label: widget.label! ,
170
- requirementLevel: ZetaFormFieldRequirement .none, //TODO implement form field
171
+ requirementLevel: widget.requirementLevel,
171
172
disabled: widget.disabled,
172
173
),
173
174
const SizedBox (height: ZetaSpacing .minimum),
@@ -181,7 +182,7 @@ class _ZetaPhoneInputState extends State<ZetaPhoneInput> {
181
182
setState (() {
182
183
_selectedCountry = _countries.firstWhere ((country) => country.dialCode == value.value);
183
184
});
184
- inputFocusNode .requestFocus ();
185
+ _inputFocusNode .requestFocus ();
185
186
}
186
187
: null ,
187
188
value: _selectedCountry.dialCode,
@@ -240,11 +241,13 @@ class _ZetaPhoneInputState extends State<ZetaPhoneInput> {
240
241
),
241
242
Expanded (
242
243
child: textInputWithBorder (
243
- initialValue: widget.phoneNumber ,
244
+ initialValue: widget.initialValue ,
244
245
disabled: widget.disabled,
245
- size: widget.size,
246
+ size: _size,
247
+ requirementLevel: widget.requirementLevel,
246
248
rounded: rounded,
247
- focusNode: inputFocusNode,
249
+ focusNode: _inputFocusNode,
250
+ errorText: widget.errorText != null ? '' : null ,
248
251
inputFormatters: [FilteringTextInputFormatter .allow (RegExp (r'[\d\s\-]' ))],
249
252
keyboardType: TextInputType .phone,
250
253
onChange: (value) => _onChanged (phoneNumber: value),
0 commit comments