Button Group
A Button Group joins related Buttons into one control to show users that their actions belong together.
When to Use
- for actions on one record that belong together, such as “Duplicate”, “Download”, and “Archive” on an invoice
- to place a Dropdown Menu of further actions next to a main one, such as “Send invoice”
- to join a Button or a Select to an Input, for example a currency to an amount
When Not to Use
- for options that stay on after a click (use a Toggle Group)
- to choose one of a few options (use a Segmented Control)
- to place an icon or a Button inside the edge of an Input (use an Input Group)
Anatomy
| Element | Usage |
|---|---|
| Button | Required |
| Group | Required |
| Text | Optional |
| Separator | Optional |
ButtonGroupText displays text that isn’t a Button.
Use a separator between secondary Buttons, as they have no visible border and users can’t see where one Button ends.
Behavior
A Button Group changes the corners and the spacing of its children; each Button keeps its own variant, size, and action. The group itself has no state.
Orientation
To stack the children and join them from top to bottom, set orientation="vertical"; each child is then as wide as the widest one. If the group is vertical, set orientation="horizontal" on its separators.
Nested Groups
If a Button Group contains other Button Groups, it places them 8px apart and doesn’t join them.
Beside a Field
A Button Group can contain an Input, an Input Group, or a Select. An Input fills the width that remains next to the Buttons, and a Select stays as wide as its value.
Accessibility
A Button Group is a div with role="group". It adds no keys: users press Tab to move to each Button in turn, and the arrow keys do nothing.
To name a Button Group for screen readers, set aria-label, as “Invoice actions” does in the preview.
An icon-only Button in a group needs its own aria-label. See Button for the rule.
Installation
npx shadcn@latest add @summit/button-groupThe CLI also adds @summit/separator. It doesn’t add Button.
Usage
import { Button } from '@/components/ui/button';
import { ButtonGroup } from '@/components/ui/button-group';
<ButtonGroup aria-label="Invoice actions">
<Button variant="outline">Duplicate</Button>
<Button variant="outline">Download</Button>
<Button variant="outline">Archive</Button>
</ButtonGroup>;With a Separator
To separate Buttons that have no visible border, place a ButtonGroupSeparator between them.
import { ButtonGroup, ButtonGroupSeparator } from '@/components/ui/button-group';
<ButtonGroup aria-label="Clipboard">
<Button variant="secondary">Copy</Button>
<ButtonGroupSeparator />
<Button variant="secondary">Paste</Button>
</ButtonGroup>;With a Menu
To add a menu of further actions, pass the second Button to DropdownMenuTrigger through render. The trigger is joined to the group like any other Button.
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu';
import { CaretDownIcon } from '@phosphor-icons/react';
<ButtonGroup>
<Button variant="outline">Send invoice</Button>
<DropdownMenu>
<DropdownMenuTrigger render={<Button variant="outline" size="icon" aria-label="More actions" />}>
<CaretDownIcon />
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuItem>Send reminder</DropdownMenuItem>
<DropdownMenuItem>Mark as paid</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</ButtonGroup>;With an Input
import { Input } from '@/components/ui/input';
import { MagnifyingGlassIcon } from '@phosphor-icons/react';
<ButtonGroup>
<Input aria-label="Search invoices" placeholder="Search invoices" />
<Button variant="outline" size="icon" aria-label="Search">
<MagnifyingGlassIcon />
</Button>
</ButtonGroup>;API Reference
ButtonGroup and ButtonGroupText accept the props of a div, and ButtonGroupSeparator accepts the props of the Separator that it renders. ButtonGroupText also accepts render, which replaces the div with another element. See the Base UI useRender documentation for render.
ButtonGroup
| Prop | Type | Default | Description |
|---|---|---|---|
orientation | 'horizontal' | 'vertical' | 'horizontal' | The axis along which the children are joined |
ButtonGroupSeparator
| Prop | Type | Default | Description |
|---|---|---|---|
orientation | 'horizontal' | 'vertical' | 'vertical' | The direction of the line. Set 'horizontal' in a vertical group. |