# Custom elements

> Every primitive as framework-agnostic Web Components, with their parts, state attributes and events, in Vue, Svelte, plain HTML and any framework.

`@audio-ui/elements` provides every primitive as a set of unstyled, accessible custom elements, built on `@audio-ui/core`: their parts, keyboard interactions, ARIA semantics and `data-*` state attributes. The elements work in plain HTML and in any framework that renders HTML, such as Vue, Svelte, Angular or Lit. Every element has a page with its attributes, its parts, a live preview and its usage in your framework.

## Installation

```bash
npm install @audio-ui/elements
```

Each primitive is a separate entry point, `@audio-ui/elements/<primitive>`, which registers its elements when imported. The package root registers every primitive. Import an entry once, before the elements are used:

```js
import "@audio-ui/elements/knob";
```

Registration is a no-op on the server: server-rendered markup upgrades once the module loads in the browser.

## Usage

**JavaScript**

```html
<audio-ui-knob min="20" max="20000" default-value="1000" scale="log">
  <audio-ui-knob-label>Cutoff</audio-ui-knob-label>
  <audio-ui-knob-control>
    <audio-ui-knob-track></audio-ui-knob-track>
    <audio-ui-knob-indicator></audio-ui-knob-indicator>
    <audio-ui-knob-thumb></audio-ui-knob-thumb>
  </audio-ui-knob-control>
  <audio-ui-knob-value></audio-ui-knob-value>
</audio-ui-knob>

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

  const knob = document.querySelector("audio-ui-knob");
  knob.addEventListener("input", (event) => setCutoff(event.detail.value));
</script>
```

**Vue**

Declare the tags as custom elements to Vue's compiler, in `vite.config.ts`, then register the elements the app uses, once, as in any page:

```ts
vue({
  template: {
    compilerOptions: { isCustomElement: (tag) => tag.startsWith("audio-ui-") },
  },
});
```

**Types.** `@audio-ui/elements/vue` adds every element to Vue's `GlobalComponents`. Import it once, in a file the project's `tsconfig.json` includes. Templates are then checked as for a component: an element's attributes (`min`, `drag-mode`), the properties it has a setter for (`value`, `format`) and its own events, with the type of their `detail`, such as a knob's `input` or a clip's `clipinput`. Strict templates (`vueCompilerOptions.strictTemplates`) are supported. The import adds nothing to the bundle.

```ts
import type {} from "@audio-ui/elements/vue";
```

**Binding.** `v-model` binds an element's `value`: Vue reads it on every `input` and writes it when the model changes. The knob, the fader, the XY pad, the envelope, the sequencer, the waveform, the piano roll and a plot's handles take `v-model`.

```vue
<script setup lang="ts">
import "@audio-ui/elements/knob";
import { ref } from "vue";

const cutoff = ref(1000);
</script>

<template>
  <audio-ui-knob min="20" max="20000" scale="log" v-model="cutoff">
    <audio-ui-knob-label>Cutoff</audio-ui-knob-label>
    <audio-ui-knob-control>
      <audio-ui-knob-track />
      <audio-ui-knob-indicator />
      <audio-ui-knob-thumb />
    </audio-ui-knob-control>
    <audio-ui-knob-value />
  </audio-ui-knob>
</template>
```

`v-model` keeps every value the element proposes. To refuse one, bind `:value` and listen to `@input`, which can call `preventDefault()`:

```vue
<script setup lang="ts">
import type { KnobInputEvent } from "@audio-ui/elements/knob";
import { ref } from "vue";

const cutoff = ref(1000);
const limit = ref(8000);

function onInput(event: KnobInputEvent) {
  if (event.detail.value > limit.value) {
    event.preventDefault();
  } else {
    cutoff.value = event.detail.value;
  }
}
</script>

<template>
  <audio-ui-knob :value="cutoff" @input="onInput" />
</template>
```

A part with a value of its own, such as a timeline clip or a range, fires events prefixed with its name: bind it with `:value` and `@clipinput` or `@rangeinput`.

**Svelte**

Svelte renders the tags as they are written. Register the elements the app uses, once, as in any page:

```ts
import "@audio-ui/elements/knob";
```

**Types.** `@audio-ui/elements/svelte` adds every element to `SvelteHTMLElements`, in `svelte/elements`. Import it once, in a file the project's `tsconfig.json` includes. Templates are then checked: an element's attributes (`min`, `drag-mode`), the properties it has a setter for (`value`, `format`) and an `on…` handler for each of its own events, with the type of their `detail`, such as a knob's `oninput` or a clip's `onclipinput`. The import adds nothing to the bundle.

```ts
import type {} from "@audio-ui/elements/svelte";
```

**Binding.** Svelte binds `bind:value` on `<input>`, `<textarea>` and `<select>` only. Bind an element with `value` and `oninput`:

```svelte
<script lang="ts">
  import "@audio-ui/elements/knob";

  let cutoff = $state(1000);
</script>

<audio-ui-knob
  min="20"
  max="20000"
  scale="log"
  value={cutoff}
  oninput={(event) => (cutoff = event.detail.value)}
>
  <audio-ui-knob-label>Cutoff</audio-ui-knob-label>
  <audio-ui-knob-control>
    <audio-ui-knob-track></audio-ui-knob-track>
    <audio-ui-knob-indicator></audio-ui-knob-indicator>
    <audio-ui-knob-thumb></audio-ui-knob-thumb>
  </audio-ui-knob-control>
  <audio-ui-knob-value></audio-ui-knob-value>
</audio-ui-knob>
```

Svelte sets what a template gives an element as a property when the element has one, `value`, `scale` and `format` among them, and as an attribute otherwise. A listener that refuses a value calls `event.preventDefault()` instead of assigning it. A part with a value of its own, such as a timeline clip or a range, fires events prefixed with its name: bind it with `value` and `onclipinput` or `onrangeinput`.

**React**

In React, use `@audio-ui/react`: the same parts as components, with typed props, a `render` prop and controlled state. React 19 renders the custom elements as well, as the previews on this page do, but the components integrate with it natively.

```tsx
import { Knob } from "@audio-ui/react";

const [cutoff, setCutoff] = useState(1000);

<Knob.Root max={20_000} min={20} onValueChange={setCutoff} scale="log" value={cutoff}>
  <Knob.Label>Cutoff</Knob.Label>
  <Knob.Control>
    <Knob.Track />
    <Knob.Indicator />
    <Knob.Thumb />
  </Knob.Control>
  <Knob.Value />
</Knob.Root>;
```

## Value and events

Every control follows the same contract:

| Member | Kind | Description |
| --- | --- | --- |
| `input` | Event | Fires on every change. `event.detail` holds the new `value` and the `reason` for the change, such as `"drag"`, `"keyboard"`, `"wheel"`, `"reset"` or `"input-change"`. Calling `preventDefault()` rejects the change. |
| `change` | Event | Fires once when an interaction that changed the value ends. Use it to commit: start a note, record an undo step, save. |
| `value` | Property | Reads the current value, and sets it. While `input` is dispatched it reads the value proposed, as a native input's does, so `event.target.value` is the new one. Framework bindings (`v-model` in Vue, `value={}` in Svelte) read and write this property. During a drag, the control follows the pointer even when the bound value lags behind. |
| `name` | Attribute | Submits the value with the enclosing form, through the control's native range input. |

A part that holds a value of its own fires events prefixed with its name, for example `clipinput` and `clipchange` on a timeline clip. These never collide with the control's own `input` and `change`, and they bubble, so a single listener on the root can handle every part.

## Styling

The elements apply only the styles their behavior depends on: the display of each box, the positioning of placed parts, `touch-action` on interactive surfaces. These rules are wrapped in `:where()`, so they carry no specificity and any rule of yours takes precedence. No color, size or spacing is set. Style the parts by tag and by the same state attributes as the React parts, with a stylesheet or with classes. Parts drawn as SVG use `currentColor`.

The examples on every element's page do both, and the **Styling** choice of the customizer says which one they show. They read the theme's variables. The CSS examples carry the default theme's values as fallbacks, so they work as pasted; to change the look, define the variables once in your own stylesheet. The Tailwind examples need them, named for their classes:

{/* styling:start: written by `bun scripts/element-usage.ts --write` */}

*With CSS*

```css
:root {
  --background: oklch(1 0 0);
  --border: oklch(0.922 0 0);
  --card: oklch(1 0 0);
  --foreground: oklch(0.145 0 0);
  --input: oklch(0.922 0 0);
  --muted: oklch(0.97 0 0);
  --muted-foreground: oklch(0.556 0 0);
  --popover: oklch(1 0 0);
  --primary: oklch(0.205 0 0);
  --primary-foreground: oklch(0.985 0 0);
  --radius: 0.625rem;
  --ring: oklch(0.708 0 0);
}

.dark {
  --background: oklch(0.145 0 0);
  --border: oklch(1 0 0 / 10%);
  --card: oklch(0.205 0 0);
  --foreground: oklch(0.985 0 0);
  --input: oklch(1 0 0 / 15%);
  --muted: oklch(0.269 0 0);
  --muted-foreground: oklch(0.708 0 0);
  --popover: oklch(0.205 0 0);
  --primary: oklch(0.922 0 0);
  --primary-foreground: oklch(0.205 0 0);
  --ring: oklch(0.556 0 0);
}
```

*With Tailwind*

```css
@import "tailwindcss";

@theme inline {
  --color-background: var(--background);
  --color-border: var(--border);
  --color-card: var(--card);
  --color-foreground: var(--foreground);
  --color-input: var(--input);
  --color-muted: var(--muted);
  --color-muted-foreground: var(--muted-foreground);
  --color-popover: var(--popover);
  --color-primary: var(--primary);
  --color-primary-foreground: var(--primary-foreground);
  --color-ring: var(--ring);
  --radius-sm: calc(var(--radius) - 4px);
  --radius-md: calc(var(--radius) - 2px);
  --radius-lg: var(--radius);
}

:root {
  --background: oklch(1 0 0);
  --border: oklch(0.922 0 0);
  --card: oklch(1 0 0);
  --foreground: oklch(0.145 0 0);
  --input: oklch(0.922 0 0);
  --muted: oklch(0.97 0 0);
  --muted-foreground: oklch(0.556 0 0);
  --popover: oklch(1 0 0);
  --primary: oklch(0.205 0 0);
  --primary-foreground: oklch(0.985 0 0);
  --radius: 0.625rem;
  --ring: oklch(0.708 0 0);
}

.dark {
  --background: oklch(0.145 0 0);
  --border: oklch(1 0 0 / 10%);
  --card: oklch(0.205 0 0);
  --foreground: oklch(0.985 0 0);
  --input: oklch(1 0 0 / 15%);
  --muted: oklch(0.269 0 0);
  --muted-foreground: oklch(0.708 0 0);
  --popover: oklch(0.205 0 0);
  --primary: oklch(0.922 0 0);
  --primary-foreground: oklch(0.205 0 0);
  --ring: oklch(0.556 0 0);
}
```

{/* styling:end */}

The **Accent**, **Radius** and **Font** of the customizer restyle every preview, and **Copy CSS** gives this stylesheet with your choices.

## Elements

Each primitive is a set of elements, with a page of its attributes, its parts and a live preview:

| Element | What it is |
| --- | --- |
| [Knob](/docs/elements/knob) | `<audio-ui-knob>` is the root of a rotary control. It owns the value and renders its parts from it. |
| [Fader](/docs/elements/fader) | `<audio-ui-fader>` is the root of a linear control, with audio defaults: vertical, from -60 to +6. It has `role="group"`, labelled by its label part. |
| [Pad](/docs/elements/pad) | `<audio-ui-pad>` is a grid of velocity-sensitive pads with `role="group"`. A pad sounds while held, by pointer or with Enter and Space, and each pointer holds its own pad. Velocity comes from pen or touch pressure, or from the vertical press position. The pads share one tab stop and are navigated with the arrow keys. |
| [Piano](/docs/elements/piano) | `<audio-ui-piano>` is a playable keyboard with `role="group"`. A key sounds while pressed, by pointer or with Enter and Space. Dragging glides across keys, and each pointer holds its own key, so chords can be played on touch screens. The keys share one tab stop and are navigated with the arrow keys, by octave with Shift. |
| [XY pad](/docs/elements/xypad) | `<audio-ui-xypad>` controls a two-dimensional value `{ x, y }`. A press moves the point to the pointer and a drag follows it; the wheel, the trackpad and the arrow keys move it; a double click or Delete resets it. The position is exposed as `--xy-pad-x` (from the left) and `--xy-pad-y` (from the top), as percentages. |
| [Meter](/docs/elements/meter) | `<audio-ui-meter>` displays one or more level channels. Levels come from the `value` and `peak` attributes or properties, one per channel, or from a live `source` property, `{ getSnapshot, subscribe }`, whose frames are written directly to the parts. A click clears clip indicators latched by a live source. |
| [Sequencer](/docs/elements/sequencer) | `<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: |
| [Envelope](/docs/elements/envelope) | `<audio-ui-envelope>` is a breakpoint envelope editor with `role="group"`. Points are dragged to move, added with a double click on the graph, and removed with a double click, Alt + click or Delete. Each segment has a curve handle at its midpoint, and Alt + drag on the graph bends the segment under the pointer. The points share one tab stop: Page Up and Page Down (or Home and End) move between them, and the arrow keys move the focused point. Points and segment handles are generated, from a `<template>` when one is provided: |
| [Plot](/docs/elements/plot) | `<audio-ui-plot>` defines two axes and lays out everything drawn on them in axis units, for response curves, filter displays and transfer functions. Each drawing part renders its own SVG covering the plot, in `currentColor`, with a constant stroke width. Curves take their function and traces their live source as properties: |
| [Waveform](/docs/elements/waveform) | `<audio-ui-waveform>` displays audio and, with a control part, seeks through it: a press seeks to the pointer, a drag scrubs, and the keyboard steps. The shape comes from the `peaks` property or a live `levels` source; the position from `value` or a live `source`, exposed as `--waveform-position`: |
| [Timeline](/docs/elements/timeline) | `<audio-ui-timeline>` is the root of an arrangement: a ruler that sets the position, lanes of clips that move, trim and fade, loop ranges, and a viewport that scrolls and zooms. Units are arbitrary: seconds, beats or steps. |
| [Piano roll](/docs/elements/piano-roll) | `<audio-ui-piano-roll>` is a note editor placed inside an `<audio-ui-timeline>`, which provides its length, zoom, grid and position. Its entry point also registers the timeline and piano elements. Notes are set through the `value` property as `{ id, pitch, start, length, velocity?, chance?, muted? }[]`, and the selection through the `selection` property. Rows, notes and velocity bars are generated from them: |

## Data attributes

Parts reflect the state of their control:

**Data attributes**

| Attribute | Description |
| --- | --- |
| `data-disabled` | Present when disabled. |
| `data-dragging` | Present while a pointer drags the control. |
| `data-drag-mode` | On knob parts, the `drag-mode`, for cursor styling. |
| `data-orientation` | On fader parts, `horizontal` or `vertical`. |
| `data-active` | On a pad or a piano key while it sounds. |
| `data-on` | On a sequencer cell or velocity bar whose step is on. |
| `data-current` | On the cells of the current step. |
| `data-painting` | On the sequencer and its parts during a paint gesture. |
| `data-blocked` | On an envelope graph or point, briefly, when an add or remove is refused. |

## The package

```bash
npm install @audio-ui/elements
```

```ts
import "@audio-ui/elements";
```

| Export | Kind | What it is |
| --- | --- | --- |
| `ENVELOPE_TAGS` | const | The names the envelope's elements are registered under, frozen: a page cannot rename them by accident. |
| `EnvelopeChangeEvent` | type | Fired once an interaction that changed the points ends. |
| `EnvelopeElement` | class | The root of a breakpoint envelope editor, with `role="group"`. |
| `EnvelopeElementEventMap` | interface | The events an envelope fires, as `addEventListener` types them. |
| `EnvelopeEventDetail` | interface | What an envelope's `input` and `change` events carry, besides the envelope itself as their target. |
| `EnvelopeFillElement` | class | The area under the curve, in `currentColor`. |
| `EnvelopeGraphElement` | class | The drawing surface, filling the envelope (`position: absolute; inset: 0`) and containing the line and the fill. |
| `EnvelopeInputEvent` | type | Fired on every change. |
| `EnvelopeLineElement` | class | The curve through the points, in `currentColor`, with a stroke width that stays constant as the graph scales. |
| `EnvelopePointElement` | class | A draggable handle for the point at `index`, positioned with `left` and `bottom`. |
| `EnvelopePointsElement` | class | Generates an `<audio-ui-envelope-point>` per point, in `x` order, from its `<template>` when present. |
| `EnvelopeSegmentElement` | class | A curve handle at the midpoint of the segment that starts at point `index`, a `role="slider"` from -1 to 1. |
| `EnvelopeSegmentsElement` | class | Generates an `<audio-ui-envelope-segment>` per segment, from its `<template>` when present. |
| `FADER_TAGS` | const | The names the fader's elements are registered under, frozen: a page cannot rename them by accident. |
| `FaderChangeEvent` | type | Fired once a gesture ends with a new value. |
| `FaderControlElement` | class | The interactive area. |
| `FaderElement` | class | The root of a linear control, with audio defaults: vertical, from -60 to +6. |
| `FaderElementEventMap` | interface | The events a fader fires, as `addEventListener` types them. |
| `FaderEventDetail` | interface | What a fader's `input` and `change` events carry, besides the fader itself as their target. |
| `FaderIndicatorElement` | class | The filled range of the track, from `min` to the value, or between `anchor` and the value. |
| `FaderInputEvent` | type | Fired on every change. |
| `FaderLabelElement` | class | The accessible label. |
| `FaderThumbElement` | class | The draggable thumb, positioned at the value. |
| `FaderTrackElement` | class | The full range of travel, containing the indicator and the thumb. |
| `FaderValueElement` | class | Renders the value, formatted with the fader's `format` and `locale`. |
| `KNOB_TAGS` | const | The names the knob's elements are registered under, frozen: a page cannot rename them by accident. |
| `KnobChangeEvent` | type | Fired once a gesture ends with a new value. |
| `KnobControlElement` | class | The interactive surface. |
| `KnobElement` | class | The root of a rotary control. |
| `KnobElementEventMap` | interface | The events a knob fires, as `addEventListener` types them. |
| `KnobEventDetail` | interface | What a knob's `input` and `change` events carry, besides the knob itself as their target. |
| `KnobIndicatorElement` | class | The arc from `anchor` to the value, rendered over the track. |
| `KnobInputEvent` | type | Fired on every change. |
| `KnobLabelElement` | class | The accessible label. |
| `KnobThumbElement` | class | Rotates with the value, clockwise from 12 o'clock, through `rotate`. |
| `KnobTrackElement` | class | The full sweep of the dial, rendered as an SVG arc in `currentColor`. |
| `KnobValueElement` | class | Renders the value, formatted with the knob's `format` and `locale`. |
| `METER_TAGS` | const | The names the meter's elements are registered under, frozen: a page cannot rename them by accident. |
| `MeterChannelElement` | class | A channel with `role="meter"`, for its `index`, labelled by `aria-label` or an `<audio-ui-meter-label>`. |
| `MeterChannelsElement` | class | Generates an `<audio-ui-meter-channel>` per level from its `<template>`, regenerated when the channel count changes. |
| `MeterElement` | class | The root of a level meter, with `role="group"`. |
| `MeterIndicatorElement` | class | The lit range of a channel, scaled to the level along the meter's length. |
| `MeterLabelElement` | class | The accessible label of its channel. |
| `MeterMarkElement` | class | A scale graduation at `value`, such as -18 dB, placed along the meter's length from its minimum. |
| `MeterPeakElement` | class | The peak-hold marker at the channel's peak level. |
| `MeterSnapshot` | interface | What the meter's parts draw from. |
| `MeterSource` | interface | A live signal, in the shape of an external store: `subscribe` calls back on each new frame, `getSnapshot` returns the latest. |
| `MeterTrackElement` | class | The full range of a channel, behind the indicator. |
| `MeterValueElement` | class | Renders the channel's level, formatted with the meter's `format` and `locale`. |
| `PAD_TAGS` | const | The names the pad's elements are registered under, frozen: a page cannot rename them by accident. |
| `PadElement` | class | The root of a velocity-sensitive pad grid, with `role="group"`. |
| `PadElementEventMap` | interface | The events a pad grid fires, as `addEventListener` types them. |
| `PadItemElement` | class | A pad, a button that sounds while held, by pointer or with Enter and Space. |
| `PadOffDetail` | interface | What a `padoff` event carries: the pad released, and why. |
| `PadOffEvent` | type | Fired when a pad stops sounding. |
| `PadOnDetail` | interface | What a `padon` event carries: the pad struck, how hard, and how. |
| `PadOnEvent` | type | Fired when a pad is struck. |
| `PIANO_TAGS` | const | The names the piano's elements are registered under, frozen: a page cannot rename them by accident. |
| `PianoElement` | class | The root of a playable keyboard, with `role="group"`. |
| `PianoElementEventMap` | interface | The events a piano fires, as `addEventListener` types them. |
| `PianoKeyElement` | class | A key, positioned for its `pitch`. |
| `PianoKeyLabelElement` | class | The name of its key, such as "C4". |
| `PianoKeysElement` | class | Generates an `<audio-ui-piano-key>` per pitch, lowest first, filled from its `<template>`, such as with an `<audio-ui-piano-key-label>`. |
| `PianoNoteOffDetail` | interface | What a `noteoff` event carries: the pitch released, and why. |
| `PianoNoteOffEvent` | type | Fired when a key stops sounding. |
| `PianoNoteOnDetail` | interface | What a `noteon` event carries: the pitch played, how hard, and how. |
| `PianoNoteOnEvent` | type | Fired when a key starts sounding. |
| `PIANO_ROLL_TAGS` | const | The names the piano roll's elements are registered under, frozen: a page cannot rename them by accident. |
| `PianoRollElement` | class | The root of a note editor, placed inside an `<audio-ui-timeline>`, which provides its length, zoom, grid and position. |
| `PianoRollElementEventMap` | interface | The events a piano roll fires, as `addEventListener` types them. |
| `PianoRollEventDetail` | interface | What a roll's `input` and `change` events carry, besides the roll itself as their target. |
| `PianoRollGridElement` | class | The note surface: a focusable timeline lane with `role="group"`, with the rows stacked vertically. |
| `PianoRollKeysElement` | class | Lays out the `<audio-ui-piano>` it contains on the roll's rows, low end at the bottom, and lights the sounding pitches. |
| `PianoRollMarqueeElement` | class | The selection rectangle during a marquee drag. |
| `PianoRollNoteElement` | class | A note, positioned at its start in timeline units and on its pitch's row. |
| `PianoRollNoteHandleElement` | class | Resizes its note from its `edge` (`start` or `end`): the end changes the length, the start trims from the front with the end fixed. |
| `PianoRollNotesElement` | class | Generates an `<audio-ui-piano-roll-note>` per note in reading order (by start, then highest pitch first), which is also the tab order, from its `<template>`, such as with `<audio-ui-piano-roll-note-handle>`s. |
| `PianoRollRowElement` | class | The band of a `pitch` across the grid, for row shading, scale highlighting and octave lines. |
| `PianoRollRowsElement` | class | Generates an `<audio-ui-piano-roll-row>` per row, highest pitch first, from its `<template>` when present. |
| `PianoRollSelectionSpanElement` | class | The time range of the selected notes, spanning the height of its container: the grid, the velocity lane or the ruler. |
| `PianoRollStretchHandleElement` | class | An `edge` of the selection span. |
| `PianoRollVelocitiesElement` | class | Generates an `<audio-ui-piano-roll-velocity>` per note, from its `<template>` when present. |
| `PianoRollVelocityElement` | class | A note's velocity, or chance in a `level="chance"` lane, rendered as a bar sized by `--piano-roll-level`. |
| `PianoRollVelocityLaneElement` | class | A timeline lane of per-note bars for velocity or, with `level="chance"`, probability, each at its note's start. |
| `PLOT_TAGS` | const | The names the plot's elements are registered under, frozen: a page cannot rename them by accident. |
| `PlotBandElement` | class | The range of one `axis` between `from` and `to`, spanning the other axis, such as a sweep range or a level above a threshold. |
| `PlotCursorElement` | class | Tracks a mouse or pen over the plot, for crosshairs and readouts. |
| `PlotCursorReadoutElement` | class | Renders the value under the pointer as text, inside an `<audio-ui-plot-cursor>`. |
| `PlotCurveElement` | class | Plots `y = fn(x)` across the plot in axis units, from the `fn` property, such as a frequency response in dB. |
| `PlotDotElement` | class | A non-interactive point, such as the input level on a compressor curve. |
| `PlotDotSource` | type | A live point, in the axes' units. |
| `PlotElement` | class | The root of a plot. |
| `PlotGridElement` | class | Grid lines and labels at round values along the axes. |
| `PlotHandleChangeEvent` | type | Fired once a gesture that moved a handle ends, and after each key or input change. |
| `PlotHandleElement` | class | A draggable point in axis units, such as an equalizer band or a filter's cutoff and resonance. |
| `PlotHandleElementEventMap` | interface | The events a handle fires, as `addEventListener` types them. |
| `PlotHandleEventDetail` | interface | What a handle's `input` and `change` events carry, besides the handle itself as their target. |
| `PlotHandleInputEvent` | type | Fired on every move of a handle. |
| `PlotLineElement` | class | A straight line at `value`: vertical on the x axis (`axis="x"`, the default), such as a cutoff, or horizontal on the y axis, such as 0 dB. |
| `PlotMarkElement` | class | A label at `value` on one `axis`, such as "1k" or "+12", positioned with `left` (x, the default) or `top` (y). |
| `PlotSnapshot` | interface | What every part draws from: the plot's two axes, and whether it is disabled. |
| `PlotTraceElement` | class | A live line from the y values of the `source` property, such as a spectrum, spread evenly across the x axis and redrawn on each change. |
| `PlotTraceSource` | type | A live list of y values, spread evenly across the x axis. |
| `SEQUENCER_TAGS` | const | The names the sequencer's elements are registered under, frozen: a page cannot rename them by accident. |
| `SequencerCellElement` | class | A step: a toggle button, pressed while the step is on (`data-on`). |
| `SequencerChangeEvent` | type | Fired when a press, a paint or a key press that changed the pattern ends. |
| `SequencerElement` | class | The root of a step sequencer, one row per sound, with `role="group"`. |
| `SequencerElementEventMap` | interface | The events a sequencer fires, as `addEventListener` types them. |
| `SequencerEventDetail` | interface | What a sequencer's `input` and `change` events carry. |
| `SequencerInputEvent` | type | Fired while cells are flipped. |
| `SequencerRowElement` | class | A row of steps with `role="group"`, for its `index` from the top. |
| `SequencerRowsElement` | class | Generates an `<audio-ui-sequencer-row>` per pattern row from its `<template>`. |
| `SequencerSource` | interface | A live value followed without rendering: here, the step being played. |
| `SequencerStepElement` | class | A generated step, for its `index`. |
| `SequencerStepsElement` | class | Generates an `<audio-ui-sequencer-step>` per step of its row from its `<template>`: a cell, a velocity bar, or both. |
| `SequencerVelocityChangeEvent` | type | Fired when a drag, a key press or a reset that changed a velocity ends. |
| `SequencerVelocityDetail` | interface | What a sequencer's `velocityinput` and `velocitychange` events carry. |
| `SequencerVelocityElement` | class | A step's velocity, rendered as a bar sized by `--sequencer-velocity`. |
| `SequencerVelocityInputEvent` | type | Fired while a velocity is drawn or nudged. |
| `TimelineClipElement` | class | A region of a source on a lane, such as a recording or a pattern. |
| `TimelineClipElementEventMap` | interface | The events a clip fires, as `addEventListener` types them. |
| `TimelineClipEventDetail` | interface | What a clip's events carry, besides the clip itself as their target. |
| `TimelineClipFadeElement` | class | Renders the fade at its `edge` (`in` or `out`) over the clip: the gain ramp as a line in `currentColor`, with the attenuated area shaded by `--clip-fade-shade` (the line color by default). |
| `TimelineClipFadeHandleElement` | class | Sets the length of the fade at its `edge` (`in` or `out`) by drag, off the grid, or through the native `<input type="range">` it contains, which carries the accessible name. |
| `TimelineClipHandleElement` | class | Trims the clip's `edge` (`start` or `end`) by drag, on the grid unless Cmd or Ctrl is held, or through the native `<input type="range">` it contains, which carries the accessible name. |
| `TimelineClipHeaderElement` | class | The clip's title bar. |
| `TimelineLaneElement` | class | A lane for placed parts, such as a track's clips or a row of markers. |
| `TimelineLaneElementEventMap` | interface | The events a `selectable` lane or ruler fires, as `addEventListener` types them. |
| `TimelineMarkElement` | class | A part placed at `value` on a lane, such as a bar number, a cue or a grid line, labelled by its content. |
| `TimelineMarkElementEventMap` | interface | The events a mark fires, as `addEventListener` types them. |
| `TimelineNavigatorElement` | class | An overview bar of the whole timeline, showing the visible range as `<audio-ui-timeline-navigator-window>`. |
| `TimelineNavigatorHandleElement` | class | An `edge` of the navigator window (`start` or `end`). |
| `TimelineNavigatorWindowElement` | class | The visible range of the timeline. |
| `TimelinePlayheadElement` | class | A marker at the playback position on its lane, following it through `--timeline-offset`. |
| `TimelineRulerElement` | class | The lane that sets the position: a press seeks to the pointer and a drag scrubs, on the grid unless Cmd or Ctrl is held, four times finer with Shift. |
| `TimelineViewportElement` | class | The scrolling container of the timeline. |
| `TimelineRangeElement` | class | A loop or selection on its lane, from `value` (`"start end"`; the whole timeline by default). |
| `TimelineRangeElementEventMap` | interface | The events a range fires, as `addEventListener` types them. |
| `TimelineRangeEventDetail` | interface | What a range's events carry: which edge moved, or `"both"`, and the range, `[start, end]` in the timeline's units. |
| `TimelineRangeHandleElement` | class | Resizes the `edge` (`start` or `end`) of its range by drag, on the grid unless Cmd or Ctrl is held, or through the native `<input type="range">` it contains, which carries the accessible name. |
| `TIMELINE_TAGS` | const | The names the timeline's elements are registered under, frozen: a page cannot rename them by accident. |
| `TimelineChangeEvent` | type | Fired once a gesture that moved the position ends. |
| `TimelineDescribe` | type | Returns how a position is announced. |
| `TimelineElement` | class | The root of a timeline. |
| `TimelineElementEventMap` | interface | The events a timeline fires, as `addEventListener` types them. |
| `TimelineEventDetail` | interface | What a timeline's `input` and `change` events carry, besides the timeline itself as their target. |
| `TimelineInputEvent` | type | Fired on every move of the position. |
| `TimelineSettings` | interface | What the timeline's parts measure and step by, as its attributes set them. |
| `TimelineZoomEvent` | type | Fired when the zoom changes, already clamped. |
| `ViewportMetrics` | interface | How the viewport is scrolled and zoomed, as last laid out. |
| `TimelineTrackElement` | class | A track: a row with a header and a lane. |
| `TimelineTrackElementEventMap` | interface | The events a track fires, as `addEventListener` types them: its height, in pixels. |
| `TimelineTrackHeaderElement` | class | The header beside a track's lane, for its name and controls. |
| `TimelineTrackResizeHandleElement` | class | Sets the track's height by drag, or through the native `<input type="range">` it contains, which carries the accessible name: the arrow keys step (Down is taller), Page Up and Page Down take larger steps, and Home and End go to the minimum and maximum. |
| `WAVEFORM_TAGS` | const | The names the waveform's elements are registered under, frozen: a page cannot rename them by accident. |
| `WaveformBarElement` | class | A bar of `<audio-ui-waveform-bars>`, for its `index`. |
| `WaveformBarsElement` | class | Renders the waveform as `count` `<audio-ui-waveform-bar>` elements (24) for CSS-styled visualizers. |
| `WaveformCanvasElement` | class | Renders the waveform on a canvas aligned to the device pixel grid, so it stays sharp at any density. |
| `WaveformChangeEvent` | type | Fired once a seek that moved the position ends. |
| `WaveformControlElement` | class | The seekable surface: a press seeks to the pointer and a drag scrubs. |
| `WaveformControlElementEventMap` | interface | The events a `selectable` waveform control fires, as `addEventListener` types them. |
| `WaveformDescribe` | type | Returns how a position is announced. |
| `WaveformElement` | class | The root of a waveform. |
| `WaveformElementEventMap` | interface | The events a waveform fires, as `addEventListener` types them. |
| `WaveformEventDetail` | interface | What a waveform's `input` and `change` events carry, besides the waveform itself as their target. |
| `WaveformHoverElement` | class | Shown at the hovered position while the pointer is over the control. |
| `WaveformInputEvent` | type | Fired on every seek. |
| `WaveformLevelsSource` | type | A live signal: the current levels, 0…1 each, or raw samples for the `scope` variant. |
| `WaveformMarkerElement` | class | A cue or chapter marker at `value`, labelled by its content. |
| `WaveformPlayheadElement` | class | A non-interactive marker at the playback position. |
| `WaveformPositionSource` | type | A live playback position, in `duration` units. |
| `WaveformRangeDetail` | interface | What a selection's and a region's events carry: the stretch, `[start, end]` in `duration` units. |
| `WaveformRegionElement` | class | A loop or selection over the waveform, from `value` (`"start end"` in `duration` units; the whole audio by default). |
| `WaveformRegionElementEventMap` | interface | The events a region fires, as `addEventListener` types them. |
| `WaveformRegionHandleElement` | class | Resizes the `edge` (`start` or `end`) of its region by drag or through the native `<input type="range">` it contains, which receives its `aria-label`. |
| `WaveformThumbElement` | class | A handle centered on the playback position, through `--waveform-position`. |
| `XYPAD_TAGS` | const | The names the XY pad's elements are registered under, frozen: a page cannot rename them by accident. |
| `XYPadChangeEvent` | type | Fired once a gesture ends with a new point. |
| `XYPadControlElement` | class | The interactive surface. |
| `XYPadElement` | class | The root of a two-dimensional control. |
| `XYPadElementEventMap` | interface | The events an XY pad fires, as `addEventListener` types them. |
| `XYPadEventDetail` | interface | What an XY pad's `input` and `change` events carry, besides the pad itself as their target. |
| `XYPadInputEvent` | type | Fired on every change. |
| `XYPadLabelElement` | class | The accessible label. |
| `XYPadThumbElement` | class | Marks the point, positioned with `left` and `top` and centered with `translate`. |
| `XYPadValueElement` | class | Renders the point as `"x, y"`, formatted with the pad's `format` and `locale`. |
