Manual UI Templates NumberInput

NumberInput

elements man ui/templates/number-input

A number field with stepper buttons, keyboard steps, formatting, wheel and scrub.

Example
import { 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