Skip to content

fix: dismiss page-action dropdowns on outside click and Escape - #1

Closed
d0lim wants to merge 3 commits into
mainfrom
fix/page-actions-dismiss
Closed

fix: dismiss page-action dropdowns on outside click and Escape#1
d0lim wants to merge 3 commits into
mainfrom
fix/page-actions-dismiss

Conversation

@d0lim

@d0lim d0lim commented Aug 25, 2026

Copy link
Copy Markdown
Owner

Problem

The page-action dropdowns in the right-hand column — Export, Open in chat, and Connect to MCP — are native <details> elements. A native <details> only closes when its own <summary> is clicked again, so clicking anywhere else on the page left the floating panel hanging over the content.

Fix

Two listeners in PageActions.astro:

  • pointerdown — closes the open dropdown unless the press landed inside it, so clicking an item in the panel still works.
  • keydown — Escape closes the open dropdown and returns focus to its trigger.

Both are registered at module scope and query the DOM live, matching the existing resize handler's pattern, so astro:after-swap re-inits don't stack duplicate listeners.

Testing

Added an e2e regression test in apps/docs/e2e/site.e2e.ts. Confirmed it fails on the unfixed code (the panel stays open after the outside click) and passes with the fix.

Also drove all three dropdowns manually via Playwright against blume dev — each closes on an outside click and on Escape, and stays open when clicking an item inside it.

bun run check, bun run typecheck, and bun run test:coverage all pass.

d0lim added 3 commits August 25, 2026 14:19
The Export, Open in chat, and Connect to MCP actions are native <details>
elements, which only close when their own summary is clicked again. Clicking
anywhere else on the page left the floating panel hanging over the content.

Close the open dropdown on any pointer press outside it, and on Escape (which
also returns focus to the trigger). Both listeners are registered at module
scope and query live, matching the existing resize handler, so client-router
swaps don't stack duplicates.
Moves focus into the open panel before pressing Escape, so the new assertion
proves the handler restored focus rather than just observing the click that
opened the menu — asserting straight after the opening click passes either way.
Without the precondition, a focus() that silently failed would leave focus on
the summary and the closing assertion would pass without Escape having restored
anything.
@d0lim

d0lim commented Aug 25, 2026

Copy link
Copy Markdown
Owner Author

Origin PR is opened. haydenbleasel#214

@d0lim d0lim closed this Aug 25, 2026
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