Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 30 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,4 +69,33 @@
## 1.0.6
* Fix Memory issues
* Fix Cursor Issue
* Fix Currency Mask format.
* 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

## 1.0.10
* Add `CustomCurrencyPicker` and `CustomCurrencyChooser` to restrict selectable currencies to a specific list.
* Add `CurrencyMultiSelector` widget to support selecting multiple currencies simultaneously.

## 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.
64 changes: 59 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,17 +34,37 @@ 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`.

### `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


| Widget | Properties |
|----------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `CurrencyPicker` | `currencyController`: (required) Manages currency state.<br> |
| `CurrencyTextField` | `currencyController`: (required) Manages currency state.<br>`currencyCode`: (required) Code of the currency to use.<br> |
| `CurrencyPicker` | `currencyController`: (required) Manages currency state.<br>`defaultCurrencyCode`: (optional) Initial currency to select. |
| `CurrencyTextField` | `currencyController`: (required) Manages currency state.<br>`currencyCode`: (required) Code of the currency to use.<br>`defaultAmount`: (optional) Initial amount to select. |
| `CurrencyTextView` | `mount`: (required) Amount to display.<br>`currencyCode`: (required) Code of the currency.<br>`CurrencyControler` : (required)Manages currency state |
| `CurrencyCardReport` | `title`: (required) Title widget for the card.<br>`icon`: (required) Icon widget for the card.<br>`mount`: (required) Amount to display.<br>`currencyCode`: (required) Code of the currency.<br>`lang`: (required) Language for formatting.<br>`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.<br>`currencyCodes`: (required) List of currency codes to allow.<br>`defaultCurrencyCode`: (optional) Initial currency to select. |
| `CustomCurrencyChooser`| `currencyController`: (required) Manages currency state.<br>`currencyCodes`: (required) List of currency codes to allow.<br>`defaultCurrencyCode`: (optional) Initial currency to select. |
| `CurrencyMultiSelector`| `onChanged`: (required) Callback fired when selection changes.<br>`initialSelected`: List of initially selected currencies.<br>`showOnlyCommon`: Toggle between common or all currencies.<br> |

**Note**: All widgets also accept standard Flutter widget properties like `key`, `padding`, `margin`, etc.

Expand Down Expand Up @@ -102,7 +122,7 @@ class MyCurrencyScreen extends StatefulWidget {
}

class _MyCurrencyScreenState extends State<MyCurrencyScreen> {
final CurrencyController _controller = CurrencyController();
final CurrencyController _controller = CurrencyController(lang: 'es', initialCurrencyCode: 'EUR');

@override
void dispose() {
Expand All @@ -120,7 +140,10 @@ class _MyCurrencyScreenState extends State<MyCurrencyScreen> {
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<Currency>(
Expand All @@ -133,7 +156,38 @@ class _MyCurrencyScreenState extends State<MyCurrencyScreen> {
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<Currency?>(
valueListenable: _controller.currencyNotifier,
builder: (_, currency, __) {
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'],
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',
),
],
),
),
Expand Down
179 changes: 127 additions & 52 deletions example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,25 @@ class _MyHomePageState extends State<MyHomePage> {
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: 'EUR',
);
final CurrencyController currencyChooserController = CurrencyController(
lang: 'es',
initialCurrencyCode: 'GBP',
);

final CurrencyController customCurrencyController = CurrencyController(
lang: 'es',
);
List<Currency> _selectedCurrencies = [];
List<String> get _selectedCurrencyCodes =>
_selectedCurrencies.map((c) => c.code).toList();

@override
Widget build(BuildContext context) {
Expand All @@ -58,61 +73,121 @@ class _MyHomePageState extends State<MyHomePage> {
// 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: <Widget>[
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),
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: <Widget>[
// 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'),
),
),
],
CurrencyTextField(
currencyCode: currencyCode,
currencyController: currencyController,
defaultAmount: 20,
),
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: 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,
// 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),
],
),
),
), // This trailing comma makes auto-formatting nicer for build methods.
);
), // closes SingleChildScrollView
); // closes Scaffold
}
}
Loading