Button Group
Joins related buttons, inputs and labels into one control with shared borders.
@zenoxai/ui/components/button-group Markdown<ButtonGroup aria-label="Alert actions">
<Button variant="outline">Acknowledge</Button>
<Button variant="outline">Assign</Button>
<Button variant="outline">Resolve</Button>
</ButtonGroup>Usage
import { Button } from "@zenoxai/ui/components/button"
import { ButtonGroup } from "@zenoxai/ui/components/button-group"
export function AlertActions() {
return (
<ButtonGroup aria-label="Alert actions">
<Button variant="outline">Acknowledge</Button>
<Button variant="outline">Assign</Button>
<Button variant="outline">Resolve</Button>
</ButtonGroup>
)
}
Use a button group for actions that act on the same object and belong together, such as the actions on an alert, or to attach a button to an input. The group only changes layout: it squares the inner corners and merges the borders of its direct children.
Use something else when:
- The buttons hold a selection state (a layout switch, a time range): use a Toggle Group.
- There are more than three or four actions: keep the main one visible and move the rest into a Dropdown Menu.
Use the same variant and size for every button in a group. Mixed heights break the shared
borders.
Examples
Nested
A ButtonGroup inside another adds an 8px gap between the inner groups. Use it for toolbars
made of several clusters, like pagination.
<ButtonGroup aria-label="Pagination">
<ButtonGroup>
<Button variant="outline" size="icon" aria-label="Previous page">
<ChevronLeftIcon />
</Button>
<Button variant="outline" size="icon" aria-label="Next page">
<ChevronRightIcon />
</Button>
</ButtonGroup>
<ButtonGroup>
<Button variant="outline">1</Button>
<Button variant="outline">2</Button>
<Button variant="outline">3</Button>
</ButtonGroup>
</ButtonGroup>Split button
A main action with a menu of variations next to it. ButtonGroupSeparator draws the divider
between two filled buttons, which have no border of their own.
<ButtonGroup>
<Button>Export report</Button>
<ButtonGroupSeparator />
<DropdownMenu>
<DropdownMenuTrigger
render={<Button size="icon" aria-label="More export formats" />}
>
<ChevronDownIcon />
</DropdownMenuTrigger>
<DropdownMenuContent align="end" className="w-40">
<DropdownMenuItem>Export as PDF</DropdownMenuItem>
<DropdownMenuItem>Export as CSV</DropdownMenuItem>
<DropdownMenuItem>Export as JSON</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</ButtonGroup>With an input
An Input inside the group stretches to fill the row. ButtonGroupText renders a static
prefix or suffix, such as a protocol or a unit, with the same borders.
<div className="flex w-full max-w-sm flex-col gap-3">
<ButtonGroup className="w-full">
<Input aria-label="Search domains" placeholder="Search domains" />
<Button variant="outline" size="icon" aria-label="Search">
<SearchIcon />
</Button>
</ButtonGroup>
<ButtonGroup className="w-full">
<ButtonGroupText>https://</ButtonGroupText>
<Input aria-label="Domain" placeholder="login.acme-corp.com" />
</ButtonGroup>
</div>Vertical
orientation="vertical" stacks the children and merges their top and bottom borders, for
compact controls such as map zoom.
<ButtonGroup orientation="vertical" aria-label="Map zoom">
<Button variant="outline" size="icon" aria-label="Zoom in">
<PlusIcon />
</Button>
<Button variant="outline" size="icon" aria-label="Zoom out">
<MinusIcon />
</Button>
</ButtonGroup>Accessibility
ButtonGrouprendersrole="group". Give it anaria-labelwhen the purpose is not clear from the buttons alone (“Alert actions”, “Pagination”).- Every button keeps its own tab stop; the group adds no arrow-key navigation. For a single tab stop with arrow keys, use a Toggle Group.
- Icon-only buttons need an
aria-label.ButtonGroupTextis plain text: an input next to it still needs its own label.
API reference
Generated from the TypeScript source. className, style and children are accepted everywhere and omitted below.
ButtonGroup
ButtonGroup joins related buttons, inputs and selects into one bar with shared borders, such as a split button or a field with its submit button. For a set of toggles where one or several are on, use ToggleGroup.
| Prop | Type | Default |
|---|---|---|
orientation | "horizontal" | "vertical" | null`horizontal` (default) joins the items side by side; `vertical` stacks them. | horizontal |
ButtonGroupSeparator
ButtonGroupSeparator draws a divider between two items whose joined edges would not show one, such as two borderless secondary buttons.
| Prop | Type | Default |
|---|---|---|
orientation | "horizontal" | "vertical"The orientation of the separator. | vertical |
render | ReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, SeparatorState>Allows you to replace the component's HTML element with a different tag, or compose it with another component. | - |
ButtonGroupText
ButtonGroupText is a static segment of the bar, such as a label or a unit, styled to match the buttons beside it.
| Prop | Type | Default |
|---|---|---|
render | ReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, {}>Allows you to replace the component's HTML element with a different tag, or compose it with another component. | - |