# ToggleGroup

A named group of toggle buttons for one optional choice or several independent options. Arrow keys move focus without changing selection.

## Usage

### When to use

- Pick one or several related toolbar options, such as alignment or text formatting.
- Keep a compact set of choices together with arrow-key navigation.

### When not to use

- One choice must always remain selected. Use RadioGroup.
- Switching between content panels. Use Tabs.
- A single independent option. Use Toggle.

## Variants

### variant

Transparent when off, or a surface with a neutral border for outline.

Values: `default`, `outline`. Default: `default`.

### size

Control height, text and icon size, the same steps as Button: sm 28px, md 32px (the default), lg 36px, xl 44px with a mouse; on touch md is 36px, lg 44px and xl 48px. Small controls keep a minimum hit area.

Values: `sm`, `md`, `lg`, `xl`. Default: `md`.

### type

single takes string values and permits deselection. multiple takes string arrays.

Values: `single`, `multiple`. Default: `undefined`.

### orientation

Controls layout and the arrow keys used for navigation.

Values: `horizontal`, `vertical`. Default: `horizontal`.

### dir

Text direction, inherited when omitted. RTL reverses horizontal arrows.

Values: `ltr`, `rtl`. Default: `ltr`.

## Examples

### Optional alignment

```tsx
<ToggleGroup type="single" aria-label="Text alignment" defaultValue="left"><ToggleGroupItem value="left">Left</ToggleGroupItem><ToggleGroupItem value="center">Center</ToggleGroupItem><ToggleGroupItem value="right">Right</ToggleGroupItem></ToggleGroup>
```

### Independent formatting

```tsx
<ToggleGroup type="multiple" aria-label="Text formatting" defaultValue={["bold"]}><ToggleGroupItem value="bold">Bold</ToggleGroupItem><ToggleGroupItem value="italic">Italic</ToggleGroupItem></ToggleGroup>
```

### Vertical view choices

```tsx
<ToggleGroup type="single" aria-label="View" orientation="vertical" variant="outline"><ToggleGroupItem value="grid">Grid</ToggleGroupItem><ToggleGroupItem value="list">List</ToggleGroupItem></ToggleGroup>
```

## Do and don't

### Do

- Name the group and keep each item label stable.
- Use single for an optional view choice and multiple for independent formatting options.

### Don't

- Do not use single when exactly one choice must remain; use RadioGroup.
- Do not repeat item values within a group.

## Props

| Name | Type | Values | Default | Description |
| --- | --- | --- | --- | --- |
| `variant` | `enum` | `default`, `outline` | `default` | Transparent when off, or a surface with a neutral border for outline. |
| `size` | `enum` | `sm`, `md`, `lg`, `xl` | `md` | Control height, text and icon size, the same steps as Button: sm 28px, md 32px (the default), lg 36px, xl 44px with a mouse; on touch md is 36px, lg 44px and xl 48px. Small controls keep a minimum hit area. |
| `disabled` | `boolean` |  | `false` | Prevents focus and selection and uses disabled colors. |
| `iconOnly` | `boolean` |  | `false` | Set on ToggleGroupItem. Makes the item square. Requires aria-label on an icon-only item. |
| `type` (required) | `enum` | `single`, `multiple` |  | single takes string values and permits deselection. multiple takes string arrays. |
| `value` | `node` |  |  | Controlled selection: a string for single or a string array for multiple. Every item requires its own unique value. |
| `defaultValue` | `node` |  |  | Initial selection when uncontrolled: a string for single or a string array for multiple. |
| `onValueChange` | `function` |  |  | Receives a string for single or a string array for multiple. Clearing single selection reports an empty string. |
| `orientation` | `enum` | `horizontal`, `vertical` | `horizontal` | Controls layout and the arrow keys used for navigation. |
| `dir` | `enum` | `ltr`, `rtl` | `ltr` | Text direction, inherited when omitted. RTL reverses horizontal arrows. |
| `loop` | `boolean` |  | `true` | Wraps arrow navigation at either end when true. |

## Anatomy

| Part | Description |
| --- | --- |
| `root` | The toggle button, transparent by default or a bordered surface in outline. On uses the soft accent pair. |
| `icon` | An optional decorative icon, 16px in sm, md and lg and 20px in xl. |
| `hitArea` | A transparent pseudo-element that extends the button target to size-target-min. |
| `wrapper` | The named group with token spacing, horizontal by default and vertical when requested. |

## Accessibility

Role: `radiogroup (single), toolbar (multiple)`

| Keys | Action |
| --- | --- |
| `Tab` | Enters the group at one item, then leaves the group. |
| `ArrowLeft, ArrowRight` | Moves focus in a horizontal group, skips disabled items, and respects text direction. |
| `ArrowUp, ArrowDown` | Moves focus in a vertical group and skips disabled items. |
| `Home, End` | Moves focus to the first or last enabled item. |
| `Space, Enter` | Toggles the focused item. |

- A group requires aria-label or aria-labelledby.
- Single items expose role="radio" and aria-checked. Multiple items expose aria-pressed.
- Pressing a selected single item clears selection. Use RadioGroup when a choice must remain selected.
- Items require unique non-empty value strings. Icon-only items require aria-label.
- Group size and variant are item defaults. An item can override either default.
- Arrow keys move focus; they do not select. loop defaults to true.

## Install

```bash
npx shadcn add https://werewolf-ui.vercel.app/r/toggle-group.json
```

This also adds `styles/werewolf.css`, the tokens every component uses, and any other component it needs. Import that file once in your root CSS, after `@import "tailwindcss"`, with a path relative to that CSS file (from `app/globals.css` it is `@import "../styles/werewolf.css"`).
