fix(ui): portal context menu so dropdown isn't clipped by sibling cards#32
Merged
Conversation
The dropdown was position:absolute inside each card, but cards create their own stacking context via transform (hover lift + fadeUp animation), trapping the menu's z-index below the next sibling card. Render the dropdown as a body portal positioned fixed relative to the trigger so it escapes the per-card stacking context. Fixes ConfigRow and ConfigCard. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
The dropdown is portaled to document.body and positioned fixed, so .ctx no longer anchors anything. Removing the obsolete rule the portal change left behind. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Anchor the dropdown against document.documentElement.clientWidth instead of window.innerWidth so a fixed `right` offset lines up with the trigger; innerWidth includes the scrollbar and shifted the menu left by its width. - Lower z-index 1000 -> 150 so it sits above the header but below modal overlays (which use 1000) instead of tying them. - Attach window scroll/resize listeners only while the menu is open, via an $effect, so closed menus do no per-scroll work; capture-phase scroll also tracks nested scroll containers. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.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
The config card three-dot menu dropdown was being covered by the card below it (see screenshot in the linked issue/report).
Root cause: the dropdown was
position: absolute; z-index: 100rendered inside each card. Each card creates its own stacking context viatransform(.row:hoverlift + the.card-wrapfadeUpanimation), so the dropdown'sz-indexis trapped within its own card and can't paint above the next sibling card. Bumping z-index alone can't escape a sibling stacking context.Fix: render the dropdown as a
document.bodyportal, positionedfixedrelative to the trigger (recomputed on resize/scroll). This lifts it out of the per-card stacking context. The sharedContextMenucomponent is used by bothConfigRow(dashboard) andConfigCard(preview), so both are fixed in one change. Click-outside now checks both the trigger and the portaled dropdown.Test plan
npm run check— 0 errorsnpm run lint— 0 errors (no new warnings on the changed file)npm test— 289 passedConfigRowcards, opened the top card's menu —elementFromPointconfirms all four items (Share/Duplicate/Export JSON/Delete) are topmost, nothing covers them; verified visually