Miraiclip SDK
React components

Overview

Unstyled React components that carry an editor's behaviour and leave the look to you.

@miraiclip/react ships the interactive parts of an editor as unstyled components: a timeline, the preview, a seek bar, waveforms and on-canvas transform handles. They handle pointer input, snapping, undo steps, virtualisation and the playhead. You write the markup around them and the CSS.

Loading demo…
Drag clips on the timeline or on the preview; trim the selected clip from its edges; Ctrl/⌘ + wheel over the timeline zooms.
npm install @miraiclip/core @miraiclip/renderer @miraiclip/editor @miraiclip/react

Requires @miraiclip/react 0.2.0 or later.

The components

ComponentWhat it doesPage
<Timeline.*>Ruler, tracks and lanes with clip move and trim, snapping, virtualised lanes, a compositor-driven playheadTimeline
<Preview>The preview canvas, sized to fit or fixed, with overlays on topPreview
<Scrubber.*>An accessible seek bar for the whole compositionScrubber
<Waveform>Waveform bars for a media range, plus useWaveformPeaksWaveform
<TransformBox.*>Move, scale and rotate the selected clip on the previewTransform box

They read the project and playback from context, so render them inside ProjectProvider and PlaybackProvider (see React). <Waveform> is the exception: it only needs its props.

import { PlaybackProvider, Preview, ProjectProvider, Timeline } from "@miraiclip/react";

export function App() {
  return (
    <ProjectProvider init={{ width: 1920, height: 1080, fps: 30 }}>
      <PlaybackProvider>
        <Preview width={640} height={360} />
        <Timeline.Root pxPerSecond={60}>{/* … */}</Timeline.Root>
      </PlaybackProvider>
    </ProjectProvider>
  );
}

Styling

The components render plain elements with no class names and only the inline styles their behaviour needs (positions, sizes, touch-action). Their state is exposed in three ways:

WayExampleUse it for
Data attributesdata-selected, data-dragging="move", data-locked, data-drop-target, data-mode="live"Styles. A flag attribute is present (empty) when true and absent when false
Render props<Timeline.Lane>{(clip) => …}</Timeline.Lane>, <Preview>{({ mode }) => …}</Preview>Choosing what to render
HooksuseTimelineClip(), usePreview(), useTransformBox()State deep inside a part, without passing props

Every part forwards className, style, event handlers and ref to its element, so Tailwind's data-attribute variants work directly:

<Timeline.Clip
  clip={clip}
  className="rounded-md bg-sky-400/15 data-[selected]:ring-2 data-[selected]:ring-sky-400 data-[dragging]:shadow-lg"
/>

Plain CSS works the same way:

[data-timeline-clip] { border-radius: 6px; background: rgb(56 189 248 / 0.15); }
[data-timeline-clip][data-selected] { outline: 2px solid rgb(56 189 248); }
[data-timeline-clip][data-dragging] { z-index: 10; }

Each part also carries its own marker attribute (data-timeline-clip, data-preview, data-scrubber, …), so you can target it from a stylesheet. If you pass your own onPointerDown or onClick and call event.preventDefault(), the part skips its own handling for that event.

Components and the Editor UI kit

The components ship in @miraiclip/react with the rest of the SDK, under the same license. The Editor UI kit is a separate purchase: the complete styled editor, with panels, themes, templates and the AI assistant. Its timeline and stage are built on these components, styled with Tailwind, so its source is a full worked example.

Other frameworks

The components are React-only for now. Their logic lives in @miraiclip/editor (clip drag, transform drag, cuts, timeline geometry) and the renderer's preview controller, so Vue and Svelte versions will be thin wrappers over the same code. Until then, use those packages directly; the Build an editor guides show how.

On this page