Button Group
A container that groups related buttons together with consistent styling.
Made by shadcnPowered by
Installation
When 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 container that visually connects related buttons. Here's how the components work together:
<ButtonGroup> {/* Container with role="group" */}
<Button> {/* Individual button */}
<ButtonGroupSeparator /> {/* Optional visual divider */}
<Button> {/* Another button */}
</ButtonGroup>Layout Structure
- ButtonGroup: Root container with
role="group"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 asChild>
<Button size="icon"><ChevronDown /></Button>
</DropdownMenuTrigger>
<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.
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.
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
InputGroup
The main component that wraps inputs and addons.
| Prop | Type | Default |
|---|---|---|
className | string |
<InputGroup>
<InputGroupInput />
<InputGroupAddon />
</InputGroup>InputGroupAddon
Displays icons, text, buttons, or other content alongside inputs.
For proper focus navigation, the InputGroupAddon component should be placed
after the input. Set the align prop to position the addon.
| Prop | Type | Default |
|---|---|---|
align | "inline-start" | "inline-end" | "block-start" | "block-end" | "inline-start" |
className | string |
<InputGroupAddon align="inline-end">
<SearchIcon />
</InputGroupAddon>For <InputGroupInput />, use the inline-start or inline-end alignment. For <InputGroupTextarea />, use the block-start or block-end alignment.
The InputGroupAddon component can have multiple InputGroupButton components and icons.
<InputGroupAddon>
<InputGroupButton>Button</InputGroupButton>
<InputGroupButton>Button</InputGroupButton>
</InputGroupAddon>InputGroupButton
Displays buttons within input groups.
| Prop | Type | Default |
|---|---|---|
size | "xs" | "icon-xs" | "sm" | "icon-sm" | "xs" |
variant | "default" | "destructive" | "outline" | "secondary" | "ghost" | "link" | "ghost" |
className | string |
<InputGroupButton>Button</InputGroupButton>
<InputGroupButton size="icon-xs" aria-label="Copy">
<CopyIcon />
</InputGroupButton>InputGroupInput
Replacement for <Input /> when building input groups. This component has the input group styles pre-applied and uses the unified data-slot="button-group-control" for focus state handling.
| Prop | Type | Default |
|---|---|---|
className | string |
All other props are passed through to the underlying <Input /> component.
<InputGroup>
<InputGroupInput placeholder="Enter text..." />
<InputGroupAddon>
<SearchIcon />
</InputGroupAddon>
</InputGroup>InputGroupTextarea
Replacement for <Textarea /> when building input groups. This component has the textarea group styles pre-applied and uses the unified data-slot="button-group-control" for focus state handling.
| Prop | Type | Default |
|---|---|---|
className | string |
All other props are passed through to the underlying <Textarea /> component.
<InputGroup>
<InputGroupTextarea placeholder="Enter message..." />
<InputGroupAddon align="block-end">
<InputGroupButton>Send</InputGroupButton>
</InputGroupAddon>
</InputGroup>Props
Credits
- We take our inspiration from Shadcn UI for the
button-groupcomponent and style.
Built by malinskibeniamin. The source code is available on GitHub.