daw-ui

Toggle Group

Rows of toggles you paint by dragging, with lanes, exclusive solo, one tab stop and one gesture per action.

Kick
Snare
Hi-hat
Clap

Anatomy

import { Toggle, ToggleGroup } from '@addstack/daw-ui/react';

<ToggleGroup>
  <Toggle />
</ToggleGroup>

Toggles can sit anywhere inside the group, in any markup: in rows of a sequencer, or in the channel strips of a mixer.

Painting

With paint, pressing a toggle and dragging sets every toggle the pointer crosses to the state the first one took: start on an empty step to fill, on a filled one to clear. The whole segment between two pointer events is tested, so a fast drag does not skip steps, and a toggle is set at most once per stroke. With erase="secondary", the right button always clears, as in FL Studio.

From the keyboard, Shift+arrow moves to the next toggle and gives it the state of the current one.

Lanes

Toggles with the same lane form a line: a row of a step sequencer, or the mute buttons of a mixer's channels. A stroke paints along the lane where it started, even when the pointer drifts over the next one; an exclusive press only turns off toggles in its lane; the arrow keys move along a lane and across lanes.

Kick
Snare
Bass
Keys

State

Two ways, which can be mixed:

  • The group holds it. Toggles with a value are pressed when the group's value (or defaultValue) contains it. A step sequencer's pattern is one array: ["kick:0", "kick:4", …].
  • Each toggle holds its own. Toggles without a value use pressed / onPressedChange, for example from a store per track. The group only coordinates them.

Exclusive presses

exclusive="click" makes a press turn off the other toggles in its lane, as Ableton Live's solo does; Cmd/Ctrl+click adds instead. "modifier" is the other way around. A map sets it per lane:

<ToggleGroup exclusive={{ solo: 'click' }}>

Gestures

onGestureStart and onGestureEnd wrap each user action: a press, a paint stroke, an exclusive press that turns five toggles off. Use them to make each action one undo step:

<ToggleGroup paint onGestureStart={() => history.begin('Mute')} onGestureEnd={() => history.commit()}>

Keyboard

The group is one tab stop: Tab reaches the last focused toggle.

KeyMoves focus to
Arrow along the lane (← → for rows)The next toggle in the lane. Left and right follow the reading direction.
Arrow across lanes (↑ ↓ for rows)The toggle at the same position in the next lane.
Home / EndThe ends of the lane; with Ctrl, of the group.
Shift + arrowMoves, and paints the next toggle with the current one's state.
Space, EnterToggles.

Without lanes, orientation decides: a row, a column, or a grid of columns.

API reference

Renders a <div> with role="group".

Prop

Type

Data attribute
data-orientation"horizontal", "vertical" or "grid".
data-paintingDuring a paint stroke: "on" or "off", the state it paints.
data-disabledWhen disabled.

See Toggle for the toggles' own props, including lane and value.

On this page