InputNumber Atom
A text input that speaks numbers rather than <input type="number">, which scrolls its value away
under the wheel, accepts e and +, and formats inconsistently across locales.
Usage
Between 1 and 10.
Steps of 0.25 — no floating point crumbs.
Current value: 3
<Field label="Seats" hint="Between 1 and 10."> <InputNumber value={seats} onValueChange={setSeats} min={1} max={10} /></Field>What it gets right
- Clamping happens on blur, not on keystroke. Clamping while someone types fights them: type
1toward15in a field withmin={10}and the naive version rewrites it to10mid-word. - Steps do not leak floating point.
0.1 + 0.2reads as0.3, because the step's own precision decides the rounding. - An empty field is
null, not0. Those mean different things, and a form that confuses them saves zero when a person meant "unset". - A comma decimal separator parses. Half the world types
12,5. - The step buttons disable when they would do nothing — at
max, the increase button is out.
Props
| Prop | Type | Default | Notes |
|---|---|---|---|
| value / defaultValue | number | null | — | null is the empty field, and it is a real value. |
| onValueChange | (value: number | null) => void | — | Fires while typing; the clamped value arrives on blur. |
| min / max | number | — | Bounds. Applied on blur and by the step buttons. |
| step | number | 1 | Also sets the rounding precision. |
| suffix | string | — | Unit shown inside the control. Decorative — keep the unit in the label too. |
| size / disabled / invalid | — | — | As every other control. |
Do
Give bounded fields a min and max, so the step buttons can tell a person where the edges are.
Don't
Use it for a phone number or a PIN — those are text that happens to be digits.