<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.
Usage
The styles read the theme's CSS variables, which Styling sets.
<style>
audio-ui-timeline {
display: block;
width: 100%;
max-width: 36rem;
}
audio-ui-timeline-viewport {
border: 1px solid var(--border, oklch(0.922 0 0));
border-radius: calc(var(--radius, 0.625rem) - 2px);
}
audio-ui-timeline-ruler {
height: calc(var(--spacing, 0.25rem) * 6);
margin-inline-start: calc(var(--spacing, 0.25rem) * 20);
background: var(--muted, oklch(0.97 0 0));
cursor: pointer;
}
audio-ui-timeline-mark {
height: 100%;
padding-inline-start: calc(var(--spacing, 0.25rem) * 1);
border-inline-start: 1px solid var(--border, oklch(0.922 0 0));
color: var(--muted-foreground, oklch(0.556 0 0));
font-size: 10px;
}
audio-ui-timeline-range {
top: 0;
bottom: 0;
background: color-mix(in oklab, var(--primary, oklch(0.205 0 0)) 15%, transparent);
}
audio-ui-timeline-track {
height: calc(var(--spacing, 0.25rem) * 14);
border-top: 1px solid var(--border, oklch(0.922 0 0));
}
audio-ui-timeline-track-header {
width: calc(var(--spacing, 0.25rem) * 20);
padding: calc(var(--spacing, 0.25rem) * 2);
border-inline-end: 1px solid var(--border, oklch(0.922 0 0));
background: var(--background, oklch(1 0 0));
font-size: 0.75rem;
line-height: 1rem;
}
audio-ui-timeline-clip {
top: calc(var(--spacing, 0.25rem) * 1);
bottom: calc(var(--spacing, 0.25rem) * 1);
overflow: hidden;
border-radius: calc(var(--radius, 0.625rem) - 4px);
background: color-mix(in oklab, var(--primary, oklch(0.205 0 0)) 15%, transparent);
}
audio-ui-timeline-clip[data-selected] {
box-shadow: 0 0 0 2px var(--ring, oklch(0.708 0 0));
}
audio-ui-timeline-clip-header {
overflow: hidden;
padding-inline: calc(var(--spacing, 0.25rem) * 1.5);
background: var(--primary, oklch(0.205 0 0));
color: var(--primary-foreground, oklch(0.985 0 0));
font-size: 10px;
text-overflow: ellipsis;
white-space: nowrap;
cursor: grab;
}
audio-ui-timeline-clip-handle {
position: absolute;
top: 0;
bottom: 0;
width: calc(var(--spacing, 0.25rem) * 1.5);
cursor: ew-resize;
}
audio-ui-timeline-clip-handle[edge="start"] {
left: 0;
}
audio-ui-timeline-clip-handle[edge="end"] {
right: 0;
}
audio-ui-timeline-playhead {
top: 0;
bottom: 0;
width: 1px;
background: var(--foreground, oklch(0.145 0 0));
}
audio-ui-timeline-navigator {
height: calc(var(--spacing, 0.25rem) * 3);
margin-top: calc(var(--spacing, 0.25rem) * 2);
border-radius: calc(var(--radius, 0.625rem) - 4px);
background: var(--muted, oklch(0.97 0 0));
}
audio-ui-timeline-navigator-window {
top: 0;
bottom: 0;
border-radius: calc(var(--radius, 0.625rem) - 4px);
background: color-mix(in oklab, var(--primary, oklch(0.205 0 0)) 25%, transparent);
cursor: grab;
}
</style>
<audio-ui-timeline duration="32" snap-step="1">
<audio-ui-timeline-viewport>
<audio-ui-timeline-ruler aria-label="Position"></audio-ui-timeline-ruler>
<audio-ui-timeline-track>
<audio-ui-timeline-track-header>Drums</audio-ui-timeline-track-header>
<audio-ui-timeline-lane seekable>
<audio-ui-timeline-clip aria-label="Beat" start="0" length="8">
<audio-ui-timeline-clip-header>Beat</audio-ui-timeline-clip-header>
</audio-ui-timeline-clip>
<audio-ui-timeline-playhead></audio-ui-timeline-playhead>
</audio-ui-timeline-lane>
</audio-ui-timeline-track>
</audio-ui-timeline-viewport>
</audio-ui-timeline>
<script type="module">
import "@audio-ui/elements/timeline";
const timeline = document.querySelector("audio-ui-timeline");
timeline.addEventListener("change", (event) =>
console.log(event.detail.value)
);
</script>API reference
pnpm add @audio-ui/elements
import "@audio-ui/elements/timeline";| Export | Kind | What it is |
|---|---|---|
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. |
Props · 13
Length of the timeline, in its units.
The playback position. The
source property follows a live position instead.Pixels per unit. When unset, the timeline fits its width.
Grid spacing. Gestures snap to it unless Cmd or Ctrl is held; 0 disables the grid.
Where the grid starts.
Magnetic positions for dragged clips and ranges, separated by spaces, such as clip edges and locators.
Arrow key step. Defaults to
snap-step, or duration / 100.Page Up and Page Down step. Defaults to ten steps.
| Event | Detail | Description |
|---|---|---|
input, change | { value, reason } | The position changes, then the gesture ends |
zoomchange | { value, reason } | The zoom changes, already clamped. preventDefault() rejects it |
Every lane sets --timeline-unit, the width of one unit; placed parts set --timeline-offset and --timeline-length.
| Part | Description |
|---|---|
<audio-ui-timeline-viewport> | The scrolling container. Cmd/Ctrl + wheel and pinch zoom around the pointer |
<audio-ui-timeline-ruler> | The lane that sets the position, containing the native range input. With selectable, Shift + drag selects a range and fires selectioninput and selectioncommit |
<audio-ui-timeline-lane> | A lane for placed parts. seekable sets the position from a press on empty space; with selectable, a drag selects a range |
<audio-ui-timeline-playhead> | A marker at the position |
<audio-ui-timeline-mark> | A part placed at value, such as a bar number. With movable, it can be dragged and fires markinput and markchange |
<audio-ui-timeline-range> | A loop or selection, value as "start end". Draggable, resizable with an <audio-ui-timeline-range-handle> per edge, and with drawable, drawn on empty lane. Fires rangeinput and rangechange with { value, edge, reason } |
<audio-ui-timeline-navigator> | An overview bar. Its <audio-ui-timeline-navigator-window> scrolls, its <audio-ui-timeline-navigator-handle>s zoom, and a double click fits the whole timeline |
<audio-ui-timeline-track> | A row with a header and a lane, sized by height in pixels. An <audio-ui-timeline-track-resize-handle> changes it and fires heightinput and heightchange. <audio-ui-timeline-track-header> stays pinned while the lane scrolls |
<audio-ui-timeline-clip> | A region of a source: start, length, offset, fade-in, fade-out, fade-in-shape, fade-out-shape, source-length. A press selects it (clipselect, then the selected attribute) and sets the position; Delete fires clipremove. Fires clipinput and clipchange with { value, reason, target, lane, delta, copy }. Sets --clip-unit for its own parts |
<audio-ui-timeline-clip-header> | Moves the clip by drag, across lanes |
<audio-ui-timeline-clip-handle> | Trims the clip's edge, shifting the source offset rather than stretching |
<audio-ui-timeline-clip-fade-handle> | Sets the fade at its edge (in or out). Double click or Enter cycles its shape |
<audio-ui-timeline-clip-fade> | Renders the fade at its edge, shaded with --clip-fade-shade |
The same control in React, and its parts' props: Timeline.