---
title: Button Group
description: A container that groups related buttons together with consistent styling.
icon: component
author:
  name: shadcn
  url: https://github.com/shadcn
mode: wide
---

<PoweredBy packages={[{ name: 'Shadcn UI', url: 'https://ui.shadcn.com/docs/components/button-group' }]} />

### Installation

```package-install
npx shadcn@latest add @redpanda/button-group
```

<ComponentPreview name="button-group-demo" />

## When to use

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

```mermaid
graph TD;
    A[❓ Need to group buttons?] -->|Yes| B{Related actions?};
    A -->|No| C[ℹ️ Use individual buttons];
    B -->|Yes| D{Toggle states?};
    B -->|No| E{Perform actions?};
    D -->|Yes| F[ℹ️ Use ToggleGroup instead];
    D -->|No| E;
    E -->|Yes| G[✅ Use ButtonGroup];
    G --> H{Need visual separation?};
    H -->|Yes| I[✅ Add ButtonGroupSeparator];
    H -->|No| J[✅ Use outline variant];
    G --> K{Combine with inputs?};
    K -->|Yes| L[✅ Wrap with ButtonGroup];

    classDef recommended fill:#4ade80,stroke:#22c55e,stroke-width:2px,color:#000;
    classDef discouraged fill:#fbbf24,stroke:#f59e0b,stroke-width:2px,color:#000;
    classDef decision fill:#60a5fa,stroke:#3b82f6,stroke-width:2px,color:#fff;
    classDef neutral fill:#9ca3af,stroke:#6b7280,stroke-width:2px,color:#fff;

    class G,I,J,L recommended;
    class F discouraged;
    class A,B,D,E,H,K decision;
    class C neutral;
```

## 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 lineNumbers
<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.

<ComponentPreview name="button-group-orientation-demo" />

### Size

Control the size of buttons using the `size` prop on individual buttons.

<ComponentPreview name="button-group-size-demo" />

### Nested

Nest `<ButtonGroup>` components to create button groups with spacing.

<ComponentPreview name="button-group-nested-demo" />

### 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.

<ComponentPreview name="button-group-separator-demo" />

### Split

Create a split button group by adding two buttons separated by a `ButtonGroupSeparator`.

<ComponentPreview name="button-group-split-demo" />

### Input

Wrap an `Input` component with buttons.

<ComponentPreview name="button-group-input-demo" />

### 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.

<ComponentPreview name="button-group-input-group-demo" />

### Dropdown Menu

Create a split button group with a `DropdownMenu` component.

<ComponentPreview name="button-group-dropdown-menu-demo" />

### Select

Pair with a `Select` component.

<ComponentPreview name="button-group-select-demo" />

### Popover

Use with a `Popover` component.

<ComponentPreview name="button-group-popover-demo" />

## 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

<div className="flex flex-row gap-x-3">
  <ExternalLink href="https://ui.shadcn.com/docs/components/button-group" text="Docs" />
</div>

## Credits

- We take our inspiration from [Shadcn UI](https://ui.shadcn.com/docs/components/button-group) for the `button-group` component and style.
