Repository navigation
fix(webkit): stop re-anchoring the popover panel when its own content scrolls - #891
Merged
Merged
Conversation
… scrolls The scroll listener is registered in the capture phase (scroll does not bubble), so it also fired for the panel's own scroll container. Repositioning there read two getBoundingClientRects and rewrote the panel's inline style on every scrolled frame, for a trigger that had not moved — which is what made a long scrollable panel stutter. Bail out early when the scroll target is inside the panel, before either the dismiss or the reposition path.
gabriel-lisboa-azion
added a commit
that referenced
this pull request
Aug 14, 2026
The design-system half of this branch's working tree, committed here so the main-based branches it was split onto (#891-#897) can be merged back in: the popover inner-scroll fix, the toast-item and progress-bar corrections, the two arrival animations, and the create-surface / errors / navigation skills.
gabriel-lisboa-azion
force-pushed
the
fix/popover-inner-scroll-anchor
branch
from
August 17, 2026 12:41
6e7776e to
2bc01ac
Compare
isaque-bock-azion
approved these changes
Aug 17, 2026
guilherme-santana-azion
approved these changes
Aug 17, 2026
gabriel-lisboa-azion
added a commit
that referenced
this pull request
Aug 26, 2026
Brings in the 17 commits main has since 2026-08-17 — the webkit documentation category (#919), the shared leading column for Select / MultiSelect / Dropdown (#935), resizable-panel (#902), the copy-button tooltip and card-box header inset (#936), --container-site (#923), the page-enter / content-enter arrivals (#896), the colored-icon currentColor fix (#930) and the skills that landed with them. Conflict resolution, all fifteen: Demo wins where it already carries work that is still an OPEN PR on main and main's side is the older shape that PR rewrote — toast-item (#900's `h-[1lh]` line box over #892's `self-center`), use-placement and popover.test (#932's translate anchoring over #891's prose), and the theme animation tokens, where the entry-count canary confirms every main entry survived alongside demo's. Main wins where its side is a superset or the corrected form — DESIGN.md (gains `text-body-prose-md` and `.layout-column-docs`), package.json (keeping demo's footer block would have duplicated the four keys main already merged in above it), and resizable-panel.test, whose named imports are the form that keeps CodeQL from reading a compiler-generated `.vue` default export as undefined. Both sides where each added something: .size-limit.json keeps demo's ratcheted 1.1 KB footer-root budget and takes main's fourteen doc-* entries; the ui-craft skill and the CLI plan keep demo's microcopy routing without duplicating main's entry. Generated artifacts were rebuilt rather than hand-resolved — theme dist via build:tokens, catalog.json via catalog:build — and both carry each side's tokens and all 258 exports.
isaque-bock-azion
added a commit
that referenced
this pull request
Sep 9, 2026
…ansition (#932) * fix(webkit): place overlay panels with translate so re-anchors can transition Three fixes to `usePlacement`, all of them about a panel that moves after it is already up. THE PANEL IS PLACED WITH `translate`, NOT `top`/`left`. A translate is a compositor property, so re-anchoring an OPEN panel can be transitioned into place instead of snapping a layout property. And `translate` is a property of its own, so it composes with the `transform: scale(...)` the open/close keyframes animate rather than overwriting it — which a `transform: translate3d(...)` here would. `anchored` GATES THAT TRANSITION. It turns true one frame AFTER the opening placements land, so the entrance stays the panel's own scale animation and only later re-anchors glide. Without it a panel would travel in from the off-screen seed. It resets on close but the panel is NOT moved off-screen there: it is still in the DOM playing its leave animation. THE PANEL IS MEASURED WITH `offsetWidth`/`offsetHeight`, NOT `getBoundingClientRect`. The rect reports the TRANSFORMED box and the panel opens under `scale(0.9) → scale(1)`: read mid-animation it was up to 10% narrow, which placed a centred tooltip 4.1px off its trigger and left it there. The layout box does not depend on which frame of the entrance it is read on. A ResizeObserver RE-ANCHORS AN OPEN PANEL WHOSE CONTENT CHANGES SIZE. A centred panel's position is computed from its measured width, so a panel that resizes after placement keeps coordinates for the width it used to have — and nothing else catches it, since the window has not resized and the page has not scrolled. Measured on the copy control, whose tooltip swaps "Copy code" for "Copied" while the pointer is still on it: the panel lost 21px of width, slid 4px, and ended 10.4px off centre in one frame. A transform does not affect the observed box and placement only writes position, so this cannot feed back into itself. Preserves #891 (`fix(webkit): stop re-anchoring the popover panel when its own content scrolls`), which landed on main after this work started. The inner-scroll guard and its regression test are byte-identical in behaviour; only the comments differ, and the ones kept here are supersets that add why repositioning on an inner scroll also cost two bounding rects and an inline-style write per frame. * test(storybook): regenerate the dropdown and tooltip baselines for the translate anchoring * test(storybook): regenerate the dropdown and tooltip mobile/tablet baselines on the merged tree Both main (regular type weight, shared leading column) and this branch (translate anchoring) had regenerated these eight snapshots; the merge could keep only one side, so they were regenerated from the merged code by the baseline workflow (run 34390189299). --------- Co-authored-by: Isaque dos Santos <isaque.santos@azion.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
usePlacement's scroll listener is in the capture phase (scroll does not bubble), so it also fired for the panel's own scroll container — repositioning read twogetBoundingClientRects and rewrote the panel's inline style on every scrolled frame, for a trigger that had not moved. That is what made a long scrollable panel (the "+N overflow" list) stutter.How to test
cd packages/webkit && npx vitest run src/components/overlay/popover/popover.test.ts→ 35 passed, including the newdoes not re-measure the trigger when the panel scrolls, but does when the page does.pnpm storybook:dev→ Components/Overlay/Popover. Open a panel whose content overflows and scroll inside it: the panel stays put and the list scrolls smoothly. Then scroll the page: the panel still re-anchors (or dismisses) as before.Notes
getBoundingClientRectspy), not onstyle.top: the recomputed coordinates are identical when the trigger has not moved, so a style assertion would pass in the broken state too.