React
Use @editframe/react for TypeScript-typed compositions with React component syntax.
Install
npm install @editframe/react
Components
All elements are available as React components:
import { Timegroup, Video, Audio, Image, Text, Captions, Surface, Waveform } from "@editframe/react";
React props use camelCase where the HTML attribute uses a hyphen or has a different name:
| HTML attribute | React prop |
|---|---|
sourcein | sourceIn |
sourceout | sourceOut |
trimstart | trimStart |
trimend | trimEnd |
mute | muted |
fft-size | fftSize |
bar-spacing | barSpacing |
line-width | lineWidth |
target (waveform) | for |
captions-src | src |
captions-script | captionsScript |
All other attributes have the same name in both HTML and React.
Basic example
import { Timegroup, Text } from "@editframe/react";
export default function Composition() {
return (
<Timegroup
duration="5s"
className="w-[1920px] h-[1080px] bg-black flex items-center justify-center"
>
<Text className="text-white text-8xl font-bold">Hello from React</Text>
</Timegroup>
);
}
Sequence with video and text
import { Timegroup, Video, Text } from "@editframe/react";
export default function Composition() {
return (
<Timegroup mode="sequence" className="w-[1920px] h-[1080px] bg-black">
<Timegroup mode="fixed" duration="5s" className="absolute w-full h-full">
<Video
src="https://assets.editframe.com/bg.mp4"
sourceIn="2s"
sourceOut="7s"
className="size-full"
style={{ objectFit: "cover" }}
/>
<Text className="absolute inset-0 flex items-center justify-center text-white text-7xl font-bold">
Scene One
</Text>
</Timegroup>
<Timegroup mode="fixed" duration="8s" className="absolute w-full h-full">
<Video
src="https://assets.editframe.com/bars-n-tone.mp4"
className="size-full"
style={{ objectFit: "cover" }}
/>
</Timegroup>
</Timegroup>
);
}
useTimingInfo
useTimingInfo() returns the current playback time for a Timegroup. Use it for time-reactive animations.
import { Timegroup, Text, useTimingInfo } from "@editframe/react";
function AnimatedHeadline() {
const { ownCurrentTimeMs, durationMs, percentComplete, ref } = useTimingInfo();
return (
<Timegroup
ref={ref}
duration="3s"
className="w-[1920px] h-[1080px] bg-black flex items-center justify-center"
>
<Text
className="text-white text-8xl font-bold"
style={{ opacity: percentComplete }}
>
Fades In
</Text>
</Timegroup>
);
}
The hook creates a ref internally and returns it. Pass it to the <Timegroup> you want to observe:
| Field | Type | Description |
|---|---|---|
ref | RefObject<EFTimegroup> | Pass to <Timegroup ref={ref}> |
ownCurrentTimeMs | number | ms since this group's start |
durationMs | number | Total duration in ms |
percentComplete | number | 0–1 progress |
Data-driven compositions
import { Timegroup, Text } from "@editframe/react";
const slides = [
{ text: "Slide One", bg: "bg-indigo-900" },
{ text: "Slide Two", bg: "bg-purple-900" },
{ text: "Slide Three", bg: "bg-rose-900" },
];
export default function Composition() {
return (
<Timegroup mode="sequence" className="w-[1920px] h-[1080px]">
{slides.map((slide) => (
<Timegroup
key={slide.text}
duration="3s"
className={`w-full h-full flex items-center justify-center ${slide.bg}`}
>
<Text className="text-white text-7xl font-bold">{slide.text}</Text>
</Timegroup>
))}
</Timegroup>
);
}
Compositions render in a headless browser — SSR concerns (hydration,
window access) don't apply.