Components
A container that groups related buttons together with consistent styling.
Playground
role="group". Use it for buttons that perform actions — for buttons that toggle state, reach for Toggle Group instead.import {
ButtonGroup,
ButtonGroupSeparator,
ButtonGroupText,
} from "@workspace/ui/components/button-group"
<ButtonGroup aria-label="Text alignment">
<Button variant="outline">Left</Button>
<Button variant="outline">Center</Button>
<Button variant="outline">Right</Button>
</ButtonGroup>orientation prop stacks the group vertically — corners and borders collapse along the block axis instead.<ButtonGroup orientation="vertical" aria-label="Zoom controls">
<Button variant="outline" size="icon" aria-label="Zoom in">
<PlusIcon />
</Button>
<Button variant="outline" size="icon" aria-label="Zoom out">
<MinusIcon />
</Button>
</ButtonGroup><ButtonGroup>
<Button variant="outline" size="sm">Small</Button>
<Button variant="outline" size="icon-sm" aria-label="Add">
<PlusIcon />
</Button>
</ButtonGroup>
<ButtonGroup>
<Button variant="outline">Default</Button>
<Button variant="outline" size="icon" aria-label="Add">
<PlusIcon />
</Button>
</ButtonGroup>
<ButtonGroup>
<Button variant="outline" size="lg">Large</Button>
<Button variant="outline" size="icon-lg" aria-label="Add">
<PlusIcon />
</Button>
</ButtonGroup>gap-2 between its child groups while each inner group keeps its fused corners.<ButtonGroup>
<ButtonGroup>
<Button variant="outline" size="icon" aria-label="Previous">
<ArrowLeftIcon />
</Button>
<Button variant="outline" size="icon" aria-label="Next">
<ArrowRightIcon />
</Button>
</ButtonGroup>
<ButtonGroup>
<Button variant="outline">Archive</Button>
<Button variant="outline">Report</Button>
</ButtonGroup>
</ButtonGroup>bg-input that stretches to the group's height.<ButtonGroup> <Button variant="secondary" size="sm">Copy</Button> <ButtonGroupSeparator /> <Button variant="secondary" size="sm">Paste</Button> </ButtonGroup>
<ButtonGroup>
<Button variant="secondary">Update branch</Button>
<ButtonGroupSeparator />
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="secondary" size="icon" aria-label="More options">
<CaretDownIcon />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuItem>Update with merge commit</DropdownMenuItem>
<DropdownMenuItem>Update with rebase</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</ButtonGroup>asChild to render it as a Label tied to an input in the group.<ButtonGroup>
<ButtonGroupText asChild>
<Label htmlFor="site-url">https://</Label>
</ButtonGroupText>
<Input id="site-url" placeholder="example.com" />
<Button variant="outline">Visit</Button>
</ButtonGroup><ButtonGroup className="w-full max-w-sm">
<Input placeholder="Search..." />
<Button variant="outline" size="icon" aria-label="Search">
<MagnifyingGlassIcon />
</Button>
</ButtonGroup>--radius on the outer group is all it takes to make the whole row pill-shaped.<ButtonGroup className="w-full max-w-sm [--radius:9999rem]">
<ButtonGroup>
<Button variant="outline" size="icon" aria-label="Attach">
<PlusIcon />
</Button>
</ButtonGroup>
<ButtonGroup>
<InputGroup>
<InputGroupInput placeholder="Send a message..." />
<InputGroupAddon align="inline-end">
<InputGroupButton size="icon-xs" aria-label="Voice mode">
<MicrophoneIcon />
</InputGroupButton>
</InputGroupAddon>
</InputGroup>
</ButtonGroup>
</ButtonGroup><ButtonGroup>
<ButtonGroup>
<Select defaultValue="USD">
<SelectTrigger className="font-mono">
<SelectValue />
</SelectTrigger>
<SelectContent className="min-w-24">
<SelectItem value="USD">USD</SelectItem>
<SelectItem value="EUR">EUR</SelectItem>
<SelectItem value="GBP">GBP</SelectItem>
</SelectContent>
</Select>
<Input placeholder="10.00" pattern="[0-9]*" />
</ButtonGroup>
<ButtonGroup>
<Button variant="outline" size="icon" aria-label="Send">
<ArrowRightIcon />
</Button>
</ButtonGroup>
</ButtonGroup><ButtonGroup>
<Button variant="outline">Follow</Button>
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="outline" size="icon" aria-label="More options">
<CaretDownIcon />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end" className="w-52">
<DropdownMenuGroup>
<DropdownMenuItem>
<SpeakerSlashIcon />
Mute Conversation
</DropdownMenuItem>
<DropdownMenuItem>
<CheckIcon />
Mark as Read
</DropdownMenuItem>
<DropdownMenuItem>
<WarningIcon />
Report Conversation
</DropdownMenuItem>
<DropdownMenuItem>
<UserMinusIcon />
Block User
</DropdownMenuItem>
</DropdownMenuGroup>
<DropdownMenuSeparator />
<DropdownMenuItem variant="destructive">
<TrashIcon />
Delete Conversation
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</ButtonGroup><ButtonGroup>
<Button variant="outline">
<RobotIcon data-icon="inline-start" />
Copilot
</Button>
<Popover>
<PopoverTrigger asChild>
<Button variant="outline" size="icon" aria-label="Open Popover">
<CaretDownIcon />
</Button>
</PopoverTrigger>
<PopoverContent align="end" className="text-sm">
<PopoverHeader>
<PopoverTitle>Start a new task with Copilot</PopoverTitle>
<PopoverDescription>
Describe your task in natural language.
</PopoverDescription>
</PopoverHeader>
<Field>
<FieldLabel htmlFor="task" className="sr-only">
Task Description
</FieldLabel>
<Textarea id="task" placeholder="I need to..." className="resize-none" />
<FieldDescription>
Copilot will open a pull request for review.
</FieldDescription>
</Field>
</PopoverContent>
</Popover>
</ButtonGroup>role="group" and Tab moves between the buttons inside it. Name the group with aria-label (or aria-labelledby) so screen readers announce what the actions have in common.<ButtonGroup aria-label="Clipboard actions"> <Button variant="outline">Copy</Button> <Button variant="outline">Paste</Button> </ButtonGroup>
data-slot="button-group" from a parent to restyle.| Component | Prop | Default |
|---|---|---|
| ButtonGroup | orientation?: "horizontal" | "vertical" | "horizontal" |
| ButtonGroupSeparator | orientation?: "horizontal" | "vertical" | "vertical" |
| ButtonGroupText | asChild?: boolean | false |
<ButtonGroup data-slot="button-group" role="group" /> <ButtonGroupSeparator data-slot="button-group-separator" />
Tokens used
5 design tokens consumed by the Button Group component.
--muted
Muted
--input
Input
--border
Border
--radius-md
Radius 0.8× (8px)
--spacing
Spacing unit (4px)