# Button Group

<FrameworkCodeSwitcher>
  <div slot="astro">
```astro
---
import { Button } from "@/components/starwind/button";
import { ButtonGroup } from "@/components/starwind/button-group";
---

<ButtonGroup>
  <Button variant="outline">Left</Button>
  <Button variant="outline">Middle</Button>
  <Button variant="outline">Right</Button>
</ButtonGroup>
```
  </div>
  <div slot="react">
```tsx
import { Button } from "@/components/starwind/button";
import { ButtonGroup } from "@/components/starwind/button-group";

export function Example() {
  return (
    <ButtonGroup>
      <Button variant="outline">Left</Button>
      <Button variant="outline">Middle</Button>
      <Button variant="outline">Right</Button>
    </ButtonGroup>
  );
}
```
  </div>
  <div slot="vue">
```vue
<script setup lang="ts">
import { Button } from "@/components/starwind/button";
import { ButtonGroup } from "@/components/starwind/button-group";
</script>

<template>
  <ButtonGroup>
    <Button variant="outline">Left</Button>
    <Button variant="outline">Middle</Button>
    <Button variant="outline">Right</Button>
  </ButtonGroup>
</template>
```
  </div>
</FrameworkCodeSwitcher>

## Installation

```bash
npx starwind@latest add button-group --framework astro
```
</DocsTabsContent>
```bash
npx starwind@latest add button-group --framework react
```
</DocsTabsContent>
```bash
npx starwind@latest add button-group --framework vue
```
</DocsTabsContent>
</DocsTabs>

## Usage

<FrameworkCodeSwitcher>
  <div slot="astro">
```astro
---
import { Button } from "@/components/starwind/button";
import { ButtonGroup } from "@/components/starwind/button-group";
---

<ButtonGroup>
  <Button variant="outline">Left</Button>
  <Button variant="outline">Middle</Button>
  <Button variant="outline">Right</Button>
</ButtonGroup>
```
  </div>
  <div slot="react">
```tsx
import { Button } from "@/components/starwind/button";
import { ButtonGroup } from "@/components/starwind/button-group";

export function Example() {
  return (
    <ButtonGroup>
      <Button variant="outline">Left</Button>
      <Button variant="outline">Middle</Button>
      <Button variant="outline">Right</Button>
    </ButtonGroup>
  );
}
```
  </div>
  <div slot="vue">
```vue
<script setup lang="ts">
import { Button } from "@/components/starwind/button";
import { ButtonGroup } from "@/components/starwind/button-group";
</script>

<template>
  <ButtonGroup>
    <Button variant="outline">Left</Button>
    <Button variant="outline">Middle</Button>
    <Button variant="outline">Right</Button>
  </ButtonGroup>
</template>
```
  </div>
</FrameworkCodeSwitcher>

## Composition

Place buttons, inputs, text, or separators inside the group:

```text
ButtonGroup
├── Button or Input
├── ButtonGroupSeparator
└── ButtonGroupText
```

## Orientation

Set the `orientation` prop to change the button group layout.

<FrameworkCodeSwitcher>
  <div slot="astro">
```astro
---
import { Button } from "@/components/starwind/button";
import { ButtonGroup } from "@/components/starwind/button-group";
import IconPlus from "@tabler/icons/outline/plus.svg";
import IconMinus from "@tabler/icons/outline/minus.svg";
---

<ButtonGroup orientation="vertical" class="h-fit">
  <Button variant="outline" size="icon">
    <IconPlus />
  </Button>
  <Button variant="outline" size="icon">
    <IconMinus />
  </Button>
</ButtonGroup>
```
  </div>
  <div slot="react">
```tsx
import { Button } from "@/components/starwind/button";
import { ButtonGroup } from "@/components/starwind/button-group";
import { IconPlus as IconPlus } from "@tabler/icons-react";
import { IconMinus as IconMinus } from "@tabler/icons-react";

export function Example() {
  return (
    <>
      <ButtonGroup orientation="vertical" className="h-fit">
        <Button variant="outline" size="icon">
          <IconPlus />
        </Button>
        <Button variant="outline" size="icon">
          <IconMinus />
        </Button>
      </ButtonGroup>
    </>
  );
}
```
  </div>
  <div slot="vue">
```vue
<script setup lang="ts">
import { Button } from "@/components/starwind/button";
import { ButtonGroup } from "@/components/starwind/button-group";
import { IconPlus as IconPlus } from "@tabler/icons-vue";
import { IconMinus as IconMinus } from "@tabler/icons-vue";
</script>

<template>
  <ButtonGroup orientation="vertical" class="h-fit">
    <Button variant="outline" size="icon">
      <IconPlus />
    </Button>
    <Button variant="outline" size="icon">
      <IconMinus />
    </Button>
  </ButtonGroup>
</template>
```
  </div>
</FrameworkCodeSwitcher>

## Size

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

<FrameworkCodeSwitcher>
  <div slot="astro">
```astro
---
import { Button } from "@/components/starwind/button";
import { ButtonGroup } from "@/components/starwind/button-group";
import IconPlus from "@tabler/icons/outline/plus.svg";
---

<div class="flex flex-col items-start gap-8">
  <ButtonGroup>
    <Button variant="outline" size="sm">Small</Button>
    <Button variant="outline" size="sm">Button</Button>
    <Button variant="outline" size="sm">Group</Button>
    <Button variant="outline" size="icon-sm">
      <IconPlus />
    </Button>
  </ButtonGroup>
  <ButtonGroup>
    <Button variant="outline">Default</Button>
    <Button variant="outline">Button</Button>
    <Button variant="outline">Group</Button>
    <Button variant="outline" size="icon">
      <IconPlus />
    </Button>
  </ButtonGroup>
  <ButtonGroup>
    <Button variant="outline" size="lg">Large</Button>
    <Button variant="outline" size="lg">Button</Button>
    <Button variant="outline" size="lg">Group</Button>
    <Button variant="outline" size="icon-lg">
      <IconPlus />
    </Button>
  </ButtonGroup>
</div>
```
  </div>
  <div slot="react">
```tsx
import { Button } from "@/components/starwind/button";
import { ButtonGroup } from "@/components/starwind/button-group";
import { IconPlus as IconPlus } from "@tabler/icons-react";

export function Example() {
  return (
    <>
      <div className="flex flex-col items-start gap-8">
        <ButtonGroup>
          <Button variant="outline" size="sm">Small</Button>
          <Button variant="outline" size="sm">Button</Button>
          <Button variant="outline" size="sm">Group</Button>
          <Button variant="outline" size="icon-sm">
            <IconPlus />
          </Button>
        </ButtonGroup>
        <ButtonGroup>
          <Button variant="outline">Default</Button>
          <Button variant="outline">Button</Button>
          <Button variant="outline">Group</Button>
          <Button variant="outline" size="icon">
            <IconPlus />
          </Button>
        </ButtonGroup>
        <ButtonGroup>
          <Button variant="outline" size="lg">Large</Button>
          <Button variant="outline" size="lg">Button</Button>
          <Button variant="outline" size="lg">Group</Button>
          <Button variant="outline" size="icon-lg">
            <IconPlus />
          </Button>
        </ButtonGroup>
      </div>
    </>
  );
}
```
  </div>
  <div slot="vue">
```vue
<script setup lang="ts">
import { Button } from "@/components/starwind/button";
import { ButtonGroup } from "@/components/starwind/button-group";
import { IconPlus as IconPlus } from "@tabler/icons-vue";
</script>

<template>
  <div class="flex flex-col items-start gap-8">
    <ButtonGroup>
      <Button variant="outline" size="sm">Small</Button>
      <Button variant="outline" size="sm">Button</Button>
      <Button variant="outline" size="sm">Group</Button>
      <Button variant="outline" size="icon-sm">
        <IconPlus />
      </Button>
    </ButtonGroup>
    <ButtonGroup>
      <Button variant="outline">Default</Button>
      <Button variant="outline">Button</Button>
      <Button variant="outline">Group</Button>
      <Button variant="outline" size="icon">
        <IconPlus />
      </Button>
    </ButtonGroup>
    <ButtonGroup>
      <Button variant="outline" size="lg">Large</Button>
      <Button variant="outline" size="lg">Button</Button>
      <Button variant="outline" size="lg">Group</Button>
      <Button variant="outline" size="icon-lg">
        <IconPlus />
      </Button>
    </ButtonGroup>
  </div>
</template>
```
  </div>
</FrameworkCodeSwitcher>

## Nested

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

<FrameworkCodeSwitcher>
  <div slot="astro">
```astro
---
import { Button } from "@/components/starwind/button";
import { ButtonGroup } from "@/components/starwind/button-group";
import IconArrowLeft from "@tabler/icons/outline/arrow-left.svg";
import IconArrowRight from "@tabler/icons/outline/arrow-right.svg";
---

<ButtonGroup>
  <ButtonGroup>
    <Button variant="outline" size="sm">1</Button>
    <Button variant="outline" size="sm">2</Button>
    <Button variant="outline" size="sm">3</Button>
    <Button variant="outline" size="sm">4</Button>
    <Button variant="outline" size="sm">5</Button>
  </ButtonGroup>
  <ButtonGroup>
    <Button variant="outline" size="icon-sm" aria-label="Previous">
      <IconArrowLeft />
    </Button>
    <Button variant="outline" size="icon-sm" aria-label="Next">
      <IconArrowRight />
    </Button>
  </ButtonGroup>
</ButtonGroup>
```
  </div>
  <div slot="react">
```tsx
import { Button } from "@/components/starwind/button";
import { ButtonGroup } from "@/components/starwind/button-group";
import { IconArrowLeft as IconArrowLeft } from "@tabler/icons-react";
import { IconArrowRight as IconArrowRight } from "@tabler/icons-react";

export function Example() {
  return (
    <>
      <ButtonGroup>
        <ButtonGroup>
          <Button variant="outline" size="sm">1</Button>
          <Button variant="outline" size="sm">2</Button>
          <Button variant="outline" size="sm">3</Button>
          <Button variant="outline" size="sm">4</Button>
          <Button variant="outline" size="sm">5</Button>
        </ButtonGroup>
        <ButtonGroup>
          <Button variant="outline" size="icon-sm" aria-label="Previous">
            <IconArrowLeft />
          </Button>
          <Button variant="outline" size="icon-sm" aria-label="Next">
            <IconArrowRight />
          </Button>
        </ButtonGroup>
      </ButtonGroup>
    </>
  );
}
```
  </div>
  <div slot="vue">
```vue
<script setup lang="ts">
import { Button } from "@/components/starwind/button";
import { ButtonGroup } from "@/components/starwind/button-group";
import { IconArrowLeft as IconArrowLeft } from "@tabler/icons-vue";
import { IconArrowRight as IconArrowRight } from "@tabler/icons-vue";
</script>

<template>
  <ButtonGroup>
    <ButtonGroup>
      <Button variant="outline" size="sm">1</Button>
      <Button variant="outline" size="sm">2</Button>
      <Button variant="outline" size="sm">3</Button>
      <Button variant="outline" size="sm">4</Button>
      <Button variant="outline" size="sm">5</Button>
    </ButtonGroup>
    <ButtonGroup>
      <Button variant="outline" size="icon-sm" aria-label="Previous">
        <IconArrowLeft />
      </Button>
      <Button variant="outline" size="icon-sm" aria-label="Next">
        <IconArrowRight />
      </Button>
    </ButtonGroup>
  </ButtonGroup>
</template>
```
  </div>
</FrameworkCodeSwitcher>

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

<FrameworkCodeSwitcher>
  <div slot="astro">
```astro
---
import { Button } from "@/components/starwind/button";
import { ButtonGroup, ButtonGroupSeparator } from "@/components/starwind/button-group";
import IconCopy from "@tabler/icons/outline/copy.svg";
import IconClipboard from "@tabler/icons/outline/clipboard.svg";
---

<ButtonGroup>
  <Button size="sm">
    <IconCopy />
    Copy
  </Button>
  <ButtonGroupSeparator />
  <Button size="sm">
    <IconClipboard />
    Paste
  </Button>
</ButtonGroup>
```
  </div>
  <div slot="react">
```tsx
import { Button } from "@/components/starwind/button";
import { ButtonGroup, ButtonGroupSeparator } from "@/components/starwind/button-group";
import { IconCopy as IconCopy } from "@tabler/icons-react";
import { IconClipboard as IconClipboard } from "@tabler/icons-react";

export function Example() {
  return (
    <>
      <ButtonGroup>
        <Button size="sm">
          <IconCopy />
          Copy
        </Button>
        <ButtonGroupSeparator />
        <Button size="sm">
          <IconClipboard />
          Paste
        </Button>
      </ButtonGroup>
    </>
  );
}
```
  </div>
  <div slot="vue">
```vue
<script setup lang="ts">
import { Button } from "@/components/starwind/button";
import { ButtonGroup, ButtonGroupSeparator } from "@/components/starwind/button-group";
import { IconCopy as IconCopy } from "@tabler/icons-vue";
import { IconClipboard as IconClipboard } from "@tabler/icons-vue";
</script>

<template>
  <ButtonGroup>
    <Button size="sm">
      <IconCopy />
      Copy
    </Button>
    <ButtonGroupSeparator />
    <Button size="sm">
      <IconClipboard />
      Paste
    </Button>
  </ButtonGroup>
</template>
```
  </div>
</FrameworkCodeSwitcher>

## Split

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

<FrameworkCodeSwitcher>
  <div slot="astro">
```astro
---
import { Button } from "@/components/starwind/button";
import { ButtonGroup, ButtonGroupSeparator } from "@/components/starwind/button-group";
import IconPlus from "@tabler/icons/outline/plus.svg";
---

<ButtonGroup>
  <Button>Button</Button>
  <ButtonGroupSeparator />
  <Button size="icon">
    <IconPlus />
  </Button>
</ButtonGroup>
```
  </div>
  <div slot="react">
```tsx
import { Button } from "@/components/starwind/button";
import { ButtonGroup, ButtonGroupSeparator } from "@/components/starwind/button-group";
import { IconPlus as IconPlus } from "@tabler/icons-react";

export function Example() {
  return (
    <>
      <ButtonGroup>
        <Button>Button</Button>
        <ButtonGroupSeparator />
        <Button size="icon">
          <IconPlus />
        </Button>
      </ButtonGroup>
    </>
  );
}
```
  </div>
  <div slot="vue">
```vue
<script setup lang="ts">
import { Button } from "@/components/starwind/button";
import { ButtonGroup, ButtonGroupSeparator } from "@/components/starwind/button-group";
import { IconPlus as IconPlus } from "@tabler/icons-vue";
</script>

<template>
  <ButtonGroup>
    <Button>Button</Button>
    <ButtonGroupSeparator />
    <Button size="icon">
      <IconPlus />
    </Button>
  </ButtonGroup>
</template>
```
  </div>
</FrameworkCodeSwitcher>

## Input

Wrap an `Input` component with buttons.

<FrameworkCodeSwitcher>
  <div slot="astro">
```astro
---
import { Button } from "@/components/starwind/button";
import { ButtonGroup } from "@/components/starwind/button-group";
import { Input } from "@/components/starwind/input";
import IconSearch from "@tabler/icons/outline/search.svg";
---

<ButtonGroup>
  <Input placeholder="Search..." />
  <Button variant="outline" aria-label="Search">
    <IconSearch />
  </Button>
</ButtonGroup>
```
  </div>
  <div slot="react">
```tsx
import { Button } from "@/components/starwind/button";
import { ButtonGroup } from "@/components/starwind/button-group";
import { Input } from "@/components/starwind/input";
import { IconSearch as IconSearch } from "@tabler/icons-react";

export function Example() {
  return (
    <>
      <ButtonGroup>
        <Input placeholder="Search..." />
        <Button variant="outline" aria-label="Search">
          <IconSearch />
        </Button>
      </ButtonGroup>
    </>
  );
}
```
  </div>
  <div slot="vue">
```vue
<script setup lang="ts">
import { Button } from "@/components/starwind/button";
import { ButtonGroup } from "@/components/starwind/button-group";
import { Input } from "@/components/starwind/input";
import { IconSearch as IconSearch } from "@tabler/icons-vue";
</script>

<template>
  <ButtonGroup>
    <Input placeholder="Search..." />
    <Button variant="outline" aria-label="Search">
      <IconSearch />
    </Button>
  </ButtonGroup>
</template>
```
  </div>
</FrameworkCodeSwitcher>

## Select

Pair with a `Select` component.

<FrameworkCodeSwitcher>
  <div slot="astro">
```astro
---
import { Button } from "@/components/starwind/button";
import { ButtonGroup } from "@/components/starwind/button-group";
import { Input } from "@/components/starwind/input";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/starwind/select";
import IconArrowRight from "@tabler/icons/outline/arrow-right.svg";
---

<ButtonGroup>
  <ButtonGroup>
    <Select defaultValue="$">
      <SelectTrigger class="font-mono">
        <SelectValue placeholder="$" />
      </SelectTrigger>
      <SelectContent class="min-w-20">
        <SelectItem value="$"> $ </SelectItem>
        <SelectItem value="€"> € </SelectItem>
        <SelectItem value="£"> £ </SelectItem>
      </SelectContent>
    </Select>
    <Input placeholder="10.00" pattern="[0-9]*" />
  </ButtonGroup>
  <ButtonGroup>
    <Button aria-label="Send" size="icon" variant="outline">
      <IconArrowRight />
    </Button>
  </ButtonGroup>
</ButtonGroup>
```
  </div>
  <div slot="react">
```tsx
import { Button } from "@/components/starwind/button";
import { ButtonGroup } from "@/components/starwind/button-group";
import { Input } from "@/components/starwind/input";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/starwind/select";
import { IconArrowRight as IconArrowRight } from "@tabler/icons-react";

export function Example() {
  return (
    <>
      <ButtonGroup>
        <ButtonGroup>
          <Select defaultValue="$">
            <SelectTrigger className="font-mono">
              <SelectValue placeholder="$" />
            </SelectTrigger>
            <SelectContent className="min-w-20">
              <SelectItem value="$"> $ </SelectItem>
              <SelectItem value="€"> € </SelectItem>
              <SelectItem value="£"> £ </SelectItem>
            </SelectContent>
          </Select>
          <Input placeholder="10.00" pattern="[0-9]*" />
        </ButtonGroup>
        <ButtonGroup>
          <Button aria-label="Send" size="icon" variant="outline">
            <IconArrowRight />
          </Button>
        </ButtonGroup>
      </ButtonGroup>
    </>
  );
}
```
  </div>
  <div slot="vue">
```vue
<script setup lang="ts">
import { Button } from "@/components/starwind/button";
import { ButtonGroup } from "@/components/starwind/button-group";
import { Input } from "@/components/starwind/input";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/starwind/select";
import { IconArrowRight as IconArrowRight } from "@tabler/icons-vue";
</script>

<template>
  <ButtonGroup>
    <ButtonGroup>
      <Select defaultValue="$">
        <SelectTrigger class="font-mono">
          <SelectValue placeholder="$" />
        </SelectTrigger>
        <SelectContent class="min-w-20">
          <SelectItem value="$"> $ </SelectItem>
          <SelectItem value="€"> € </SelectItem>
          <SelectItem value="£"> £ </SelectItem>
        </SelectContent>
      </Select>
      <Input placeholder="10.00" pattern="[0-9]*" />
    </ButtonGroup>
    <ButtonGroup>
      <Button aria-label="Send" size="icon" variant="outline">
        <IconArrowRight />
      </Button>
    </ButtonGroup>
  </ButtonGroup>
</template>
```
  </div>
</FrameworkCodeSwitcher>

## Dropdown Menu

Create a split button group with a dropdown menu.

<FrameworkCodeSwitcher>
  <div slot="astro">
```astro
---
import { Button } from "@/components/starwind/button";
import { ButtonGroup } from "@/components/starwind/button-group";
import { Dropdown, DropdownContent, DropdownItem, DropdownSeparator, DropdownTrigger } from "@/components/starwind/dropdown";
import IconChevronDown from "@tabler/icons/outline/chevron-down.svg";
---

<ButtonGroup>
  <Button variant="outline">Follow</Button>
  <Dropdown>
    <DropdownTrigger asChild>
      <Button variant="outline" size="icon">
        <IconChevronDown />
      </Button>
    </DropdownTrigger>
    <DropdownContent align="end" class="min-w-[200px]">
      <DropdownItem>Mute Conversation</DropdownItem>
      <DropdownItem>Mark as Read</DropdownItem>
      <DropdownItem>Report Conversation</DropdownItem>
      <DropdownSeparator />
      <DropdownItem>Delete Conversation</DropdownItem>
    </DropdownContent>
  </Dropdown>
</ButtonGroup>
```
  </div>
  <div slot="react">
```tsx
import { Button } from "@/components/starwind/button";
import { ButtonGroup } from "@/components/starwind/button-group";
import { Dropdown, DropdownContent, DropdownItem, DropdownSeparator, DropdownTrigger } from "@/components/starwind/dropdown";
import { IconChevronDown as IconChevronDown } from "@tabler/icons-react";

export function Example() {
  return (
    <>
      <ButtonGroup>
        <Button variant="outline">Follow</Button>
        <Dropdown>
          <DropdownTrigger asChild>
            <Button variant="outline" size="icon">
              <IconChevronDown />
            </Button>
          </DropdownTrigger>
          <DropdownContent align="end" className="min-w-[200px]">
            <DropdownItem>Mute Conversation</DropdownItem>
            <DropdownItem>Mark as Read</DropdownItem>
            <DropdownItem>Report Conversation</DropdownItem>
            <DropdownSeparator />
            <DropdownItem>Delete Conversation</DropdownItem>
          </DropdownContent>
        </Dropdown>
      </ButtonGroup>
    </>
  );
}
```
  </div>
  <div slot="vue">
```vue
<script setup lang="ts">
import { Button, ButtonVariants } from "@/components/starwind/button";
import { ButtonGroup } from "@/components/starwind/button-group";
import {
  Dropdown,
  DropdownContent,
  DropdownItem,
  DropdownSeparator,
  DropdownTrigger,
} from "@/components/starwind/dropdown";
import { IconChevronDown as IconChevronDown } from "@tabler/icons-vue";
</script>

<template>
  <ButtonGroup>
    <Button variant="outline">Follow</Button>
    <Dropdown>
      <DropdownTrigger asChild>
        <button :class="ButtonVariants.button({ variant: 'outline', size: 'icon' })" type="button">
          <IconChevronDown />
        </button>
      </DropdownTrigger>
      <DropdownContent align="end" class="min-w-[200px]">
        <DropdownItem>Mute Conversation</DropdownItem>
        <DropdownItem>Mark as Read</DropdownItem>
        <DropdownItem>Report Conversation</DropdownItem>
        <DropdownSeparator />
        <DropdownItem>Delete Conversation</DropdownItem>
      </DropdownContent>
    </Dropdown>
  </ButtonGroup>
</template>
```
  </div>
</FrameworkCodeSwitcher>

## API Reference
### ButtonGroup
| Prop | Type | Required | Default | Kind | Description |
| --- | --- | --- | --- | --- | --- |
| `orientation` | `"horizontal" \| "vertical"` | No | `"horizontal"` | Styled variant | Selects the horizontal or vertical layout direction. |
- Inherits div attributes.

### ButtonGroupSeparator
- Inherits Separator props.

### ButtonGroupText
- Inherits div attributes.

## Changelog

### v1.1.1

- Named the generated aggregate default export so React and Astro tooling can identify the installed component cleanly.

### v1.1.0

- Added contract-generated Astro and React implementations while preserving the component's existing public API and styling.

### v1.0.2

- Refactor tailwind variants functions into separate `variants.ts` file

### v1.0.0

- Initial release with starwind v1.12