@clipkit/editor 1.0.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/LICENSE +201 -0
- package/README.md +51 -0
- package/dist/Editor.d.ts +3 -0
- package/dist/Editor.d.ts.map +1 -0
- package/dist/Editor.js +73 -0
- package/dist/Editor.js.map +1 -0
- package/dist/ExportDialog.d.ts +12 -0
- package/dist/ExportDialog.d.ts.map +1 -0
- package/dist/ExportDialog.js +30 -0
- package/dist/ExportDialog.js.map +1 -0
- package/dist/MotionPathOverlay.d.ts +5 -0
- package/dist/MotionPathOverlay.d.ts.map +1 -0
- package/dist/MotionPathOverlay.js +156 -0
- package/dist/MotionPathOverlay.js.map +1 -0
- package/dist/PerfHud.d.ts +2 -0
- package/dist/PerfHud.d.ts.map +1 -0
- package/dist/PerfHud.js +85 -0
- package/dist/PerfHud.js.map +1 -0
- package/dist/Stage.d.ts +2 -0
- package/dist/Stage.d.ts.map +1 -0
- package/dist/Stage.js +406 -0
- package/dist/Stage.js.map +1 -0
- package/dist/StageOverlay.d.ts +7 -0
- package/dist/StageOverlay.d.ts.map +1 -0
- package/dist/StageOverlay.js +508 -0
- package/dist/StageOverlay.js.map +1 -0
- package/dist/commands.d.ts +18 -0
- package/dist/commands.d.ts.map +1 -0
- package/dist/commands.js +103 -0
- package/dist/commands.js.map +1 -0
- package/dist/configuration.d.ts +9 -0
- package/dist/configuration.d.ts.map +1 -0
- package/dist/configuration.js +21 -0
- package/dist/configuration.js.map +1 -0
- package/dist/controls/AnimationsStack.d.ts +8 -0
- package/dist/controls/AnimationsStack.d.ts.map +1 -0
- package/dist/controls/AnimationsStack.js +188 -0
- package/dist/controls/AnimationsStack.js.map +1 -0
- package/dist/controls/CameraControl.d.ts +19 -0
- package/dist/controls/CameraControl.d.ts.map +1 -0
- package/dist/controls/CameraControl.js +47 -0
- package/dist/controls/CameraControl.js.map +1 -0
- package/dist/controls/CaptionLengthControl.d.ts +5 -0
- package/dist/controls/CaptionLengthControl.d.ts.map +1 -0
- package/dist/controls/CaptionLengthControl.js +11 -0
- package/dist/controls/CaptionLengthControl.js.map +1 -0
- package/dist/controls/CaptionTranscribe.d.ts +2 -0
- package/dist/controls/CaptionTranscribe.d.ts.map +1 -0
- package/dist/controls/CaptionTranscribe.js +95 -0
- package/dist/controls/CaptionTranscribe.js.map +1 -0
- package/dist/controls/ColorPicker.d.ts +17 -0
- package/dist/controls/ColorPicker.d.ts.map +1 -0
- package/dist/controls/ColorPicker.js +354 -0
- package/dist/controls/ColorPicker.js.map +1 -0
- package/dist/controls/ControlRenderer.d.ts +20 -0
- package/dist/controls/ControlRenderer.d.ts.map +1 -0
- package/dist/controls/ControlRenderer.js +106 -0
- package/dist/controls/ControlRenderer.js.map +1 -0
- package/dist/controls/CropControl.d.ts +2 -0
- package/dist/controls/CropControl.d.ts.map +1 -0
- package/dist/controls/CropControl.js +177 -0
- package/dist/controls/CropControl.js.map +1 -0
- package/dist/controls/EffectsStack.d.ts +8 -0
- package/dist/controls/EffectsStack.d.ts.map +1 -0
- package/dist/controls/EffectsStack.js +89 -0
- package/dist/controls/EffectsStack.js.map +1 -0
- package/dist/controls/GradeControl.d.ts +2 -0
- package/dist/controls/GradeControl.d.ts.map +1 -0
- package/dist/controls/GradeControl.js +120 -0
- package/dist/controls/GradeControl.js.map +1 -0
- package/dist/controls/KeyframeDiamond.d.ts +11 -0
- package/dist/controls/KeyframeDiamond.d.ts.map +1 -0
- package/dist/controls/KeyframeDiamond.js +87 -0
- package/dist/controls/KeyframeDiamond.js.map +1 -0
- package/dist/controls/LightingControls.d.ts +24 -0
- package/dist/controls/LightingControls.d.ts.map +1 -0
- package/dist/controls/LightingControls.js +108 -0
- package/dist/controls/LightingControls.js.map +1 -0
- package/dist/controls/ShapePresetControl.d.ts +4 -0
- package/dist/controls/ShapePresetControl.d.ts.map +1 -0
- package/dist/controls/ShapePresetControl.js +30 -0
- package/dist/controls/ShapePresetControl.js.map +1 -0
- package/dist/controls/ValueField.d.ts +10 -0
- package/dist/controls/ValueField.d.ts.map +1 -0
- package/dist/controls/ValueField.js +158 -0
- package/dist/controls/ValueField.js.map +1 -0
- package/dist/controls/VolumeControl.d.ts +10 -0
- package/dist/controls/VolumeControl.d.ts.map +1 -0
- package/dist/controls/VolumeControl.js +75 -0
- package/dist/controls/VolumeControl.js.map +1 -0
- package/dist/controls/compound.d.ts +46 -0
- package/dist/controls/compound.d.ts.map +1 -0
- package/dist/controls/compound.js +160 -0
- package/dist/controls/compound.js.map +1 -0
- package/dist/controls/layout.d.ts +38 -0
- package/dist/controls/layout.d.ts.map +1 -0
- package/dist/controls/layout.js +162 -0
- package/dist/controls/layout.js.map +1 -0
- package/dist/controls/primitives.d.ts +83 -0
- package/dist/controls/primitives.d.ts.map +1 -0
- package/dist/controls/primitives.js +194 -0
- package/dist/controls/primitives.js.map +1 -0
- package/dist/controls/transcribe.worker.d.ts +2 -0
- package/dist/controls/transcribe.worker.d.ts.map +1 -0
- package/dist/controls/transcribe.worker.js +22 -0
- package/dist/controls/transcribe.worker.js.map +1 -0
- package/dist/frame/AddElementBar.d.ts +2 -0
- package/dist/frame/AddElementBar.d.ts.map +1 -0
- package/dist/frame/AddElementBar.js +103 -0
- package/dist/frame/AddElementBar.js.map +1 -0
- package/dist/frame/Breadcrumbs.d.ts +2 -0
- package/dist/frame/Breadcrumbs.d.ts.map +1 -0
- package/dist/frame/Breadcrumbs.js +32 -0
- package/dist/frame/Breadcrumbs.js.map +1 -0
- package/dist/frame/GroupFlash.d.ts +2 -0
- package/dist/frame/GroupFlash.d.ts.map +1 -0
- package/dist/frame/GroupFlash.js +65 -0
- package/dist/frame/GroupFlash.js.map +1 -0
- package/dist/frame/Resizable.d.ts +12 -0
- package/dist/frame/Resizable.d.ts.map +1 -0
- package/dist/frame/Resizable.js +37 -0
- package/dist/frame/Resizable.js.map +1 -0
- package/dist/frame/Section.d.ts +23 -0
- package/dist/frame/Section.d.ts.map +1 -0
- package/dist/frame/Section.js +23 -0
- package/dist/frame/Section.js.map +1 -0
- package/dist/frame/ZoomControl.d.ts +9 -0
- package/dist/frame/ZoomControl.d.ts.map +1 -0
- package/dist/frame/ZoomControl.js +15 -0
- package/dist/frame/ZoomControl.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/camera-gizmo.d.ts +15 -0
- package/dist/lib/camera-gizmo.d.ts.map +1 -0
- package/dist/lib/camera-gizmo.js +57 -0
- package/dist/lib/camera-gizmo.js.map +1 -0
- package/dist/lib/camera-tool.d.ts +43 -0
- package/dist/lib/camera-tool.d.ts.map +1 -0
- package/dist/lib/camera-tool.js +80 -0
- package/dist/lib/camera-tool.js.map +1 -0
- package/dist/lib/caption-segments.d.ts +17 -0
- package/dist/lib/caption-segments.d.ts.map +1 -0
- package/dist/lib/caption-segments.js +50 -0
- package/dist/lib/caption-segments.js.map +1 -0
- package/dist/lib/group.d.ts +12 -0
- package/dist/lib/group.d.ts.map +1 -0
- package/dist/lib/group.js +61 -0
- package/dist/lib/group.js.map +1 -0
- package/dist/lib/keyframes.d.ts +29 -0
- package/dist/lib/keyframes.d.ts.map +1 -0
- package/dist/lib/keyframes.js +92 -0
- package/dist/lib/keyframes.js.map +1 -0
- package/dist/lib/sfx-preview.d.ts +18 -0
- package/dist/lib/sfx-preview.d.ts.map +1 -0
- package/dist/lib/sfx-preview.js +74 -0
- package/dist/lib/sfx-preview.js.map +1 -0
- package/dist/lib/shape-presets.d.ts +35 -0
- package/dist/lib/shape-presets.d.ts.map +1 -0
- package/dist/lib/shape-presets.js +81 -0
- package/dist/lib/shape-presets.js.map +1 -0
- package/dist/lib/ungroup.d.ts +12 -0
- package/dist/lib/ungroup.d.ts.map +1 -0
- package/dist/lib/ungroup.js +40 -0
- package/dist/lib/ungroup.js.map +1 -0
- package/dist/lib/utils.d.ts +3 -0
- package/dist/lib/utils.d.ts.map +1 -0
- package/dist/lib/utils.js +9 -0
- package/dist/lib/utils.js.map +1 -0
- package/dist/panels/AssetsPanel.d.ts +2 -0
- package/dist/panels/AssetsPanel.d.ts.map +1 -0
- package/dist/panels/AssetsPanel.js +108 -0
- package/dist/panels/AssetsPanel.js.map +1 -0
- package/dist/panels/InspectorPanel.d.ts +2 -0
- package/dist/panels/InspectorPanel.d.ts.map +1 -0
- package/dist/panels/InspectorPanel.js +286 -0
- package/dist/panels/InspectorPanel.js.map +1 -0
- package/dist/panels/InterpolationPanel.d.ts +2 -0
- package/dist/panels/InterpolationPanel.d.ts.map +1 -0
- package/dist/panels/InterpolationPanel.js +226 -0
- package/dist/panels/InterpolationPanel.js.map +1 -0
- package/dist/panels/LayersTree.d.ts +4 -0
- package/dist/panels/LayersTree.d.ts.map +1 -0
- package/dist/panels/LayersTree.js +137 -0
- package/dist/panels/LayersTree.js.map +1 -0
- package/dist/panels/LeftRail.d.ts +6 -0
- package/dist/panels/LeftRail.d.ts.map +1 -0
- package/dist/panels/LeftRail.js +35 -0
- package/dist/panels/LeftRail.js.map +1 -0
- package/dist/panels/SourcePanel.d.ts +2 -0
- package/dist/panels/SourcePanel.d.ts.map +1 -0
- package/dist/panels/SourcePanel.js +470 -0
- package/dist/panels/SourcePanel.js.map +1 -0
- package/dist/panels/TimelinePanel.d.ts +11 -0
- package/dist/panels/TimelinePanel.d.ts.map +1 -0
- package/dist/panels/TimelinePanel.js +98 -0
- package/dist/panels/TimelinePanel.js.map +1 -0
- package/dist/panels/assets/SfxBrowser.d.ts +2 -0
- package/dist/panels/assets/SfxBrowser.d.ts.map +1 -0
- package/dist/panels/assets/SfxBrowser.js +49 -0
- package/dist/panels/assets/SfxBrowser.js.map +1 -0
- package/dist/panels/assets/use-assets.d.ts +11 -0
- package/dist/panels/assets/use-assets.d.ts.map +1 -0
- package/dist/panels/assets/use-assets.js +84 -0
- package/dist/panels/assets/use-assets.js.map +1 -0
- package/dist/panels/assets/use-sfx.d.ts +6 -0
- package/dist/panels/assets/use-sfx.d.ts.map +1 -0
- package/dist/panels/assets/use-sfx.js +47 -0
- package/dist/panels/assets/use-sfx.js.map +1 -0
- package/dist/panels/timeline/CanvasTimeline.d.ts +7 -0
- package/dist/panels/timeline/CanvasTimeline.d.ts.map +1 -0
- package/dist/panels/timeline/CanvasTimeline.js +1536 -0
- package/dist/panels/timeline/CanvasTimeline.js.map +1 -0
- package/dist/panels/timeline/Clip.d.ts +37 -0
- package/dist/panels/timeline/Clip.d.ts.map +1 -0
- package/dist/panels/timeline/Clip.js +176 -0
- package/dist/panels/timeline/Clip.js.map +1 -0
- package/dist/panels/timeline/CurveEditor.d.ts +2 -0
- package/dist/panels/timeline/CurveEditor.d.ts.map +1 -0
- package/dist/panels/timeline/CurveEditor.js +233 -0
- package/dist/panels/timeline/CurveEditor.js.map +1 -0
- package/dist/panels/timeline/MixerRail.d.ts +7 -0
- package/dist/panels/timeline/MixerRail.d.ts.map +1 -0
- package/dist/panels/timeline/MixerRail.js +295 -0
- package/dist/panels/timeline/MixerRail.js.map +1 -0
- package/dist/panels/timeline/Waveform.d.ts +11 -0
- package/dist/panels/timeline/Waveform.d.ts.map +1 -0
- package/dist/panels/timeline/Waveform.js +63 -0
- package/dist/panels/timeline/Waveform.js.map +1 -0
- package/dist/panels/timeline/clip-style.d.ts +10 -0
- package/dist/panels/timeline/clip-style.d.ts.map +1 -0
- package/dist/panels/timeline/clip-style.js +20 -0
- package/dist/panels/timeline/clip-style.js.map +1 -0
- package/dist/panels/timeline/filmstrip.d.ts +7 -0
- package/dist/panels/timeline/filmstrip.d.ts.map +1 -0
- package/dist/panels/timeline/filmstrip.js +135 -0
- package/dist/panels/timeline/filmstrip.js.map +1 -0
- package/dist/panels/timeline/timeline-layout.d.ts +65 -0
- package/dist/panels/timeline/timeline-layout.d.ts.map +1 -0
- package/dist/panels/timeline/timeline-layout.js +118 -0
- package/dist/panels/timeline/timeline-layout.js.map +1 -0
- package/dist/types.d.ts +68 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/package.json +56 -0
- package/src/styles.css +185 -0
|
@@ -0,0 +1,470 @@
|
|
|
1
|
+
// Source pane (EDITORS B10) — a CodeMirror 6 JSON view of the WHOLE
|
|
2
|
+
// document, living as the left rail's third tab (ruled by Ian
|
|
3
|
+
// 2026-06-11). Bidirectional:
|
|
4
|
+
//
|
|
5
|
+
// editor → store valid edits commit (debounced) through
|
|
6
|
+
// replaceSource — one history entry each, engine
|
|
7
|
+
// syncs through the normal subscription. Invalid
|
|
8
|
+
// text NEVER commits; it lints inline instead.
|
|
9
|
+
// store → editor canvas/inspector edits rewrite the pane,
|
|
10
|
+
// UNLESS the pane is focused mid-edit (the user's
|
|
11
|
+
// keystrokes win; we resync on blur/commit).
|
|
12
|
+
//
|
|
13
|
+
// Selection sync rides the lezer syntax tree, not regexes: cursor
|
|
14
|
+
// inside an element's object selects it on canvas; canvas selection
|
|
15
|
+
// scrolls the pane to that element. Inline validation is two-layer:
|
|
16
|
+
// jsonParseLinter for syntax, the protocol's normative validate()
|
|
17
|
+
// for schema — zod issue paths are resolved to exact text ranges by
|
|
18
|
+
// walking the tree.
|
|
19
|
+
'use client';
|
|
20
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
21
|
+
import { useEffect, useRef } from 'react';
|
|
22
|
+
import { EditorState } from '@codemirror/state';
|
|
23
|
+
import { EditorView, drawSelection, highlightActiveLine, keymap, lineNumbers, } from '@codemirror/view';
|
|
24
|
+
import { defaultKeymap, history, historyKeymap, indentWithTab, } from '@codemirror/commands';
|
|
25
|
+
import { json, jsonParseLinter } from '@codemirror/lang-json';
|
|
26
|
+
import { linter, lintGutter } from '@codemirror/lint';
|
|
27
|
+
import { search, searchKeymap, openSearchPanel, highlightSelectionMatches, } from '@codemirror/search';
|
|
28
|
+
import { HighlightStyle, bracketMatching, ensureSyntaxTree, foldGutter, indentOnInput, syntaxHighlighting, } from '@codemirror/language';
|
|
29
|
+
import { tags } from '@lezer/highlight';
|
|
30
|
+
import { validate } from '@clipkit/protocol';
|
|
31
|
+
import { useEditor, useEditorContext } from '@clipkit/editor-core';
|
|
32
|
+
const COMMIT_DEBOUNCE_MS = 400;
|
|
33
|
+
const format = (source) => JSON.stringify(source, null, 2);
|
|
34
|
+
/**
|
|
35
|
+
* Lezer parses lazily (viewport-first); elements deep in the document
|
|
36
|
+
* aren't in the tree yet when selection sync needs them. Force a full
|
|
37
|
+
* parse (bounded) before tree walks.
|
|
38
|
+
*/
|
|
39
|
+
function fullTree(state) {
|
|
40
|
+
return (ensureSyntaxTree(state, state.doc.length, 200) ??
|
|
41
|
+
ensureSyntaxTree(state, state.doc.length, 1000));
|
|
42
|
+
}
|
|
43
|
+
/** Resolve a key/index path to the value NODE (not just its range). */
|
|
44
|
+
function nodeForPath(state, path) {
|
|
45
|
+
const tree = fullTree(state);
|
|
46
|
+
if (!tree)
|
|
47
|
+
return null;
|
|
48
|
+
let node = tree.topNode.firstChild; // JsonText → root value
|
|
49
|
+
for (const seg of path) {
|
|
50
|
+
if (!node)
|
|
51
|
+
return null;
|
|
52
|
+
if (node.name === 'Object' && typeof seg === 'string') {
|
|
53
|
+
let found = null;
|
|
54
|
+
for (let prop = node.firstChild; prop; prop = prop.nextSibling) {
|
|
55
|
+
if (prop.name !== 'Property')
|
|
56
|
+
continue;
|
|
57
|
+
const keyNode = prop.firstChild;
|
|
58
|
+
if (!keyNode)
|
|
59
|
+
continue;
|
|
60
|
+
const key = state.sliceDoc(keyNode.from + 1, keyNode.to - 1);
|
|
61
|
+
if (key === seg) {
|
|
62
|
+
found = keyNode.nextSibling;
|
|
63
|
+
break;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
node = found;
|
|
67
|
+
}
|
|
68
|
+
else if (node.name === 'Array' && typeof seg === 'number') {
|
|
69
|
+
let i = -1;
|
|
70
|
+
let found = null;
|
|
71
|
+
for (let child = node.firstChild; child; child = child.nextSibling) {
|
|
72
|
+
if (child.name === '[' || child.name === ']')
|
|
73
|
+
continue;
|
|
74
|
+
i += 1;
|
|
75
|
+
if (i === seg) {
|
|
76
|
+
found = child;
|
|
77
|
+
break;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
node = found;
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return node ?? null;
|
|
87
|
+
}
|
|
88
|
+
/** Resolve a zod issue path (keys + indices) to the value's text range. */
|
|
89
|
+
function rangeForPath(state, path) {
|
|
90
|
+
const node = nodeForPath(state, path);
|
|
91
|
+
return node ? { from: node.from, to: node.to } : null;
|
|
92
|
+
}
|
|
93
|
+
/** The id of the top-level `elements[i]` object containing `pos`. */
|
|
94
|
+
function elementIdAtPos(state, pos) {
|
|
95
|
+
const arr = nodeForPath(state, ['elements']);
|
|
96
|
+
if (!arr || arr.name !== 'Array')
|
|
97
|
+
return null;
|
|
98
|
+
if (pos < arr.from || pos > arr.to)
|
|
99
|
+
return null;
|
|
100
|
+
for (let child = arr.firstChild; child; child = child.nextSibling) {
|
|
101
|
+
if (child.name !== 'Object' || pos < child.from || pos > child.to)
|
|
102
|
+
continue;
|
|
103
|
+
for (let prop = child.firstChild; prop; prop = prop.nextSibling) {
|
|
104
|
+
if (prop.name !== 'Property')
|
|
105
|
+
continue;
|
|
106
|
+
const keyNode = prop.firstChild;
|
|
107
|
+
if (!keyNode)
|
|
108
|
+
continue;
|
|
109
|
+
if (state.sliceDoc(keyNode.from + 1, keyNode.to - 1) === 'id') {
|
|
110
|
+
const value = keyNode.nextSibling;
|
|
111
|
+
if (value?.name === 'String') {
|
|
112
|
+
return state.sliceDoc(value.from + 1, value.to - 1);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return null; // inside an element without an id
|
|
117
|
+
}
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
/** Text range of the top-level element object with this id. */
|
|
121
|
+
function rangeForElementId(state, id) {
|
|
122
|
+
const arr = nodeForPath(state, ['elements']);
|
|
123
|
+
if (!arr || arr.name !== 'Array')
|
|
124
|
+
return null;
|
|
125
|
+
for (let child = arr.firstChild; child; child = child.nextSibling) {
|
|
126
|
+
if (child.name !== 'Object')
|
|
127
|
+
continue;
|
|
128
|
+
for (let prop = child.firstChild; prop; prop = prop.nextSibling) {
|
|
129
|
+
if (prop.name !== 'Property')
|
|
130
|
+
continue;
|
|
131
|
+
const keyNode = prop.firstChild;
|
|
132
|
+
if (!keyNode)
|
|
133
|
+
continue;
|
|
134
|
+
if (state.sliceDoc(keyNode.from + 1, keyNode.to - 1) === 'id') {
|
|
135
|
+
const value = keyNode.nextSibling;
|
|
136
|
+
if (value?.name === 'String' &&
|
|
137
|
+
state.sliceDoc(value.from + 1, value.to - 1) === id) {
|
|
138
|
+
return { from: child.from, to: child.to };
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return null;
|
|
144
|
+
}
|
|
145
|
+
// ── Theme (the editor's tokens; flips with data-theme for free) ────
|
|
146
|
+
const cmTheme = EditorView.theme({
|
|
147
|
+
'&': {
|
|
148
|
+
height: '100%',
|
|
149
|
+
fontSize: '11px',
|
|
150
|
+
backgroundColor: 'transparent',
|
|
151
|
+
color: 'var(--color-foreground)',
|
|
152
|
+
},
|
|
153
|
+
'.cm-scroller': {
|
|
154
|
+
fontFamily: 'ui-monospace, SFMono-Regular, Menlo, Consolas, monospace',
|
|
155
|
+
lineHeight: '1.55',
|
|
156
|
+
},
|
|
157
|
+
'.cm-content': { caretColor: 'var(--color-foreground)' },
|
|
158
|
+
'&.cm-focused': { outline: 'none' },
|
|
159
|
+
'.cm-gutters': {
|
|
160
|
+
backgroundColor: 'transparent',
|
|
161
|
+
color: 'var(--color-muted-foreground)',
|
|
162
|
+
border: 'none',
|
|
163
|
+
opacity: 0.7,
|
|
164
|
+
},
|
|
165
|
+
'.cm-activeLine': { backgroundColor: 'var(--color-secondary)' },
|
|
166
|
+
'.cm-activeLineGutter': { backgroundColor: 'transparent' },
|
|
167
|
+
// Dedicated selection band (theme-tuned, see --color-selection). The
|
|
168
|
+
// old --color-ring (#2e2e2e) painted a near-black block; a blue tint
|
|
169
|
+
// clashed hue-for-hue with the blue string text. This muted blue-gray
|
|
170
|
+
// keeps every syntax color legible on the selection.
|
|
171
|
+
'.cm-selectionBackground, &.cm-focused .cm-selectionBackground': {
|
|
172
|
+
backgroundColor: 'var(--color-selection) !important',
|
|
173
|
+
},
|
|
174
|
+
'.cm-cursor': { borderLeftColor: 'var(--color-foreground)' },
|
|
175
|
+
'.cm-foldGutter .cm-gutterElement': { cursor: 'pointer' },
|
|
176
|
+
'.cm-lintRange-error': {
|
|
177
|
+
backgroundImage: 'none',
|
|
178
|
+
textDecoration: 'underline wavy var(--color-destructive) 1px',
|
|
179
|
+
textUnderlineOffset: '2.5px',
|
|
180
|
+
},
|
|
181
|
+
'.cm-tooltip': {
|
|
182
|
+
backgroundColor: 'var(--color-popover)',
|
|
183
|
+
color: 'var(--color-popover-foreground)',
|
|
184
|
+
border: '1px solid var(--color-border)',
|
|
185
|
+
borderRadius: '6px',
|
|
186
|
+
fontSize: '11px',
|
|
187
|
+
},
|
|
188
|
+
// Search / replace panel — flat, matching the inspector chrome:
|
|
189
|
+
// bg-background (no card), bg-field wells, a focus ring instead of
|
|
190
|
+
// borders, rounded-md. Same tokens the inspector's controls use.
|
|
191
|
+
'.cm-panels': {
|
|
192
|
+
backgroundColor: 'var(--color-background)',
|
|
193
|
+
color: 'var(--color-foreground)',
|
|
194
|
+
},
|
|
195
|
+
'.cm-panels.cm-panels-top': { borderBottom: '1px solid var(--color-border)' },
|
|
196
|
+
'.cm-panel.cm-search': { padding: '6px 10px', fontSize: '11px' },
|
|
197
|
+
'.cm-panel.cm-search label': {
|
|
198
|
+
fontSize: '11px',
|
|
199
|
+
color: 'var(--color-muted-foreground)',
|
|
200
|
+
},
|
|
201
|
+
'.cm-panel.cm-search .cm-textfield': {
|
|
202
|
+
backgroundColor: 'var(--color-field)',
|
|
203
|
+
color: 'var(--color-foreground)',
|
|
204
|
+
border: 'none',
|
|
205
|
+
outline: 'none',
|
|
206
|
+
borderRadius: '6px',
|
|
207
|
+
padding: '3px 7px',
|
|
208
|
+
fontSize: '11px',
|
|
209
|
+
},
|
|
210
|
+
'.cm-panel.cm-search .cm-textfield:focus': {
|
|
211
|
+
outline: 'none',
|
|
212
|
+
boxShadow: '0 0 0 1px var(--color-ring)',
|
|
213
|
+
},
|
|
214
|
+
'.cm-panel.cm-search .cm-button': {
|
|
215
|
+
backgroundColor: 'var(--color-field)',
|
|
216
|
+
color: 'var(--color-foreground)',
|
|
217
|
+
border: 'none',
|
|
218
|
+
backgroundImage: 'none',
|
|
219
|
+
borderRadius: '6px',
|
|
220
|
+
padding: '3px 9px',
|
|
221
|
+
fontSize: '11px',
|
|
222
|
+
},
|
|
223
|
+
'.cm-panel.cm-search .cm-button:hover': {
|
|
224
|
+
backgroundColor: 'var(--color-field-hover)',
|
|
225
|
+
},
|
|
226
|
+
'.cm-panel.cm-search button[name=close]': {
|
|
227
|
+
color: 'var(--color-muted-foreground)',
|
|
228
|
+
cursor: 'pointer',
|
|
229
|
+
fontSize: '14px',
|
|
230
|
+
},
|
|
231
|
+
'.cm-searchMatch': {
|
|
232
|
+
backgroundColor: 'color-mix(in srgb, var(--color-yellow) 28%, transparent)',
|
|
233
|
+
},
|
|
234
|
+
'.cm-searchMatch.cm-searchMatch-selected': {
|
|
235
|
+
backgroundColor: 'color-mix(in srgb, var(--color-yellow) 55%, transparent)',
|
|
236
|
+
},
|
|
237
|
+
'.cm-selectionMatch': {
|
|
238
|
+
backgroundColor: 'color-mix(in srgb, var(--color-playhead) 22%, transparent)',
|
|
239
|
+
},
|
|
240
|
+
});
|
|
241
|
+
const jsonHighlight = HighlightStyle.define([
|
|
242
|
+
{ tag: tags.propertyName, color: 'var(--color-syntax-key)' },
|
|
243
|
+
{ tag: tags.string, color: 'var(--color-syntax-string)' },
|
|
244
|
+
{ tag: tags.number, color: 'var(--color-syntax-number)' },
|
|
245
|
+
{ tag: [tags.bool, tags.null], color: 'var(--color-syntax-bool)' },
|
|
246
|
+
{ tag: tags.punctuation, color: 'var(--color-muted-foreground)' },
|
|
247
|
+
]);
|
|
248
|
+
// ── The panel ───────────────────────────────────────────────────────
|
|
249
|
+
export function SourcePanel() {
|
|
250
|
+
const { store } = useEditorContext();
|
|
251
|
+
const actions = useEditor();
|
|
252
|
+
const hostRef = useRef(null);
|
|
253
|
+
const viewRef = useRef(null);
|
|
254
|
+
const statusRef = useRef(null);
|
|
255
|
+
const actionsRef = useRef(actions);
|
|
256
|
+
actionsRef.current = actions;
|
|
257
|
+
useEffect(() => {
|
|
258
|
+
const host = hostRef.current;
|
|
259
|
+
if (!host)
|
|
260
|
+
return;
|
|
261
|
+
// Guards against feedback loops between the two sync directions.
|
|
262
|
+
let applyingExternal = false; // store → editor rewrite in flight
|
|
263
|
+
let committed = false; // our own commit echoing back from the store
|
|
264
|
+
let commitTimer;
|
|
265
|
+
let lastSelected = null;
|
|
266
|
+
const setStatus = (text, bad) => {
|
|
267
|
+
const el = statusRef.current;
|
|
268
|
+
if (!el)
|
|
269
|
+
return;
|
|
270
|
+
el.textContent = text;
|
|
271
|
+
el.style.color = bad
|
|
272
|
+
? 'var(--color-destructive)'
|
|
273
|
+
: 'var(--color-muted-foreground)';
|
|
274
|
+
};
|
|
275
|
+
const tryCommit = (view) => {
|
|
276
|
+
const text = view.state.doc.toString();
|
|
277
|
+
const result = validate(text);
|
|
278
|
+
if (!result.valid) {
|
|
279
|
+
setStatus(`${result.errors.length} issue${result.errors.length === 1 ? '' : 's'}`, true);
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
setStatus('valid', false);
|
|
283
|
+
if (text === format(store.getState().source))
|
|
284
|
+
return; // no-op edit
|
|
285
|
+
committed = true;
|
|
286
|
+
actionsRef.current.replaceSource(result.data);
|
|
287
|
+
};
|
|
288
|
+
const protocolLinter = linter((view) => {
|
|
289
|
+
const text = view.state.doc.toString();
|
|
290
|
+
try {
|
|
291
|
+
JSON.parse(text);
|
|
292
|
+
}
|
|
293
|
+
catch {
|
|
294
|
+
return []; // syntax layer (jsonParseLinter) owns this state
|
|
295
|
+
}
|
|
296
|
+
const result = validate(text);
|
|
297
|
+
if (result.valid)
|
|
298
|
+
return [];
|
|
299
|
+
return result.errors.map((err) => {
|
|
300
|
+
const range = rangeForPath(view.state, err.path);
|
|
301
|
+
return {
|
|
302
|
+
from: range?.from ?? 0,
|
|
303
|
+
to: range?.to ?? 0,
|
|
304
|
+
severity: 'error',
|
|
305
|
+
message: err.path.length
|
|
306
|
+
? `${err.path.join('.')}: ${err.message}`
|
|
307
|
+
: err.message,
|
|
308
|
+
};
|
|
309
|
+
});
|
|
310
|
+
});
|
|
311
|
+
const updateListener = EditorView.updateListener.of((update) => {
|
|
312
|
+
if (update.docChanged && !applyingExternal) {
|
|
313
|
+
setStatus('editing…', false);
|
|
314
|
+
clearTimeout(commitTimer);
|
|
315
|
+
commitTimer = setTimeout(() => tryCommit(update.view), COMMIT_DEBOUNCE_MS);
|
|
316
|
+
}
|
|
317
|
+
// Cursor → canvas selection (only for user-driven selection moves
|
|
318
|
+
// while the pane has focus, and only when the text is parseable).
|
|
319
|
+
if (update.selectionSet &&
|
|
320
|
+
!applyingExternal &&
|
|
321
|
+
update.view.hasFocus) {
|
|
322
|
+
const id = elementIdAtPos(update.view.state, update.view.state.selection.main.head);
|
|
323
|
+
if (id && id !== lastSelected) {
|
|
324
|
+
lastSelected = id;
|
|
325
|
+
const current = store.getState().selection;
|
|
326
|
+
if (!(current.length === 1 && current[0] === id)) {
|
|
327
|
+
actionsRef.current.selectOne(id);
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
});
|
|
332
|
+
const extensions = [
|
|
333
|
+
lineNumbers(),
|
|
334
|
+
foldGutter(),
|
|
335
|
+
history(),
|
|
336
|
+
drawSelection(),
|
|
337
|
+
indentOnInput(),
|
|
338
|
+
bracketMatching(),
|
|
339
|
+
highlightActiveLine(),
|
|
340
|
+
json(),
|
|
341
|
+
syntaxHighlighting(jsonHighlight),
|
|
342
|
+
linter(jsonParseLinter()),
|
|
343
|
+
protocolLinter,
|
|
344
|
+
lintGutter(),
|
|
345
|
+
// Find / replace docked at the TOP of the pane (⌘F / the Find button).
|
|
346
|
+
search({ top: true }),
|
|
347
|
+
highlightSelectionMatches(),
|
|
348
|
+
keymap.of([...searchKeymap, ...defaultKeymap, ...historyKeymap, indentWithTab]),
|
|
349
|
+
cmTheme,
|
|
350
|
+
updateListener,
|
|
351
|
+
EditorView.lineWrapping,
|
|
352
|
+
];
|
|
353
|
+
const view = new EditorView({
|
|
354
|
+
state: EditorState.create({
|
|
355
|
+
doc: format(store.getState().source),
|
|
356
|
+
extensions,
|
|
357
|
+
}),
|
|
358
|
+
parent: host,
|
|
359
|
+
});
|
|
360
|
+
viewRef.current = view;
|
|
361
|
+
setStatus('valid', false);
|
|
362
|
+
// Store → editor. Skip the echo of our own commit; let focused
|
|
363
|
+
// keystrokes win over external edits until blur.
|
|
364
|
+
const unsubSource = store.subscribe((state, prev) => {
|
|
365
|
+
if (state.source === prev.source)
|
|
366
|
+
return;
|
|
367
|
+
if (committed) {
|
|
368
|
+
committed = false;
|
|
369
|
+
// Even our own commit may re-serialize differently (e.g. zod
|
|
370
|
+
// defaults); only rewrite if the canonical text drifted AND
|
|
371
|
+
// the user isn't already typing the next edit.
|
|
372
|
+
if (view.hasFocus)
|
|
373
|
+
return;
|
|
374
|
+
}
|
|
375
|
+
const text = format(state.source);
|
|
376
|
+
if (text === view.state.doc.toString())
|
|
377
|
+
return;
|
|
378
|
+
if (view.hasFocus)
|
|
379
|
+
return; // user mid-edit: their keystrokes win
|
|
380
|
+
applyingExternal = true;
|
|
381
|
+
view.dispatch({
|
|
382
|
+
changes: { from: 0, to: view.state.doc.length, insert: text },
|
|
383
|
+
});
|
|
384
|
+
applyingExternal = false;
|
|
385
|
+
setStatus('valid', false);
|
|
386
|
+
// Live autoscroll-to-edit: when a single element is selected and
|
|
387
|
+
// its source is changing under us (e.g. a timeline/stage drag),
|
|
388
|
+
// keep that element's JSON in view so the user watches it update
|
|
389
|
+
// in real time. Selection unchanged → the selection sub below
|
|
390
|
+
// won't fire, so we re-pin here. The hasFocus guard above means
|
|
391
|
+
// we never do this while the user is typing.
|
|
392
|
+
if (state.selection.length === 1) {
|
|
393
|
+
const range = rangeForElementId(view.state, state.selection[0]);
|
|
394
|
+
if (range) {
|
|
395
|
+
view.dispatch({
|
|
396
|
+
effects: EditorView.scrollIntoView(range.from, { y: 'start', yMargin: 24 }),
|
|
397
|
+
});
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
});
|
|
401
|
+
// On blur, resync from the store if the pane diverged invalidly.
|
|
402
|
+
const onBlur = () => {
|
|
403
|
+
const text = format(store.getState().source);
|
|
404
|
+
if (view.state.doc.toString() !== text && !validate(view.state.doc.toString()).valid) {
|
|
405
|
+
applyingExternal = true;
|
|
406
|
+
view.dispatch({
|
|
407
|
+
changes: { from: 0, to: view.state.doc.length, insert: text },
|
|
408
|
+
});
|
|
409
|
+
applyingExternal = false;
|
|
410
|
+
setStatus('valid', false);
|
|
411
|
+
}
|
|
412
|
+
};
|
|
413
|
+
view.contentDOM.addEventListener('blur', onBlur);
|
|
414
|
+
// Click-outside → blur the pane. The stage/timeline targets aren't
|
|
415
|
+
// focusable, so clicking them leaves focus sitting in this
|
|
416
|
+
// contentEditable: the cursor lingers AND the hasFocus guard below
|
|
417
|
+
// keeps blocking live store→editor updates (drags rewriting the JSON)
|
|
418
|
+
// until you click something focusable. Blurring on any pointerdown
|
|
419
|
+
// outside the pane drops the cursor and resumes live updates — which
|
|
420
|
+
// is what you'd expect from clicking away. Capture phase so it runs
|
|
421
|
+
// before handlers that stopPropagation.
|
|
422
|
+
const onOutsidePointerDown = (e) => {
|
|
423
|
+
if (!view.hasFocus)
|
|
424
|
+
return;
|
|
425
|
+
const target = e.target;
|
|
426
|
+
if (target && host.contains(target))
|
|
427
|
+
return; // inside pane → keep focus
|
|
428
|
+
view.contentDOM.blur();
|
|
429
|
+
};
|
|
430
|
+
document.addEventListener('pointerdown', onOutsidePointerDown, true);
|
|
431
|
+
// Canvas selection → scroll the pane to the element.
|
|
432
|
+
const unsubSelection = store.subscribe((state, prev) => {
|
|
433
|
+
if (state.selection === prev.selection)
|
|
434
|
+
return;
|
|
435
|
+
if (state.selection.length !== 1)
|
|
436
|
+
return;
|
|
437
|
+
const id = state.selection[0];
|
|
438
|
+
if (id === lastSelected)
|
|
439
|
+
return;
|
|
440
|
+
lastSelected = id;
|
|
441
|
+
if (view.hasFocus)
|
|
442
|
+
return; // don't yank the cursor mid-edit
|
|
443
|
+
const range = rangeForElementId(view.state, id);
|
|
444
|
+
if (!range)
|
|
445
|
+
return;
|
|
446
|
+
view.dispatch({
|
|
447
|
+
selection: { anchor: range.from },
|
|
448
|
+
effects: EditorView.scrollIntoView(range.from, { y: 'start', yMargin: 24 }),
|
|
449
|
+
});
|
|
450
|
+
});
|
|
451
|
+
return () => {
|
|
452
|
+
clearTimeout(commitTimer);
|
|
453
|
+
view.contentDOM.removeEventListener('blur', onBlur);
|
|
454
|
+
document.removeEventListener('pointerdown', onOutsidePointerDown, true);
|
|
455
|
+
unsubSource();
|
|
456
|
+
unsubSelection();
|
|
457
|
+
view.destroy();
|
|
458
|
+
viewRef.current = null;
|
|
459
|
+
};
|
|
460
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
461
|
+
}, [store]);
|
|
462
|
+
return (_jsxs("div", { className: "flex flex-col h-full min-h-0", children: [_jsx("div", { ref: hostRef, className: "flex-1 min-h-0 overflow-hidden" }), _jsxs("div", { className: "flex items-center justify-between h-6 px-2 border-t border-border shrink-0", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "text-[10px] text-muted-foreground/60", children: "Source" }), _jsxs("button", { type: "button", className: "flex items-center gap-1 text-[10px] text-muted-foreground hover:text-foreground transition-colors", title: "Find / replace (\u2318F)", onClick: () => {
|
|
463
|
+
const v = viewRef.current;
|
|
464
|
+
if (v) {
|
|
465
|
+
openSearchPanel(v);
|
|
466
|
+
v.focus();
|
|
467
|
+
}
|
|
468
|
+
}, children: [_jsxs("svg", { width: "11", height: "11", viewBox: "0 0 14 14", "aria-hidden": "true", children: [_jsx("circle", { cx: "6", cy: "6", r: "4", fill: "none", stroke: "currentColor", strokeWidth: "1.3" }), _jsx("path", { d: "M9 9 L12 12", stroke: "currentColor", strokeWidth: "1.3", strokeLinecap: "round" })] }), "Find"] })] }), _jsx("span", { ref: statusRef, className: "text-[10px] text-muted-foreground" })] })] }));
|
|
469
|
+
}
|
|
470
|
+
//# sourceMappingURL=SourcePanel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SourcePanel.js","sourceRoot":"","sources":["../../src/panels/SourcePanel.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Source } from '@clipkit/protocol';
|
|
2
|
+
import type { ExportFormatOption, ExportRequest } from '../types.js';
|
|
3
|
+
export declare function TimelinePanel({ onRender, exportFormats, rendering, renderProgress, }: {
|
|
4
|
+
/** Render handler — fired with the Source + the export-dialog choice. */
|
|
5
|
+
onRender?: (source: Source, request: ExportRequest) => void;
|
|
6
|
+
/** Formats the export dialog offers; defaults to MP4 only (free in-browser). */
|
|
7
|
+
exportFormats?: ExportFormatOption[];
|
|
8
|
+
rendering?: boolean;
|
|
9
|
+
renderProgress?: number;
|
|
10
|
+
}): import("react").JSX.Element;
|
|
11
|
+
//# sourceMappingURL=TimelinePanel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TimelinePanel.d.ts","sourceRoot":"","sources":["../../src/panels/TimelinePanel.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAehD,OAAO,KAAK,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAMrE,wBAAgB,aAAa,CAAC,EAC5B,QAAQ,EACR,aAAa,EACb,SAAiB,EACjB,cAAc,GACf,EAAE;IACD,yEAAyE;IACzE,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,KAAK,IAAI,CAAC;IAC5D,gFAAgF;IAChF,aAAa,CAAC,EAAE,kBAAkB,EAAE,CAAC;IACrC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,+BAgPA"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
// Timeline panel — transport row (play/pause, frame stepping via
|
|
2
|
+
// engine.stepFrame, loop, timecode readout, zoom) over the canvas
|
|
3
|
+
// timeline (layer headers, snap-true move/trim, waveforms, keyframe
|
|
4
|
+
// lanes; virtualized for huge layer counts). The mixer rail attaches
|
|
5
|
+
// alongside.
|
|
6
|
+
'use client';
|
|
7
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
8
|
+
import { useEffect, useRef, useState } from 'react';
|
|
9
|
+
import { computeSourceDuration, formatTimecode, useEditor, useEditorContext, useEditorStore, } from '@clipkit/editor-core';
|
|
10
|
+
import { cn } from '../lib/utils.js';
|
|
11
|
+
import { ZoomControl } from '../frame/ZoomControl.js';
|
|
12
|
+
import { CanvasTimeline } from './timeline/CanvasTimeline.js';
|
|
13
|
+
import { HEADER_W } from './timeline/timeline-layout.js';
|
|
14
|
+
import { MixerRail } from './timeline/MixerRail.js';
|
|
15
|
+
import { useConfiguration } from '../configuration.js';
|
|
16
|
+
import { ExportDialog } from '../ExportDialog.js';
|
|
17
|
+
const SCALE_STEP = 1.4;
|
|
18
|
+
const DEFAULT_EXPORT_FORMATS = [{ id: 'mp4', label: 'MP4' }];
|
|
19
|
+
export function TimelinePanel({ onRender, exportFormats, rendering = false, renderProgress, }) {
|
|
20
|
+
const { engine } = useEditorContext();
|
|
21
|
+
const { configuration } = useConfiguration();
|
|
22
|
+
const { togglePlay, setUiState, undo, redo, canUndo, canRedo } = useEditor();
|
|
23
|
+
const playing = useEditorStore((s) => s.playback.playing);
|
|
24
|
+
const ready = useEditorStore((s) => s.playback.ready);
|
|
25
|
+
const loop = useEditorStore((s) => s.ui.loop);
|
|
26
|
+
const source = useEditorStore((s) => s.source);
|
|
27
|
+
const pastLen = useEditorStore((s) => s.history.past.length);
|
|
28
|
+
const futureLen = useEditorStore((s) => s.history.future.length);
|
|
29
|
+
// Zoom + mixer expansion are editor state (lens rule) — never
|
|
30
|
+
// serialized. The mixer's open state lives here so the transport's
|
|
31
|
+
// fader button and the Master strip's chevron stay one control.
|
|
32
|
+
const [pxPerSec, setPxPerSec] = useState(100);
|
|
33
|
+
const [mixerOpen, setMixerOpen] = useState(false);
|
|
34
|
+
const [exportOpen, setExportOpen] = useState(false);
|
|
35
|
+
const exportFormatList = exportFormats?.length ? exportFormats : DEFAULT_EXPORT_FORMATS;
|
|
36
|
+
const setScale = (next) => setPxPerSec(Math.max(10, Math.min(800, next)));
|
|
37
|
+
const audioCount = source.elements.filter((el) => (el.type === 'audio' || el.type === 'video') && !!el.id).length;
|
|
38
|
+
const duration = computeSourceDuration(source);
|
|
39
|
+
// Fit-to-width (the legacy timeline's fit, same control as the
|
|
40
|
+
// stage's): scale so the whole composition spans the scroll
|
|
41
|
+
// viewport, minus the header column and a breathing margin.
|
|
42
|
+
const scrollRef = useRef(null);
|
|
43
|
+
const fitTimeline = () => {
|
|
44
|
+
const scroll = scrollRef.current;
|
|
45
|
+
if (!scroll || duration <= 0)
|
|
46
|
+
return;
|
|
47
|
+
const available = scroll.clientWidth - HEADER_W - 64;
|
|
48
|
+
if (available <= 0)
|
|
49
|
+
return;
|
|
50
|
+
setScale(available / duration);
|
|
51
|
+
};
|
|
52
|
+
// Auto-fit on load: once the scroll viewport has a width (it can be 0
|
|
53
|
+
// on the first paint before layout settles), scale so the whole source
|
|
54
|
+
// fits. Runs ONCE per mount — a fresh source remounts the editor, so a
|
|
55
|
+
// new clip refits; adding to the current one doesn't yank the zoom.
|
|
56
|
+
const didFitRef = useRef(false);
|
|
57
|
+
useEffect(() => {
|
|
58
|
+
const scroll = scrollRef.current;
|
|
59
|
+
if (!scroll || didFitRef.current)
|
|
60
|
+
return;
|
|
61
|
+
const fit = () => {
|
|
62
|
+
if (didFitRef.current || duration <= 0)
|
|
63
|
+
return;
|
|
64
|
+
const available = scroll.clientWidth - HEADER_W - 64;
|
|
65
|
+
if (available <= 0)
|
|
66
|
+
return;
|
|
67
|
+
setPxPerSec(Math.max(10, Math.min(800, available / duration)));
|
|
68
|
+
didFitRef.current = true;
|
|
69
|
+
ro.disconnect();
|
|
70
|
+
};
|
|
71
|
+
const ro = new ResizeObserver(fit);
|
|
72
|
+
ro.observe(scroll);
|
|
73
|
+
fit();
|
|
74
|
+
return () => ro.disconnect();
|
|
75
|
+
}, [duration]);
|
|
76
|
+
return (_jsxs("div", { className: "flex flex-col h-full bg-background", children: [_jsxs("div", { className: "flex items-center gap-1 h-9 px-2 border-b border-border shrink-0", children: [_jsx(TransportButton, { label: "Previous frame", disabled: !ready, onClick: () => engine?.stepFrame(-1), children: _jsxs("svg", { width: "12", height: "12", viewBox: "0 0 14 14", "aria-hidden": "true", children: [_jsx("rect", { x: "2", y: "3", width: "1.5", height: "8", rx: "0.5", fill: "currentColor" }), _jsx("path", { d: "M12 3 L5 7 L12 11 Z", fill: "currentColor" })] }) }), _jsx("button", { type: "button", className: "w-7 h-7 grid place-items-center bg-primary text-primary-foreground rounded hover:bg-primary/90 disabled:opacity-40 transition", disabled: !ready, onClick: () => void togglePlay(), "aria-label": playing ? 'Pause' : 'Play', children: playing ? (_jsxs("svg", { width: "10", height: "10", viewBox: "0 0 12 12", "aria-hidden": "true", children: [_jsx("rect", { x: "3", y: "2", width: "2.5", height: "8", rx: "0.5", fill: "currentColor" }), _jsx("rect", { x: "6.5", y: "2", width: "2.5", height: "8", rx: "0.5", fill: "currentColor" })] })) : (_jsx("svg", { width: "10", height: "10", viewBox: "0 0 12 12", "aria-hidden": "true", children: _jsx("path", { d: "M3 2 L10 6 L3 10 Z", fill: "currentColor" }) })) }), _jsx(TransportButton, { label: "Next frame", disabled: !ready, onClick: () => engine?.stepFrame(1), children: _jsxs("svg", { width: "12", height: "12", viewBox: "0 0 14 14", "aria-hidden": "true", children: [_jsx("path", { d: "M2 3 L9 7 L2 11 Z", fill: "currentColor" }), _jsx("rect", { x: "10.5", y: "3", width: "1.5", height: "8", rx: "0.5", fill: "currentColor" })] }) }), _jsx(TransportButton, { label: "Toggle loop", active: loop, onClick: () => setUiState({ loop: !loop }), children: _jsx("svg", { width: "12", height: "12", viewBox: "0 0 14 14", "aria-hidden": "true", children: _jsx("path", { d: "M3 5 a4 4 0 0 1 7 -1 M11 9 a4 4 0 0 1 -7 1 M10 2 V5 H7 M4 12 V9 H7", fill: "none", stroke: "currentColor", strokeWidth: "1.4", strokeLinecap: "round" }) }) }), _jsx("span", { className: "w-px h-3.5 bg-border mx-1", "aria-hidden": true }), _jsx(TransportButton, { label: "Undo (\u2318Z)", disabled: !(pastLen > 0 && canUndo()), onClick: () => undo(), children: _jsx("svg", { width: "13", height: "13", viewBox: "0 0 16 16", "aria-hidden": "true", children: _jsx("path", { d: "M3.5 7 L6 4.5 M3.5 7 L6 9.5 M3.5 7 H10 a3 3 0 0 1 3 3 v0.5", fill: "none", stroke: "currentColor", strokeWidth: "1.4", strokeLinecap: "round", strokeLinejoin: "round" }) }) }), _jsx(TransportButton, { label: "Redo (\u21E7\u2318Z)", disabled: !(futureLen > 0 && canRedo()), onClick: () => redo(), children: _jsx("svg", { width: "13", height: "13", viewBox: "0 0 16 16", "aria-hidden": "true", children: _jsx("path", { d: "M12.5 7 L10 4.5 M12.5 7 L10 9.5 M12.5 7 H6 a3 3 0 0 0 -3 3 v0.5", fill: "none", stroke: "currentColor", strokeWidth: "1.4", strokeLinecap: "round", strokeLinejoin: "round" }) }) }), _jsx(TimeReadout, { extent: duration }), _jsx("span", { className: "flex-1" }), _jsx(ZoomControl, { readout: `${Math.round(pxPerSec)}px/s`, onZoomOut: () => setScale(pxPerSec / SCALE_STEP), onZoomIn: () => setScale(pxPerSec * SCALE_STEP), onFit: fitTimeline, fitLabel: "Fit timeline to width" }), configuration.views.mixer && (_jsxs(_Fragment, { children: [_jsx("span", { className: "w-px h-3 bg-border mx-1", "aria-hidden": true }), _jsx("button", { type: "button", className: cn('w-6 h-6 grid place-items-center rounded-sm transition-colors disabled:opacity-30', mixerOpen
|
|
77
|
+
? 'text-foreground bg-secondary'
|
|
78
|
+
: 'text-muted-foreground hover:text-foreground hover:bg-secondary'), disabled: audioCount === 0, onClick: () => setMixerOpen((v) => !v), title: audioCount === 0
|
|
79
|
+
? 'No audio in this composition'
|
|
80
|
+
: mixerOpen
|
|
81
|
+
? 'Collapse mixer'
|
|
82
|
+
: 'Expand mixer', "aria-pressed": mixerOpen, "aria-label": "Toggle mixer", children: _jsxs("svg", { width: "13", height: "13", viewBox: "0 0 14 14", "aria-hidden": "true", children: [_jsx("path", { d: "M3 2 V12 M7 2 V12 M11 2 V12", stroke: "currentColor", strokeWidth: "1.2", strokeLinecap: "round" }), _jsx("rect", { x: "1.8", y: "8", width: "2.4", height: "1.8", rx: "0.5", fill: "currentColor" }), _jsx("rect", { x: "5.8", y: "4", width: "2.4", height: "1.8", rx: "0.5", fill: "currentColor" }), _jsx("rect", { x: "9.8", y: "6.5", width: "2.4", height: "1.8", rx: "0.5", fill: "currentColor" })] }) })] })), onRender && (_jsxs(_Fragment, { children: [_jsx("span", { className: "w-px h-3.5 bg-border mx-1", "aria-hidden": true }), rendering && (_jsx("span", { className: "text-[10px] text-muted-foreground tabular-nums mr-1", children: typeof renderProgress === 'number'
|
|
83
|
+
? `${Math.round(renderProgress * 100)}%`
|
|
84
|
+
: 'rendering…' })), _jsx("button", { type: "button", className: "h-6 px-2.5 rounded bg-primary text-primary-foreground text-[11px] font-medium hover:bg-primary/90 disabled:opacity-40 transition", disabled: rendering, onClick: () => setExportOpen(true), title: rendering ? 'Render in progress' : 'Export this source', children: rendering ? 'Rendering…' : 'Export' }), _jsx(ExportDialog, { open: exportOpen, formats: exportFormatList, onClose: () => setExportOpen(false), onConfirm: (request) => {
|
|
85
|
+
setExportOpen(false);
|
|
86
|
+
onRender(source, request);
|
|
87
|
+
} })] }))] }), _jsxs("div", { className: "flex flex-1 min-h-0", children: [_jsx(CanvasTimeline, { pxPerSec: pxPerSec, scrollRef: scrollRef, onScale: setScale }), configuration.views.mixer && (_jsx(MixerRail, { open: mixerOpen, onToggle: () => setMixerOpen((v) => !v) }))] })] }));
|
|
88
|
+
}
|
|
89
|
+
function TransportButton({ label, onClick, disabled, active, children, }) {
|
|
90
|
+
return (_jsx("button", { type: "button", className: cn('w-7 h-7 grid place-items-center rounded transition disabled:opacity-40', active
|
|
91
|
+
? 'text-foreground ring-1 ring-border bg-background'
|
|
92
|
+
: 'text-muted-foreground hover:text-foreground hover:bg-card'), disabled: disabled, onClick: onClick, title: label, "aria-label": label, children: children }));
|
|
93
|
+
}
|
|
94
|
+
function TimeReadout({ extent }) {
|
|
95
|
+
const time = useEditorStore((s) => s.playback.time);
|
|
96
|
+
return (_jsxs("span", { className: "ml-2 font-mono text-[11px] text-muted-foreground tabular-nums whitespace-nowrap", children: [formatTimecode(time, extent), _jsxs("span", { className: "text-muted-foreground/60", children: [" / ", formatTimecode(extent)] })] }));
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=TimelinePanel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TimelinePanel.js","sourceRoot":"","sources":["../../src/panels/TimelinePanel.tsx"],"names":[],"mappings":"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"}
|