Toggle

A two-state button that stays pressed when toggled on. Used for formatting toolbars (bold/italic) or option toggles.

Variants

Sizes

With text

Disabled

Installation

pnpm
pnpm dlx @hex-core/cli add toggle

Pressed (controlled)

Lift the pressed state into a parent component to mirror it in your editor model

tsx
function BoldToolbarButton() {
  const [bold, setBold] = React.useState(false);
  return (
    <Toggle
      pressed={bold}
      onPressedChange={setBold}
      aria-label="Toggle bold"
    >
      B
    </Toggle>
  );
}

With icon only

Icon-only toggle — aria-label is required since there is no visible text

tsx
<Toggle aria-label="Bold">
  <svg
    xmlns="http://www.w3.org/2000/svg"
    viewBox="0 0 24 24"
    fill="none"
    stroke="currentColor"
    strokeWidth="2"
    strokeLinecap="round"
    strokeLinejoin="round"
    aria-hidden="true"
  >
    <path d="M6 4h8a4 4 0 0 1 4 4 4 4 0 0 1-4 4H6z" />
    <path d="M6 12h9a4 4 0 0 1 4 4 4 4 0 0 1-4 4H6z" />
  </svg>
</Toggle>

Variant values

variantVisual variants
ValueDescription
defaultdefault
Transparent ghost-style toggle
outline
Bordered toggle
sizeSize variants
ValueDescription
defaultdefault
Standard size (h-10)
sm
Compact size (h-9)
lg
Large size (h-11)

API Reference

PropTypeDefaultDescription
pressed
booleanControlled pressed state
defaultPressed
booleanfalseDefault pressed state for uncontrolled usage
onPressedChange
functionCallback on pressed change: (pressed: boolean) => void
variant
"default" | "outline"defaultVisual style
size
"default" | "sm" | "lg"defaultToggle size
disabled
booleanfalseDisable the toggle

AI Guidance

When to use

Use for binary on/off actions that persist: toolbar formatting buttons (bold, italic), layout mode switches, filter toggles. Not submitted as form data.

When not to use

Don't use for instant settings (use Switch). Don't use for form boolean fields (use Checkbox). Don't use for choosing one of many (use ToggleGroup).

Common mistakes

  • Using for form field submission (use Checkbox instead)
  • Forgetting aria-label on icon-only toggles
  • Using Toggle when ToggleGroup's single-select mode is needed

Accessibility

Radix sets aria-pressed correctly. Icon-only toggles MUST have aria-label. Space/Enter toggles state.

Token budget: 400