Morphos
Inputs

ToggleGroup

A compound component for managing single or multiple selection across a set of toggle buttons.

Interactive example

Installation

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

Import

import { ToggleGroup, ToggleGroupItem } from '@morphos/inputs'

Compound components

ComponentDescription
ToggleGroupRoot container managing selection state, rendered with role="group"
ToggleGroupItemIndividual toggle button within the group

Usage

Single selection

@Component()
class MyComponent extends StatefulComponent {
  @State() group = new ToggleGroup({ type: 'single', defaultValue: 'left', orientation: 'horizontal' })

  render() {
    return (
      <ToggleGroup class="morphos-toggle-group" type="single" orientation="horizontal" aria-label="Text alignment">
        <ToggleGroupItem class="morphos-toggle-group-item" group={this.group} value="left" aria-label="Align left">
          Left
        </ToggleGroupItem>
        <ToggleGroupItem class="morphos-toggle-group-item" group={this.group} value="center" aria-label="Align center">
          Center
        </ToggleGroupItem>
        <ToggleGroupItem class="morphos-toggle-group-item" group={this.group} value="right" aria-label="Align right">
          Right
        </ToggleGroupItem>
      </ToggleGroup>
    )
  }
}

The group prop on each ToggleGroupItem must be the same ToggleGroup instance backing the rendered <ToggleGroup> root — ToggleGroupItem reads group.isPressed(value) and calls group.toggle(value) directly on it.

Multiple selection

@Component()
class MyComponent extends StatefulComponent {
  @State() group = new ToggleGroup({ type: 'multiple', defaultValue: ['bold'] })

  render() {
    return (
      <ToggleGroup class="morphos-toggle-group" type="multiple" aria-label="Text formatting">
        <ToggleGroupItem class="morphos-toggle-group-item" group={this.group} value="bold" aria-label="Bold">
          <strong>B</strong>
        </ToggleGroupItem>
        <ToggleGroupItem class="morphos-toggle-group-item" group={this.group} value="italic" aria-label="Italic">
          <em>I</em>
        </ToggleGroupItem>
        <ToggleGroupItem class="morphos-toggle-group-item" group={this.group} value="underline" aria-label="Underline">
          <u>U</u>
        </ToggleGroupItem>
      </ToggleGroup>
    )
  }
}

Controlled

@Component()
class MyComponent extends StatefulComponent {
  @State() group = new ToggleGroup({ type: 'single' })
  @State() layout = 'grid'

  render() {
    return (
      <ToggleGroup
        class="morphos-toggle-group"
        type="single"
        value={() => this.layout}
        onValueChange={(value) => (this.layout = value as string)}
        aria-label="View layout"
      >
        <ToggleGroupItem class="morphos-toggle-group-item" group={this.group} value="list" aria-label="List view">
          List
        </ToggleGroupItem>
        <ToggleGroupItem class="morphos-toggle-group-item" group={this.group} value="grid" aria-label="Grid view">
          Grid
        </ToggleGroupItem>
      </ToggleGroup>
    )
  }
}

Props — ToggleGroup

PropTypeDefaultDescription
type"single" | "multiple"Selection mode: one or many (required)
valuestring | string[]Controlled selected value(s)
defaultValuestring | string[]Uncontrolled initial value(s) — resolves to [] when type is "multiple" and no default is given
disabledbooleanfalseDisables all items in the group
orientation"horizontal" | "vertical""horizontal"Sets aria-orientation and data-orientation
onValueChange(value: string | string[]) => voidFires when selection changes
classstringAdditional CSS classes
idstringHTML id attribute
childrenChildrenThe ToggleGroupItem items
aria-labelstringAccessible label for the group container
aria-labelledbystringID of an element that labels the group

Props — ToggleGroupItem

PropTypeDefaultDescription
groupToggleGroupThe parent ToggleGroup instance (required)
valuestringThe value this item represents (required)
disabledbooleanOverrides the group's disabled for this item only
childrenChildrenContent rendered inside the button
classstringAdditional CSS classes
idstringHTML id attribute
aria-labelstringAccessible label for this item
aria-labelledbystringID of an element that labels this item

data-* attributes

AttributeElementWhen present
data-typeGroup rootAlways — value is "single" or "multiple"
data-orientationGroup rootAlways — value is "horizontal" or "vertical"
data-disabledGroup rootdisabled is true
data-pressedItem rootItem is in the current selection
data-disabledItem rootGroup's disabled or the item's own disabled is true

Accessibility

ToggleGroup renders a <div role="group"> with aria-orientation and aria-disabled. Each ToggleGroupItem renders a <button> with aria-pressed reflecting whether its value is in the current selection.

ToggleGroup and ToggleGroupItem do not implement roving-tabindex or arrow-key navigation — each item button is independently focusable via Tab, and pressing Space/Enter on a focused button activates it natively. If you need arrow-key movement between items, wire it up yourself.

Styling example

.morphos-toggle-group[data-orientation="vertical"] {
  flex-direction: column;
}

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

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

On this page