Controls

The <ef-controls> element is a context bridge that allows you to control an <ef-preview> or <ef-workbench> element from anywhere in your application, even when they're not direct ancestors. It proxies playback state, timing information, and other contexts from a target element to its children.

Basic Usage

<ef-preview id="my-preview">
  <ef-timegroup slot="canvas" mode="contain" className="w-[1920px] h-[1080px]">
    <ef-video src="/assets/video.mp4"></ef-video>
  </ef-timegroup>
</ef-preview>

<!-- Controls can be placed anywhere, not inside the preview -->
<ef-controls target="my-preview">
  <ef-toggle-play>
    <button slot="play">Play</button>
    <button slot="pause">Pause</button>
  </ef-toggle-play>
  <ef-scrubber></ef-scrubber>
  <ef-time-display></ef-time-display>
</ef-controls>

How Context Bridging Works

Normally, control elements like <ef-scrubber> and <ef-toggle-play> need to be descendants of an <ef-preview> or <ef-workbench> to access playback context. The <ef-controls> element solves this by:

  1. Finding the target element by its ID
  2. Subscribing to all relevant contexts from that target
  3. Re-providing those contexts to its own children
  4. Keeping all contexts synchronized in real-time

This enables flexible UI layouts where controls can be positioned independently of the video preview.

Learn More: For a detailed explanation of how the target system works and what temporal elements are, see Understanding Temporal Elements.

Attributes

target

typestring
DOM
readwrite

The ID of the element to control, typically an <ef-preview> or <ef-workbench>.

The controls element will look for an element with this ID in the document and bridge its context to child elements.

Example:

<ef-preview id="main-preview">...</ef-preview>
<ef-controls target="main-preview">...</ef-controls>

Proxied Contexts

The <ef-controls> element automatically bridges the following contexts from the target element:

| Context | Type | Description | |---------|------|-------------| | playing | boolean | Whether the video is currently playing | | loop | boolean | Whether the video should loop on completion | | currentTimeMs | number | Current playback time in milliseconds | | durationMs | number | Total duration in milliseconds | | targetTimegroup | EFTimegroup | Reference to the root timegroup | | focusedElement | HTMLElement | Currently focused element for editing | | focusContext | FocusContext | Focus management context |

Child elements of <ef-controls> can read and write to these contexts as if they were direct children of the target element.

Examples

Remote Control Panel

Create a separate control panel that can be positioned anywhere:

<div className="layout">
  <div className="preview-area">
    <ef-preview id="editor-preview">
      <ef-timegroup slot="canvas" mode="contain" className="w-[1920px] h-[1080px]">
        <ef-video src="/video.mp4"></ef-video>
      </ef-timegroup>
    </ef-preview>
  </div>
  
  <div className="control-panel">
    <ef-controls target="editor-preview">
      <div className="flex flex-col gap-4 p-4 bg-gray-800 rounded">
        <h3 className="text-white">Playback Controls</h3>
        
        <div className="flex gap-2">
          <ef-toggle-play>
            <button className="btn" slot="play">▶ Play</button>
            <button className="btn" slot="pause">⏸ Pause</button>
          </ef-toggle-play>
          
          <ef-toggle-loop>
            <button className="btn">🔁 Loop</button>
          </ef-toggle-loop>
        </div>
        
        <ef-scrubber></ef-scrubber>
        <ef-time-display></ef-time-display>
      </div>
    </ef-controls>
  </div>
</div>

Multiple Control Sets

Control the same preview from multiple locations:

<ef-preview id="video-editor">
  <!-- Video content -->
</ef-preview>

<!-- Main controls -->
<ef-controls target="video-editor">
  <ef-scrubber></ef-scrubber>
  <ef-toggle-play>...</ef-toggle-play>
</ef-controls>

<!-- Secondary controls in a different part of the UI -->
<ef-controls target="video-editor">
  <ef-time-display></ef-time-display>
  <ef-toggle-loop>...</ef-toggle-loop>
</ef-controls>

Use controls in a modal or overlay that's outside the normal DOM hierarchy:

<!-- Main video editor -->
<ef-preview id="main-editor">
  <ef-timegroup slot="canvas" mode="contain" className="w-[1920px] h-[1080px]">
    <ef-video src="/video.mp4"></ef-video>
  </ef-timegroup>
</ef-preview>

<!-- Modal rendered at document root -->
<dialog open>
  <h2>Playback Settings</h2>
  <ef-controls target="main-editor">
    <ef-toggle-loop>
      <label>
        <input type="checkbox" /> Loop playback
      </label>
    </ef-toggle-loop>
    <ef-time-display></ef-time-display>
  </ef-controls>
</dialog>

Use Cases

Separated UI Layout

Build layouts where the video preview and controls are in completely different parts of your application:

  • Video player in the main content area
  • Controls in a sticky footer
  • Timeline in a collapsible sidebar
  • Settings in a modal dialog

Portal-Based Rendering

When using React portals, Vue teleports, or similar patterns that render content outside the normal component tree, <ef-controls> maintains the connection to the target element.

Multi-Monitor Editing

Build applications where the video preview is on one screen and the control interface is on another, all controlled through a single set of contexts.

Technical Notes

  • Uses Lit's @lit/context for efficient context updates
  • Automatically subscribes to context changes for real-time synchronization
  • Renders with display: block by default (can be styled with CSS)
  • Uses createRenderRoot() override to render in light DOM
  • Updates are batched for performance

Limitations

  • The target element must have an id attribute
  • The target element must be present in the DOM when controls are initialized
  • Context updates flow both ways: children can modify target state
  • EFPreview - Preview container that can be controlled
  • EFTogglePlay - Playback control for use within ef-controls
  • EFToggleLoop - Loop control for use within ef-controls
  • EFScrubber - Scrubbing control for use within ef-controls
  • EFTimeDisplay - Time display for use within ef-controls