Skip to main content
CurrencyField ← Back to Table of Contents

Summary

Revolut-style currency input: locale-aware formatting, digit animations, optional currency picker, and minor-unit storage.
ClassBjanczak\FilamentFlexFields\Filament\Forms\Components\CurrencyField
State typeint|null (single) or array<amount: int|null, currency: string> (multi)
Model cast'price' => 'integer' · 'budget' => 'array'
FieldTypecurrency
Playgroundcurrency-field slug in Flex Fields playground

Basic usage

Fixed currency (PLN)

use Bjanczak\FilamentFlexFields\Filament\Forms\Components\CurrencyField;

CurrencyField::make('price')
    ->label('Amount')
    ->currency('PLN')
    ->locale('pl_PL')
    ->required();

Multi-currency with picker

use Bjanczak\FilamentFlexFields\Filament\Forms\Components\CurrencyField;

CurrencyField::make('budget')
    ->currencies(['EUR', 'USD', 'GBP', 'PLN'])
    ->currency('EUR')
    ->min(0)
    ->max(99999.99);

State & storage

Minor units

Amounts are stored as the smallest currency unit (e.g. grosze, cents). Commas, spaces, and currency symbols are display only.
DisplayMinor units (int)
99,99 PLN9999
1 250,50 EUR125050
¥1,500 (JPY, 0 decimals)1500
Multi-currency state:
[
    'amount' => 125050,   // minor units
    'currency' => 'EUR',
]

Hydration (normalizeState)

On load, the field normalizes incoming values:
  • 6666660 (int) → Treated as minor units6666660
  • 66666.60 (float) → Treated as major units → converted to 6666660
  • "12.50" (string with .) → Major units → 1250

Configuration API

All methods accept Closure unless noted.
MethodTypeDefaultDescription
currency(string|Closure $currencyCode)Setup'PLN'Default currency code
currencies(array|Closure|null $currencies)SetupnullWhitelist for currency picker
locale(string|Closure|null $locale)SetupautoFormatting locale (e.g. en_US)
min(float|int|Closure|null $value)SetupnullMinimum value in major units
max(float|int|Closure|null $value)SetupnullMaximum value in major units
allowNegative(bool|Closure $condition = true)SetupfalseAllow negative amounts
animated(bool|Closure $condition = true)SetuptrueEnable digit animations
commitDecimalsOnBlur(bool|Closure $condition = true)SetuptruePad decimals when field loses focus
searchable(bool|Closure $condition = true)SetuptrueEnable search in currency picker
variant(string|Closure $variant)Setup'primary'Visual style: primary, secondary, flat, soft
size(string|ControlSize|Closure $size)Setup'md'Control size: sm, md, lg
rounding(string|Closure|null $rounding)SetupconfigBorder radius token

min() / max()

Defined in major units (e.g. 10.50) but validated internally as minor units.
CurrencyField::make('price')
    ->min(0)
    ->max(10000);

Custom database formats

By default, CurrencyField saves minor units as integers. If your database uses decimals, override dehydration:

Store major units (decimal)

CurrencyField::make('price')
    ->currency('PLN')
    ->dehydrateStateUsing(fn (?int $state) => $state === null ? null : $state / 100);
Map at the model layer to keep form logic clean:
// Model
protected function casts(): array
{
    return [
        'price' => MinorUnitsCast::class, // Custom cast: DB decimal ↔ app int
    ];
}

Real-world examples

Product price in a resource

public static function form(Form $form): Form
{
    return $form->schema([
        CurrencyField::make('price')
            ->currency('USD')
            ->locale('en_US')
            ->min(0.01)
            ->required(),
    ]);
}

Multi-currency donation form

CurrencyField::make('donation_amount')
    ->currencies(['USD', 'EUR', 'GBP'])
    ->currency('USD')
    ->variant('flat')
    ->size('lg');

Playground

/admin/flex-fields-playground/currency-field See Playground for setup.
ComponentWhen to use instead
FlexTextInputFor simple numeric inputs without currency formatting
PriceRangeFieldFor selecting a range of prices (min/max)
CountryFieldFor picking a country instead of a currency

CSS classes (reference)

ClassRole
fff-currency-fieldRoot wrapper
fff-currency-field--{sm|md|lg}Size modifier
fff-currency-field--{variant}Visual variant
fff-currency-field__currency-triggerCurrency picker chip
fff-currency-field__digitsAnimated digit display
fff-currency-field__symbolTrailing currency symbol

Performance

MechanismWhat it does
SSR Pre-rendergetInitialDisplay() renders segments server-side to prevent layout flash
Memoized MetadataCurrency metadata (symbols, decimals) is cached for Alpine
Efficient ValidationNormalizes state to minor units for consistent server-side validation