NumberInput
Numeric input with stepper buttons, clamping, precision, and locale formatting
Category: inputs · WCAG 2.2-AA · form, number, input, spinbutton, stepper
Sizes
- sm
- md
- lg
States
- idle
- focused
- error
Props
| Prop | Type | Default | Description |
|---|---|---|---|
value | number | null | — | The controlled value. |
defaultValue | number | — | The initial value when uncontrolled. |
onValueChange | (value: number | null) => void | — | Fired on commit (blur, Enter, stepping); null when empty or unparseable |
onChange | (value: number | null) => void | — | Deprecated: use onValueChange (same number | null) |
min | number | — | Minimum allowed value. |
max | number | — | Maximum allowed value. |
step | number | 1 | Increment between allowed values. |
precision | number | — | Decimal places applied on commit |
formatOptions | Intl.NumberFormatOptions | — | Display formatting applied on blur; raw editable string while focused |
label | string | — | Text label for the control. |
hint | string | — | Supplementary hint text shown with the control. |
error | string | — | Error message shown when the value is invalid. |
size | 'sm' | 'md' | 'lg' | md | Visual size of the component (e.g. 'sm', 'md', 'lg'). |
disabled | boolean | false | When true, disables the control and removes it from the tab order. |
incrementLabel | string | Increment | Accessible label for the increment button. |
decrementLabel | string | Decrement | Accessible label for the decrement button. |
Design tokens
--cascivo-color-surface--cascivo-color-border--cascivo-color-accent--cascivo-color-destructive--cascivo-color-bg-subtle--cascivo-color-text-subtle--cascivo-radius-input--cascivo-focus-ring
When to use
- Collecting a bounded numeric value where increment/decrement by a known step is natural (quantity, opacity, count)
- Numeric entry that needs clamping to min/max, fixed precision, or locale-aware display formatting (e.g. currency)
- Inputs where keyboard ArrowUp/ArrowDown stepping speeds up adjustment
When not to use
- Free-form or non-numeric text — use Input
- Choosing along a continuous range where the exact number matters less than the relative position — use Slider
- Phone numbers, PINs, or codes that are digit strings rather than quantities — use Input or OtpInput
How to build an accessible NumberInput in React →
Examples
Basic
<NumberInput label="Quantity" defaultValue={1} min={0} max={99} />Currency
<NumberInput label="Price" precision={2} formatOptions={{ style: "currency", currency: "USD" }} />Stepped
<NumberInput label="Opacity" min={0} max={1} step={0.1} />