ref(🥞): add Layer primitive with portal outlets and stacking context isolation#114516
Open
natemoo-re wants to merge 7 commits into
Open
ref(🥞): add Layer primitive with portal outlets and stacking context isolation#114516natemoo-re wants to merge 7 commits into
natemoo-re wants to merge 7 commits into
Conversation
Layer primitive
14 tasks
d9e086a to
38c44e6
Compare
Contributor
📊 Type Coverage Diff✅ No new type safety issues introduced. Coverage: 93.59% |
This was referenced May 20, 2026
8c5a144 to
39b9752
Compare
167ce34 to
17924a0
Compare
Layer now supports a render child pattern for flex/grid contexts
where the wrapper div breaks layout. When children is a function,
Layer passes {className} and the consumer renders its own element.
Add z-index: 2147483647 to PortalOutlet so portaled content paints
above sticky headers and other positioned elements within the Layer.
Co-Authored-By: Claude Opus 4 <noreply@anthropic.com>
isolation: isolate alone creates a stacking context. position: relative conflicts with consumer positioning (e.g. position: sticky) when using the render child pattern. Co-Authored-By: Claude Opus 4 <noreply@anthropic.com>
Each Layer now creates its own tooltip warmth group, so tooltips within a stacking context share instant-open behavior while isolating warmth from other Layers. Inner HoverOverlayGroupProviders can still override for sub-groups. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Layer exports are unused until wire-portals lands consumers. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The previous inset: 0 approach created a full-viewport overlay that Selenium's hit-testing saw as blocking clicks even with pointer-events: none. Use width: 0; height: 0; overflow: visible instead — the outlet has no bounding rect but portaled children still render via overflow. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
17924a0 to
d66e9b8
Compare
15 tasks
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
Add a
Layercomponent that usesisolation: isolateto create scoped stacking contexts. Each Layer provides a portal outlet for portaled children (tooltips, hovercards, dropdowns) so they remain contained within the Layer's paint order. Stacking order between sibling Layers is determined by DOM position, not z-index.Layer Component
Three semantic variants (
content,nav,overlay) describe the surface type. Recursive nesting is supported with automatic depth tracking. Each Layer renders aposition: fixed; inset: 0; pointer-events: noneportal outlet at the end of its DOM, following the same pattern already used byDrawerContainer.Hooks
useLayerContext()returns the current{ variant, depth, portalOutlet }.usePortalContainer()returns the nearest Layer's portal outlet element for use withcreatePortal.This is purely additive with no consumers — safe to merge with zero behavioral change.
🥞 Layer Primitive Series
nm/zindex/layer-primitive— Layer component + hooks ← this PRnm/zindex/dom-order— DOM restructuring for paint-order stackingnm/zindex/wire-portals— Wire portal consumers to Layer outletsnm/zindex/remove-structural-zindex— Remove structural z-index refsnm/zindex/remove-portal-zindex— Remove portal z-index refsnm/zindex/remove-local-zindex— Replace local z-index refs with bare z-index: 1nm/zindex/deprecate-zindex— Deprecate theme.zIndex scalenm/zindex/lint-ban— Lint rule banning z-index/zIndexnm/zindex/final-cleanup— Remove theme.zIndex entirelyTest plan
isolation: isolatestacking contextposition: fixed; inset: 0; pointer-events: noneusePortalContainer()returns the nearest Layer's portal outletpnpm test-ci static/app/components/core/layer/