Skip to content

Commit

Permalink
Merge branch 'main' of github.com:cedvdb/phone_form_field
Browse files Browse the repository at this point in the history
  • Loading branch information
cedvdb committed May 21, 2024
2 parents dfc2648 + 584baba commit ec7f403
Show file tree
Hide file tree
Showing 17 changed files with 301 additions and 213 deletions.
20 changes: 17 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,24 @@
## [9.1.2]
## [9.2.4]
- upgrade metadata
- Do not preload flags by default anymore. Use [PhoneFormField.preloadFlags()] to preload flags

## [9.1.1]
## [9.2.3]
- upgrade flutter country selector dependency

## [9.2.2]
- added language selection to demo
- fixed a bug where country selection language

## [9.2.1]
- fix readme

## [9.2.0]
- add missing translation messages
- add Hungarian localization messages
- fix RTL
- added `showDropdownIndicator`
- [deprecate] country button stylings properties in favor of one `countryButtonStyle` property
- add showDropdownIcon bool

## [9.1.0]

Expand Down Expand Up @@ -37,7 +51,7 @@
- Added some missing countries
- [Breaking] : no validation done by default
- [Breaking] : provided validators now require a context parameter
- [Breaking] : `LocalizedCountryRegistry` removed. If you were using it to localize a country name, you should use `PhoneFieldLocalization.of(context).countryName(isoCode)`.
- [Breaking] : `LocalizedCountryRegistry` removed. If you were using it to localize a country name, you should use `CountrySelectorLocalization.of(context).countryName(isoCode)`.
- [Deprecated] : `isCountryChipPersistent` in favor of `isCountryButtonPersistent`.
- [Deprecated] : `shouldFormat`, it is now always ON by default
- [Deprecated] : `defaultCountry`, you should now use either `initialValue` or provide a controller with an initial value.
Expand Down
15 changes: 8 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ Flutter phone input integrated with flutter internationalization
- Phone formatting localized by region
- Phone number validation (built-in validators included for main use cases)
- Support auto fill and copy paste
- Form field
- Uses dart phone_numbers_parser for parsing
- Form field

## Demo

Expand All @@ -33,13 +33,15 @@ PhoneFormField(
countrySelectorNavigator: const CountrySelectorNavigator.page(),
onChanged: (phoneNumber) => print('changed into $phoneNumber'),
enabled: true,
countryButtonPadding: null,
isCountrySelectionEnabled: true,
isCountryButtonPersistent: true,
showDialCode: true,
showIsoCodeInInput: true,
showFlagInInput: true,
flagSize: 16
countryButtonStyle: const CountryButtonStyle(
showDialCode: true,
showIsoCode: true,
showFlag: true,
flagSize: 16
),
// + all parameters of TextField
// + all parameters of FormField
// ...
Expand Down Expand Up @@ -185,7 +187,6 @@ This package uses the `flutter_country_selector` package under the hood, which e
- hi
- hu
- it
- ku
- nb
- nl
- pt
Expand Down
Binary file modified demo.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
141 changes: 92 additions & 49 deletions example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,40 @@ void main() {
// For a simpler example see the README

class PhoneFieldView extends StatelessWidget {
static const supportedLocales = [
Locale('ar'),
// not supported by material yet
// Locale('ckb'),
Locale('de'),
Locale('el'),
Locale('en'),
Locale('es'),
Locale('fa'),
Locale('fr'),
Locale('hi'),
Locale('hu'),
Locale('it'),
// not supported by material yet
// Locale('ku'),
Locale('nb'),
Locale('nl'),
Locale('pt'),
Locale('ru'),
Locale('sv'),
Locale('tr'),
Locale('uz'),
Locale('zh'),
// ...
];

final PhoneController controller;
final FocusNode focusNode;
final CountrySelectorNavigator selectorNavigator;
final bool withLabel;
final bool outlineBorder;
final bool isCountryButtonPersistant;
final bool mobileOnly;
final bool useRtl;
final Locale locale;

const PhoneFieldView({
Key? key,
Expand All @@ -28,7 +54,7 @@ class PhoneFieldView extends StatelessWidget {
required this.outlineBorder,
required this.isCountryButtonPersistant,
required this.mobileOnly,
required this.useRtl,
required this.locale,
}) : super(key: key);

PhoneNumberInputValidator? _getValidator(BuildContext context) {
Expand All @@ -44,32 +70,42 @@ class PhoneFieldView extends StatelessWidget {
@override
Widget build(BuildContext context) {
return AutofillGroup(
child: Directionality(
textDirection: useRtl ? TextDirection.rtl : TextDirection.ltr,
child: PhoneFormField(
focusNode: focusNode,
controller: controller,
isCountryButtonPersistent: isCountryButtonPersistant,
autofocus: false,
autofillHints: const [AutofillHints.telephoneNumber],
countrySelectorNavigator: selectorNavigator,
decoration: InputDecoration(
label: withLabel ? const Text('Phone') : null,
border: outlineBorder
? const OutlineInputBorder()
: const UnderlineInputBorder(),
hintText: withLabel ? '' : 'Phone',
),
enabled: true,
showIsoCodeInInput: false,
showFlagInInput: true,
validator: _getValidator(context),
autovalidateMode: AutovalidateMode.onUserInteraction,
cursorColor: Theme.of(context).colorScheme.primary,
// ignore: avoid_print
onSaved: (p) => print('saved $p'),
// ignore: avoid_print
onChanged: (p) => print('changed $p'),
child: Localizations.override(
context: context,
locale: locale,
child: Builder(
builder: (context) {
final label = PhoneFieldLocalization.of(context).phoneNumber;
return PhoneFormField(
focusNode: focusNode,
controller: controller,
isCountryButtonPersistent: isCountryButtonPersistant,
autofocus: false,
autofillHints: const [AutofillHints.telephoneNumber],
countrySelectorNavigator: selectorNavigator,
decoration: InputDecoration(
label: withLabel ? Text(label) : null,
border: outlineBorder
? const OutlineInputBorder()
: const UnderlineInputBorder(),
hintText: withLabel ? '' : label,
),
enabled: true,
countryButtonStyle: const CountryButtonStyle(
showFlag: true,
showIsoCode: false,
showDialCode: true,
showDropdownIcon: true,
),
validator: _getValidator(context),
autovalidateMode: AutovalidateMode.onUserInteraction,
cursorColor: Theme.of(context).colorScheme.primary,
// ignore: avoid_print
onSaved: (p) => print('saved $p'),
// ignore: avoid_print
onChanged: (p) => print('changed $p'),
);
},
),
),
);
Expand All @@ -83,19 +119,8 @@ class MyApp extends StatelessWidget {
Widget build(BuildContext context) {
return MaterialApp(
localizationsDelegates: PhoneFieldLocalization.delegates,
supportedLocales: const [
Locale('en', ''),
Locale('fr', ''),
Locale('es', ''),
Locale('el', ''),
Locale('de', ''),
Locale('it', ''),
Locale('ru', ''),
Locale('sv', ''),
Locale('tr', ''),
Locale('zh', ''),
// ...
],
supportedLocales: PhoneFieldView.supportedLocales,
locale: const Locale('en'),
title: 'Phone field demo',
theme: ThemeData(
brightness: Brightness.dark,
Expand All @@ -121,9 +146,9 @@ class PhoneFormFieldScreenState extends State<PhoneFormFieldScreen> {
bool mobileOnly = true;
bool isCountryButtonPersistent = true;
bool withLabel = true;
bool useRtl = false;
CountrySelectorNavigator selectorNavigator =
const CountrySelectorNavigator.page();
Locale locale = const Locale('en');
final formKey = GlobalKey<FormState>();

@override
Expand Down Expand Up @@ -175,12 +200,30 @@ class PhoneFormFieldScreenState extends State<PhoneFormFieldScreen> {
onChanged: (v) => setState(() => mobileOnly = v),
title: const Text('Mobile phone number only'),
),
SwitchListTile(
value: useRtl,
onChanged: (v) {
setState(() => useRtl = v);
},
title: const Text('RTL'),
ListTile(
title: Wrap(
alignment: WrapAlignment.spaceBetween,
crossAxisAlignment: WrapCrossAlignment.center,
children: [
const Text('Language: '),
DropdownButton<Locale>(
value: locale,
onChanged: (Locale? value) {
if (value != null) {
setState(() => locale = value);
}
},
items: [
for (final locale
in PhoneFieldView.supportedLocales)
DropdownMenuItem(
value: locale,
child: Text(locale.toLanguageTag()),
),
],
),
],
),
),
ListTile(
title: Wrap(
Expand Down Expand Up @@ -240,7 +283,7 @@ class PhoneFormFieldScreenState extends State<PhoneFormFieldScreen> {
isCountryButtonPersistant:
isCountryButtonPersistent,
mobileOnly: mobileOnly,
useRtl: useRtl,
locale: locale,
),
],
),
Expand Down
4 changes: 2 additions & 2 deletions example/macos/Flutter/ephemeral/Flutter-Generated.xcconfig
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// This is a generated file; do not edit or check into version control.
FLUTTER_ROOT=/Users/cedvdb/Development/flutter
FLUTTER_APPLICATION_PATH=/Users/cedvdb/Development/libs/country/phone_form_field/example
FLUTTER_ROOT=C:\dev\flutter
FLUTTER_APPLICATION_PATH=C:\Users\cedva\Documents\Dev\libraries\countries\phone_form_field\example
COCOAPODS_PARALLEL_CODE_SIGN=true
FLUTTER_BUILD_DIR=build
FLUTTER_BUILD_NAME=1.0.0
Expand Down
4 changes: 2 additions & 2 deletions example/macos/Flutter/ephemeral/flutter_export_environment.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/bin/sh
# This is a generated file; do not edit or check into version control.
export "FLUTTER_ROOT=/Users/cedvdb/Development/flutter"
export "FLUTTER_APPLICATION_PATH=/Users/cedvdb/Development/libs/country/phone_form_field/example"
export "FLUTTER_ROOT=C:\dev\flutter"
export "FLUTTER_APPLICATION_PATH=C:\Users\cedva\Documents\Dev\libraries\countries\phone_form_field\example"
export "COCOAPODS_PARALLEL_CODE_SIGN=true"
export "FLUTTER_BUILD_DIR=build"
export "FLUTTER_BUILD_NAME=1.0.0"
Expand Down
2 changes: 1 addition & 1 deletion example/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ packages:
path: ".."
relative: true
source: path
version: "9.1.2"
version: "9.2.4"
phone_numbers_parser:
dependency: transitive
description:
Expand Down
10 changes: 5 additions & 5 deletions l10n/ku.arb
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"@@locale": "ku",
"invalidPhoneNumber": "ژمارەی تەلەفۆنی نادروست",
"invalidCountry": "وڵاتێکی نادروست",
"invalidMobilePhoneNumber": "ژمارەی مۆبایل نادروستە",
"invalidFixedLinePhoneNumber": "ژمارەی تەلەفۆنی هێڵی جێگیر نادروستە",
"requiredPhoneNumber": "ژمارەی تەلەفۆنی پێویست",
"invalidPhoneNumber": "Hejmara têlefonê nederbasdar e",
"invalidCountry": "Welatê nederbasdar",
"invalidMobilePhoneNumber": "Hejmara têlefona desta nederbasdar e",
"invalidFixedLinePhoneNumber": "Hejmara têlefonê ya xeta sabît nederbasdar e",
"requiredPhoneNumber": "Hejmara têlefonê ya pêwîst",
"selectACountrySemanticLabel": "Welatek hilbijêre, bijartina niha: {countryName} {dialCode}",
"@selectACountrySemanticLabel": {
"description": "semantic description of the country button",
Expand Down
1 change: 1 addition & 0 deletions lib/phone_form_field.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ library phone_number_input;
export 'src/phone_form_field.dart';
export 'src/country_selector_navigator.dart';
export 'src/country_button.dart';
export 'src/country_button_style.dart';

export 'src/validation/phone_validator.dart';
export 'src/localization/localization.dart';
Expand Down
18 changes: 9 additions & 9 deletions lib/src/country_button.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,33 +8,33 @@ typedef CountryChip = CountryButton;
class CountryButton extends StatelessWidget {
final Function()? onTap;
final IsoCode isoCode;
final bool showFlag;
final bool showDialCode;
final TextStyle? textStyle;
final EdgeInsets padding;
final double flagSize;
final TextDirection? textDirection;
final bool showFlag;
final bool showDialCode;
final bool showIsoCode;
final bool showDropdownIcon;
final bool enabled;

const CountryButton({
super.key,
required this.isoCode,
required this.onTap,
this.textStyle,
this.showFlag = true,
this.showDialCode = true,
this.padding = const EdgeInsets.fromLTRB(12, 16, 4, 16),
this.flagSize = 20,
this.textDirection,
this.showFlag = true,
this.showDialCode = true,
this.showIsoCode = false,
this.showDropdownIcon = true,
this.enabled = true,
});

@override
Widget build(BuildContext context) {
final textStyle = this.textStyle ??
Theme.of(context).textTheme.labelMedium ??
Theme.of(context).textTheme.bodyMedium?.copyWith(fontSize: 16) ??
const TextStyle();
final countryLocalization = CountrySelectorLocalization.of(context) ??
CountrySelectorLocalizationEn();
Expand Down Expand Up @@ -71,10 +71,10 @@ class CountryButton extends StatelessWidget {
style: textStyle.copyWith(
color: enabled ? null : Theme.of(context).disabledColor,
),
textDirection: textDirection,
),
],
const ExcludeSemantics(child: Icon(Icons.arrow_drop_down)),
if (showDropdownIcon)
const ExcludeSemantics(child: Icon(Icons.arrow_drop_down)),
],
),
),
Expand Down
Loading

0 comments on commit ec7f403

Please sign in to comment.