Button Group
Button Group arranges closely related controls into one horizontal or vertical unit. Connected borders make the relationship visible while each button keeps its own action.
Use a group for actions that operate on the same object or represent one compact tool set. Unrelated primary actions should remain separate.
Installation
pnpm dlx shadcn@latest add http://ui.argv-tech.dev/r/button-group.json
Usage
import {
ButtonGroup,
ButtonGroupButton
} from "@/components/ui/argv/button-group"
<ButtonGroup aria-label="Editor actions">
<ButtonGroupButton variant="outline">Save</ButtonGroupButton>
<ButtonGroupButton>Publish</ButtonGroupButton>
</ButtonGroup>
Composition
ButtonGroup
├── ButtonGroupText (optional)
├── ButtonGroupButton
├── ButtonGroupSeparator (optional)
└── ButtonGroupButton
Set orientation="horizontal" for a row or orientation="vertical" for a stack. The root renders role="group" and forwards native div props.
ButtonGroupButton renders the argv Button directly and forwards its variants, sizes, render prop, refs, events, and accessibility attributes. Use it for the standard group API; an existing Button may still be used directly as a child.
Use ButtonGroupText for a short readout or label that belongs inside the connected surface. Use ButtonGroupSeparator only when a visible boundary helps distinguish subsets of controls.
Match the separator to the boundary: vertical separators belong in horizontal groups, while horizontal separators belong in vertical groups.
Interaction states
Grouped buttons remove the leading rails and triangular corner cuts that disrupt the connected silhouette. They keep the Button's small signature details: clipped scan passes, telemetry ticks, and fine corner marks.
Hover affects only the actionable segment under the pointer while the group keeps one shared outer shadow. The active segment stays stationary and uses a two-pixel foreground inset ring for contained press feedback.
The interaction stack is deterministic: children rise in DOM order, while hover, active, and focus occupy successively higher layer bands. This prevents a separator or neighboring segment from cutting through the current effect.
Keyboard focus uses a high-contrast neutral inset ring, so it remains visible on outline, filled, and destructive buttons without changing the group's footprint. Invalid focus uses the destructive color. Disabled segments remain fully opaque, switch to the muted gray palette, and do not trigger hover or active feedback.
API Reference
ButtonGroup
| Prop | Type | Default |
|---|---|---|
orientation | "horizontal" | "vertical" | "horizontal" |
className | string | - |
ButtonGroupText
| Prop | Type | Default |
|---|---|---|
render | ReactElement | function | div |
className | string | - |
ButtonGroupButton
ButtonGroupButton accepts the same props as Button, including variant, size, render, and disabled.
ButtonGroupSeparator
| Prop | Type | Default |
|---|---|---|
orientation | "horizontal" | "vertical" | "vertical" |
className | string | - |
Accessibility
Give every group an accessible name with aria-label or aria-labelledby. The label should describe what the controls affect, such as “Release actions.”
Each button still needs a clear individual name. Grouping controls does not replace the accessible label of an icon-only button.