@editframe/create 0.44.0 → 0.45.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.
Files changed (98) hide show
  1. package/dist/index.js +16 -28
  2. package/dist/index.js.map +1 -1
  3. package/dist/skills/editframe-brand-video-generator/README.md +155 -0
  4. package/dist/skills/editframe-brand-video-generator/SKILL.md +207 -0
  5. package/dist/skills/editframe-brand-video-generator/references/brand-examples.md +178 -0
  6. package/dist/skills/editframe-brand-video-generator/references/color-psychology.md +227 -0
  7. package/dist/skills/editframe-brand-video-generator/references/composition-patterns.md +383 -0
  8. package/dist/skills/editframe-brand-video-generator/references/editing.md +66 -0
  9. package/dist/skills/editframe-brand-video-generator/references/emotional-arcs.md +496 -0
  10. package/dist/skills/editframe-brand-video-generator/references/genre-selection.md +135 -0
  11. package/dist/skills/editframe-brand-video-generator/references/transition-styles.md +611 -0
  12. package/dist/skills/editframe-brand-video-generator/references/typography-personalities.md +326 -0
  13. package/dist/skills/editframe-brand-video-generator/references/video-archetypes.md +86 -0
  14. package/dist/skills/editframe-brand-video-generator/references/video-fundamentals.md +169 -0
  15. package/dist/skills/editframe-brand-video-generator/references/visual-metaphors.md +50 -0
  16. package/dist/skills/editframe-composition/SKILL.md +169 -0
  17. package/dist/skills/editframe-composition/references/audio.md +483 -0
  18. package/dist/skills/editframe-composition/references/captions.md +844 -0
  19. package/dist/skills/editframe-composition/references/composition-model.md +73 -0
  20. package/dist/skills/editframe-composition/references/configuration.md +403 -0
  21. package/dist/skills/editframe-composition/references/css-parts.md +105 -0
  22. package/dist/skills/editframe-composition/references/css-variables.md +640 -0
  23. package/dist/skills/editframe-composition/references/entry-points.md +810 -0
  24. package/dist/skills/editframe-composition/references/events.md +499 -0
  25. package/dist/skills/editframe-composition/references/getting-started.md +259 -0
  26. package/dist/skills/editframe-composition/references/hooks.md +234 -0
  27. package/dist/skills/editframe-composition/references/image.md +241 -0
  28. package/dist/skills/editframe-composition/references/r3f.md +580 -0
  29. package/dist/skills/editframe-composition/references/render-api.md +484 -0
  30. package/dist/skills/editframe-composition/references/render-strategies.md +119 -0
  31. package/dist/skills/editframe-composition/references/render-to-video.md +1101 -0
  32. package/dist/skills/editframe-composition/references/scripting.md +606 -0
  33. package/dist/skills/editframe-composition/references/sequencing.md +116 -0
  34. package/dist/skills/editframe-composition/references/server-rendering.md +753 -0
  35. package/dist/skills/editframe-composition/references/surface.md +329 -0
  36. package/dist/skills/editframe-composition/references/text.md +627 -0
  37. package/dist/skills/editframe-composition/references/time-model.md +99 -0
  38. package/dist/skills/editframe-composition/references/timegroup-modes.md +102 -0
  39. package/dist/skills/editframe-composition/references/timegroup.md +457 -0
  40. package/dist/skills/editframe-composition/references/timeline-root.md +398 -0
  41. package/dist/skills/editframe-composition/references/transcription.md +47 -0
  42. package/dist/skills/editframe-composition/references/transitions.md +608 -0
  43. package/dist/skills/editframe-composition/references/use-media-info.md +357 -0
  44. package/dist/skills/editframe-composition/references/video.md +506 -0
  45. package/dist/skills/editframe-composition/references/waveform.md +327 -0
  46. package/dist/skills/editframe-editor-gui/SKILL.md +152 -0
  47. package/dist/skills/editframe-editor-gui/references/active-root-temporal.md +657 -0
  48. package/dist/skills/editframe-editor-gui/references/canvas.md +947 -0
  49. package/dist/skills/editframe-editor-gui/references/controls.md +366 -0
  50. package/dist/skills/editframe-editor-gui/references/dial.md +756 -0
  51. package/dist/skills/editframe-editor-gui/references/editor-toolkit.md +587 -0
  52. package/dist/skills/editframe-editor-gui/references/filmstrip.md +460 -0
  53. package/dist/skills/editframe-editor-gui/references/fit-scale.md +772 -0
  54. package/dist/skills/editframe-editor-gui/references/focus-overlay.md +561 -0
  55. package/dist/skills/editframe-editor-gui/references/hierarchy.md +544 -0
  56. package/dist/skills/editframe-editor-gui/references/overlay-item.md +634 -0
  57. package/dist/skills/editframe-editor-gui/references/overlay-layer.md +429 -0
  58. package/dist/skills/editframe-editor-gui/references/pan-zoom.md +568 -0
  59. package/dist/skills/editframe-editor-gui/references/pause.md +397 -0
  60. package/dist/skills/editframe-editor-gui/references/play.md +370 -0
  61. package/dist/skills/editframe-editor-gui/references/preview.md +391 -0
  62. package/dist/skills/editframe-editor-gui/references/resizable-box.md +749 -0
  63. package/dist/skills/editframe-editor-gui/references/scrubber.md +588 -0
  64. package/dist/skills/editframe-editor-gui/references/thumbnail-strip.md +566 -0
  65. package/dist/skills/editframe-editor-gui/references/time-display.md +492 -0
  66. package/dist/skills/editframe-editor-gui/references/timeline-ruler.md +489 -0
  67. package/dist/skills/editframe-editor-gui/references/timeline.md +604 -0
  68. package/dist/skills/editframe-editor-gui/references/toggle-loop.md +618 -0
  69. package/dist/skills/editframe-editor-gui/references/toggle-play.md +526 -0
  70. package/dist/skills/editframe-editor-gui/references/transform-handles.md +924 -0
  71. package/dist/skills/editframe-editor-gui/references/trim-handles.md +725 -0
  72. package/dist/skills/editframe-editor-gui/references/workbench.md +453 -0
  73. package/dist/skills/editframe-motion-design/SKILL.md +101 -0
  74. package/dist/skills/editframe-motion-design/references/0-editframe.md +299 -0
  75. package/dist/skills/editframe-motion-design/references/1-intent.md +201 -0
  76. package/dist/skills/editframe-motion-design/references/2-physics-model.md +405 -0
  77. package/dist/skills/editframe-motion-design/references/3-attention.md +350 -0
  78. package/dist/skills/editframe-motion-design/references/4-process.md +418 -0
  79. package/dist/skills/editframe-vite-plugin/SKILL.md +75 -0
  80. package/dist/skills/editframe-vite-plugin/references/file-api.md +111 -0
  81. package/dist/skills/editframe-vite-plugin/references/getting-started.md +96 -0
  82. package/dist/skills/editframe-vite-plugin/references/jit-transcoding.md +91 -0
  83. package/dist/skills/editframe-vite-plugin/references/local-assets.md +75 -0
  84. package/dist/skills/editframe-vite-plugin/references/visual-testing.md +136 -0
  85. package/dist/skills/editframe-webhooks/SKILL.md +126 -0
  86. package/dist/skills/editframe-webhooks/references/events.md +382 -0
  87. package/dist/skills/editframe-webhooks/references/getting-started.md +232 -0
  88. package/dist/skills/editframe-webhooks/references/security.md +418 -0
  89. package/dist/skills/editframe-webhooks/references/testing.md +409 -0
  90. package/dist/skills/editframe-webhooks/references/troubleshooting.md +457 -0
  91. package/dist/templates/html/AGENTS.md +13 -0
  92. package/dist/templates/react/AGENTS.md +13 -0
  93. package/dist/utils.js +15 -16
  94. package/dist/utils.js.map +1 -1
  95. package/package.json +1 -1
  96. package/tsdown.config.ts +4 -0
  97. package/dist/detectAgent.js +0 -89
  98. package/dist/detectAgent.js.map +0 -1
@@ -0,0 +1,657 @@
1
+ ---
2
+ title: Active Root Temporal Element
3
+ description: Component that displays the ID of whichever root temporal element is currently active based on canvas selection state.
4
+ type: reference
5
+ nav:
6
+ parent: "Editor Shells"
7
+ priority: 20
8
+ api:
9
+ attributes:
10
+ - name: canvas
11
+ type: string
12
+ description: Canvas element ID or selector to bind to
13
+ properties:
14
+ - name: activeRootTemporal
15
+ type: "TemporalMixinInterface & HTMLElement | null"
16
+ description: Currently active root temporal element
17
+ react:
18
+ generate: true
19
+ componentName: ActiveRootTemporal
20
+ importPath: "@editframe/react"
21
+ additionalProps:
22
+ - name: className
23
+ type: string
24
+ description: CSS classes for styling
25
+ - name: onRootChange
26
+ type: "(event: CustomEvent) => void"
27
+ description: Callback fired when active root temporal changes
28
+ nav:
29
+ parent: "Components / Editor UI"
30
+ priority: 62
31
+ related: ["hierarchy", "canvas", "timeline-root"]
32
+ status: not-yet-exported
33
+ ---
34
+
35
+ <!-- html-only -->
36
+ # ef-active-root-temporal
37
+ <!-- /html-only -->
38
+ <!-- react-only -->
39
+ # ActiveRootTemporal
40
+ <!-- /react-only -->
41
+
42
+ Displays the ID of the active root temporal element from a canvas.
43
+
44
+ <!-- react-only -->
45
+ > **Note**: The ActiveRootTemporal component is currently not exported from `@editframe/react`. This documentation describes the underlying `ef-active-root-temporal` HTML element. To use it in React, you'll need to use the HTML element directly or wait for official React component export.
46
+
47
+ ## Import
48
+
49
+ When officially exported, usage will be:
50
+
51
+ ```tsx
52
+ import { ActiveRootTemporal } from "@editframe/react";
53
+ ```
54
+ <!-- /react-only -->
55
+
56
+ ## Basic Usage
57
+
58
+ <!-- html-only -->
59
+ Show the active root temporal ID:
60
+
61
+ ```html
62
+ <ef-active-root-temporal canvas="my-canvas">None</ef-active-root-temporal>
63
+
64
+ <ef-canvas id="my-canvas">
65
+ <ef-timegroup id="scene-1">
66
+ <!-- Content -->
67
+ </ef-timegroup>
68
+ <ef-timegroup id="scene-2">
69
+ <!-- Content -->
70
+ </ef-timegroup>
71
+ </ef-canvas>
72
+ ```
73
+
74
+ When you select an element in the canvas, the active root temporal ID displays.
75
+ <!-- /html-only -->
76
+ <!-- react-only -->
77
+ ```tsx
78
+ export const App = () => {
79
+ return (
80
+ <div className="h-screen flex flex-col">
81
+ {/* Header showing active timegroup */}
82
+ <div className="p-4 bg-gray-800 text-white">
83
+ <span className="mr-2">Active Timegroup:</span>
84
+ <ef-active-root-temporal canvas="editor-canvas" />
85
+ </div>
86
+
87
+ {/* Canvas */}
88
+ <div className="flex-1">
89
+ <ef-canvas id="editor-canvas">
90
+ <ef-timegroup id="root-tg" mode="sequence" className="w-[1920px] h-[1080px]">
91
+ <ef-video src="/assets/video.mp4" />
92
+ </ef-timegroup>
93
+ </ef-canvas>
94
+ </div>
95
+ </div>
96
+ );
97
+ };
98
+ ```
99
+ <!-- /react-only -->
100
+
101
+ ## Canvas Binding
102
+
103
+ <!-- html-only -->
104
+ Bind to a canvas by ID or selector:
105
+
106
+ ### By ID
107
+
108
+ ```html
109
+ <ef-active-root-temporal canvas="my-canvas"></ef-active-root-temporal>
110
+ <ef-canvas id="my-canvas"></ef-canvas>
111
+ ```
112
+
113
+ ### By Selector
114
+
115
+ ```html
116
+ <ef-active-root-temporal canvas=".editor-canvas"></ef-active-root-temporal>
117
+ <ef-canvas class="editor-canvas"></ef-canvas>
118
+ ```
119
+
120
+ ### Nearest Ancestor
121
+
122
+ Omit canvas attribute to use nearest ancestor:
123
+
124
+ ```html
125
+ <ef-canvas>
126
+ <ef-active-root-temporal></ef-active-root-temporal>
127
+ </ef-canvas>
128
+ ```
129
+ <!-- /html-only -->
130
+ <!-- react-only -->
131
+ ### Auto-Detection
132
+
133
+ ```tsx
134
+ export const AutoDetect = () => {
135
+ return (
136
+ <div>
137
+ {/* Will find nearest ef-canvas ancestor */}
138
+ <ef-canvas>
139
+ <div className="p-2 bg-gray-100">
140
+ <span>Current Root: </span>
141
+ <ef-active-root-temporal />
142
+ </div>
143
+
144
+ <ef-timegroup id="auto-detected-root" mode="sequence">
145
+ <ef-video src="/assets/video.mp4" />
146
+ </ef-timegroup>
147
+ </ef-canvas>
148
+ </div>
149
+ );
150
+ };
151
+ ```
152
+ <!-- /react-only -->
153
+
154
+ ## Active Root Temporal
155
+
156
+ The active root temporal is the topmost timegroup containing the selected element:
157
+
158
+ ```html
159
+ <ef-canvas id="canvas">
160
+ <ef-timegroup id="root-1">
161
+ <ef-timegroup id="child-1">
162
+ <div id="element-1">Content</div>
163
+ </ef-timegroup>
164
+ </ef-timegroup>
165
+ </ef-canvas>
166
+ ```
167
+
168
+ When `element-1` is selected, active root temporal is `root-1`.
169
+
170
+ ## Display Content
171
+
172
+ <!-- html-only -->
173
+ ### Default Content
174
+
175
+ Show ID of active root temporal:
176
+
177
+ ```html
178
+ <ef-active-root-temporal canvas="canvas"></ef-active-root-temporal>
179
+ <!-- Displays: "root-1" when root-1 is active -->
180
+ ```
181
+
182
+ ### Fallback Content
183
+
184
+ Provide fallback text for when no root is active:
185
+
186
+ ```html
187
+ <ef-active-root-temporal canvas="canvas">
188
+ No selection
189
+ </ef-active-root-temporal>
190
+ <!-- Displays: "No selection" when nothing is selected -->
191
+ ```
192
+ <!-- /html-only -->
193
+ <!-- react-only -->
194
+ ### With Hierarchy
195
+
196
+ ```tsx
197
+ export const EditorLayout = () => {
198
+ return (
199
+ <div className="h-screen flex flex-col">
200
+ {/* Top bar with active root display */}
201
+ <div className="p-2 bg-gray-800 text-white flex items-center gap-4">
202
+ <span className="text-sm">Active Root:</span>
203
+ <ef-active-root-temporal
204
+ canvas="canvas"
205
+ className="font-mono text-sm bg-gray-700 px-2 py-1 rounded"
206
+ />
207
+ </div>
208
+
209
+ {/* Main editor area */}
210
+ <div className="flex-1 flex">
211
+ <div className="w-64 border-r bg-gray-50">
212
+ <ef-hierarchy target="canvas" />
213
+ </div>
214
+
215
+ <div className="flex-1">
216
+ <ef-canvas id="canvas">
217
+ <ef-timegroup id="scene-1" mode="contain" className="w-[1920px] h-[1080px]">
218
+ <ef-video src="/assets/video.mp4" />
219
+ </ef-timegroup>
220
+ </ef-canvas>
221
+ </div>
222
+ </div>
223
+ </div>
224
+ );
225
+ };
226
+ ```
227
+
228
+ ### Styled Display
229
+
230
+ ```tsx
231
+ export const StyledDisplay = () => {
232
+ return (
233
+ <div className="flex items-center gap-2 p-4 bg-gray-900 text-white">
234
+ <svg className="w-4 h-4" fill="currentColor" viewBox="0 0 20 20">
235
+ <path d="M2 6a2 2 0 012-2h5l2 2h5a2 2 0 012 2v6a2 2 0 01-2 2H4a2 2 0 01-2-2V6z" />
236
+ </svg>
237
+ <span className="text-sm text-gray-400">Active Scene:</span>
238
+ <ef-active-root-temporal
239
+ canvas="canvas"
240
+ className="text-sm font-mono bg-gray-800 px-3 py-1 rounded border border-gray-700"
241
+ />
242
+ </div>
243
+ );
244
+ };
245
+ ```
246
+
247
+ ### Breadcrumb Navigation
248
+
249
+ ```tsx
250
+ export const BreadcrumbNav = () => {
251
+ return (
252
+ <div className="flex items-center gap-2 p-2 bg-white border-b text-sm">
253
+ <span className="text-gray-500">Project</span>
254
+ <span className="text-gray-400">/</span>
255
+ <span className="text-gray-500">Composition</span>
256
+ <span className="text-gray-400">/</span>
257
+ <ef-active-root-temporal
258
+ canvas="canvas"
259
+ className="font-medium text-blue-600"
260
+ />
261
+ </div>
262
+ );
263
+ };
264
+ ```
265
+ <!-- /react-only -->
266
+
267
+ ## Events
268
+
269
+ <!-- html-only -->
270
+ Listen for changes:
271
+
272
+ ```javascript
273
+ const canvas = document.querySelector('ef-canvas');
274
+
275
+ canvas.addEventListener('activeroottemporalchange', (e) => {
276
+ const { activeRootTemporal } = e.detail;
277
+ console.log('Active root:', activeRootTemporal?.id);
278
+ });
279
+ ```
280
+
281
+ The canvas fires this event, not ef-active-root-temporal.
282
+ <!-- /html-only -->
283
+ <!-- react-only -->
284
+ The canvas fires `activeroottemporalchange` when the active root changes:
285
+
286
+ ```typescript
287
+ interface ActiveRootTemporalChangeDetail {
288
+ id: string | null;
289
+ element: HTMLElement | null;
290
+ }
291
+ ```
292
+
293
+ Listen to this event to track changes:
294
+
295
+ ```tsx
296
+ useEffect(() => {
297
+ const canvas = document.getElementById("canvas");
298
+ if (!canvas) return;
299
+
300
+ const handleChange = (e: CustomEvent) => {
301
+ console.log("New active root:", e.detail.id);
302
+ };
303
+
304
+ canvas.addEventListener("activeroottemporalchange", handleChange);
305
+ return () => {
306
+ canvas.removeEventListener("activeroottemporalchange", handleChange);
307
+ };
308
+ }, []);
309
+ ```
310
+ <!-- /react-only -->
311
+
312
+ ## Use Cases
313
+
314
+ <!-- html-only -->
315
+ ### Timeline Scrubbing
316
+
317
+ Use active root temporal to determine which timeline to scrub:
318
+
319
+ ```javascript
320
+ const activeRootDisplay = document.querySelector('ef-active-root-temporal');
321
+ const canvas = document.querySelector('ef-canvas');
322
+
323
+ canvas.addEventListener('activeroottemporalchange', (e) => {
324
+ const rootTemporal = e.detail.activeRootTemporal;
325
+
326
+ if (rootTemporal) {
327
+ // Update scrubber to control this timegroup
328
+ scrubber.target = rootTemporal.id;
329
+ }
330
+ });
331
+ ```
332
+
333
+ ### Playback Controls
334
+
335
+ Connect playback controls to active root:
336
+
337
+ ```javascript
338
+ const canvas = document.querySelector('ef-canvas');
339
+ const controls = document.querySelector('ef-controls');
340
+
341
+ canvas.addEventListener('activeroottemporalchange', (e) => {
342
+ if (e.detail.activeRootTemporal) {
343
+ controls.target = e.detail.activeRootTemporal.id;
344
+ }
345
+ });
346
+ ```
347
+
348
+ ### Context Display
349
+
350
+ Show which composition is active:
351
+
352
+ ```html
353
+ <div class="toolbar">
354
+ <span class="label">Active Composition:</span>
355
+ <ef-active-root-temporal canvas="canvas" class="font-mono">
356
+ None
357
+ </ef-active-root-temporal>
358
+ </div>
359
+ ```
360
+ <!-- /html-only -->
361
+ <!-- react-only -->
362
+ - **Editor breadcrumbs**: Show current timegroup in navigation
363
+ - **Scene indicator**: Display active scene in multi-scene compositions
364
+ - **Context display**: Show editing context to users
365
+ - **Debug info**: Display active root for development
366
+ - **Status bar**: Show current focus in status/toolbar
367
+ <!-- /react-only -->
368
+
369
+ ## Multiple Canvases
370
+
371
+ <!-- html-only -->
372
+ Use separate instances for multiple canvases:
373
+
374
+ ```html
375
+ <ef-active-root-temporal canvas="canvas-1">None</ef-active-root-temporal>
376
+ <ef-canvas id="canvas-1"></ef-canvas>
377
+
378
+ <ef-active-root-temporal canvas="canvas-2">None</ef-active-root-temporal>
379
+ <ef-canvas id="canvas-2"></ef-canvas>
380
+ ```
381
+
382
+ Each instance tracks its own canvas independently.
383
+ <!-- /html-only -->
384
+ <!-- react-only -->
385
+ ```tsx
386
+ export const MultiCanvas = () => {
387
+ return (
388
+ <div className="grid grid-cols-2 gap-4 p-4">
389
+ {/* Canvas 1 */}
390
+ <div className="space-y-2">
391
+ <div className="p-2 bg-blue-100">
392
+ Canvas 1 Root:
393
+ <ef-active-root-temporal canvas="canvas-1" />
394
+ </div>
395
+ <ef-canvas id="canvas-1">
396
+ <ef-timegroup id="canvas-1-root" mode="contain">
397
+ <ef-video src="/assets/video1.mp4" />
398
+ </ef-timegroup>
399
+ </ef-canvas>
400
+ </div>
401
+
402
+ {/* Canvas 2 */}
403
+ <div className="space-y-2">
404
+ <div className="p-2 bg-green-100">
405
+ Canvas 2 Root:
406
+ <ef-active-root-temporal canvas="canvas-2" />
407
+ </div>
408
+ <ef-canvas id="canvas-2">
409
+ <ef-timegroup id="canvas-2-root" mode="contain">
410
+ <ef-video src="/assets/video2.mp4" />
411
+ </ef-timegroup>
412
+ </ef-canvas>
413
+ </div>
414
+ </div>
415
+ );
416
+ };
417
+ ```
418
+ <!-- /react-only -->
419
+
420
+ ## Selection Behavior
421
+
422
+ Active root temporal updates when:
423
+
424
+ - Element is selected in canvas
425
+ - Selection changes to different element
426
+ - Selection is cleared
427
+
428
+ Selection of nested elements always resolves to their root temporal ancestor.
429
+
430
+ ## Finding Root Temporal
431
+
432
+ The canvas walks up the DOM tree from selected element to find the topmost timegroup:
433
+
434
+ ```javascript
435
+ // Simplified algorithm
436
+ let current = selectedElement;
437
+ let rootTemporal = null;
438
+
439
+ while (current && current !== canvas) {
440
+ if (current.tagName === 'EF-TIMEGROUP') {
441
+ rootTemporal = current;
442
+ }
443
+ current = current.parentElement;
444
+ }
445
+
446
+ return rootTemporal;
447
+ ```
448
+
449
+ <!-- html-only -->
450
+ ## Null State
451
+
452
+ When no element is selected or selected element has no root temporal ancestor:
453
+
454
+ ```javascript
455
+ const display = document.querySelector('ef-active-root-temporal');
456
+ console.log(display.activeRootTemporal); // null
457
+
458
+ // Text content shows fallback
459
+ console.log(display.textContent); // "None" (from slot content)
460
+ ```
461
+ <!-- /html-only -->
462
+
463
+ ## Temporal Mixin Interface
464
+
465
+ Active root temporal is typed as `TemporalMixinInterface`:
466
+
467
+ ```typescript
468
+ interface TemporalMixinInterface {
469
+ id: string;
470
+ durationMs: number;
471
+ currentTimeMs: number;
472
+ play(): void;
473
+ pause(): void;
474
+ // ... other temporal properties and methods
475
+ }
476
+ ```
477
+
478
+ This ensures the element has timing capabilities.
479
+
480
+ <!-- html-only -->
481
+ ## Canvas Property
482
+
483
+ Access the bound canvas element:
484
+
485
+ ```javascript
486
+ const display = document.querySelector('ef-active-root-temporal');
487
+
488
+ // Canvas element reference (internal)
489
+ console.log(display.canvasElement); // EFCanvas instance
490
+ ```
491
+ <!-- /html-only -->
492
+
493
+ <!-- react-only -->
494
+ ## With Selection Context
495
+
496
+ ```tsx
497
+ export const SelectionAware = () => {
498
+ const [activeRoot, setActiveRoot] = useState<string | null>(null);
499
+
500
+ useEffect(() => {
501
+ const canvas = document.getElementById("canvas");
502
+ if (!canvas) return;
503
+
504
+ const handleRootChange = (e: CustomEvent) => {
505
+ setActiveRoot(e.detail?.id || null);
506
+ };
507
+
508
+ canvas.addEventListener("activeroottemporalchange" as any, handleRootChange);
509
+ return () => {
510
+ canvas.removeEventListener("activeroottemporalchange" as any, handleRootChange);
511
+ };
512
+ }, []);
513
+
514
+ return (
515
+ <div className="space-y-4">
516
+ <div className="p-4 bg-gray-100">
517
+ <div className="text-sm text-gray-600">Active Root ID:</div>
518
+ <div className="font-mono">{activeRoot || "None"}</div>
519
+ </div>
520
+
521
+ <ef-canvas id="canvas">
522
+ <ef-timegroup id="main-sequence" mode="sequence">
523
+ <ef-timegroup id="scene-1" mode="contain">
524
+ <ef-video src="/assets/video1.mp4" />
525
+ </ef-timegroup>
526
+ <ef-timegroup id="scene-2" mode="contain">
527
+ <ef-video src="/assets/video2.mp4" />
528
+ </ef-timegroup>
529
+ </ef-timegroup>
530
+ </ef-canvas>
531
+ </div>
532
+ );
533
+ };
534
+ ```
535
+
536
+ ## Dynamic Root Display
537
+
538
+ ```tsx
539
+ export const DynamicRootDisplay = () => {
540
+ const canvasRef = useRef<any>(null);
541
+
542
+ const selectRoot = (rootId: string) => {
543
+ if (canvasRef.current) {
544
+ canvasRef.current.selectElement(rootId);
545
+ }
546
+ };
547
+
548
+ return (
549
+ <div className="space-y-4">
550
+ {/* Root selector */}
551
+ <div className="p-4 bg-gray-100 space-x-2">
552
+ <button
553
+ onClick={() => selectRoot("scene-1")}
554
+ className="px-3 py-1 bg-blue-500 text-white rounded"
555
+ >
556
+ Scene 1
557
+ </button>
558
+ <button
559
+ onClick={() => selectRoot("scene-2")}
560
+ className="px-3 py-1 bg-blue-500 text-white rounded"
561
+ >
562
+ Scene 2
563
+ </button>
564
+ </div>
565
+
566
+ {/* Active root display */}
567
+ <div className="p-4 bg-white border rounded">
568
+ <span className="text-gray-600">Current: </span>
569
+ <ef-active-root-temporal canvas="canvas" className="font-semibold" />
570
+ </div>
571
+
572
+ {/* Canvas */}
573
+ <ef-canvas ref={canvasRef} id="canvas">
574
+ <ef-timegroup id="scene-1" mode="contain">
575
+ <ef-video src="/assets/video1.mp4" />
576
+ </ef-timegroup>
577
+ <ef-timegroup id="scene-2" mode="contain">
578
+ <ef-video src="/assets/video2.mp4" />
579
+ </ef-timegroup>
580
+ </ef-canvas>
581
+ </div>
582
+ );
583
+ };
584
+ ```
585
+
586
+ ## Future React Component
587
+
588
+ When officially exported, usage will be:
589
+
590
+ ```tsx
591
+ import { ActiveRootTemporal } from "@editframe/react";
592
+
593
+ <ActiveRootTemporal
594
+ canvas="canvas-id"
595
+ className="font-mono"
596
+ onRootChange={(e) => console.log(e.detail)}
597
+ />
598
+ ```
599
+ <!-- /react-only -->
600
+
601
+ ## Styling
602
+
603
+ Style the display element:
604
+
605
+ ```css
606
+ ef-active-root-temporal {
607
+ display: inline-block;
608
+ font-family: monospace;
609
+ padding: 4px 8px;
610
+ background: #f5f5f5;
611
+ border: 1px solid #ddd;
612
+ border-radius: 4px;
613
+ }
614
+ ```
615
+
616
+ ## Reactive Updates
617
+
618
+ Display automatically updates when selection changes. No manual refresh needed.
619
+
620
+ <!-- html-only -->
621
+ ## Disconnection
622
+
623
+ When disconnected, the element:
624
+
625
+ - Removes event listener from canvas
626
+ - Clears active root temporal reference
627
+ - Cleans up internal state
628
+
629
+ ## Initialization
630
+
631
+ On connection, the element:
632
+
633
+ 1. Finds canvas (by attribute, selector, or ancestor)
634
+ 2. Reads initial active root temporal
635
+ 3. Sets up event listener
636
+ 4. Updates display
637
+ <!-- /html-only -->
638
+
639
+ ## Important Notes
640
+
641
+ <!-- html-only -->
642
+ - Canvas attribute can be ID or CSS selector
643
+ - Falls back to nearest ancestor canvas if not specified
644
+ - Only displays root temporal elements (top-level timegroups)
645
+ - Updates automatically - no manual refresh needed
646
+ - Shows element ID, not a friendly name
647
+ - Returns null when no root temporal is active
648
+ <!-- /html-only -->
649
+ <!-- react-only -->
650
+ - Currently not exported from React package - use HTML element
651
+ - Canvas attribute can be ID or CSS selector
652
+ - Falls back to nearest ancestor canvas if not specified
653
+ - Only displays root temporal elements (top-level timegroups)
654
+ - Updates automatically - no manual refresh needed
655
+ - Shows element ID, not a friendly name
656
+ - Returns empty string when no root temporal is active
657
+ <!-- /react-only -->