NumberField
4 partsA numeric input with stepper controls, keyboard increment/decrement, and
optional clamping. The interactive root: it owns the value (controlled via
v-model / update:modelValue or uncontrolled via defaultValue), clamps
to min/max, snaps to step, formats with the active locale, and provides
context to NumberFieldInput, NumberFieldIncrement, and
NumberFieldDecrement. Use it whenever you need a styled number entry with
spinner buttons and arrow-key support.
Demo
Anatomy
Import the parts and compose them. Each part forwards attributes to its underlying element.
import {
NumberFieldDecrement,
NumberFieldIncrement,
NumberFieldInput,
NumberFieldRoot,
} from '@robonen/primitives/forms/number-field';
<NumberFieldRoot>
<NumberFieldDecrement />
<NumberFieldIncrement />
<NumberFieldInput />
</NumberFieldRoot>API Reference
NumberFieldDecrement
DecrementA button that decreases the value by one `step`. Rendered as a `<button>` by default, kept out of the tab order (the input is the focusable spinbutton) but exposed to assistive tech with an `aria-label`. Holding the button auto-repeats the decrement, and it is disabled when the root is `disabled`/`readonly`, when its own `disabled` prop is set, or when the value is already at `min`.
| Prop | Type | Description |
|---|---|---|
disabled? | boolean | Disable this button independently of the root. |
ariaLabel? | string | Accessible label for assistive tech. Bind via aria-label (Vue maps the
kebab-case attribute to this prop). |
NumberFieldIncrement
IncrementA button that increases the value by one `step`. Rendered as a `<button>` by default, kept out of the tab order (the input is the focusable spinbutton) but exposed to assistive tech with an `aria-label`. Holding the button auto-repeats the increment, and it is disabled when the root is `disabled`/`readonly`, when its own `disabled` prop is set, or when the value is already at `max`.
| Prop | Type | Description |
|---|---|---|
disabled? | boolean | Disable this button independently of the root. |
ariaLabel? | string | Accessible label for assistive tech. Bind via aria-label (Vue maps the
kebab-case attribute to this prop). |
NumberFieldInput
InputThe text field that displays and edits the value, rendered as a native `<input role="spinbutton">` wired to the root context. It parses typed input, mirrors the current value via `aria-valuenow`/`aria-valuemin`/`aria-valuemax`, and handles Arrow/Page/Home/End keys to step, jump, or clamp to the bounds. Mouse-wheel scrolling steps the value while focused, keystrokes that would produce an invalid number are rejected, and the value is re-clamped, snapped, and reformatted on blur or Enter.
| Prop | Type | Description |
|---|---|---|
placeholder? | string | — |
name? | string | — |
required? | boolean | — |
NumberFieldRoot
RootA numeric input with stepper controls, keyboard increment/decrement, and optional clamping. The interactive root: it owns the value (controlled via `v-model` / `update:modelValue` or uncontrolled via `defaultValue`), clamps to `min`/`max`, snaps to `step`, formats with the active locale, and provides context to `NumberFieldInput`, `NumberFieldIncrement`, and `NumberFieldDecrement`. Use it whenever you need a styled number entry with spinner buttons and arrow-key support.
| Prop | Type | Description |
|---|---|---|
defaultValue? | number | null | — |
min? | number | — |
max? | number | — |
step? | number | — |
stepSnapping? | boolean | When false, values are clamped but not snapped to the nearest step. |
disabled? | boolean | — |
readonly? | boolean | — |
name? | string | Native input name; submits the value with the surrounding <form>. |
required? | boolean | Mark the field required so native form validation fires on empty submit. |
formatOptions? | Intl.NumberFormatOptions | Intl.NumberFormat options controlling display and the allowed characters. |
locale? | string | Locale override for formatting/parsing; falls back to the app ConfigProvider. |
disableWheelChange? | boolean | When false, wheel scrolling over the input does not change the value. |
invertWheelChange? | boolean | Invert the direction of wheel-driven stepping. |
focusOnChange? | boolean | When true (default), stepper buttons return focus to the input. |
modelValue? | number | null | Two-way bound value (v-model). |
| Event | Payload |
|---|---|
update:modelValue | [value: number | null] |