@elah/editor 0.3.1 → 0.4.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.
- package/README.md +22 -5
- package/dist/editor/AssetPanel/AssetPanel.js +2 -1
- package/dist/editor/EditorProvider.js +2 -1
- package/dist/editor/Preview/MediaTransformOverlay.js +2 -1
- package/dist/editor/Preview/Preview.js +2 -2
- package/dist/editor/Preview/ShapeOverlay.js +2 -1
- package/dist/editor/Preview/StageBorder.js +2 -1
- package/dist/editor/Preview/TextOverlay.js +2 -1
- package/dist/editor/SourcePanel/SourcePanel.js +2 -1
- package/dist/editor/activation.d.ts +1 -1
- package/dist/editor/activation.js +1 -1
- package/dist/editor/useResolvedScene.js +2 -1
- package/dist/index.d.ts +8 -5
- package/dist/index.js +7 -5
- package/package.json +7 -4
package/README.md
CHANGED
|
@@ -16,7 +16,9 @@ Ships `EditorProvider`, `Preview` (WebGL2 canvas + interactive transform overlay
|
|
|
16
16
|
npm install @elah/editor
|
|
17
17
|
```
|
|
18
18
|
|
|
19
|
-
Peer dependencies: `react`, `react-dom` >= 18.
|
|
19
|
+
Peer dependencies: `react`, `react-dom` >= 18, `lucide-react` >= 0.400.0 (used by the
|
|
20
|
+
bundled `@elah/timeline` UI for clip icons — install it alongside `react`/`react-dom`
|
|
21
|
+
even though nothing in your own code imports it).
|
|
20
22
|
|
|
21
23
|
**Bundle size:** ~10 KiB gzipped for the editor layer (51 KiB raw); ~63 KiB gzipped for the full SDK graph (`core` + `timeline` + `editor`, 330 KiB raw). `mediabunny` is injected, never bundled — see [BUNDLE_STRATEGY.md](../../BUNDLE_STRATEGY.md).
|
|
22
24
|
|
|
@@ -142,12 +144,26 @@ Runs in a web worker. Reuses `resolveTimeline` + the GPU renderer's placement ma
|
|
|
142
144
|
## Package layers
|
|
143
145
|
|
|
144
146
|
```
|
|
145
|
-
@elah/core — engine, playback, resolver, stores, media, export (framework-agnostic)
|
|
146
|
-
@elah/
|
|
147
|
-
@elah/
|
|
147
|
+
@elah/core — engine, playback, resolver, vanilla stores, media, export (framework-agnostic)
|
|
148
|
+
@elah/react — React bindings: EditorContext, store hooks, audio hooks
|
|
149
|
+
@elah/timeline — React timeline UI components and hooks (consumes @elah/core + @elah/react)
|
|
150
|
+
@elah/editor — EditorProvider, Preview, AssetPanel + re-exports @elah/core, @elah/react, @elah/timeline
|
|
151
|
+
@elah/cli — headless split/trim/build/export/serve on top of @elah/core
|
|
148
152
|
```
|
|
149
153
|
|
|
150
|
-
Use `@elah/editor` for the full experience. Use `@elah/core` directly
|
|
154
|
+
Use `@elah/editor` for the full in-browser experience. Use `@elah/core` directly
|
|
155
|
+
for headless or custom rendering pipelines, or pair it with `@elah/react` if you
|
|
156
|
+
want the hooks without the timeline UI. Use `@elah/cli` for automation,
|
|
157
|
+
AI-generation pipelines, and server-side rendering.
|
|
158
|
+
|
|
159
|
+
**One active project per page.** `@elah/core`'s stores (`tracksStore`,
|
|
160
|
+
`playbackStore`, `selectionStore`, `transitionsStore`, `mediaLibraryStore`) are
|
|
161
|
+
module-level singletons, and `<EditorProvider>` wires the `TimelineEngine` /
|
|
162
|
+
`PlaybackEngine` it creates into those same shared stores. Mounting a second
|
|
163
|
+
`<EditorProvider>` on the same page (two independent projects at once) will have
|
|
164
|
+
both instances overwrite each other's state — there is currently no per-instance
|
|
165
|
+
scoping. If you need multiple concurrent editors, isolate each in its own
|
|
166
|
+
tab/window/iframe.
|
|
151
167
|
|
|
152
168
|
---
|
|
153
169
|
|
|
@@ -156,5 +172,6 @@ Use `@elah/editor` for the full experience. Use `@elah/core` directly for headle
|
|
|
156
172
|
- [Website](https://www.elah.dev)
|
|
157
173
|
- [GitHub](https://github.com/elahlabs/elah)
|
|
158
174
|
- [Discord](https://discord.gg/8CeZ2XbPy)
|
|
175
|
+
- [Headless CLI — @elah/cli](https://www.npmjs.com/package/@elah/cli)
|
|
159
176
|
- [License](https://github.com/elahlabs/elah/blob/main/LICENSE)
|
|
160
177
|
- [Commercial licensing](mailto:paul@elah.dev)
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { useCallback, useEffect, useRef, useState, } from 'react';
|
|
3
3
|
import { createPortal } from 'react-dom';
|
|
4
|
-
import { importFiles, importUrl, MEDIA_DRAG_MIME, mediaDragKindMime,
|
|
4
|
+
import { importFiles, importUrl, MEDIA_DRAG_MIME, mediaDragKindMime, } from '@elah/core';
|
|
5
|
+
import { useMediaLibrary, useMediaLibraryStore } from '@elah/react';
|
|
5
6
|
import { cn } from '@elah/timeline';
|
|
6
7
|
import { isActivationKey, useAssetActivation, } from '../activation';
|
|
7
8
|
const KIND_ICONS = {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { useEffect, useMemo } from 'react';
|
|
3
|
-
import { TimelineEngine, PlaybackEngine,
|
|
3
|
+
import { TimelineEngine, PlaybackEngine, installTraceGlobal, trace, } from '@elah/core';
|
|
4
|
+
import { useTracksStore, usePlaybackStore, useTransitionsStore, EditorContext, } from '@elah/react';
|
|
4
5
|
export function EditorProvider({ fps, stage, defaultTrackHeight, maxHistorySize, initialTracks, children, }) {
|
|
5
6
|
const engine = useMemo(() => new TimelineEngine({
|
|
6
7
|
fps,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useCallback, useLayoutEffect, useMemo, useRef, useState, } from 'react';
|
|
3
|
-
import {
|
|
3
|
+
import { resolveDrawRect, transformFromContainRect, computeContainViewport, } from '@elah/core';
|
|
4
|
+
import { useTimelineEngine, useSelectionStore, usePlaybackStore, useMediaLibraryStore, } from '@elah/react';
|
|
4
5
|
import { useResolvedScene } from '../useResolvedScene';
|
|
5
6
|
const MIN_BOX_PX = 28;
|
|
6
7
|
const BOX_PAD = 0;
|
|
@@ -2,8 +2,8 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { forwardRef, useEffect, useImperativeHandle, useRef, } from 'react';
|
|
3
3
|
import { GpuRenderer } from '@elah/core';
|
|
4
4
|
import { resolveTimeline } from '@elah/core';
|
|
5
|
-
import { useTimelineEngine, usePlaybackEngine } from '@elah/
|
|
6
|
-
import { AudioPlaybackController,
|
|
5
|
+
import { useTimelineEngine, usePlaybackEngine, useMediaLibraryStore } from '@elah/react';
|
|
6
|
+
import { AudioPlaybackController, preloadProjectImages, warmImageSrc } from '@elah/core';
|
|
7
7
|
import { cn } from '@elah/timeline';
|
|
8
8
|
import { TextOverlay } from './TextOverlay';
|
|
9
9
|
import { ShapeOverlay } from './ShapeOverlay';
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useCallback, useLayoutEffect, useMemo, useRef, useState, } from 'react';
|
|
3
|
-
import {
|
|
3
|
+
import { computeContainViewport } from '@elah/core';
|
|
4
|
+
import { useTimelineEngine, useSelectionStore, usePlaybackStore, } from '@elah/react';
|
|
4
5
|
import { useResolvedScene } from '../useResolvedScene';
|
|
5
6
|
const DEFAULT_SCALE = 0.5;
|
|
6
7
|
const DEFAULT_CENTER = 0.5;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { useLayoutEffect, useMemo, useRef, useState } from 'react';
|
|
3
|
-
import { computeContainViewport
|
|
3
|
+
import { computeContainViewport } from '@elah/core';
|
|
4
|
+
import { useTracksStore } from '@elah/react';
|
|
4
5
|
export function StageBorder() {
|
|
5
6
|
const rootRef = useRef(null);
|
|
6
7
|
const [size, setSize] = useState({ width: 0, height: 0 });
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState, } from 'react';
|
|
3
|
-
import { computeTextLayout, computeContainViewport,
|
|
3
|
+
import { computeTextLayout, computeContainViewport, SIDE_MARGIN, } from '@elah/core';
|
|
4
|
+
import { useTimelineEngine, useSelectionStore, usePlaybackStore, } from '@elah/react';
|
|
4
5
|
import { useResolvedScene } from '../useResolvedScene';
|
|
5
6
|
const MIN_FONT_SIZE = 6;
|
|
6
7
|
const MAX_FONT_SIZE = 4000;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { useCallback, useEffect, useRef, useState, } from 'react';
|
|
3
3
|
import { createPortal } from 'react-dom';
|
|
4
|
-
import { importFiles, importUrl, MEDIA_DRAG_MIME, mediaDragKindMime,
|
|
4
|
+
import { importFiles, importUrl, MEDIA_DRAG_MIME, mediaDragKindMime, } from '@elah/core';
|
|
5
|
+
import { useMediaLibrary, useMediaLibraryStore } from '@elah/react';
|
|
5
6
|
import { ELEMENT_DRAG_MIME, cn } from '@elah/timeline';
|
|
6
7
|
import { isActivationKey, useAssetActivation, } from '../activation';
|
|
7
8
|
const KIND_ICONS = { video: '▶', audio: '♪', image: '◻' };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useCallback, useContext } from 'react';
|
|
2
|
-
import { EditorContext } from '@elah/
|
|
2
|
+
import { EditorContext } from '@elah/react';
|
|
3
3
|
import { insertElement, insertMediaAsset, } from '@elah/timeline';
|
|
4
4
|
export function isActivationKey(key) {
|
|
5
5
|
return key === 'Enter' || key === ' ';
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { useMemo, useRef } from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { resolveTimeline } from '@elah/core';
|
|
3
|
+
import { useTimelineEngine, useTracksStore, usePlaybackStore, } from '@elah/react';
|
|
3
4
|
export function useResolvedScene(frameOverride) {
|
|
4
5
|
const engine = useTimelineEngine();
|
|
5
6
|
const playbackFrame = usePlaybackStore((s) => (s.isPlaying ? null : s.currentFrame));
|
package/dist/index.d.ts
CHANGED
|
@@ -18,11 +18,12 @@ export { AudioPlaybackController } from '@elah/core';
|
|
|
18
18
|
export type { AudioPlaybackControllerOptions } from '@elah/core';
|
|
19
19
|
export { defaultAudioResolver } from '@elah/core';
|
|
20
20
|
export type { AudioResolver } from '@elah/core';
|
|
21
|
-
export {
|
|
21
|
+
export { MEDIA_DRAG_MIME, mediaDragKindMime, importFiles, importUrl } from '@elah/core';
|
|
22
|
+
export { useMediaLibrary, useMediaLibraryStore } from '@elah/react';
|
|
22
23
|
export type { MediaAsset, MediaKind, DragMediaPayload, ImportFilesOptions, ImportFilesResult, SkippedImport } from '@elah/core';
|
|
23
|
-
export { useTracksStore } from '@elah/
|
|
24
|
-
export { usePlaybackStore } from '@elah/
|
|
25
|
-
export { useSelectionStore } from '@elah/
|
|
24
|
+
export { useTracksStore } from '@elah/react';
|
|
25
|
+
export { usePlaybackStore } from '@elah/react';
|
|
26
|
+
export { useSelectionStore } from '@elah/react';
|
|
26
27
|
export { createVideoClip } from '@elah/core';
|
|
27
28
|
export { createAudioClip } from '@elah/core';
|
|
28
29
|
export { createTextClip } from '@elah/core';
|
|
@@ -48,7 +49,9 @@ export { ELEMENT_DRAG_MIME } from '@elah/timeline';
|
|
|
48
49
|
export type { DragElementPayload, ElementKind, ShapeVariant, InsertAssetOptions, InsertAssetResult, InsertAssetFailureReason, InsertedKind, } from '@elah/timeline';
|
|
49
50
|
export { EditorProvider } from './editor/EditorProvider';
|
|
50
51
|
export type { EditorProviderProps } from './editor/EditorProvider';
|
|
51
|
-
export { useEditor, useTimelineEngine, usePlaybackEngine } from '@elah/
|
|
52
|
+
export { useEditor, useTimelineEngine, usePlaybackEngine } from '@elah/react';
|
|
53
|
+
export { useAudioMixer, useMasterVolume, useTrackLevels } from '@elah/react';
|
|
54
|
+
export type { AudioMixerApi, MasterVolumeApi, TrackLevel } from '@elah/react';
|
|
52
55
|
export { useResolvedScene } from './editor/useResolvedScene';
|
|
53
56
|
export { AssetPanel } from './editor/AssetPanel';
|
|
54
57
|
export type { AssetPanelProps } from './editor/AssetPanel';
|
package/dist/index.js
CHANGED
|
@@ -7,10 +7,11 @@ export { createDefaultDemuxerFactory, createMediabunnyBackend, isMediabunnyCompa
|
|
|
7
7
|
export { createVideoFrameProvider, MockVideoFrameProvider, SyntheticVideoFrameProvider } from '@elah/core';
|
|
8
8
|
export { AudioPlaybackController } from '@elah/core';
|
|
9
9
|
export { defaultAudioResolver } from '@elah/core';
|
|
10
|
-
export {
|
|
11
|
-
export {
|
|
12
|
-
export {
|
|
13
|
-
export {
|
|
10
|
+
export { MEDIA_DRAG_MIME, mediaDragKindMime, importFiles, importUrl } from '@elah/core';
|
|
11
|
+
export { useMediaLibrary, useMediaLibraryStore } from '@elah/react';
|
|
12
|
+
export { useTracksStore } from '@elah/react';
|
|
13
|
+
export { usePlaybackStore } from '@elah/react';
|
|
14
|
+
export { useSelectionStore } from '@elah/react';
|
|
14
15
|
export { createVideoClip } from '@elah/core';
|
|
15
16
|
export { createAudioClip } from '@elah/core';
|
|
16
17
|
export { createTextClip } from '@elah/core';
|
|
@@ -30,7 +31,8 @@ export { useTimelineDrop } from '@elah/timeline';
|
|
|
30
31
|
export { insertMediaAsset, insertElement } from '@elah/timeline';
|
|
31
32
|
export { ELEMENT_DRAG_MIME } from '@elah/timeline';
|
|
32
33
|
export { EditorProvider } from './editor/EditorProvider';
|
|
33
|
-
export { useEditor, useTimelineEngine, usePlaybackEngine } from '@elah/
|
|
34
|
+
export { useEditor, useTimelineEngine, usePlaybackEngine } from '@elah/react';
|
|
35
|
+
export { useAudioMixer, useMasterVolume, useTrackLevels } from '@elah/react';
|
|
34
36
|
export { useResolvedScene } from './editor/useResolvedScene';
|
|
35
37
|
export { AssetPanel } from './editor/AssetPanel';
|
|
36
38
|
export { ElementsPanel } from './editor/ElementsPanel';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@elah/editor",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Full React video editor SDK — timeline UI, WebGL2 preview, media library, drag and drop, and MP4 export",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -55,11 +55,13 @@
|
|
|
55
55
|
"license": "Apache-2.0",
|
|
56
56
|
"peerDependencies": {
|
|
57
57
|
"react": ">=18.0.0",
|
|
58
|
-
"react-dom": ">=18.0.0"
|
|
58
|
+
"react-dom": ">=18.0.0",
|
|
59
|
+
"lucide-react": ">=0.400.0"
|
|
59
60
|
},
|
|
60
61
|
"dependencies": {
|
|
61
|
-
"@elah/core": "^0.
|
|
62
|
-
"@elah/
|
|
62
|
+
"@elah/core": "^0.4.0",
|
|
63
|
+
"@elah/react": "^0.4.0",
|
|
64
|
+
"@elah/timeline": "^0.4.0",
|
|
63
65
|
"immer": "^10.1.1",
|
|
64
66
|
"zustand": "^5.0.3"
|
|
65
67
|
},
|
|
@@ -67,6 +69,7 @@
|
|
|
67
69
|
"@types/react": "^18.3.18",
|
|
68
70
|
"@types/react-dom": "^18.3.5",
|
|
69
71
|
"autoprefixer": "^10.4.21",
|
|
72
|
+
"lucide-react": "^0.511.0",
|
|
70
73
|
"postcss": "^8.5.3",
|
|
71
74
|
"tailwindcss": "^3.4.17",
|
|
72
75
|
"typescript": "^5.7.3",
|