Number Field
A labelled input for a single numeric value.
NumberField is a text input constrained to numbers, with stepping, parsing, and
locale-aware formatting handled for you. Reach for it when the value is a
quantity to compute with — an amount, a count, a rate — not an identifier like a
card or phone number, which belongs in a TextField.
Formatting
Currency
<NumberField
label="Price"
defaultValue={19.99}
formatOptions={{ style: 'currency', currency: 'USD' }}
/>Percentage
<NumberField
label="Rate"
defaultValue={0.075}
formatOptions={{ style: 'percent', minimumFractionDigits: 1 }}
/>formatOptions takes Intl.NumberFormat options, so currency, percent, and
fraction-digit rules come from the standard library and stay correct across
locales. The user still types a plain number — the component parses and
reformats it.
States
Invalid
<NumberField
label="Quantity"
defaultValue={42}
isInvalid
errorMessage="Enter a value of 10 or less."
/>Read-only
<NumberField label="Locked" defaultValue={100} isReadOnly />Disabled
<NumberField label="Unavailable" defaultValue={0} isDisabled />Suffix
<NumberField label="Amount" defaultValue={1.5} end={<span>ETH</span>} />start and end render inside the field's border, as on
Text Field. Use them for a unit
formatOptions cannot express, like a token symbol.
Distinguish the inert states: isReadOnly keeps the value readable and
submitted, while isDisabled removes the field from the form and the tab order.
Passing errorMessage marks the field invalid and swaps the description slot for
the error.
Prefixes and suffixes
Unit suffix
<NumberField
label="Stake"
defaultValue={32}
end={<span className="pe-2.5 text-body text-bds-fg-muted">ETH</span>}
/>start and end render inside the field's border, the same as on
Text Field. Use them for a
unit formatOptions cannot express, such as a token symbol — not for buttons.
When to use
Use NumberField for a quantity to compute with — an amount, a count, a
rate, a percentage.
Use something else when:
- The value is an identifier like a card, account, or phone number. Use Text Field.
- There are only a few fixed values. Use Segment or Select.
Usage
Do
Use formatOptions to state the unit — a currency symbol or percent sign
the user can see beats a separate label explaining the number.
Don't
Use NumberField for identifiers like card, account, or phone numbers.
Stepping and thousands separators corrupt values that only look numeric.
Props
| Prop | Type | Default |
|---|---|---|
classNameThe CSS [className](https://developer.mozilla.org/en-US/docs/Web/API/Element/className) for the | TypeClassNameOrFunction<NumberFieldRenderProps> | Default— |
commitBehaviorControls the behavior of the number field when the user blurs the field after editing. 'snap' | Type"validate" | "snap" | Default'snap' |
decrementAriaLabelA custom aria-label for the decrement button. If not provided, the localized string "Decrement" | Typestring | Default— |
defaultValueThe default value (uncontrolled). | Typenumber | Default— |
description | TypeReactNode | Default— |
end | TypeReactNode | Default— |
errorMessage | TypeChildrenOrFunction<FieldErrorRenderProps> | Default— |
formatOptionsFormatting options for the value displayed in the number field. | TypeNumberFormatOptions | Default— |
incrementAriaLabelA custom aria-label for the increment button. If not provided, the localized string "Increment" | Typestring | Default— |
isDisabledWhether the input is disabled. | Typeboolean | Default— |
isInvalidWhether the input value is invalid. | Typeboolean | Default— |
isReadOnlyWhether the input can be selected but not changed by the user. | Typeboolean | Default— |
isRequiredWhether user input is required on the input before form submission. | Typeboolean | Default— |
isWheelDisabledEnables or disables changing the value with scroll. | Typeboolean | Default— |
label | TypeReactNode | Default— |
maxValueThe largest value allowed for the input. | Typenumber | Default— |
minValueThe smallest value allowed for the input. | Typenumber | Default— |
start | TypeReactNode | Default— |
stepThe amount that the input value changes with each increment or decrement "tick". | Typenumber | Default— |
validateA function that returns an error message if a given value is invalid. | Type((value: number) => true | ValidationError | null) | Default— |
validationBehaviorWhether to use native HTML form validation to prevent form submission | Type"native" | "aria" | Default'native' |
Accessibility
NumberField wraps React Aria's NumberField, which associates the label,
description, and error message with the input and exposes stepping through both
the keyboard and assistive tech. Give any field without a visible label an
aria-label. In development, a NumberField with no label and no
aria-label logs a console warning.
The description uses fg-muted, which meets 4.5:1 contrast against the page
background in light and dark themes.