Skip to content

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

Free

Stepper Button Group for Ark UI

Steppers with a field between the buttons: quantity steps by 1 from 1, price by 10 from 100.

A field with down and up on either side. Quantity starts at 1 and steps by 1. Price starts at 100 and steps by 10. The buttons stop at 0. A typed negative number is stored as typed. Clearing the field stores 0.

Use this when the field and the buttons should share one border. Limits, steps, and keyboard increments together are Number Input. In React, Ark UI does not clamp a number someone types.

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

Button Group anatomy: root, group, button, separator

Usage

<div className="flex flex-col gap-4">
  <ButtonGroup aria-label="Quantity">
    <Button
      aria-label="Decrease quantity"
      onClick={decreaseQuantity}
      size="icon-md"
      variant="outline"
    >
      <ChevronDownIcon aria-hidden="true" />
    </Button>
    <Input
      aria-label="Quantity"
      className="w-20 bg-background text-center"
      onChange={handleQuantityChange}
      type="number"
      value={quantity}
    />
    <Button
      aria-label="Increase quantity"
      onClick={increaseQuantity}
      size="icon-md"
      variant="outline"
    >
      <ChevronUpIcon aria-hidden="true" />
    </Button>
  </ButtonGroup>
  <ButtonGroup aria-label="Price">
    <Button
      aria-label="Decrease price"
      onClick={decreasePrice}
      size="icon-md"
{/* The rest of the file is under Installation. */}

FAQ

How are the values tracked?

Each stepper keeps a number, 1 and 100. Down subtracts the step and stops at 0, up adds it, and typing in the field stores the typed number.

How are the chevron buttons named?

Each has an aria-label, such as Decrease quantity or Increase price, and size="icon-md". The fields have aria-labels too, Quantity and Price.

What happens if someone types a negative number?

It's stored as typed; only the buttons stop at 0. Add min to the input and clamp the typed value if negatives aren't allowed.

What happens when the field is cleared?

An empty field is stored as 0, since the demo converts the text to a number. Keep the raw text if you need to tell empty from 0.

Is there a component for this?

Yes. Number Input handles typing, limits, steps and keyboard increments in one component.

How wide is the field?

w-20 for the quantity and w-24 for the price, with text-center so the number sits between the buttons.

API Reference

Button Group

Sets aria-label="Quantity" and aria-label="Price". The rest is on the Button Group page.

Button

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

Input

Sets aria-label="Quantity", onChange={handleQuantityChange}, type="number", value={quantity}, aria-label="Price" and onChange={handlePriceChange}. The rest is on the Input page.