ButtonGroup
button-groupJoins related buttons into a segmented horizontal or vertical control.
Usage
Continuous row icon group
Default attached: The sub-buttons are integrated into one, the inner corners are smoothed, and the borders are merged. Subitem variant recommends the same.
<ButtonGroup aria-label="Alignment">
<Button variant="outline" size="icon" aria-label="Left aligned"><AlignLeft className="size-4" /></Button>
<Button variant="outline" size="icon" aria-label="center"><AlignCenter className="size-4" /></Button>
<Button variant="outline" size="icon" aria-label="right aligned"><AlignRight className="size-4" /></Button>
</ButtonGroup>Icon + text segmentation
Toolbar-style segmented operation, with copywriting for each segment icon.
<ButtonGroup aria-label="Text Format">
<Button variant="outline"><Bold className="size-4" />Bold</Button>
<Button variant="outline"><Italic className="size-4" />italic</Button>
<Button variant="outline"><Underline className="size-4" />underscore</Button>
</ButtonGroup>Split button
Main operation + a drop-down triggered "More", commonly seen in save/submit scenarios.
<ButtonGroup aria-label="Save">
<Button>Save</Button>
<Button size="icon" aria-label="More saving options"><ChevronDown className="size-4" /></Button>
</ButtonGroup>Vertically arranged
orientation="vertical" Change to upper and lower rows, smooth the upper and lower inner fillets.
<ButtonGroup orientation="vertical" aria-label="Tools">
<Button variant="outline">Copy</Button>
<Button variant="outline">Paste</Button>
<Button variant="outline">Delete</Button>
</ButtonGroup>Separate grouping
When attached={false}, gap is left between the sub-buttons, which is only used for semantic/alignment grouping and does not fit.
<ButtonGroup attached={false} aria-label="Operation">
<Button variant="outline">Cancel</Button>
<Button>OK</Button>
</ButtonGroup>When to use
Use ButtonGroup for related Buttons, such as toolbar segments, a split button with a primary action and menu, or a decrement/value/increment stepper. The default attached mode joins adjacent controls; pass attached={false} to preserve spacing while keeping the semantic group. ButtonGroup only provides layout and does not override each child's variant or size. Use Button directly for a standalone action.
Import
import { ButtonGroup } from "@hulianui/ui"Props
| Name | Type | Default | Description |
|---|---|---|---|
| orientation | "horizontal" | "vertical" | "horizontal" | Layout direction. |
| attached | boolean | true | Joins child controls by removing inner radii and merging adjacent borders. Pass false to keep the configured gap. |
| gap | "sm" | "md" | "sm" | Gap between children when attached={false}. |
| className | string | — | Additional class name for the root element. |
| aria-label | string | — | Accessible label for the group. |
Slots
| Slot | Type | Description |
|---|---|---|
| children | ReactNode | Usually <Button> elements; trigger buttons wrapped by Dropdown or Tooltip are also supported. |
Usage guidelines
gap only applies when attached={false}. In attached mode, the component joins corners and borders without adding margins between child controls.
Related
Button · ShimmerButton · RainbowButton · PulsatingButton · RippleButton · SocialButton
Playground
<ButtonGroup>
<Button variant="outline">one</Button>
<Button variant="outline">two</Button>
<Button variant="outline">three</Button>
</ButtonGroup>