Morphos
Inputs

Toggle

A stateful button that can be pressed or unpressed, with aria-pressed semantics.

Interactive example

Installation

npm install @morphos/inputs
pnpm add @morphos/inputs
yarn add @morphos/inputs
bun add @morphos/inputs

Import

import { Toggle } from '@morphos/inputs'

Usage

@Component()
class MyComponent extends StatefulComponent {
  @State() bold = false

  render() {
    return (
      <Toggle
        pressed={this.bold}
        onPressedChange={(pressed) => (this.bold = pressed)}
        aria-label="Bold"
      >
        <strong>B</strong>
      </Toggle>
    )
  }
}

Uncontrolled

@Component()
class MyComponent extends StatefulComponent {
  render() {
    return (
      <Toggle defaultPressed={false} aria-label="Mute audio">
        <span>Mute</span>
      </Toggle>
    )
  }
}

Toolbar example

@Component()
class MyComponent extends StatefulComponent {
  @State() bold = false
  @State() italic = false
  @State() underline = false

  render() {
    return (
      <div role="toolbar" aria-label="Text formatting">
        <Toggle
          pressed={this.bold}
          onPressedChange={(v) => (this.bold = v)}
          aria-label="Bold"
        >
          B
        </Toggle>
        <Toggle
          pressed={this.italic}
          onPressedChange={(v) => (this.italic = v)}
          aria-label="Italic"
        >
          I
        </Toggle>
        <Toggle
          pressed={this.underline}
          onPressedChange={(v) => (this.underline = v)}
          aria-label="Underline"
        >
          U
        </Toggle>
      </div>
    )
  }
}

Props — Toggle

PropTypeDefaultDescription
pressedbooleanControlled pressed state
defaultPressedbooleanfalseUncontrolled initial pressed state
disabledbooleanfalseDisables the toggle
onPressedChange(pressed: boolean) => voidFires when the pressed state changes
classstringAdditional CSS classes
idstringHTML id attribute
childrenChildrenContent rendered inside the button
aria-labelstringAccessible label (required when children are not descriptive)
aria-labelledbystringID of an element that labels the toggle
aria-describedbystringID of an element that describes the toggle

data-* attributes

AttributeElementWhen present
data-pressedRootThe toggle is currently pressed
data-disabledRootdisabled is true

Keyboard navigation

KeyBehavior
SpaceToggle the pressed state
EnterToggle the pressed state
TabMove focus to the next focusable element

Accessibility

Toggle renders as a <button> with aria-pressed set to "true" or "false" depending on state. When disabled is true, the button receives the native disabled HTML attribute (button elements are automatically excluded from focus and click when disabled). Always provide a descriptive aria-label when the button content is a visual icon.

For groups of mutually exclusive or multi-selectable toggles, use ToggleGroup and ToggleGroupItem instead — they share selection state through a single group instance.

Styling example

.morphos-toggle[data-pressed] {
  background: var(--morphos-color-accent);
  border-color: var(--morphos-color-accent);
  color: var(--morphos-color-accent-text);
}

.morphos-toggle[data-disabled] {
  opacity: 0.5;
  cursor: not-allowed;
}

On this page