Skip to content

fix(floating): dismiss sibling menus and preserve nested portals - #428

Merged
chaxus merged 4 commits into
mainfrom
codex/assistant-interface-audit
Oct 18, 2026
Merged

chaxus merged 4 commits into
mainfrom
codex/assistant-interface-audit

Conversation

@chaxus

@chaxus chaxus commented Oct 18, 2026

Copy link
Copy Markdown
Owner

Merge Verdict

[APPROVE]

Implementation and independent follow-up review are complete. Preserve the four commits requested for this change.

Summary

Clicking a Select or another propagation-stopping control could leave a sibling Popover open, causing overlapping menus. A document capture listener alone also misclassifies content hidden inside a closed shadow root, and a module-local ownership map loses nested portal ancestry when standalone component bundles are loaded separately.

Share outside-click classification between Select and Popover. Track each open portaled panel's logical owner on the node using Symbol.for, classify hidden clicks inside the owning root, and use a guarded document fallback for clicks outside that root. Add unit and real-browser coverage, including independently built IIFEs in both load orders.

Application integration: ranuts/document#286

Risk Analysis

Risk Level Mitigation
Capture-phase dismissal changes interactions with nested or sibling controls Medium Test both sibling opening orders, nested Select/Popover interaction and controls that stop propagation
Retargeted events or delayed callbacks dismiss a newer state Low Local-root classification, binding/state generations, disconnection checks and lifecycle-managed listeners
Standalone bundles cannot share portal ancestry Low Node-owned registered symbol; exercise actual build artifacts in both script load orders

Design Decisions

  • Keep the behavior in the existing shared FloatingController, with no placement, spacing, theme or public event contract changes.
  • Do not stop an outside click before its target control can handle it.
  • Defer closed-root document fallback until dispatch completes; microtasks can run between listeners during trusted browser clicks.
  • Remove ownership on close and destroy, and invalidate stale callbacks on disconnect or new state transitions.
  • Keep package versions and release automation unchanged.

Code Concerns

No unresolved findings. Independent review approved the closed-root handling, separate-bundle ownership and symmetric Select/Popover dismissal corrections.

Verification

Conclusion basis: Verified

  • Full ranui unit/integration suite: 95 files / 1,577 tests passed.
  • SSR suite: 8 files / 76 tests passed.
  • Existing Select/Popover interaction and lifecycle browser regression: 132 tests passed across Chromium, Firefox and WebKit.
  • New functional browser coverage: 20 tests passed across Chromium, Firefox, WebKit and Mobile Chrome, including closed-root pixel clicks and both standalone IIFE load orders.
  • Full pnpm -F ranui build passed for ESM, complete IIFE, individual component IIFEs and declarations.
  • Type checking, design verification (no new violations), component API verification, changed-file oxlint and Prettier passed.
  • Outside-click, reverse sibling and standalone-bundle regressions were observed failing before their respective fixes.

@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying ran with  Cloudflare Pages  Cloudflare Pages

Latest commit: b12cfc1
Status: ✅  Deploy successful!
Preview URL: https://7b150366.ran-4ty.pages.dev
Branch Preview URL: https://codex-assistant-interface-au.ran-4ty.pages.dev

View logs

@chaxus
chaxus merged commit 35a68ad into main Oct 18, 2026
16 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