NumberInput
elements man ui/templates/number-inputA number field with stepper buttons, keyboard steps, formatting, wheel and scrub.
Exampleimport { NumberInput } from "@elements/ui/number-input"; <NumberInput value={cart.quantity} min={1} max={99} attrs={{ "aria-label": "Quantity" }} /> <NumberInput value={form.price} format={{ style: "currency", currency: "USD" }} step={0.5} /> <NumberInput value={layer.width} scrubLabel="Width" buttons="end" allowWheelScrub />
Parts
| Part | What it is |
|---|---|
.number-input |
The root. |
.number-input-scrub |
The scrub label. |
.number-input-group |
The bordered control holding the input and buttons. |
.number-input-input |
The text input, role=spinbutton. |
.number-input-button |
Decrement and increment buttons. |
.number-input-cursor |
The cursor drawn while a scrub holds pointer lock. |
Attributes
| Attribute | Type | Default | Description |
|---|---|---|---|
value |
number | null (two-way) |
null |
The number; null when the input is empty. |
min |
number | undefined |
undefined |
Lowest value. Home goes here. |
max |
number | undefined |
undefined |
Highest value. End goes here. |
step |
number | "any" |
1 |
Arrow and button step. "any" steps by 1. |
smallStep |
number |
0.1 |
Alt + arrow step. |
largeStep |
number |
10 |
Shift + arrow, PageUp and PageDown step. |
snapOnStep |
boolean |
false |
Steps land on multiples of the step. |
allowOutOfRange |
boolean |
false |
Typed values may stay outside min and max (marked invalid). |
allowWheelScrub |
boolean |
false |
The mouse wheel steps while the input is focused and hovered. |
format |
Intl.NumberFormatOptions |
{} |
Display format: currency, percent, unit, fraction digits, grouping. |
locale |
string |
"" |
Locale for formatting and parsing; empty uses the browser's. |
buttons |
"sides" | "end" | "none" |
"sides" |
Minus and plus on each side, stacked chevrons at the end, or none. |
size |
"sm" | "md" | "lg" |
"md" |
Height and type size from the control tokens. |
scrubLabel |
string |
"" |
A label above the input you drag to change the value. |
scrubDirection |
"horizontal" | "vertical" |
"horizontal" |
Which drag direction scrubs. |
pixelSensitivity |
number |
2 |
Pixels of drag per step. |
teleportDistance |
number |
0 |
How far the scrub cursor travels before it loops back; 0 loops at the window's edge. |
placeholder |
string |
"" |
Shown while empty. |
name |
string |
"" |
Submits the raw number with the form. |
form |
string |
"" |
The id of the form the value belongs to. |
disabled |
boolean |
false |
Not interactive. |
readonly |
boolean |
false |
Focusable and readable, not editable. |
required |
boolean |
false |
The form will not submit while empty. |
invalid |
boolean |
false |
Marks the field invalid. |
incrementLabel |
string |
"Increase" |
The increment button's accessible name. |
decrementLabel |
string |
"Decrease" |
The decrement button's accessible name. |
roleDescription |
string |
"Number field" |
aria-roledescription on the input. |
class |
string |
"" |
Extra classes on the root. |
attrs |
Record<string, string | number | boolean | undefined> |
{} |
Attributes for the input: id, aria-label, data-*. |
onValueChange |
(value: number | null, details: NumberInputChangeDetails) => void |
() => {} |
Every change, with details.reason, details.direction and details.cancel(). |
onValueCommit |
(value: number | null, details: NumberInputCommitDetails) => void |
() => {} |
When a change is final: blur, Enter, a key step, a button release, wheel or scrub end. |
Keyboard
| Keys | Action |
|---|---|
ArrowUp / ArrowDown |
Step up or down. |
Shift + ArrowUp / ArrowDown |
Large step. |
Alt + ArrowUp / ArrowDown |
Small step. |
PageUp / PageDown |
Large step. |
Home / End |
Go to min or max, when set. |
Enter |
Formats, clamps and commits the typed value. |
Data attributes
| Attribute | Values | On |
|---|---|---|
data-disabled |
present when disabled | root, scrub, group, input, buttons, cursor |
data-readonly |
present when read-only | root, scrub, group, input, buttons, cursor |
data-required |
present when required | root, scrub, group, input, buttons, cursor |
data-step-mismatch |
present while the value is off step from an explicit min; the form will not submit | root |
data-invalid |
present when invalid or out of range | root, scrub, group, input, buttons, cursor |
data-focused, data-filled, data-dirty, data-touched, data-valid |
inside a Field, mirror the Field's state | root, scrub, group, input, buttons, cursor |
data-scrubbing |
present while scrubbing | root, scrub, group, input, buttons, cursor |
data-buttons |
"sides" | "end" | "none" |
group |
data-direction |
"up" | "down" |
button |
Accessibility
- The input is role=spinbutton with aria-valuenow, aria-valuemin, aria-valuemax and aria-valuetext for formatted values.
- The buttons are out of the tab order (the arrow keys do their job), named Increase and Decrease, and point at the input with aria-controls.
- A value outside min and max sets aria-invalid.
- The scrub label is the input's label, so it names the field too.
See also
- Slider (opens in a new tab): Pick a value or a range by dragging thumbs along a track, with full keyboard support.
- PasswordInput (opens in a new tab): A password field with a button that shows and hides what was typed.
- InputOTP (opens in a new tab): A one-time code in separate slots, with paste, SMS autofill and a pattern.
- TagsInput (opens in a new tab): Type a list of tags into one field: add, edit, delete and paste them from the keyboard.
- ColorPicker (opens in a new tab): Pick a color with an area, channel sliders, inputs, swatches and the eye dropper.
- FileUpload (opens in a new tab): Drop, paste or browse for files; see them listed with previews, sizes, errors and progress.