# ToggleButton

> A button that stays pressed, alone or in a group with single or multiple selection.

Category: Actions · Status: stable · Package: @bindshq/stance-react@0.1.1 · Docs: https://stanceui.com/components/toggle-button

Use ToggleButton for a setting that switches on and off in place, like bold text or showing gridlines. ToggleButtonGroup arranges several toggles with one tab stop and arrow-key navigation: type="single" works like a segmented control (alignment, view mode) and type="multiple" allows any combination (text formatting). For settings that take effect as preferences, prefer Switch.

## Import

```tsx
import { ToggleButton, ToggleButtonGroup } from '@bindshq/stance-react';
```

Styles are imported once per app: `@bindshq/stance-tokens/css` and `@bindshq/stance-react/styles.css`.

## Examples

### Single selection

Pass required to prevent deselecting the active option.

```tsx
import { Icon, ToggleButton, ToggleButtonGroup } from '@bindshq/stance-react';

export function Single() {
  return (
    <ToggleButtonGroup label="Template view" defaultValue="grid" required>
      <ToggleButton value="grid" icon={<Icon name="layout-grid" />}>
        Grid
      </ToggleButton>
      <ToggleButton value="list" icon={<Icon name="list" />}>
        List
      </ToggleButton>
    </ToggleButtonGroup>
  );
}
```

### Standalone

```tsx
import { Icon, ToggleButton } from '@bindshq/stance-react';

export function Standalone() {
  return (
    <ToggleButton defaultPressed icon={<Icon name="eye" />}>
      Show placeholders
    </ToggleButton>
  );
}
```

### Multiple selection

```tsx
import { ToggleButton, ToggleButtonGroup } from '@bindshq/stance-react';

export function Multiple() {
  return (
    <ToggleButtonGroup
      type="multiple"
      label="Show in signature"
      defaultValue={['phone', 'logo']}
      attached={false}
    >
      <ToggleButton value="phone">Phone</ToggleButton>
      <ToggleButton value="address">Address</ToggleButton>
      <ToggleButton value="logo">Logo</ToggleButton>
      <ToggleButton value="social">Social links</ToggleButton>
    </ToggleButtonGroup>
  );
}
```

### Controlled

```tsx
import * as React from 'react';
import { Icon, ToggleButton, ToggleButtonGroup } from '@bindshq/stance-react';

export function Controlled() {
  const [value, setValue] = React.useState<string | null>('desktop');
  return (
    <div style={{ display: 'grid', gap: 12, justifyItems: 'start' }}>
      <ToggleButtonGroup
        label="Preview device"
        value={value}
        onValueChange={setValue}
        required
        size="sm"
      >
        <ToggleButton value="desktop" icon={<Icon name="monitor" />}>
          Desktop
        </ToggleButton>
        <ToggleButton value="mobile">Mobile</ToggleButton>
      </ToggleButtonGroup>
      <span style={{ fontSize: 14 }}>Previewing on: {value}</span>
    </div>
  );
}
```

## API reference

| Component | Prop | Type | Default | Description |
| --- | --- | --- | --- | --- |
| ToggleButton | `pressed` | `boolean` | None | Controlled pressed state (standalone). |
| ToggleButton | `defaultPressed` | `boolean` | `false` | Initial pressed state (standalone). |
| ToggleButton | `onPressedChange` | `(pressed: boolean) => void` | None | Called when toggled. |
| ToggleButton | `value` | `string` | None | Identifies the button inside a group. |
| ToggleButton | `icon` | `ReactNode` | None | Icon before the label. |
| ToggleButton | `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | Inherited from the group. |
| ToggleButtonGroup | `type` | `'single' \| 'multiple'` | `'single'` | Selection mode. |
| ToggleButtonGroup | `value` | `string \| null \| string[]` | None | Controlled value: a string (single) or array (multiple). |
| ToggleButtonGroup | `defaultValue` | `string \| null \| string[]` | None | Initial value. |
| ToggleButtonGroup | `onValueChange` | `(value) => void` | None | Called with the new value. |
| ToggleButtonGroup | `required` | `boolean` | `false` | Single mode: prevent clearing the selection. |
| ToggleButtonGroup | `label` | `string` | None | Accessible name for the group. |
| ToggleButtonGroup | `attached` | `boolean` | `true` | Join buttons into a segmented bar. |
| ToggleButtonGroup | `orientation` | `'horizontal' \| 'vertical'` | `'horizontal'` | Layout and arrow-key axis. |

## Accessibility

- Each toggle exposes aria-pressed, so assistive technology announces "pressed" or "not pressed".
- The group has one tab stop: Tab enters on the selected item and arrow keys move between items (roving tabindex).
- Keep the label constant while toggling; the pressed state communicates the change, not a new label.

## Keyboard

| Keys | Action |
| --- | --- |
| `Space` `Enter` | Toggles the focused button. |
| `ArrowRight` `ArrowLeft` | Moves focus within a horizontal group. |
| `ArrowDown` `ArrowUp` | Moves focus within a vertical group. |
| `Home` `End` | Moves to the first or last button. |

## Guidelines

**Do**

- Use icons with text, or provide aria-label on icon-only toggles.

**Don’t**

- Change the button label when its state changes.

## Related

- https://stanceui.com/components/button-group
- https://stanceui.com/components/switch
- https://stanceui.com/components/toolbar
