Xzero UI
Pro library

Number field

Enter a bounded number with clear increment controls.

$ pnpm dlx shadcn@4.23.0 add @xzero-ui/number-field
Live · keyboard ready

When to use

When not to use

Installation

Register both Xzero UI namespaces in your project's components.json:

{
  "registries": {
    "@xzero-ui": "https://mcp.xzero.co.uk/r/{name}.json",
    "@xzero-ui-pro": "https://mcp.xzero.co.uk/r/pro/{name}.json"
  }
}
npx shadcn@4.23.0 add @xzero-ui/number-field

Install xzero-foundation once, and import @/components/xzero/foundation.css in your app root. No Xzero token is used by this snapshot. For sample portraits, photos, fonts, or logos, download https://mcp.xzero.co.uk/install-assets.mjs and run node xzero-install-assets.mjs <receiving-project>.

Usage

import { NumberField } from "@/components/xzero/number-field/number-field";

export function SeatsField() {
  const [seats, setSeats] = useState(5);
  return (
    <NumberField
      label="Seats"
      value={seats}
      onValueChange={setSeats}
      min={1}
      max={500}
      suffix={(n) => (n === 1 ? " seat" : " seats")}
      scrub
    />
  );
}

API reference

NumberField

A numeric spinbutton with stepper buttons, rolling digits, hold-to-repeat, and optional label scrubbing.

PropTypeDefaultDescription
label (required)string–Visible label; also names the stepper buttons.
valuenumber–Controlled value.
defaultValuenumber0Initial value when uncontrolled.
onValueChange(value: number) => void–Called on every committed step, scrub, or valid typed draft.
minnumber0Lower bound.
maxnumberNumber.MAX_SAFE_INTEGERUpper bound.
stepnumber1Increment; its precision also sets default fraction digits.
largeStepnumberstep * 10Distance for PageUp, PageDown, and Shift with an arrow.
descriptionstring–Helper copy under the field.
disabledboolean–Disables the input and buttons.
idstring–Input id. Generated when omitted.
prefixstring | ((value: number) => string)–Text before the number, such as "$".
suffixstring | ((value: number) => string)–Text after the number; a function can pluralize, e.g. n => n === 1 ? " seat" : " seats".
scrubbooleanfalseDrag the label sideways to change the value.
localestring"en-US"Formatting locale, fixed so server and client match.
formatOptions{ minimumFractionDigits?: number; maximumFractionDigits?: number; useGrouping?: boolean }–Fraction digits and grouping.
size"sm" | "md" | "lg""md"Control height, type size, and default width (164, 196, or 228px).
limitHintboolean | ((edge: "min" | "max", limit: number) => string)trueNote beside the label when a press meets a limit (about 1.5s) or a typed value passes one. Defaults to "Max 10 seats" using the prefix and suffix; false hides it.

Keyboard interactions

KeysAction
ArrowUp / ArrowDownSteps by step; holding repeats and speeds up, and keeps pushing at a limit.
Shift + Arrow / PageUp / PageDownSteps by largeStep.
Home / EndJumps to min or max when not typing.
EnterCommits a typed draft, clamped to min and max, or selects the value.
EscapeReverts a typed draft to the value before editing.

Accessibility

Motion

Responsive behavior

Performance

Notes for AI

Also in special inputs

Guidance for AI tools

Number field: Enter a bounded number with clear increment controls. Follow the declared prop types and do not invent props. Keep keyboard access, reduced motion support, and both light and dark themes intact when adapting it.

Full library index: https://ui.xzero.co.uk/llms.txt

Browse all components