@editframe/create 0.43.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 (99) hide show
  1. package/README.md +11 -0
  2. package/dist/index.js +16 -28
  3. package/dist/index.js.map +1 -1
  4. package/dist/skills/editframe-brand-video-generator/README.md +155 -0
  5. package/dist/skills/editframe-brand-video-generator/SKILL.md +207 -0
  6. package/dist/skills/editframe-brand-video-generator/references/brand-examples.md +178 -0
  7. package/dist/skills/editframe-brand-video-generator/references/color-psychology.md +227 -0
  8. package/dist/skills/editframe-brand-video-generator/references/composition-patterns.md +383 -0
  9. package/dist/skills/editframe-brand-video-generator/references/editing.md +66 -0
  10. package/dist/skills/editframe-brand-video-generator/references/emotional-arcs.md +496 -0
  11. package/dist/skills/editframe-brand-video-generator/references/genre-selection.md +135 -0
  12. package/dist/skills/editframe-brand-video-generator/references/transition-styles.md +611 -0
  13. package/dist/skills/editframe-brand-video-generator/references/typography-personalities.md +326 -0
  14. package/dist/skills/editframe-brand-video-generator/references/video-archetypes.md +86 -0
  15. package/dist/skills/editframe-brand-video-generator/references/video-fundamentals.md +169 -0
  16. package/dist/skills/editframe-brand-video-generator/references/visual-metaphors.md +50 -0
  17. package/dist/skills/editframe-composition/SKILL.md +169 -0
  18. package/dist/skills/editframe-composition/references/audio.md +483 -0
  19. package/dist/skills/editframe-composition/references/captions.md +844 -0
  20. package/dist/skills/editframe-composition/references/composition-model.md +73 -0
  21. package/dist/skills/editframe-composition/references/configuration.md +403 -0
  22. package/dist/skills/editframe-composition/references/css-parts.md +105 -0
  23. package/dist/skills/editframe-composition/references/css-variables.md +640 -0
  24. package/dist/skills/editframe-composition/references/entry-points.md +810 -0
  25. package/dist/skills/editframe-composition/references/events.md +499 -0
  26. package/dist/skills/editframe-composition/references/getting-started.md +259 -0
  27. package/dist/skills/editframe-composition/references/hooks.md +234 -0
  28. package/dist/skills/editframe-composition/references/image.md +241 -0
  29. package/dist/skills/editframe-composition/references/r3f.md +580 -0
  30. package/dist/skills/editframe-composition/references/render-api.md +484 -0
  31. package/dist/skills/editframe-composition/references/render-strategies.md +119 -0
  32. package/dist/skills/editframe-composition/references/render-to-video.md +1101 -0
  33. package/dist/skills/editframe-composition/references/scripting.md +606 -0
  34. package/dist/skills/editframe-composition/references/sequencing.md +116 -0
  35. package/dist/skills/editframe-composition/references/server-rendering.md +753 -0
  36. package/dist/skills/editframe-composition/references/surface.md +329 -0
  37. package/dist/skills/editframe-composition/references/text.md +627 -0
  38. package/dist/skills/editframe-composition/references/time-model.md +99 -0
  39. package/dist/skills/editframe-composition/references/timegroup-modes.md +102 -0
  40. package/dist/skills/editframe-composition/references/timegroup.md +457 -0
  41. package/dist/skills/editframe-composition/references/timeline-root.md +398 -0
  42. package/dist/skills/editframe-composition/references/transcription.md +47 -0
  43. package/dist/skills/editframe-composition/references/transitions.md +608 -0
  44. package/dist/skills/editframe-composition/references/use-media-info.md +357 -0
  45. package/dist/skills/editframe-composition/references/video.md +506 -0
  46. package/dist/skills/editframe-composition/references/waveform.md +327 -0
  47. package/dist/skills/editframe-editor-gui/SKILL.md +152 -0
  48. package/dist/skills/editframe-editor-gui/references/active-root-temporal.md +657 -0
  49. package/dist/skills/editframe-editor-gui/references/canvas.md +947 -0
  50. package/dist/skills/editframe-editor-gui/references/controls.md +366 -0
  51. package/dist/skills/editframe-editor-gui/references/dial.md +756 -0
  52. package/dist/skills/editframe-editor-gui/references/editor-toolkit.md +587 -0
  53. package/dist/skills/editframe-editor-gui/references/filmstrip.md +460 -0
  54. package/dist/skills/editframe-editor-gui/references/fit-scale.md +772 -0
  55. package/dist/skills/editframe-editor-gui/references/focus-overlay.md +561 -0
  56. package/dist/skills/editframe-editor-gui/references/hierarchy.md +544 -0
  57. package/dist/skills/editframe-editor-gui/references/overlay-item.md +634 -0
  58. package/dist/skills/editframe-editor-gui/references/overlay-layer.md +429 -0
  59. package/dist/skills/editframe-editor-gui/references/pan-zoom.md +568 -0
  60. package/dist/skills/editframe-editor-gui/references/pause.md +397 -0
  61. package/dist/skills/editframe-editor-gui/references/play.md +370 -0
  62. package/dist/skills/editframe-editor-gui/references/preview.md +391 -0
  63. package/dist/skills/editframe-editor-gui/references/resizable-box.md +749 -0
  64. package/dist/skills/editframe-editor-gui/references/scrubber.md +588 -0
  65. package/dist/skills/editframe-editor-gui/references/thumbnail-strip.md +566 -0
  66. package/dist/skills/editframe-editor-gui/references/time-display.md +492 -0
  67. package/dist/skills/editframe-editor-gui/references/timeline-ruler.md +489 -0
  68. package/dist/skills/editframe-editor-gui/references/timeline.md +604 -0
  69. package/dist/skills/editframe-editor-gui/references/toggle-loop.md +618 -0
  70. package/dist/skills/editframe-editor-gui/references/toggle-play.md +526 -0
  71. package/dist/skills/editframe-editor-gui/references/transform-handles.md +924 -0
  72. package/dist/skills/editframe-editor-gui/references/trim-handles.md +725 -0
  73. package/dist/skills/editframe-editor-gui/references/workbench.md +453 -0
  74. package/dist/skills/editframe-motion-design/SKILL.md +101 -0
  75. package/dist/skills/editframe-motion-design/references/0-editframe.md +299 -0
  76. package/dist/skills/editframe-motion-design/references/1-intent.md +201 -0
  77. package/dist/skills/editframe-motion-design/references/2-physics-model.md +405 -0
  78. package/dist/skills/editframe-motion-design/references/3-attention.md +350 -0
  79. package/dist/skills/editframe-motion-design/references/4-process.md +418 -0
  80. package/dist/skills/editframe-vite-plugin/SKILL.md +75 -0
  81. package/dist/skills/editframe-vite-plugin/references/file-api.md +111 -0
  82. package/dist/skills/editframe-vite-plugin/references/getting-started.md +96 -0
  83. package/dist/skills/editframe-vite-plugin/references/jit-transcoding.md +91 -0
  84. package/dist/skills/editframe-vite-plugin/references/local-assets.md +75 -0
  85. package/dist/skills/editframe-vite-plugin/references/visual-testing.md +136 -0
  86. package/dist/skills/editframe-webhooks/SKILL.md +126 -0
  87. package/dist/skills/editframe-webhooks/references/events.md +382 -0
  88. package/dist/skills/editframe-webhooks/references/getting-started.md +232 -0
  89. package/dist/skills/editframe-webhooks/references/security.md +418 -0
  90. package/dist/skills/editframe-webhooks/references/testing.md +409 -0
  91. package/dist/skills/editframe-webhooks/references/troubleshooting.md +457 -0
  92. package/dist/templates/html/AGENTS.md +13 -0
  93. package/dist/templates/react/AGENTS.md +13 -0
  94. package/dist/utils.js +15 -16
  95. package/dist/utils.js.map +1 -1
  96. package/package.json +2 -2
  97. package/tsdown.config.ts +4 -0
  98. package/dist/detectAgent.js +0 -89
  99. package/dist/detectAgent.js.map +0 -1
@@ -0,0 +1,588 @@
1
+ ---
2
+ title: Scrubber Element
3
+ description: Timeline scrubber with horizontal seek and vertical zoom modes, keyboard shortcuts, and frame-accurate time control.
4
+ type: reference
5
+ nav:
6
+ parent: "Timeline"
7
+ priority: 12
8
+ api:
9
+ attributes:
10
+ - name: target
11
+ type: string
12
+ description: ID of target temporal element to control
13
+ - name: orientation
14
+ type: string
15
+ default: horizontal
16
+ description: Layout orientation ("horizontal" or "vertical")
17
+ - name: current-time-ms
18
+ type: number
19
+ description: Current playback time in milliseconds
20
+ - name: duration-ms
21
+ type: number
22
+ description: Total duration in milliseconds
23
+ - name: zoom-scale
24
+ type: number
25
+ default: 1.0
26
+ description: Zoom level for vertical timeline mode
27
+ - name: fps
28
+ type: number
29
+ description: Frame rate for frame-snapping behavior
30
+ parts:
31
+ - name: scrubber
32
+ description: Main scrubber container
33
+ - name: progress
34
+ description: Progress bar fill (horizontal mode only)
35
+ - name: handle
36
+ description: Draggable handle (horizontal mode only)
37
+ - name: playhead
38
+ description: Vertical playhead line (vertical mode only)
39
+ events:
40
+ - name: seek
41
+ detail: number
42
+ description: Emitted when user seeks to a new time position
43
+ react:
44
+ generate: true
45
+ componentName: Scrubber
46
+ importPath: "@editframe/react"
47
+ propMapping:
48
+ current-time-ms: currentTimeMs
49
+ duration-ms: durationMs
50
+ zoom-scale: zoomScale
51
+ additionalProps:
52
+ - name: className
53
+ type: string
54
+ description: CSS classes for styling
55
+ - name: containerWidth
56
+ type: number
57
+ description: Container width for calculations
58
+ - name: rawScrubTimeMs
59
+ type: "number | null"
60
+ description: Raw scrub time without frame snapping
61
+ - name: scrollContainerRef
62
+ type: React.RefObject<HTMLElement>
63
+ description: Reference to scroll container for timeline sync
64
+ - name: isScrubbingRef
65
+ type: React.MutableRefObject<boolean>
66
+ description: Ref to track scrubbing state
67
+ - name: onSeek
68
+ type: "(time: number) => void"
69
+ description: Callback fired when seeking to a new time
70
+ nav:
71
+ parent: "Components / Timeline Controls"
72
+ priority: 60
73
+ related: ["time-display", "controls"]
74
+ ---
75
+
76
+ <!-- html-only -->
77
+ # ef-scrubber
78
+ <!-- /html-only -->
79
+ <!-- react-only -->
80
+ # Scrubber
81
+ <!-- /react-only -->
82
+
83
+ Timeline scrubber control for navigating playback time. Supports both horizontal progress bar mode and vertical timeline mode with zoom.
84
+
85
+ <!-- react-only -->
86
+ ## Import
87
+
88
+ ```tsx
89
+ import { Scrubber } from "@editframe/react";
90
+ ```
91
+
92
+ Also available: `ScrubberProps` type for TypeScript.
93
+ <!-- /react-only -->
94
+
95
+ ## Basic Usage
96
+
97
+ <!-- html-only -->
98
+ Horizontal scrubber with progress bar.
99
+
100
+ ```html live
101
+ <ef-timegroup mode="contain" class="w-[720px] h-[480px] bg-black" id="scrubber-demo">
102
+ <ef-video src="https://assets.editframe.com/bars-n-tone.mp4" class="size-full object-contain"></ef-video>
103
+ </ef-timegroup>
104
+ <div class="flex flex-col gap-2 p-4 bg-gray-900 rounded-lg mt-4">
105
+ <ef-scrubber target="scrubber-demo"></ef-scrubber>
106
+ <ef-controls target="scrubber-demo" class="flex gap-2 items-center">
107
+ <ef-toggle-play class="px-3 py-1 bg-blue-600 text-white rounded"></ef-toggle-play>
108
+ <ef-time-display class="text-white text-sm"></ef-time-display>
109
+ </ef-controls>
110
+ </div>
111
+ ```
112
+ <!-- /html-only -->
113
+ <!-- react-only -->
114
+ ```tsx
115
+ import { Preview, Scrubber } from "@editframe/react";
116
+
117
+ <div className="flex flex-col gap-2">
118
+ <Preview className="w-full h-[600px]" />
119
+ <Scrubber className="w-full h-2 bg-gray-700 rounded cursor-pointer" />
120
+ </div>
121
+ ```
122
+
123
+ The scrubber automatically connects to the nearest timeline context via Preview or Controls.
124
+ <!-- /react-only -->
125
+
126
+ <!-- react-only -->
127
+ ## In Control Bar
128
+
129
+ Typical control bar layout:
130
+
131
+ ```tsx
132
+ import { TogglePlay, Scrubber, TimeDisplay } from "@editframe/react";
133
+
134
+ export const ControlBar = () => {
135
+ return (
136
+ <div className="bg-gray-800 p-4 flex items-center gap-4">
137
+ <TogglePlay>
138
+ <button slot="play" className="w-10 h-10 text-white">▶</button>
139
+ <button slot="pause" className="w-10 h-10 text-white">⏸</button>
140
+ </TogglePlay>
141
+
142
+ <TimeDisplay className="text-white text-sm font-mono" />
143
+ <Scrubber className="flex-1 h-2" />
144
+ </div>
145
+ );
146
+ };
147
+ ```
148
+ <!-- /react-only -->
149
+
150
+ ## Vertical Timeline Mode
151
+
152
+ <!-- html-only -->
153
+ Vertical scrubber displays a playhead line that moves across a timeline. Used in `ef-timeline` and `ef-filmstrip` components.
154
+
155
+ ```html live
156
+ <ef-timegroup mode="contain" class="w-[720px] h-[480px] bg-black" id="vertical-demo">
157
+ <ef-video src="https://assets.editframe.com/bars-n-tone.mp4" class="size-full object-contain"></ef-video>
158
+ </ef-timegroup>
159
+ <div class="mt-4 h-[120px] relative overflow-hidden bg-gray-900 rounded-lg">
160
+ <ef-scrubber
161
+ target="vertical-demo"
162
+ orientation="vertical"
163
+ zoom-scale="2"
164
+ class="absolute inset-0"
165
+ ></ef-scrubber>
166
+ <div class="absolute top-0 left-0 right-0 h-6 bg-gray-800 text-white text-xs flex items-center justify-center">
167
+ Timeline (scroll to see full width)
168
+ </div>
169
+ </div>
170
+ <div class="mt-2 flex gap-2">
171
+ <ef-controls target="vertical-demo">
172
+ <ef-toggle-play class="px-3 py-1 bg-blue-600 text-white rounded"></ef-toggle-play>
173
+ </ef-controls>
174
+ </div>
175
+ ```
176
+ <!-- /html-only -->
177
+ <!-- react-only -->
178
+ Use vertical orientation for timeline views:
179
+
180
+ ```tsx
181
+ <Scrubber
182
+ orientation="vertical"
183
+ className="w-full h-full"
184
+ />
185
+ ```
186
+
187
+ Vertical scrubbers are typically used in filmstrip/timeline views where the playhead moves vertically.
188
+ <!-- /react-only -->
189
+
190
+ ## Frame Snapping
191
+
192
+ When `fps` is set, scrubbing snaps to frame boundaries.
193
+
194
+ <!-- html-only -->
195
+ ```html live
196
+ <ef-timegroup mode="contain" class="w-[720px] h-[480px] bg-black" id="snap-demo" fps="30">
197
+ <ef-video src="https://assets.editframe.com/bars-n-tone.mp4" class="size-full object-contain"></ef-video>
198
+ </ef-timegroup>
199
+ <div class="flex flex-col gap-2 p-4 bg-gray-900 rounded-lg mt-4">
200
+ <div class="text-white text-sm mb-2">Scrubbing snaps to 30fps frame boundaries:</div>
201
+ <ef-scrubber target="snap-demo" fps="30"></ef-scrubber>
202
+ <ef-controls target="snap-demo" class="flex gap-2 items-center">
203
+ <ef-toggle-play class="px-3 py-1 bg-blue-600 text-white rounded"></ef-toggle-play>
204
+ <ef-time-display class="text-white text-sm"></ef-time-display>
205
+ </ef-controls>
206
+ </div>
207
+ ```
208
+ <!-- /html-only -->
209
+ <!-- react-only -->
210
+ Enable frame-accurate seeking:
211
+
212
+ ```tsx
213
+ <Scrubber
214
+ fps={30}
215
+ className="w-full h-2"
216
+ />
217
+ ```
218
+
219
+ When `fps` is provided, the scrubber snaps to frame boundaries during seeking.
220
+ <!-- /react-only -->
221
+
222
+ ## Custom Styling
223
+
224
+ <!-- html-only -->
225
+ ### CSS Parts
226
+
227
+ Style scrubber appearance using `::part()` selectors.
228
+
229
+ ```html live
230
+ <ef-timegroup mode="contain" class="w-[720px] h-[480px] bg-black" id="styled-scrubber">
231
+ <ef-video src="https://assets.editframe.com/bars-n-tone.mp4" class="size-full object-contain"></ef-video>
232
+ </ef-timegroup>
233
+ <div class="flex flex-col gap-2 p-4 bg-gray-900 rounded-lg mt-4">
234
+ <ef-scrubber target="styled-scrubber" id="custom-scrubber"></ef-scrubber>
235
+ <ef-controls target="styled-scrubber" class="flex gap-2 items-center">
236
+ <ef-toggle-play class="px-3 py-1 bg-blue-600 text-white rounded"></ef-toggle-play>
237
+ <ef-time-display class="text-white text-sm"></ef-time-display>
238
+ </ef-controls>
239
+ </div>
240
+
241
+ <style>
242
+ #custom-scrubber::part(scrubber) {
243
+ background: linear-gradient(to right, #1e293b, #334155);
244
+ height: 8px;
245
+ border-radius: 4px;
246
+ }
247
+
248
+ #custom-scrubber::part(progress) {
249
+ background: linear-gradient(to right, #3b82f6, #8b5cf6);
250
+ border-radius: 4px;
251
+ }
252
+
253
+ #custom-scrubber::part(handle) {
254
+ width: 16px;
255
+ height: 16px;
256
+ background: white;
257
+ box-shadow: 0 2px 4px rgba(0,0,0,0.3);
258
+ }
259
+ </style>
260
+ ```
261
+ <!-- /html-only -->
262
+ <!-- react-only -->
263
+ Style the scrubber track and handle:
264
+
265
+ ```tsx
266
+ <Scrubber
267
+ className="w-full h-1.5 bg-white/20 rounded-full cursor-pointer"
268
+ />
269
+ ```
270
+ <!-- /react-only -->
271
+
272
+ ## CSS Custom Properties
273
+
274
+ Control scrubber appearance through CSS variables:
275
+
276
+ <!-- html-only -->
277
+ ```css
278
+ ef-scrubber {
279
+ --ef-scrubber-height: 4px;
280
+ --ef-scrubber-background: rgba(255, 255, 255, 0.2);
281
+ --ef-scrubber-progress-color: #fff;
282
+ --ef-scrubber-handle-size: 12px;
283
+ }
284
+ ```
285
+ <!-- /html-only -->
286
+ <!-- react-only -->
287
+ ```tsx
288
+ <Scrubber
289
+ className="w-full"
290
+ style={{
291
+ '--ef-scrubber-height': '6px',
292
+ '--ef-scrubber-background': 'rgba(255, 255, 255, 0.2)',
293
+ '--ef-scrubber-progress-color': '#3b82f6',
294
+ '--ef-scrubber-handle-size': '16px',
295
+ } as React.CSSProperties}
296
+ />
297
+ ```
298
+
299
+ ### Available CSS Variables
300
+
301
+ | Variable | Default | Description |
302
+ |----------|---------|-------------|
303
+ | `--ef-scrubber-height` | `4px` | Track height |
304
+ | `--ef-scrubber-background` | `rgba(255, 255, 255, 0.2)` | Track background color |
305
+ | `--ef-scrubber-progress-color` | `#fff` | Progress bar and handle color |
306
+ | `--ef-scrubber-handle-size` | `12px` | Handle diameter |
307
+ <!-- /react-only -->
308
+
309
+ <!-- react-only -->
310
+ ## CSS Shadow Parts
311
+
312
+ Style internal elements using `::part()`:
313
+
314
+ ```tsx
315
+ <Scrubber
316
+ className={`
317
+ w-full h-1.5 bg-white/20 rounded-full cursor-pointer
318
+ [&::part(progress)]:bg-red-500
319
+ [&::part(progress)]:rounded-full
320
+ [&::part(handle)]:bg-white
321
+ [&::part(handle)]:w-3
322
+ [&::part(handle)]:h-3
323
+ [&::part(handle)]:rounded-full
324
+ [&::part(handle)]:shadow-lg
325
+ `}
326
+ />
327
+ ```
328
+
329
+ ### Available Parts
330
+
331
+ | Part | Description |
332
+ |------|-------------|
333
+ | `scrubber` | The track container |
334
+ | `progress` | The filled progress bar |
335
+ | `handle` | The draggable seek handle |
336
+ <!-- /react-only -->
337
+
338
+ ## Seek Events
339
+
340
+ <!-- html-only -->
341
+ ```html
342
+ <ef-scrubber target="my-video" id="my-scrubber"></ef-scrubber>
343
+
344
+ <script>
345
+ const scrubber = document.getElementById('my-scrubber');
346
+ scrubber.addEventListener('seek', (e) => {
347
+ console.log('Seeking to:', e.detail, 'ms');
348
+ });
349
+ </script>
350
+ ```
351
+ <!-- /html-only -->
352
+ <!-- react-only -->
353
+ Listen to seek events:
354
+
355
+ ```tsx
356
+ import { Scrubber } from "@editframe/react";
357
+
358
+ <Scrubber
359
+ onSeek={(time) => {
360
+ console.log('Seeking to:', time, 'ms');
361
+ }}
362
+ className="w-full h-2"
363
+ />
364
+ ```
365
+ <!-- /react-only -->
366
+
367
+ <!-- react-only -->
368
+ ## With Timeline Sync
369
+
370
+ Sync scrubber with a scrollable timeline:
371
+
372
+ ```tsx
373
+ import { useRef, useState } from "react";
374
+ import { Scrubber } from "@editframe/react";
375
+
376
+ export const TimelineWithScrubber = () => {
377
+ const scrollContainerRef = useRef<HTMLDivElement>(null);
378
+ const isScrubbingRef = useRef(false);
379
+ const [zoomScale, setZoomScale] = useState(1);
380
+
381
+ return (
382
+ <div>
383
+ <div
384
+ ref={scrollContainerRef}
385
+ className="overflow-x-auto"
386
+ >
387
+ {/* Timeline content */}
388
+ </div>
389
+
390
+ <Scrubber
391
+ orientation="vertical"
392
+ zoomScale={zoomScale}
393
+ scrollContainerRef={scrollContainerRef}
394
+ isScrubbingRef={isScrubbingRef}
395
+ className="w-full h-full"
396
+ />
397
+ </div>
398
+ );
399
+ };
400
+ ```
401
+ <!-- /react-only -->
402
+
403
+ <!-- react-only -->
404
+ ## TypeScript Types
405
+
406
+ ```tsx
407
+ import type { ScrubberProps } from "@editframe/react";
408
+
409
+ const scrubberConfig: ScrubberProps = {
410
+ orientation: "horizontal",
411
+ zoomScale: 1.5,
412
+ fps: 30,
413
+ className: "w-full h-2",
414
+ onSeek: (time) => console.log(time),
415
+ };
416
+ ```
417
+ <!-- /react-only -->
418
+
419
+ <!-- react-only -->
420
+ ## Styled Examples
421
+
422
+ ### Gradient Progress
423
+
424
+ ```tsx
425
+ <Scrubber
426
+ className="w-full h-2"
427
+ style={{
428
+ '--ef-scrubber-background': 'rgba(0, 0, 0, 0.2)',
429
+ '--ef-scrubber-progress-color': 'linear-gradient(to right, #3b82f6, #8b5cf6)',
430
+ } as React.CSSProperties}
431
+ />
432
+ ```
433
+
434
+ ### Large Handle
435
+
436
+ ```tsx
437
+ <Scrubber
438
+ className="w-full h-3"
439
+ style={{
440
+ '--ef-scrubber-height': '12px',
441
+ '--ef-scrubber-handle-size': '20px',
442
+ '--ef-scrubber-progress-color': '#10b981',
443
+ } as React.CSSProperties}
444
+ />
445
+ ```
446
+
447
+ ### Minimal Scrubber
448
+
449
+ ```tsx
450
+ <Scrubber
451
+ className="w-full h-0.5"
452
+ style={{
453
+ '--ef-scrubber-height': '2px',
454
+ '--ef-scrubber-handle-size': '0px',
455
+ '--ef-scrubber-background': 'transparent',
456
+ '--ef-scrubber-progress-color': '#ef4444',
457
+ } as React.CSSProperties}
458
+ />
459
+ ```
460
+ <!-- /react-only -->
461
+
462
+ <!-- react-only -->
463
+ ## Full Editor Example
464
+
465
+ Complete video editor with styled scrubber:
466
+
467
+ ```tsx
468
+ import {
469
+ Preview,
470
+ TogglePlay,
471
+ ToggleLoop,
472
+ Scrubber,
473
+ TimeDisplay,
474
+ } from "@editframe/react";
475
+
476
+ export const VideoEditor = () => {
477
+ return (
478
+ <div className="h-screen flex flex-col bg-gray-900">
479
+ <div className="flex-1 flex items-center justify-center p-8">
480
+ <Preview className="w-full max-w-[1280px] aspect-video bg-black rounded-lg" />
481
+ </div>
482
+
483
+ <div className="bg-gray-800 border-t border-gray-700">
484
+ <div className="flex items-center gap-4 px-6 py-3">
485
+ <TogglePlay>
486
+ <button slot="play" className="w-8 h-8 text-white hover:text-blue-400">
487
+
488
+ </button>
489
+ <button slot="pause" className="w-8 h-8 text-white hover:text-gray-400">
490
+
491
+ </button>
492
+ </TogglePlay>
493
+
494
+ <TimeDisplay className="text-white text-sm font-mono min-w-[120px]" />
495
+
496
+ <div className="flex-1">
497
+ <Scrubber
498
+ className="w-full"
499
+ style={{
500
+ '--ef-scrubber-height': '6px',
501
+ '--ef-scrubber-background': 'rgba(255, 255, 255, 0.15)',
502
+ '--ef-scrubber-progress-color': '#3b82f6',
503
+ '--ef-scrubber-handle-size': '14px',
504
+ } as React.CSSProperties}
505
+ />
506
+ </div>
507
+
508
+ <ToggleLoop>
509
+ <button slot="off" className="w-8 h-8 text-gray-400 hover:text-white">
510
+ 🔁
511
+ </button>
512
+ <button slot="on" className="w-8 h-8 text-green-400 hover:text-green-300">
513
+ 🔁
514
+ </button>
515
+ </ToggleLoop>
516
+ </div>
517
+ </div>
518
+ </div>
519
+ );
520
+ };
521
+ ```
522
+
523
+ ## Minimal Controls
524
+
525
+ Compact control layout:
526
+
527
+ ```tsx
528
+ <div className="flex items-center gap-2 p-2 bg-black/80 rounded">
529
+ <TogglePlay className="w-6 h-6 text-white">
530
+ <button slot="play">▶</button>
531
+ <button slot="pause">⏸</button>
532
+ </TogglePlay>
533
+ <Scrubber className="flex-1 h-1" />
534
+ </div>
535
+ ```
536
+ <!-- /react-only -->
537
+
538
+ ## Usage Modes
539
+
540
+ **Horizontal mode** — Compact progress bar for playback controls:
541
+ - Shows progress fill and draggable handle
542
+ - Best for control panels and compact UIs
543
+ - Automatically reads duration from context
544
+
545
+ **Vertical mode** — Timeline scrubber for editing:
546
+ - Shows vertical playhead line
547
+ <!-- html-only -->
548
+ - Requires `zoom-scale` for proper positioning
549
+ - Used internally by `ef-timeline` and `ef-filmstrip`
550
+ <!-- /html-only -->
551
+ <!-- react-only -->
552
+ - Requires `zoomScale` for proper positioning
553
+ - Used internally by Timeline and Filmstrip components
554
+ <!-- /react-only -->
555
+ - Supports scrollable timelines with edge detection
556
+
557
+ ## Interaction
558
+
559
+ The scrubber supports:
560
+ - **Click:** Jump to position
561
+ - **Drag:** Scrub through timeline
562
+ - **Touch:** Mobile-friendly touch controls
563
+
564
+ All interactions automatically update the connected timeline's playback position.
565
+
566
+ ## Accessibility
567
+
568
+ The scrubber is keyboard accessible and supports:
569
+ - Click to seek
570
+ - Drag to scrub
571
+ - Touch gestures on mobile devices
572
+
573
+ For enhanced accessibility, consider wrapping in a labeled container:
574
+
575
+ <!-- html-only -->
576
+ ```html
577
+ <div role="group" aria-label="Video scrubber">
578
+ <ef-scrubber target="my-video"></ef-scrubber>
579
+ </div>
580
+ ```
581
+ <!-- /html-only -->
582
+ <!-- react-only -->
583
+ ```tsx
584
+ <div role="group" aria-label="Video scrubber">
585
+ <Scrubber className="w-full h-2" />
586
+ </div>
587
+ ```
588
+ <!-- /react-only -->