Miraiclip SDK
API reference

@miraiclip/react

React bindings for Miraiclip: providers, state hooks, playback, timeline behaviour hooks, and unstyled editor components.

npm install @miraiclip/react
Version0.2.0
Runs inBrowser, React 18 or 19
Exports72
GuidesReact, Components

Functions

isEditableTarget

True for inputs, text areas, selects and contenteditable: keys there belong to the field.

function isEditableTarget(target: EventTarget | null): boolean

PlaybackProvider

Playback and preview for the project above it: a preview controller (renderer, player, fallback clock, monitoring volume) exposed as React state. Transport state comes from player events, so it never drifts from what the player is doing.

function PlaybackProvider({ options, volumeStorageKey, children }: PlaybackProviderProps): react.JSX.Element

Guides: Preview & playback, Overview, Preview, Timeline

ProjectProvider

Provides one Miraiclip project to everything below it. Pass init (and optionally seed) to have the provider create the project once for its lifetime, or project to share one you created.

function ProjectProvider(props: ProjectProviderProps): react.JSX.Element

Guides: Overview, Timeline, Installation, React

ProjectSessionProvider

A <ProjectProvider> whose project can be swapped at runtime (Open / New). Loading remounts everything below it, so engine, renderer and UI all re-initialize cleanly from the loaded state.

function ProjectSessionProvider({ initial, children }: {
    initial: SessionInit;
    children: ReactNode;
}): react.JSX.Element

Guides: React

rulerStepUs

Smallest "nice" tick step that keeps ticks at least minGapPx apart.

function rulerStepUs(pxPerSecond: number, minGapPx?: number): Us

Guides: Timeline, React

shallowEqual

Shallow equality for arrays and objects of primitives — for list selectors.

function shallowEqual<T>(a: T, b: T): boolean

Guides: React

useClip

function useClip(clipId: string | null | undefined): Clip | undefined

Guides: React

useClipCount

How many clips a track has.

function useClipCount(trackId: string): number

Guides: React

useClips

A track's clips, sorted by start time.

function useClips(trackId: string): Clip[]

Guides: Reading state, Installation, React

useCommands

Typed command builders bound to the current project. Stable across renders.

function useCommands(): Commands

Guides: Blocks, React

useCompositorPlayhead

Moves a playhead-driven element without per-frame style recalcs.

While playing, the element runs a linear Web Animations transform from the playhead to the end, so the browser's compositor moves it with no main- thread work. The store's playhead only re-syncs it: the animation restarts when the real playhead drifts more than toleranceUs from its prediction (seek, loop, buffering stall). Paused, it gets a static transform.

toTransform maps a time to a CSS transform; list what it depends on in deps.

function useCompositorPlayhead(ref: RefObject<HTMLElement | null>, toTransform: (us: Us, durationUs: Us) => string, deps: readonly unknown[], toleranceUs?: number): void

Guides: Timeline, React

useDurationUs

Composition length: the end of the last clip. Recomputed only on edits.

function useDurationUs(): Us

Guides: React

useEditorShortcuts

Binds the default editor keys (see matchEditorShortcut) on window, limited to actions. Keys typed into text fields are left alone.

function useEditorShortcuts(actions?: readonly EditorAction[]): void

Guides: Selection & canvas editing, Blocks, Timeline, React

useGesture

Start a live edit that lands in history as one entry (see beginGesture).

function useGesture(): (label: string) => Gesture

Guides: Blocks, React

useHistoryState

function useHistoryState(): {
    canUndo: boolean;
    canRedo: boolean;
}

Deprecated

Use useUndoRedo.

usePlayback

Transport, preview and volume from the nearest <PlaybackProvider>.

function usePlayback(): PlaybackValue

Guides: Preview, Installation, React

usePlayheadFollow

Keeps the playhead findable: while playing, pages the timeline so the playhead stays in view (pausing for 1.5 s after the user scrolls by hand), and reports when it is off screen, for an edge indicator.

function usePlayheadFollow(scrollRef: RefObject<HTMLElement | null>, pxPerSecond: number, headerWidthPx?: number): PlayheadFollow

Guides: React

usePlayheadRef

The playhead in a ref that updates without re-rendering. Pass onChange to write to the DOM directly on each change (e.g. a time label's textContent).

function usePlayheadRef(onChange?: (us: Us) => void): MutableRefObject<Us>

Guides: React

usePlayheadUs

Playhead position in µs. Re-renders on every played frame (60×/s), so use it only in small components; usePlayheadRef reads it without re-rendering.

function usePlayheadUs(): Us

Guides: Reading state, Scrubber, React

usePreview

Size and status of the enclosing <Preview>, for overlays.

function usePreview(): PreviewState

Guides: Overview, Preview, React

useProject

The project from the nearest <ProjectProvider>.

function useProject(): Project

Guides: React

useProjectSession

Open / New for the nearest <ProjectSessionProvider>.

function useProjectSession(): ProjectSession

Guides: React

useProjectState

Subscribe to a slice of project state. Re-renders only when the selected value changes (per isEqual, default Object.is). Every other state hook builds on this one; narrow selectors keep a busy timeline cheap.

function useProjectState<T>(selector: (state: ProjectState) => T, isEqual?: (a: T, b: T) => boolean): T

Guides: Reading state, Scrubber, React

useSelectedClip

The selected clip when exactly one is selected.

function useSelectedClip(): Clip | undefined

Guides: Blocks, React

useSelection

Selected clip ids.

function useSelection(): string[]

Guides: Reading state, Preview, React

useSettings

Project settings (size, frame rate, name).

function useSettings(): ProjectSettings

Guides: React

useTimeline

The timeline's scale, layout and drag entry point. Use inside <Timeline.Root>.

function useTimeline(): TimelineContextValue

Guides: Timeline, React

useTimelineClip

State of the enclosing <Timeline.Clip>, live while it is dragged.

function useTimelineClip(): TimelineClipState

Guides: Overview, Timeline, Waveform, React

useTimelineDrag

The clip being dragged, as it would land now; null when no drag is in progress.

function useTimelineDrag(): ClipDragPreview | null

Guides: Timeline, React

useTimelineRange

The time range the viewport shows (plus a margin), for virtualising custom rows.

function useTimelineRange(): {
    fromUs: Us;
    toUs: Us;
}

Guides: Timeline, React

useTimelineTrack

The track of the enclosing <Timeline.Track>.

function useTimelineTrack(): Track

Guides: Timeline, React

useTimelineZoom

Ctrl/⌘ + wheel zooms the timeline around the pointer; plain wheel keeps scrolling.

function useTimelineZoom(scrollRef: RefObject<HTMLElement | null>, options: TimelineZoomOptions): void

Guides: Timeline, React

useTrack

function useTrack(trackId: string): Track | undefined

Guides: React

useTrackOrder

Track ids in render order (index 0 = bottom layer).

function useTrackOrder(): string[]

Guides: React

useTracks

All tracks, in render order.

function useTracks(): Track[]

Guides: React

useTransformBox

State of the enclosing <TransformBox.Root>, for custom handles and drawing.

function useTransformBox(): TransformBoxState

Guides: Overview, Transform box, React

useTransitions

A track's transitions.

function useTransitions(trackId: string): Transition[]

Guides: React

useUndoRedo

Undo and redo, with live availability for the buttons.

function useUndoRedo(): UndoRedo

Guides: React

useVisibleRange

The time range a scrolling timeline should render (see visibleRange in

function useVisibleRange(scrollRef: RefObject<HTMLElement | null>, pxPerSecond: number, headerWidthPx?: number): {
    fromUs: Us;
    toUs: Us;
}

Guides: Timeline, React

useWaveformPeaks

Waveform peaks for an audio or video asset, or null while computing (and when it has no audio). Computed once per asset src with a streamed decode, shared by every component that asks, one asset at a time.

function useWaveformPeaks(asset: Asset | undefined): WaveformPeaks | null

Guides: Timeline, Overview, Waveform, React

Constants

Preview

The preview canvas, wired to <PlaybackProvider>: hands its <canvas> to the renderer on mount, keeps the render target matched to its size, and releases it on unmount. The element is position: relative and exactly the canvas's size, so overlays can use position: absolute; inset: 0. data-mode carries the playback mode; data-error is set after a render error.

const Preview: react.ForwardRefExoticComponent<PreviewProps & react.RefAttributes<HTMLDivElement>>

Guides: Preview & playback, Overview, Preview, Transform box

Scrubber

Unstyled seek bar parts: <Scrubber.Root> with <Scrubber.Range> and <Scrubber.Thumb> inside.

const Scrubber: {
    Root: react.ForwardRefExoticComponent<ScrubberRootProps & react.RefAttributes<HTMLDivElement>>;
    Range: react.ForwardRefExoticComponent<Omit<HTMLAttributes<HTMLDivElement>, "children"> & {
        children?: ReactNode;
    } & react.RefAttributes<HTMLDivElement>>;
    Thumb: react.ForwardRefExoticComponent<Omit<HTMLAttributes<HTMLDivElement>, "children"> & {
        children?: ReactNode;
    } & react.RefAttributes<HTMLDivElement>>;
}

Guides: Overview, Preview, Scrubber, React

Timeline

Unstyled timeline parts. See the module comment for the structure.

const Timeline: {
    Root: react.ForwardRefExoticComponent<TimelineRootProps & react.RefAttributes<HTMLDivElement>>;
    Viewport: react.ForwardRefExoticComponent<TimelineViewportProps & react.RefAttributes<HTMLDivElement>>;
    Ruler: react.ForwardRefExoticComponent<TimelineRulerProps & react.RefAttributes<HTMLDivElement>>;
    Track: react.ForwardRefExoticComponent<TimelineTrackProps & react.RefAttributes<HTMLDivElement>>;
    TrackHeader: react.ForwardRefExoticComponent<DivProps & {
        children?: ReactNode;
    } & react.RefAttributes<HTMLDivElement>>;
    Lane: react.ForwardRefExoticComponent<Time …

Guides: Timeline, Overview, Scrubber, Timeline

TransformBox

Unstyled transform-box parts for the preview. See the module comment for the structure.

const TransformBox: {
    Root: react.ForwardRefExoticComponent<TransformBoxRootProps & react.RefAttributes<HTMLDivElement>>;
    Outline: typeof Outline;
    Guides: typeof Guides;
    Body: typeof Body;
    Handle: react.ForwardRefExoticComponent<Omit<HTMLAttributes<HTMLDivElement>, "children"> & {
        children?: ReactNode;
    } & {
        corner: 0 | 1 | 2 | 3;
    } & react.RefAttributes<HTMLDivElement>>;
    RotateHandle: react.ForwardRefExoticComponent<Omit<HTMLAttributes<HTMLDivElement>, "children"> & {
        children?: ReactNode;
    } & {
        distance?: number;
    } & react.RefAttributes<HTM …

Guides: Selection & canvas editing, Overview, Preview, Transform box

Waveform

Mirrored waveform bars for a media range, filling the canvas's CSS box. Bars use currentColor, so the text color styles them. Redraws on resize and when its inputs change; the backing store is capped so very wide clips at high zoom stay within mobile memory limits.

const Waveform: react.ForwardRefExoticComponent<WaveformProps & react.RefAttributes<HTMLCanvasElement>>

Guides: Timeline, Overview, Timeline, Waveform

Interfaces

PlaybackProviderProps

MemberTypeDescription
options?PreviewControllerOptionsRenderer and player options. Read when the provider mounts.
volumeStorageKey?stringRemember the monitoring volume in localStorage under this key (off by default).
childrenReactNode

PlaybackValue

MemberTypeDescription
isPlayingboolean
modePreviewMode
lastErrorstring | null
play() => void
pause() => void
toggle() => void
seek(us: Us) => void
attachCanvas(canvas: HTMLCanvasElement, size: { width: number; height: number; }) => voidHand the preview <canvas> to the renderer (once it is in the DOM). size is its CSS size.
resizePreview(width: number, height: number) => voidThe preview's CSS size changed.
detachCanvas() => void
getClipBounds(clipId: string) => ClipBounds | nullWhere a clip is drawn now, in composition px (null when not drawn or not live).
hitTest(xPx: number, yPx: number, filter?: (clip: Clip) => boolean) => string | nullTopmost clip at a composition-px point (null when none or not live).
volumenumberMonitoring volume, 0..1 (never written to the project or exports).
mutedboolean
setVolume(volume: number) => void
toggleMute() => void
controllerPreviewControllerThe framework-free controller underneath, for anything not covered here.

PlayheadFollow

MemberTypeDescription
side"left" | "right" | nullWhich side the playhead is scrolled off, or null when visible.
usUsPlayhead time when it went off screen (refreshed every 0.5 s while off).
reveal() => voidScroll the playhead back into view.

Guides: Timeline, React

PreviewProps

Extends Omit<HTMLAttributes<HTMLDivElement>, "children">.

MemberTypeDescription
width?numberCSS size of the canvas. Give both for a fixed size; leave both out to fit the composition's aspect inside the parent element (measured live).
height?number
fitPadding?numberFit mode only: space kept free around the preview inside the parent, px (default 0).
canvasProps?CanvasHTMLAttributes<HTMLCanvasElement>Props for the <canvas>.
children?RenderChildren<PreviewState>Drawn over the canvas (selection boxes, messages). A function receives the preview's state.

PreviewState

MemberTypeDescription
widthnumberCSS size of the canvas, px.
heightnumber
scalenumberScreen px per composition px.
modePreviewMode"live" (renderer drawing), "fallback" (clock only) or "unsupported" (no WebCodecs).
lastErrorstring | null

ProjectSession

MemberTypeDescription
loadDocument(doc: ProjectDocument) => voidReplace the current composition with a serialized document (Open).
newProject() => voidStart over from the initial project (New).

Guides: MCP server

RulerTick

MemberTypeDescription
usUs
xnumberOffset from the ruler's left edge, px.
labelstringformatClock(us).

ScrubberRootProps

Extends DivProps.

MemberTypeDescription
stepUs?UsArrow-key step (default 1 s).
largeStepUs?UsPage Up / Page Down and Shift + arrow step (default 5 s).

SessionInit

MemberTypeDescription
initProjectSettings | ProjectDocument
seed?(project: Project) => void

TimelineClipProps

Extends DivProps.

MemberTypeDescription
clipClip
insetPx?numberPixels taken off the left edge (a gap between neighbouring clips; default 0).
minWidthPx?numberNarrowest drawn width, px (default 2).
children?RenderChildren<TimelineClipState>

TimelineClipState

MemberTypeDescription
clipClip
startUsUsLive position: the drag preview while this clip is dragged, else the clip's own.
durationUsUs
trimStartUsUsMedia in-point, live while trimming the start (0 for clips without media).
selectedboolean
draggingClipDragMode | nullWhat the current drag does to this clip, or null.
lockedbooleanOn a locked track: selectable, not draggable.

TimelineContextValue

MemberTypeDescription
pxPerSecondnumber
headerWidthnumberWidth of the sticky header column inside the viewport, in px.
lengthUsUsScrollable length of the timeline.
viewportRefRefObject<HTMLDivElement | null>The scroll container (set by <Timeline.Viewport>).
usAtClientX(clientX: number) => UsTimeline time under a viewport x (clamped at 0).
beginClipDrag(event: PointerEvent, clip: Clip, mode: ClipDragMode) => voidStart dragging a clip from a pointer event (what <Timeline.Clip> and <Timeline.TrimHandle> call).

TimelineCut

Extends TrackCut.

MemberTypeDescription
xnumberOffset of the cut from the lane's left edge, px.

TimelineCutsProps

MemberTypeDescription
children(cut: TimelineCut) => ReactNodeRender one cut. Only cuts in the visible range are passed.
hideWhileDragging?booleanHide cut markers while a clip is dragged (default true).

TimelineLaneProps

Extends DivProps.

MemberTypeDescription
children(clip: Clip) => ReactNodeRender one clip (usually a <Timeline.Clip>). Called only for clips in the visible range, plus a dragged clip.
deselectOnClick?booleanClicking the empty lane clears the selection (default true).
overlay?ReactNodeExtra content after the clips (cut markers, drop indicators).

TimelineRootProps

Extends DivProps.

MemberTypeDescription
pxPerSecondnumberZoom: horizontal pixels per second.
onPxPerSecondChange?(pxPerSecond: number) => voidCalled by Ctrl/⌘ + wheel zoom (around the pointer). Leave out to disable wheel zoom.
minPxPerSecond?number
maxPxPerSecond?number
headerWidth?numberWidth of a sticky header column at the left of the viewport (default 0).
lengthUs?UsScrollable length. Default: the composition plus 5 s, at least 10 s.
snapPx?numberClip edges snap within this many pixels (default 8; 0 turns snapping off).
children?ReactNode

TimelineRulerProps

Extends DivProps.

MemberTypeDescription
stepUs?Us | ((pxPerSecond: number) => Us)Tick spacing: a fixed step, or one picked from the zoom. Default: the smallest step at least 60 px apart.
renderTick?(tick: RulerTick) => ReactNodeRender one tick. Default: an absolutely placed <span data-tick> with the clock label.
children?ReactNodeExtra content after the ticks (a <Timeline.Playhead> knob, markers).

TimelineTrackProps

Extends DivProps.

MemberTypeDescription
trackTrack
children?ReactNode

TimelineTrimHandleProps

Extends DivProps.

MemberTypeDescription
side"start" | "end"Which edge it trims.
children?ReactNode

TimelineViewportProps

Extends DivProps.

MemberTypeDescription
contentProps?DivPropsProps for the inner element sized to the timeline's length.
children?ReactNode

TimelineZoomOptions

MemberTypeDescription
pxPerSecondnumber
setPxPerSecond(pxPerSecond: number) => void
minPxPerSecondnumber
maxPxPerSecondnumber
headerWidthPx?numberSticky header column width inside the scroll container.
enabled?booleanSet false to leave Ctrl/⌘ + wheel to the browser (default true).

TransformBoxOutlineProps

Extends SVGProps<SVGPolygonElement>.

MemberTypeDescription
target?"selection" | "hover"The selected clip (default) or the clip under the pointer.

TransformBoxRootProps

Extends Omit<HTMLAttributes<HTMLDivElement>, "children">.

MemberTypeDescription
snapPx?numberMove snapping to the frame's edges and center, in screen px (default 6; 0 turns it off). Alt places freely.
dragThresholdPx?numberMovement below this many screen px is a click (default 2).
nudge?booleanArrow keys nudge the selection 1 px (Shift: 10 px) (default true).
canSelect?(clip: Clip) => booleanWhich clips a click can pick. Default: visual clips on unlocked tracks.
onClipDoubleClick?(clipId: string) => voidDouble-click on a clip (e.g. open its text editor).
children?ReactNode

TransformBoxState

MemberTypeDescription
boxClipBounds | nullThe selected clip's bounds (composition px), when one visual clip is selected and drawn.
hoverClipBounds | nullThe clip under the pointer, when it isn't the selection.
guidesTransformGuidesFrame lines the current move snapped to (composition px).
editablebooleanTrue when the selected clip can be edited (visual, track not locked).
draggingTransformDragMode | nullThe drag in progress, if any.
scalenumberScreen px per composition px.
widthnumber
heightnumber
startDrag(event: PointerEvent, mode: TransformDragMode) => voidStart a drag on the selected box (what the handles call).

UndoRedo

MemberTypeDescription
canUndoboolean
canRedoboolean
undo() => boolean
redo() => boolean

WaveformProps

Extends Omit<CanvasHTMLAttributes<HTMLCanvasElement>, "children">.

MemberTypeDescription
peaksWaveformPeaksPeaks for the whole asset (from useWaveformPeaks or the renderer's computeWaveformPeaks).
fromUsUsMedia range to draw (for a clip: its trim start to trim start + duration).
toUsUs
gain?numberLinear gain applied before drawing, so volume changes show (default 1).
barWidth?numberBar width and gap, CSS px (default 2 and 1).
barGap?number
floorDb?numberQuietest level drawn, dB (default −60). Heights use a decibel scale so quiet material stays visible.
maxCanvasPx?numberLongest side of the canvas backing store, device px (default 4096).

Types

ProjectProviderProps

type ProjectProviderProps = {
    init: ProjectSettings | ProjectDocument;
    seed?: (project: Project) => void;
    project?: never;
    children: ReactNode;
} | {
    project: Project;
    init?: never;
    seed?: never;
    children: ReactNode;
};

On this page