Lab

Sequencer

The <audio-ui-sequencer> custom element of @audio-ui/elements: its attributes, its parts and a live preview.

<audio-ui-sequencer> is a step grid with one row per sound and role="group". Pressing a cell toggles it, and dragging applies the new state to every cell crossed. The cells share one tab stop and are navigated with the arrow keys. Rows and steps are generated from templates:

Usage

The styles read the theme's CSS variables, which Styling sets.

<style>
  audio-ui-sequencer {
    display: grid;
    gap: calc(var(--spacing, 0.25rem) * 1 * var(--density, 1));
    width: 100%;
    max-width: 36rem;
  }

  audio-ui-sequencer-row {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: 1fr;
    gap: calc(var(--spacing, 0.25rem) * 1 * var(--density, 1));
  }

  audio-ui-sequencer-cell {
    aspect-ratio: 1;
    border-radius: calc(var(--radius, 0.625rem) - 4px);
    background: var(--muted, oklch(0.97 0 0));
    outline: none;
  }

  audio-ui-sequencer-cell:focus-visible {
    box-shadow: 0 0 0 2px var(--ring, oklch(0.708 0 0));
  }

  audio-ui-sequencer-cell[data-on] {
    background: var(--primary, oklch(0.205 0 0));
  }
</style>

<audio-ui-sequencer aria-label="Pattern" default-value="x.x. ..x.">
  <audio-ui-sequencer-row index="0" aria-label="Kick">
    <audio-ui-sequencer-cell step="0"></audio-ui-sequencer-cell>
    <audio-ui-sequencer-cell step="1"></audio-ui-sequencer-cell>
    <audio-ui-sequencer-cell step="2"></audio-ui-sequencer-cell>
    <audio-ui-sequencer-cell step="3"></audio-ui-sequencer-cell>
  </audio-ui-sequencer-row>
  <audio-ui-sequencer-row index="1" aria-label="Snare">
    <audio-ui-sequencer-cell step="0"></audio-ui-sequencer-cell>
    <audio-ui-sequencer-cell step="1"></audio-ui-sequencer-cell>
    <audio-ui-sequencer-cell step="2"></audio-ui-sequencer-cell>
    <audio-ui-sequencer-cell step="3"></audio-ui-sequencer-cell>
  </audio-ui-sequencer-row>
</audio-ui-sequencer>

<script type="module">
  import "@audio-ui/elements/sequencer";

  const sequencer = document.querySelector("audio-ui-sequencer");
  sequencer.addEventListener("change", (event) =>
    console.log(event.detail.value)
  );
</script>

In plain HTML, a row of <template> gives the rows and their steps from labels:

<audio-ui-sequencer aria-label="Pattern" default-value="x...x... ..x...x.">
  <audio-ui-sequencer-rows labels="Kick, Snare">
    <template>
      <audio-ui-sequencer-steps>
        <template><audio-ui-sequencer-cell></audio-ui-sequencer-cell></template>
      </audio-ui-sequencer-steps>
    </template>
  </audio-ui-sequencer-rows>
</audio-ui-sequencer>

API reference

pnpm add @audio-ui/elements
import "@audio-ui/elements/sequencer";
ExportKindWhat it is
SEQUENCER_TAGSconstThe names the sequencer's elements are registered under, frozen: a page cannot rename them by accident.
SequencerCellElementclassA step: a toggle button, pressed while the step is on (data-on).
SequencerChangeEventtypeFired when a press, a paint or a key press that changed the pattern ends.
SequencerElementclassThe root of a step sequencer, one row per sound, with role="group".
SequencerElementEventMapinterfaceThe events a sequencer fires, as addEventListener types them.
SequencerEventDetailinterfaceWhat a sequencer's input and change events carry.
SequencerInputEventtypeFired while cells are flipped.
SequencerRowElementclassA row of steps with role="group", for its index from the top.
SequencerRowsElementclassGenerates an <audio-ui-sequencer-row> per pattern row from its <template>.
SequencerSourceinterfaceA live value followed without rendering: here, the step being played.
SequencerStepElementclassA generated step, for its index.
SequencerStepsElementclassGenerates an <audio-ui-sequencer-step> per step of its row from its <template>: a cell, a velocity bar, or both.
SequencerVelocityChangeEventtypeFired when a drag, a key press or a reset that changed a velocity ends.
SequencerVelocityDetailinterfaceWhat a sequencer's velocityinput and velocitychange events carry.
SequencerVelocityElementclassA step's velocity, rendered as a bar sized by --sequencer-velocity.
SequencerVelocityInputEventtypeFired while a velocity is drawn or nudged.

Props · 3

EventDetailDescription
input, change{ value, reason }The pattern changes, then the gesture ends
velocityinput, velocitychange{ velocities, reason }Step velocities change, then the gesture ends

The velocities property holds each step's velocity as number[][] (0 to 1). The source property, { getSnapshot, subscribe } returning the current step, marks that step's cells with data-current.

PartDescription
<audio-ui-sequencer-rows>Generates an <audio-ui-sequencer-row> per row from its <template>. labels names them, separated by commas
<audio-ui-sequencer-row>A row with role="group", for its index
<audio-ui-sequencer-steps>Generates an <audio-ui-sequencer-step> per step from its <template>. Both render with display: contents, so the cells are the grid items
<audio-ui-sequencer-cell>A step, a toggle button pressed when on (data-on), labelled with its row and step ("Kick, step 5")
<audio-ui-sequencer-velocity>A step's velocity as a bar sized by --sequencer-velocity. Press or drag to set it; Alt + click or Delete resets it to full; its native range input takes the keyboard

The same control in React, and its parts' props: Sequencer.

Built by Ouest Labs, the source code is available on GitHub.
RSS