From 919f461125d4c3d6294f4ad0e57aa1fe0989ed9c Mon Sep 17 00:00:00 2001 From: Jacques Date: Wed, 21 Feb 2024 11:14:47 +0100 Subject: [PATCH 1/2] fix: Proper saving of value and more customization --- example/pubspec.lock | 2 +- lib/src/inputs/inputs.dart | 1 + lib/src/inputs/phone/phone.dart | 119 ++++++++++--------- lib/src/inputs/phone/phone_number_model.dart | 9 ++ pubspec.yaml | 2 +- 5 files changed, 78 insertions(+), 55 deletions(-) create mode 100644 lib/src/inputs/phone/phone_number_model.dart diff --git a/example/pubspec.lock b/example/pubspec.lock index a44fe71..7ef7265 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -68,7 +68,7 @@ packages: path: ".." relative: true source: path - version: "3.1.0" + version: "3.2.0" flutter_lints: dependency: "direct dev" description: diff --git a/lib/src/inputs/inputs.dart b/lib/src/inputs/inputs.dart index bcaa357..d0825a7 100644 --- a/lib/src/inputs/inputs.dart +++ b/lib/src/inputs/inputs.dart @@ -4,6 +4,7 @@ export 'date_picker/date_picker.dart'; export 'number_picker/number_picker.dart'; export 'phone/countries.dart'; export 'phone/phone.dart'; +export 'phone/phone_number_model.dart'; export 'scroll_picker/scroll_picker.dart'; export 'slider/slider.dart'; export 'text/password.dart'; diff --git a/lib/src/inputs/phone/phone.dart b/lib/src/inputs/phone/phone.dart index 794985d..418e4d5 100644 --- a/lib/src/inputs/phone/phone.dart +++ b/lib/src/inputs/phone/phone.dart @@ -17,25 +17,29 @@ class FlutterFormInputPhone extends StatefulWidget { this.onSaved, this.validator, this.onFieldSubmitted, - this.style, + this.numberFieldStyle, + this.dialCodeSelectorStyle, this.enabled = true, this.priorityCountries = const ['NL', 'BE', 'LU'], - this.countrySelectorUnderline, - this.countrySelectorWidth = 100, + this.dialCodeSelectorUnderline, + this.dialCodeSelectorWidth = 100, + this.dialCodeWrapper, }); final InputDecoration? decoration; final Widget? label; - final String? initialValue; - final Function(String?)? onSaved; - final String? Function(String?)? validator; - final Function(String?)? onChanged; - final Function(String?)? onFieldSubmitted; - final TextStyle? style; + final PhoneNumber? initialValue; + final Function(PhoneNumber?)? onSaved; + final String? Function(PhoneNumber?)? validator; + final Function(PhoneNumber?)? onChanged; + final Function(PhoneNumber?)? onFieldSubmitted; + final TextStyle? numberFieldStyle; + final TextStyle? dialCodeSelectorStyle; final bool enabled; final List? priorityCountries; - final Widget? countrySelectorUnderline; - final double countrySelectorWidth; + final Widget? dialCodeSelectorUnderline; + final double dialCodeSelectorWidth; + final Widget Function(Widget child)? dialCodeWrapper; @override State createState() => _FlutterFormInputPhoneState(); @@ -70,7 +74,10 @@ class _FlutterFormInputPhoneState extends State { } } - _selectedCountry = _countryList.first; + _selectedCountry = _countryList.firstWhereOrNull( + (country) => widget.initialValue?.dialCode == country.dialCode, + ) ?? + _countryList.first; } @override @@ -80,57 +87,63 @@ class _FlutterFormInputPhoneState extends State { label: widget.label ?? const Text('Phone number'), ); + var dropDownButton = DropdownButton( + value: _selectedCountry, + style: widget.dialCodeSelectorStyle, + underline: widget.dialCodeSelectorUnderline, + items: [ + for (var country in _countryList) ...[ + DropdownMenuItem( + value: country, + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Text(country.flag), + const SizedBox( + width: 4, + ), + Text('+${country.dialCode}'), + ], + ), + ), + ], + ], + onChanged: (value) { + if (value != null) { + setState(() { + _selectedCountry = value; + }); + } + }, + ); + return Row( children: [ Container( padding: const EdgeInsets.only(top: 16), - width: widget.countrySelectorWidth, - child: DropdownButton( - value: _selectedCountry, - style: widget.style, - underline: widget.countrySelectorUnderline, - items: [ - for (var country in _countryList) ...[ - DropdownMenuItem( - value: country, - child: Row( - mainAxisSize: MainAxisSize.min, - children: [ - Text(country.flag), - const SizedBox( - width: 4, - ), - Text('+${country.dialCode}'), - ], - ), - ), - ], - ], - onChanged: (value) { - if (value != null) { - setState(() { - _selectedCountry = value; - }); - } - }, - ), + width: widget.dialCodeSelectorWidth, + child: widget.dialCodeWrapper?.call(dropDownButton) ?? dropDownButton, ), const SizedBox( width: 16, ), Expanded( child: FlutterFormInputPlainText( - style: widget.style, - initialValue: widget.initialValue, - onSaved: (value) => - widget.onSaved?.call('${_selectedCountry.dialCode}$value'), - validator: (value) => - widget.validator?.call('${_selectedCountry.dialCode}$value'), - onChanged: (value) => - widget.onChanged?.call('${_selectedCountry.dialCode}$value'), - onFieldSubmitted: (value) => widget.onFieldSubmitted - ?.call('${_selectedCountry.dialCode}$value'), - decoration: inputDecoration.copyWith(), + style: widget.numberFieldStyle, + initialValue: widget.initialValue?.number, + onSaved: (value) => widget.onSaved?.call( + PhoneNumber(dialCode: _selectedCountry.dialCode, number: value), + ), + validator: (value) => widget.validator?.call( + PhoneNumber(dialCode: _selectedCountry.dialCode, number: value), + ), + onChanged: (value) => widget.onChanged?.call( + PhoneNumber(dialCode: _selectedCountry.dialCode, number: value), + ), + onFieldSubmitted: (value) => widget.onFieldSubmitted?.call( + PhoneNumber(dialCode: _selectedCountry.dialCode, number: value), + ), + decoration: inputDecoration, keyboardType: TextInputType.phone, enabled: widget.enabled, ), diff --git a/lib/src/inputs/phone/phone_number_model.dart b/lib/src/inputs/phone/phone_number_model.dart new file mode 100644 index 0000000..25f0d15 --- /dev/null +++ b/lib/src/inputs/phone/phone_number_model.dart @@ -0,0 +1,9 @@ +class PhoneNumber { + PhoneNumber({ + this.dialCode, + this.number, + }); + + final String? dialCode; + final String? number; +} diff --git a/pubspec.yaml b/pubspec.yaml index a1e4e90..8fb418a 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -4,7 +4,7 @@ version: 3.2.0 repository: https://github.com/Iconica-Development/flutter_input_library environment: - sdk: ">=2.18.2 <3.0.0" + sdk: ^3.0.0 flutter: ">=1.17.0" dependencies: From 8e8fe01467043bc0082c04edc89e5a1e47764736 Mon Sep 17 00:00:00 2001 From: Jacques Date: Wed, 21 Feb 2024 13:55:02 +0100 Subject: [PATCH 2/2] fix: Chang dial code selector to prefix icon --- CHANGELOG.md | 4 + lib/src/inputs/bool/bool_field.dart | 2 - .../inputs/date_picker/date_picker_field.dart | 6 +- lib/src/inputs/phone/phone.dart | 120 ++++++++---------- lib/src/inputs/phone/phone_number_model.dart | 2 +- pubspec.yaml | 2 +- 6 files changed, 65 insertions(+), 71 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 21809c7..b2da3ff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -72,3 +72,7 @@ ## 3.2.0 * Added `FlutterFormInputPhone` + +## 3.2.1 +* Added `PhoneNumber` model to save the `FlutterFormInputPhone` result. +* Added more customization for `FlutterFormInputPhone`. diff --git a/lib/src/inputs/bool/bool_field.dart b/lib/src/inputs/bool/bool_field.dart index e0eaa3e..79acd7c 100644 --- a/lib/src/inputs/bool/bool_field.dart +++ b/lib/src/inputs/bool/bool_field.dart @@ -85,7 +85,6 @@ class _BoolWidgetState extends State { focusNode: widget.focusNode, onChanged: onChanged, ); - break; case BoolWidgetType.checkbox: child = Checkbox( @@ -97,7 +96,6 @@ class _BoolWidgetState extends State { } }, ); - break; } return Column( diff --git a/lib/src/inputs/date_picker/date_picker_field.dart b/lib/src/inputs/date_picker/date_picker_field.dart index b614d8e..576fe35 100644 --- a/lib/src/inputs/date_picker/date_picker_field.dart +++ b/lib/src/inputs/date_picker/date_picker_field.dart @@ -107,7 +107,7 @@ class _DateInputFieldState extends State { userInput = unformatted != null ? widget.dateFormat.format(unformatted) : userInput; - break; + case FlutterFormDateTimeType.dateTime: await getInputFromUser(FlutterFormDateTimeType.date) .then((value) async { @@ -132,7 +132,7 @@ class _DateInputFieldState extends State { } } }); - break; + case FlutterFormDateTimeType.range: if (context.mounted) { userInput = await showDateRangePicker( @@ -147,7 +147,7 @@ class _DateInputFieldState extends State { : '', ); } - break; + case FlutterFormDateTimeType.time: if (context.mounted) { userInput = await showTimePicker( diff --git a/lib/src/inputs/phone/phone.dart b/lib/src/inputs/phone/phone.dart index 418e4d5..a2c2f68 100644 --- a/lib/src/inputs/phone/phone.dart +++ b/lib/src/inputs/phone/phone.dart @@ -21,9 +21,8 @@ class FlutterFormInputPhone extends StatefulWidget { this.dialCodeSelectorStyle, this.enabled = true, this.priorityCountries = const ['NL', 'BE', 'LU'], - this.dialCodeSelectorUnderline, - this.dialCodeSelectorWidth = 100, - this.dialCodeWrapper, + this.textAlignVertical = TextAlignVertical.top, + this.dialCodeSelectorPadding = const EdgeInsets.only(top: 6), }); final InputDecoration? decoration; @@ -37,9 +36,8 @@ class FlutterFormInputPhone extends StatefulWidget { final TextStyle? dialCodeSelectorStyle; final bool enabled; final List? priorityCountries; - final Widget? dialCodeSelectorUnderline; - final double dialCodeSelectorWidth; - final Widget Function(Widget child)? dialCodeWrapper; + final EdgeInsets dialCodeSelectorPadding; + final TextAlignVertical textAlignVertical; @override State createState() => _FlutterFormInputPhoneState(); @@ -87,68 +85,62 @@ class _FlutterFormInputPhoneState extends State { label: widget.label ?? const Text('Phone number'), ); - var dropDownButton = DropdownButton( - value: _selectedCountry, - style: widget.dialCodeSelectorStyle, - underline: widget.dialCodeSelectorUnderline, - items: [ - for (var country in _countryList) ...[ - DropdownMenuItem( - value: country, - child: Row( - mainAxisSize: MainAxisSize.min, - children: [ - Text(country.flag), - const SizedBox( - width: 4, + return FlutterFormInputPlainText( + label: widget.label, + style: widget.numberFieldStyle, + initialValue: widget.initialValue?.number, + onSaved: (value) => widget.onSaved?.call( + PhoneNumber(dialCode: _selectedCountry.dialCode, number: value), + ), + validator: (value) => widget.validator?.call( + PhoneNumber(dialCode: _selectedCountry.dialCode, number: value), + ), + onChanged: (value) => widget.onChanged?.call( + PhoneNumber(dialCode: _selectedCountry.dialCode, number: value), + ), + onFieldSubmitted: (value) => widget.onFieldSubmitted?.call( + PhoneNumber(dialCode: _selectedCountry.dialCode, number: value), + ), + decoration: inputDecoration.copyWith( + contentPadding: EdgeInsets.zero, + prefixIcon: Padding( + padding: widget.dialCodeSelectorPadding, + child: DropdownButton( + padding: EdgeInsets.zero, + elevation: 0, + value: _selectedCountry, + style: widget.dialCodeSelectorStyle, + underline: const SizedBox.shrink(), + items: [ + for (var country in _countryList) ...[ + DropdownMenuItem( + value: country, + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Text(country.flag), + const SizedBox( + width: 4, + ), + Text('+${country.dialCode}'), + ], + ), ), - Text('+${country.dialCode}'), ], - ), - ), - ], - ], - onChanged: (value) { - if (value != null) { - setState(() { - _selectedCountry = value; - }); - } - }, - ); - - return Row( - children: [ - Container( - padding: const EdgeInsets.only(top: 16), - width: widget.dialCodeSelectorWidth, - child: widget.dialCodeWrapper?.call(dropDownButton) ?? dropDownButton, - ), - const SizedBox( - width: 16, - ), - Expanded( - child: FlutterFormInputPlainText( - style: widget.numberFieldStyle, - initialValue: widget.initialValue?.number, - onSaved: (value) => widget.onSaved?.call( - PhoneNumber(dialCode: _selectedCountry.dialCode, number: value), - ), - validator: (value) => widget.validator?.call( - PhoneNumber(dialCode: _selectedCountry.dialCode, number: value), - ), - onChanged: (value) => widget.onChanged?.call( - PhoneNumber(dialCode: _selectedCountry.dialCode, number: value), - ), - onFieldSubmitted: (value) => widget.onFieldSubmitted?.call( - PhoneNumber(dialCode: _selectedCountry.dialCode, number: value), - ), - decoration: inputDecoration, - keyboardType: TextInputType.phone, - enabled: widget.enabled, + ], + onChanged: (value) { + if (value != null) { + setState(() { + _selectedCountry = value; + }); + } + }, ), ), - ], + ), + keyboardType: TextInputType.phone, + enabled: widget.enabled, + textAlignVertical: widget.textAlignVertical, ); } } diff --git a/lib/src/inputs/phone/phone_number_model.dart b/lib/src/inputs/phone/phone_number_model.dart index 25f0d15..54ae16b 100644 --- a/lib/src/inputs/phone/phone_number_model.dart +++ b/lib/src/inputs/phone/phone_number_model.dart @@ -1,5 +1,5 @@ class PhoneNumber { - PhoneNumber({ + const PhoneNumber({ this.dialCode, this.number, }); diff --git a/pubspec.yaml b/pubspec.yaml index 8fb418a..fc64213 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_input_library description: A new Flutter package project. -version: 3.2.0 +version: 3.2.1 repository: https://github.com/Iconica-Development/flutter_input_library environment: