Skip to content

Overlay / top-layer overhaul Phase 2: migrate all overlays, tokenize residuals, strict guard - #59

Merged
Aztec03hub merged 6 commits into
mainfrom
worktree-agent-a2e251760d77c3e15
Jun 26, 2026
Merged

Overlay / top-layer overhaul Phase 2: migrate all overlays, tokenize residuals, strict guard#59
Aztec03hub merged 6 commits into
mainfrom
worktree-agent-a2e251760d77c3e15

Conversation

@Aztec03hub

Copy link
Copy Markdown
Owner

Overlay / top-layer overhaul — Phase 2

Builds on Phase 1 (#58: the topLayer action, <Modal>/<Popover> wrappers, the --z-* token scale, the Tier-1 guard, StatusEditor). Phase 2 migrates every remaining floating overlay off ad-hoc position:fixed/absolute + manual z-index (and the partial portaling) onto the browser native top layer, tokenizes all residual surfaces, and flips the guard to strict.

Anchored overlays → <Popover> / use:topLayer

MentionDropdown (anchored to the composer textarea), ReactionBar (hover tooltip → manual popover, hover lifecycle preserved), ArtifactDetailHeader dropdowns, EmojiPicker, ProfileCard, NotificationPolicyMenu, ReadReceipt. Dropped their raw positioning + z-index; kept each component's own outside-click/keyboard dismiss handlers so jsdom unit coverage holds (the action capability-guards the native calls).

Already-portaled → drop portal()+z-index, use the primitive

ReactionDetailsPanel (was z250), MemberContextMenu (was z9999), ChannelContextMenu + its submenu (the submenu is a nested manual popover, §F.8). Rewrote tests/context-menu-top-layer-bugfix.spec.js — it pinned z-index:9999 + {@attach portal()} by regex (now gone); it asserts the new primitive instead. Also updated the matching 04/05 e2e source-pins.

Manual-portal + raw modals → native <dialog>.showModal()

LeaveChannelDialog, TypeNameConfirmDialog, InviteParticipantDialog, ChannelDirectoryModal, KeyboardShortcutsHelp, ForwardPicker, and the App.svelte quick-join dialog — native ::backdrop + built-in focus-trap, no manual portals/z-index.

bits-ui kept (ContextMenu, ChannelModal, ConfirmDialog)

Unchanged — they already portal to <body> with their own focus-trap (§F.1).

Tokenized residual surfaces

Toasts (--z-toast), banners (--z-banner), docked panels (--z-panel), sidebar (--z-sidebar), in-flow content, and the App mobile-sidebar block — all bare z-index collapsed onto var(--z-*) (added value-preserving local rungs --z-raised/content/elevated + --z-noise). Toasts/banners stay non-top-layer by design.

Strict guard

ALLOWED shrunk to the 4 passive toasts/banners + the 3 bits-ui components; everything else passes both rules on merit (uses the primitive, only var(--z-*) tokens).

Verification

  • pnpm --dir web test: 1333 passed, 0 failed, 0 skipped (run 3×, stable).
  • pnpm --dir web build: green.
  • Svelte MCP autofixer: clean on every edited .svelte.
  • Playwright: full suite 251 passed / 1 pre-existing skip / 0 failed. Scenario 14 adds on-top + native-pseudo-class assertions (MentionDropdown :popover-open over the message list; ChannelContextMenu :popover-open over an open backdrop-filter panel; quick-join native :modal + inert background), all green in real Chromium.

No version bump.

🤖 Generated with Claude Code

…layer

MentionDropdown, ReactionBar (hover tooltip -> manual popover, hover
lifecycle preserved), ArtifactDetailHeader dropdowns, EmojiPicker,
ProfileCard, NotificationPolicyMenu, ReadReceipt now open via
<Popover>/use:topLayer (Popover API), dropping raw position:fixed/absolute
+ z-index. MessageInput passes the textarea as the MentionDropdown anchor.
Each keeps its existing outside-click/keyboard dismiss handlers so jsdom
unit coverage holds (the action capability-guards the native calls).
ReactionDetailsPanel, MemberContextMenu, and ChannelContextMenu (+ its
submenu as a nested manual popover, design F.8) now use use:topLayer
instead of portal()+hardcoded z-index (9999/250). Rewrite
context-menu-top-layer-bugfix.spec.js: the old z-index:9999 + @Attach
portal() source pins are gone, so it now asserts the new primitive usage
(use:topLayer, no portal, no bare z-index; two use:topLayer for the menu+
submenu) plus render/outside-click/unmount behaviour. Adapt
reaction-details-panel.spec.js off the portal-parent assertion.
LeaveChannelDialog, TypeNameConfirmDialog, InviteParticipantDialog,
ChannelDirectoryModal, KeyboardShortcutsHelp, and ForwardPicker now render
a native <dialog> driven by showModal() via use:topLayer (or the <Modal>
wrapper), using the native ::backdrop + built-in focus-trap and inert
background. Drops the manual portals, backdrop elements, position:fixed and
z-index. Existing cancel/confirm handlers retained for jsdom coverage.
Extend the app.css token scale with value-preserving local rungs
(--z-raised/content/elevated) + --z-noise, and collapse every remaining
bare z-index onto var(--z-*): toasts (--z-toast), banners (--z-banner),
docked panels (--z-panel), sidebar (--z-sidebar), in-flow content, and the
App.svelte mobile-sidebar block. Migrate the App.svelte Ctrl+J quick-join
prompt to a native <dialog use:topLayer> with a native ::backdrop, dropping
its manual backdrop + z-index:9000. Toasts/banners stay non-top-layer by
design (a top-layer toast would steal focus / inert the page).
Shrink the ALLOWED set to its irreducible core: the passive
toasts/banners (must NOT be top layer, design F.5) and the three bits-ui
components (ContextMenu/ChannelModal/ConfirmDialog, design F.1). Every
other overlay/panel/in-flow file plus App.svelte and app.css now passes
both rules on merit (uses the primitive, carries only var(--z-*) tokens).
Update the comments + the self-doc test to assert the strict core.
Scenario 14 gains on-top + native-pseudo-class assertions for the new
trap pairs: MentionDropdown over the message list (:popover-open),
ChannelContextMenu over an open backdrop-filter panel (:popover-open), and
the quick-join native :modal dialog (inert background + Esc dismiss), all
via expectLocatorOnTop. Rewrite the 04/05 source-pins that asserted the
removed z-index:9999 + @Attach portal() to assert use:topLayer instead, and
update the ProfileCard dismiss test to a real outside-click (its backdrop
element is gone).
@Aztec03hub
Aztec03hub merged commit e4b8539 into main Jun 26, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant