---
type: doc
title: Button Group
description: Groups related controls with connected edges and consistent focus behavior.
---

```astro live props={{ name: 'button-group' }}
---
import ArchiveIcon from "@lucide/astro/icons/archive"
import MailIcon from "@lucide/astro/icons/mail"
import TrashIcon from "@lucide/astro/icons/trash"

import { Button } from "@/components/ui/button"
import { ButtonGroup } from "@/components/ui/button-group"
---

<ButtonGroup aria-label="Message actions">
  <Button variant="outline">
    <ArchiveIcon /> Archive
  </Button>
  <Button variant="outline">
    <MailIcon /> Mark unread
  </Button>
  <Button variant="outline" size="icon" aria-label="Delete">
    <TrashIcon />
  </Button>
</ButtonGroup>
```

## Installation

```bash
npx shadcn@latest add @fulldev/button-group
```

## Usage

```astro
---
import { Button } from "@/components/ui/button"
import { ButtonGroup } from "@/components/ui/button-group"
---

<ButtonGroup aria-label="Document actions">
  <Button variant="outline">Save</Button>
  <Button variant="outline">Publish</Button>
</ButtonGroup>
```

Give each group an accessible name with `aria-label` or `aria-labelledby`.

## Examples

### Sizes

Button sizes continue to work inside a group.

```astro live
---
import { Button } from "@/components/ui/button"
import { ButtonGroup } from "@/components/ui/button-group"
---

<div class="flex flex-col items-start gap-4">
  <ButtonGroup aria-label="Small view controls">
    <Button variant="outline" size="sm">
      List
    </Button>
    <Button variant="outline" size="sm">
      Grid
    </Button>
  </ButtonGroup>
  <ButtonGroup aria-label="Default view controls">
    <Button variant="outline">List</Button>
    <Button variant="outline">Grid</Button>
  </ButtonGroup>
</div>
```

### Vertical

```astro live
---
import CopyIcon from "@lucide/astro/icons/copy"
import SearchIcon from "@lucide/astro/icons/search"
import SettingsIcon from "@lucide/astro/icons/settings"

import { Button } from "@/components/ui/button"
import { ButtonGroup } from "@/components/ui/button-group"
---

<ButtonGroup orientation="vertical" aria-label="Document tools">
  <Button variant="outline" size="icon" aria-label="Search">
    <SearchIcon />
  </Button>
  <Button variant="outline" size="icon" aria-label="Copy">
    <CopyIcon />
  </Button>
  <Button variant="outline" size="icon" aria-label="Settings">
    <SettingsIcon />
  </Button>
</ButtonGroup>
```

### With Text

`ButtonGroupText` is polymorphic. Render it as a label when it describes a form control.

```astro live
---
import { ButtonGroup, ButtonGroupText } from "@/components/ui/button-group"
import { Input } from "@/components/ui/input"
---

<ButtonGroup class="w-full max-w-sm" aria-label="Repository owner">
  <ButtonGroupText as="label" for="repository-name">
    full.dev/
  </ButtonGroupText>
  <Input id="repository-name" value="ui" aria-label="Repository name" />
</ButtonGroup>
```

### Nested Groups

Nested groups keep a gap between related sets while preserving connected controls inside each set.

```astro live
---
import ChevronLeftIcon from "@lucide/astro/icons/chevron-left"
import ChevronRightIcon from "@lucide/astro/icons/chevron-right"

import { Button } from "@/components/ui/button"
import { ButtonGroup } from "@/components/ui/button-group"
---

<ButtonGroup aria-label="Pagination controls">
  <ButtonGroup aria-label="Pages">
    <Button as="a" href="?page=1" variant="outline">
      1
    </Button>
    <Button as="a" href="?page=2" variant="outline">
      2
    </Button>
    <Button as="a" href="?page=3" variant="outline">
      3
    </Button>
  </ButtonGroup>
  <ButtonGroup aria-label="Previous and next page">
    <Button
      as="a"
      href="?page=1"
      variant="outline"
      size="icon-xs"
      aria-label="Previous page"
    >
      <ChevronLeftIcon />
    </Button>
    <Button
      as="a"
      href="?page=3"
      variant="outline"
      size="icon-xs"
      aria-label="Next page"
    >
      <ChevronRightIcon />
    </Button>
  </ButtonGroup>
</ButtonGroup>
```

## API Reference

### ButtonGroup

| Prop          | Type                         | Default        | Description                              |
| ------------- | ---------------------------- | -------------- | ---------------------------------------- |
| `orientation` | `"horizontal" \| "vertical"` | `"horizontal"` | Controls the layout and connected edges. |
| `as`          | `HTMLTag`                    | `"div"`        | Changes the rendered element.            |

### ButtonGroupText

Accepts `as` and the attributes for that HTML element.

### ButtonGroupSeparator

Uses the Separator API. Its `orientation` defaults to `"vertical"`.

See the [GitHub source code](https://github.com/fulldotdev/ui/tree/main/src/components/ui/button-group) for the component source.
