Components
Button Group
Joins a set of independent actions into one control -- a shared edge, with the radius on the outermost corners only. Each button fires its own action; the group holds no selected state.
Choosing one option (a view or filter switch) is not this -- use Tabs or a single-select Toggle Group. On/off formatting (bold, italic) is a Toggle Group. Button Group is only for actions that sit together but act independently.
Preview
Rendered with live Folio tokens. The seam is shared; only the outer corners round, no dark: classes.
Variants
<ButtonGroup>
<Button variant="outline"><ChevronLeft /> Previous</Button>
<Button variant="outline">Next <ChevronRight /></Button>
</ButtonGroup><ButtonGroup>
<Button variant="outline"><Undo2 /></Button>
<Button variant="outline"><Redo2 /></Button>
</ButtonGroup><ButtonGroup>
<Button variant="outline">Cut</Button>
<Button variant="outline">Copy</Button>
<Button variant="outline">Paste</Button>
</ButtonGroup><ButtonGroup orientation="vertical">
<Button variant="outline">Duplicate</Button>
…
</ButtonGroup>Text pairs, icon actions, action triads, and vertical stacks all join the same way. Set orientation to stack them.
States
Default. At rest.
Hover. Per button, on pointer over (shown statically).
Active. Press feedback per button (shown statically).
<Button variant="outline" disabled>Cut</Button>
<Button variant="outline" disabled>Copy</Button>
<Button variant="outline" disabled>Paste</Button><Button variant="outline" disabled>Hover and active respond per button. The group has no disabled prop: set disabled on each button to disable the whole set, or on one button only.
API
Individual buttons accept standard Button props, including variant, size, and disabled. Set them on each button; the group does not pass them down. The module also exports ButtonGroupText (a static label segment) and ButtonGroupSeparator (a divider between segments).
Don't and Do
Don't use a Button Group to pick one option -- a Day / Week / Month view switcher is mutually exclusive, so it's Tabs or a single-select Toggle Group. Bold / Italic / Underline hold on/off state, so that's a Toggle Group. And don't join unrelated actions -- the shared edge says they belong together.
// Independent actions that belong together
<ButtonGroup>
<Button variant="outline"><ChevronLeft /> Previous</Button>
<Button variant="outline">Next <ChevronRight /></Button>
</ButtonGroup>Use it for independent actions that belong together: Previous / Next, Undo / Redo, or Cut / Copy / Paste.
import { ButtonGroup } from "@/components/shadcn/button-group";
import { Button } from "@/components/shadcn/button";
import { Undo2, Redo2 } from "lucide-react";
// A toolbar of independent actions -- each fires on its own, no selected state.
export function HistoryControls() {
return (
<ButtonGroup>
<Button variant="outline" aria-label="Undo"><Undo2 /></Button>
<Button variant="outline" aria-label="Redo"><Redo2 /></Button>
</ButtonGroup>
);
}