Number Input
A field that allows user input of numeric values.
You can explore the number-input component in the following curated examples.
Anatomy
<NumberInput.Root>
<NumberInput.Label />
<NumberInput.Scrubber />
<NumberInput.Control>
<NumberInput.Input />
<NumberInput.IncrementTrigger />
<NumberInput.DecrementTrigger />
</NumberInput.Control>
</NumberInput.Root>
Examples
Min and Max
Pass the min prop or max prop to set an upper and lower limit for the input. By default, the input will restrict the
value to stay within the specified range.
To allow values outside the min/max range, set
clampValueOnBlurtofalse.
Precision
In some cases, you might need the value to be rounded to specific decimal points. Set the formatOptions and provide
Intl.NumberFormatOptions such as maximumFractionDigits or minimumFractionDigits.
Scrubbing
The NumberInput supports the scrubber interaction pattern. To use this pattern, render the NumberInput.Scrubber
component. It uses the Pointer lock API and tracks the pointer movement. It also renders a virtual cursor which mimics
the real cursor's pointer.
Mouse Wheel
The NumberInput exposes a way to increment/decrement the value using the mouse wheel event. To activate this, set the
allowMouseWheel prop to true.
Formatting
To apply custom formatting to the input's value, set the formatOptions and provide Intl.NumberFormatOptions such as
style and currency.
Field
The Field component helps manage form-related state and accessibility attributes of a number input. It includes
handling ARIA labels, helper text, and error text to ensure proper accessibility.
Root Provider
An alternative way to control the number input is to use the RootProvider component and the useNumberInput hook.
This way you can access the state and methods from outside the component.
Guides
Scrubber
The NumberInput.Scrubber component provides an interactive scrub area that allows users to drag to change the input
value. It renders as a <div> element and displays a custom cursor element during scrubbing interactions.
This component utilizes the Pointer Lock API for smooth dragging interactions.
Note: Browsers may show a notification when the Pointer Lock API is activated. The scrubber is automatically disabled in Safari to prevent layout shifts.
Controlled
When controlling the NumberInput component, it's recommended to use string values instead of converting to numbers. This
is especially important when using formatOptions for currency or locale-specific formatting.
const [value, setValue] = useState('0')
<NumberInput.Root value={value} onValueChange={(details) => setValue(details.value)}>
{/* ... */}
</NumberInput.Root>
Converting values to numbers can cause issues with locale-specific formatting, particularly for currencies that use
different decimal and thousands separators (e.g., 1.523,30 vs 1,523.30). By keeping values as strings, you preserve
the correct formatting and avoid parsing issues.
If you need to submit a numeric value in your form, use a hidden input that reads valueAsNumber from
NumberInput.Context:
<NumberInput.Root value={value} onValueChange={(details) => setValue(details.value)}>
<NumberInput.Input />
<NumberInput.Context>
{(context) => <input type="hidden" name="amount" value={context.valueAsNumber} />}
</NumberInput.Context>
</NumberInput.Root>
API Reference
Props
Root
Renders a <div> element.
| Prop | Default | Type |
|---|---|---|
allowMouseWheel | booleanWhether to allow mouse wheel to change the value | |
allowOverflow | true | booleanWhether to allow the value overflow the min/max range |
asChild | booleanUse the provided child element as the default rendered element, combining their props and behavior. For more details, read our Composition guide. | |
clampValueOnBlur | true | booleanWhether to clamp the value when the input loses focus (blur) |
defaultValue | stringThe initial value of the input when rendered. Use when you don't need to control the value of the input. | |
disabled | booleanWhether the number input is disabled. | |
focusInputOnChange | true | booleanWhether to focus input when the value changes |
form | stringThe associate form of the input element. | |
formatOptions | NumberFormatOptionsThe options to pass to the `Intl.NumberFormat` constructor | |
id | stringThe unique identifier of the machine. | |
ids | Partial<{
root: string
label: string
input: string
incrementTrigger: string
decrementTrigger: string
scrubber: string
}>The ids of the elements in the number input. Useful for composition. | |
inputMode | 'decimal' | InputModeHints at the type of data that might be entered by the user. It also determines the type of keyboard shown to the user on mobile devices |
invalid | booleanWhether the number input value is invalid. | |
locale | 'en-US' | stringThe current locale. Based on the BCP 47 definition. |
max | Number.MAX_SAFE_INTEGER | numberThe maximum value of the number input |
min | Number.MIN_SAFE_INTEGER | numberThe minimum value of the number input |
name | stringThe name attribute of the number input. Useful for form submission. | |
onFocusChange | (details: FocusChangeDetails) => voidFunction invoked when the number input is focused | |
onValueChange | (details: ValueChangeDetails) => voidFunction invoked when the value changes | |
onValueInvalid | (details: ValueInvalidDetails) => voidFunction invoked when the value overflows or underflows the min/max range | |
pattern | '-?[0-9]*(.[0-9]+)?' | stringThe pattern used to check the <input> element's value against |
readOnly | booleanWhether the number input is readonly | |
required | booleanWhether the number input is required | |
spinOnPress | true | booleanWhether to spin the value when the increment/decrement button is pressed |
step | 1 | numberThe amount to increment or decrement the value by |
translations | IntlTranslationsSpecifies the localized strings that identifies the accessibility elements and their states | |
value | stringThe controlled value of the input |
| Attribute | Description |
|---|---|
[data-scope] | number-input |
[data-part] | root |
[data-disabled] | Present when disabled |
[data-focus] | Present when focused |
[data-invalid] | Present when invalid |
[data-scrubbing] |
Control
Renders a <div> element.
| Prop | Default | Type |
|---|---|---|
asChild | booleanUse the provided child element as the default rendered element, combining their props and behavior. For more details, read our Composition guide. |
| Attribute | Description |
|---|---|
[data-scope] | number-input |
[data-part] | control |
[data-focus] | Present when focused |
[data-disabled] | Present when disabled |
[data-invalid] | Present when invalid |
[data-scrubbing] |
DecrementTrigger
Renders a <button> element.
| Prop | Default | Type |
|---|---|---|
asChild | booleanUse the provided child element as the default rendered element, combining their props and behavior. For more details, read our Composition guide. |
| Attribute | Description |
|---|---|
[data-scope] | number-input |
[data-part] | decrement-trigger |
[data-disabled] | Present when disabled |
[data-scrubbing] |
IncrementTrigger
Renders a <button> element.
| Prop | Default | Type |
|---|---|---|
asChild | booleanUse the provided child element as the default rendered element, combining their props and behavior. For more details, read our Composition guide. |
| Attribute | Description |
|---|---|
[data-scope] | number-input |
[data-part] | increment-trigger |
[data-disabled] | Present when disabled |
[data-scrubbing] |
Input
Renders a <input> element.
| Prop | Default | Type |
|---|---|---|
asChild | booleanUse the provided child element as the default rendered element, combining their props and behavior. For more details, read our Composition guide. |
| Attribute | Description |
|---|---|
[data-scope] | number-input |
[data-part] | input |
[data-invalid] | Present when invalid |
[data-disabled] | Present when disabled |
[data-scrubbing] |
Label
Renders a <label> element.
| Prop | Default | Type |
|---|---|---|
asChild | booleanUse the provided child element as the default rendered element, combining their props and behavior. For more details, read our Composition guide. |
| Attribute | Description |
|---|---|
[data-scope] | number-input |
[data-part] | label |
[data-disabled] | Present when disabled |
[data-focus] | Present when focused |
[data-invalid] | Present when invalid |
[data-required] | Present when required |
[data-scrubbing] |
RootProvider
Renders a <div> element.
| Prop | Default | Type |
|---|---|---|
value | UseNumberInputReturn | |
asChild | booleanUse the provided child element as the default rendered element, combining their props and behavior. For more details, read our Composition guide. |
Scrubber
Renders a <div> element.
| Prop | Default | Type |
|---|---|---|
asChild | booleanUse the provided child element as the default rendered element, combining their props and behavior. For more details, read our Composition guide. |
| Attribute | Description |
|---|---|
[data-scope] | number-input |
[data-part] | scrubber |
[data-disabled] | Present when disabled |
[data-scrubbing] |
ValueText
Renders a <span> element.
| Prop | Default | Type |
|---|---|---|
asChild | booleanUse the provided child element as the default rendered element, combining their props and behavior. For more details, read our Composition guide. |
| Attribute | Description |
|---|---|
[data-scope] | number-input |
[data-part] | value-text |
[data-disabled] | Present when disabled |
[data-invalid] | Present when invalid |
[data-focus] | Present when focused |
[data-scrubbing] |
Context
API
| Property | Type |
|---|---|
focused | booleanWhether the input is focused. |
invalid | booleanWhether the input is invalid. |
empty | booleanWhether the input value is empty. |
value | stringThe formatted value of the input. |
valueAsNumber | numberThe value of the input as a number. |
setValue | (value: number) => voidFunction to set the value of the input. |
clearValue | VoidFunctionFunction to clear the value of the input. |
increment | VoidFunctionFunction to increment the value of the input by the step. |
decrement | VoidFunctionFunction to decrement the value of the input by the step. |
setToMax | VoidFunctionFunction to set the value of the input to the max. |
setToMin | VoidFunctionFunction to set the value of the input to the min. |
focus | VoidFunctionFunction to focus the input. |
Accessibility
Complies with the Spinbutton WAI-ARIA design pattern.
Keyboard Support
| Key | Description |
|---|---|
ArrowUp | Increments the value of the number input by a predefined step. |
ArrowDown | Decrements the value of the number input by a predefined step. |
PageUp | Increments the value of the number input by a larger predefined step. |
PageDown | Decrements the value of the number input by a larger predefined step. |
Home | Sets the value of the number input to its minimum allowed value. |
End | Sets the value of the number input to its maximum allowed value. |
Enter | Submits the value entered in the number input. |