Skill detail
editor-gui
Builds video editing interfaces with Editframe GUI components: timeline, scrubber, canvas, preview, and playback controls. Editor tooling, not editing itself.
Inspect before use
Read the source instructions and check the requirements before you install this skill.
SKILL.md
The saved excerpt is a snapshot from when this skill was listed. The external source remains the complete and most current version.
---
name: editor-gui
description: "Build video editing interfaces with Editframe's GUI components. Assemble a timeline, scrubber, canvas, preview, playback controls, and transform handles into a custom editor. Use this for a timeline, scrubber, preview, playback control, volume control, mute button, fullscreen toggle, picture-in-picture toggle, resolution picker, trim handle, or hierarchy panel."
license: MIT
metadata:
author: editframe
version: "2.0"
---
# Editor Toolkit
Build a video editing interface by composing GUI components. Each component is a self-contained custom element. Each component connects to your composition through a `target` attribute. Build the composition itself with the `composition` skill. These components add the controls and views around it.
## Quick Start
```html
<ef-timegroup id="my-video">
<ef-video src="/video.mp4"></ef-video>
</ef-timegroup>
<ef-controls target="my-video">
<ef-toggle-play></ef-toggle-play>
<ef-scrubber></ef-scrubber>
<ef-time-display></ef-time-display>
</ef-controls>
```
`ef-timegroup` sets no `mode` here, so it defaults to `contain`. Its duration comes from `video.mp4`'s own length, not from a hardcoded number. See the `composition` skill's Timegroups & sequencing section for the full duration model.
## Core Concepts: Target & Bridge
Each playback control (`ef-play`, `ef-pause`, `ef-toggle-play`, `ef-toggle-loop`, `ef-volume`, `ef-mute`, `ef-scrubber`, `ef-time-display`) resolves the composition it drives in this order:
1. Its own `target="id-or-selector"` attribute, if set. This resolves directly.
2. Otherwise, it walks up through ancestor `ef-controls`, `ef-preview`, and `ef-configuration` elements. An ancestor with its own `target` resolves there, in one hop. A bare `ef-configuration` ancestor resolves to itself. The control climbs past a bare `ef-controls` or `ef-preview` ancestor to look further up.
3. As a last resort, it resolves to the nearest enclosing temporal root.
`ef-controls` is a pure proxy. It renders nothing itself. It gives a group of descendant controls a shared `target`, so each control does not need its own:
```html
<ef-timegroup id="my-video" mode="contain">…</ef-timegroup>
<!-- Elsewhere in the DOM -->
<ef-controls target="my-video">
<ef-toggle-play></ef-toggle-play>
<ef-scrubber></ef-scrubber>
</ef-controls>
```
`ef-canvas`, `ef-hierarchy`, and `ef-timeline` share selection state through a separate, independent mechanism: a shared `SelectionBridge`, keyed by the resolved composition root. This is not the playback bridge above. Selecting a row in `ef-hierarchy` highlights it in `ef-canvas`, and the reverse also works. Neither element needs to reference the other directly.
## Preview & Canvas
`ef-preview` is a thin passthrough container. It tracks which element the pointer hovers over, and fires `focus-changed`. `ef-canvas` uses it internally for hover highlighting.
`ef-canvas` wraps your composition as light-DOM children, the same as `ef-preview`. It adds click-to-select, drag-to-move, corner-resize, and rotate directly on top of your composition. It shares selection state with `ef-hierarchy` and `ef-timeline` through `SelectionBridge`. When you set no explicit `target`, it auto-assigns one from the first slotted temporal child's `id`. Set `readonly` to keep the overlays visible but non-interactive.
```html
<ef-canvas class="relative">
<ef-timegroup id="scene" mode="contain" class="w-[1920px] h-[1080px]">
<ef-video id="bg" src="/bg.mp4" class="absolute inset-0 size-full object-cover"></ef-video>
<ef-text id="title" duration="5s" class="absolute top-12 left-12 text-6xl text-white">Title</ef-text>
</ef-timegroup>
</ef-canvas>
```
- Click a selectable element, any `TemporalElement` with an `id`, to select it. This replaces the current selection.
- Click the empty canvas background to deselect.
- Drag from the empty background to draw a marquee. This selects every element the marquee touches. Hold Shift or Cmd/CtrlRead the full source on GitHub (opens external page)