Skip to content

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

Free

Segmented Control Button Group for Ark UI

Ghost segments for Overview through Settings, and for Day through Year, each row keeping its own selection.

Two segment rows, and they do not share a value. The first is Overview, Analytics, Reports, and Settings, starting on Overview. The second is Day, Week, Month, and Year, starting on Week. Only the selected button is filled. No panel changes.

Use ghost segments when the row should stay quiet. If each choice reveals its own panel, use Tabs. In React, Ark UI does not show a panel for the selected segment.

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="Section">
    {TABS.map((item) => (
      <Button
        aria-pressed={tab === item.value}
        key={item.value}
        onClick={handleTab}
        size="sm"
        value={item.value}
        variant={tab === item.value ? "default" : "ghost"}
      >
        {item.label}
      </Button>
    ))}
  </ButtonGroup>
  <ButtonGroup aria-label="Period">
    {PERIODS.map((item) => (
      <Button
        aria-pressed={period === item.value}
        key={item.value}
        onClick={handlePeriod}
        size="sm"
        value={item.value}
        variant={period === item.value ? "default" : "ghost"}
      >
        {item.label}
      </Button>
    ))}
  </ButtonGroup>
</div>

FAQ

How is each selection tracked?

Each group has its own value, overview and week. Each button carries its own value, and pressing it stores that value for its group.

Why ghost and not outline?

variant="ghost" shows no edge until hover, so the row reads as one strip with a single filled segment. Use outline if the options should look like separate buttons.

How is the selected segment announced?

It sets aria-pressed, so a screen reader reads it as pressed.

Should Overview, Analytics and Reports be Tabs?

If they switch panels on the page, yes: Tabs link each trigger to its panel and handle Arrow keys. Use buttons when the choice changes a setting rather than which panel is visible.

Does the demo switch any content?

No. It only stores the two values. Render your sections or data from them.

What size are the buttons?

All use size="sm".

API Reference

Button Group

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

Button

Sets aria-pressed={tab === item.value}, onClick={handleTab}, size="sm", value={item.value}, variant={tab === item.value ? "default" : "ghost"} and aria-pressed={period === item.value}. The rest is on the Button page.