Components / Actions

ButtonGroup

Related actions joined into one surface with hairline dividers: a hover highlight glides between segments, the pressed one answers in place, and an attached menu can close the row.

Install

npx shadcn@latest add https://irisui.dev/r/button-group.json
import { ButtonGroup } from "@/components/iris/button-group/button-group";
Registry item button-groupBrings in foundationRegistry JSON

Preview

ButtonGroup

Related actions joined into one surface with hairline dividers: a hover highlight glides between segments, the pressed one answers in place, and an attached menu can close the row.

When to use

  • A short set of related, equal-weight actions on one object — Comment / Share / Export on a document, Undo / Redo / Run in an editor.
  • Compact controls with a live value between them, such as zoom out / 100% / zoom in (use content on the middle segment).
  • For actions as separate soft buttons in a tray (selection toolbars, canvas rails), use FloatingButtonGroup. For choosing one option from a set, use a segmented control instead.

Usage

import { ButtonGroup } from "@/components/iris/button-group/button-group";

<ButtonGroup
  label="Document actions"
  items={[
    { id: "comment", label: "Comment", icon: <MessageIcon /> },
    { id: "share", label: copied ? "Copied" : "Share", reserve: ["Copied"], icon: <ShareIcon />, onSelect: copyLink },
    { id: "export", label: "Export", icon: <DownloadIcon /> },
  ]}
  menu={{
    label: "More actions",
    items: [
      { id: "duplicate", label: "Duplicate", onSelect: duplicate },
      { id: "delete", label: "Delete document", destructive: true, onSelect: remove },
    ],
  }}
/>;

Props

Prop Type Default Description
items ButtonGroupItem[] — Segments (required): { id, label, reserve?, icon?, iconOnly?, content?, onSelect?, href?, disabled? }.
label string — Accessible name of the group (required), e.g. "Document actions".
menu { label, items: ButtonGroupMenuItem[] } — Adds a trailing chevron segment opening a menu. Items: { id, label, icon?, onSelect?, href?, disabled?, destructive? }.
variant "outline" | "solid" "outline" Surface style.
size "sm" | "md" "md" Segment height.
orientation "horizontal" | "vertical" "horizontal" Row or column.
collapseLabels boolean true When the row overflows its container, segments with an icon drop their label. Horizontal only.
disabled boolean false Disables every segment and the menu.
className, style — — Passed to the root.

Notes

  • Renders role="group" with your label. Arrow keys (Left/Right, or Up/Down when vertical), Home and End move focus between segments.
  • iconOnly segments use the label as accessible name and tooltip. reserve sizes a segment to its widest label so a label swap never shifts the row.
  • href renders a segment as a link. The highlight glides for the pointer and jumps for the keyboard; reduced motion removes the glide.