# Toggle button

> A button that stays pressed — a setting shown as a button rather than a checkbox.

A toggle button is on or off, and says so with `aria-pressed`. Bold in a text editor, a filter that is applied, a panel that is showing.

There is no hidden input behind it: `aria-pressed` is the whole state, so a server-rendered toggle shows a setting and `setPressed()` is what changes it. Reach for `checkbox()` when it belongs in a form and `toggle()` — the switch — when it is a setting in a list.

## Basic toggle

```javascript
stack({ direction: 'row', gap: 'sm' },
  toggleButton({ pressed: true }, 'Bold'),
  toggleButton('Italic'),
  toggleButton('Underline'),
)
```

## Variants

```javascript
stack({ gap: 'md' },
  stack({ direction: 'row', gap: 'sm' },
    toggleButton({ variant: 'outline', pressed: true }, 'Outline on'),
    toggleButton({ variant: 'outline' }, 'Outline off'),
  ),
  stack({ direction: 'row', gap: 'sm' },
    toggleButton({ variant: 'ghost', pressed: true }, 'Ghost on'),
    toggleButton({ variant: 'ghost' }, 'Ghost off'),
  ),
  stack({ direction: 'row', gap: 'sm' },
    toggleButton({ variant: 'soft', pressed: true }, 'Soft on'),
    toggleButton({ variant: 'soft' }, 'Soft off'),
  ),
)
```

## Sizes

```javascript
stack({ direction: 'row', gap: 'sm', align: 'center' },
  toggleButton({ size: 'sm', pressed: true }, 'Small'),
  toggleButton({ size: 'md', pressed: true }, 'Medium'),
  toggleButton({ size: 'lg', pressed: true }, 'Large'),
)
```

## With icons

An icon-only toggle needs an accessible name — pass `aria-label`, which falls through to the button.

```javascript
stack({ direction: 'row', gap: 'sm' },
  toggleButton({
    pressed: true,
    'aria-label': 'Bold',
    title: 'Bold',
    startIcon: icon('bold'),
  }),
  toggleButton({
    'aria-label': 'Italic',
    title: 'Italic',
    startIcon: icon('italic'),
  }),
)
```

## Disabled

```javascript
stack({ direction: 'row', gap: 'sm' },
  toggleButton({ pressed: true, disabled: true }, 'On, locked'),
  toggleButton({ disabled: true }, 'Off, locked'),
)
```

## Making it do something

One call flips the attribute; the styling follows it. Inside a single-choice `toggleGroup()` it lets go of the siblings too.

`Anywhere`

```javascript
toggleButton({ onclick: "import('/su/pressed.js').then(m=>m.set(this))" }, 'Bold')
```

Or from your own module, when there is already one running:

`src/main.js`

```javascript
import { setPressed } from 'sitelo/ui/client'

setPressed('bold')
```

## Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `pressed` | `boolean` | `false` | Sets aria-pressed. setPressed() changes it afterwards. |
| `variant` | `'outline' \| 'ghost' \| 'soft'` | `'outline'` | How the unpressed button looks. |
| `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | Same scale as button(). |
| `disabled` | `boolean` | `false` | Disables the button. |

Everything else falls through to `button()` — `startIcon`, `endIcon`, `onclick` and the rest. For a set of them, see `toggleGroup()`.
