Mosmox UI
Current version
GitHubnpmjs.com
Forms & Inputs

Input Currency

Locale-aware monetary input with formatting, constraints, precision, and step controls.

Input Currency

InputCurrency is a numeric form field for prices, budgets, payments, and other monetary values. It formats the displayed value with Intl.NumberFormat, supports locale-specific separators and currency presentation, and exposes numeric values through callbacks.

Basic usage

import { InputCurrency } from '@mosmox/ui';

<InputCurrency label="Price" currency="USD" defaultValue={1299.99} />

The field displays the currency symbol, grouping separators, and fraction digits according to currency, locale, and the fraction options.

Controlled and uncontrolled values

Use defaultValue when the component should manage its own value. Use value and onChange when the parent owns the value:

const [budget, setBudget] = useState<number | null>(1000);

<InputCurrency
  currency="USD"
  value={budget}
  onChange={(value, formattedValue) => {
    setBudget(value);
    console.log('Formatted:', formattedValue);
  }}
/>

value={null} represents an empty value. onChange receives the numeric value (number or null) and the formatted string. onBlur receives the committed numeric value after the current text is parsed, constrained, and formatted.

Currency and locale

currency is passed to Intl.NumberFormat and normally uses an ISO 4217 currency code. locale controls decimal separators, grouping separators, symbol placement, and localized currency names.

<InputCurrency currency="UAH" locale="uk-UA" defaultValue={2499.99} />
<InputCurrency currency="EUR" locale="de-DE" defaultValue={8900} />
<InputCurrency currency="GBP" locale="en-GB" currencyDisplay="code" defaultValue={4250.75} />

currencyDisplay accepts symbol, narrowSymbol, code, or name.

Minimum, maximum, and step

<InputCurrency currency="USD" min={0} max={100000} step={50} defaultValue={500} />
  • min sets the lower numeric bound.
  • max sets the upper numeric bound.
  • step controls the increment and decrement amount; default 1.

Bounds are applied when a value is emitted and when the field loses focus. Arrow Up, Arrow Down, and the visible controls use step. The decrease/increase buttons become disabled at the corresponding bound. If min or max is omitted, that side has no limit.

Precision and fraction digits

<InputCurrency currency="USD" precision={2} defaultValue={12.5} />
<InputCurrency currency="JPY" locale="ja-JP" precision={0} defaultValue={120000} />
<InputCurrency currency="USD" minFractionDigits={2} maxFractionDigits={4} />
  • precision sets both minimum and maximum fraction digits.
  • minFractionDigits and maxFractionDigits control the two sides independently.

When no precision is supplied, the component uses a minimum of 0 and a maximum of 2 fraction digits. Independent fraction props take precedence over precision for the corresponding side.

Formatting options

<InputCurrency currency="USD" useGrouping={false} defaultValue={1234.5} />
<InputCurrency currency="USD" signDisplay="always" defaultValue={125} />

useGrouping controls thousands separators and defaults to true. signDisplay accepts auto, always, or exceptZero and defaults to auto. While focused, the input exposes an editable numeric representation; on blur it returns to the localized currency format.

Controls, clearing, and states

<InputCurrency
  label="Order total"
  name="amount"
  currency="USD"
  clearable
  description="The amount charged to the customer."
  prefix={<span aria-hidden="true">≈</span>}
  suffix={<span aria-hidden="true">per month</span>}
/>
  • controls shows increment/decrement buttons and defaults to true.
  • clearable shows a Clear amount button when a value exists and defaults to false.
  • disabled prevents interaction and disables the input.
  • readOnly prevents editing and hides active controls.
  • loading disables the input and controls while showing a loading status.
  • error marks the field invalid and renders an alert message.
  • description renders supporting text and associates it with the input.
  • prefix and suffix render custom adornments.
  • size accepts sm, default, or lg.

Events

<InputCurrency
  currency="USD"
  min={0}
  max={5000}
  onChange={(value, formattedValue) => {
    console.log(value);          // number | null
    console.log(formattedValue); // localized string
  }}
  onBlur={(value) => console.log('Committed:', value)}
/>

onChange runs as numeric text changes and receives the bounded numeric value plus its formatted representation. onBlur runs after the current text is parsed, clamped to min/max, stored, and formatted.

Accessibility and form integration

The input uses role="spinbutton" and exposes aria-valuemin, aria-valuemax, and aria-valuenow when the corresponding values exist. A visible label is associated with the input. If there is no visible label, provide aria-label.

<InputCurrency
  aria-label="Monthly budget"
  name="monthlyBudget"
  id="monthly-budget"
  placeholder="Enter amount"
  currency="USD"
/>

Arrow Up/Down step the value. Validation messages passed through error use an alert region.

API reference

PropTypeDefaultDescription
labelReactNode—Visible field label.
descriptionReactNode—Supporting text associated with the input.
errorReactNode—Validation message and invalid state.
currencystring'USD'Currency code passed to Intl.NumberFormat.
localestring'en-US'Formatting locale.
currencyDisplay'symbol' | 'narrowSymbol' | 'code' | 'name''symbol'Currency presentation.
valuenumber | null—Controlled numeric value.
defaultValuenumber—Initial uncontrolled value.
onChange(value: number | null, formattedValue: string) => void—Numeric and formatted value event.
onBlur(value: number | null) => void—Committed value event.
minnumber—Minimum numeric value.
maxnumber—Maximum numeric value.
stepnumber1Arrow/control increment.
precisionnumber—Sets minimum and maximum fraction digits.
minFractionDigitsnumber0Minimum fraction digits unless overridden by precision.
maxFractionDigitsnumber2Maximum fraction digits unless overridden by precision.
useGroupingbooleantrueShows grouping separators.
signDisplay'auto' | 'always' | 'exceptZero''auto'Sign formatting.
controlsbooleantrueShows increment/decrement controls.
clearablebooleanfalseShows a clear button when populated.
disabledbooleanfalseDisables input and controls.
readOnlybooleanfalsePrevents editing and control interaction.
loadingbooleanfalseShows loading state and disables interaction.
size'sm' | 'default' | 'lg''default'Field density.
prefixReactNode—Leading adornment.
suffixReactNode—Trailing adornment.
placeholderstringlocalized zeroPlaceholder text.
namestring—Native form field name.
idstringgeneratedInput ID used by the label.
aria-labelstring—Accessible name when no visible label exists.
classNamestring—Root field class.
styleCSSProperties—Root inline styles.

InputCurrency does not expose imperative methods through a forwarded ref. Use controlled value, onChange, and onBlur for application logic.