> For AI agents: the complete documentation index is available at https://wallarm.github.io/design-system/llms.txt, the full documentation bundle is available at https://wallarm.github.io/design-system/llms-full.txt.

# ToggleButton

A button that stays pressed — for something the reader flips in place and can see the result of, like pinning a panel or holding a filter on. Reach for `Switch` when it belongs in a settings form, and `SegmentedControl` when one of several options has to win.

[Source](https://github.com/wallarm/design-system/tree/main/packages/design-system/src/components/ToggleButton) · [Storybook](https://wallarm.github.io/design-system/storybook/?path=/docs/actions-togglebutton--overview)

```tsx
import { ToggleButton } from '@wallarm-org/design-system/ToggleButton';

export const Basic = () => (
  <ToggleButton data-testid='toggle-button'>
    Toggle Me
  </ToggleButton>
);
```

## Usage

```tsx
import { ToggleButton } from '@wallarm-org/design-system/ToggleButton';
```

## Examples

### Variants and colors

`outline` reads as a control that is always there; `ghost` disappears until needed, for
toolbars. `brand` tints the pressed state, `neutral` keeps it grey for when several toggles sit
together and colour would shout.

```tsx
import { HStack, VStack } from '@wallarm-org/design-system/Stack';
import { ToggleButton } from '@wallarm-org/design-system/ToggleButton';

export const VariantsAndColors = () => (
  <VStack>
    <HStack>
      <ToggleButton variant='outline' color='brand'>
        Outline
      </ToggleButton>
      <ToggleButton variant='ghost' color='brand'>
        Ghost
      </ToggleButton>
    </HStack>
    <HStack>
      <ToggleButton variant='outline' color='neutral'>
        Outline
      </ToggleButton>
      <ToggleButton variant='ghost' color='neutral'>
        Ghost
      </ToggleButton>
    </HStack>
  </VStack>
);
```

### Sizes

Three heights matching `Button`, so a toggle can sit in a row of them without breaking
the line.

```tsx
import { HStack } from '@wallarm-org/design-system/Stack';
import { ToggleButton } from '@wallarm-org/design-system/ToggleButton';

export const Sizes = () => (
  <HStack align='center'>
    <ToggleButton size='small'>
      Small
    </ToggleButton>
    <ToggleButton size='medium'>
      Medium
    </ToggleButton>
    <ToggleButton size='large'>
      Large
    </ToggleButton>
  </HStack>
);
```

### Disabled

Both states while disabled. A disabled toggle still shows whether it is on, which is the
point — say elsewhere why it cannot be changed.

```tsx
import { HStack } from '@wallarm-org/design-system/Stack';
import { ToggleButton } from '@wallarm-org/design-system/ToggleButton';

export const Disabled = () => (
  <HStack>
    <ToggleButton disabled>
      Disabled
    </ToggleButton>
    <ToggleButton disabled active>
      Disabled Active
    </ToggleButton>
    <ToggleButton disabled variant='ghost'>
      Ghost Disabled
    </ToggleButton>
  </HStack>
);
```

### Loading

For a toggle whose effect is a request. It keeps the label's footprint and disables itself,
so the pressed state does not flicker while the answer is in flight.

```tsx
import { HStack } from '@wallarm-org/design-system/Stack';
import { ToggleButton } from '@wallarm-org/design-system/ToggleButton';

export const Loading = () => (
  <HStack>
    <ToggleButton loading>
      Loading
    </ToggleButton>
    <ToggleButton loading active>
      Loading Active
    </ToggleButton>
    <ToggleButton loading variant='ghost'>
      Ghost Loading
    </ToggleButton>
  </HStack>
);
```

### Icons

An icon before or after the label. Pressed state is carried by the whole button, not the
icon, so don't swap the icon to signal it.

```tsx
import { ChevronLeft, ChevronRight } from '@wallarm-org/design-system/icons';
import { HStack } from '@wallarm-org/design-system/Stack';
import { ToggleButton } from '@wallarm-org/design-system/ToggleButton';

export const Icons = () => (
  <HStack>
    <ToggleButton>
      <ChevronLeft />
      Left icon
    </ToggleButton>
    <ToggleButton>
      Right icon
      <ChevronRight />
    </ToggleButton>
    <ToggleButton>
      <ChevronLeft />
      Both icons
      <ChevronRight />
    </ToggleButton>
  </HStack>
);
```

### Icon only

The toolbar case: an icon alone squares the button off. `aria-label` is doing all the
naming here, so it is not optional.

```tsx
import { ChevronRight } from '@wallarm-org/design-system/icons';
import { HStack } from '@wallarm-org/design-system/Stack';
import { ToggleButton } from '@wallarm-org/design-system/ToggleButton';

export const IconOnly = () => (
  <HStack>
    <ToggleButton aria-label='Toggle option 1'>
      <ChevronRight />
    </ToggleButton>
    <ToggleButton loading aria-label='Toggle option 2'>
      <ChevronRight />
    </ToggleButton>
    <ToggleButton disabled aria-label='Toggle option 3'>
      <ChevronRight />
    </ToggleButton>
  </HStack>
);
```

### Controlled

Pass `active` and own the state when something else has to move with it — a panel opening,
a filter applying. Once `active` is set the button stops tracking itself.

```tsx
import { useState } from 'react';
import { ToggleButton } from '@wallarm-org/design-system/ToggleButton';

export const Controlled = () => {
  const [active, setActive] = useState<boolean>(false);

  return (
    <ToggleButton aria-label='Toggle option 1' active={active} onToggle={setActive}>
      Controlled
    </ToggleButton>
  );
};
```

## Props

| Prop           | Type                                                                                         | Default   | Description |
| -------------- | -------------------------------------------------------------------------------------------- | --------- | ----------- |
| title          | `string \| undefined`                                                                        |           |             |
| defaultChecked | `boolean \| undefined`                                                                       |           |             |
| defaultValue   | `string \| number \| readonly string[] \| undefined`                                         | `false`   |             |
| autoFocus      | `boolean \| undefined`                                                                       |           |             |
| id             | `string \| undefined`                                                                        |           |             |
| tabIndex       | `number \| undefined`                                                                        |           |             |
| rel            | `string \| undefined`                                                                        |           |             |
| color          | `string \| undefined`                                                                        | `brand`   |             |
| onChange       | `ChangeEventHandler<T, Element> \| undefined`                                                |           |             |
| type           | `"button" \| "submit" \| "reset" \| undefined`                                               |           |             |
| disabled       | `boolean \| undefined`                                                                       | `false`   |             |
| name           | `string \| undefined`                                                                        |           |             |
| value          | `string \| number \| readonly string[] \| undefined`                                         |           |             |
| asChild        | `boolean \| undefined`                                                                       | `false`   |             |
| size           | `{ small: string; medium: string; large: string; 'inline-edit': string; }`                   | `large`   |             |
| data-testid    | `string \| undefined`                                                                        |           |             |
| loading        | `{ true: string; }`                                                                          | `false`   |             |
| as             | `C \| undefined`                                                                             |           |             |
| fullWidth      | `{ true: string; false: string; }`                                                           |           |             |
| variant        | `{ outline: string; ghost: string; }`                                                        | `outline` |             |
| active         | `{ true: string; false: string; }`                                                           |           |             |
| onToggle       | `((active: boolean, event: MouseEvent<HTMLButtonElement, MouseEvent>) => void) \| undefined` |           |             |
