Skip to content

fix(core): track overlay on inner-container scroll (#913)#1690

Open
aalimovs wants to merge 2 commits into
puckeditor:mainfrom
aalimovs:fix/913-overlay-scroll-tracking
Open

fix(core): track overlay on inner-container scroll (#913)#1690
aalimovs wants to merge 2 commits into
puckeditor:mainfrom
aalimovs:fix/913-overlay-scroll-tracking

Conversation

@aalimovs

@aalimovs aalimovs commented Jun 6, 2026

Copy link
Copy Markdown

Not gonna lie, thank you Claude.

However, this was extensively manually reviewed and tested, for both iframe and non-iframe setup.

Happy to clean up comments if this is approved.

Closes #913.

Description

Fixes issue with horizontal scrolling when a component is selected or hovered, exactly like on video in #913.

The overlay is portaled outside the scrolling container, but getStyle() was compensating with getDeepScrollPosition(el), which summed the scroll of every ancestor, including the inner DropZone. That extra amount cancelled out the item's movement, so the overlay froze.

Now it only accounts for the scroll of the element the overlay is actually attached to:

  • non-iframe: the [data-puck-preview] container's own scroll
  • iframe / body portal: the document's own scroll

Changes made

  • getStyle() compensates for only the portal target's own scroll instead of summing every ancestor.
  • Hovered components (not just selected/dragging) now re-sync on scroll, so hover overlays track too — without starting the per-frame rAF loop on hover.
  • Removed the now-unused get-deep-scroll-position helper (internal-only).

How to test

See #913 video.

The selection/hover overlay is portaled outside any scrollable DropZone and
positioned absolutely against the portal target. getStyle() compensated for
scroll using getDeepScrollPosition(el), which summed *every* ancestor's
scroll — including intermediate scroll containers between the item and the
portal target. That term cancelled the item's getBoundingClientRect()
movement, so the overlay froze whenever an inner container (e.g. a DropZone
with overflow:auto) was scrolled, even though page scroll worked.

Compensate for only the portal target's own scroll instead:
- non-iframe: the [data-puck-preview] container's own scrollLeft/Top
- iframe / document-body portal: the document's own scrollX/Y

Also re-sync the overlay on scroll while hovering (not just when selected or
dragging) so hovered overlays track inner-container scroll, while keeping the
continuous rAF layout-shift tracker gated to selected/dragging to avoid a
per-frame loop on hover. Removes the now-unused get-deep-scroll-position helper.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@vercel

vercel Bot commented Jun 6, 2026

Copy link
Copy Markdown

@aalimovs is attempting to deploy a commit to the Puck Team on Vercel.

A member of the Team first needs to authorize it.

@FedericoBonel FedericoBonel requested a review from chrisvxd June 8, 2026 01:22
@vercel

vercel Bot commented Jun 8, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
puck-demo Ready Ready Preview, Comment Jun 12, 2026 12:17pm
puck-docs Ready Ready Preview Jun 12, 2026 12:17pm

Request Review

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes overlay positioning for selected/hovered components when scrolling within inner overflow containers (notably horizontally overflowing DropZones), addressing #913 by compensating only for the portal target’s own scroll rather than summing all ancestor scroll offsets.

Changes:

  • Updated DraggableComponent overlay getStyle() to compensate for portal target scroll only (preview container scroll in non-iframe mode; document scroll in iframe/body-portal mode).
  • Ensured hovered (and indicative-hovered) overlays re-sync on scroll/resize without enabling the continuous per-frame rAF loop (reserved for selected/dragging).
  • Removed the unused internal get-deep-scroll-position helper.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
packages/core/lib/get-deep-scroll-position.ts Removed unused deep ancestor scroll-summing helper now that overlay positioning no longer needs it.
packages/core/components/DraggableComponent/index.tsx Reworked overlay scroll compensation logic and expanded scroll/resize resync to hovered states while keeping rAF usage limited to selected/dragging.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@chrisvxd

Copy link
Copy Markdown
Contributor

@shannonhochkins would you mind checking this against your Home Assistant use-case?

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.

DropZones That Overflow in the X Axis Provide Buggy Visual Feedback When Scrolling

3 participants