@pixerate/editor-react 0.48.0 → 0.50.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/video-editor/useVideoEditor.ts","../../src/video-editor/VideoPreview.tsx","../../src/video-editor/VideoTransport.tsx","../../src/video-editor/VideoTimeline.tsx","../../src/video-editor/ClipInspector.tsx","../../src/video-editor/MediaBin.tsx","../../src/video-editor/VideoEditor.tsx"],"sourcesContent":["import { useEffect, useMemo, useRef, useSyncExternalStore } from 'react';\nimport {\n VideoEditorController,\n createVideoEditorToolProvider,\n type VideoEditResult,\n type VideoEditorOptions,\n type VideoEditorState,\n type VideoEditorToolProviderOptions,\n} from '@pixerate/editor/video-editor';\nimport type { ToolRegistry } from '@pixerate/editor/tools';\n\n/** A `VideoEditorController` created once for the component's lifetime (destroyed on unmount). */\nexport function useVideoEditorController(options: VideoEditorOptions = {}): VideoEditorController {\n const ref = useRef<VideoEditorController | null>(null);\n if (!ref.current) ref.current = new VideoEditorController(options);\n const controller = ref.current;\n useEffect(() => () => controller.destroy(), [controller]);\n return controller;\n}\n\n/** The controller's state (re-renders on every change, including each played frame). */\nexport function useVideoEditorState(controller: VideoEditorController): VideoEditorState {\n return useSyncExternalStore(controller.subscribe, controller.getState, controller.getState);\n}\n\nexport interface UseVideoEditorResult {\n controller: VideoEditorController;\n state: VideoEditorState;\n play: () => void;\n pause: () => void;\n toggle: () => void;\n /** Moves the playhead (ms). */\n seek: (time: number) => void;\n /** Moves the playhead by whole frames (negative steps back), pausing. */\n step: (frames: number) => void;\n undo: () => void;\n redo: () => void;\n /** Splits the selected clips (or every clip) under the playhead, as one undo step. */\n splitAtPlayhead: () => VideoEditResult;\n /** Deletes the selected clips; `ripple` closes the gaps they leave. */\n deleteSelection: (options?: { ripple?: boolean }) => VideoEditResult;\n}\n\n/**\n * Subscribes to a video editor controller and exposes its state with bound actions.\n * Pass options instead of a controller to create one for the component's lifetime.\n */\nexport function useVideoEditor(controllerOrOptions: VideoEditorController | VideoEditorOptions = {}): UseVideoEditorResult {\n const own = useRef<VideoEditorController | null>(null);\n let controller: VideoEditorController;\n if (controllerOrOptions instanceof VideoEditorController) controller = controllerOrOptions;\n else {\n if (!own.current) own.current = new VideoEditorController(controllerOrOptions);\n controller = own.current;\n }\n useEffect(() => () => own.current?.destroy(), []);\n const state = useVideoEditorState(controller);\n const actions = useMemo(\n () => ({\n play: () => controller.play(),\n pause: () => controller.pause(),\n toggle: () => controller.toggle(),\n seek: (time: number) => controller.seek(time),\n step: (frames: number) => controller.step(frames),\n undo: () => void controller.undo(),\n redo: () => void controller.redo(),\n splitAtPlayhead: () => controller.splitAtPlayhead(),\n deleteSelection: (options?: { ripple?: boolean }) => controller.deleteSelection(options),\n }),\n [controller],\n );\n return { controller, state, ...actions };\n}\n\n/**\n * Registers the video editor's agent tools (`get_video_project`, `add_video_clip`,\n * `trim_video_clip`, …) in `registry` while mounted.\n */\nexport function useVideoEditorTools(\n registry: ToolRegistry | null | undefined,\n controller: VideoEditorController,\n options: VideoEditorToolProviderOptions = {},\n): void {\n const { id, namespace, readOnly, rasterize } = options;\n useEffect(() => {\n if (!registry) return;\n return registry.register(createVideoEditorToolProvider(controller, { id, namespace, readOnly, rasterize }));\n }, [registry, controller, id, namespace, readOnly, rasterize]);\n}\n","import React, { useEffect, useRef } from 'react';\nimport { VideoPreviewEngine, type VideoEditorController, type VideoPreviewOptions } from '@pixerate/editor/video-editor';\nimport { useVideoEditorState } from './useVideoEditor';\n\nexport interface VideoPreviewProps {\n controller: VideoEditorController;\n /** Canvas pixels per frame pixel (default: fits the displayed width at the device pixel ratio, at most 1). */\n resolution?: number;\n /** Called after each frame is drawn. */\n onFrame?: VideoPreviewOptions['onFrame'];\n className?: string;\n style?: React.CSSProperties;\n}\n\n/**\n * Plays the controller's project on a canvas the shape of its frame: a `VideoPreviewEngine` keeps\n * one `<video>` / `<audio>` element per playing clip in step with the playhead and draws each frame.\n * The engine is created when the canvas mounts and destroyed on unmount or when the controller changes.\n */\nexport function VideoPreview({ controller, resolution, onFrame, className = '', style }: VideoPreviewProps) {\n const { project } = useVideoEditorState(controller);\n const canvas = useRef<HTMLCanvasElement>(null);\n const frameRef = useRef(onFrame);\n frameRef.current = onFrame;\n useEffect(() => {\n const el = canvas.current;\n if (!el) return;\n const engine = new VideoPreviewEngine(controller, el, { resolution, onFrame: (frame) => frameRef.current?.(frame) });\n return () => engine.destroy();\n }, [controller, resolution]);\n return (\n <canvas\n ref={canvas}\n className={className}\n style={{ display: 'block', width: '100%', aspectRatio: `${project.width} / ${project.height}`, background: project.background ?? '#000', ...style }}\n role=\"img\"\n aria-label={`Preview of ${project.name ?? 'the video'}`}\n data-video-preview=\"\"\n />\n );\n}\n","import React from 'react';\nimport { formatVideoTimecode, type VideoEditorController } from '@pixerate/editor/video-editor';\nimport { useVideoEditorState } from './useVideoEditor';\n\nexport interface VideoTransportProps {\n controller: VideoEditorController;\n /** Show the editing buttons (split, delete, ripple delete, undo, redo; default true). */\n editable?: boolean;\n className?: string;\n}\n\nconst btn = 'rounded border border-border px-2 py-0.5 text-xs disabled:opacity-40';\n\n/**\n * Play / pause, a frame back and forward, the playhead and total length as timecode, and the\n * edits that work on the playhead and the selection: split, delete, ripple delete, undo and redo.\n */\nexport function VideoTransport({ controller, editable = true, className = '' }: VideoTransportProps) {\n const state = useVideoEditorState(controller);\n const { time, duration, playing, project, selection, readOnly } = state;\n const canEdit = editable && !readOnly;\n return (\n <div className={`flex flex-wrap items-center gap-1.5 text-xs ${className}`} data-video-transport=\"\">\n <button type=\"button\" className={btn} onClick={() => controller.step(-1)} aria-label=\"Previous frame\" title=\"Previous frame (←)\" data-step-back=\"\">\n ◀|\n </button>\n <button type=\"button\" className={btn} onClick={() => controller.toggle()} aria-label={playing ? 'Pause' : 'Play'} title=\"Play / pause (Space)\" disabled={duration <= 0} data-play=\"\">\n {playing ? 'Pause' : 'Play'}\n </button>\n <button type=\"button\" className={btn} onClick={() => controller.step(1)} aria-label=\"Next frame\" title=\"Next frame (→)\" data-step-forward=\"\">\n |▶\n </button>\n <span className=\"px-1 tabular-nums text-muted-foreground\" data-timecode=\"\">\n {formatVideoTimecode(time, project.fps)} / {formatVideoTimecode(duration, project.fps)}\n </span>\n {editable && (\n <>\n <span className=\"mx-1 h-4 w-px bg-border\" />\n <button type=\"button\" className={btn} onClick={() => controller.splitAtPlayhead()} disabled={!canEdit} title=\"Split at the playhead (S)\" data-split=\"\">\n Split\n </button>\n <button type=\"button\" className={btn} onClick={() => controller.deleteSelection()} disabled={!canEdit || !selection.length} title=\"Delete the selected clips (Delete)\" data-delete=\"\">\n Delete\n </button>\n <button\n type=\"button\"\n className={btn}\n onClick={() => controller.deleteSelection({ ripple: true })}\n disabled={!canEdit || !selection.length}\n title=\"Delete the selected clips and close the gaps (Shift+Delete)\"\n data-ripple-delete=\"\"\n >\n Ripple delete\n </button>\n <button type=\"button\" className={btn} onClick={() => controller.undo()} disabled={!canEdit || !state.canUndo} title={state.canUndo ? `Undo ${state.undoLabel}` : 'Nothing to undo'} data-undo=\"\">\n Undo\n </button>\n <button type=\"button\" className={btn} onClick={() => controller.redo()} disabled={!canEdit || !state.canRedo} title={state.canRedo ? `Redo ${state.redoLabel}` : 'Nothing to redo'} data-redo=\"\">\n Redo\n </button>\n </>\n )}\n </div>\n );\n}\n","import React, { useEffect, useRef, useState } from 'react';\nimport {\n planVideoClipDrag,\n videoAssetMap,\n videoClipLabel,\n videoClipTint,\n videoDropTracks,\n videoRulerTicks,\n formatVideoSeconds,\n type VideoClip,\n type VideoClipDragMode,\n type VideoClipDragPlan,\n type VideoEditorController,\n type VideoTrack,\n} from '@pixerate/editor/video-editor';\nimport { useVideoEditorState } from './useVideoEditor';\n\nexport interface VideoTimelineProps {\n controller: VideoEditorController;\n /** Zoom: pixels per second of timeline. With `onPxPerSecondChange` the host owns it; otherwise it is the starting zoom (default 100). */\n pxPerSecond?: number;\n /** Called when the zoom control changes. Without it the timeline keeps its own zoom and shows a zoom slider. */\n onPxPerSecondChange?: (pxPerSecond: number) => void;\n /** Allow selecting, dragging, trimming and the track toggles (default true). */\n editable?: boolean;\n className?: string;\n}\n\nconst HEADER = 150;\nconst RULER = 24;\nconst ROW = 44;\nconst HANDLE = 6;\nconst DRAG_THRESHOLD = 3;\nconst MIN_ZOOM = 10;\nconst MAX_ZOOM = 400;\n\ninterface Drag {\n clip: string;\n mode: VideoClipDragMode;\n x: number;\n pointer: number;\n moved: boolean;\n plan: VideoClipDragPlan | null;\n}\n\nconst isField = (el: EventTarget | null) => el instanceof HTMLElement && /^(INPUT|TEXTAREA|SELECT)$/.test(el.tagName);\n\n/**\n * The tracks of a `VideoEditorController` laid out in time: a ruler with markers (click or drag it\n * to scrub), a playhead, and one row per track with its toggles (mute, hide, lock) and its clips.\n * Click a clip to select it (Shift / Cmd to add or remove it), drag it to move it (onto another\n * track of the same kind too), drag an edge to trim it (Alt to ripple). Moves snap to clip edges,\n * markers, the playhead and frames. Every edit is one undo step; refused edits show why.\n *\n * Keyboard (when focused): Space plays, ←/→ step a frame, S splits at the playhead, Delete removes\n * the selection (Shift to ripple), Cmd/Ctrl+Z undoes, Shift+Cmd/Ctrl+Z redoes.\n */\nexport function VideoTimeline({ controller, pxPerSecond, onPxPerSecondChange, editable = true, className = '' }: VideoTimelineProps) {\n const state = useVideoEditorState(controller);\n const { project, duration, time, selection, readOnly, error } = state;\n const [ownZoom, setOwnZoom] = useState(pxPerSecond ?? 100);\n const px = onPxPerSecondChange ? (pxPerSecond ?? 100) : ownZoom;\n const canEdit = editable && !readOnly;\n const [drag, setDrag] = useState<Drag | null>(null);\n const dragRef = useRef<Drag | null>(null);\n const rows = useRef(new Map<string, HTMLDivElement>());\n const ruler = useRef<HTMLDivElement>(null);\n const assets = videoAssetMap(project);\n const msToPx = (ms: number) => (ms * px) / 1000;\n const span = Math.max(duration + 5000, 10000);\n const width = msToPx(span);\n const ticks = videoRulerTicks(span, px, project.fps);\n\n const seekAt = (clientX: number) => {\n const box = ruler.current!.getBoundingClientRect();\n controller.seek(Math.max(0, ((clientX - box.left) * 1000) / px));\n };\n\n const trackAt = (clipId: string, clientY: number): string | undefined => {\n const allowed = videoDropTracks(project, clipId);\n for (const [id, el] of rows.current) {\n const box = el.getBoundingClientRect();\n if (clientY >= box.top && clientY < box.bottom && allowed.includes(id)) return id;\n }\n return undefined;\n };\n\n const planFor = (d: Drag, e: { clientX: number; clientY: number; altKey: boolean }) =>\n planVideoClipDrag(project, {\n clip: d.clip,\n mode: d.mode,\n delta: ((e.clientX - d.x) * 1000) / px,\n track: d.mode === 'move' ? trackAt(d.clip, e.clientY) : undefined,\n ripple: e.altKey,\n snap: (t) => controller.snap(t, { exclude: [d.clip] }).time,\n });\n\n const update = (next: Drag | null) => {\n dragRef.current = next;\n setDrag(next);\n };\n\n // The latest render's values, for the window listeners of a drag in progress.\n const live = useRef({ planFor, selection });\n live.current = { planFor, selection };\n const stopDrag = useRef<(() => void) | null>(null);\n useEffect(() => () => stopDrag.current?.(), []);\n\n const onClipPointerDown = (e: React.PointerEvent<HTMLDivElement>, clip: VideoClip, track: VideoTrack) => {\n if (e.button !== undefined && e.button !== 0) return;\n e.stopPropagation();\n if (!editable) return;\n try {\n e.currentTarget.setPointerCapture?.(e.pointerId);\n } catch {\n // No pointer to capture (synthetic events).\n }\n const handle = (e.target as HTMLElement).closest('[data-handle]')?.getAttribute('data-handle');\n const mode: VideoClipDragMode = handle === 'start' ? 'trim-start' : handle === 'end' ? 'trim-end' : 'move';\n const fixed = !canEdit || !!track.locked;\n stopDrag.current?.();\n update({ clip: clip.id, mode, x: e.clientX, pointer: e.pointerId, moved: false, plan: null });\n // Follow the pointer on the window: the block may move to another track's row (a new element) mid-drag.\n const move = (ev: PointerEvent) => {\n const d = dragRef.current;\n if (!d || fixed) return;\n if (!d.moved && Math.abs(ev.clientX - d.x) < DRAG_THRESHOLD) return;\n if (!d.moved && !live.current.selection.includes(d.clip)) controller.select([d.clip]);\n update({ ...d, moved: true, plan: live.current.planFor(d, ev) });\n };\n const up = (ev: PointerEvent) => {\n stop();\n const d = dragRef.current;\n if (!d) return;\n update(null);\n if (!d.moved) {\n if (ev.shiftKey || ev.metaKey || ev.ctrlKey) controller.select([d.clip], { add: true });\n else controller.select([d.clip]);\n return;\n }\n const plan = live.current.planFor(d, ev);\n if (plan?.edit) controller.apply(plan.edit, d.mode === 'move' ? 'Move clip' : ev.altKey ? 'Ripple trim' : 'Trim clip');\n };\n const cancel = () => {\n stop();\n update(null);\n };\n const stop = () => {\n window.removeEventListener('pointermove', move);\n window.removeEventListener('pointerup', up);\n window.removeEventListener('pointercancel', cancel);\n stopDrag.current = null;\n };\n window.addEventListener('pointermove', move);\n window.addEventListener('pointerup', up);\n window.addEventListener('pointercancel', cancel);\n stopDrag.current = stop;\n };\n\n const onKeyDown = (e: React.KeyboardEvent<HTMLDivElement>) => {\n if (isField(e.target)) return;\n const mod = e.metaKey || e.ctrlKey;\n const key = e.key.toLowerCase();\n if (e.key === ' ') {\n if ((e.target as HTMLElement).tagName === 'BUTTON') return;\n controller.toggle();\n } else if (e.key === 'ArrowLeft' && !mod) controller.step(-1);\n else if (e.key === 'ArrowRight' && !mod) controller.step(1);\n else if (e.key === 'Escape') controller.select(null);\n else if (!canEdit) return;\n else if (key === 's' && !mod) controller.splitAtPlayhead();\n else if ((e.key === 'Delete' || e.key === 'Backspace') && !mod) controller.deleteSelection({ ripple: e.shiftKey });\n else if (key === 'z' && mod) {\n if (e.shiftKey) controller.redo();\n else controller.undo();\n } else return;\n e.preventDefault();\n };\n\n // Where each clip is drawn: the dragged one follows the plan (possibly on another track).\n const placed = project.tracks.map((track) => ({\n track,\n clips: project.tracks.flatMap((t) =>\n t.clips\n .map((clip) => {\n const plan = drag?.moved && drag.clip === clip.id ? drag.plan : null;\n const on = plan ? plan.track : t.id;\n return on === track.id ? { clip, home: t, start: plan ? plan.start : clip.start, duration: plan ? plan.duration : clip.duration, dragging: !!plan } : null;\n })\n .filter((x): x is NonNullable<typeof x> => x !== null),\n ),\n }));\n\n const toggle = (track: VideoTrack, field: 'muted' | 'hidden' | 'locked', label: string) => (\n <button\n type=\"button\"\n className={`rounded border px-1 text-[10px] leading-4 ${track[field] ? 'border-rose-500 bg-rose-500/15 text-rose-600' : 'border-border text-muted-foreground'} disabled:opacity-40`}\n aria-pressed={!!track[field]}\n aria-label={`${label} ${track.name ?? track.id}`}\n title={label}\n disabled={!canEdit}\n data-track-toggle={field}\n onClick={() => controller.apply({ op: 'update_track', track: track.id, set: { [field]: !track[field] } }, `${track[field] ? 'Un' : ''}${field === 'muted' ? 'mute' : field === 'hidden' ? 'hide' : 'lock'} track`)}\n >\n {field === 'muted' ? 'M' : field === 'hidden' ? 'H' : 'L'}\n </button>\n );\n\n return (\n <div className={`flex flex-col gap-1 ${className}`} data-video-timeline-wrapper=\"\">\n {!onPxPerSecondChange && (\n <label className=\"flex items-center gap-2 self-end text-xs text-muted-foreground\">\n Zoom\n <input type=\"range\" min={MIN_ZOOM} max={MAX_ZOOM} step={5} value={ownZoom} aria-label=\"Timeline zoom\" onChange={(e) => setOwnZoom(Number(e.target.value))} data-zoom=\"\" />\n </label>\n )}\n <div\n className=\"relative overflow-x-auto rounded border border-border outline-none focus-visible:ring-2 focus-visible:ring-rose-500/50\"\n tabIndex={0}\n role=\"group\"\n aria-label=\"Video timeline\"\n onKeyDown={onKeyDown}\n data-video-timeline=\"\"\n >\n <div className=\"relative\" style={{ width: HEADER + width }}>\n <div className=\"flex\" style={{ height: RULER }}>\n <div className=\"sticky left-0 z-20 shrink-0 border-b border-r border-border bg-background\" style={{ width: HEADER }} />\n <div\n ref={ruler}\n className=\"relative shrink-0 cursor-ew-resize select-none touch-none border-b border-border text-[10px] text-muted-foreground\"\n style={{ width }}\n role=\"slider\"\n aria-label=\"Playhead\"\n aria-valuemin={0}\n aria-valuemax={duration}\n aria-valuenow={Math.round(time)}\n data-ruler=\"\"\n onPointerDown={(e) => {\n try {\n e.currentTarget.setPointerCapture?.(e.pointerId);\n } catch {\n // No pointer to capture (synthetic events).\n }\n seekAt(e.clientX);\n }}\n onPointerMove={(e) => {\n if (e.buttons & 1) seekAt(e.clientX);\n }}\n >\n {ticks.map((t) => (\n <div key={t.time} className={`absolute bottom-0 w-px ${t.major ? 'h-2.5 bg-muted-foreground/70' : 'h-1 bg-muted-foreground/40'}`} style={{ left: t.x }} data-tick={t.time}>\n {t.label && <span className=\"absolute -top-3.5 left-1 whitespace-nowrap tabular-nums\">{t.label}</span>}\n </div>\n ))}\n {(project.markers ?? []).map((m) => (\n <div\n key={m.id}\n className=\"absolute top-0 h-2.5 w-2.5 -translate-x-1/2 rotate-45\"\n style={{ left: msToPx(m.time), background: m.color ?? '#f59e0b' }}\n title={`${m.label ?? m.id} at ${formatVideoSeconds(m.time)}`}\n data-marker={m.id}\n />\n ))}\n </div>\n </div>\n {placed.map(({ track, clips }) => (\n <div key={track.id} className=\"flex border-b border-border last:border-b-0\" style={{ height: ROW }} data-track={track.id}>\n <div className=\"sticky left-0 z-20 flex shrink-0 flex-col justify-center gap-0.5 border-r border-border bg-background px-2 text-xs\" style={{ width: HEADER }} data-track-header=\"\">\n <div className=\"flex items-center gap-1\">\n <span className=\"truncate font-medium\">{track.name ?? track.id}</span>\n <span className=\"rounded bg-muted px-1 text-[10px] uppercase text-muted-foreground\" data-track-kind=\"\">\n {track.kind}\n </span>\n </div>\n {editable && (\n <div className=\"flex gap-1\">\n {toggle(track, 'muted', 'Mute')}\n {track.kind === 'video' && toggle(track, 'hidden', 'Hide')}\n {toggle(track, 'locked', 'Lock')}\n </div>\n )}\n </div>\n <div\n ref={(el) => {\n if (el) rows.current.set(track.id, el);\n else rows.current.delete(track.id);\n }}\n className={`relative shrink-0 ${track.hidden ? 'opacity-50' : ''} ${track.locked ? 'bg-muted/40' : ''}`}\n style={{ width }}\n data-track-lane={track.id}\n onPointerDown={(e) => {\n if (e.target === e.currentTarget && editable) controller.select(null);\n }}\n >\n {clips.map(({ clip, home, start, duration: length, dragging }) => {\n const asset = clip.type === 'media' ? assets.get(clip.asset) : undefined;\n const selected = selection.includes(clip.id);\n const label = videoClipLabel(clip, asset);\n return (\n <div\n key={clip.id}\n className={`absolute top-1 bottom-1 select-none touch-none overflow-hidden rounded text-[11px] text-white ${canEdit && !home.locked ? 'cursor-grab' : 'cursor-default'} ${dragging ? 'opacity-80 shadow-lg' : ''}`}\n style={{\n left: msToPx(start),\n width: Math.max(2, msToPx(length)),\n background: videoClipTint(clip, asset),\n outline: selected ? '2px solid #f43f5e' : undefined,\n outlineOffset: selected ? 1 : undefined,\n zIndex: dragging ? 10 : selected ? 2 : 1,\n }}\n title={`${label} · ${formatVideoSeconds(start)}–${formatVideoSeconds(start + length)}`}\n data-clip={clip.id}\n data-selected={selected ? '' : undefined}\n data-dragging={dragging ? '' : undefined}\n aria-selected={selected}\n onPointerDown={(e) => onClipPointerDown(e, clip, home)}\n >\n <span className=\"pointer-events-none block truncate px-1.5 py-0.5 leading-4\">{label}</span>\n {clip.transition && (\n <span className=\"pointer-events-none absolute left-1 bottom-0.5 rounded bg-black/40 px-1 text-[9px] leading-3\" title={`${clip.transition.type} ${clip.transition.duration} ms`} data-transition={clip.transition.type}>\n ⧓ {clip.transition.type}\n </span>\n )}\n {canEdit && !home.locked && (\n <>\n <div className=\"absolute inset-y-0 left-0 cursor-ew-resize bg-white/0 hover:bg-white/40\" style={{ width: HANDLE }} data-handle=\"start\" aria-hidden=\"true\" />\n <div className=\"absolute inset-y-0 right-0 cursor-ew-resize bg-white/0 hover:bg-white/40\" style={{ width: HANDLE }} data-handle=\"end\" aria-hidden=\"true\" />\n </>\n )}\n </div>\n );\n })}\n </div>\n </div>\n ))}\n <div className=\"pointer-events-none absolute top-0 bottom-0 w-0.5 -translate-x-1/2 bg-rose-500\" style={{ left: HEADER + msToPx(time), zIndex: 15 }} data-playhead=\"\" />\n </div>\n </div>\n {error && (\n <p className=\"text-xs text-red-500\" role=\"alert\" data-edit-error=\"\">\n {error}\n </p>\n )}\n </div>\n );\n}\n","import React from 'react';\nimport {\n findVideoClip,\n formatVideoSeconds,\n VIDEO_TRANSITION_TYPES,\n videoKeyframeRows,\n videoKeyframeToggleEdit,\n videoKeyframeValueEdit,\n type VideoClip,\n type VideoEditorController,\n type VideoTransitionType,\n} from '@pixerate/editor/video-editor';\nimport { useVideoEditorState } from './useVideoEditor';\n\nexport interface ClipInspectorProps {\n controller: VideoEditorController;\n className?: string;\n}\n\nconst field = 'w-full rounded border border-border bg-transparent px-1 py-0.5 text-xs disabled:opacity-50';\nconst DEFAULT_TRANSITION = 500;\n\n/** An input (or textarea) that commits on blur or Enter, and resets when its value changes from outside. */\nfunction Commit({\n value,\n onCommit,\n multiline,\n ...rest\n}: { value: string; onCommit: (raw: string) => void; multiline?: boolean } & Omit<React.InputHTMLAttributes<HTMLInputElement>, 'value' | 'defaultValue'>) {\n const commit = (raw: string) => {\n if (raw !== value) onCommit(raw);\n };\n if (multiline)\n return (\n <textarea\n key={value}\n className={field}\n rows={2}\n defaultValue={value}\n disabled={rest.disabled}\n aria-label={rest['aria-label']}\n onBlur={(e) => commit(e.currentTarget.value)}\n />\n );\n return <input key={value} className={field} {...rest} defaultValue={value} onKeyDown={(e) => e.key === 'Enter' && e.currentTarget.blur()} onBlur={(e) => commit(e.currentTarget.value)} />;\n}\n\nfunction Row({ label, name, children }: { label: string; name: string; children: React.ReactNode }) {\n return (\n <label className=\"grid grid-cols-[5.5rem_minmax(0,1fr)] items-center gap-2 text-xs\" data-field={name}>\n <span className=\"text-muted-foreground\">{label}</span>\n {children}\n </label>\n );\n}\n\n/**\n * Edits the one selected clip: its name, fades, opacity, volume and transform (each with a keyframe\n * toggle at the playhead: ◆ adds a key holding the value there or removes the one there; typing a\n * value on a keyed property sets the key at the playhead); volume, speed and mute for media;\n * text, colour, size and background for titles; colour for colour clips; and the transition into\n * it. Each change is one undo step (`update_clip` / `set_transition`), committed on blur or change.\n */\nexport function ClipInspector({ controller, className = '' }: ClipInspectorProps) {\n const state = useVideoEditorState(controller);\n const { project, selection, readOnly, time } = state;\n if (selection.length !== 1)\n return (\n <p className={`text-xs text-muted-foreground ${className}`} data-clip-inspector=\"\">\n {selection.length ? `${selection.length} clips selected. Select one clip to edit it.` : 'Select a clip on the timeline to edit it.'}\n </p>\n );\n const at = findVideoClip(project, selection[0]);\n if (!at) return null;\n const clip: VideoClip = at.clip;\n const disabled = readOnly || !!at.track.locked;\n\n const set = (key: string, value: unknown, label = `Change ${key}`) => {\n if (value === undefined || value === '') controller.apply({ op: 'update_clip', clip: clip.id, remove: [key] }, label);\n else controller.apply({ op: 'update_clip', clip: clip.id, set: { [key]: value } }, label);\n };\n const num = (key: string, raw: string, label?: string) => {\n const trimmed = raw.trim();\n if (!trimmed) return set(key, undefined, label);\n const n = Number(trimmed);\n if (Number.isFinite(n)) set(key, n, label);\n };\n const text = (key: string, label?: string) => {\n const value = (clip as unknown as Record<string, unknown>)[key];\n return (\n <Commit value={value === undefined ? '' : String(value)} aria-label={label ?? key} disabled={disabled} onCommit={(raw) => set(key, raw.trim() || undefined, `Change ${label ?? key}`)} />\n );\n };\n const number = (key: string, label: string, attrs: { min?: number; max?: number; step?: number } = {}) => {\n const value = (clip as unknown as Record<string, unknown>)[key];\n return <Commit type=\"number\" value={value === undefined ? '' : String(value)} aria-label={label} disabled={disabled} onCommit={(raw) => num(key, raw, `Change ${label.toLowerCase()}`)} {...attrs} />;\n };\n\n const transition = clip.transition;\n return (\n <div className={`flex flex-col gap-1.5 ${className}`} data-clip-inspector=\"\" data-clip-id={clip.id}>\n <div className=\"flex items-center gap-2 text-xs\">\n <span className=\"font-medium\">{clip.type === 'media' ? 'Media clip' : clip.type === 'text' ? 'Title' : 'Colour clip'}</span>\n <code className=\"text-muted-foreground\">{clip.id}</code>\n {at.track.locked && <span className=\"text-amber-500\">locked track</span>}\n </div>\n <Row label=\"Name\" name=\"name\">\n {text('name', 'Name')}\n </Row>\n <Row label=\"Start\" name=\"start\">\n <span className=\"tabular-nums text-xs\">{formatVideoSeconds(clip.start)}</span>\n </Row>\n <Row label=\"Duration\" name=\"duration\">\n <span className=\"tabular-nums text-xs\">{formatVideoSeconds(clip.duration)}</span>\n </Row>\n {videoKeyframeRows(project, clip.id, time).map((row) => (\n <Row key={row.property} label={row.label} name={row.property}>\n <span className=\"flex min-w-0 items-center gap-1\" data-keyframe-row={row.property}>\n <Commit\n type=\"number\"\n value={row.keyed || (row.property === 'opacity' ? clip.opacity : row.property === 'volume' ? (clip as { volume?: unknown }).volume : clip.transform?.[row.property]) !== undefined ? String(row.value) : ''}\n placeholder={String(row.value)}\n aria-label={row.label}\n disabled={disabled}\n min={row.min}\n max={row.max}\n step={row.step}\n onCommit={(raw) => {\n const n = Number(raw);\n if (raw.trim() && !Number.isFinite(n)) return;\n const edit = videoKeyframeValueEdit(project, clip.id, row.property, time, raw.trim() ? n : undefined);\n if (edit) controller.apply(edit, row.keyed ? `Keyframe ${row.label.toLowerCase()}` : `Change ${row.label.toLowerCase()}`);\n }}\n />\n <button\n type=\"button\"\n className={`shrink-0 rounded px-1 text-xs disabled:opacity-50 ${row.onKey ? 'text-amber-500' : row.keyed ? 'text-foreground' : 'text-muted-foreground'}`}\n aria-label={`${row.onKey ? 'Remove' : 'Add'} ${row.label.toLowerCase()} keyframe at playhead`}\n aria-pressed={row.onKey}\n title={row.keyed ? `${row.keys} key${row.keys === 1 ? '' : 's'}; ${row.onKey ? 'remove the one' : 'add one'} at the playhead` : 'Animate: add a key at the playhead'}\n disabled={disabled}\n data-keyframe-toggle={row.property}\n onClick={() => {\n const edit = videoKeyframeToggleEdit(project, clip.id, row.property, time);\n if (edit) controller.apply(edit, `${row.onKey ? 'Remove' : 'Add'} ${row.label.toLowerCase()} keyframe`);\n }}\n >\n {row.onKey ? '◆' : '◇'}\n </button>\n {row.keyed && (\n <span className=\"shrink-0 text-[10px] tabular-nums text-muted-foreground\" data-keyframe-count={row.property}>\n {row.keys}\n </span>\n )}\n </span>\n </Row>\n ))}\n <Row label=\"Fade in (ms)\" name=\"fadeIn\">\n {number('fadeIn', 'Fade in', { min: 0, step: 100 })}\n </Row>\n <Row label=\"Fade out (ms)\" name=\"fadeOut\">\n {number('fadeOut', 'Fade out', { min: 0, step: 100 })}\n </Row>\n {clip.type === 'media' && (\n <>\n <Row label=\"Speed\" name=\"speed\">\n {number('speed', 'Speed', { min: 0.1, step: 0.25 })}\n </Row>\n <Row label=\"Muted\" name=\"muted\">\n <input type=\"checkbox\" className=\"justify-self-start\" checked={!!clip.muted} disabled={disabled} aria-label=\"Muted\" onChange={(e) => set('muted', e.target.checked || undefined, e.target.checked ? 'Mute clip' : 'Unmute clip')} />\n </Row>\n </>\n )}\n {clip.type === 'text' && (\n <>\n <Row label=\"Text\" name=\"text\">\n <Commit multiline value={clip.text} aria-label=\"Text\" disabled={disabled} onCommit={(raw) => set('text', raw, 'Change text')} />\n </Row>\n <Row label=\"Colour\" name=\"color\">\n {text('color', 'Colour')}\n </Row>\n <Row label=\"Font size\" name=\"fontSize\">\n {number('fontSize', 'Font size', { min: 1, step: 2 })}\n </Row>\n <Row label=\"Background\" name=\"background\">\n {text('background', 'Background')}\n </Row>\n </>\n )}\n {clip.type === 'color' && (\n <Row label=\"Colour\" name=\"color\">\n <Commit value={clip.color} aria-label=\"Colour\" disabled={disabled} onCommit={(raw) => raw.trim() && set('color', raw.trim(), 'Change colour')} />\n </Row>\n )}\n <Row label=\"Transition in\" name=\"transition\">\n <select\n className={field}\n value={transition?.type ?? ''}\n disabled={disabled}\n aria-label=\"Transition\"\n onChange={(e) => {\n const type = e.target.value as VideoTransitionType | '';\n controller.apply(\n { op: 'set_transition', clip: clip.id, transition: type ? { ...transition, type, duration: transition?.duration ?? DEFAULT_TRANSITION } : null },\n type ? 'Set transition' : 'Remove transition',\n );\n }}\n >\n <option value=\"\">None</option>\n {VIDEO_TRANSITION_TYPES.map((t) => (\n <option key={t} value={t}>\n {t === 'crossfade' ? 'Crossfade' : t === 'dip' ? 'Dip to colour' : 'Wipe'}\n </option>\n ))}\n </select>\n </Row>\n {transition && (\n <Row label=\"Length (ms)\" name=\"transitionDuration\">\n <Commit\n type=\"number\"\n min={1}\n step={100}\n value={String(transition.duration)}\n aria-label=\"Transition length\"\n disabled={disabled}\n onCommit={(raw) => {\n const n = Number(raw);\n if (raw.trim() && Number.isFinite(n) && n > 0) controller.apply({ op: 'set_transition', clip: clip.id, transition: { ...transition, duration: n } }, 'Change transition length');\n }}\n />\n </Row>\n )}\n </div>\n );\n}\n","import React, { useState } from 'react';\nimport {\n formatVideoSeconds,\n probeVideoMedia,\n videoAssetDropEdit,\n videoAssetKindOf,\n type VideoAsset,\n type VideoAssetKind,\n type VideoEditorController,\n} from '@pixerate/editor/video-editor';\nimport { useVideoEditorState } from './useVideoEditor';\n\nexport interface MediaBinProps {\n controller: VideoEditorController;\n /** Show the import controls and \"Add to timeline\" buttons (default true). */\n editable?: boolean;\n /** Turns a file into a URL the preview and exporter can open (default `URL.createObjectURL`). */\n fileToUrl?: (file: File) => string;\n /** Reads a source's length and size (default `probeVideoMedia`). */\n probe?: typeof probeVideoMedia;\n className?: string;\n}\n\nconst btn = 'rounded border border-border px-2 py-0.5 text-xs disabled:opacity-40';\n\n/**\n * The project's assets (name, kind, length), each with an \"Add to timeline\" button that puts it at\n * the end of the first unlocked track of its kind. Import media by choosing or dropping files (read\n * as object URLs and probed for their length and size) or by URL. Each import is one undo step.\n */\nexport function MediaBin({ controller, editable = true, fileToUrl, probe = probeVideoMedia, className = '' }: MediaBinProps) {\n const { project, readOnly } = useVideoEditorState(controller);\n const canEdit = editable && !readOnly;\n const [url, setUrl] = useState('');\n const [urlKind, setUrlKind] = useState<VideoAssetKind | ''>('');\n const [busy, setBusy] = useState(0);\n const [problem, setProblem] = useState<string | null>(null);\n const [over, setOver] = useState(false);\n\n const addSource = async (src: string, kind: VideoAssetKind, name: string) => {\n setBusy((n) => n + 1);\n try {\n const found = await probe(src, kind).catch(() => null);\n const result = controller.apply({ op: 'add_asset', asset: { kind, src, name, ...(found ?? {}) } }, `Import ${name}`);\n if (!result.ok) setProblem(result.error);\n } finally {\n setBusy((n) => n - 1);\n }\n };\n\n const addFiles = async (files: FileList | File[] | null) => {\n setProblem(null);\n for (const file of Array.from(files ?? [])) {\n const kind = videoAssetKindOf(file.type || file.name);\n if (!kind) {\n setProblem(`\"${file.name}\" is not a video, audio or image file.`);\n continue;\n }\n const src = fileToUrl ? fileToUrl(file) : URL.createObjectURL(file);\n await addSource(src, kind, file.name);\n }\n };\n\n const addUrl = async () => {\n const src = url.trim();\n if (!src) return;\n const kind = urlKind || videoAssetKindOf(src.replace(/[?#].*$/, ''));\n if (!kind) {\n setProblem(`Can't tell whether \"${src}\" is video, audio or an image; choose its kind.`);\n return;\n }\n setProblem(null);\n await addSource(src, kind, src.replace(/[?#].*$/, '').replace(/^.*[\\\\/]/, '') || src);\n setUrl('');\n };\n\n const addToTimeline = (asset: VideoAsset) => {\n const edit = videoAssetDropEdit(project, asset.id);\n if (!edit) {\n setProblem(`There is no unlocked ${asset.kind === 'audio' ? 'audio' : 'video'} track to put \"${asset.name ?? asset.id}\" on.`);\n return;\n }\n setProblem(null);\n const result = controller.apply(edit, `Add ${asset.name ?? asset.id}`);\n if (result.ok) {\n const added = result.outcomes[0]?.clip;\n if (added) controller.select([added]);\n }\n };\n\n return (\n <div\n className={`flex flex-col gap-2 rounded ${over ? 'ring-2 ring-rose-500/60' : ''} ${className}`}\n data-media-bin=\"\"\n onDragOver={(e) => {\n if (!canEdit || !e.dataTransfer?.types?.includes('Files')) return;\n e.preventDefault();\n setOver(true);\n }}\n onDragLeave={() => setOver(false)}\n onDrop={(e) => {\n setOver(false);\n if (!canEdit || !e.dataTransfer?.files?.length) return;\n e.preventDefault();\n void addFiles(e.dataTransfer.files);\n }}\n >\n <div className=\"text-xs font-medium\">Media</div>\n {project.assets.length ? (\n <ul className=\"flex flex-col gap-1\" aria-label=\"Media assets\">\n {project.assets.map((asset) => (\n <li key={asset.id} className=\"flex items-center gap-2 text-xs\" data-asset={asset.id}>\n <span className=\"rounded bg-muted px-1 text-[10px] uppercase text-muted-foreground\" data-asset-kind=\"\">\n {asset.kind}\n </span>\n <span className=\"min-w-0 flex-1 truncate\" title={asset.src}>\n {asset.name ?? asset.id}\n </span>\n {asset.duration !== undefined && <span className=\"tabular-nums text-muted-foreground\">{formatVideoSeconds(asset.duration)}</span>}\n {editable && (\n <button type=\"button\" className={btn} disabled={!canEdit} onClick={() => addToTimeline(asset)} data-add-to-timeline=\"\">\n Add to timeline\n </button>\n )}\n </li>\n ))}\n </ul>\n ) : (\n <p className=\"text-xs text-muted-foreground\">No media yet.{editable ? ' Choose or drop files, or add a URL.' : ''}</p>\n )}\n {editable && (\n <>\n <label className=\"flex flex-col gap-1 rounded border border-dashed border-border p-2 text-xs text-muted-foreground\">\n Choose or drop video, audio or image files\n <input\n type=\"file\"\n multiple\n accept=\"video/*,audio/*,image/*\"\n disabled={!canEdit}\n aria-label=\"Import media files\"\n data-import-files=\"\"\n onChange={(e) => {\n const files = e.currentTarget.files ? Array.from(e.currentTarget.files) : [];\n e.currentTarget.value = '';\n void addFiles(files);\n }}\n />\n </label>\n <form\n className=\"flex items-center gap-1\"\n onSubmit={(e) => {\n e.preventDefault();\n void addUrl();\n }}\n >\n <input\n className=\"min-w-0 flex-1 rounded border border-border bg-transparent px-1 py-0.5 text-xs\"\n placeholder=\"https://…/clip.mp4\"\n value={url}\n disabled={!canEdit}\n aria-label=\"Media URL\"\n onChange={(e) => setUrl(e.target.value)}\n />\n <select className=\"rounded border border-border bg-transparent px-1 py-0.5 text-xs\" value={urlKind} disabled={!canEdit} aria-label=\"Media kind\" onChange={(e) => setUrlKind(e.target.value as VideoAssetKind | '')}>\n <option value=\"\">Auto</option>\n <option value=\"video\">Video</option>\n <option value=\"audio\">Audio</option>\n <option value=\"image\">Image</option>\n </select>\n <button type=\"submit\" className={btn} disabled={!canEdit || !url.trim()} data-add-url=\"\">\n Add\n </button>\n </form>\n </>\n )}\n {busy > 0 && <p className=\"text-xs text-muted-foreground\">Reading media…</p>}\n {problem && (\n <p className=\"text-xs text-red-500\" role=\"alert\" data-media-error=\"\">\n {problem}\n </p>\n )}\n </div>\n );\n}\n","import React, { useEffect } from 'react';\nimport type { VideoEditorController, VideoEditorOptions } from '@pixerate/editor/video-editor';\nimport { ClipInspector } from './ClipInspector';\nimport { MediaBin } from './MediaBin';\nimport { useVideoEditor } from './useVideoEditor';\nimport { VideoPreview } from './VideoPreview';\nimport { VideoTimeline } from './VideoTimeline';\nimport { VideoTransport } from './VideoTransport';\n\nexport interface VideoEditorProps {\n /** The controller to edit. Without it one is created from `options` for the component's lifetime. */\n controller?: VideoEditorController;\n /** Options for the controller created when `controller` is not given. */\n options?: VideoEditorOptions;\n /**\n * Show the editing UI: the media bin's imports, the transport's edit buttons, timeline dragging\n * and track toggles, and the clip inspector (default true). False also makes the project read-only\n * while mounted.\n */\n editable?: boolean;\n /** Timeline zoom in pixels per second (with `onPxPerSecondChange` the host owns it). */\n pxPerSecond?: number;\n onPxPerSecondChange?: (pxPerSecond: number) => void;\n /** Canvas pixels per frame pixel for the preview (see `<VideoPreview resolution>`). */\n resolution?: number;\n /** List the project's issues under the timeline (default true). */\n showIssues?: boolean;\n className?: string;\n}\n\n/**\n * A whole non-linear video editor for a `VideoEditorController`: the media bin, the preview, the\n * transport, the timeline and the clip inspector, with the project's issues listed under the\n * timeline. Every edit is one undo step; the controller's agent tools edit the same project.\n */\nexport function VideoEditor({ controller: given, options, editable = true, pxPerSecond, onPxPerSecondChange, resolution, showIssues = true, className = '' }: VideoEditorProps) {\n const { controller, state } = useVideoEditor(given ?? options ?? {});\n useEffect(() => {\n if (editable) return;\n const was = controller.getState().readOnly;\n controller.setReadOnly(true);\n return () => controller.setReadOnly(was);\n }, [controller, editable]);\n const { issues } = state;\n const issueList = showIssues && issues.length > 0 && (\n <ul className=\"space-y-0.5 text-xs\" aria-label=\"Video issues\" data-video-issues=\"\">\n {issues.map((issue, i) => (\n <li key={i} className={issue.severity === 'error' ? 'text-red-500' : issue.severity === 'warning' ? 'text-amber-500' : 'text-muted-foreground'} data-issue={issue.code}>\n {issue.message}\n </li>\n ))}\n </ul>\n );\n return (\n <div className={`flex flex-col gap-3 ${className}`} data-video-editor=\"\">\n <div className={`grid gap-3 ${editable ? 'lg:grid-cols-[16rem_minmax(0,1fr)_18rem]' : ''}`}>\n {editable && <MediaBin controller={controller} className=\"min-w-0\" />}\n <div className=\"flex min-w-0 flex-col gap-2\">\n <VideoPreview controller={controller} resolution={resolution} className=\"rounded-md border border-border\" />\n <VideoTransport controller={controller} editable={editable} />\n </div>\n {editable && <ClipInspector controller={controller} className=\"min-w-0\" />}\n </div>\n <VideoTimeline controller={controller} editable={editable} pxPerSecond={pxPerSecond} onPxPerSecondChange={onPxPerSecondChange} />\n {issueList}\n </div>\n );\n}\n"],"mappings":"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","names":["useEffect","useRef","useRef","useEffect","jsx","useEffect","useRef","Fragment","jsx","jsxs","useRef","useEffect","field","formatVideoSeconds","Fragment","jsx","jsxs","formatVideoSeconds","useState","formatVideoSeconds","Fragment","jsx","jsxs","btn","useState","formatVideoSeconds","useEffect","jsx","jsxs","useEffect"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pixerate/editor-react",
3
- "version": "0.48.0",
3
+ "version": "0.50.0",
4
4
  "description": "React bindings and prompt/rich-text components for @pixerate/editor",
5
5
  "author": "Pixerate",
6
6
  "license": "MIT",
@@ -73,6 +73,11 @@
73
73
  "types": "./dist/chart/index.d.ts",
74
74
  "import": "./dist/chart/index.js",
75
75
  "require": "./dist/chart/index.cjs"
76
+ },
77
+ "./video-editor": {
78
+ "types": "./dist/video-editor/index.d.ts",
79
+ "import": "./dist/video-editor/index.js",
80
+ "require": "./dist/video-editor/index.cjs"
76
81
  }
77
82
  },
78
83
  "typesVersions": {
@@ -109,6 +114,9 @@
109
114
  ],
110
115
  "chart": [
111
116
  "./dist/chart/index.d.ts"
117
+ ],
118
+ "video-editor": [
119
+ "./dist/video-editor/index.d.ts"
112
120
  ]
113
121
  }
114
122
  },
@@ -123,7 +131,7 @@
123
131
  },
124
132
  "peerDependencies": {
125
133
  "@dagrejs/dagre": "^1.1.8",
126
- "@pixerate/editor": ">=0.73.0 <1.0.0-0",
134
+ "@pixerate/editor": ">=0.79.0 <1.0.0-0",
127
135
  "@tiptap/core": "^2.11.5",
128
136
  "@tiptap/pm": "^2.11.5",
129
137
  "@tiptap/react": "^2.11.5",
@@ -150,7 +158,7 @@
150
158
  "tsup": "^8.4.0",
151
159
  "typescript": "^5.7.3",
152
160
  "vitest": "^4.1.11",
153
- "@pixerate/editor": "0.73.0"
161
+ "@pixerate/editor": "0.79.0"
154
162
  },
155
163
  "scripts": {
156
164
  "build": "tsup",