---
id: number-input
title: Number Input
description: A field that allows user input of numeric values.
---

<ComponentPreview id="NumberInput" />

## Anatomy

<Anatomy id="number-input" />

```tsx
<NumberInput.Root>
  <NumberInput.Label />
  <NumberInput.Scrubber />
  <NumberInput.Control>
    <NumberInput.Input />
    <NumberInput.IncrementTrigger />
    <NumberInput.DecrementTrigger />
  </NumberInput.Control>
</NumberInput.Root>
```

## Examples

<Example id="basic" />

### 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.

<Example id="min-max" />

> To allow values outside the min/max range, set `clampValueOnBlur` to `false`.

### 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`.

<Example id="fraction-digits" />

### 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.

<Example id="scrubber" />

### 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`.

<Example id="mouse-wheel" />

### Formatting

To apply custom formatting to the input's value, set the `formatOptions` and provide `Intl.NumberFormatOptions` such as
`style` and `currency`.

<Example id="formatting" />

### 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.

<Example id="with-field" />

### 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.

<Example id="root-provider" />

## 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](https://developer.mozilla.org/en-US/docs/Web/API/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.

```tsx
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`:

```tsx
<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

<ComponentTypes id="number-input" />

### Context

<ContextType id="number-input" />

## Accessibility

Complies with the [Spinbutton WAI-ARIA design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/spinbutton/).

### Keyboard Support

<KeyBindingsTable id="number-input" />
