# Toggle

A button that turns a formatting option or view mode on or off. The selected state uses a soft accent fill.

## Usage

### When to use

- Turn one option on or off, such as pinning an item or applying emphasis.
- Keep a toolbar action selected until the user turns it off.

### When not to use

- An action with no persistent on state. Use Button.
- A setting submitted in a form. Use Switch.
- Related selection options. Use ToggleGroup.

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

## Examples

### Formatting

```tsx
<Toggle>Bold</Toggle>
```

### Selected initially

```tsx
<Toggle variant="outline" defaultPressed>Grid view</Toggle>
```

### Icon only

```tsx
<Toggle iconOnly aria-label="Bold"><IconBold size={16} /></Toggle>
```

### Disabled selection

```tsx
<Toggle disabled defaultPressed>Locked format</Toggle>
```

## Do and don't

### Do

- Use a stable label that names the option.
- Use iconOnly with aria-label for compact formatting controls.

### Don't

- Do not use a Toggle for an action that has no persistent state.
- Do not use it for a setting that applies at once; use Switch.

## 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` | Makes the button square. Requires aria-label on an icon-only button. |
| `pressed` | `boolean` |  |  | Controlled on or off state. Pair with onPressedChange. |
| `defaultPressed` | `boolean` |  | `false` | Initial state when uncontrolled. |
| `onPressedChange` | `function` |  |  | Receives the requested boolean state after activation. |

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

## Accessibility

Role: `button`

| Keys | Action |
| --- | --- |
| `Space, Enter` | Toggles pressed state. |
| `Tab` | Moves focus to the next control. |

- Text children provide the accessible name. iconOnly requires aria-label.
- aria-pressed exposes the on or off state. Keep the label stable when state changes.
- The button defaults to type="button" and does not submit its form.
- Pass size and weight to every icon. Use regular off and optionally fill on.

## Install

```bash
npx shadcn add https://werewolf-ui.vercel.app/r/toggle.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"`).
