Toggle

A two-state button that can be either on or off

Installation

pnpm add @wandercom/design-system-web

Usage

import { Toggle } from '@wandercom/design-system-web/ui/toggle';
import { IconBold } from '@central-icons-react/round-outlined-radius-2-stroke-1.5/IconBold';

export function Example() {
  return (
    <Toggle aria-label="Toggle bold">
      <IconBold className="size-4" />
    </Toggle>
  );
}

Examples

Loading example...

The toggle component supports icon-only and text variants across multiple sizes. The default variant transitions from ghost to filled background when pressed, while the filter variant uses bordered styling suitable for filter chips.

Variants

Default

The default variant has a ghost background that becomes filled when pressed.

import { IconStar } from '@central-icons-react/round-outlined-radius-2-stroke-1.5/IconStar';

<Toggle variant="default" aria-label="Toggle option">
  <IconStar className="size-4" />
</Toggle>

Filter

The filter variant has a bordered appearance, useful for filter chips and selection UI.

import { IconFilter1 } from '@central-icons-react/round-outlined-radius-2-stroke-1.5/IconFilter1';

<Toggle variant="filter" size="md">
  <IconFilter1 className="size-4" />
  Filters
</Toggle>

Sizes

Icon sizes

Icon-only toggles come in three sizes.

import { IconBold } from '@central-icons-react/round-outlined-radius-2-stroke-1.5/IconBold';

<Toggle size="icon-sm" aria-label="Small toggle">
  <IconBold className="size-4" />
</Toggle>

<Toggle size="icon-md" aria-label="Medium toggle">
  <IconBold className="size-4" />
</Toggle>

<Toggle size="icon-lg" aria-label="Large toggle">
  <IconBold className="size-5" />
</Toggle>

Text sizes

Toggles with text content also come in three sizes.

import { IconBold } from '@central-icons-react/round-outlined-radius-2-stroke-1.5/IconBold';

<Toggle size="sm">
  <IconBold className="size-4" />
  Small
</Toggle>

<Toggle size="md">
  <IconBold className="size-4" />
  Medium
</Toggle>

<Toggle size="lg">
  <IconBold className="size-5" />
  Large
</Toggle>

Controlled state

Use pressed and onPressedChange for controlled state.

import { Toggle } from '@wandercom/design-system-web/ui/toggle';
import { IconStar } from '@central-icons-react/round-outlined-radius-2-stroke-1.5/IconStar';
import { useState } from 'react';

export function ControlledToggle() {
  const [pressed, setPressed] = useState(false);

  return (
    <Toggle pressed={pressed} onPressedChange={setPressed}>
      <IconStar className="size-4" />
    </Toggle>
  );
}

Props

variant?

'default' | 'filter'
Visual style variant. Default has ghost styling, filter has bordered styling.

size?

'sm' | 'md' | 'lg' | 'icon-sm' | 'icon-md' | 'icon-lg'
Size variant. Icon sizes are square, text sizes include horizontal padding. Defaults to 'icon-sm'.

defaultPressed?

boolean
The default pressed state when uncontrolled.

pressed?

boolean
The controlled pressed state.

onPressedChange?

(pressed: boolean) => void
Callback fired when the pressed state changes.

disabled?

boolean
Disables the toggle when true.

className?

string
Additional CSS classes to apply.

Accessibility

The Toggle component is built on Radix UI Toggle primitive and follows WAI-ARIA button pattern.

Keyboard interaction:

  • Space - Toggles the pressed state
  • Enter - Toggles the pressed state

Always provide an aria-label when using icon-only toggles to ensure screen readers can announce the toggle's purpose.

Toggle