Appica UIUI 1.0.0

Number Field

A number input with stepper buttons for adjusting the value.

Usage

NumberField folds the decrement button, text input, and increment button into one control — you render a single <NumberField />, not a set of parts. It accepts only numeric input, steps with the buttons or the ↑/↓ arrow keys, and reformats the value when you commit. Use it uncontrolled with defaultValue, or controlled with value + onValueChange.

Unlike a checkbox or radio, the input is a real text field, so give it a label the usual way — an external <label htmlFor> pointing at the field's id, or an aria-label. The rolling-digit animation on stepper presses is skipped when the user prefers reduced motion.

Examples

Variants

variant switches the appearance between a bordered outline (default) and a filled soft field. The stepper buttons invert their fill so they stay legible against either.

Sizes

size scales the field width, steppers, and text together — sm, md (default), or lg.

Min, max & step

min and max clamp the value and disable the stepper once a bound is reached; clearing the field and blurring snaps back to min (or 0). step sets how far each press or arrow key moves the value — hold Shift for largeStep (10× by default) or Alt for smallStep.

Formatting

Pass format — an Intl.NumberFormatOptions object — and an optional locale to display the value as currency, a percentage, units, and the like. The display reformats while the underlying value stays a plain number.

Controlled

Drive the value yourself with value + onValueChange. The handler receives null when the field is empty, so coalesce before using the number.

Disabled & error states

disabled greys out the field and both steppers and blocks interaction. Set aria-invalid to paint the error state — it's mirrored to data-invalid on the field and its steppers. Wrapping the field in a Field marked invalid produces the same styling and is the better choice when you're also rendering a validation message.

RTL

Every Appica UI component supports right-to-left layouts out of the box. Set the dir attribute on a container (commonly your <html> element) so CSS logical properties resolve correctly, and wrap your tree in DirectionProvider so direction-aware behavior — roving focus, popup placement, and the like — follows the same direction.

The decrement and increment steppers swap sides to follow the resolved direction, and a matching locale formats the value with that locale's own digits. For setup details and caveats, see the RTL guide.

API reference

A single control. The variant, size, placeholder, and inputProps props are Appica additions; every other prop is forwarded to Base UI's NumberField.Root.

NumberField wraps Base UI's NumberField (Root, Input, Increment, Decrement) and forwards every remaining Root prop. It exposes data-* state attributes (data-disabled, data-readonly, data-invalid, data-scrubbing, …) on the field and its parts for styling — see the Base UI docs for the full surface. When placed inside a Base UI Field.Root marked invalid, the error state (data-invalid) propagates to the input and both steppers automatically.

Accessibility

  • The inner element is a real <input> with role="spinbutton", exposing aria-valuenow, aria-valuemin, and aria-valuemax to assistive tech.
  • Give the field an accessible name — an external <label htmlFor> pointing at its id, or an aria-label.
  • The steppers are real <button>s labelled Increase value / Decrease value, and become disabled at a bound or when the field is disabled.
  • ↑/↓ step the value (with Shift/Alt for the large/small step), and typing accepts only valid numeric input.
  • disabled blocks all interaction; readOnly keeps the field focusable but inert.
  • aria-invalid is bridged to data-invalid so the error state can be styled without a wrapping Field.
  • The rolling-digit animation on stepper presses honours prefers-reduced-motion.

© 2026 Appica UI. A free component library, crafted by the Appica team.