From 698bcc48304abf5b178cd881806dc331961dc3b7 Mon Sep 17 00:00:00 2001 From: Abdo-Nabil <93052392+Abdo-Nabil@users.noreply.github.com> Date: Thu, 31 Jul 2025 23:29:12 +0300 Subject: [PATCH 1/3] Add optional parameter spaceAfterDropdownIcon --- lib/country_code_picker.dart | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/lib/country_code_picker.dart b/lib/country_code_picker.dart index c4b5260..f01d793 100644 --- a/lib/country_code_picker.dart +++ b/lib/country_code_picker.dart @@ -115,6 +115,9 @@ class CountryCodePicker extends StatefulWidget { ///Header Text Alignment final MainAxisAlignment headerAlignment; + /// space after dropdown icon if shown + final double? spaceAfterDropdownIcon; + const CountryCodePicker({ this.onChanged, this.onInit, @@ -159,6 +162,7 @@ class CountryCodePicker extends StatefulWidget { this.headerTextStyle = const TextStyle(fontSize: 18, fontWeight: FontWeight.bold), this.hideHeaderText = false, this.topBarPadding = const EdgeInsets.symmetric(vertical: 5.0, horizontal: 20), + this.spaceAfterDropdownIcon, Key? key, }) : super(key: key); @@ -177,9 +181,9 @@ class CountryCodePicker extends StatefulWidget { final uppercaseCustomList = countryFilter!.map((criteria) => criteria.toUpperCase()).toList(); elements = elements .where((criteria) => - uppercaseCustomList.contains(criteria.code) || - uppercaseCustomList.contains(criteria.name) || - uppercaseCustomList.contains(criteria.dialCode)) + uppercaseCustomList.contains(criteria.code) || + uppercaseCustomList.contains(criteria.name) || + uppercaseCustomList.contains(criteria.dialCode)) .toList(); } @@ -207,8 +211,8 @@ class CountryCodePickerState extends State { internalWidget = TextButton( onPressed: widget.enabled ? pickerStyle == PickerStyle.dialog - ? showCountryCodePickerDialog - : showCountryCodePickerBottomSheet + ? showCountryCodePickerDialog + : showCountryCodePickerBottomSheet : null, child: Padding( padding: widget.padding, @@ -249,8 +253,8 @@ class CountryCodePickerState extends State { fit: widget.alignLeft ? FlexFit.tight : FlexFit.loose, child: Padding( padding: (widget.alignLeft - ? const EdgeInsets.only(right: 16.0, left: 8.0) - : const EdgeInsets.only(right: 16.0)), + ? EdgeInsets.only(right: widget.spaceAfterDropdownIcon?? 16.0, left: 8.0) + : EdgeInsets.only(right: widget.spaceAfterDropdownIcon?? 16.0)), child: Icon( Icons.arrow_drop_down, color: Colors.grey, @@ -280,8 +284,8 @@ class CountryCodePickerState extends State { if (oldWidget.initialSelection != widget.initialSelection) { if (widget.initialSelection != null) { selectedItem = elements.firstWhere( - (criteria) => - (criteria.code!.toUpperCase() == widget.initialSelection!.toUpperCase()) || + (criteria) => + (criteria.code!.toUpperCase() == widget.initialSelection!.toUpperCase()) || (criteria.dialCode == widget.initialSelection) || (criteria.name!.toUpperCase() == widget.initialSelection!.toUpperCase()), orElse: () => elements[0]); @@ -298,8 +302,8 @@ class CountryCodePickerState extends State { if (widget.initialSelection != null) { selectedItem = elements.firstWhere( - (item) => - (item.code!.toUpperCase() == widget.initialSelection!.toUpperCase()) || + (item) => + (item.code!.toUpperCase() == widget.initialSelection!.toUpperCase()) || (item.dialCode == widget.initialSelection) || (item.name!.toUpperCase() == widget.initialSelection!.toUpperCase()), orElse: () => elements[0]); @@ -309,11 +313,11 @@ class CountryCodePickerState extends State { favoriteElements = elements .where((item) => - widget.favorite.firstWhereOrNull((criteria) => - item.code!.toUpperCase() == criteria.toUpperCase() || - item.dialCode == criteria || - item.name!.toUpperCase() == criteria.toUpperCase()) != - null) + widget.favorite.firstWhereOrNull((criteria) => + item.code!.toUpperCase() == criteria.toUpperCase() || + item.dialCode == criteria || + item.name!.toUpperCase() == criteria.toUpperCase()) != + null) .toList(); } From fadb059b3e6bcd6705ede7872fa10f96ed5c4ba7 Mon Sep 17 00:00:00 2001 From: Abdo-Nabil <93052392+Abdo-Nabil@users.noreply.github.com> Date: Mon, 4 Aug 2025 14:59:06 +0300 Subject: [PATCH 2/3] Add showDialogCustomFunction, showBottomSheetCustomFunction to controll the style of them --- lib/country_code_picker.dart | 223 +++++++++++++++++++++-------------- 1 file changed, 133 insertions(+), 90 deletions(-) diff --git a/lib/country_code_picker.dart b/lib/country_code_picker.dart index f01d793..27d5cb0 100644 --- a/lib/country_code_picker.dart +++ b/lib/country_code_picker.dart @@ -9,12 +9,12 @@ import 'src/country_code.dart'; import 'src/country_codes.dart'; import 'src/selection_dialog.dart'; +export 'src/bottom_sheet.dart'; +export 'src/constants.dart'; export 'src/country_code.dart'; export 'src/country_codes.dart'; export 'src/country_localizations.dart'; export 'src/selection_dialog.dart'; -export 'src/bottom_sheet.dart'; -export 'src/constants.dart'; class CountryCodePicker extends StatefulWidget { final ValueChanged? onChanged; @@ -118,6 +118,14 @@ class CountryCodePicker extends StatefulWidget { /// space after dropdown icon if shown final double? spaceAfterDropdownIcon; + /// This function will receive the child and show a custom + /// dialog based on the function implementation + final Function? showDialogCustomFunction; + + /// This function will receive the child and show a custom + /// modal bottom sheet based on the function implementation + final Function? showBottomSheetCustomFunction; + const CountryCodePicker({ this.onChanged, this.onInit, @@ -155,14 +163,19 @@ class CountryCodePicker extends StatefulWidget { this.closeIcon = const Icon(Icons.close), this.countryList = codes, this.pickerStyle = PickerStyle.dialog, - this.dialogItemPadding = const EdgeInsets.symmetric(horizontal: 24, vertical: 8), + this.dialogItemPadding = + const EdgeInsets.symmetric(horizontal: 24, vertical: 8), this.searchPadding = const EdgeInsets.symmetric(horizontal: 24), this.headerAlignment = MainAxisAlignment.spaceBetween, this.headerText = "Select Country", - this.headerTextStyle = const TextStyle(fontSize: 18, fontWeight: FontWeight.bold), + this.headerTextStyle = + const TextStyle(fontSize: 18, fontWeight: FontWeight.bold), this.hideHeaderText = false, - this.topBarPadding = const EdgeInsets.symmetric(vertical: 5.0, horizontal: 20), + this.topBarPadding = + const EdgeInsets.symmetric(vertical: 5.0, horizontal: 20), this.spaceAfterDropdownIcon, + this.showDialogCustomFunction, + this.showBottomSheetCustomFunction, Key? key, }) : super(key: key); @@ -171,19 +184,21 @@ class CountryCodePicker extends StatefulWidget { State createState() { List> jsonList = countryList; - List elements = jsonList.map((json) => CountryCode.fromJson(json)).toList(); + List elements = + jsonList.map((json) => CountryCode.fromJson(json)).toList(); if (comparator != null) { elements.sort(comparator); } if (countryFilter != null && countryFilter!.isNotEmpty) { - final uppercaseCustomList = countryFilter!.map((criteria) => criteria.toUpperCase()).toList(); + final uppercaseCustomList = + countryFilter!.map((criteria) => criteria.toUpperCase()).toList(); elements = elements .where((criteria) => - uppercaseCustomList.contains(criteria.code) || - uppercaseCustomList.contains(criteria.name) || - uppercaseCustomList.contains(criteria.dialCode)) + uppercaseCustomList.contains(criteria.code) || + uppercaseCustomList.contains(criteria.name) || + uppercaseCustomList.contains(criteria.dialCode)) .toList(); } @@ -204,15 +219,20 @@ class CountryCodePickerState extends State { Widget internalWidget; if (widget.builder != null) { internalWidget = InkWell( - onTap: pickerStyle == PickerStyle.dialog ? showCountryCodePickerDialog : showCountryCodePickerBottomSheet, + onTap: pickerStyle == PickerStyle.dialog + ? () => showCountryCodePickerDialog(widget.showDialogCustomFunction) + : () => showCountryCodePickerBottomSheet( + widget.showBottomSheetCustomFunction), child: widget.builder!(selectedItem), ); } else { internalWidget = TextButton( onPressed: widget.enabled ? pickerStyle == PickerStyle.dialog - ? showCountryCodePickerDialog - : showCountryCodePickerBottomSheet + ? () => + showCountryCodePickerDialog(widget.showDialogCustomFunction) + : () => showCountryCodePickerBottomSheet( + widget.showBottomSheetCustomFunction) : null, child: Padding( padding: widget.padding, @@ -220,12 +240,16 @@ class CountryCodePickerState extends State { direction: Axis.horizontal, mainAxisSize: MainAxisSize.min, children: [ - if (widget.showFlagMain != null ? widget.showFlagMain! : widget.showFlag) + if (widget.showFlagMain != null + ? widget.showFlagMain! + : widget.showFlag) Flexible( flex: widget.alignLeft ? 0 : 1, fit: widget.alignLeft ? FlexFit.tight : FlexFit.loose, child: Container( - clipBehavior: widget.flagDecoration == null ? Clip.none : Clip.hardEdge, + clipBehavior: widget.flagDecoration == null + ? Clip.none + : Clip.hardEdge, decoration: widget.flagDecoration, margin: widget.margin ?? (widget.alignLeft @@ -242,8 +266,11 @@ class CountryCodePickerState extends State { Flexible( fit: widget.alignLeft ? FlexFit.tight : FlexFit.loose, child: Text( - widget.showOnlyCountryWhenClosed ? selectedItem!.toCountryStringOnly() : selectedItem.toString(), - style: widget.textStyle ?? Theme.of(context).textTheme.labelLarge, + widget.showOnlyCountryWhenClosed + ? selectedItem!.toCountryStringOnly() + : selectedItem.toString(), + style: widget.textStyle ?? + Theme.of(context).textTheme.labelLarge, overflow: widget.textOverflow, ), ), @@ -253,8 +280,11 @@ class CountryCodePickerState extends State { fit: widget.alignLeft ? FlexFit.tight : FlexFit.loose, child: Padding( padding: (widget.alignLeft - ? EdgeInsets.only(right: widget.spaceAfterDropdownIcon?? 16.0, left: 8.0) - : EdgeInsets.only(right: widget.spaceAfterDropdownIcon?? 16.0)), + ? EdgeInsets.only( + right: widget.spaceAfterDropdownIcon ?? 16.0, + left: 8.0) + : EdgeInsets.only( + right: widget.spaceAfterDropdownIcon ?? 16.0)), child: Icon( Icons.arrow_drop_down, color: Colors.grey, @@ -284,10 +314,12 @@ class CountryCodePickerState extends State { if (oldWidget.initialSelection != widget.initialSelection) { if (widget.initialSelection != null) { selectedItem = elements.firstWhere( - (criteria) => - (criteria.code!.toUpperCase() == widget.initialSelection!.toUpperCase()) || + (criteria) => + (criteria.code!.toUpperCase() == + widget.initialSelection!.toUpperCase()) || (criteria.dialCode == widget.initialSelection) || - (criteria.name!.toUpperCase() == widget.initialSelection!.toUpperCase()), + (criteria.name!.toUpperCase() == + widget.initialSelection!.toUpperCase()), orElse: () => elements[0]); } else { selectedItem = elements[0]; @@ -302,10 +334,12 @@ class CountryCodePickerState extends State { if (widget.initialSelection != null) { selectedItem = elements.firstWhere( - (item) => - (item.code!.toUpperCase() == widget.initialSelection!.toUpperCase()) || + (item) => + (item.code!.toUpperCase() == + widget.initialSelection!.toUpperCase()) || (item.dialCode == widget.initialSelection) || - (item.name!.toUpperCase() == widget.initialSelection!.toUpperCase()), + (item.name!.toUpperCase() == + widget.initialSelection!.toUpperCase()), orElse: () => elements[0]); } else { selectedItem = elements[0]; @@ -313,49 +347,52 @@ class CountryCodePickerState extends State { favoriteElements = elements .where((item) => - widget.favorite.firstWhereOrNull((criteria) => - item.code!.toUpperCase() == criteria.toUpperCase() || - item.dialCode == criteria || - item.name!.toUpperCase() == criteria.toUpperCase()) != - null) + widget.favorite.firstWhereOrNull((criteria) => + item.code!.toUpperCase() == criteria.toUpperCase() || + item.dialCode == criteria || + item.name!.toUpperCase() == criteria.toUpperCase()) != + null) .toList(); } - void showCountryCodePickerDialog() async { - final item = await showDialog( - barrierColor: widget.barrierColor ?? Colors.grey.withAlpha(128), - context: context, - builder: (context) => Center( - child: Dialog( - child: SelectionDialog( - elements, - favoriteElements, - showCountryOnly: widget.showCountryOnly, - emptySearchBuilder: widget.emptySearchBuilder, - searchDecoration: widget.searchDecoration, - searchStyle: widget.searchStyle, - textStyle: widget.dialogTextStyle, - boxDecoration: widget.boxDecoration, - showFlag: widget.showFlagDialog ?? widget.showFlag, - flagWidth: widget.flagWidth, - size: widget.dialogSize, - headerAlignment: widget.headerAlignment, - headerText: widget.headerText, - headerTextStyle: widget.headerTextStyle, - hideHeaderText: widget.hideHeaderText, - topBarPadding: widget.topBarPadding, - backgroundColor: widget.dialogBackgroundColor, - barrierColor: widget.barrierColor, - hideSearch: widget.hideSearch, - hideCloseIcon: widget.hideCloseIcon, - closeIcon: widget.closeIcon, - flagDecoration: widget.flagDecoration, - dialogItemPadding: widget.dialogItemPadding, - searchPadding: widget.searchPadding, - ), - ), - ), + void showCountryCodePickerDialog(Function? showDialogCustomFunction) async { + late final childWidget = SelectionDialog( + elements, + favoriteElements, + showCountryOnly: widget.showCountryOnly, + emptySearchBuilder: widget.emptySearchBuilder, + searchDecoration: widget.searchDecoration, + searchStyle: widget.searchStyle, + textStyle: widget.dialogTextStyle, + boxDecoration: widget.boxDecoration, + showFlag: widget.showFlagDialog ?? widget.showFlag, + flagWidth: widget.flagWidth, + size: widget.dialogSize, + headerAlignment: widget.headerAlignment, + headerText: widget.headerText, + headerTextStyle: widget.headerTextStyle, + hideHeaderText: widget.hideHeaderText, + topBarPadding: widget.topBarPadding, + backgroundColor: widget.dialogBackgroundColor, + barrierColor: widget.barrierColor, + hideSearch: widget.hideSearch, + hideCloseIcon: widget.hideCloseIcon, + closeIcon: widget.closeIcon, + flagDecoration: widget.flagDecoration, + dialogItemPadding: widget.dialogItemPadding, + searchPadding: widget.searchPadding, ); + final item = showDialogCustomFunction == null + ? await showDialog( + barrierColor: widget.barrierColor ?? Colors.grey.withAlpha(128), + context: context, + builder: (context) => Center( + child: Dialog( + child: childWidget, + ), + ), + ) + : await showDialogCustomFunction(context, childWidget); if (item != null) { setState(() { @@ -366,33 +403,39 @@ class CountryCodePickerState extends State { } } - void showCountryCodePickerBottomSheet() async { - final item = await showModalBottomSheet( - isScrollControlled: true, - context: context, - backgroundColor: Colors.transparent, - elevation: 0, - builder: (ctx) { - return SelectionBottomSheet( - elements, - favoriteElements, - showCountryOnly: widget.showCountryOnly, - emptySearchBuilder: widget.emptySearchBuilder, - searchDecoration: widget.searchDecoration, - searchStyle: widget.searchStyle, - textStyle: widget.dialogTextStyle, - boxDecoration: widget.boxDecoration, - showFlag: widget.showFlagDialog ?? widget.showFlag, - flagWidth: widget.flagWidth, - size: widget.dialogSize, - backgroundColor: widget.dialogBackgroundColor, - barrierColor: widget.barrierColor, - hideSearch: widget.hideSearch, - closeIcon: widget.closeIcon, - flagDecoration: widget.flagDecoration, - ); - }, + void showCountryCodePickerBottomSheet( + Function? showBottomSheetCustomFunction) async { + // + late final sheetWidget = SelectionBottomSheet( + elements, + favoriteElements, + showCountryOnly: widget.showCountryOnly, + emptySearchBuilder: widget.emptySearchBuilder, + searchDecoration: widget.searchDecoration, + searchStyle: widget.searchStyle, + textStyle: widget.dialogTextStyle, + boxDecoration: widget.boxDecoration, + showFlag: widget.showFlagDialog ?? widget.showFlag, + flagWidth: widget.flagWidth, + size: widget.dialogSize, + backgroundColor: widget.dialogBackgroundColor, + barrierColor: widget.barrierColor, + hideSearch: widget.hideSearch, + closeIcon: widget.closeIcon, + flagDecoration: widget.flagDecoration, ); + // + final item = showBottomSheetCustomFunction == null + ? await showModalBottomSheet( + isScrollControlled: true, + context: context, + backgroundColor: Colors.transparent, + elevation: 0, + builder: (ctx) { + return sheetWidget; + }, + ) + : await showBottomSheetCustomFunction(context, sheetWidget); if (item == null) return; From 80678213bba86d9c98791f8abf612ea65ae06f3a Mon Sep 17 00:00:00 2001 From: Abdo-Nabil <93052392+Abdo-Nabil@users.noreply.github.com> Date: Tue, 5 Aug 2025 13:59:41 +0300 Subject: [PATCH 3/3] Update country_code_picker.dart --- lib/country_code_picker.dart | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/country_code_picker.dart b/lib/country_code_picker.dart index 27d5cb0..f8ff4c9 100644 --- a/lib/country_code_picker.dart +++ b/lib/country_code_picker.dart @@ -120,10 +120,13 @@ class CountryCodePicker extends StatefulWidget { /// This function will receive the child and show a custom /// dialog based on the function implementation + /// Note: You have to return this function to back to the package to select the country final Function? showDialogCustomFunction; /// This function will receive the child and show a custom /// modal bottom sheet based on the function implementation + /// Note: You have to return this function to back to the package to select the country + final Function? showBottomSheetCustomFunction; const CountryCodePicker({