

# NumberInput

Numeric field with increment and decrement steppers. Built on React Aria `NumberField` with a stepper group for keyboard- and pointer-friendly adjustments. Prefer this over a plain text field when the value must stay numeric.

## Examples

### Default

Pass a `label` and seed with `defaultValue` (or control via `value` / `onChange`).

```tsx
import { NumberInput } from '@var-ui/react';

<NumberInput label="Quantity" defaultValue={1} />
```

```astro
<!-- No Astro binding yet — use @var-ui/react -->
```

```html
<!-- No HTML demo yet — use @var-ui/react -->
```

### Bounds and step

Clamp the range with `minValue` / `maxValue` and set `step` for how far each stepper click (or arrow key) moves.

```tsx
import { NumberInput } from '@var-ui/react';

<NumberInput
  label="Quantity"
  defaultValue={1}
  minValue={0}
  maxValue={10}
  step={1}
  description="Between 0 and 10"
/>
```

```astro
<!-- No Astro binding yet — use @var-ui/react -->
```

```html
<!-- No HTML demo yet — use @var-ui/react -->
```

## Props

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| className | string \| undefined | no |  |  |
| description | string \| undefined | no |  | Helper text shown below the control when there is no error. |
| errorMessage | string \| undefined | no |  | Validation message; when set, the field is shown in an error state. |
| label | string \| undefined | no |  | Visible label rendered above the control. |
| placeholder | string \| undefined | no |  |  |
| aria-describedby | string \| undefined | no |  | Identifies the element (or elements) that describes the object. |
| aria-details | string \| undefined | no |  | Identifies the element (or elements) that provide a detailed, extended description for the object. |
| aria-label | string \| undefined | no |  | Defines a string value that labels the current element. |
| aria-labelledby | string \| undefined | no |  | Identifies the element (or elements) that labels the current element. |
| autoFocus | boolean \| undefined | no |  | Whether the element should receive focus on render. |
| children | ChildrenOrFunction<NumberFieldRenderProps> | no |  | The children of the component. A function may be provided to alter the children based on component state. |
| decrementAriaLabel | string \| undefined | no |  | A custom aria-label for the decrement button. If not provided, the localized string "Decrement" is used. |
| defaultValue | number \| undefined | no |  | The default value (uncontrolled). |
| dir | string \| undefined | no |  |  |
| form | string \| undefined | no |  | The `<form>` element to associate the input with. The value of this attribute must be the id of a `<form>` in the same document. See [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/input#form). |
| hidden | boolean \| undefined | no |  |  |
| id | string \| undefined | no |  | The element's unique identifier. See [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/id). |
| incrementAriaLabel | string \| undefined | no |  | A custom aria-label for the increment button. If not provided, the localized string "Increment" is used. |
| inert | boolean \| undefined | no |  |  |
| isDisabled | boolean \| undefined | no |  | Whether the input is disabled. |
| isInvalid | boolean \| undefined | no |  | Whether the input value is invalid. |
| isReadOnly | boolean \| undefined | no |  | Whether the input can be selected but not changed by the user. |
| isRequired | boolean \| undefined | no |  | Whether user input is required on the input before form submission. |
| isWheelDisabled | boolean \| undefined | no |  | Enables or disables changing the value with scroll. |
| lang | string \| undefined | no |  |  |
| maxValue | number \| undefined | no |  | The largest value allowed for the input. |
| minValue | number \| undefined | no |  | The smallest value allowed for the input. |
| name | string \| undefined | no |  | The name of the input element, used when submitting an HTML form. See [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#htmlattrdefname). |
| onAnimationEnd | AnimationEventHandler<HTMLDivElement> \| undefined | no |  |  |
| onAnimationEndCapture | AnimationEventHandler<HTMLDivElement> \| undefined | no |  |  |
| onAnimationIteration | AnimationEventHandler<HTMLDivElement> \| undefined | no |  |  |
| onAnimationIterationCapture | AnimationEventHandler<HTMLDivElement> \| undefined | no |  |  |
| onAnimationStart | AnimationEventHandler<HTMLDivElement> \| undefined | no |  |  |
| onAnimationStartCapture | AnimationEventHandler<HTMLDivElement> \| undefined | no |  |  |
| onAuxClick | MouseEventHandler<HTMLDivElement> \| undefined | no |  |  |
| onAuxClickCapture | MouseEventHandler<HTMLDivElement> \| undefined | no |  |  |
| onBeforeInput | FormEventHandler<HTMLInputElement> \| undefined | no |  | Handler that is called when the input value is about to be modified. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/beforeinput_event). |
| onBlur | ((e: FocusEvent<Element, Element>) => void) \| undefined | no |  | Handler that is called when the element loses focus. |
| onChange | ((value: number) => void) \| undefined | no |  | Handler that is called when the value changes. |
| onClick | MouseEventHandler<HTMLDivElement> \| undefined | no |  |  |
| onClickCapture | MouseEventHandler<HTMLDivElement> \| undefined | no |  |  |
| onCompositionEnd | CompositionEventHandler<HTMLInputElement> \| undefined | no |  | Handler that is called when a text composition system completes or cancels the current text composition session. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Element/compositionend_event). |
| onCompositionStart | CompositionEventHandler<HTMLInputElement> \| undefined | no |  | Handler that is called when a text composition system starts a new text composition session. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Element/compositionstart_event). |
| onCompositionUpdate | CompositionEventHandler<HTMLInputElement> \| undefined | no |  | Handler that is called when a new character is received in the current text composition session. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Element/compositionupdate_event). |
| onContextMenu | MouseEventHandler<HTMLDivElement> \| undefined | no |  |  |
| onContextMenuCapture | MouseEventHandler<HTMLDivElement> \| undefined | no |  |  |
| onCopy | ClipboardEventHandler<HTMLInputElement> \| undefined | no |  | Handler that is called when the user copies text. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/oncopy). |
| onCut | ClipboardEventHandler<HTMLInputElement> \| undefined | no |  | Handler that is called when the user cuts text. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/oncut). |
| onDoubleClick | MouseEventHandler<HTMLDivElement> \| undefined | no |  |  |
| onDoubleClickCapture | MouseEventHandler<HTMLDivElement> \| undefined | no |  |  |
| onFocus | ((e: FocusEvent<Element, Element>) => void) \| undefined | no |  | Handler that is called when the element receives focus. |
| onFocusChange | ((isFocused: boolean) => void) \| undefined | no |  | Handler that is called when the element's focus status changes. |
| onGotPointerCapture | PointerEventHandler<HTMLDivElement> \| undefined | no |  |  |
| onGotPointerCaptureCapture | PointerEventHandler<HTMLDivElement> \| undefined | no |  |  |
| onInput | FormEventHandler<HTMLInputElement> \| undefined | no |  | Handler that is called when the input value is modified. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/input_event). |
| onKeyDown | ((e: KeyboardEvent) => void) \| undefined | no |  | Handler that is called when a key is pressed. |
| onKeyUp | ((e: KeyboardEvent) => void) \| undefined | no |  | Handler that is called when a key is released. |
| onLostPointerCapture | PointerEventHandler<HTMLDivElement> \| undefined | no |  |  |
| onLostPointerCaptureCapture | PointerEventHandler<HTMLDivElement> \| undefined | no |  |  |
| onMouseDown | MouseEventHandler<HTMLDivElement> \| undefined | no |  |  |
| onMouseDownCapture | MouseEventHandler<HTMLDivElement> \| undefined | no |  |  |
| onMouseEnter | MouseEventHandler<HTMLDivElement> \| undefined | no |  |  |
| onMouseLeave | MouseEventHandler<HTMLDivElement> \| undefined | no |  |  |
| onMouseMove | MouseEventHandler<HTMLDivElement> \| undefined | no |  |  |
| onMouseMoveCapture | MouseEventHandler<HTMLDivElement> \| undefined | no |  |  |
| onMouseOut | MouseEventHandler<HTMLDivElement> \| undefined | no |  |  |
| onMouseOutCapture | MouseEventHandler<HTMLDivElement> \| undefined | no |  |  |
| onMouseOver | MouseEventHandler<HTMLDivElement> \| undefined | no |  |  |
| onMouseOverCapture | MouseEventHandler<HTMLDivElement> \| undefined | no |  |  |
| onMouseUp | MouseEventHandler<HTMLDivElement> \| undefined | no |  |  |
| onMouseUpCapture | MouseEventHandler<HTMLDivElement> \| undefined | no |  |  |
| onPaste | ClipboardEventHandler<HTMLInputElement> \| undefined | no |  | Handler that is called when the user pastes text. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/onpaste). |
| onPointerCancel | PointerEventHandler<HTMLDivElement> \| undefined | no |  |  |
| onPointerCancelCapture | PointerEventHandler<HTMLDivElement> \| undefined | no |  |  |
| onPointerDown | PointerEventHandler<HTMLDivElement> \| undefined | no |  |  |
| onPointerDownCapture | PointerEventHandler<HTMLDivElement> \| undefined | no |  |  |
| onPointerEnter | PointerEventHandler<HTMLDivElement> \| undefined | no |  |  |
| onPointerLeave | PointerEventHandler<HTMLDivElement> \| undefined | no |  |  |
| onPointerMove | PointerEventHandler<HTMLDivElement> \| undefined | no |  |  |
| onPointerMoveCapture | PointerEventHandler<HTMLDivElement> \| undefined | no |  |  |
| onPointerOut | PointerEventHandler<HTMLDivElement> \| undefined | no |  |  |
| onPointerOutCapture | PointerEventHandler<HTMLDivElement> \| undefined | no |  |  |
| onPointerOver | PointerEventHandler<HTMLDivElement> \| undefined | no |  |  |
| onPointerOverCapture | PointerEventHandler<HTMLDivElement> \| undefined | no |  |  |
| onPointerUp | PointerEventHandler<HTMLDivElement> \| undefined | no |  |  |
| onPointerUpCapture | PointerEventHandler<HTMLDivElement> \| undefined | no |  |  |
| onScroll | UIEventHandler<HTMLDivElement> \| undefined | no |  |  |
| onScrollCapture | UIEventHandler<HTMLDivElement> \| undefined | no |  |  |
| onSelect | ReactEventHandler<HTMLInputElement> \| undefined | no |  | Handler that is called when text in the input is selected. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Element/select_event). |
| onTouchCancel | TouchEventHandler<HTMLDivElement> \| undefined | no |  |  |
| onTouchCancelCapture | TouchEventHandler<HTMLDivElement> \| undefined | no |  |  |
| onTouchEnd | TouchEventHandler<HTMLDivElement> \| undefined | no |  |  |
| onTouchEndCapture | TouchEventHandler<HTMLDivElement> \| undefined | no |  |  |
| onTouchMove | TouchEventHandler<HTMLDivElement> \| undefined | no |  |  |
| onTouchMoveCapture | TouchEventHandler<HTMLDivElement> \| undefined | no |  |  |
| onTouchStart | TouchEventHandler<HTMLDivElement> \| undefined | no |  |  |
| onTouchStartCapture | TouchEventHandler<HTMLDivElement> \| undefined | no |  |  |
| onTransitionCancel | TransitionEventHandler<HTMLDivElement> \| undefined | no |  |  |
| onTransitionCancelCapture | TransitionEventHandler<HTMLDivElement> \| undefined | no |  |  |
| onTransitionEnd | TransitionEventHandler<HTMLDivElement> \| undefined | no |  |  |
| onTransitionEndCapture | TransitionEventHandler<HTMLDivElement> \| undefined | no |  |  |
| onTransitionRun | TransitionEventHandler<HTMLDivElement> \| undefined | no |  |  |
| onTransitionRunCapture | TransitionEventHandler<HTMLDivElement> \| undefined | no |  |  |
| onTransitionStart | TransitionEventHandler<HTMLDivElement> \| undefined | no |  |  |
| onTransitionStartCapture | TransitionEventHandler<HTMLDivElement> \| undefined | no |  |  |
| onWheel | WheelEventHandler<HTMLDivElement> \| undefined | no |  |  |
| onWheelCapture | WheelEventHandler<HTMLDivElement> \| undefined | no |  |  |
| render | DOMRenderFunction<"div", NumberFieldRenderProps> \| undefined | no |  | Overrides the default DOM element with a custom render function. This allows rendering existing components with built-in styles and behaviors such as router links, animation libraries, and pre-styled components.  Requirements:  - You must render the expected element type (e.g. if `<button>` is expected, you cannot render an   `<a>`). - Only a single root DOM element can be rendered (no fragments). - You must pass through props and ref to the underlying DOM element, merging with your own prop   as appropriate. |
| slot | string \| null \| undefined | no |  | A slot name for the component. Slots allow the component to receive props from a parent component. An explicit `null` value indicates that the local props completely override all props received from a parent. |
| step | number \| undefined | no |  | The amount that the input value changes with each increment or decrement "tick". |
| style | StyleOrFunction<NumberFieldRenderProps> \| undefined | no |  | The inline [style](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/style) for the element. A function may be provided to compute the style based on component state. |
| translate | "yes" \| "no" \| undefined | no |  |  |
| validate | ((value: number) => true \| ValidationError \| null \| undefined) \| undefined | no |  | A function that returns an error message if a given value is invalid. Validation errors are displayed to the user when the form is submitted if `validationBehavior="native"`. For realtime validation, use the `isInvalid` prop instead. |
| validationBehavior | "native" \| "aria" \| undefined | no | 'native' | Whether to use native HTML form validation to prevent form submission when the value is missing or invalid, or mark the field as required or invalid via ARIA. |
| value | number \| undefined | no |  | The current value (controlled). |
| commitBehavior | "validate" \| "snap" \| undefined | no | 'snap' | Controls the behavior of the number field when the user blurs the field after editing. 'snap' will clamp the value to the min/max values, and snap to the nearest step value. 'validate' will not clamp the value, and will validate that the value is within the min/max range and on a valid step. |
| formatOptions | NumberFormatOptions \| undefined | no |  | Formatting options for the value displayed in the number field. This also affects what characters are allowed to be typed by the user. |

## Accessibility

Built on React Aria `NumberField`. The increment and decrement controls expose `aria-label`s (“Increase” / “Decrease”). Pair with `label`, and use `description` / `errorMessage` so assistive tech gets the same help and validation copy as sighted users. Arrow keys adjust the value within any configured bounds.
