import 'package:flutter/material.dart'; import '../config/country_codes.dart'; import '../config/lang_enum.dart'; import '../config/provider.dart'; import '../config/style.dart'; import '../providers/language_provider.dart'; /// Flag + dial code button that opens a searchable country list. /// /// Replaces the free-text dropdown that used to sit next to the phone field: /// that one rendered its suggestion overlay inside the field's own width, so /// country names were clipped and the list covered the fields underneath. class CountryCodePicker extends StatelessWidget { const CountryCodePicker({ super.key, required this.selected, required this.onSelected, this.height = 44, }); final Map selected; final ValueChanged> onSelected; final double height; @override Widget build(BuildContext context) { final bool isDark = Theme.of(context).brightness == Brightness.dark; final bool isArabic = Provider.of(context).currentLangCode == Language.ar; final Color fill = isDark ? AppNewStyle.darkInputFieldColor : AppNewStyle.inputFieldColor; // Square edge on the side that meets the phone field. // Deliberately physical (not BorderRadiusDirectional): the ternary below // already mirrors for Arabic, so a directional radius would flip twice. final BorderRadius radius = BorderRadius.only( topLeft: isArabic ? Radius.zero : const Radius.circular(8), bottomLeft: isArabic ? Radius.zero : const Radius.circular(8), topRight: isArabic ? const Radius.circular(8) : Radius.zero, bottomRight: isArabic ? const Radius.circular(8) : Radius.zero, ); return InkWell( borderRadius: radius, onTap: () async { final Map? picked = await showModalBottomSheet>( context: context, isScrollControlled: true, backgroundColor: Theme.of(context).scaffoldBackgroundColor, shape: const RoundedRectangleBorder( borderRadius: BorderRadius.vertical(top: Radius.circular(20)), ), builder: (_) => const _CountryPickerSheet(), ); if (picked != null) onSelected(picked); }, child: Container( height: height, padding: const EdgeInsets.symmetric(horizontal: 8), decoration: BoxDecoration( color: fill, borderRadius: radius, border: Border.all(color: fill, width: 0.4), ), child: Row( mainAxisAlignment: MainAxisAlignment.center, mainAxisSize: MainAxisSize.min, children: [ Text( countryFlag(selected["code"] ?? defaultCountryIsoCode), style: const TextStyle(fontSize: 18), ), const SizedBox(width: 4), Flexible( child: Text( selected["dial_code"] ?? "", maxLines: 1, overflow: TextOverflow.visible, softWrap: false, textDirection: TextDirection.ltr, style: TextStyle( fontSize: 13, fontFamily: isArabic ? "Readex_Pro" : "Inter", fontWeight: FontWeight.w500, color: Theme.of(context).colorScheme.onSurface, ), ), ), Icon( Icons.arrow_drop_down, size: 18, color: Theme.of(context).colorScheme.onSurface.withOpacity(0.6), ), ], ), ), ); } } class _CountryPickerSheet extends StatefulWidget { const _CountryPickerSheet(); @override State<_CountryPickerSheet> createState() => _CountryPickerSheetState(); } class _CountryPickerSheetState extends State<_CountryPickerSheet> { final TextEditingController _searchController = TextEditingController(); List> _results = countryCodes; @override void dispose() { _searchController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { final langP = Provider.of(context); final bool isDark = Theme.of(context).brightness == Brightness.dark; final Color onSurface = Theme.of(context).colorScheme.onSurface; return Padding( // Keeps the list clear of the keyboard. padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom), child: SizedBox( height: MediaQuery.of(context).size.height * 0.75, child: Column( children: [ Container( width: 40, height: 4, margin: const EdgeInsets.symmetric(vertical: 10), decoration: BoxDecoration( color: onSurface.withOpacity(0.2), borderRadius: BorderRadius.circular(2), ), ), Padding( padding: const EdgeInsets.fromLTRB(16, 0, 16, 12), child: TextField( controller: _searchController, autofocus: false, style: TextStyle(fontSize: 14, color: onSurface), onChanged: (value) => setState(() => _results = searchCountries(value)), decoration: InputDecoration( isDense: true, filled: true, fillColor: isDark ? AppNewStyle.darkInputFieldColor : AppNewStyle.inputFieldColor, prefixIcon: Icon(Icons.search, size: 20, color: onSurface.withOpacity(0.6)), hintText: langP.translate("Search country"), hintStyle: TextStyle( fontSize: 13, color: onSurface.withOpacity(0.5)), contentPadding: const EdgeInsets.symmetric(vertical: 12, horizontal: 12), border: OutlineInputBorder( borderRadius: BorderRadius.circular(8), borderSide: BorderSide.none, ), ), ), ), Expanded( child: _results.isEmpty ? Center( child: Text( langP.translate("No country found"), style: TextStyle( fontSize: 13, color: onSurface.withOpacity(0.6)), ), ) : ListView.builder( itemCount: _results.length, itemBuilder: (context, index) { final country = _results[index]; return ListTile( dense: true, leading: Text( countryFlag(country["code"]!), style: const TextStyle(fontSize: 22), ), title: Text( country["name"]!, style: TextStyle(fontSize: 14, color: onSurface), ), trailing: Text( country["dial_code"]!, textDirection: TextDirection.ltr, style: TextStyle( fontSize: 14, fontWeight: FontWeight.w500, color: onSurface.withOpacity(0.7), ), ), onTap: () => Navigator.pop(context, country), ); }, ), ), ], ), ), ); } }