From b464f6f8e2fcde5649c81eb794f6f68cd08865d8 Mon Sep 17 00:00:00 2001 From: Gonzalo Juarez Date: Sat, 9 May 2026 01:35:24 -0300 Subject: [PATCH 1/6] feat: implement currency selection widgets and controller utilities with version update --- CHANGELOG.md | 13 ++- README.md | 19 +++- example/lib/main.dart | 14 +++ example/pubspec.lock | 20 ++-- lib/currency_widget.dart | 3 +- lib/src/Controller/currency_controller.dart | 1 + lib/src/utils/currency_picker_utils.dart | 50 ++++++++++ .../utils/masked_text_editing_controller.dart | 55 ++++++++--- lib/src/view/currency_chooser.dart | 96 +++++++++++++++++++ lib/src/view/currency_picker.dart | 69 +------------ lib/src/view/currency_textfield.dart | 1 + lib/src/view/currency_textview.dart | 1 + pubspec.yaml | 4 +- 13 files changed, 255 insertions(+), 91 deletions(-) create mode 100644 lib/src/utils/currency_picker_utils.dart create mode 100644 lib/src/view/currency_chooser.dart diff --git a/CHANGELOG.md b/CHANGELOG.md index 4b9f71b..f085893 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -69,4 +69,15 @@ ## 1.0.6 * Fix Memory issues * Fix Cursor Issue - * Fix Currency Mask format. \ No newline at end of file + * Fix Currency Mask format. + + ## 1.0.7 + * Fix Controller on TextEditingController + * Fix Relative Cursor Issue + + ## 1.0.8 + * add currencyChooser + + ## 1.0.9 + * Minor refactor in currencyChooser + \ No newline at end of file diff --git a/README.md b/README.md index 0cd075b..aa716ca 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,13 @@ A widget for **displaying a list of currency values in a card format**. This is * Each item in the list can represent a different currency or aspect of a report. * Customizable to fit various reporting needs. +### `CurrencyChooser` +A lightweight widget to **select a currency without requiring an amount**. Use it when you only need the user to pick a currency, with no amount input involved. +* Dropdown to select from common or all supported currencies. +* Toggle button (⭐ / 🌐) to switch between most-used and all currencies. +* Displays the full localized name of the selected currency. +* Exposes the selection via `CurrencyController.currency` and `CurrencyController.currencyNotifier`. + ## Properties per Widget @@ -45,6 +52,7 @@ A widget for **displaying a list of currency values in a card format**. This is | `CurrencyTextField` | `currencyController`: (required) Manages currency state.
`currencyCode`: (required) Code of the currency to use.
| | `CurrencyTextView` | `mount`: (required) Amount to display.
`currencyCode`: (required) Code of the currency.
`CurrencyControler` : (required)Manages currency state | | `CurrencyCardReport` | `title`: (required) Title widget for the card.
`icon`: (required) Icon widget for the card.
`mount`: (required) Amount to display.
`currencyCode`: (required) Code of the currency.
`lang`: (required) Language for formatting.
`style`: Text Style | +| `CurrencyChooser` | `currencyController`: (required) Manages currency state and exposes the selected currency via `controller.currency` and `controller.currencyNotifier`. | **Note**: All widgets also accept standard Flutter widget properties like `key`, `padding`, `margin`, etc. @@ -133,7 +141,16 @@ class _MyCurrencyScreenState extends State { width: 200, child: CurrencyCardReport( title: Text('Currency Report'), icon: Icon(Icons.currency_exchange),mount: 250.24, currencyCode: 'usd', lang: 'en',) - ) + ), + SizedBox(height: 20), + // CurrencyChooser: pick a currency without entering an amount + CurrencyChooser(currencyController: _controller), + ValueListenableBuilder( + valueListenable: _controller.currencyNotifier, + builder: (_, currency, __) { + return Text('Selected: ${currency?.getDefaultView() ?? ''}'); + }, + ), ], ), ), diff --git a/example/lib/main.dart b/example/lib/main.dart index 9e652a6..8b00084 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -39,6 +39,9 @@ class _MyHomePageState extends State { final CurrencyController currencyControllerEn = CurrencyController( lang: 'en', ); + final CurrencyController currencyChooserController = CurrencyController( + lang: 'es', + ); @override Widget build(BuildContext context) { @@ -110,6 +113,17 @@ class _MyHomePageState extends State { lang: 'en', ), ), + const Divider(), + const Text('CurrencyChooser (sin monto)'), + CurrencyChooser(currencyController: currencyChooserController), + ListenableBuilder( + listenable: currencyChooserController.currencyNotifier, + builder: (context, child) { + return Text( + 'Moneda seleccionada: ${currencyChooserController.currency.getDefaultView()}', + ); + }, + ), ], ), ), // This trailing comma makes auto-formatting nicer for build methods. diff --git a/example/pubspec.lock b/example/pubspec.lock index 632a0a2..4bb7cb3 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -21,10 +21,10 @@ packages: dependency: transitive description: name: characters - sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803 + sha256: faf38497bda5ead2a8c7615f4f7939df04333478bf32e4173fcb06d428b5716b url: "https://pub.dev" source: hosted - version: "1.4.0" + version: "1.4.1" clock: dependency: transitive description: @@ -55,7 +55,7 @@ packages: path: ".." relative: true source: path - version: "1.0.0" + version: "1.0.8" fake_async: dependency: transitive description: @@ -118,18 +118,18 @@ packages: dependency: transitive description: name: matcher - sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2 + sha256: dc0b7dc7651697ea4ff3e69ef44b0407ea32c487a39fff6a4004fa585e901861 url: "https://pub.dev" source: hosted - version: "0.12.17" + version: "0.12.19" material_color_utilities: dependency: transitive description: name: material_color_utilities - sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec + sha256: "9c337007e82b1889149c82ed242ed1cb24a66044e30979c44912381e9be4c48b" url: "https://pub.dev" source: hosted - version: "0.11.1" + version: "0.13.0" meta: dependency: transitive description: @@ -195,10 +195,10 @@ packages: dependency: transitive description: name: test_api - sha256: ab2726c1a94d3176a45960b6234466ec367179b87dd74f1611adb1f3b5fb9d55 + sha256: "8161c84903fd860b26bfdefb7963b3f0b68fee7adea0f59ef805ecca346f0c7a" url: "https://pub.dev" source: hosted - version: "0.7.7" + version: "0.7.10" vector_math: dependency: transitive description: @@ -216,5 +216,5 @@ packages: source: hosted version: "15.0.0" sdks: - dart: ">=3.8.1 <4.0.0" + dart: ">=3.9.0-0 <4.0.0" flutter: ">=3.18.0-18.0.pre.54" diff --git a/lib/currency_widget.dart b/lib/currency_widget.dart index 0c23e37..409ef67 100644 --- a/lib/currency_widget.dart +++ b/lib/currency_widget.dart @@ -4,4 +4,5 @@ export 'package:currency_widget/src/view/currency_picker.dart'; export 'package:currency_widget/src/Controller/currency_controller.dart'; export 'package:currency_widget/src/view/currency_textview.dart'; export 'package:currency_widget/src/view/currency_textfield.dart'; -export 'package:currency_widget/src/view/currency_card_view_report.dart'; \ No newline at end of file +export 'package:currency_widget/src/view/currency_card_view_report.dart'; +export 'package:currency_widget/src/view/currency_chooser.dart'; \ No newline at end of file diff --git a/lib/src/Controller/currency_controller.dart b/lib/src/Controller/currency_controller.dart index 25aefd8..407181c 100644 --- a/lib/src/Controller/currency_controller.dart +++ b/lib/src/Controller/currency_controller.dart @@ -11,6 +11,7 @@ class CurrencyController{ ValueNotifier mount = ValueNotifier(0); ValueNotifier _currency = ValueNotifier(null); + ValueNotifier get currencyNotifier => _currency; Currency get currency => _currency.value??supportedCurrencies[0]; void set currency(Currency? currency){ _currency.value = currency; diff --git a/lib/src/utils/currency_picker_utils.dart b/lib/src/utils/currency_picker_utils.dart new file mode 100644 index 0000000..0ab2650 --- /dev/null +++ b/lib/src/utils/currency_picker_utils.dart @@ -0,0 +1,50 @@ +import 'package:currency_widget/currency_widget.dart'; +import 'package:currency_widget/src/assets/supported_currencies.dart'; +import 'package:currency_widget/src/utils/common_currencies.dart'; +import 'package:flutter/material.dart'; + +/// Returns the filtered list of currencies based on [showOnlyCommon]. +List filteredCurrencies(bool showOnlyCommon) { + if (showOnlyCommon) { + return supportedCurrencies + .where((c) => commonCurrencyCodes.contains(c.code.toUpperCase())) + .toList(); + } + return supportedCurrencies; +} + +/// Returns the localized tooltip text for the common/all toggle button. +String currencyFilterTooltip(String lang, bool showOnlyCommon) { + const Map> translations = { + 'en': {'common': 'Most used', 'all': 'All currencies'}, + 'es': {'common': 'Más usadas', 'all': 'Todas'}, + 'pt': {'common': 'Mais usadas', 'all': 'Todas'}, + 'fr': {'common': 'Plus utilisées', 'all': 'Toutes'}, + 'de': {'common': 'Meist genutzt', 'all': 'Alle'}, + 'it': {'common': 'Più usate', 'all': 'Tutte'}, + 'ru': {'common': 'Популярные', 'all': 'Все'}, + 'zh': {'common': '常用', 'all': '全部'}, + 'ja': {'common': 'よく使われる', 'all': 'すべて'}, + 'ko': {'common': '자주 사용됨', 'all': '모두'}, + 'ar': {'common': 'الأكثر استخداماً', 'all': 'الكل'}, + 'hi': {'common': 'अधिक उपयोग', 'all': 'सभी'}, + 'id': {'common': 'Paling banyak digunakan', 'all': 'Semua'}, + 'ur': {'common': 'سب سے زیادہ استعمال', 'all': 'تمام'}, + }; + final t = translations[lang.toLowerCase()] ?? translations['en']!; + return showOnlyCommon ? t['common']! : t['all']!; +} + +/// Builds the [DropdownMenuItem] list for a given [currencies] list. +List> currencyDropdownItems( + List currencies) { + return currencies.map((Currency currency) { + return DropdownMenuItem( + value: currency, + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 15), + child: Text(currency.getDefaultView()), + ), + ); + }).toList(); +} diff --git a/lib/src/utils/masked_text_editing_controller.dart b/lib/src/utils/masked_text_editing_controller.dart index d91b6be..0bb113b 100644 --- a/lib/src/utils/masked_text_editing_controller.dart +++ b/lib/src/utils/masked_text_editing_controller.dart @@ -25,22 +25,38 @@ class AutoDecimalNumberFormatter extends TextInputFormatter { }); @override TextEditingValue formatEditUpdate( - TextEditingValue oldValue, - TextEditingValue newValue, - ) { + TextEditingValue oldValue, + TextEditingValue newValue, + ) { // Permitir borrado completo if (newValue.text.isEmpty) { - return newValue.copyWith(selection: const TextSelection.collapsed(offset: 0)); + return newValue.copyWith( + selection: const TextSelection.collapsed(offset: 0)); } // Solo permitir dígitos final digitsOnly = newValue.text.replaceAll(RegExp(r'[^\d]'), ''); if (digitsOnly.isEmpty) { - return newValue.copyWith(text: ''); + return const TextEditingValue( + text: '', + selection: TextSelection.collapsed(offset: 0), + ); } - // Calcular posición del cursor - final cursorPosition = newValue.selection.baseOffset; + // Guardar la posición del cursor original + // Si hay una selección (rango), usar el final de la selección + final oldCursorPosition = newValue.selection.isCollapsed + ? newValue.selection.baseOffset + : newValue.selection.end; + + // Contar cuántos dígitos hay DESPUÉS del cursor en el texto sin formatear + // Esto mantiene la posición relativa desde el final + int digitsAfterCursor = 0; + for (int i = oldCursorPosition; i < newValue.text.length; i++) { + if (RegExp(r'\d').hasMatch(newValue.text[i])) { + digitsAfterCursor++; + } + } // Separar parte entera y decimal String integerPart; @@ -80,11 +96,26 @@ class AutoDecimalNumberFormatter extends TextInputFormatter { : '$formattedInt$decimalSeparator$decimalPart'; // Calcular nueva posición del cursor - int newCursorPosition = formatted.length; - if (cursorPosition > 0 && cursorPosition <= newValue.text.length) { - // Lógica para mantener el cursor en una posición relativa - final relativePosition = cursorPosition / newValue.text.length; - newCursorPosition = (formatted.length * relativePosition).round(); + int newCursorPosition; + + // Caso especial: si no hay dígitos después del cursor, poner al final + if (digitsAfterCursor == 0) { + newCursorPosition = formatted.length; + } else { + // Contar dígitos desde el final para encontrar la posición correcta + int digitCount = 0; + newCursorPosition = formatted.length; + + for (int i = formatted.length - 1; i >= 0; i--) { + if (RegExp(r'\d').hasMatch(formatted[i])) { + digitCount++; + if (digitCount == digitsAfterCursor) { + // El cursor debe ir ANTES de este dígito + newCursorPosition = i; + break; + } + } + } } return TextEditingValue( diff --git a/lib/src/view/currency_chooser.dart b/lib/src/view/currency_chooser.dart new file mode 100644 index 0000000..eebcef8 --- /dev/null +++ b/lib/src/view/currency_chooser.dart @@ -0,0 +1,96 @@ +import 'package:currency_widget/currency_widget.dart'; +import 'package:currency_widget/src/assets/currencies_names/currencies_names.dart'; +import 'package:currency_widget/src/utils/currency_picker_utils.dart'; +import 'package:flutter/material.dart'; + +/// A widget that allows the user to select a currency without requiring an amount. +/// +/// Use [CurrencyChooser] when you only need the user to pick a currency, +/// without any amount input. The selected [Currency] is exposed through +/// the [currencyController]. +/// +/// Example: +/// ```dart +/// CurrencyChooser(currencyController: CurrencyController(lang: 'en')) +/// ``` +class CurrencyChooser extends StatefulWidget { + final CurrencyController currencyController; + + const CurrencyChooser({super.key, required this.currencyController}); + + @override + State createState() => _CurrencyChooserState(); +} + +class _CurrencyChooserState extends State { + List _currencies = []; + bool _showOnlyCommon = true; + + @override + void initState() { + super.initState(); + _updateCurrencyList(); + widget.currencyController.currency = _currencies[0]; + } + + void _updateCurrencyList() { + _currencies = filteredCurrencies(_showOnlyCommon); + } + + @override + Widget build(BuildContext context) { + return Container( + margin: const EdgeInsets.all(10), + child: ListTile( + title: Row( + children: [ + Expanded(child: _buildDropdown()), + Tooltip( + message: _getTooltipText(), + child: IconButton( + icon: Icon( + _showOnlyCommon ? Icons.star : Icons.public, + size: 22, + ), + onPressed: () { + setState(() { + _showOnlyCommon = !_showOnlyCommon; + _updateCurrencyList(); + if (!_currencies + .contains(widget.currencyController.currency)) { + widget.currencyController.currency = _currencies[0]; + } + }); + }, + ), + ), + ], + ), + subtitle: Text( + countryNames( + widget.currencyController.lang, + widget.currencyController.currency.code, + ), + style: const TextStyle(fontSize: 13), + ), + ), + ); + } + + DropdownButton _buildDropdown() { + return DropdownButton( + value: widget.currencyController.currency, + onChanged: (Currency? newValue) { + if (newValue == null) return; + setState(() { + widget.currencyController.currency = newValue; + }); + }, + items: currencyDropdownItems(_currencies), + ); + } + + String _getTooltipText() { + return currencyFilterTooltip(widget.currencyController.lang, _showOnlyCommon); + } +} diff --git a/lib/src/view/currency_picker.dart b/lib/src/view/currency_picker.dart index b147ad2..9ef676c 100644 --- a/lib/src/view/currency_picker.dart +++ b/lib/src/view/currency_picker.dart @@ -1,7 +1,6 @@ import 'package:currency_widget/currency_widget.dart'; import 'package:currency_widget/src/assets/currencies_names/currencies_names.dart'; -import 'package:currency_widget/src/assets/supported_currencies.dart'; -import 'package:currency_widget/src/utils/common_currencies.dart'; +import 'package:currency_widget/src/utils/currency_picker_utils.dart'; import 'package:currency_widget/src/utils/masked_text_editing_controller.dart'; import 'package:flutter/material.dart'; @@ -32,39 +31,10 @@ class _CurrencyPicker extends State { : '', ); - // Listen to mount changes to update TextField - widget.currencyController.mount.addListener(_onMountChanged); - } - - void _onMountChanged() { - final mount = widget.currencyController.mount.value; - if (mount != null && mount > 0) { - final formatted = mount.toStringAsFixed( - widget.currencyController.currency.decimalDigits, - ); - if (controller.text != formatted) { - // Remover listener temporalmente para evitar loops - widget.currencyController.mount.removeListener(_onMountChanged); - - controller.text = formatted; - // Poner cursor al final para evitar auto-selección - controller.selection = TextSelection.collapsed(offset: formatted.length); - - // Re-agregar listener - widget.currencyController.mount.addListener(_onMountChanged); - } - } } void _updateCurrencyList() { - if (_showOnlyCommon) { - _currencies = supportedCurrencies - .where((currency) => - commonCurrencyCodes.contains(currency.code.toUpperCase())) - .toList(); - } else { - _currencies = supportedCurrencies; - } + _currencies = filteredCurrencies(_showOnlyCommon); } @override @@ -103,6 +73,7 @@ class _CurrencyPicker extends State { controller: controller, keyboardType: TextInputType.number, textAlign: TextAlign.center, + enableInteractiveSelection: true, decoration: InputDecoration( hintText: 0.toStringAsFixed( widget.currencyController.currency.decimalDigits), @@ -150,14 +121,7 @@ class _CurrencyPicker extends State { onChanged: (Currency? newValue) async { chooseCurrency(newValue!); }, - items: _currencies.map((Currency currency) { - return DropdownMenuItem( - value: currency, - child: Padding( - padding: const EdgeInsets.only(left: 15, right: 15), - child: Text(currency.getDefaultView())), - ); - }).toList(), + items: currencyDropdownItems(_currencies), ); } @@ -176,34 +140,11 @@ class _CurrencyPicker extends State { @override void dispose() { - widget.currencyController.mount.removeListener(_onMountChanged); controller.dispose(); super.dispose(); } String _getTooltipText() { - final lang = widget.currencyController.lang.toLowerCase(); - final isCommon = _showOnlyCommon; - - // Translations for tooltip using the same locale system as countryNames - final Map> translations = { - 'en': {'common': 'Most used', 'all': 'All currencies'}, - 'es': {'common': 'Más usadas', 'all': 'Todas'}, - 'pt': {'common': 'Mais usadas', 'all': 'Todas'}, - 'fr': {'common': 'Plus utilisées', 'all': 'Toutes'}, - 'de': {'common': 'Meist genutzt', 'all': 'Alle'}, - 'it': {'common': 'Più usate', 'all': 'Tutte'}, - 'ru': {'common': 'Популярные', 'all': 'Все'}, - 'zh': {'common': '常用', 'all': '全部'}, - 'ja': {'common': 'よく使われる', 'all': 'すべて'}, - 'ko': {'common': '자주 사용됨', 'all': '모두'}, - 'ar': {'common': 'الأكثر استخداماً', 'all': 'الكل'}, - 'hi': {'common': 'अधिक उपयोग', 'all': 'सभी'}, - 'id': {'common': 'Paling banyak digunakan', 'all': 'Semua'}, - 'ur': {'common': 'سب سے زیادہ استعمال', 'all': 'تمام'}, - }; - - final langTranslations = translations[lang] ?? translations['en']!; - return isCommon ? langTranslations['common']! : langTranslations['all']!; + return currencyFilterTooltip(widget.currencyController.lang, _showOnlyCommon); } } diff --git a/lib/src/view/currency_textfield.dart b/lib/src/view/currency_textfield.dart index 56f2b28..ca13e38 100644 --- a/lib/src/view/currency_textfield.dart +++ b/lib/src/view/currency_textfield.dart @@ -56,6 +56,7 @@ class _CurrencyTextFieldState extends State { enabled: true, // Set readOnly to false to allow user input. readOnly: false, + enableInteractiveSelection: true, textAlign: currency!.position == 'first' ? TextAlign.start : currency!.position == 'last' diff --git a/lib/src/view/currency_textview.dart b/lib/src/view/currency_textview.dart index 8884341..ae695bf 100644 --- a/lib/src/view/currency_textview.dart +++ b/lib/src/view/currency_textview.dart @@ -40,6 +40,7 @@ class _CurrencyTextViewState extends State { @override void initState() { super.initState(); + controller = TextEditingController(); _updateCurrency(); _updateController(); } diff --git a/pubspec.yaml b/pubspec.yaml index 400be95..e76f438 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: currency_widget description: "A currency list of widgets which you can choose or get information about the currency" -version: 1.0.6 +version: 1.0.9 homepage: https://github.com/DecksPlayer/currency_widget repository: https://github.com/DecksPlayer/currency_widget @@ -15,7 +15,7 @@ dependencies: dev_dependencies: flutter_test: sdk: flutter - flutter_lints: ^6.0.0 + flutter_lints: '>=6.0.0 <7.0.0' # For information on the generic Dart part of this file, see the # following page: https://dart.dev/tools/pub/pubspec From 5251ff17669ff433fc799dd8bbd87ba2c0c50e72 Mon Sep 17 00:00:00 2001 From: Gonzalo Juarez Date: Sat, 9 May 2026 02:30:56 -0300 Subject: [PATCH 2/6] feat: add CustomCurrencyPicker, CustomCurrencyChooser, and CurrencyMultiSelector widgets with documentation and example app updates --- README.md | 26 ++++ example/lib/main.dart | 58 ++++++-- lib/currency_widget.dart | 5 +- lib/src/utils/currency_picker_utils.dart | 8 ++ lib/src/view/currency_multi_selector.dart | 107 +++++++++++++++ lib/src/view/custom_currency_chooser.dart | 95 +++++++++++++ lib/src/view/custom_currency_picker.dart | 154 ++++++++++++++++++++++ 7 files changed, 444 insertions(+), 9 deletions(-) create mode 100644 lib/src/view/currency_multi_selector.dart create mode 100644 lib/src/view/custom_currency_chooser.dart create mode 100644 lib/src/view/custom_currency_picker.dart diff --git a/README.md b/README.md index aa716ca..2f93a70 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,15 @@ A lightweight widget to **select a currency without requiring an amount**. Use i * Displays the full localized name of the selected currency. * Exposes the selection via `CurrencyController.currency` and `CurrencyController.currencyNotifier`. +### `CustomCurrencyPicker` +Similar to `CurrencyPicker` (includes amount input), but allows you to restrict the selectable currencies to a specific list of currency codes (e.g., `['USD', 'EUR']`). + +### `CustomCurrencyChooser` +Similar to `CurrencyChooser` (no amount input), but displays the options as selectable chips (`ChoiceChip`) instead of a dropdown, and restricts the selectable currencies to a specific list. + +### `CurrencyMultiSelector` +A widget that allows the user to select multiple currencies at once. It displays currencies as actionable chips (`FilterChip`) in a responsive `Wrap` layout, including a toggle button to switch between favorite and all currencies. + ## Properties per Widget @@ -53,6 +62,9 @@ A lightweight widget to **select a currency without requiring an amount**. Use i | `CurrencyTextView` | `mount`: (required) Amount to display.
`currencyCode`: (required) Code of the currency.
`CurrencyControler` : (required)Manages currency state | | `CurrencyCardReport` | `title`: (required) Title widget for the card.
`icon`: (required) Icon widget for the card.
`mount`: (required) Amount to display.
`currencyCode`: (required) Code of the currency.
`lang`: (required) Language for formatting.
`style`: Text Style | | `CurrencyChooser` | `currencyController`: (required) Manages currency state and exposes the selected currency via `controller.currency` and `controller.currencyNotifier`. | +| `CustomCurrencyPicker`| `currencyController`: (required) Manages currency state.
`currencyCodes`: (required) List of currency codes to allow.
| +| `CustomCurrencyChooser`| `currencyController`: (required) Manages currency state.
`currencyCodes`: (required) List of currency codes to allow.
| +| `CurrencyMultiSelector`| `onChanged`: (required) Callback fired when selection changes.
`initialSelected`: List of initially selected currencies.
`showOnlyCommon`: Toggle between common or all currencies.
| **Note**: All widgets also accept standard Flutter widget properties like `key`, `padding`, `margin`, etc. @@ -151,6 +163,20 @@ class _MyCurrencyScreenState extends State { return Text('Selected: ${currency?.getDefaultView() ?? ''}'); }, ), + SizedBox(height: 20), + // CurrencyMultiSelector: pick multiple currencies at once + CurrencyMultiSelector( + showOnlyCommon: true, + onChanged: (selectedList) { + print('Selected currencies: $selectedList'); + }, + ), + SizedBox(height: 20), + // CustomCurrencyChooser: pick a single currency from a restricted list using chips + CustomCurrencyChooser( + currencyController: _controller, + currencyCodes: ['USD', 'EUR', 'ARS'], + ), ], ), ), diff --git a/example/lib/main.dart b/example/lib/main.dart index 8b00084..51370da 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -42,6 +42,13 @@ class _MyHomePageState extends State { final CurrencyController currencyChooserController = CurrencyController( lang: 'es', ); + + final CurrencyController customCurrencyController = CurrencyController( + lang: 'es', + ); + List _selectedCurrencies = []; + List get _selectedCurrencyCodes => + _selectedCurrencies.map((c) => c.code).toList(); @override Widget build(BuildContext context) { @@ -61,12 +68,13 @@ class _MyHomePageState extends State { // the App.build method, and use it to set our appbar title. title: Text(widget.title), ), - body: Center( - // Center is a layout widget. It takes a single child and positions it - // in the middle of the parent. - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ + body: SingleChildScrollView( + child: Center( + // Center is a layout widget. It takes a single child and positions it + // in the middle of the parent. + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ CurrencyPicker(currencyController: currencyControllerEn), CurrencyTextView( currencyCode: 'usd', @@ -124,9 +132,43 @@ class _MyHomePageState extends State { ); }, ), + const Divider(), + const Text('Multi-Selector & Custom Chooser', style: TextStyle(fontWeight: FontWeight.bold)), + const SizedBox(height: 10), + CurrencyMultiSelector( + showOnlyCommon: true, + initialSelected: _selectedCurrencies, + onChanged: (selected) { + setState(() { + _selectedCurrencies = selected; + }); + }, + ), + if (_selectedCurrencyCodes.isNotEmpty) ...[ + const SizedBox(height: 10), + CustomCurrencyChooser( + currencyController: customCurrencyController, + currencyCodes: _selectedCurrencyCodes, + ), + ListenableBuilder( + listenable: customCurrencyController.currencyNotifier, + builder: (context, child) { + return Text( + 'Custom seleccionada: ${customCurrencyController.currency.getDefaultView()}', + ); + }, + ), + ] else ...[ + const Padding( + padding: EdgeInsets.all(8.0), + child: Text('Selecciona al menos una moneda arriba'), + ), + ], + const SizedBox(height: 40), ], ), - ), // This trailing comma makes auto-formatting nicer for build methods. - ); + ), + ), // closes SingleChildScrollView + ); // closes Scaffold } } diff --git a/lib/currency_widget.dart b/lib/currency_widget.dart index 409ef67..095ee15 100644 --- a/lib/currency_widget.dart +++ b/lib/currency_widget.dart @@ -5,4 +5,7 @@ export 'package:currency_widget/src/Controller/currency_controller.dart'; export 'package:currency_widget/src/view/currency_textview.dart'; export 'package:currency_widget/src/view/currency_textfield.dart'; export 'package:currency_widget/src/view/currency_card_view_report.dart'; -export 'package:currency_widget/src/view/currency_chooser.dart'; \ No newline at end of file +export 'package:currency_widget/src/view/currency_chooser.dart'; +export 'package:currency_widget/src/view/custom_currency_chooser.dart'; +export 'package:currency_widget/src/view/custom_currency_picker.dart'; +export 'package:currency_widget/src/view/currency_multi_selector.dart'; \ No newline at end of file diff --git a/lib/src/utils/currency_picker_utils.dart b/lib/src/utils/currency_picker_utils.dart index 0ab2650..cb26f18 100644 --- a/lib/src/utils/currency_picker_utils.dart +++ b/lib/src/utils/currency_picker_utils.dart @@ -13,6 +13,14 @@ List filteredCurrencies(bool showOnlyCommon) { return supportedCurrencies; } +/// Returns the filtered list of currencies based on a custom list of [codes]. +List customFilteredCurrencies(List codes) { + final upperCodes = codes.map((c) => c.toUpperCase()).toList(); + return supportedCurrencies + .where((c) => upperCodes.contains(c.code.toUpperCase())) + .toList(); +} + /// Returns the localized tooltip text for the common/all toggle button. String currencyFilterTooltip(String lang, bool showOnlyCommon) { const Map> translations = { diff --git a/lib/src/view/currency_multi_selector.dart b/lib/src/view/currency_multi_selector.dart new file mode 100644 index 0000000..ccd41b8 --- /dev/null +++ b/lib/src/view/currency_multi_selector.dart @@ -0,0 +1,107 @@ +import 'package:currency_widget/currency_widget.dart'; +import 'package:currency_widget/src/utils/currency_picker_utils.dart'; +import 'package:flutter/material.dart'; + +/// A widget that displays currencies as actionable chips in a Wrap layout, +/// allowing the user to select multiple currencies. +class CurrencyMultiSelector extends StatefulWidget { + /// Callback fired when the selection changes. + final ValueChanged> onChanged; + + /// The initially selected currencies. + final List initialSelected; + + /// If true, shows only the most common currencies. If false, shows all supported currencies. + final bool showOnlyCommon; + + /// The language code for tooltips (e.g., 'en', 'es'). + final String lang; + + const CurrencyMultiSelector({ + super.key, + required this.onChanged, + this.initialSelected = const [], + this.showOnlyCommon = true, + this.lang = 'en', + }); + + @override + State createState() => _CurrencyMultiSelectorState(); +} + +class _CurrencyMultiSelectorState extends State { + late List _availableCurrencies; + late Set _selectedCurrencies; + + late bool _showOnlyCommon; + + @override + void initState() { + super.initState(); + _showOnlyCommon = widget.showOnlyCommon; + _selectedCurrencies = Set.from(widget.initialSelected); + _availableCurrencies = filteredCurrencies(_showOnlyCommon); + } + + @override + void didUpdateWidget(covariant CurrencyMultiSelector oldWidget) { + super.didUpdateWidget(oldWidget); + if (widget.showOnlyCommon != oldWidget.showOnlyCommon) { + _showOnlyCommon = widget.showOnlyCommon; + _availableCurrencies = filteredCurrencies(_showOnlyCommon); + } + } + + void _toggleSelection(Currency currency) { + setState(() { + if (_selectedCurrencies.contains(currency)) { + _selectedCurrencies.remove(currency); + } else { + _selectedCurrencies.add(currency); + } + }); + widget.onChanged(_selectedCurrencies.toList()); + } + + @override + Widget build(BuildContext context) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Tooltip( + message: currencyFilterTooltip(widget.lang, _showOnlyCommon), + child: IconButton( + icon: Icon( + _showOnlyCommon ? Icons.star : Icons.public, + size: 22, + ), + onPressed: () { + setState(() { + _showOnlyCommon = !_showOnlyCommon; + _availableCurrencies = filteredCurrencies(_showOnlyCommon); + }); + }, + ), + ), + ], + ), + Wrap( + spacing: 8.0, + runSpacing: 8.0, + children: _availableCurrencies.map((currency) { + final isSelected = _selectedCurrencies.contains(currency); + return FilterChip( + label: Text(currency.getDefaultView()), + selected: isSelected, + onSelected: (_) => _toggleSelection(currency), + ); + }).toList(), + ), + ], + ); + } +} diff --git a/lib/src/view/custom_currency_chooser.dart b/lib/src/view/custom_currency_chooser.dart new file mode 100644 index 0000000..fd94830 --- /dev/null +++ b/lib/src/view/custom_currency_chooser.dart @@ -0,0 +1,95 @@ +import 'package:currency_widget/currency_widget.dart'; +import 'package:currency_widget/src/assets/currencies_names/currencies_names.dart'; +import 'package:currency_widget/src/utils/currency_picker_utils.dart'; +import 'package:flutter/material.dart'; + +/// A widget that allows the user to select a currency from a custom list. +/// +/// Use [CustomCurrencyChooser] when you want to restrict the selectable +/// currencies to a specific list of currency codes (e.g., `['USD', 'EUR']`). +class CustomCurrencyChooser extends StatefulWidget { + final CurrencyController currencyController; + final List currencyCodes; + + const CustomCurrencyChooser({ + super.key, + required this.currencyController, + required this.currencyCodes, + }); + + @override + State createState() => _CustomCurrencyChooserState(); +} + +class _CustomCurrencyChooserState extends State { + List _currencies = []; + + @override + void initState() { + super.initState(); + _updateCurrencyList(); + if (_currencies.isNotEmpty) { + widget.currencyController.currency = _currencies[0]; + } + } + + void _updateCurrencyList() { + _currencies = customFilteredCurrencies(widget.currencyCodes); + } + + @override + void didUpdateWidget(covariant CustomCurrencyChooser oldWidget) { + super.didUpdateWidget(oldWidget); + if (widget.currencyCodes != oldWidget.currencyCodes) { + setState(() { + _updateCurrencyList(); + if (_currencies.isNotEmpty && !_currencies.contains(widget.currencyController.currency)) { + widget.currencyController.currency = _currencies[0]; + } + }); + } + } + + @override + Widget build(BuildContext context) { + if (_currencies.isEmpty) { + return const SizedBox.shrink(); + } + + return Container( + margin: const EdgeInsets.all(10), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Wrap( + spacing: 8.0, + runSpacing: 8.0, + children: _currencies.map((currency) { + final isSelected = widget.currencyController.currency == currency; + return ChoiceChip( + label: Text(currency.getDefaultView()), + selected: isSelected, + onSelected: (selected) { + if (selected) { + setState(() { + widget.currencyController.currency = currency; + }); + } + }, + ); + }).toList(), + ), + const SizedBox(height: 8), + Text( + countryNames( + widget.currencyController.lang, + widget.currencyController.currency.code, + ), + style: const TextStyle(fontSize: 13, color: Colors.grey), + ), + ], + ), + ); + } +} diff --git a/lib/src/view/custom_currency_picker.dart b/lib/src/view/custom_currency_picker.dart new file mode 100644 index 0000000..48fe7b3 --- /dev/null +++ b/lib/src/view/custom_currency_picker.dart @@ -0,0 +1,154 @@ +import 'package:currency_widget/currency_widget.dart'; +import 'package:currency_widget/src/assets/currencies_names/currencies_names.dart'; +import 'package:currency_widget/src/utils/currency_picker_utils.dart'; +import 'package:currency_widget/src/utils/masked_text_editing_controller.dart'; +import 'package:flutter/material.dart'; + +/// A widget that allows the user to select a currency from a custom list and input an amount. +/// +/// Use [CustomCurrencyPicker] when you want to restrict the selectable +/// currencies to a specific list of currency codes (e.g., `['USD', 'EUR']`). +class CustomCurrencyPicker extends StatefulWidget { + final CurrencyController currencyController; + final List currencyCodes; + + const CustomCurrencyPicker({ + super.key, + required this.currencyController, + required this.currencyCodes, + }); + + @override + State createState() => _CustomCurrencyPickerState(); +} + +class _CustomCurrencyPickerState extends State { + List _currencies = []; + late TextEditingController controller; + + @override + void initState() { + super.initState(); + _updateCurrencyList(); + if (_currencies.isNotEmpty) { + widget.currencyController.currency = _currencies[0]; + } + + controller = TextEditingController( + text: widget.currencyController.mount.value != null && + widget.currencyController.mount.value! > 0 + ? widget.currencyController.mount.value.toString() + : '', + ); + } + + void _updateCurrencyList() { + _currencies = customFilteredCurrencies(widget.currencyCodes); + } + + @override + void didUpdateWidget(covariant CustomCurrencyPicker oldWidget) { + super.didUpdateWidget(oldWidget); + if (widget.currencyCodes != oldWidget.currencyCodes) { + setState(() { + _updateCurrencyList(); + if (_currencies.isNotEmpty && !_currencies.contains(widget.currencyController.currency)) { + widget.currencyController.currency = _currencies[0]; + final mount = widget.currencyController.mount.value; + if (mount != null && mount > 0) { + controller.text = mount.toStringAsFixed(_currencies[0].decimalDigits); + } + } + }); + } + } + + @override + Widget build(BuildContext context) { + if (_currencies.isEmpty) { + return const SizedBox.shrink(); + } + + return Container( + margin: const EdgeInsets.all(10), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + ListTile( + title: Row( + children: [ + Expanded(child: _buildDropdown()), + ], + ), + subtitle: TextField( + controller: controller, + keyboardType: TextInputType.number, + textAlign: TextAlign.center, + enableInteractiveSelection: true, + decoration: InputDecoration( + hintText: 0.toStringAsFixed( + widget.currencyController.currency.decimalDigits), + labelText: countryNames( + widget.currencyController.lang, + widget.currencyController.currency.code), + prefixText: + widget.currencyController.currency.position == 'first' + ? widget.currencyController.currency.symbol + : null, + suffixText: + widget.currencyController.currency.position == 'last' + ? widget.currencyController.currency.symbol + : null, + ), + onChanged: (str) { + if (str.isEmpty) { + widget.currencyController.mount.value = 0; + return; + } + try { + String value = str.replaceAll(',', ''); + widget.currencyController.mount.value = double.parse(value); + } catch (e) { + widget.currencyController.mount.value = 0; + } + }, + inputFormatters: [ + AutoDecimalNumberFormatter( + decimalDigits: + widget.currencyController.currency.decimalDigits), + ], + ), + ), + ], + ), + ); + } + + DropdownButton _buildDropdown() { + return DropdownButton( + value: widget.currencyController.currency, + isExpanded: true, + onChanged: (Currency? newValue) async { + chooseCurrency(newValue); + }, + items: currencyDropdownItems(_currencies), + ); + } + + void chooseCurrency(Currency? selected) { + if (selected == null) return; + setState(() { + widget.currencyController.currency = selected; + final mount = widget.currencyController.mount.value; + if (mount != null && mount > 0) { + controller.text = mount.toStringAsFixed(selected.decimalDigits); + } + }); + } + + @override + void dispose() { + controller.dispose(); + super.dispose(); + } +} From 38f8770b3800b84c1b9cfd022e0aa59db3ff809c Mon Sep 17 00:00:00 2001 From: Gonzalo Juarez Date: Sun, 10 May 2026 18:39:52 -0300 Subject: [PATCH 3/6] feat: add comprehensive currency data list and update package version --- CHANGELOG.md | 4 ++++ lib/src/assets/supported_currencies.dart | 4 ++-- pubspec.yaml | 2 +- script/currencies/currency.dart | 4 ++-- 4 files changed, 9 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f085893..4878bc9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -80,4 +80,8 @@ ## 1.0.9 * Minor refactor in currencyChooser + + ## 1.0.10 + * Add `CustomCurrencyPicker` and `CustomCurrencyChooser` to restrict selectable currencies to a specific list. + * Add `CurrencyMultiSelector` widget to support selecting multiple currencies simultaneously. \ No newline at end of file diff --git a/lib/src/assets/supported_currencies.dart b/lib/src/assets/supported_currencies.dart index 83f1a6c..96cd0dc 100644 --- a/lib/src/assets/supported_currencies.dart +++ b/lib/src/assets/supported_currencies.dart @@ -559,7 +559,7 @@ final supportedCurrencies = [ Currency( code: "KGS", name: "Kyrgyzstani som", - symbol: "лв", + symbol: "с", emoji: "🇰🇬", decimalDigits: 2, position: "last", @@ -1191,7 +1191,7 @@ final supportedCurrencies = [ Currency( code: "UZS", name: "Uzbekistani soʻm", - symbol: "лв", + symbol: "so'm", emoji: "🇺🇿", decimalDigits: 2, position: "last", diff --git a/pubspec.yaml b/pubspec.yaml index e76f438..78543f6 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: currency_widget description: "A currency list of widgets which you can choose or get information about the currency" -version: 1.0.9 +version: 1.0.11 homepage: https://github.com/DecksPlayer/currency_widget repository: https://github.com/DecksPlayer/currency_widget diff --git a/script/currencies/currency.dart b/script/currencies/currency.dart index d5f2acc..76b2046 100644 --- a/script/currencies/currency.dart +++ b/script/currencies/currency.dart @@ -554,7 +554,7 @@ List> currencies =[ { "code": "KGS", "name": "Kyrgyzstani som", -"symbol": "лв", +"symbol": "с", "emoji": "🇰🇬", "decimal_digits": 2, "position": "last" @@ -1186,7 +1186,7 @@ List> currencies =[ { "code": "UZS", "name": "Uzbekistani soʻm", -"symbol": "лв", +"symbol": "so'm", "emoji": "🇺🇿", "decimal_digits": 2, "position": "last" From 06881ed5c141bc41694c5af1d60d6ee0a5a9ccaf Mon Sep 17 00:00:00 2001 From: Gonzalo Juarez Date: Mon, 11 May 2026 12:55:41 -0300 Subject: [PATCH 4/6] feat: implement CurrencyController and custom currency picker widgets for streamlined currency selection and input --- README.md | 21 ++- example/lib/main.dart | 184 +++++++++++--------- lib/src/Controller/currency_controller.dart | 7 +- lib/src/view/currency_picker.dart | 15 +- lib/src/view/custom_currency_chooser.dart | 19 +- lib/src/view/custom_currency_picker.dart | 19 +- 6 files changed, 172 insertions(+), 93 deletions(-) diff --git a/README.md b/README.md index 2f93a70..6dd1b37 100644 --- a/README.md +++ b/README.md @@ -57,13 +57,13 @@ A widget that allows the user to select multiple currencies at once. It displays | Widget | Properties | |----------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `CurrencyPicker` | `currencyController`: (required) Manages currency state.
| +| `CurrencyPicker` | `currencyController`: (required) Manages currency state.
`defaultCurrencyCode`: (optional) Initial currency to select. | | `CurrencyTextField` | `currencyController`: (required) Manages currency state.
`currencyCode`: (required) Code of the currency to use.
| | `CurrencyTextView` | `mount`: (required) Amount to display.
`currencyCode`: (required) Code of the currency.
`CurrencyControler` : (required)Manages currency state | | `CurrencyCardReport` | `title`: (required) Title widget for the card.
`icon`: (required) Icon widget for the card.
`mount`: (required) Amount to display.
`currencyCode`: (required) Code of the currency.
`lang`: (required) Language for formatting.
`style`: Text Style | | `CurrencyChooser` | `currencyController`: (required) Manages currency state and exposes the selected currency via `controller.currency` and `controller.currencyNotifier`. | -| `CustomCurrencyPicker`| `currencyController`: (required) Manages currency state.
`currencyCodes`: (required) List of currency codes to allow.
| -| `CustomCurrencyChooser`| `currencyController`: (required) Manages currency state.
`currencyCodes`: (required) List of currency codes to allow.
| +| `CustomCurrencyPicker`| `currencyController`: (required) Manages currency state.
`currencyCodes`: (required) List of currency codes to allow.
`defaultCurrencyCode`: (optional) Initial currency to select. | +| `CustomCurrencyChooser`| `currencyController`: (required) Manages currency state.
`currencyCodes`: (required) List of currency codes to allow.
`defaultCurrencyCode`: (optional) Initial currency to select. | | `CurrencyMultiSelector`| `onChanged`: (required) Callback fired when selection changes.
`initialSelected`: List of initially selected currencies.
`showOnlyCommon`: Toggle between common or all currencies.
| **Note**: All widgets also accept standard Flutter widget properties like `key`, `padding`, `margin`, etc. @@ -122,7 +122,7 @@ class MyCurrencyScreen extends StatefulWidget { } class _MyCurrencyScreenState extends State { - final CurrencyController _controller = CurrencyController(); + final CurrencyController _controller = CurrencyController(lang: 'es', initialCurrencyCode: 'EUR'); @override void dispose() { @@ -140,7 +140,10 @@ class _MyCurrencyScreenState extends State { padding: const EdgeInsets.all(16.0), child: Column( children: [ - CurrencyPicker(currencyController: _controller), + CurrencyPicker( + currencyController: _controller, + defaultCurrencyCode: 'EUR', + ), SizedBox(height: 20), // You can listen to changes in the controller ValueListenableBuilder( @@ -176,6 +179,14 @@ class _MyCurrencyScreenState extends State { CustomCurrencyChooser( currencyController: _controller, currencyCodes: ['USD', 'EUR', 'ARS'], + defaultCurrencyCode: 'USD', + ), + SizedBox(height: 20), + // CustomCurrencyPicker: pick a currency from a restricted list with amount input + CustomCurrencyPicker( + currencyController: _controller, + currencyCodes: ['USD', 'GBP', 'JPY'], + defaultCurrencyCode: 'GBP', ), ], ), diff --git a/example/lib/main.dart b/example/lib/main.dart index 51370da..d813b64 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -35,14 +35,19 @@ class _MyHomePageState extends State { final CurrencyController controller = CurrencyController(lang: 'es'); final String currencyCode = 'usd'; - final CurrencyController currencyController = CurrencyController(lang: 'es'); + final CurrencyController currencyController = CurrencyController( + lang: 'es', + initialCurrencyCode: 'ARS', + ); final CurrencyController currencyControllerEn = CurrencyController( lang: 'en', + initialCurrencyCode: 'ARS', ); final CurrencyController currencyChooserController = CurrencyController( lang: 'es', + initialCurrencyCode: 'GBP', ); - + final CurrencyController customCurrencyController = CurrencyController( lang: 'es', ); @@ -75,100 +80,113 @@ class _MyHomePageState extends State { child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - CurrencyPicker(currencyController: currencyControllerEn), - CurrencyTextView( - currencyCode: 'usd', - mount: 250.24, - currencyController: currencyControllerEn, - ), - ListenableBuilder( - listenable: currencyControllerEn.mount, - builder: (context, child) { - return CurrencyTextView( - currencyCode: currencyControllerEn.currency.code, - mount: currencyControllerEn.mount.value ?? 0, - currencyController: currencyControllerEn, - ); - }, - ), - CurrencyTextView( - currencyCode: 'usa', - mount: 250.24, - currencyController: CurrencyController(lang: 'es'), - ), - CurrencyTextField( - currencyCode: currencyCode, - currencyController: currencyController, - ), - SizedBox( - width: 200, - child: CurrencyCardReport( - title: 'Currency Report', - icon: Icon(Icons.currency_exchange), + // Se inicializará con 'EUR' por el controlador + CurrencyPicker(currencyController: currencyControllerEn), + CurrencyTextView( + currencyCode: 'usd', mount: 250.24, - currencyCode: 'eu', - lang: 'en', - style: TextStyle(fontSize: 10, fontWeight: FontWeight.bold), + currencyController: currencyControllerEn, + ), + ListenableBuilder( + listenable: currencyControllerEn.mount, + builder: (context, child) { + return CurrencyTextView( + currencyCode: currencyControllerEn.currency.code, + mount: currencyControllerEn.mount.value ?? 0, + currencyController: currencyControllerEn, + ); + }, ), - ), - SizedBox( - width: 200, - child: CurrencyCardReport( - title: 'Currency Report', - icon: Icon(Icons.currency_exchange), + CurrencyTextView( + currencyCode: 'usa', mount: 250.24, - currencyCode: 'usd', - lang: 'en', + currencyController: CurrencyController(lang: 'es'), ), - ), - const Divider(), - const Text('CurrencyChooser (sin monto)'), - CurrencyChooser(currencyController: currencyChooserController), - ListenableBuilder( - listenable: currencyChooserController.currencyNotifier, - builder: (context, child) { - return Text( - 'Moneda seleccionada: ${currencyChooserController.currency.getDefaultView()}', - ); - }, - ), - const Divider(), - const Text('Multi-Selector & Custom Chooser', style: TextStyle(fontWeight: FontWeight.bold)), - const SizedBox(height: 10), - CurrencyMultiSelector( - showOnlyCommon: true, - initialSelected: _selectedCurrencies, - onChanged: (selected) { - setState(() { - _selectedCurrencies = selected; - }); - }, - ), - if (_selectedCurrencyCodes.isNotEmpty) ...[ - const SizedBox(height: 10), - CustomCurrencyChooser( - currencyController: customCurrencyController, - currencyCodes: _selectedCurrencyCodes, + CurrencyTextField( + currencyCode: currencyCode, + currencyController: currencyController, + ), + SizedBox( + width: 200, + child: CurrencyCardReport( + title: 'Currency Report', + icon: Icon(Icons.currency_exchange), + mount: 250.24, + currencyCode: 'eu', + lang: 'en', + style: TextStyle(fontSize: 10, fontWeight: FontWeight.bold), + ), + ), + SizedBox( + width: 200, + child: CurrencyCardReport( + title: 'Currency Report', + icon: Icon(Icons.currency_exchange), + mount: 250.24, + currencyCode: 'usd', + lang: 'en', + ), ), + const Divider(), + const Text('CurrencyChooser (sin monto)'), + CurrencyChooser(currencyController: currencyChooserController), ListenableBuilder( - listenable: customCurrencyController.currencyNotifier, + listenable: currencyChooserController.currencyNotifier, builder: (context, child) { return Text( - 'Custom seleccionada: ${customCurrencyController.currency.getDefaultView()}', + 'Moneda seleccionada: ${currencyChooserController.currency.getDefaultView()}', ); }, ), - ] else ...[ - const Padding( - padding: EdgeInsets.all(8.0), - child: Text('Selecciona al menos una moneda arriba'), + const Divider(), + const Text( + 'Multi-Selector & Custom Chooser', + style: TextStyle(fontWeight: FontWeight.bold), ), + const SizedBox(height: 10), + CurrencyMultiSelector( + showOnlyCommon: true, + initialSelected: _selectedCurrencies, + onChanged: (selected) { + setState(() { + _selectedCurrencies = selected; + }); + }, + ), + if (_selectedCurrencyCodes.isNotEmpty) ...[ + const SizedBox(height: 10), + CustomCurrencyChooser( + currencyController: customCurrencyController, + currencyCodes: _selectedCurrencyCodes, + // Podemos sobrescribir el del controlador si queremos + defaultCurrencyCode: 'EUR', + ), + const SizedBox(height: 10), + const Text('CustomCurrencyPicker'), + CustomCurrencyPicker( + currencyController: customCurrencyController, + currencyCodes: _selectedCurrencyCodes, + defaultCurrencyCode: 'USD', + ), + ListenableBuilder( + listenable: customCurrencyController.currencyNotifier, + builder: (context, child) { + return Text( + 'Custom seleccionada: ${customCurrencyController.currency.getDefaultView()}', + ); + }, + ), + ] else ...[ + const Padding( + padding: EdgeInsets.all(8.0), + child: Text('Selecciona al menos una moneda arriba'), + ), + ], + const SizedBox(height: 40), ], - const SizedBox(height: 40), - ], + ), ), - ), - ), // closes SingleChildScrollView - ); // closes Scaffold + ), // closes SingleChildScrollView + ); // closes Scaffold } } diff --git a/lib/src/Controller/currency_controller.dart b/lib/src/Controller/currency_controller.dart index 407181c..11e3a30 100644 --- a/lib/src/Controller/currency_controller.dart +++ b/lib/src/Controller/currency_controller.dart @@ -7,7 +7,12 @@ class CurrencyController{ String lang; /// Creates a new `CurrencyController` instance. /// The `lang` parameter is required and specifies the language code for localization. - CurrencyController({required this.lang}); + /// The `initialCurrencyCode` parameter is optional and sets the initial currency. + CurrencyController({required this.lang, String? initialCurrencyCode}) { + if (initialCurrencyCode != null) { + currency = getCurrencyByCode(initialCurrencyCode); + } + } ValueNotifier mount = ValueNotifier(0); ValueNotifier _currency = ValueNotifier(null); diff --git a/lib/src/view/currency_picker.dart b/lib/src/view/currency_picker.dart index 9ef676c..f022b1a 100644 --- a/lib/src/view/currency_picker.dart +++ b/lib/src/view/currency_picker.dart @@ -6,7 +6,8 @@ import 'package:flutter/material.dart'; class CurrencyPicker extends StatefulWidget { final CurrencyController currencyController; - const CurrencyPicker({super.key, required this.currencyController}); + final String? defaultCurrencyCode; + const CurrencyPicker({super.key, required this.currencyController, this.defaultCurrencyCode}); @override State createState() => _CurrencyPicker(); @@ -21,7 +22,17 @@ class _CurrencyPicker extends State { void initState() { super.initState(); _updateCurrencyList(); - widget.currencyController.currency = _currencies[0]; + + if (widget.defaultCurrencyCode != null) { + final defaultCurrency = _currencies.firstWhere( + (c) => + c.code.toLowerCase() == widget.defaultCurrencyCode!.toLowerCase(), + orElse: () => _currencies[0], + ); + widget.currencyController.currency = defaultCurrency; + } else if (widget.currencyController.currencyNotifier.value == null) { + widget.currencyController.currency = _currencies[0]; + } // Initialize controller with current value controller = TextEditingController( diff --git a/lib/src/view/custom_currency_chooser.dart b/lib/src/view/custom_currency_chooser.dart index fd94830..2089026 100644 --- a/lib/src/view/custom_currency_chooser.dart +++ b/lib/src/view/custom_currency_chooser.dart @@ -10,11 +10,13 @@ import 'package:flutter/material.dart'; class CustomCurrencyChooser extends StatefulWidget { final CurrencyController currencyController; final List currencyCodes; + final String? defaultCurrencyCode; const CustomCurrencyChooser({ super.key, required this.currencyController, required this.currencyCodes, + this.defaultCurrencyCode, }); @override @@ -28,7 +30,22 @@ class _CustomCurrencyChooserState extends State { void initState() { super.initState(); _updateCurrencyList(); - if (_currencies.isNotEmpty) { + + if (widget.defaultCurrencyCode != null) { + final defaultCurrency = _currencies.firstWhere( + (c) => + c.code.toLowerCase() == widget.defaultCurrencyCode!.toLowerCase(), + orElse: () => _currencies.isNotEmpty ? _currencies[0] : _currencies[0], + ); + widget.currencyController.currency = defaultCurrency; + } else if (widget.currencyController.currencyNotifier.value == null && + _currencies.isNotEmpty) { + widget.currencyController.currency = _currencies[0]; + } + + // Ensure the selected currency is within the allowed list + if (_currencies.isNotEmpty && + !_currencies.contains(widget.currencyController.currency)) { widget.currencyController.currency = _currencies[0]; } } diff --git a/lib/src/view/custom_currency_picker.dart b/lib/src/view/custom_currency_picker.dart index 48fe7b3..ab889a0 100644 --- a/lib/src/view/custom_currency_picker.dart +++ b/lib/src/view/custom_currency_picker.dart @@ -11,11 +11,13 @@ import 'package:flutter/material.dart'; class CustomCurrencyPicker extends StatefulWidget { final CurrencyController currencyController; final List currencyCodes; + final String? defaultCurrencyCode; const CustomCurrencyPicker({ super.key, required this.currencyController, required this.currencyCodes, + this.defaultCurrencyCode, }); @override @@ -30,7 +32,22 @@ class _CustomCurrencyPickerState extends State { void initState() { super.initState(); _updateCurrencyList(); - if (_currencies.isNotEmpty) { + + if (widget.defaultCurrencyCode != null) { + final defaultCurrency = _currencies.firstWhere( + (c) => + c.code.toLowerCase() == widget.defaultCurrencyCode!.toLowerCase(), + orElse: () => _currencies.isNotEmpty ? _currencies[0] : _currencies[0], + ); + widget.currencyController.currency = defaultCurrency; + } else if (widget.currencyController.currencyNotifier.value == null && + _currencies.isNotEmpty) { + widget.currencyController.currency = _currencies[0]; + } + + // Ensure the selected currency is within the allowed list + if (_currencies.isNotEmpty && + !_currencies.contains(widget.currencyController.currency)) { widget.currencyController.currency = _currencies[0]; } From fc16ff8f8dbef3894a268d396d0841b5457405b3 Mon Sep 17 00:00:00 2001 From: Gonzalo Juarez Date: Mon, 11 May 2026 15:14:47 -0300 Subject: [PATCH 5/6] feat: introduce currency widgets with auto-decimal masking and formatting support --- CHANGELOG.md | 16 +- README.md | 2 +- example/lib/main.dart | 3 +- lib/src/assets/supported_currencies.dart | 346 +++++++++ lib/src/models/currency.dart | 10 +- lib/src/utils/currency_format_utils.dart | 38 + .../utils/masked_text_editing_controller.dart | 4 +- lib/src/view/currency_card_view_report.dart | 7 +- lib/src/view/currency_picker.dart | 24 +- lib/src/view/currency_textfield.dart | 45 +- lib/src/view/currency_textview.dart | 5 +- lib/src/view/custom_currency_picker.dart | 27 +- pubspec.yaml | 2 +- script/currencies/currencies_generator.dart | 2 + script/currencies/currency.dart | 692 +++++++++++++----- 15 files changed, 1022 insertions(+), 201 deletions(-) create mode 100644 lib/src/utils/currency_format_utils.dart diff --git a/CHANGELOG.md b/CHANGELOG.md index 4878bc9..f89416a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -84,4 +84,18 @@ ## 1.0.10 * Add `CustomCurrencyPicker` and `CustomCurrencyChooser` to restrict selectable currencies to a specific list. * Add `CurrencyMultiSelector` widget to support selecting multiple currencies simultaneously. - \ No newline at end of file + + ## 1.0.11 + + * Add default currency selector + + ## 1.0.12 + + * Fix `CurrencyTextField` to display the default amount when the currency is initialized. + +# 1.0.13 + +* Fix pub dev issues. + +# 1.0.14 +* Fix Currency Decimal Format. \ No newline at end of file diff --git a/README.md b/README.md index 6dd1b37..e0097c4 100644 --- a/README.md +++ b/README.md @@ -58,7 +58,7 @@ A widget that allows the user to select multiple currencies at once. It displays | Widget | Properties | |----------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | `CurrencyPicker` | `currencyController`: (required) Manages currency state.
`defaultCurrencyCode`: (optional) Initial currency to select. | -| `CurrencyTextField` | `currencyController`: (required) Manages currency state.
`currencyCode`: (required) Code of the currency to use.
| +| `CurrencyTextField` | `currencyController`: (required) Manages currency state.
`currencyCode`: (required) Code of the currency to use.
`defaultAmount`: (optional) Initial amount to select. | | `CurrencyTextView` | `mount`: (required) Amount to display.
`currencyCode`: (required) Code of the currency.
`CurrencyControler` : (required)Manages currency state | | `CurrencyCardReport` | `title`: (required) Title widget for the card.
`icon`: (required) Icon widget for the card.
`mount`: (required) Amount to display.
`currencyCode`: (required) Code of the currency.
`lang`: (required) Language for formatting.
`style`: Text Style | | `CurrencyChooser` | `currencyController`: (required) Manages currency state and exposes the selected currency via `controller.currency` and `controller.currencyNotifier`. | diff --git a/example/lib/main.dart b/example/lib/main.dart index d813b64..dce6862 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -41,7 +41,7 @@ class _MyHomePageState extends State { ); final CurrencyController currencyControllerEn = CurrencyController( lang: 'en', - initialCurrencyCode: 'ARS', + initialCurrencyCode: 'EUR', ); final CurrencyController currencyChooserController = CurrencyController( lang: 'es', @@ -105,6 +105,7 @@ class _MyHomePageState extends State { CurrencyTextField( currencyCode: currencyCode, currencyController: currencyController, + defaultAmount: 20, ), SizedBox( width: 200, diff --git a/lib/src/assets/supported_currencies.dart b/lib/src/assets/supported_currencies.dart index 96cd0dc..899f8e3 100644 --- a/lib/src/assets/supported_currencies.dart +++ b/lib/src/assets/supported_currencies.dart @@ -11,6 +11,8 @@ final supportedCurrencies = [ emoji: "🇦🇪", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "AFN", @@ -19,6 +21,8 @@ final supportedCurrencies = [ emoji: "🇦🇫", decimalDigits: 2, position: "last", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "ALL", @@ -27,6 +31,8 @@ final supportedCurrencies = [ emoji: "🇦🇱", decimalDigits: 2, position: "last", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "AMD", @@ -35,6 +41,8 @@ final supportedCurrencies = [ emoji: "🇦🇲", decimalDigits: 2, position: "last", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "AOA", @@ -43,6 +51,8 @@ final supportedCurrencies = [ emoji: "🇦🇴", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "ARS", @@ -51,6 +61,8 @@ final supportedCurrencies = [ emoji: "🇦🇷", decimalDigits: 2, position: "first", + thousandSeparator: ".", + decimalSeparator: ",", ), Currency( code: "AUD", @@ -59,6 +71,8 @@ final supportedCurrencies = [ emoji: "🇦🇺", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "AWG", @@ -67,6 +81,8 @@ final supportedCurrencies = [ emoji: "🇦🇼", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "AZN", @@ -75,6 +91,8 @@ final supportedCurrencies = [ emoji: "🇦🇿", decimalDigits: 2, position: "last", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "BAM", @@ -83,6 +101,8 @@ final supportedCurrencies = [ emoji: "🇧🇦", decimalDigits: 2, position: "last", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "BBD", @@ -91,6 +111,8 @@ final supportedCurrencies = [ emoji: "🇧🇧", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "BDT", @@ -99,6 +121,8 @@ final supportedCurrencies = [ emoji: "🇧🇩", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "BGN", @@ -107,6 +131,8 @@ final supportedCurrencies = [ emoji: "🇧🇬", decimalDigits: 2, position: "last", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "BHD", @@ -115,6 +141,8 @@ final supportedCurrencies = [ emoji: "🇧🇭", decimalDigits: 3, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "BIF", @@ -123,6 +151,8 @@ final supportedCurrencies = [ emoji: "🇧🇮", decimalDigits: 0, position: "last", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "BMD", @@ -131,6 +161,8 @@ final supportedCurrencies = [ emoji: "🇧🇲", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "BND", @@ -139,6 +171,8 @@ final supportedCurrencies = [ emoji: "🇧🇳", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "BOB", @@ -147,6 +181,8 @@ final supportedCurrencies = [ emoji: "🇧🇴", decimalDigits: 2, position: "first", + thousandSeparator: ".", + decimalSeparator: ",", ), Currency( code: "BOV", @@ -155,6 +191,8 @@ final supportedCurrencies = [ emoji: "🇧🇴", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "BRL", @@ -163,6 +201,8 @@ final supportedCurrencies = [ emoji: "🇧🇷", decimalDigits: 2, position: "first", + thousandSeparator: ".", + decimalSeparator: ",", ), Currency( code: "BSD", @@ -171,6 +211,8 @@ final supportedCurrencies = [ emoji: "🇧🇸", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "BTN", @@ -179,6 +221,8 @@ final supportedCurrencies = [ emoji: "🇧🇹", decimalDigits: 2, position: "last", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "BWP", @@ -187,6 +231,8 @@ final supportedCurrencies = [ emoji: "🇧🇼", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "BYN", @@ -195,6 +241,8 @@ final supportedCurrencies = [ emoji: "🇧🇾", decimalDigits: 2, position: "last", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "BZD", @@ -203,6 +251,8 @@ final supportedCurrencies = [ emoji: "🇧🇿", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "CAD", @@ -211,6 +261,8 @@ final supportedCurrencies = [ emoji: "🇨🇦", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "CDF", @@ -219,6 +271,8 @@ final supportedCurrencies = [ emoji: "🇨🇩", decimalDigits: 2, position: "last", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "CHF", @@ -227,6 +281,8 @@ final supportedCurrencies = [ emoji: "🇨🇭", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "CLF", @@ -235,6 +291,8 @@ final supportedCurrencies = [ emoji: "🇨🇱", decimalDigits: 4, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "CLP", @@ -243,6 +301,8 @@ final supportedCurrencies = [ emoji: "🇨🇱", decimalDigits: 0, position: "first", + thousandSeparator: ".", + decimalSeparator: ",", ), Currency( code: "CNY", @@ -251,6 +311,8 @@ final supportedCurrencies = [ emoji: "🇨🇳", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "COP", @@ -259,6 +321,8 @@ final supportedCurrencies = [ emoji: "🇨🇴", decimalDigits: 2, position: "first", + thousandSeparator: ".", + decimalSeparator: ",", ), Currency( code: "COU", @@ -267,6 +331,8 @@ final supportedCurrencies = [ emoji: "🇨🇴", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "CRC", @@ -275,6 +341,8 @@ final supportedCurrencies = [ emoji: "🇨🇷", decimalDigits: 2, position: "first", + thousandSeparator: ".", + decimalSeparator: ",", ), Currency( code: "CUP", @@ -283,6 +351,8 @@ final supportedCurrencies = [ emoji: "🇨🇺", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "CVE", @@ -291,6 +361,8 @@ final supportedCurrencies = [ emoji: "🇨🇻", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "CZK", @@ -299,6 +371,8 @@ final supportedCurrencies = [ emoji: "🇨🇿", decimalDigits: 2, position: "last", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "DJF", @@ -307,6 +381,8 @@ final supportedCurrencies = [ emoji: "🇩🇯", decimalDigits: 0, position: "last", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "DKK", @@ -315,6 +391,8 @@ final supportedCurrencies = [ emoji: "🇩🇰", decimalDigits: 2, position: "last", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "DOP", @@ -323,6 +401,8 @@ final supportedCurrencies = [ emoji: "🇩🇴", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "DZD", @@ -331,6 +411,8 @@ final supportedCurrencies = [ emoji: "🇩🇿", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "EGP", @@ -339,6 +421,8 @@ final supportedCurrencies = [ emoji: "🇪🇬", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "ERN", @@ -347,6 +431,8 @@ final supportedCurrencies = [ emoji: "🇪🇷", decimalDigits: 2, position: "last", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "ETB", @@ -355,6 +441,8 @@ final supportedCurrencies = [ emoji: "🇪🇹", decimalDigits: 2, position: "last", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "EUR", @@ -363,6 +451,8 @@ final supportedCurrencies = [ emoji: "🇪🇺", decimalDigits: 2, position: "first", + thousandSeparator: ".", + decimalSeparator: ",", ), Currency( code: "FJD", @@ -371,6 +461,8 @@ final supportedCurrencies = [ emoji: "🇫🇯", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "FKP", @@ -379,6 +471,8 @@ final supportedCurrencies = [ emoji: "🇫🇰", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "GBP", @@ -387,6 +481,8 @@ final supportedCurrencies = [ emoji: "🇬🇧", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "GEL", @@ -395,6 +491,8 @@ final supportedCurrencies = [ emoji: "🇬🇪", decimalDigits: 2, position: "last", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "GHS", @@ -403,6 +501,8 @@ final supportedCurrencies = [ emoji: "🇬🇭", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "GIP", @@ -411,6 +511,8 @@ final supportedCurrencies = [ emoji: "🇬🇮", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "GMD", @@ -419,6 +521,8 @@ final supportedCurrencies = [ emoji: "🇬🇲", decimalDigits: 2, position: "last", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "GNF", @@ -427,6 +531,8 @@ final supportedCurrencies = [ emoji: "🇬🇳", decimalDigits: 0, position: "last", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "GTQ", @@ -435,6 +541,8 @@ final supportedCurrencies = [ emoji: "🇬🇹", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "GYD", @@ -443,6 +551,8 @@ final supportedCurrencies = [ emoji: "🇬🇾", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "HKD", @@ -451,6 +561,8 @@ final supportedCurrencies = [ emoji: "🇭🇰", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "HNL", @@ -459,6 +571,8 @@ final supportedCurrencies = [ emoji: "🇭🇳", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "HTG", @@ -467,6 +581,8 @@ final supportedCurrencies = [ emoji: "🇭🇹", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "HUF", @@ -475,6 +591,8 @@ final supportedCurrencies = [ emoji: "🇭🇺", decimalDigits: 0, position: "last", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "IDR", @@ -483,6 +601,8 @@ final supportedCurrencies = [ emoji: "🇮🇩", decimalDigits: 0, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "ILS", @@ -491,6 +611,8 @@ final supportedCurrencies = [ emoji: "🇮🇱", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "INR", @@ -499,6 +621,8 @@ final supportedCurrencies = [ emoji: "🇮🇳", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "IQD", @@ -507,6 +631,8 @@ final supportedCurrencies = [ emoji: "🇮🇶", decimalDigits: 3, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "IRR", @@ -515,6 +641,8 @@ final supportedCurrencies = [ emoji: "🇮🇷", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "ISK", @@ -523,6 +651,8 @@ final supportedCurrencies = [ emoji: "🇮🇸", decimalDigits: 0, position: "last", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "JMD", @@ -531,6 +661,8 @@ final supportedCurrencies = [ emoji: "🇯🇲", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "JOD", @@ -539,6 +671,8 @@ final supportedCurrencies = [ emoji: "🇯🇴", decimalDigits: 3, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "JPY", @@ -547,6 +681,8 @@ final supportedCurrencies = [ emoji: "🇯🇵", decimalDigits: 0, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "KES", @@ -555,6 +691,8 @@ final supportedCurrencies = [ emoji: "🇰🇪", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "KGS", @@ -563,6 +701,8 @@ final supportedCurrencies = [ emoji: "🇰🇬", decimalDigits: 2, position: "last", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "KHR", @@ -571,6 +711,8 @@ final supportedCurrencies = [ emoji: "🇰🇭", decimalDigits: 2, position: "last", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "KMF", @@ -579,6 +721,8 @@ final supportedCurrencies = [ emoji: "🇰🇲", decimalDigits: 0, position: "last", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "KPW", @@ -587,6 +731,8 @@ final supportedCurrencies = [ emoji: "🇰🇵", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "KRW", @@ -595,6 +741,8 @@ final supportedCurrencies = [ emoji: "🇰🇷", decimalDigits: 0, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "KWD", @@ -603,6 +751,8 @@ final supportedCurrencies = [ emoji: "🇰🇼", decimalDigits: 3, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "KYD", @@ -611,6 +761,8 @@ final supportedCurrencies = [ emoji: "🇰🇾", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "KZT", @@ -619,6 +771,8 @@ final supportedCurrencies = [ emoji: "🇰🇿", decimalDigits: 2, position: "last", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "LAK", @@ -627,6 +781,8 @@ final supportedCurrencies = [ emoji: "🇱🇦", decimalDigits: 2, position: "last", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "LBP", @@ -635,6 +791,8 @@ final supportedCurrencies = [ emoji: "🇱🇧", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "LKR", @@ -643,6 +801,8 @@ final supportedCurrencies = [ emoji: "🇱🇰", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "LRD", @@ -651,6 +811,8 @@ final supportedCurrencies = [ emoji: "🇱🇷", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "LSL", @@ -659,6 +821,8 @@ final supportedCurrencies = [ emoji: "🇱🇸", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "LYD", @@ -667,6 +831,8 @@ final supportedCurrencies = [ emoji: "🇱🇾", decimalDigits: 3, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "MAD", @@ -675,6 +841,8 @@ final supportedCurrencies = [ emoji: "🇲🇦", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "MDL", @@ -683,6 +851,8 @@ final supportedCurrencies = [ emoji: "🇲🇩", decimalDigits: 2, position: "last", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "MGA", @@ -691,6 +861,8 @@ final supportedCurrencies = [ emoji: "🇲🇬", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "MKD", @@ -699,6 +871,8 @@ final supportedCurrencies = [ emoji: "🇲🇰", decimalDigits: 2, position: "last", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "MMK", @@ -707,6 +881,8 @@ final supportedCurrencies = [ emoji: "🇲🇲", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "MNT", @@ -715,6 +891,8 @@ final supportedCurrencies = [ emoji: "🇲🇳", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "MOP", @@ -723,6 +901,8 @@ final supportedCurrencies = [ emoji: "🇲🇴", decimalDigits: 2, position: "last", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "MRU", @@ -731,6 +911,8 @@ final supportedCurrencies = [ emoji: "🇲🇷", decimalDigits: 2, position: "last", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "MUR", @@ -739,6 +921,8 @@ final supportedCurrencies = [ emoji: "🇲🇺", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "MVR", @@ -747,6 +931,8 @@ final supportedCurrencies = [ emoji: "🇲🇻", decimalDigits: 2, position: "last", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "MWK", @@ -755,6 +941,8 @@ final supportedCurrencies = [ emoji: "🇲🇼", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "MXN", @@ -763,6 +951,8 @@ final supportedCurrencies = [ emoji: "🇲🇽", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "MXV", @@ -771,6 +961,8 @@ final supportedCurrencies = [ emoji: "🇲🇽", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "MYR", @@ -779,6 +971,8 @@ final supportedCurrencies = [ emoji: "🇲🇾", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "MZN", @@ -787,6 +981,8 @@ final supportedCurrencies = [ emoji: "🇲🇿", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "NAD", @@ -795,6 +991,8 @@ final supportedCurrencies = [ emoji: "🇳🇦", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "NGN", @@ -803,6 +1001,8 @@ final supportedCurrencies = [ emoji: "🇳🇬", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "NIO", @@ -811,6 +1011,8 @@ final supportedCurrencies = [ emoji: "🇳🇮", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "NOK", @@ -819,6 +1021,8 @@ final supportedCurrencies = [ emoji: "🇳🇴", decimalDigits: 2, position: "last", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "NPR", @@ -827,6 +1031,8 @@ final supportedCurrencies = [ emoji: "🇳🇵", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "NZD", @@ -835,6 +1041,8 @@ final supportedCurrencies = [ emoji: "🇳🇿", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "OMR", @@ -843,6 +1051,8 @@ final supportedCurrencies = [ emoji: "🇴🇲", decimalDigits: 3, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "PAB", @@ -851,6 +1061,8 @@ final supportedCurrencies = [ emoji: "🇵🇦", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "PEN", @@ -859,6 +1071,8 @@ final supportedCurrencies = [ emoji: "🇵🇪", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "PGK", @@ -867,6 +1081,8 @@ final supportedCurrencies = [ emoji: "🇵🇬", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "PHP", @@ -875,6 +1091,8 @@ final supportedCurrencies = [ emoji: "🇵🇭", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "PKR", @@ -883,6 +1101,8 @@ final supportedCurrencies = [ emoji: "🇵🇰", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "PLN", @@ -891,6 +1111,8 @@ final supportedCurrencies = [ emoji: "🇵🇱", decimalDigits: 2, position: "last", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "PYG", @@ -899,6 +1121,8 @@ final supportedCurrencies = [ emoji: "🇵🇾", decimalDigits: 0, position: "first", + thousandSeparator: ".", + decimalSeparator: ",", ), Currency( code: "QAR", @@ -907,6 +1131,8 @@ final supportedCurrencies = [ emoji: "🇶🇦", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "RON", @@ -915,6 +1141,8 @@ final supportedCurrencies = [ emoji: "🇷🇴", decimalDigits: 2, position: "last", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "RSD", @@ -923,6 +1151,8 @@ final supportedCurrencies = [ emoji: "🇷🇸", decimalDigits: 2, position: "last", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "RUB", @@ -931,6 +1161,8 @@ final supportedCurrencies = [ emoji: "🇷🇺", decimalDigits: 2, position: "last", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "RWF", @@ -939,6 +1171,8 @@ final supportedCurrencies = [ emoji: "🇷🇼", decimalDigits: 0, position: "last", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "SAR", @@ -947,6 +1181,8 @@ final supportedCurrencies = [ emoji: "🇸🇦", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "SBD", @@ -955,6 +1191,8 @@ final supportedCurrencies = [ emoji: "🇸🇧", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "SCR", @@ -963,6 +1201,8 @@ final supportedCurrencies = [ emoji: "🇸🇨", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "SDG", @@ -971,6 +1211,8 @@ final supportedCurrencies = [ emoji: "🇸🇩", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "SEK", @@ -979,6 +1221,8 @@ final supportedCurrencies = [ emoji: "🇸🇪", decimalDigits: 2, position: "last", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "SGD", @@ -987,6 +1231,8 @@ final supportedCurrencies = [ emoji: "🇸🇬", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "SHP", @@ -995,6 +1241,8 @@ final supportedCurrencies = [ emoji: "🇸🇭", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "SLE", @@ -1003,6 +1251,8 @@ final supportedCurrencies = [ emoji: "🇸🇱", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "SOS", @@ -1011,6 +1261,8 @@ final supportedCurrencies = [ emoji: "🇸🇴", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "SRD", @@ -1019,6 +1271,8 @@ final supportedCurrencies = [ emoji: "🇸🇷", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "SSP", @@ -1027,6 +1281,8 @@ final supportedCurrencies = [ emoji: "🇸🇸", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "STN", @@ -1035,6 +1291,8 @@ final supportedCurrencies = [ emoji: "🇸🇹", decimalDigits: 2, position: "last", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "SVC", @@ -1043,6 +1301,8 @@ final supportedCurrencies = [ emoji: "🇸🇻", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "SYP", @@ -1051,6 +1311,8 @@ final supportedCurrencies = [ emoji: "🇸🇾", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "SZL", @@ -1059,6 +1321,8 @@ final supportedCurrencies = [ emoji: "🇸🇿", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "THB", @@ -1067,6 +1331,8 @@ final supportedCurrencies = [ emoji: "🇹🇭", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "TJS", @@ -1075,6 +1341,8 @@ final supportedCurrencies = [ emoji: "🇹🇯", decimalDigits: 2, position: "last", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "TMT", @@ -1083,6 +1351,8 @@ final supportedCurrencies = [ emoji: "🇹🇲", decimalDigits: 2, position: "last", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "TND", @@ -1091,6 +1361,8 @@ final supportedCurrencies = [ emoji: "🇹🇳", decimalDigits: 3, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "TOP", @@ -1099,6 +1371,8 @@ final supportedCurrencies = [ emoji: "🇹🇴", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "TRY", @@ -1107,6 +1381,8 @@ final supportedCurrencies = [ emoji: "🇹🇷", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "TTD", @@ -1115,6 +1391,8 @@ final supportedCurrencies = [ emoji: "🇹🇹", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "TWD", @@ -1123,6 +1401,8 @@ final supportedCurrencies = [ emoji: "🇹🇼", decimalDigits: 0, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "TZS", @@ -1131,6 +1411,8 @@ final supportedCurrencies = [ emoji: "🇹🇿", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "UAH", @@ -1139,6 +1421,8 @@ final supportedCurrencies = [ emoji: "🇺🇦", decimalDigits: 2, position: "last", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "UGX", @@ -1147,6 +1431,8 @@ final supportedCurrencies = [ emoji: "🇺🇬", decimalDigits: 0, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "USD", @@ -1155,6 +1441,8 @@ final supportedCurrencies = [ emoji: "🇺🇸", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "USN", @@ -1163,6 +1451,8 @@ final supportedCurrencies = [ emoji: "🇺🇸", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "UYI", @@ -1171,6 +1461,8 @@ final supportedCurrencies = [ emoji: "🇺🇾", decimalDigits: 0, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "UYU", @@ -1179,6 +1471,8 @@ final supportedCurrencies = [ emoji: "🇺🇾", decimalDigits: 2, position: "first", + thousandSeparator: ".", + decimalSeparator: ",", ), Currency( code: "UYW", @@ -1187,6 +1481,8 @@ final supportedCurrencies = [ emoji: "🇺🇾", decimalDigits: 4, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "UZS", @@ -1195,6 +1491,8 @@ final supportedCurrencies = [ emoji: "🇺🇿", decimalDigits: 2, position: "last", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "VES", @@ -1203,6 +1501,8 @@ final supportedCurrencies = [ emoji: "🇻🇪", decimalDigits: 2, position: "first", + thousandSeparator: ".", + decimalSeparator: ",", ), Currency( code: "VND", @@ -1211,6 +1511,8 @@ final supportedCurrencies = [ emoji: "🇻🇳", decimalDigits: 0, position: "last", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "VUV", @@ -1219,6 +1521,8 @@ final supportedCurrencies = [ emoji: "🇻🇺", decimalDigits: 0, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "WST", @@ -1227,6 +1531,8 @@ final supportedCurrencies = [ emoji: "🇼🇸", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "XAF", @@ -1235,6 +1541,8 @@ final supportedCurrencies = [ emoji: "🇨🇲", decimalDigits: 0, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "XAG", @@ -1243,6 +1551,8 @@ final supportedCurrencies = [ emoji: "🪙", decimalDigits: 0, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "XAU", @@ -1251,6 +1561,8 @@ final supportedCurrencies = [ emoji: "🪙", decimalDigits: 0, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "XBA", @@ -1259,6 +1571,8 @@ final supportedCurrencies = [ emoji: "🇪🇺", decimalDigits: 0, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "XBB", @@ -1267,6 +1581,8 @@ final supportedCurrencies = [ emoji: "🇪🇺", decimalDigits: 0, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "XBC", @@ -1275,6 +1591,8 @@ final supportedCurrencies = [ emoji: "🇪🇺", decimalDigits: 0, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "XBD", @@ -1283,6 +1601,8 @@ final supportedCurrencies = [ emoji: "🇪🇺", decimalDigits: 0, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "XCD", @@ -1291,6 +1611,8 @@ final supportedCurrencies = [ emoji: "🇰🇳", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "XDR", @@ -1299,6 +1621,8 @@ final supportedCurrencies = [ emoji: "🏦", decimalDigits: 0, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "XOF", @@ -1307,6 +1631,8 @@ final supportedCurrencies = [ emoji: "🇨🇮", decimalDigits: 0, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "XPD", @@ -1315,6 +1641,8 @@ final supportedCurrencies = [ emoji: "🪙", decimalDigits: 0, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "XPF", @@ -1323,6 +1651,8 @@ final supportedCurrencies = [ emoji: "🇵🇫", decimalDigits: 0, position: "last", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "XPT", @@ -1331,6 +1661,8 @@ final supportedCurrencies = [ emoji: "🪙", decimalDigits: 0, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "XSU", @@ -1339,6 +1671,8 @@ final supportedCurrencies = [ emoji: "🇪🇨", decimalDigits: 0, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "XTS", @@ -1347,6 +1681,8 @@ final supportedCurrencies = [ emoji: "❓", decimalDigits: 0, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "XUA", @@ -1355,6 +1691,8 @@ final supportedCurrencies = [ emoji: "🏦", decimalDigits: 0, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "YER", @@ -1363,6 +1701,8 @@ final supportedCurrencies = [ emoji: "🇾🇪", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "ZAR", @@ -1371,6 +1711,8 @@ final supportedCurrencies = [ emoji: "🇿🇦", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "ZMW", @@ -1379,6 +1721,8 @@ final supportedCurrencies = [ emoji: "🇿🇲", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), Currency( code: "ZWL", @@ -1387,5 +1731,7 @@ final supportedCurrencies = [ emoji: "🇿🇼", decimalDigits: 2, position: "first", + thousandSeparator: ",", + decimalSeparator: ".", ), ]; diff --git a/lib/src/models/currency.dart b/lib/src/models/currency.dart index affc1e4..bfdc0d8 100644 --- a/lib/src/models/currency.dart +++ b/lib/src/models/currency.dart @@ -7,6 +7,8 @@ class Currency{ String emoji; int decimalDigits; String position; + String thousandSeparator; + String decimalSeparator; Currency({ required this.code, @@ -14,7 +16,9 @@ class Currency{ required this.symbol, required this.emoji, required this.decimalDigits, - required this.position + required this.position, + this.thousandSeparator = ',', + this.decimalSeparator = '.', }); factory Currency.fromJson(Map json) { @@ -25,6 +29,8 @@ class Currency{ emoji: json['emoji'] as String? ?? '', decimalDigits: json['decimal_digits'] as int? ?? 0, position: json['position'] as String? ?? '', + thousandSeparator: json['thousand_separator'] as String? ?? ',', + decimalSeparator: json['decimal_separator'] as String? ?? '.', ); } @@ -37,6 +43,8 @@ class Currency{ 'emoji': emoji, 'decimal_digits': decimalDigits, 'position': position, + 'thousand_separator': thousandSeparator, + 'decimal_separator': decimalSeparator, }; } diff --git a/lib/src/utils/currency_format_utils.dart b/lib/src/utils/currency_format_utils.dart new file mode 100644 index 0000000..3462e82 --- /dev/null +++ b/lib/src/utils/currency_format_utils.dart @@ -0,0 +1,38 @@ +import '../models/currency.dart'; + +class CurrencyFormatUtils { + /// Formats a [double] amount into a string using the [Currency] object's separators. + static String formatAmount(double amount, Currency currency) { + String integerPart; + String decimalPart = ''; + + final decimalDigits = currency.decimalDigits; + final decimalSeparator = currency.decimalSeparator; + final thousandSeparator = currency.thousandSeparator; + + // Convert to fixed string with proper decimal digits + String fixedString = amount.toStringAsFixed(decimalDigits); + + List parts = fixedString.split('.'); + integerPart = parts[0]; + if (parts.length > 1) { + decimalPart = parts[1]; + } + + // Apply thousands separator + String formattedInt = ''; + for (int i = 0; i < integerPart.length; i++) { + final reversedIndex = integerPart.length - i - 1; + formattedInt = integerPart[reversedIndex] + formattedInt; + if ((i + 1) % 3 == 0 && reversedIndex != 0 && integerPart[reversedIndex - 1] != '-') { + formattedInt = thousandSeparator + formattedInt; + } + } + + if (decimalDigits == 0) { + return formattedInt; + } else { + return '$formattedInt$decimalSeparator$decimalPart'; + } + } +} diff --git a/lib/src/utils/masked_text_editing_controller.dart b/lib/src/utils/masked_text_editing_controller.dart index 0bb113b..7cc3b14 100644 --- a/lib/src/utils/masked_text_editing_controller.dart +++ b/lib/src/utils/masked_text_editing_controller.dart @@ -20,8 +20,8 @@ class AutoDecimalNumberFormatter extends TextInputFormatter { /// - `thousandSeparator`: ',' AutoDecimalNumberFormatter({ this.decimalDigits = 2, - this.decimalSeparator = '.', - this.thousandSeparator = ',', + required this.decimalSeparator, + required this.thousandSeparator, }); @override TextEditingValue formatEditUpdate( diff --git a/lib/src/view/currency_card_view_report.dart b/lib/src/view/currency_card_view_report.dart index 28eded2..6209d01 100644 --- a/lib/src/view/currency_card_view_report.dart +++ b/lib/src/view/currency_card_view_report.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import '../../currency_widget.dart'; +import '../utils/currency_format_utils.dart'; class CurrencyCardReport extends StatefulWidget { final String title; @@ -38,8 +39,10 @@ class _CurrencyCardReportState extends State { currencyController.currency = currency; textController = TextEditingController( - text: currencyController.mount.value - ?.toStringAsFixed(currency?.decimalDigits ?? 0), + text: currencyController.mount.value != null && currency != null + ? CurrencyFormatUtils.formatAmount( + currencyController.mount.value!, currency!) + : '', ); } diff --git a/lib/src/view/currency_picker.dart b/lib/src/view/currency_picker.dart index f022b1a..445ff7d 100644 --- a/lib/src/view/currency_picker.dart +++ b/lib/src/view/currency_picker.dart @@ -1,5 +1,6 @@ import 'package:currency_widget/currency_widget.dart'; import 'package:currency_widget/src/assets/currencies_names/currencies_names.dart'; +import 'package:currency_widget/src/utils/currency_format_utils.dart'; import 'package:currency_widget/src/utils/currency_picker_utils.dart'; import 'package:currency_widget/src/utils/masked_text_editing_controller.dart'; import 'package:flutter/material.dart'; @@ -35,10 +36,11 @@ class _CurrencyPicker extends State { } // Initialize controller with current value + final mount = widget.currencyController.mount.value; controller = TextEditingController( - text: widget.currencyController.mount.value != null && - widget.currencyController.mount.value! > 0 - ? widget.currencyController.mount.value.toString() + text: mount != null && mount > 0 + ? CurrencyFormatUtils.formatAmount( + mount, widget.currencyController.currency) : '', ); @@ -104,9 +106,12 @@ class _CurrencyPicker extends State { widget.currencyController.mount.value = 0; return; } + final currency = widget.currencyController.currency; try { // Usar str en lugar de controller.text para evitar conflictos - String value = str.replaceAll(',', ''); + String value = str + .replaceAll(currency.thousandSeparator, '') + .replaceAll(currency.decimalSeparator, '.'); widget.currencyController.mount.value = double.parse(value); } catch (e) { // Invalid input, ignore @@ -115,8 +120,13 @@ class _CurrencyPicker extends State { }, inputFormatters: [ AutoDecimalNumberFormatter( - decimalDigits: - widget.currencyController.currency.decimalDigits), + decimalDigits: + widget.currencyController.currency.decimalDigits, + thousandSeparator: + widget.currencyController.currency.thousandSeparator, + decimalSeparator: + widget.currencyController.currency.decimalSeparator, + ), ], ), ), @@ -144,7 +154,7 @@ class _CurrencyPicker extends State { // Update TextField formatting when currency changes final mount = widget.currencyController.mount.value; if (mount != null && mount > 0) { - controller.text = mount.toStringAsFixed(selected.decimalDigits); + controller.text = CurrencyFormatUtils.formatAmount(mount, selected); } }); } diff --git a/lib/src/view/currency_textfield.dart b/lib/src/view/currency_textfield.dart index ca13e38..37f746c 100644 --- a/lib/src/view/currency_textfield.dart +++ b/lib/src/view/currency_textfield.dart @@ -4,15 +4,18 @@ import 'package:flutter/material.dart'; import '../../currency_widget.dart'; import '../utils/currency_errors.dart'; import '../utils/masked_text_editing_controller.dart'; +import '../utils/currency_format_utils.dart'; class CurrencyTextField extends StatefulWidget { final String currencyCode; final CurrencyController? currencyController; + final double? defaultAmount; const CurrencyTextField({ super.key, required this.currencyCode, required this.currencyController, + this.defaultAmount, }); @override @@ -26,8 +29,39 @@ class _CurrencyTextFieldState extends State { @override void initState() { super.initState(); - controller = TextEditingController(); - currency = widget.currencyController!.getCurrencyByCode(widget.currencyCode); + _updateCurrency(); + + if (widget.defaultAmount != null && + (widget.currencyController?.mount.value == null || + widget.currencyController?.mount.value == 0)) { + widget.currencyController?.mount.value = widget.defaultAmount; + } + + final initialMount = widget.currencyController?.mount.value; + controller = TextEditingController( + text: initialMount != null && initialMount > 0 && currency != null + ? CurrencyFormatUtils.formatAmount(initialMount, currency!) + : '', + ); + } + + void _updateCurrency() { + currency = + widget.currencyController?.getCurrencyByCode(widget.currencyCode); + } + + @override + void didUpdateWidget(covariant CurrencyTextField oldWidget) { + super.didUpdateWidget(oldWidget); + if (widget.currencyCode != oldWidget.currencyCode) { + setState(() { + _updateCurrency(); + final mount = widget.currencyController?.mount.value; + if (mount != null && mount > 0 && currency != null) { + controller.text = CurrencyFormatUtils.formatAmount(mount, currency!); + } + }); + } } @override @@ -67,7 +101,10 @@ class _CurrencyTextFieldState extends State { controller: controller, onChanged: (str) { // Usar str en lugar de controller.text para evitar conflictos - String value = str.replaceAll(',', ''); + // Remover separador de miles y reemplazar separador decimal por punto para parsear + String value = str + .replaceAll(currency!.thousandSeparator, '') + .replaceAll(currency!.decimalSeparator, '.'); try { widget.currencyController!.mount.value = double.parse(value); @@ -79,6 +116,8 @@ class _CurrencyTextFieldState extends State { inputFormatters: [ AutoDecimalNumberFormatter( decimalDigits: currency!.decimalDigits, + thousandSeparator: currency!.thousandSeparator, + decimalSeparator: currency!.decimalSeparator, ), ])), ) diff --git a/lib/src/view/currency_textview.dart b/lib/src/view/currency_textview.dart index ae695bf..8308f0c 100644 --- a/lib/src/view/currency_textview.dart +++ b/lib/src/view/currency_textview.dart @@ -3,6 +3,7 @@ import 'package:flutter/material.dart'; import '../../currency_widget.dart'; import '../utils/currency_errors.dart'; +import '../utils/currency_format_utils.dart'; ///[CurrencyTextView] /// @@ -63,7 +64,9 @@ class _CurrencyTextViewState extends State { } void _updateController() { - controller.text = widget.mount.toStringAsFixed(currency?.decimalDigits ?? 0); + controller.text = currency != null + ? CurrencyFormatUtils.formatAmount(widget.mount, currency!) + : widget.mount.toStringAsFixed(0); } @override diff --git a/lib/src/view/custom_currency_picker.dart b/lib/src/view/custom_currency_picker.dart index ab889a0..64dac03 100644 --- a/lib/src/view/custom_currency_picker.dart +++ b/lib/src/view/custom_currency_picker.dart @@ -1,5 +1,6 @@ import 'package:currency_widget/currency_widget.dart'; import 'package:currency_widget/src/assets/currencies_names/currencies_names.dart'; +import 'package:currency_widget/src/utils/currency_format_utils.dart'; import 'package:currency_widget/src/utils/currency_picker_utils.dart'; import 'package:currency_widget/src/utils/masked_text_editing_controller.dart'; import 'package:flutter/material.dart'; @@ -51,10 +52,11 @@ class _CustomCurrencyPickerState extends State { widget.currencyController.currency = _currencies[0]; } + final mount = widget.currencyController.mount.value; controller = TextEditingController( - text: widget.currencyController.mount.value != null && - widget.currencyController.mount.value! > 0 - ? widget.currencyController.mount.value.toString() + text: mount != null && mount > 0 + ? CurrencyFormatUtils.formatAmount( + mount, widget.currencyController.currency) : '', ); } @@ -73,7 +75,8 @@ class _CustomCurrencyPickerState extends State { widget.currencyController.currency = _currencies[0]; final mount = widget.currencyController.mount.value; if (mount != null && mount > 0) { - controller.text = mount.toStringAsFixed(_currencies[0].decimalDigits); + controller.text = + CurrencyFormatUtils.formatAmount(mount, _currencies[0]); } } }); @@ -122,8 +125,11 @@ class _CustomCurrencyPickerState extends State { widget.currencyController.mount.value = 0; return; } + final currency = widget.currencyController.currency; try { - String value = str.replaceAll(',', ''); + String value = str + .replaceAll(currency.thousandSeparator, '') + .replaceAll(currency.decimalSeparator, '.'); widget.currencyController.mount.value = double.parse(value); } catch (e) { widget.currencyController.mount.value = 0; @@ -131,8 +137,13 @@ class _CustomCurrencyPickerState extends State { }, inputFormatters: [ AutoDecimalNumberFormatter( - decimalDigits: - widget.currencyController.currency.decimalDigits), + decimalDigits: + widget.currencyController.currency.decimalDigits, + thousandSeparator: + widget.currencyController.currency.thousandSeparator, + decimalSeparator: + widget.currencyController.currency.decimalSeparator, + ), ], ), ), @@ -158,7 +169,7 @@ class _CustomCurrencyPickerState extends State { widget.currencyController.currency = selected; final mount = widget.currencyController.mount.value; if (mount != null && mount > 0) { - controller.text = mount.toStringAsFixed(selected.decimalDigits); + controller.text = CurrencyFormatUtils.formatAmount(mount, selected); } }); } diff --git a/pubspec.yaml b/pubspec.yaml index 78543f6..a7be60f 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: currency_widget description: "A currency list of widgets which you can choose or get information about the currency" -version: 1.0.11 +version: 1.0.13 homepage: https://github.com/DecksPlayer/currency_widget repository: https://github.com/DecksPlayer/currency_widget diff --git a/script/currencies/currencies_generator.dart b/script/currencies/currencies_generator.dart index 0aaba51..4c4098b 100755 --- a/script/currencies/currencies_generator.dart +++ b/script/currencies/currencies_generator.dart @@ -21,6 +21,8 @@ void main() async { buffer.writeln(' emoji: "${currency['emoji']}",'); buffer.writeln(' decimalDigits: ${currency['decimal_digits']},'); buffer.writeln(' position: "${currency['position']}",'); + buffer.writeln(' thousandSeparator: "${currency['thousand_separator'] ?? ','}",'); + buffer.writeln(' decimalSeparator: "${currency['decimal_separator'] ?? '.'}",'); buffer.writeln(' ),'); } diff --git a/script/currencies/currency.dart b/script/currencies/currency.dart index 76b2046..3282073 100644 --- a/script/currencies/currency.dart +++ b/script/currencies/currency.dart @@ -5,7 +5,9 @@ List> currencies =[ "symbol": "د.إ", "emoji": "🇦🇪", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "AFN", @@ -13,7 +15,9 @@ List> currencies =[ "symbol": "؋", "emoji": "🇦🇫", "decimal_digits": 2, -"position": "last" +"position": "last", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "ALL", @@ -21,7 +25,9 @@ List> currencies =[ "symbol": "L", "emoji": "🇦🇱", "decimal_digits": 2, -"position": "last" +"position": "last", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "AMD", @@ -29,7 +35,9 @@ List> currencies =[ "symbol": "֏", "emoji": "🇦🇲", "decimal_digits": 2, -"position": "last" +"position": "last", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "AOA", @@ -37,7 +45,9 @@ List> currencies =[ "symbol": "Kz", "emoji": "🇦🇴", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "ARS", @@ -45,7 +55,9 @@ List> currencies =[ "symbol": "\$", "emoji": "🇦🇷", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ".", +"decimal_separator": "," }, { "code": "AUD", @@ -53,7 +65,9 @@ List> currencies =[ "symbol": "AU\$", "emoji": "🇦🇺", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "AWG", @@ -61,7 +75,9 @@ List> currencies =[ "symbol": "ƒ", "emoji": "🇦🇼", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "AZN", @@ -69,7 +85,9 @@ List> currencies =[ "symbol": "₼", "emoji": "🇦🇿", "decimal_digits": 2, -"position": "last" +"position": "last", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "BAM", @@ -77,7 +95,9 @@ List> currencies =[ "symbol": "KM", "emoji": "🇧🇦", "decimal_digits": 2, -"position": "last" +"position": "last", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "BBD", @@ -85,7 +105,9 @@ List> currencies =[ "symbol": "Bds\$", "emoji": "🇧🇧", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "BDT", @@ -93,7 +115,9 @@ List> currencies =[ "symbol": "৳", "emoji": "🇧🇩", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "BGN", @@ -101,7 +125,9 @@ List> currencies =[ "symbol": "лв", "emoji": "🇧🇬", "decimal_digits": 2, -"position": "last" +"position": "last", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "BHD", @@ -109,7 +135,9 @@ List> currencies =[ "symbol": ".د.ب", "emoji": "🇧🇭", "decimal_digits": 3, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "BIF", @@ -117,7 +145,9 @@ List> currencies =[ "symbol": "FBu", "emoji": "🇧🇮", "decimal_digits": 0, -"position": "last" +"position": "last", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "BMD", @@ -125,7 +155,9 @@ List> currencies =[ "symbol": "BD\$", "emoji": "🇧🇲", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "BND", @@ -133,7 +165,9 @@ List> currencies =[ "symbol": "B\$", "emoji": "🇧🇳", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "BOB", @@ -141,7 +175,9 @@ List> currencies =[ "symbol": "Bs.", "emoji": "🇧🇴", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ".", +"decimal_separator": "," }, { "code": "BOV", @@ -149,7 +185,9 @@ List> currencies =[ "symbol": "BOV", "emoji": "🇧🇴", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "BRL", @@ -157,7 +195,9 @@ List> currencies =[ "symbol": "R\$", "emoji": "🇧🇷", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ".", +"decimal_separator": "," }, { "code": "BSD", @@ -165,7 +205,9 @@ List> currencies =[ "symbol": "B\$", "emoji": "🇧🇸", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "BTN", @@ -173,7 +215,9 @@ List> currencies =[ "symbol": "Nu.", "emoji": "🇧🇹", "decimal_digits": 2, -"position": "last" +"position": "last", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "BWP", @@ -181,7 +225,9 @@ List> currencies =[ "symbol": "P", "emoji": "🇧🇼", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "BYN", @@ -189,7 +235,9 @@ List> currencies =[ "symbol": "Br", "emoji": "🇧🇾", "decimal_digits": 2, -"position": "last" +"position": "last", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "BZD", @@ -197,7 +245,9 @@ List> currencies =[ "symbol": "BZ\$", "emoji": "🇧🇿", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "CAD", @@ -205,7 +255,9 @@ List> currencies =[ "symbol": "CA\$", "emoji": "🇨🇦", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "CDF", @@ -213,7 +265,9 @@ List> currencies =[ "symbol": "FC", "emoji": "🇨🇩", "decimal_digits": 2, -"position": "last" +"position": "last", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "CHF", @@ -221,7 +275,9 @@ List> currencies =[ "symbol": "CHF", "emoji": "🇨🇭", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "CLF", @@ -229,7 +285,9 @@ List> currencies =[ "symbol": "UF", "emoji": "🇨🇱", "decimal_digits": 4, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "CLP", @@ -237,7 +295,9 @@ List> currencies =[ "symbol": "CLP\$", "emoji": "🇨🇱", "decimal_digits": 0, -"position": "first" +"position": "first", +"thousand_separator": ".", +"decimal_separator": "," }, { "code": "CNY", @@ -245,7 +305,9 @@ List> currencies =[ "symbol": "¥", "emoji": "🇨🇳", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "COP", @@ -253,7 +315,9 @@ List> currencies =[ "symbol": "COL\$", "emoji": "🇨🇴", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ".", +"decimal_separator": "," }, { "code": "COU", @@ -261,7 +325,9 @@ List> currencies =[ "symbol": "UVR", "emoji": "🇨🇴", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "CRC", @@ -269,7 +335,9 @@ List> currencies =[ "symbol": "₡", "emoji": "🇨🇷", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ".", +"decimal_separator": "," }, { "code": "CUP", @@ -277,7 +345,9 @@ List> currencies =[ "symbol": "₱", "emoji": "🇨🇺", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "CVE", @@ -285,7 +355,9 @@ List> currencies =[ "symbol": "Esc", "emoji": "🇨🇻", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "CZK", @@ -293,7 +365,9 @@ List> currencies =[ "symbol": "Kč", "emoji": "🇨🇿", "decimal_digits": 2, -"position": "last" +"position": "last", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "DJF", @@ -301,7 +375,9 @@ List> currencies =[ "symbol": "Fdj", "emoji": "🇩🇯", "decimal_digits": 0, -"position": "last" +"position": "last", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "DKK", @@ -309,7 +385,9 @@ List> currencies =[ "symbol": "kr", "emoji": "🇩🇰", "decimal_digits": 2, -"position": "last" +"position": "last", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "DOP", @@ -317,7 +395,9 @@ List> currencies =[ "symbol": "RD\$", "emoji": "🇩🇴", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "DZD", @@ -325,7 +405,9 @@ List> currencies =[ "symbol": "دج", "emoji": "🇩🇿", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "EGP", @@ -333,7 +415,9 @@ List> currencies =[ "symbol": "£", "emoji": "🇪🇬", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "ERN", @@ -341,7 +425,9 @@ List> currencies =[ "symbol": "Nfk", "emoji": "🇪🇷", "decimal_digits": 2, -"position": "last" +"position": "last", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "ETB", @@ -349,7 +435,9 @@ List> currencies =[ "symbol": "Br", "emoji": "🇪🇹", "decimal_digits": 2, -"position": "last" +"position": "last", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "EUR", @@ -357,7 +445,9 @@ List> currencies =[ "symbol": "€", "emoji": "🇪🇺", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ".", +"decimal_separator": "," }, { "code": "FJD", @@ -365,7 +455,9 @@ List> currencies =[ "symbol": "FJ\$", "emoji": "🇫🇯", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "FKP", @@ -373,7 +465,9 @@ List> currencies =[ "symbol": "£", "emoji": "🇫🇰", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "GBP", @@ -381,7 +475,9 @@ List> currencies =[ "symbol": "£", "emoji": "🇬🇧", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "GEL", @@ -389,7 +485,9 @@ List> currencies =[ "symbol": "₾", "emoji": "🇬🇪", "decimal_digits": 2, -"position": "last" +"position": "last", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "GHS", @@ -397,7 +495,9 @@ List> currencies =[ "symbol": "₵", "emoji": "🇬🇭", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "GIP", @@ -405,7 +505,9 @@ List> currencies =[ "symbol": "£", "emoji": "🇬🇮", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "GMD", @@ -413,7 +515,9 @@ List> currencies =[ "symbol": "D", "emoji": "🇬🇲", "decimal_digits": 2, -"position": "last" +"position": "last", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "GNF", @@ -421,7 +525,9 @@ List> currencies =[ "symbol": "FG", "emoji": "🇬🇳", "decimal_digits": 0, -"position": "last" +"position": "last", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "GTQ", @@ -429,7 +535,9 @@ List> currencies =[ "symbol": "Q", "emoji": "🇬🇹", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "GYD", @@ -437,7 +545,9 @@ List> currencies =[ "symbol": "GY\$", "emoji": "🇬🇾", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "HKD", @@ -445,7 +555,9 @@ List> currencies =[ "symbol": "HK\$", "emoji": "🇭🇰", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "HNL", @@ -453,7 +565,9 @@ List> currencies =[ "symbol": "L", "emoji": "🇭🇳", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "HTG", @@ -461,7 +575,9 @@ List> currencies =[ "symbol": "G", "emoji": "🇭🇹", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "HUF", @@ -469,7 +585,9 @@ List> currencies =[ "symbol": "Ft", "emoji": "🇭🇺", "decimal_digits": 0, -"position": "last" +"position": "last", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "IDR", @@ -477,7 +595,9 @@ List> currencies =[ "symbol": "Rp", "emoji": "🇮🇩", "decimal_digits": 0, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "ILS", @@ -485,7 +605,9 @@ List> currencies =[ "symbol": "₪", "emoji": "🇮🇱", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "INR", @@ -493,7 +615,9 @@ List> currencies =[ "symbol": "₹", "emoji": "🇮🇳", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "IQD", @@ -501,7 +625,9 @@ List> currencies =[ "symbol": "ع.د", "emoji": "🇮🇶", "decimal_digits": 3, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "IRR", @@ -509,7 +635,9 @@ List> currencies =[ "symbol": "﷼", "emoji": "🇮🇷", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "ISK", @@ -517,7 +645,9 @@ List> currencies =[ "symbol": "kr", "emoji": "🇮🇸", "decimal_digits": 0, -"position": "last" +"position": "last", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "JMD", @@ -525,7 +655,9 @@ List> currencies =[ "symbol": "J\$", "emoji": "🇯🇲", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "JOD", @@ -533,7 +665,9 @@ List> currencies =[ "symbol": "JD", "emoji": "🇯🇴", "decimal_digits": 3, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "JPY", @@ -541,7 +675,9 @@ List> currencies =[ "symbol": "¥", "emoji": "🇯🇵", "decimal_digits": 0, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "KES", @@ -549,7 +685,9 @@ List> currencies =[ "symbol": "KSh", "emoji": "🇰🇪", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "KGS", @@ -557,7 +695,9 @@ List> currencies =[ "symbol": "с", "emoji": "🇰🇬", "decimal_digits": 2, -"position": "last" +"position": "last", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "KHR", @@ -565,7 +705,9 @@ List> currencies =[ "symbol": "៛", "emoji": "🇰🇭", "decimal_digits": 2, -"position": "last" +"position": "last", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "KMF", @@ -573,7 +715,9 @@ List> currencies =[ "symbol": "CF", "emoji": "🇰🇲", "decimal_digits": 0, -"position": "last" +"position": "last", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "KPW", @@ -581,7 +725,9 @@ List> currencies =[ "symbol": "₩", "emoji": "🇰🇵", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "KRW", @@ -589,7 +735,9 @@ List> currencies =[ "symbol": "₩", "emoji": "🇰🇷", "decimal_digits": 0, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "KWD", @@ -597,7 +745,9 @@ List> currencies =[ "symbol": "د.ك", "emoji": "🇰🇼", "decimal_digits": 3, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "KYD", @@ -605,7 +755,9 @@ List> currencies =[ "symbol": "CI\$", "emoji": "🇰🇾", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "KZT", @@ -613,7 +765,9 @@ List> currencies =[ "symbol": "₸", "emoji": "🇰🇿", "decimal_digits": 2, -"position": "last" +"position": "last", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "LAK", @@ -621,7 +775,9 @@ List> currencies =[ "symbol": "₭", "emoji": "🇱🇦", "decimal_digits": 2, -"position": "last" +"position": "last", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "LBP", @@ -629,7 +785,9 @@ List> currencies =[ "symbol": "£", "emoji": "🇱🇧", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "LKR", @@ -637,7 +795,9 @@ List> currencies =[ "symbol": "Rs", "emoji": "🇱🇰", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "LRD", @@ -645,7 +805,9 @@ List> currencies =[ "symbol": "L\$", "emoji": "🇱🇷", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "LSL", @@ -653,7 +815,9 @@ List> currencies =[ "symbol": "M", "emoji": "🇱🇸", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "LYD", @@ -661,7 +825,9 @@ List> currencies =[ "symbol": "ل.د", "emoji": "🇱🇾", "decimal_digits": 3, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "MAD", @@ -669,7 +835,9 @@ List> currencies =[ "symbol": "د.م.", "emoji": "🇲🇦", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "MDL", @@ -677,7 +845,9 @@ List> currencies =[ "symbol": "L", "emoji": "🇲🇩", "decimal_digits": 2, -"position": "last" +"position": "last", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "MGA", @@ -685,7 +855,9 @@ List> currencies =[ "symbol": "Ar", "emoji": "🇲🇬", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "MKD", @@ -693,7 +865,9 @@ List> currencies =[ "symbol": "ден", "emoji": "🇲🇰", "decimal_digits": 2, -"position": "last" +"position": "last", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "MMK", @@ -701,7 +875,9 @@ List> currencies =[ "symbol": "K", "emoji": "🇲🇲", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "MNT", @@ -709,7 +885,9 @@ List> currencies =[ "symbol": "₮", "emoji": "🇲🇳", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "MOP", @@ -717,7 +895,9 @@ List> currencies =[ "symbol": "P", "emoji": "🇲🇴", "decimal_digits": 2, -"position": "last" +"position": "last", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "MRU", @@ -725,7 +905,9 @@ List> currencies =[ "symbol": "UM", "emoji": "🇲🇷", "decimal_digits": 2, -"position": "last" +"position": "last", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "MUR", @@ -733,7 +915,9 @@ List> currencies =[ "symbol": "Rs", "emoji": "🇲🇺", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "MVR", @@ -741,7 +925,9 @@ List> currencies =[ "symbol": "Rf", "emoji": "🇲🇻", "decimal_digits": 2, -"position": "last" +"position": "last", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "MWK", @@ -749,7 +935,9 @@ List> currencies =[ "symbol": "MK", "emoji": "🇲🇼", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "MXN", @@ -757,7 +945,9 @@ List> currencies =[ "symbol": "\$", "emoji": "🇲🇽", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "MXV", @@ -765,7 +955,9 @@ List> currencies =[ "symbol": "MXV", "emoji": "🇲🇽", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "MYR", @@ -773,7 +965,9 @@ List> currencies =[ "symbol": "RM", "emoji": "🇲🇾", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "MZN", @@ -781,7 +975,9 @@ List> currencies =[ "symbol": "MT", "emoji": "🇲🇿", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "NAD", @@ -789,7 +985,9 @@ List> currencies =[ "symbol": "N\$", "emoji": "🇳🇦", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "NGN", @@ -797,7 +995,9 @@ List> currencies =[ "symbol": "₦", "emoji": "🇳🇬", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "NIO", @@ -805,7 +1005,9 @@ List> currencies =[ "symbol": "C\$", "emoji": "🇳🇮", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "NOK", @@ -813,7 +1015,9 @@ List> currencies =[ "symbol": "kr", "emoji": "🇳🇴", "decimal_digits": 2, -"position": "last" +"position": "last", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "NPR", @@ -821,7 +1025,9 @@ List> currencies =[ "symbol": "Rs", "emoji": "🇳🇵", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "NZD", @@ -829,7 +1035,9 @@ List> currencies =[ "symbol": "NZ\$", "emoji": "🇳🇿", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "OMR", @@ -837,7 +1045,9 @@ List> currencies =[ "symbol": "ر.ع.", "emoji": "🇴🇲", "decimal_digits": 3, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "PAB", @@ -845,7 +1055,9 @@ List> currencies =[ "symbol": "B/.", "emoji": "🇵🇦", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "PEN", @@ -853,7 +1065,9 @@ List> currencies =[ "symbol": "S/", "emoji": "🇵🇪", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "PGK", @@ -861,7 +1075,9 @@ List> currencies =[ "symbol": "K", "emoji": "🇵🇬", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "PHP", @@ -869,7 +1085,9 @@ List> currencies =[ "symbol": "₱", "emoji": "🇵🇭", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "PKR", @@ -877,7 +1095,9 @@ List> currencies =[ "symbol": "Rs", "emoji": "🇵🇰", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "PLN", @@ -885,7 +1105,9 @@ List> currencies =[ "symbol": "zł", "emoji": "🇵🇱", "decimal_digits": 2, -"position": "last" +"position": "last", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "PYG", @@ -893,7 +1115,9 @@ List> currencies =[ "symbol": "₲", "emoji": "🇵🇾", "decimal_digits": 0, -"position": "first" +"position": "first", +"thousand_separator": ".", +"decimal_separator": "," }, { "code": "QAR", @@ -901,7 +1125,9 @@ List> currencies =[ "symbol": "ر.ق", "emoji": "🇶🇦", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "RON", @@ -909,7 +1135,9 @@ List> currencies =[ "symbol": "lei", "emoji": "🇷🇴", "decimal_digits": 2, -"position": "last" +"position": "last", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "RSD", @@ -917,7 +1145,9 @@ List> currencies =[ "symbol": "дин.", "emoji": "🇷🇸", "decimal_digits": 2, -"position": "last" +"position": "last", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "RUB", @@ -925,7 +1155,9 @@ List> currencies =[ "symbol": "₽", "emoji": "🇷🇺", "decimal_digits": 2, -"position": "last" +"position": "last", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "RWF", @@ -933,7 +1165,9 @@ List> currencies =[ "symbol": "FRw", "emoji": "🇷🇼", "decimal_digits": 0, -"position": "last" +"position": "last", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "SAR", @@ -941,7 +1175,9 @@ List> currencies =[ "symbol": "ر.س", "emoji": "🇸🇦", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "SBD", @@ -949,7 +1185,9 @@ List> currencies =[ "symbol": "SI\$", "emoji": "🇸🇧", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "SCR", @@ -957,7 +1195,9 @@ List> currencies =[ "symbol": "SR", "emoji": "🇸🇨", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "SDG", @@ -965,7 +1205,9 @@ List> currencies =[ "symbol": "SDG", "emoji": "🇸🇩", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "SEK", @@ -973,7 +1215,9 @@ List> currencies =[ "symbol": "kr", "emoji": "🇸🇪", "decimal_digits": 2, -"position": "last" +"position": "last", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "SGD", @@ -981,7 +1225,9 @@ List> currencies =[ "symbol": "S\$", "emoji": "🇸🇬", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "SHP", @@ -989,7 +1235,9 @@ List> currencies =[ "symbol": "£", "emoji": "🇸🇭", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "SLE", @@ -997,7 +1245,9 @@ List> currencies =[ "symbol": "Le", "emoji": "🇸🇱", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "SOS", @@ -1005,7 +1255,9 @@ List> currencies =[ "symbol": "Ssh", "emoji": "🇸🇴", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "SRD", @@ -1013,7 +1265,9 @@ List> currencies =[ "symbol": "SR\$", "emoji": "🇸🇷", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "SSP", @@ -1021,7 +1275,9 @@ List> currencies =[ "symbol": "SS£", "emoji": "🇸🇸", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "STN", @@ -1029,7 +1285,9 @@ List> currencies =[ "symbol": "Db", "emoji": "🇸🇹", "decimal_digits": 2, -"position": "last" +"position": "last", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "SVC", @@ -1037,7 +1295,9 @@ List> currencies =[ "symbol": "₡", "emoji": "🇸🇻", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "SYP", @@ -1045,7 +1305,9 @@ List> currencies =[ "symbol": "£", "emoji": "🇸🇾", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "SZL", @@ -1053,7 +1315,9 @@ List> currencies =[ "symbol": "E", "emoji": "🇸🇿", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "THB", @@ -1061,7 +1325,9 @@ List> currencies =[ "symbol": "฿", "emoji": "🇹🇭", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "TJS", @@ -1069,7 +1335,9 @@ List> currencies =[ "symbol": "ЅМ", "emoji": "🇹🇯", "decimal_digits": 2, -"position": "last" +"position": "last", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "TMT", @@ -1077,7 +1345,9 @@ List> currencies =[ "symbol": "m", "emoji": "🇹🇲", "decimal_digits": 2, -"position": "last" +"position": "last", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "TND", @@ -1085,7 +1355,9 @@ List> currencies =[ "symbol": "د.ت", "emoji": "🇹🇳", "decimal_digits": 3, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "TOP", @@ -1093,7 +1365,9 @@ List> currencies =[ "symbol": "T\$", "emoji": "🇹🇴", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "TRY", @@ -1101,7 +1375,9 @@ List> currencies =[ "symbol": "₺", "emoji": "🇹🇷", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "TTD", @@ -1109,7 +1385,9 @@ List> currencies =[ "symbol": "TT\$", "emoji": "🇹🇹", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "TWD", @@ -1117,7 +1395,9 @@ List> currencies =[ "symbol": "NT\$", "emoji": "🇹🇼", "decimal_digits": 0, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "TZS", @@ -1125,7 +1405,9 @@ List> currencies =[ "symbol": "TZS", "emoji": "🇹🇿", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "UAH", @@ -1133,7 +1415,9 @@ List> currencies =[ "symbol": "₴", "emoji": "🇺🇦", "decimal_digits": 2, -"position": "last" +"position": "last", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "UGX", @@ -1141,7 +1425,9 @@ List> currencies =[ "symbol": "USh", "emoji": "🇺🇬", "decimal_digits": 0, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "USD", @@ -1149,7 +1435,9 @@ List> currencies =[ "symbol": "\$", "emoji": "🇺🇸", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "USN", @@ -1157,7 +1445,9 @@ List> currencies =[ "symbol": "USN", "emoji": "🇺🇸", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "UYI", @@ -1165,7 +1455,9 @@ List> currencies =[ "symbol": "UYI", "emoji": "🇺🇾", "decimal_digits": 0, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "UYU", @@ -1173,7 +1465,9 @@ List> currencies =[ "symbol": "\$U", "emoji": "🇺🇾", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ".", +"decimal_separator": "," }, { "code": "UYW", @@ -1181,7 +1475,9 @@ List> currencies =[ "symbol": "UYW", "emoji": "🇺🇾", "decimal_digits": 4, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "UZS", @@ -1189,7 +1485,9 @@ List> currencies =[ "symbol": "so'm", "emoji": "🇺🇿", "decimal_digits": 2, -"position": "last" +"position": "last", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "VES", @@ -1197,7 +1495,9 @@ List> currencies =[ "symbol": "Bs.", "emoji": "🇻🇪", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ".", +"decimal_separator": "," }, { "code": "VND", @@ -1205,7 +1505,9 @@ List> currencies =[ "symbol": "₫", "emoji": "🇻🇳", "decimal_digits": 0, -"position": "last" +"position": "last", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "VUV", @@ -1213,7 +1515,9 @@ List> currencies =[ "symbol": "VT", "emoji": "🇻🇺", "decimal_digits": 0, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "WST", @@ -1221,7 +1525,9 @@ List> currencies =[ "symbol": "WS\$", "emoji": "🇼🇸", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "XAF", @@ -1229,7 +1535,9 @@ List> currencies =[ "symbol": "FCFA", "emoji": "🇨🇲", "decimal_digits": 0, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "XAG", @@ -1237,7 +1545,9 @@ List> currencies =[ "symbol": "XAG", "emoji": "🪙", "decimal_digits": 0, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "XAU", @@ -1245,7 +1555,9 @@ List> currencies =[ "symbol": "XAU", "emoji": "🪙", "decimal_digits": 0, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "XBA", @@ -1253,7 +1565,9 @@ List> currencies =[ "symbol": "XBA", "emoji": "🇪🇺", "decimal_digits": 0, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "XBB", @@ -1261,7 +1575,9 @@ List> currencies =[ "symbol": "XBB", "emoji": "🇪🇺", "decimal_digits": 0, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "XBC", @@ -1269,7 +1585,9 @@ List> currencies =[ "symbol": "XBC", "emoji": "🇪🇺", "decimal_digits": 0, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "XBD", @@ -1277,7 +1595,9 @@ List> currencies =[ "symbol": "XBD", "emoji": "🇪🇺", "decimal_digits": 0, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "XCD", @@ -1285,7 +1605,9 @@ List> currencies =[ "symbol": "EC\$", "emoji": "🇰🇳", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "XDR", @@ -1293,7 +1615,9 @@ List> currencies =[ "symbol": "SDR", "emoji": "🏦", "decimal_digits": 0, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "XOF", @@ -1301,7 +1625,9 @@ List> currencies =[ "symbol": "CFA", "emoji": "🇨🇮", "decimal_digits": 0, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "XPD", @@ -1309,7 +1635,9 @@ List> currencies =[ "symbol": "XPD", "emoji": "🪙", "decimal_digits": 0, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "XPF", @@ -1317,7 +1645,9 @@ List> currencies =[ "symbol": "F", "emoji": "🇵🇫", "decimal_digits": 0, -"position": "last" +"position": "last", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "XPT", @@ -1325,7 +1655,9 @@ List> currencies =[ "symbol": "XPT", "emoji": "🪙", "decimal_digits": 0, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "XSU", @@ -1333,7 +1665,9 @@ List> currencies =[ "symbol": "XSU", "emoji": "🇪🇨", "decimal_digits": 0, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "XTS", @@ -1341,7 +1675,9 @@ List> currencies =[ "symbol": "XTS", "emoji": "❓", "decimal_digits": 0, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "XUA", @@ -1349,7 +1685,9 @@ List> currencies =[ "symbol": "XUA", "emoji": "🏦", "decimal_digits": 0, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "YER", @@ -1357,7 +1695,9 @@ List> currencies =[ "symbol": "﷼", "emoji": "🇾🇪", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "ZAR", @@ -1365,7 +1705,9 @@ List> currencies =[ "symbol": "R", "emoji": "🇿🇦", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "ZMW", @@ -1373,7 +1715,9 @@ List> currencies =[ "symbol": "ZK", "emoji": "🇿🇲", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." }, { "code": "ZWL", @@ -1381,6 +1725,8 @@ List> currencies =[ "symbol": "Z\$", "emoji": "🇿🇼", "decimal_digits": 2, -"position": "first" +"position": "first", +"thousand_separator": ",", +"decimal_separator": "." } ]; From 2514e84540e358c9ccfaeacdb09c40cf72e31df4 Mon Sep 17 00:00:00 2001 From: Gonzalo Juarez Date: Tue, 12 May 2026 17:13:08 -0300 Subject: [PATCH 6/6] chore: bump package version to 1.0.14 --- pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pubspec.yaml b/pubspec.yaml index a7be60f..b133473 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: currency_widget description: "A currency list of widgets which you can choose or get information about the currency" -version: 1.0.13 +version: 1.0.14 homepage: https://github.com/DecksPlayer/currency_widget repository: https://github.com/DecksPlayer/currency_widget