Button Group
A container that groups related buttons together with consistent styling.
Powered by
Installation
npx shadcn@latest add @redpanda/button-grouppnpm dlx shadcn@latest add @redpanda/button-groupyarn dlx shadcn@latest add @redpanda/button-groupbunx shadcn@latest add @redpanda/button-groupnubx shadcn@latest add @redpanda/button-groupaube dlx shadcn@latest add @redpanda/button-groupWhen to use
Use this decision tree to determine when to use the Button Group component:
Usage
import { ButtonGroup, ButtonGroupSeparator, ButtonGroupText } from '@/components/ui/button-group';<ButtonGroup> <Button>Button 1</Button> <Button>Button 2</Button></ButtonGroup>Anatomy
The ButtonGroup component provides a native fieldset that visually connects related buttons. Its ref points to HTMLFieldSetElement; disabled uses native fieldset behavior to disable its controls. Give a named action group an aria-label or aria-labelledby. Here’s how the components work together:
<ButtonGroup> {/* Native fieldset grouping related controls */} <Button> {/* Individual button */} <ButtonGroupSeparator /> {/* Optional visual divider */} <Button> {/* Another button */}</ButtonGroup>Layout Structure
- ButtonGroup: Native fieldset container with implicit group semantics that applies border radius to first/last children and removes borders between adjacent buttons
- Button: Standard button components that adapt their borders when inside a ButtonGroup
- ButtonGroupSeparator: Vertical divider for visual separation between buttons (not needed with
outlinevariant) - ButtonGroupText: Text content that can be displayed alongside buttons
Orientation
Button groups support two orientations via the orientation prop:
- horizontal (default): Buttons arranged in a row
- vertical: Buttons arranged in a column
Typical Usage Patterns
// Simple horizontal group<ButtonGroup> <Button>Save</Button> <Button>Cancel</Button></ButtonGroup>
// Vertical group with separators<ButtonGroup orientation="vertical"> <Button>Edit</Button> <ButtonGroupSeparator /> <Button>Delete</Button></ButtonGroup>
// Split button with dropdown<ButtonGroup> <Button>Save</Button> <ButtonGroupSeparator /> <DropdownMenu> <DropdownMenuTrigger render={<Button size="icon"><ChevronDown /></Button>} /> <DropdownMenuContent>{/* ... */}</DropdownMenuContent> </DropdownMenu></ButtonGroup>
// Combined with inputs<ButtonGroup> <Button>-</Button> <Input className="w-20" /> <Button>+</Button></ButtonGroup>Accessibility
- The
ButtonGroupcomponent has theroleattribute set togroup. - Use
Tabto navigate between the buttons in the group. - Use
aria-labeloraria-labelledbyto label the button group.
<ButtonGroup aria-label="Button group"> <Button>Button 1</Button> <Button>Button 2</Button></ButtonGroup>ButtonGroup vs ToggleGroup
- Use the
ButtonGroupcomponent when you want to group buttons that perform an action. - Use the
ToggleGroupcomponent when you want to group buttons that toggle a state.
Examples
Orientation
Set the orientation prop to change the button group layout.
Size
Control the size of buttons using the size prop on individual buttons.
Nested
Nest <ButtonGroup> components to create button groups with spacing.
Separator
The ButtonGroupSeparator component visually divides buttons within a group.
It inherits the standard Separator variants: default, subtle, and strong. Choose the appropriate contrast with variant; the group does not override the divider’s theme paint.
Buttons with variant outline do not need a separator since they have a border. For other variants, a separator is recommended to improve the visual hierarchy.
Split
Create a split button group by adding two buttons separated by a ButtonGroupSeparator.
Input
Wrap an Input component with buttons.
Input Group
Wrap an InputGroup component to create complex input layouts.
For pill-shaped controls, set the existing shape="pill" prop on each Button, InputGroup, and InputGroupButton that needs it. Do not change a radius custom property on the whole group. The voice-mode example uses standard warning and ghost button variants, retains the text draft while voice mode disables the input, and does not record or send audio.
Dropdown Menu
Create a split button group with a DropdownMenu component.
Select
Pair with a Select component.
Popover
Use with a Popover component.
API Reference
ButtonGroup
The native fieldset that groups related buttons with implicit group semantics, applying border radius to the first/last children and removing borders between adjacent buttons.
| Prop | Type | Default |
|---|---|---|
orientation |
"horizontal" | "vertical" |
"horizontal" |
className |
string |
<ButtonGroup> <Button>Button 1</Button> <Button>Button 2</Button></ButtonGroup>ButtonGroupSeparator
A divider that visually separates buttons within a group. Buttons using the outline variant already have a border and do not need a separator.
| Prop | Type | Default |
|---|---|---|
orientation |
"horizontal" | "vertical" |
"vertical" |
variant |
"default" | "subtle" | "strong" |
"default" |
className |
string |
<ButtonGroup> <Button>Save</Button> <ButtonGroupSeparator variant="strong" /> <Button>Cancel</Button></ButtonGroup>ButtonGroupText
Renders text or label content alongside buttons within a group. Supports the Base UI render prop to render as a custom element such as a <label>.
| Prop | Type | Default |
|---|---|---|
render |
ReactNode |
|
className |
string |
<ButtonGroup> <ButtonGroupText render={<label htmlFor="email" />}>Email</ButtonGroupText> <Input id="email" /></ButtonGroup>Props
Credits
- We take our inspiration from Shadcn UI for the
button-groupcomponent and style.