Skip to content

shadcn.io is an independent project built on shadcn/ui

Free

Number Input with Controls for Ark UI

A Quantity field that starts at 1, between a minus button that stops at 1 and a plus button, and that still allows typing.

Quantity starts at 1, between a minus button and a plus button. Minus stops at 1. Plus keeps going. People can also type in the field.

Use it for a small count, such as items in a cart. Stepping and a minimum kept for you already exist on Number Input. In React, Ark UI does not clamp what you type here.

Preview

Preview width

Installation

Sign in to get your install command
Free with an account. It carries your token, so the CLI installs everything in one go.
Use email insteadNo credit card

Anatomy

Input anatomy: input, placeholder, value, caret

Usage

<Field className="w-full max-w-sm">
  <FieldLabel>Quantity</FieldLabel>
  <div className="flex gap-2">
    <Button
      aria-label="Decrease quantity"
      onClick={handleDecrement}
      size="icon-md"
      type="button"
      variant="outline"
    >
      <MinusIcon aria-hidden="true" />
    </Button>
    <Input
      className="bg-background text-center"
      min="1"
      onChange={handleChange}
      type="number"
      value={value}
    />
    <Button
      aria-label="Increase quantity"
      onClick={handleIncrement}
      size="icon-md"
      type="button"
      variant="outline"
    >
      <PlusIcon aria-hidden="true" />
    </Button>
  </div>
</Field>

FAQ

How do the buttons change the number?

The quantity lives in state, starting at 1. Minus lowers it by one but never below 1; plus raises it by one with no upper limit.

Can people type the quantity?

Yes. The input is type number with min 1, and what's typed is converted to a number and stored. text-center centers the digits between the buttons.

How do screen readers know what the buttons do?

They show only an icon, MinusIcon or PlusIcon with aria-hidden, so each has an aria-label: Decrease quantity and Increase quantity.

How are the buttons styled?

variant outline and size icon-md, square buttons matching the input's height, in a row with gap-2. They're type button, so pressing one never submits a form.

Is there a ready-made number field?

Yes. Number Input has increment and decrement controls, clamping, step and formatting built in. This example builds the pattern from an Input and two Buttons.

How is Quantity tied to the field?

Clicking the label focuses the field, and screen readers announce it with the field. The buttons are separate controls with their own names. Field links FieldLabel to the input inside it, so there is no id to match.

API Reference

Field

No extra props in this demo. The rest is on the Field page.

Button

Sets aria-label="Decrease quantity", onClick={handleDecrement}, size="icon-md", type="button", variant="outline" and aria-label="Increase quantity". The rest is on the Button page.

Input

Sets min="1", onChange={handleChange}, type="number" and value={value}. The rest is on the Input page.