|Kit

Number Input

A numeric input with increment / decrement steppers on Ark UI's NumberInput machine — clamping, locale-aware formatting, mouse-wheel, and the full keyboard model on the shared input shell.

NumberInput is a numeric <input> with spin buttons, built on Ark UI's NumberInput machine and the same shell as Input. It clamps to a range, formats with Intl.NumberFormat, supports the mouse wheel, and ships the full keyboard model ( / step, PageUp / PageDown jump, Home / End to min / max).

import { NumberInput } from '@42/ui-react/number-input';

<NumberInput defaultValue={3} min={0} max={10} />

The value is a real number — the machine speaks strings internally, but value / defaultValue take a number and onChange hands one back. Like the rest of the family it carries its own label, description, error, and required — no external wrapper needed — and passing error flips it to the invalid (red) state. Omit them and it still composes cleanly inside a Field.

Playground

Component

Loading preview

Props

Code

<Component  label="Slots"  size="md"  step={1}/>

Min, max & step

min / max clamp the range; step sets the spin amount. With allowMouseWheel, scrolling over a focused input nudges the value too.

Formatting

formatOptions is forwarded straight to Intl.NumberFormat, so currency, percent, and unit display come for free — the parsed value stays a plain number.

Sizes

Five heights — xs through xl — matching the rest of the family. The control font, padding, and the steppers scale to match.

Code

<NumberInput size="xs" defaultValue={1} /><NumberInput size="sm" defaultValue={1} /><NumberInput size="md" defaultValue={1} /><NumberInput size="lg" defaultValue={1} /><NumberInput size="xl" defaultValue={1} />

No controls

hideControls drops the steppers for a plain numeric field — useful inside dense forms where the spin buttons would crowd the layout.

Colors

Like the rest of the form family, the resting input is palette-independent — only the focus ring references --c-solid, so each palette tints the focus state for free. See Colors.

Code

<NumberInput color="brand" defaultValue={1} /><NumberInput color="green" defaultValue={1} /><NumberInput color="purple" defaultValue={1} />

Invalid & disabled

invalid swaps the border and ring to red regardless of color (and sets aria-invalid). disabled dims the shell and blocks input; readOnly keeps full contrast but rejects edits.

Code

<NumberInput invalid defaultValue={5} /><NumberInput disabled defaultValue={5} /><NumberInput readOnly defaultValue={5} />

With label, description & error

label, description (helper text), and error are built in via Field — no external wrapper needed. Passing error flips the shell to the invalid (red) state; required adds the semantic flag and a red asterisk on the label.

How many evaluation slots to book.
Pick at least one

Code

<NumberInput label="Slots" description="How many evaluation slots to book." defaultValue={1} min={1} /><NumberInput label="Slots" required defaultValue={1} min={1} /><NumberInput label="Slots" error="Pick at least one" defaultValue={0} min={1} />

If you omit these props, the control still composes inside an outer Field, inheriting the field's invalid, disabled, and readOnly from context — so an error on the field flips the input red automatically.

Controlled

Drive the value from state. onChange hands you a number (NaN while the field is empty or mid-edit).

'use client';
import { useState } from 'react';
import { NumberInput } from '@42/ui-react/number-input';

export function Slots() {
  const [value, setValue] = useState(1);
  return <NumberInput value={value} onChange={setValue} min={1} max={99} />;
}

Forms

A name wires the underlying input into native <form> submission and FormData — no controlled state required.

<form action={save}>
  <NumberInput name="slots" defaultValue={1} min={1} />
</form>

API

Prop

Type

Accessibility

  • Full NumberInput keyboard model from Ark: / step, PageUp / PageDown jump by a larger step, Home / End snap to min / max.
  • The input is role="spinbutton" with aria-valuemin / aria-valuemax / aria-valuenow / aria-valuetext wired from the machine.
  • invalid sets aria-invalid. Pass label / description / error for an accessible name and error text via the built-in Field, or compose inside an outer Field instead.
  • The steppers are real <button>s with Increment / Decrement labels; the wheel and scrub gestures are progressive enhancements over keyboard / typing.

On this page