Skip to content

NumberInput

<NumberInput> is a quantity-style numeric input — text field plus +/ stepper buttons. Distinct from <Input type="number"> (browser-native; mobile keyboards vary) and from NumericInput (formatted strings, not raw numbers).

import from "@na/ui/components/NumberInput" ▶ Open in Storybook packages/ui/src/components/NumberInput.tsx

When to use

  • Quantity / count inputs (cart items, retries, replicas).
  • Bounded integer fields with min / max.
  • Anywhere a stepper makes incrementing / decrementing easier than typing.

Don’t use NumberInput for: currency / formatted numbers (NumericInput), unbounded ranges (a Slider might be better), or text-with-digits like phone numbers (MaskedInput).

Default

const [v, setV] = useState<number | undefined>(1);
<NumberInput value={v} onChange={setV} min={0} max={100} />

Custom step

<NumberInput value={v} onChange={setV} step={5} min={0} max={100} />

API

Prop Type Default Description
value number Controlled value. Pair with onChange.
defaultValue number Initial value for uncontrolled mode.
onChange (value: number | undefined) => void Fires on every change. undefined when the user clears the field.
min number Smallest allowed value. Decrement disabled at min.
max number Largest allowed value. Increment disabled at max.
step number 1 Stepper increment.
hideStepper boolean false Hide +/- buttons; the user types only.
disabled boolean false Disable trigger and steppers.

Design guidelines

✓ Do

  • Set min and max. Unbounded NumberInputs invite typos that crash the request.
  • Pick a step that matches the user's mental model — step={1} for items, step={5} or step={10} for cents / percentages.

✗ Don't

  • Use NumberInput for currency. The thousands separator + decimal handling belongs in NumericInput.
  • Default to a large step. step={100} surprises users.

Accessibility

  • Underlying <input type="number">role="spinbutton", aria-valuemin/max set automatically.
  • Stepper buttons are real <Button> instances with aria-label="Increment" / aria-label="Decrement".
  • Keyboard: / on the input increments / decrements.
  • NumericInput — Formatted numbers (currency, percent).
  • Slider — When position-in-range matters.
  • Input — Plain text input.

▶ Open NumberInput stories in Storybook