Skip to content

feat(studio): preserve drop position when dropping blocks onto preview#1010

Merged
miguel-heygen merged 9 commits into
mainfrom
worktree-feat+studio-blocks-drop-position
May 21, 2026
Merged

feat(studio): preserve drop position when dropping blocks onto preview#1010
miguel-heygen merged 9 commits into
mainfrom
worktree-feat+studio-blocks-drop-position

Conversation

@miguel-heygen
Copy link
Copy Markdown
Collaborator

Summary

  • Blocks dragged from the Blocks panel and dropped onto the composition preview now land at the exact position where they were dropped, instead of always being placed at (0, 0)
  • The preview viewport converts screen coordinates to composition space using the stage element's bounding rect, correctly accounting for zoom and pan transforms
  • A visual drop indicator (dashed border overlay with accent color) appears while dragging over the preview area

Changes

  • usePreviewBlockDrop.ts (new) — Extracted hook handling drag-over/drop events on the preview viewport, coordinate conversion from screen → composition space, and block centering
  • NLEPreview.tsx — Wires the new hook into the preview viewport's drag event handlers and renders the drop indicator overlay
  • NLELayout.tsx — Forwards onPreviewBlockDrop callback to NLEPreview
  • StudioPreviewArea.tsx — Accepts and passes the new callback
  • App.tsx — Creates handlePreviewBlockDrop that calls addBlockToProject with visualPosition
  • blockInstaller.ts — Accepts optional visualPosition and uses it for the inserted element's left/top CSS

Test plan

  • Open Studio with Blocks panel enabled (VITE_STUDIO_ENABLE_BLOCKS_PANEL=true)
  • Drag a block from the Blocks panel onto the composition preview at a non-center position
  • Verify the block's left/top in the generated HTML corresponds to the drop position in composition space (not 0,0)
  • Verify the dashed-border drop indicator appears while dragging over the preview
  • Verify dropping on the timeline still works as before (start/track placement, no visual position)
  • Verify the "Add" button click still places blocks at (0,0) as before
  • Verify zooming/panning the preview doesn't break coordinate conversion

Blocks dragged from the Blocks panel and dropped onto the composition
preview now land at the position where they were dropped, instead of
always being placed at (0, 0).

The preview viewport converts screen coordinates to composition space
using the stage element's bounding rect, accounting for zoom and pan.
A visual drop indicator (dashed border overlay) appears while dragging
over the preview.
- Rename "Blocks" tab to "Catalog"
- Replace fullscreen hover popup with inline preview in main area
- Fix z-index: newly added blocks/components use max existing z-index + 1
  instead of element count, ensuring they appear on top
Render the catalog hover preview as a full-bleed video inside the
preview overlay slot instead of a dimmed card overlay on top.
VITE_STUDIO_* env vars set in the user's shell had no effect when
running `hyperframes preview` because the pre-built studio bundle had
them baked at Vite build time.

The embedded Hono server now collects VITE_STUDIO_* vars from
process.env and injects them as a `window.__HF_STUDIO_ENV__` script
tag into index.html. The client merges this runtime object on top of
the baked `import.meta.env`, so flags like
VITE_STUDIO_ENABLE_BLOCKS_PANEL=1 work as expected at runtime.
The DomEditOverlay sits at z-10 with pointer-events:auto over the
preview, intercepting all drag events before they reach NLEPreview's
viewport. Move block drop handling from NLEPreview up to the wrapper
div in NLELayout that contains both the preview and the overlay, so
drag-and-drop from the Catalog panel onto the preview area works
regardless of inspector state.
Replace fragile regex z-index parsing with getComputedStyle on the
preview iframe elements — the same source of truth the inspector uses.

Rename "Layer" to "Z-index" in the design panel for clarity.
Blocks were using their own native dimensions (e.g. 1920x1080) instead
of the host composition dimensions (e.g. 1280x720), causing them to
overflow the viewport and break the layout. The block's iframe scales
its content to fit the container, so using host dimensions is correct.
insertTimelineAssetIntoSource now detects the parent indent level and
adds the new element with matching child indentation. Block attributes
are written one-per-line for readability.
Blocks and components now start at the current playhead position
instead of being appended after all existing content. If the new
element extends beyond the root composition's data-duration, the
root is automatically extended to fit.
@miguel-heygen miguel-heygen force-pushed the worktree-feat+studio-blocks-drop-position branch from 8162c90 to 67701df Compare May 21, 2026 22:28
@miguel-heygen miguel-heygen merged commit d50c48a into main May 21, 2026
11 of 12 checks passed
@miguel-heygen miguel-heygen deleted the worktree-feat+studio-blocks-drop-position branch May 21, 2026 22:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant