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.
npm install @miraiclip/core @miraiclip/renderer @miraiclip/editor @miraiclip/reactRequires @miraiclip/react 0.2.0 or later.
The components
| Component | What it does | Page |
|---|---|---|
<Timeline.*> | Ruler, tracks and lanes with clip move and trim, snapping, virtualised lanes, a compositor-driven playhead | Timeline |
<Preview> | The preview canvas, sized to fit or fixed, with overlays on top | Preview |
<Scrubber.*> | An accessible seek bar for the whole composition | Scrubber |
<Waveform> | Waveform bars for a media range, plus useWaveformPeaks | Waveform |
<TransformBox.*> | Move, scale and rotate the selected clip on the preview | Transform 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:
| Way | Example | Use it for |
|---|---|---|
| Data attributes | data-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 |
| Hooks | useTimelineClip(), 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.