ef-preview
Attributes
targetstringID of timegroup to preview (inherited from EFTargetable)
Preview container with automatic focus tracking for interactive composition editing.
Basic Usage
Wrap a composition to enable preview mode:
<ef-preview class="w-[720px] h-[480px] bg-gray-100 border border-gray-300 rounded"><ef-timegroup mode="contain" class="size-full bg-black"><ef-video src="https://assets.editframe.com/bars-n-tone.mp4" class="size-full object-contain"></ef-video></ef-timegroup></ef-preview>
The preview element provides a viewing area with a crosshair cursor by default.
With Controls
Focus Tracking
ef-preview tracks which temporal element (timegroup, video, audio, etc.) is currently under the cursor:
<div><ef-preview id="focus-demo" class="w-[720px] h-[480px] bg-gray-100 border border-gray-300 rounded"><ef-timegroup mode="contain" class="size-full bg-black"><ef-video src="https://assets.editframe.com/bars-n-tone.mp4" class="size-full object-contain"></ef-video><div class="absolute top-4 left-4 bg-white/90 backdrop-blur px-3 py-2 rounded"><p class="text-sm font-semibold">Hover over elements</p><p id="focus-output" class="text-xs text-gray-600 mt-1">Focused: None</p></div></ef-timegroup></ef-preview><script>const preview = document.getElementById('focus-demo');const output = document.getElementById('focus-output');// Listen for focus changes via custom eventpreview.addEventListener('pointerover', (e) => {if (e.target !== preview) {output.textContent = `Focused: ${e.target.tagName.toLowerCase()}`;}});preview.addEventListener('pointerout', () => {output.textContent = 'Focused: None';});</script></div>
Context Provision
ef-preview provides the currently focused element via Lit context. This enables other components to react to focus changes:
import { consume } from '@lit/context';import { focusedElementContext } from '@editframe/elements';@consume({ context: focusedElementContext })focusedElement?: HTMLElement;
For example, a selection overlay can highlight the focused element, or a properties panel can show details about the focused element.
Target Binding
Use the target attribute to bind the preview to a specific timegroup:
<div><ef-timegroup id="preview-target" mode="contain" class="w-[720px] h-[480px] bg-black"><ef-video src="https://assets.editframe.com/bars-n-tone.mp4" class="size-full object-contain"></ef-video><div class="absolute top-4 left-4 bg-blue-500 text-white px-3 py-2 rounded"><p class="text-sm font-semibold">Target Composition</p></div></ef-timegroup><ef-preview target="preview-target" class="w-[360px] h-[240px] mt-4 bg-gray-100 border border-gray-300 rounded"><!-- Preview mirrors the target timegroup above --></ef-preview></div>
This allows the preview to display a timegroup defined elsewhere in the DOM.
Focus Detection Behavior
Focus is determined by finding the closest temporal element in the DOM tree:
- User hovers over an element
- Preview searches up the DOM tree from the hovered element
- First temporal ancestor is marked as focused (timegroup, video, audio, image, etc.)
- Non-temporal elements (like
<div>) are skipped
This means hovering over text inside a video element will focus the video, not the text.
Focus Overlay Integration
Combine with ef-focus-overlay to visually highlight the focused element:
<ef-preview class="w-[720px] h-[480px] bg-gray-100 border border-gray-300 rounded relative"><ef-timegroup mode="contain" class="size-full bg-black"><ef-video src="https://assets.editframe.com/bars-n-tone.mp4" class="size-full object-contain"></ef-video><div class="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 bg-white/10 backdrop-blur border-2 border-white/50 px-6 py-4 rounded-lg"><p class="text-white text-lg font-semibold">Hover to focus</p></div></ef-timegroup><!-- Focus overlay would go here in a real editor --></ef-preview>
Building an Editor
Use ef-preview as the foundation for a composition editor:
<div class="bg-gray-900 p-4 rounded-lg"><div class="flex gap-4"><!-- Preview area --><ef-preview class="flex-1 bg-gray-800 border border-gray-700 rounded"><ef-timegroup mode="sequence" class="w-[720px] h-[480px] bg-black"><ef-timegroup mode="fixed" duration="3s" class="absolute size-full flex items-center justify-center"><div class="text-white text-4xl font-bold">Scene 1</div></ef-timegroup><ef-timegroup mode="fixed" duration="3s" class="absolute size-full flex items-center justify-center"><div class="text-white text-4xl font-bold">Scene 2</div></ef-timegroup></ef-timegroup></ef-preview><!-- Properties panel --><div class="w-64 bg-gray-800 border border-gray-700 rounded p-4"><h3 class="text-white font-semibold mb-2">Properties</h3><p class="text-gray-400 text-sm">Hover elements to inspect</p></div></div></div>
Styling
The preview element has these default styles:
display: block- Block-level containerposition: relative- For positioning overlayscursor: crosshair- Visual feedback for interactive mode
Override with classes:
<ef-preview class="w-full h-screen cursor-default"><!-- Content --></ef-preview>
Events
Focus tracking uses standard pointer events internally:
pointerover- Element gains focuspointerout- Element loses focus
Listen to these events on the preview element to react to focus changes:
const preview = document.querySelector('ef-preview');preview.addEventListener('pointerover', (e) => {if (e.target !== preview) {console.log('Focused:', e.target);}});preview.addEventListener('pointerout', (e) => {console.log('Lost focus');});
Focus Clearing
Focus is cleared when:
- Moving outside the preview entirely
- Moving to the preview element itself (not a child)
- Moving to an element that's not within a temporal
This ensures focus only highlights meaningful composition elements.
Use Cases
Video Editor: Display composition with interactive element selection
<ef-preview><ef-timegroup mode="contain"><ef-video src="video.mp4"></ef-video></ef-timegroup></ef-preview>
Properties Inspector: Show details about focused elements
<ef-preview id="editor"><ef-timegroup><!-- composition --></ef-timegroup></ef-preview><div id="properties-panel"><!-- shows focused element props --></div>
Selection System: Highlight and select elements for editing
<ef-preview><ef-timegroup><ef-video id="clip1"></ef-video><ef-text id="title"></ef-text></ef-timegroup></ef-preview>
Nested Previews
Previews can be nested — each maintains its own focus state:
<ef-preview class="outer"><ef-timegroup><ef-preview class="inner"><ef-timegroup><!-- nested composition --></ef-timegroup></ef-preview></ef-timegroup></ef-preview>
The inner preview tracks focus independently of the outer preview.