Skip to content

Use Radix Dropdown Menu for reliable focus and navigation - #645

Open
parsakhaz wants to merge 1 commit into
mainfrom
codex/audit-dropdown
Open

parsakhaz wants to merge 1 commit into
mainfrom
codex/audit-dropdown

Conversation

@parsakhaz

Copy link
Copy Markdown
Member

Disabled entries before a selected dropdown item changed the index used to focus the rendered menu, so opening or hovering could focus a different action. The custom menu also maintained its own keyboard loop, portal positioning, animation polling, and dismissal listeners.

This replaces those mechanics with a thin Radix Dropdown Menu wrapper while retaining Pane's trigger/item styles, checked selection, disabled actions, footer controls, keep-open selection, portal containers, and trigger-width menus. Initial focus uses the selected element directly. Footer actions join the framework's focus collection. A dialog opened by a menu action restores focus to the persistent menu trigger through its ARIA association; the selected menu item is transient.

The unused navigation module and its 12 pure-helper tests are removed. Rendered Playwright checks cover the former failure, pointer/keyboard agreement, disabled selection, wrapping, Home/End, footer activation, Escape/focus return, outside dismissal, and full width. The dropdown spec is now included in maintained CI smoke coverage.

Supply chain: pin @radix-ui/react-dropdown-menu@2.1.15 (published 2025-05-20) to match the existing Radix primitive versions. The lock adds only Dropdown Menu, Menu, and Roving Focus; all are MIT and have no install lifecycle scripts. Every existing locked package and snapshot stays unchanged. The seven-day age floor and build-script allowlist remain intact. NOTICES adds the three regenerated attribution entries.

Built verification also reproduced #635: an unavailable Google Fonts stylesheet rejected Vite's CSS preload and prevented the renderer from mounting. The external import is removed, using the existing local font fallback stack.

Validation:

  • pnpm install --frozen-lockfile --offline --ignore-scripts
  • pnpm lint and pnpm typecheck
  • pnpm build:frontend, including xterm and React Scan build guards
  • Six dropdown browser checks using Vite
  • Built preview: theme keyboard selection, Home/About focus and axe, Night Owl axe

Built theme dropdown

Closes #618.
Closes #635.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 14, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-09-14T15:28:18.210570Z d689dfc PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@socket-security

socket-security Bot commented Sep 14, 2026 •

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Addednpm/​@​radix-ui/​react-dropdown-menu@​2.1.15991007195100

View full report

@github-actions

github-actions Bot commented Sep 14, 2026 •

Copy link
Copy Markdown

React Doctor found no new issues. 🎉

Reviewed by React Doctor for commit eb92d18.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d689dfc78a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

{trigger}
</DropdownMenu.Trigger>
<DropdownMenu.Portal container={portalContainer ?? undefined}>
<DropdownMenu.Content

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Restore Tab exit handling for the Radix menu

When a keyboard user presses Tab or Shift+Tab from an open dropdown, Radix Menu.Content prevents the browser's default Tab action and does not close the menu. With no Tab override here, focus remains on the current item; the replaced implementation explicitly closed the menu, returned focus to the trigger, and allowed Tab to continue. Restore an explicit Tab exit path so users can navigate past dropdowns in either direction.

Useful? React with 👍 / 👎.

This branch has not been deployed

No deployments
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.

Remove runtime Google Fonts import that can abort offline desktop startup Replace bespoke dropdown mechanics and fix disabled-item focus indexing

1 participant