Replace portals with Popover API for layering#722
Open
NullVoxPopuli-ai-agent wants to merge 27 commits intouniversal-ember:mainfrom
Open
Replace portals with Popover API for layering#722NullVoxPopuli-ai-agent wants to merge 27 commits intouniversal-ember:mainfrom
NullVoxPopuli-ai-agent wants to merge 27 commits intouniversal-ember:mainfrom
Conversation
Content elements now use popover="manual" + showPopover() to promote to the browser's top layer, replacing the Portal/PortalTargets approach. This solves z-index and overflow clipping issues natively without requiring consumers to add <PortalTargets /> to their templates. - Remove Portal and TARGETS imports from popover component - Remove @inline arg (no longer needed — top layer replaces both modes) - Add showPopover modifier for popover="manual" lifecycle - Update demos to remove <PortalTargets /> - FloatingUI still handles all positioning (flip, shift, offset, arrow) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
|
Contributor
|
- Reset overflow: visible on popover elements to prevent arrow clipping - Add border: none to demo 1 CSS to override [popover] UA border Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Nested popovers inside another popover no longer get promoted to the top layer separately. Instead, they render as regular positioned elements within the parent popover's top layer entry. This ensures the child popover renders above the parent's content rather than behind it (which happened when both competed for top layer position). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Shows how to use Popover for accessible disabled-state tooltips that appear on hover/focus via CSS opacity transitions. The tooltip is always in the DOM for screen readers but visually hidden until needed. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
A tooltip is not a dialog — plain div is correct here. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Content now always renders as <dialog popover="manual" role="none">. This replaces the @as arg and element helper with a single element. - <dialog> allows nested popovers to fall back to <dialog open> when opting out of the top layer (avoiding parent/child stacking issues) - popover="manual" + showPopover() promotes to the browser's top layer, escaping overflow clipping without portals - role="none" suppresses the dialog a11y announcement by default; consumers can override via ...attributes Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The Setup job was missing `pnpm i -f` before `pnpm build`, causing ember-tsc binary symlinks to not be created. All other jobs already had this step. Also updated the disabled button tooltip demo to mention that users can select and copy tooltip text. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The docs-support build requires ember-tsc from @glint/ember-tsc. In CI, pnpm may not create the bin symlink even after pnpm i -f. This was masked by turbo caching on main — the docs-support build was replayed from cache and never actually ran. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Header, Settings button, and site container use light-dark() for adaptive backgrounds, text colors, and borders - Nested popover uses dark slate in dark mode instead of #eee - Removed hardcoded color: black from header text - Changed header filter: drop-shadow to box-shadow (avoids creating a containing block for position: fixed children) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Use the docs site's existing dark mode colors: - Backgrounds: #0f172a (header/button), #1e293b (nested popover, borders) - Text: #f1f5f9 (primary), #94a3b8 (body) - Borders: #e2e8f0 light / #1e293b dark Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
<div> is simpler — no UA dialog styles (border, padding), no role="none" needed, and nested popovers just work when popover attr is removed (a div without popover is already visible, unlike dialog which needs the open attribute). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Allows consumers to customize the wrapper element tag, e.g. @as="dialog" for focus trapping. Defaults to div. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Remove extra ember-tsc check from CI (pnpm i -f handles it) - Fix emdash in docs intro - Add "Migrating from <= v0.55" section covering: - PortalTargets removal - @inline removal - CSS considerations for [popover] UA defaults Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When a popover element has tabindex (e.g. Menu content), focus it after entering the top layer. This partially fixes Menu focus management but tabster's deloser still doesn't move focus to the first menuitem correctly in the top layer. 5 Menu tests still failing - needs tabster/top-layer investigation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- When @as="dialog" is used, the component automatically adds the open attribute when opting out of the top layer (nested case), so users don't need to specify it - Use full import paths in migration diff - Clarify that border/padding defaults come from the browser's UA stylesheet, not from ember-primitives Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When popover content enters the top layer, focus doesn't
automatically move into it (unlike portaled content). Use
schedule('afterRender') to focus the first focusable child,
which integrates with Ember's runloop so test helpers like
await click() wait for focus to settle.
All Menu tests now pass.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace @ember/runloop schedule with requestAnimationFrame. Check el.isConnected before focusing to guard against the element being removed before the frame fires. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Popover should only handle layering, not focus. The focus-first-child logic now lives in Menu's installContent modifier where it belongs. Uses a microtask (Promise.resolve) to defer focus until after showPopover() promotes the element to the top layer. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The browser fires a toggle event natively when showPopover() opens a popover. Listen for it to focus the first menu item, replacing the microtask hack. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Remove PortalTargets import and usage from Menu demo - Update intro text to reference Popover API instead of portals - Add migration section matching Popover's migration guide Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Same ember-tsc binary issue as Setup job. The existing pnpm i -f ran after pnpm build, too late. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (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
<Portal>+<PortalTargets>with the native Popover API (popover="manual") for promoting Content elements to the browser's top layer@inlinearg — no longer needed since the top layer replaces both inline and portaled modes<PortalTargets />in their templatesThis is a focused change: only the layering mechanism changes (portals → popover API). Positioning stays the same.
Closes #265
Test plan
🤖 Generated with Claude Code