ButtonGroup
Layout wrapper to group and align related action buttons.
The ButtonGroup primitive allows you to group multiple adjacent buttons into a single horizontal or vertical unit, automatically handling border merging and corner radius clipping.
It's a thin layout primitive — there's no aria, no focus-management, no state. It exists purely to make a row of buttons look like a single attached segmented control. Everything else (keyboard navigation, focus rings, disabled propagation) is handled by Button underneath.
Reach for it when you have visually related buttons: a tab filter, an alignment toggler, a segmented yes/no/maybe picker. Don't reach for it when buttons are independent — just use a flex container.
Import
import { ButtonGroup } from 'boltdocs/primitives'
Quick Start
Group buttons together horizontally:
import { Button, ButtonGroup } from 'boltdocs/primitives'
export default function FilterGroup() {
return (
<ButtonGroup className="rounded-lg border border-subtle overflow-hidden">
<Button className="px-4 py-2 bg-surface hover:bg-soft text-body border-r border-subtle">
Tab 1
</Button>
<Button className="px-4 py-2 bg-surface hover:bg-soft text-body border-r border-subtle">
Tab 2
</Button>
<Button className="px-4 py-2 bg-surface hover:bg-soft text-body">
Tab 3
</Button>
</ButtonGroup>
)
}
Layout Configurations
Horizontal Alignment (Default)
By default, <ButtonGroup> aligns button children in a row. It strips internal adjacent border margins and applies left and right border radii properly to the outer edges.
Vertical Alignment
Set vertical to true to stack the button children in a vertical column structure.
<ButtonGroup vertical className="rounded-md">
<Button className="px-4 py-2 border-b border-subtle">Stack Top</Button>
<Button className="px-4 py-2 border-b border-subtle">Stack Middle</Button>
<Button className="px-4 py-2">Stack Bottom</Button>
</ButtonGroup>
Component Props
The ButtonGroup component accepts these layout configuration properties:
| Property | Type | Default | Description |
|---|---|---|---|
vertical | boolean | false | Stacks the buttons vertically if set to true. Otherwise, arranges them in a horizontal flex row. |
children | ReactNode | Required | The buttons or interactive list nodes to group. |
className | string | undefined | Custom CSS utility class overrides. |
style | CSSProperties | undefined | Inline styling overrides. |
Common pitfalls
- Use
flexborder colors, not arbitrary CSS. Addingborderto each child anddivide-xon the parent is much cleaner than manually clipping radius withfirst:rounded-l-* / last:rounded-r-*. - Don't put non-buttons inside. Layout primitives in Boltdocs prefer specialized children (
Button,Link,Tab.Item) over generic divs. A grouped layout with non-semantic content should be a regular flex container. - Vertical orientation doesn't auto-rotate icons. If you want the segmented control's icon to rotate (e.g. for a vertical splitter), the parent layout is responsible for that.