Skip to content
Redpanda UI
Esc
↑↓navigate↵open⌘Jpreview
Made by shadcn
Edit on GitHub

Button Group

A container that groups related buttons together with consistent styling.

Powered by

Installation

bash
npx shadcn@latest add @redpanda/button-group
bash
pnpm dlx shadcn@latest add @redpanda/button-group
bash
yarn dlx shadcn@latest add @redpanda/button-group
bash
bunx shadcn@latest add @redpanda/button-group
bash
nubx shadcn@latest add @redpanda/button-group
bash
aube dlx shadcn@latest add @redpanda/button-group

When to use

Use this decision tree to determine when to use the Button Group component:

Usage

tsx
import { ButtonGroup, ButtonGroupSeparator, ButtonGroupText } from '@/components/ui/button-group';
tsx
<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:

tsx
<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 outline variant)
  • 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

tsx
// 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 ButtonGroup component has the role attribute set to group.
  • Use Tab to navigate between the buttons in the group.
  • Use aria-label or aria-labelledby to label the button group.
tsx
<ButtonGroup aria-label="Button group">  <Button>Button 1</Button>  <Button>Button 2</Button></ButtonGroup>

ButtonGroup vs ToggleGroup

  • Use the ButtonGroup component when you want to group buttons that perform an action.
  • Use the ToggleGroup component 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.

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
tsx
<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
tsx
<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
tsx
<ButtonGroup>  <ButtonGroupText render={<label htmlFor="email" />}>Email</ButtonGroupText>  <Input id="email" /></ButtonGroup>

Props

Credits

  • We take our inspiration from Shadcn UI for the button-group component and style.

Recent changes

  • patchv1.2.0Pin shipped dependency floors to the version we develop against. Registry items now declare ranges like `^5.1.9` (the actual installed version) instead of collapsing to `^5.0.0`, so consumers start on the known-tested baseline while caret semantics still allow any compatible release within the same major.#133
  • minorv1.1.0Theme docs refresh, readability pass on semantic foregrounds, and consumer-facing Base UI regression fixes.#121
  • minorv1.0.0Post-Base-UI polish. Public API unchanged.#116
  • majorv1.0.0Migrate every Radix-based primitive to `@base-ui/react@^1.4.0` (Base UI).#114
  • minorv0.3.0Add theme-provider component to the registry with documentation and tests. Includes playground type improvements (export RegistryItem, remove as-const boilerplate) and docs site dark mode border color fix.#109
See full history →

Last updated on

Was this page helpful?