Everything you need. Nothing you don't.
A single import gives you a typed, validated, fully themeable currency field that runs everywhere Flutter does.
Generic by design
Type it with String, an enum, or your own currency model. Full type-safety end to end — no casts, no boilerplate.
Three layout modes
inline for dashboards, stacked for mobile, adaptive to switch automatically at a breakpoint you set.
Layered validation
Validate currency, amount, or combined business rules independently — with plain Flutter form semantics.
Controller API
Read, set, and clear values programmatically. Prefill state for review and confirm flows out of the box.
Pixel-level control
Tune padding, flex ratios, divider sizing, dropdown shape, decimals, and a full style object.
Every platform
Android, iOS, Web, macOS, Linux, and Windows from one codebase — zero extra configuration.
One widget, three layouts
Pick the layout that fits the screen — or let adaptive decide at runtime. Try them live in the demo above.
.inlineInline
Currency and amount sit side by side. Best for admin dashboards and desktop forms.
.stackedStacked
Currency stacks above the amount. Best for mobile-first forms and narrow viewports.
.adaptiveAdaptive
Flips between inline and stacked automatically, using a stackBreakpoint you control.
Up and running in minutes
One import. One widget. Full validation and layout control out of the box — no setup, no theme wiring.
- 1Add the dependency with flutter pub add
- 2Create a typed CurrencyInputController<T>
- 3Drop CurrencyInputField into any Form
import 'package:currency_input_field/currency_input_field.dart'; final _controller = CurrencyInputController<String>( initialCurrency: 'USD', ); CurrencyInputField<String>( controller: _controller, currencies: const ['USD', 'GBP', 'EUR', 'ZWG'], currencyLabelBuilder: (c) => c, layoutMode: CurrencyInputLayoutMode.adaptive, amountValidator: (value) { final amount = double.tryParse(value); if (amount == null || amount <= 0) { return 'Enter a valid amount'; } return null; }, );
Validate at the right level
Three independent hooks — currency, amount, or combined — all using plain Flutter form semantics.
currencyValidatorRestrict or flag currencies per flow — block unsupported regions before submit.
currencyValidator: (currency) {
if (currency == 'ZAR') {
return 'Not supported here';
}
return null;
},amountValidatorEnforce minimums, maximums, or format rules purely on the numeric value.
amountValidator: (value) {
final n = double.tryParse(value);
if (n == null || n < 5) {
return 'Minimum amount is 5';
}
return null;
},validatorCombine currency and amount for cross-field business rules in one place.
validator: (value) {
if (value.currency == 'USD' &&
(value.amount ?? 0) > 500) {
return 'USD max is 500';
}
return null;
},Tunable down to the pixel
From compact admin tables to spacious mobile flows — adjust spacing, behavior, and a full style object to match any design system.
Sizing & spacing
containerPaddingfieldVerticalPaddinginlineDividerHeightcurrencyFlexamountFlexLabels & hints
useLabelTextcurrencyHintTextmonetaryHintTextDropdown
dropdownBorderRadiusdropdownMenuMaxHeightInput behavior
decimalDigitsallowNegativeamountKeyboardTypeamountInputFormattersStates
enabledreadOnlyAmountautofocusAmountTheming
CurrencyInputFieldStyleborderColorfocusedBorderColoramountTextStyleBuilt for real scenarios
The example app ships six production-style flows covering every layout, validation state, and styling preset.
inlineCompact inline layout, enterprise spacing, payout rules.
stackedStacked mobile layout, spacious padding, donation validation.
adaptiveEnum-based currency, adaptive layout, currency-specific rules.
inlinePrefilled controller, read-only amount, review and confirm.
inlineInline with icon-decorated fields and fast-entry UX.
stackedStacked consumer layout with icons and guided decoration.