pnpm add @audio-ui/react
import { adjacentPoint, clipEnd, copyRange, coverClips, duplicateClip, /* … */ } from "@audio-ui/react/timeline";| Export | Kind | What it is |
|---|---|---|
adjacentPoint | function | The nearest of points strictly after from (direction 1) or strictly before it (direction -1), or null when there is none that way: what jumping to the next or the previous locator, or cue, needs. |
ClipLimits | interface | What a clip edit keeps a clip within: the timeline's length, the shortest it may be, and its source's length. |
ClipValue | interface | A clip: a stretch of a source (a recording, a pattern) placed on the timeline. |
clipEnd | function | Where the clip ends on the timeline. |
copyRange | function | What the stretch from from to to holds of items: the part of each clip inside it, moved so the stretch starts at 0. |
coverClips | function | What a clip laid on a lane leaves of the clips already there: they are covered, not stacked. |
duplicateClip | function | A copy of the clip placed right after it, or as late as the timeline allows when there is not room for it. |
FADE_SHAPES | const | The fade shapes in the order a control steps through them. |
FadeShape | type | How a fade rises or falls: evenly, quick then slow, slow then quick, or eased at both ends. |
fadeGain | function | The gain a fade of shape has progress of the way through it, from 0 (silent) to 1 (full): the curve of a fade-in; a fade-out plays it backwards. |
insertTime | function | Opens a stretch length long at at: everything from there moves later, and a clip across at is cut in two around the gap. |
moveClip | function | Moves the clip to begin at start, keeping its length and its place in the source. |
nextFadeShape | function | The shape after shape, going round, for a control that steps through them. |
removeTime | function | Takes the stretch from from to to out of the timeline: what is in it goes, and everything after it moves back to close the gap. |
setClipFadeIn | function | Sets the fade-in's length, which cannot run into the fade-out. |
setClipFadeOut | function | Sets the fade-out's length, which cannot run into the fade-in. |
setClipFadeShape | function | Gives the fade at edge the shape shape. |
splitClip | function | Cuts the clip in two at at, a position on the timeline. |
trimClipEnd | function | Trims the clip's end to end, as far as the timeline and the source allow. |
trimClipStart | function | Trims the clip's start to start: what is cut off stays in the source, so the clip's content does not move on the timeline. |
Timeline.Clip | function | A stretch of a source laid on a lane: a recording, a pattern. |
Timeline.ClipFade | function | Draws a fade over the clip's content, as a DAW does: the ramp as a line from the clip's edge, as long as the fade, with what it attenuates shaded by --clip-fade-shade (the line's own color if it is not set). |
Timeline.ClipFadeHandle | function | Sets how long one of the clip's fades lasts: by dragging, which is not on the grid, or from the keyboard through the native <input type="range"> it holds, which carries the accessible name. |
Timeline.ClipHandle | function | Trims one edge of the clip: by dragging, on the grid unless Cmd/Ctrl is held, or from the keyboard through the native <input type="range"> it holds, which carries the accessible name. |
Timeline.ClipHeader | function | The clip's title bar: dragging it moves the clip, on the grid unless Cmd/Ctrl is held, and over other lanes too. |
Timeline.Lane | function | A strip along the timeline that its parts are placed on: a track, the ruler's strip, a row of markers. |
Timeline.Mark | function | Something placed at value on a lane: a bar number on the ruler, a cue, a grid line. |
Timeline.Navigator | function | The whole timeline as one bar, with the stretch the viewport shows drawn inside it as Timeline.NavigatorWindow: drag the window to scroll, drag one of its Timeline.NavigatorHandles to zoom, double-click to show everything. |
Timeline.NavigatorHandle | function | One edge of the window: dragging it zooms, holding the other edge in place. |
Timeline.NavigatorWindow | function | The stretch of the timeline the viewport shows. |
Timeline.Playhead | function | A marker at the playback position, on the lane it sits in. |
Timeline.Range | function | A stretch of the timeline, such as a loop, a selection or a clip, laid on the lane it sits in from value[0] to value[1]. |
Timeline.RangeHandle | function | Resizes one edge of the range: by dragging, on the grid unless Cmd/Ctrl is held, or from the keyboard through the native <input type="range"> it holds, which carries the accessible name. |
Timeline.Root | function | Groups the parts of a timeline and owns what they share: its length, its zoom, its grid and the playback position. |
Timeline.Ruler | function | The lane that moves the position: a press jumps to the pointer and a drag scrubs, both on the grid unless Cmd/Ctrl is held; with Shift held the drag scrubs four times finer. |
Timeline.Track | function | One track of the arrangement: a row holding a header beside a lane. |
Timeline.TrackHeader | function | The strip beside a track's lane that names it and holds what sets it. |
Timeline.TrackResizeHandle | function | Sets the track's height: by dragging, or from the keyboard through the native <input type="range"> it holds, which carries the accessible name: the arrows move by a step (Down is taller), Page Up and Down by a large one, Home and End to the minimum and the maximum. |
Timeline.Viewport | function | The scrolling window onto the timeline. |
Anatomy
Import the primitive and assemble its parts.
import { Timeline } from "@audio-ui/react";
<Timeline.Root>
<Timeline.Viewport>
<Timeline.Ruler>
<Timeline.Mark value={0} />
<Timeline.Playhead />
</Timeline.Ruler>
<Timeline.Track>
<Timeline.TrackHeader>
<Timeline.TrackResizeHandle />
</Timeline.TrackHeader>
<Timeline.Lane />
</Timeline.Track>
<Timeline.Lane>
<Timeline.Range>
<Timeline.RangeHandle edge="start" />
<Timeline.RangeHandle edge="end" />
</Timeline.Range>
<Timeline.Clip>
<Timeline.ClipHeader />
<Timeline.ClipFade edge="in" />
<Timeline.ClipFade edge="out" />
<Timeline.ClipHandle edge="start" />
<Timeline.ClipHandle edge="end" />
<Timeline.ClipFadeHandle edge="in" />
<Timeline.ClipFadeHandle edge="out" />
</Timeline.Clip>
<Timeline.Playhead />
</Timeline.Lane>
</Timeline.Viewport>
<Timeline.Navigator>
<Timeline.NavigatorWindow />
<Timeline.NavigatorHandle edge="start" />
<Timeline.NavigatorHandle edge="end" />
</Timeline.Navigator>
</Timeline.Root>API reference
Root
Groups the parts of a timeline and owns what they share: its length, its zoom, its grid and the playback position. Units are yours: seconds, beats, pulses or steps. zoom is how many px one unit takes; leave it unset and the timeline fits the width it is given. The position comes from position, or from a live source that the playhead follows straight in the DOM without re-rendering React. With a snapStep, every gesture lands on the grid unless Cmd/Ctrl is held, and snapPoints (the edges of other clips, the locators) pull a dragged clip or range onto them from a few px away. Renders a <div> element.
Props · 17
steps.eventDetails.cancel() keeps the zoom where it was.duration.position.snapStep, or a hundredth of duration.Data attributes · 3
data-disableddata-fitteddata-scrubbingNavigator
The whole timeline as one bar, with the stretch the viewport shows drawn inside it as Timeline.NavigatorWindow: drag the window to scroll, drag one of its Timeline.NavigatorHandles to zoom, double-click to show everything. Place it anywhere inside Timeline.Root, outside the viewport. Renders a <div> element.
Props · 2
Data attributes · 3
data-disableddata-fitteddata-scrubbingThe styled TimelineNavigator sets minWindowWidth to 48.
NavigatorWindow
The stretch of the timeline the viewport shows. Dragging it scrolls; its native <input type="range"> scrolls from the keyboard and carries its accessible name. Renders a <div> element.
Data attributes · 3
data-disableddata-fitteddata-scrubbingNavigatorHandle
One edge of the window: dragging it zooms, holding the other edge in place. Its native <input type="range"> does the same from the keyboard and carries its accessible name. Renders a <div> element.
Props · 1
Data attributes · 3
data-disableddata-fitteddata-scrubbingViewport
The scrolling window onto the timeline. Cmd/Ctrl + wheel (and pinch on a trackpad) zooms around the pointer; a bare wheel scrolls as usual. Every zoom change keeps its anchor point in place, or the middle of the view when there is none. A clip moved or trimmed with the pointer held near its edges scrolls it. It reports its scroll offset and width for Timeline.Navigator. Renders a <div> element.
Data attributes · 3
data-disableddata-fitteddata-scrubbingLane
A strip along the timeline that its parts are placed on: a track, the ruler's strip, a row of markers. Zoomed, it is as long as the timeline; fitted, it takes the width it is given and the timeline is spread across it. Its --timeline-unit CSS variable is the width of one unit. With seekable, a press on its bare area moves the position, as on the ruler, so the cursor can be put anywhere along a track; with onSelectionChange too, a drag from there selects a stretch of time instead of scrubbing. Renders a <div> element.
Props · 3
seekable, fires while a drag from the lane's bare area selects a stretch of time, as [start, end] in timeline units on the grid unless Cmd/Ctrl is held: from where the press put the position to the pointer. The drag then no longer scrubs. eventDetails.cancel() keeps the selection as it was.Data attributes · 3
data-disableddata-fitteddata-scrubbingTrack
One track of the arrangement: a row holding a header beside a lane. Renders a <div> element.
Props · 6
data-selected.undefined. eventDetails.cancel() refuses it.Data attributes · 2
data-selecteddata-resizingTrackHeader
The strip beside a track's lane that names it and holds what sets it. It stays at the left edge while the lane scrolls under it, at the stacking level of the --timeline-track-header-z CSS variable (20): raise it while the header is hovered or focused if it shows something that reaches into the next row, such as a value readout. It carries the track's data-selected and data-resizing. Renders a <div> element.
TrackResizeHandle
Sets the track's height: by dragging, or from the keyboard through the native <input type="range"> it holds, which carries the accessible name. The arrows move by a step (Down is taller), Page Up and Page Down by a large one, Home and End to the minimum and the maximum. Place it along the track's lower edge. A double-click clears the height, so the track shares the room again. Renders a <div> element.
Ruler
The lane that moves the position: a press jumps to the pointer and a drag scrubs, both on the grid unless Cmd/Ctrl is held; with Shift held the drag scrubs four times finer. With onSelectionChange, a drag that starts with Shift held selects a stretch instead, to loop. It holds the native <input type="range"> that takes focus, handles the keyboard and carries the accessible name (aria-label / aria-labelledby). Place Timeline.Marks in it for its labels. Renders a <div> element.
Props · 3
"bar 3, beat 2". Defaults to the number.[start, end] in timeline units on the grid unless Cmd/Ctrl is held: feed it to a Timeline.Range as a loop. A plain press and drag still move the position. eventDetails.cancel() keeps the selection as it was.Data attributes · 3
data-disableddata-fitteddata-scrubbingMark
Something placed at value on a lane: a bar number on the ruler, a cue, a grid line. Its children are its label. With onValueChange or onValueCommitted it moves: a drag takes it along the lane, on the grid unless Cmd/Ctrl is held, landing on a snapPoints place within a few px, and Left and Right on something focused inside it move it by step. A press that stays one keeps its click; a drag does not click.
Props · 4
onValueCommitted, the mark can be moved.step.Data attributes · 1
data-draggingRange
A stretch of the timeline, such as a loop, a selection or a clip, laid on the lane it sits in from value[0] to value[1]. Dragging its body moves it, on the grid unless Cmd/Ctrl is held; add a Timeline.RangeHandle per edge to resize it. With drawable, dragging across empty lane draws a new range. Its own native <input type="range"> moves it from the keyboard and carries its accessible name (aria-label / aria-labelledby): Left and Right by a step, Up and Down by its own length, and with Cmd/Ctrl, Left and Right shorten or lengthen it by a step while Up and Down double or halve it. A drag lands an edge on a snapPoints place within a few px. Renders a <div> element.
Props · 10
[start, end] in the timeline's units.Data attributes · 2
data-disableddata-draggingRangeHandle
Resizes one edge of the range: by dragging, on the grid unless Cmd/Ctrl is held, or from the keyboard through the native <input type="range"> it holds, which carries the accessible name. Renders a <div> element.
Props · 1
Data attributes · 2
data-disableddata-draggingClip
A stretch of a source laid on a lane. Dragging its Timeline.ClipHeader moves it, on the grid unless Cmd/Ctrl is held, and over other lanes too, or to the nearest when the pointer is off them; held near an edge of the view, a move or a trim scrolls it, and a move scrolls down to the lanes below too; pressing its body selects it and puts the cursor there. Add a Timeline.ClipHandle per edge to trim it and a Timeline.ClipFadeHandle per fade. It sets --clip-offset, --clip-source-length, --clip-fade-in and --clip-fade-out for its content, and --clip-fade-in-max and --clip-fade-out-max, how long each fade can grow, to draw the limit of a fade being dragged (data-fading), and --clip-unit, the width of one unit for what is placed inside it. Its own native <input type="range"> moves it from the keyboard and carries its accessible name (aria-label / aria-labelledby); Delete and Backspace on it call onRemove. Renders a <div> element.
Props · 14
{ start, length, offset, fadeIn, fadeOut }, all in the timeline's units.selected is not set.additive), which eventDetails.event carries.Data attributes · 4
data-disableddata-draggingdata-fading"in" or "out": the fade a pointer is dragging.data-selectedClipHeader
The clip's title bar: dragging it moves the clip, on the grid unless Cmd/Ctrl is held, and over other lanes too. The rest of the clip is its body, where a press puts the cursor. Place it along the clip's top and put the clip's name in it. Renders a <div> element.
Data attributes · 3
data-disableddata-draggingdata-selectedClipHandle
Trims one edge of the clip: by dragging, on the grid unless Cmd/Ctrl is held, or from the keyboard through the native <input type="range"> it holds, which carries the accessible name. Trimming the start moves where in the source the clip begins and leaves its content where it is; trimming the end stops where the source or the timeline does. Renders a <div> element.
Props · 1
ClipFadeHandle
Sets how long one of the clip's fades lasts: by dragging, or from the keyboard through the native <input type="range"> it holds, which carries the accessible name. Double-clicking it, or pressing Enter on its input, steps the fade through its shapes, and Delete or Backspace takes the fade away. It sits where its fade ends, at the clip's top edge. The two fades cannot overlap. Renders a <div> element.
Props · 1
ClipFade
Draws a fade over the clip's content, as a DAW does: the ramp as a line from the clip's edge, as long as the fade, with what it attenuates lightly shaded. It is hidden while its fade is empty and ignores the pointer. Its color is the color it is given. Renders an <svg> element.
Props · 1
Playhead
A marker at the playback position, on the lane it sits in. It follows the position straight in the DOM, through its own --timeline-offset CSS variable, so a playhead moving every frame never re-renders React. Renders a <div> element.
Data attributes · 3
data-disableddata-fitteddata-scrubbingMark
Something placed at value on a lane: a bar number on the ruler, a cue, a grid line. Its children are its label. Renders a <div> element.
Props · 1
Data attributes · 3
data-disableddata-fitteddata-scrubbingStyled
The registry's styled Arrangement, its usage and interaction: Arrangement.