fix: resolve drop and click positions in viewport coordinates - #3225
fix: resolve drop and click positions in viewport coordinates#3225christianhg wants to merge 1 commit into
Conversation
🦋 Changeset detectedLatest commit: acf9123 The changes in this PR will be included in the next version bump. This PR includes changesets to release 14 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Bundle Stats✅ No significant changes. All scenario measurements (7)🗺️
Significant means at least 1.0 KB and 1% gzip, or at least 5 ms and 10% import time. |
`getEventPositionBlock` compared `event.pageY` (page coordinates, scroll offset included) against `getBoundingClientRect` values (viewport coordinates) in all three checks. On a window-scrolled page the inflated `pageY` made the below-last-block check fire for any pointer position and pushed the half detection past `height / 2`, so every drop position resolved to 'end': the indicator stuck to bottom edges and drops landed after the hovered block. An inner scroll container keeps `pageY` and `clientY` equal, which is why Studio never showed it. Compare `clientY` throughout. The first/last block boundary checks also move behind a `nodePath.length === 0` gate: they can only decide anything when the pointer is over the editor's own surface (its padding), because over a block the pointer sits inside that block's band, between the first block's top and the last block's bottom. That removes two rect reads per drag event on the hot path. Pinned by a test dispatching a `dragover` through the real pipeline with the trusted-event coordinate relationship simulated on the instance (`pageY = clientY + 2000`; synthetic events always report `pageY === clientY`, so a real window scroll cannot exercise the old code from a test): red on `pageY`, hovering a block's upper half must resolve 'start'.
747cefd to
acf9123
Compare
Take an editor on a page where the whole window scrolls, like the playground or a plain embed (Studio is unaffected: its panes scroll an inner container). Before scrolling, drag and drop works. Scroll down and drag a block: the drop line now always sits at the bottom edge of whatever block you hover, and dropping always puts the dragged block after it. Dropping before a block becomes impossible.
The cause is a units mix-up. To decide whether the pointer is in the upper or lower half of a block, the code compared the pointer position measured from the top of the page (
pageY, which includes the scroll distance) with the block position measured from the top of the visible window (getBoundingClientRect). Once the page is scrolled, the pointer number is bigger than every block number by the scroll distance, so the pointer always looks like it is below everything and every check answersend. The fix measures both from the window:clientY.A small perf rider: the "above the first block / below the last block" checks now run only when the pointer is over the editor's own padding. Over a block they can never be true, and skipping them removes two layout reads per drag event.
The pinning test sets
pageYon the event by hand, the way a real scrolled page would; synthetic events always havepageYequal toclientY, so a real scroll cannot trigger the bug from a test. It fails on the old code. Full editor suite green (2041 passed, 3 expected fail).