28
CHANGELOG.md
28
CHANGELOG.md
@@ -1,3 +1,31 @@
|
||||
## 1.3.12+1
|
||||
|
||||
- Fix Cayman Islands code
|
||||
|
||||
## 1.3.12
|
||||
|
||||
- Allow to edit dialog textStyle
|
||||
|
||||
## 1.3.11
|
||||
|
||||
- Fix initialization
|
||||
|
||||
## 1.3.9
|
||||
|
||||
- Add hideSearch property
|
||||
|
||||
- Add spanish support
|
||||
|
||||
## 1.3.8
|
||||
|
||||
- Expose state to let use a key to open the dialog
|
||||
|
||||
- Add dialog size config
|
||||
|
||||
- Remove customList and fix countryFilter
|
||||
|
||||
- Fix filtering with localization
|
||||
|
||||
## 1.3.7
|
||||
|
||||
- Add `customList` property
|
||||
|
||||
33
README.md
33
README.md
@@ -55,7 +55,8 @@ Just add the `CountryLocalizations.delegate` in the list of your app delegates
|
||||
supportedLocales: [
|
||||
Locale('en'),
|
||||
Locale('it'),
|
||||
Locale('en'),
|
||||
Locale('fr'),
|
||||
Locale('es'),
|
||||
],
|
||||
localizationsDelegates: [
|
||||
CountryLocalizations.delegate,
|
||||
@@ -64,6 +65,36 @@ Just add the `CountryLocalizations.delegate` in the list of your app delegates
|
||||
],
|
||||
```
|
||||
|
||||
## Customization
|
||||
|
||||
Here is a list of properties available to customize your widget:
|
||||
|
||||
| Name | Type | Description |
|
||||
|-----|-----|------|
|
||||
|onChanged| ValueChanged<CountryCode> | callback invoked when the selection changes |
|
||||
|onInit| ValueChanged<CountryCode> | callback invoked during initialization of the widget |
|
||||
|initialSelection| String | used to set the initial selected value |
|
||||
|favorite| List<String> | used to populate the favorite country list |
|
||||
|textStyle| TextStyle | TextStyle applied to the widget button |
|
||||
|padding| EdgeInsetsGeometry | the padding applied to the button |
|
||||
|showCountryOnly| bool | true if you want to see only the countries in the selection dialog |
|
||||
|searchDecoration| InputDecoration | decoration applied to the TextField search widget |
|
||||
|searchStyle| TextStyle | style applied to the TextField search widget text |
|
||||
|emptySearchBuilder| WidgetBuilder | use this to customize the widget used when the search returns 0 elements |
|
||||
|builder| Function(CountryCode) | use this to build a custom widget instead of the default FlatButton |
|
||||
|enabled| bool | set to false to disable the widget |
|
||||
|textOverflow| TextOverflow | the button text overflow behaviour |
|
||||
|dialogSize| Size | the size of the selection dialog |
|
||||
|countryFilter| List<String> | uses a list of strings to filter a sublist of countries |
|
||||
|showOnlyCountryWhenClosed| bool | if true it'll show only the country |
|
||||
|alignLeft| bool | aligns the flag and the Text to the left |
|
||||
|showFlag| bool | shows the flag everywhere |
|
||||
|showFlagMain| bool | shows the flag only when closed |
|
||||
|showFlagDialog| bool | shows the flag only in dialog |
|
||||
|flagWidth| double | the width of the flags |
|
||||
|comparator| Comparator<CountryCode> | use this to sort the countries in the selection dialog |
|
||||
|hideSearch| bool | if true the search feature will be disabled |
|
||||
|
||||
## Contributions
|
||||
|
||||
Contributions of any kind are more than welcome! Feel free to fork and improve country_code_picker in any way you want, make a pull request, or open an issue.
|
||||
|
||||
@@ -11,18 +11,14 @@ class MyApp extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _MyAppState extends State<MyApp> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return new MaterialApp(
|
||||
supportedLocales: [
|
||||
Locale('en'),
|
||||
Locale('it'),
|
||||
Locale('en'),
|
||||
Locale('fr'),
|
||||
Locale('es'),
|
||||
],
|
||||
localizationsDelegates: [
|
||||
CountryLocalizations.delegate,
|
||||
@@ -43,11 +39,12 @@ class _MyAppState extends State<MyApp> {
|
||||
initialSelection: 'IT',
|
||||
favorite: ['+39', 'FR'],
|
||||
showFlag: false,
|
||||
customList: ['IT', 'FR'],
|
||||
countryFilter: ['IT', 'FR'],
|
||||
showFlagDialog: true,
|
||||
comparator: (a, b) => b.name.compareTo(a.name),
|
||||
//Get the country information relevant to the initial selection
|
||||
onInit: (code) => print("${code.name} ${code.dialCode}"),
|
||||
onInit: (code) =>
|
||||
print("on init ${code.name} ${code.dialCode}"),
|
||||
),
|
||||
SizedBox(
|
||||
width: 400,
|
||||
@@ -57,6 +54,7 @@ class _MyAppState extends State<MyApp> {
|
||||
child: CountryCodePicker(
|
||||
onChanged: print,
|
||||
initialSelection: 'TF',
|
||||
hideSearch: true,
|
||||
showCountryOnly: true,
|
||||
showOnlyCountryWhenClosed: true,
|
||||
alignLeft: true,
|
||||
@@ -72,7 +70,7 @@ class _MyAppState extends State<MyApp> {
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: CountryCodePicker(
|
||||
onChanged: print,
|
||||
onChanged: (e) => print(e.toLongString()),
|
||||
initialSelection: 'TF',
|
||||
showCountryOnly: true,
|
||||
showOnlyCountryWhenClosed: true,
|
||||
|
||||
@@ -59,13 +59,9 @@ class CountryCode {
|
||||
@override
|
||||
String toString() => "$dialCode";
|
||||
|
||||
String toLongString([BuildContext context]) =>
|
||||
"$dialCode ${toCountryStringOnly(context)}";
|
||||
String toLongString() => "$dialCode ${toCountryStringOnly()}";
|
||||
|
||||
String toCountryStringOnly([BuildContext context]) {
|
||||
if (context != null) {
|
||||
return CountryLocalizations.of(context)?.translate(code) ?? name;
|
||||
}
|
||||
String toCountryStringOnly() {
|
||||
return '$name';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,13 +17,17 @@ class CountryCodePicker extends StatefulWidget {
|
||||
final bool showCountryOnly;
|
||||
final InputDecoration searchDecoration;
|
||||
final TextStyle searchStyle;
|
||||
final TextStyle dialogTextStyle;
|
||||
final WidgetBuilder emptySearchBuilder;
|
||||
final Function(CountryCode) builder;
|
||||
final bool enabled;
|
||||
final TextOverflow textOverflow;
|
||||
|
||||
/// the size of the selection dialog
|
||||
final Size dialogSize;
|
||||
|
||||
/// used to customize the country list
|
||||
final List<String> customList;
|
||||
final List<String> countryFilter;
|
||||
|
||||
/// shows the name of the country instead of the dialcode
|
||||
final bool showOnlyCountryWhenClosed;
|
||||
@@ -42,26 +46,26 @@ class CountryCodePicker extends StatefulWidget {
|
||||
|
||||
final bool showFlagDialog;
|
||||
|
||||
/// contains the country codes to load only the specified countries.
|
||||
final List<String> countryFilter;
|
||||
|
||||
/// Width of the flag images
|
||||
final double flagWidth;
|
||||
|
||||
/// Use this property to change the order of the options
|
||||
final Comparator<CountryCode> comparator;
|
||||
|
||||
/// Set to true if you want to hide the search part
|
||||
final bool hideSearch;
|
||||
|
||||
CountryCodePicker({
|
||||
this.onChanged,
|
||||
this.onInit,
|
||||
this.initialSelection,
|
||||
this.favorite = const [],
|
||||
this.countryFilter = const [],
|
||||
this.textStyle,
|
||||
this.padding = const EdgeInsets.all(0.0),
|
||||
this.showCountryOnly = false,
|
||||
this.searchDecoration = const InputDecoration(),
|
||||
this.searchStyle,
|
||||
this.dialogTextStyle,
|
||||
this.emptySearchBuilder,
|
||||
this.showOnlyCountryWhenClosed = false,
|
||||
this.alignLeft = false,
|
||||
@@ -73,8 +77,11 @@ class CountryCodePicker extends StatefulWidget {
|
||||
this.enabled = true,
|
||||
this.textOverflow = TextOverflow.ellipsis,
|
||||
this.comparator,
|
||||
this.customList,
|
||||
});
|
||||
this.countryFilter,
|
||||
this.hideSearch = false,
|
||||
this.dialogSize,
|
||||
Key key,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() {
|
||||
@@ -87,42 +94,40 @@ class CountryCodePicker extends StatefulWidget {
|
||||
elements.sort(comparator);
|
||||
}
|
||||
|
||||
if (customList != null) {
|
||||
if (countryFilter != null && countryFilter.isNotEmpty) {
|
||||
final uppercaseCustomList =
|
||||
countryFilter.map((c) => c.toUpperCase()).toList();
|
||||
elements = elements
|
||||
.where((c) =>
|
||||
customList.contains(c.code) ||
|
||||
customList.contains(c.name) ||
|
||||
customList.contains(c.dialCode))
|
||||
uppercaseCustomList.contains(c.code) ||
|
||||
uppercaseCustomList.contains(c.name) ||
|
||||
uppercaseCustomList.contains(c.dialCode))
|
||||
.toList();
|
||||
}
|
||||
|
||||
if (countryFilter.length > 0) {
|
||||
elements = elements.where((c) => countryFilter.contains(c.code)).toList();
|
||||
}
|
||||
|
||||
return _CountryCodePickerState(elements);
|
||||
return CountryCodePickerState(elements);
|
||||
}
|
||||
}
|
||||
|
||||
class _CountryCodePickerState extends State<CountryCodePicker> {
|
||||
class CountryCodePickerState extends State<CountryCodePicker> {
|
||||
CountryCode selectedItem;
|
||||
List<CountryCode> elements = [];
|
||||
List<CountryCode> favoriteElements = [];
|
||||
|
||||
_CountryCodePickerState(this.elements);
|
||||
CountryCodePickerState(this.elements);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Widget _widget;
|
||||
if (widget.builder != null)
|
||||
_widget = InkWell(
|
||||
onTap: _showSelectionDialog,
|
||||
child: widget.builder(selectedItem.localize(context)),
|
||||
onTap: showCountryCodePickerDialog,
|
||||
child: widget.builder(selectedItem),
|
||||
);
|
||||
else {
|
||||
_widget = FlatButton(
|
||||
padding: widget.padding,
|
||||
onPressed: widget.enabled ? _showSelectionDialog : null,
|
||||
onPressed: widget.enabled ? showCountryCodePickerDialog : null,
|
||||
child: Flex(
|
||||
direction: Axis.horizontal,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
@@ -146,7 +151,7 @@ class _CountryCodePickerState extends State<CountryCodePicker> {
|
||||
fit: widget.alignLeft ? FlexFit.tight : FlexFit.loose,
|
||||
child: Text(
|
||||
widget.showOnlyCountryWhenClosed
|
||||
? selectedItem.toCountryStringOnly(context)
|
||||
? selectedItem.toCountryStringOnly()
|
||||
: selectedItem.toString(),
|
||||
style: widget.textStyle ?? Theme.of(context).textTheme.button,
|
||||
overflow: widget.textOverflow,
|
||||
@@ -159,49 +164,63 @@ class _CountryCodePickerState extends State<CountryCodePicker> {
|
||||
return _widget;
|
||||
}
|
||||
|
||||
@override
|
||||
void didChangeDependencies() {
|
||||
super.didChangeDependencies();
|
||||
|
||||
this.elements = elements.map((e) => e.localize(context)).toList();
|
||||
}
|
||||
|
||||
@override
|
||||
void didUpdateWidget(CountryCodePicker oldWidget) {
|
||||
super.didUpdateWidget(oldWidget);
|
||||
|
||||
_onInit(selectedItem);
|
||||
|
||||
if (oldWidget.initialSelection != widget.initialSelection) {
|
||||
if (widget.initialSelection != null) {
|
||||
selectedItem = elements.firstWhere(
|
||||
(e) =>
|
||||
(e.code.toUpperCase() ==
|
||||
widget.initialSelection.toUpperCase()) ||
|
||||
(e.dialCode == widget.initialSelection.toString()),
|
||||
(e.dialCode == widget.initialSelection) ||
|
||||
(e.name.toUpperCase() == widget.initialSelection.toUpperCase()),
|
||||
orElse: () => elements[0]);
|
||||
} else {
|
||||
selectedItem = elements[0];
|
||||
}
|
||||
_onInit(selectedItem);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
initState() {
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
if (widget.initialSelection != null) {
|
||||
selectedItem = elements.firstWhere(
|
||||
(e) =>
|
||||
(e.code.toUpperCase() == widget.initialSelection.toUpperCase()) ||
|
||||
(e.dialCode == widget.initialSelection.toString()),
|
||||
(e.dialCode == widget.initialSelection) ||
|
||||
(e.name.toUpperCase() == widget.initialSelection.toUpperCase()),
|
||||
orElse: () => elements[0]);
|
||||
} else {
|
||||
selectedItem = elements[0];
|
||||
}
|
||||
|
||||
_onInit(selectedItem);
|
||||
|
||||
favoriteElements = elements
|
||||
.where((e) =>
|
||||
widget.favorite.firstWhere(
|
||||
(f) => e.code == f.toUpperCase() || e.dialCode == f.toString(),
|
||||
(f) =>
|
||||
e.code.toUpperCase() == f.toUpperCase() ||
|
||||
e.dialCode == f ||
|
||||
e.name.toUpperCase() == f.toUpperCase(),
|
||||
orElse: () => null) !=
|
||||
null)
|
||||
.toList();
|
||||
super.initState();
|
||||
}
|
||||
|
||||
void _showSelectionDialog() {
|
||||
void showCountryCodePickerDialog() {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (_) => SelectionDialog(
|
||||
@@ -211,8 +230,11 @@ class _CountryCodePickerState extends State<CountryCodePicker> {
|
||||
emptySearchBuilder: widget.emptySearchBuilder,
|
||||
searchDecoration: widget.searchDecoration,
|
||||
searchStyle: widget.searchStyle,
|
||||
textStyle: widget.dialogTextStyle,
|
||||
showFlag: widget.showFlag || (widget.showFlagDialog == true),
|
||||
flagWidth: widget.flagWidth,
|
||||
size: widget.dialogSize,
|
||||
hideSearch: widget.hideSearch,
|
||||
),
|
||||
).then((e) {
|
||||
if (e != null) {
|
||||
@@ -227,13 +249,13 @@ class _CountryCodePickerState extends State<CountryCodePicker> {
|
||||
|
||||
void _publishSelection(CountryCode e) {
|
||||
if (widget.onChanged != null) {
|
||||
widget.onChanged(e.localize(context));
|
||||
widget.onChanged(e);
|
||||
}
|
||||
}
|
||||
|
||||
void _onInit(CountryCode e) {
|
||||
if (widget.onInit != null) {
|
||||
widget.onInit(e.localize(context));
|
||||
widget.onInit(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -202,7 +202,7 @@ List<Map<String, String>> codes = [
|
||||
{
|
||||
"name": "Cayman Islands",
|
||||
"code": "KY",
|
||||
"dial_code": "+ 345",
|
||||
"dial_code": "+1345",
|
||||
},
|
||||
{
|
||||
"name": "Ködörösêse tî Bêafrîka",
|
||||
|
||||
@@ -48,6 +48,7 @@ class _CountryLocalizationsDelegate
|
||||
'en',
|
||||
'it',
|
||||
'fr',
|
||||
'es',
|
||||
].contains(locale.languageCode);
|
||||
}
|
||||
|
||||
|
||||
@@ -7,9 +7,12 @@ class SelectionDialog extends StatefulWidget {
|
||||
final bool showCountryOnly;
|
||||
final InputDecoration searchDecoration;
|
||||
final TextStyle searchStyle;
|
||||
final TextStyle textStyle;
|
||||
final WidgetBuilder emptySearchBuilder;
|
||||
final bool showFlag;
|
||||
final double flagWidth;
|
||||
final Size size;
|
||||
final bool hideSearch;
|
||||
|
||||
/// elements passed as favorite
|
||||
final List<CountryCode> favoriteElements;
|
||||
@@ -22,8 +25,11 @@ class SelectionDialog extends StatefulWidget {
|
||||
this.emptySearchBuilder,
|
||||
InputDecoration searchDecoration = const InputDecoration(),
|
||||
this.searchStyle,
|
||||
this.textStyle,
|
||||
this.showFlag,
|
||||
this.flagWidth = 32,
|
||||
this.size,
|
||||
this.hideSearch = false,
|
||||
}) : assert(searchDecoration != null, 'searchDecoration must not be null!'),
|
||||
this.searchDecoration =
|
||||
searchDecoration.copyWith(prefixIcon: Icon(Icons.search)),
|
||||
@@ -52,20 +58,22 @@ class _SelectionDialogState extends State<SelectionDialog> {
|
||||
),
|
||||
onPressed: () => Navigator.pop(context),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24),
|
||||
child: TextField(
|
||||
style: widget.searchStyle,
|
||||
decoration: widget.searchDecoration,
|
||||
onChanged: _filterElements,
|
||||
if (!widget.hideSearch)
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24),
|
||||
child: TextField(
|
||||
style: widget.searchStyle,
|
||||
decoration: widget.searchDecoration,
|
||||
onChanged: _filterElements,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
children: [
|
||||
Container(
|
||||
width: MediaQuery.of(context).size.width,
|
||||
height: MediaQuery.of(context).size.height * 0.7,
|
||||
width: widget.size?.width ?? MediaQuery.of(context).size.width,
|
||||
height:
|
||||
widget.size?.height ?? MediaQuery.of(context).size.height * 0.7,
|
||||
child: ListView(
|
||||
children: [
|
||||
widget.favoriteElements.isEmpty
|
||||
@@ -123,9 +131,10 @@ class _SelectionDialogState extends State<SelectionDialog> {
|
||||
flex: 4,
|
||||
child: Text(
|
||||
widget.showCountryOnly
|
||||
? e.toCountryStringOnly(context)
|
||||
: e.toLongString(context),
|
||||
? e.toCountryStringOnly()
|
||||
: e.toLongString(),
|
||||
overflow: TextOverflow.fade,
|
||||
style: widget.textStyle,
|
||||
),
|
||||
),
|
||||
],
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
name: country_code_picker
|
||||
description: A flutter package for showing a country code selector. In addition it gives the possibility to select a list of favorites countries, as well as to search using a simple searchbox
|
||||
version: 1.3.7
|
||||
version: 1.3.12+1
|
||||
homepage: https://github.com/imtoori/CountryCodePicker
|
||||
|
||||
environment:
|
||||
@@ -16,3 +16,4 @@ flutter:
|
||||
- packages/country_code_picker/i18n/en.json
|
||||
- packages/country_code_picker/i18n/it.json
|
||||
- packages/country_code_picker/i18n/fr.json
|
||||
- packages/country_code_picker/i18n/es.json
|
||||
|
||||
Reference in New Issue
Block a user