Skip to content

OXY-152: Add dropdown menu support to TopBar - #299

Open
Kalin-Rudnicki wants to merge 2 commits into
mainfrom
OXY-152
Open

OXY-152: Add dropdown menu support to TopBar#299
Kalin-Rudnicki wants to merge 2 commits into
mainfrom
OXY-152

Conversation

@Kalin-Rudnicki

Copy link
Copy Markdown
Owner

What

Adds first-class dropdown / popup-menu support so apps can declare nav/action menus without hand-rolling overlay + click-outside + keyboard + focus logic.

  • New component/DropdownMenu (fills the reserved package TODO): click-to-open menu of typed items (label, icon, disabled, separator; onClickPush / onSelectAction / onSelect). Self-contained open/closed state via a per-instance PageLocalState[Boolean] keyed by a caller-supplied stable id (no page-state threading). Fixed transparent scrim for outside-click; closes on Escape/Tab/select.
  • A11y + keyboard: role=button/menu/menuitem, aria-haspopup/aria-expanded/aria-disabled; Enter/Space/↓ open, ↑/↓ roving (wrap), Home/End, Enter/Space activate, Esc closes + restores focus, focus-first-on-open.
  • Stylesheet O.DropdownMenu (theme tokens) registered via the existing coreOxygenStyleSheets; new ZIndices.dropdownMenuScrim/Panel (below modals, above content).
  • TopBar integration: TopBar.item.dropdown(id, label)(...) / dropdownWithIcon, plus TopBar.menuItem / TopBar.menuSeparator; trigger reuses bar chrome + caret; right-section menus auto-align end. Existing flat call sites unchanged.
  • Showcase DropdownMenuPage (TopBar left menu + right user menu with disabled item + separator, and a standalone reusable menu) + nav/registration; docs table row.

Decisions (open questions resolved — see report/OXY-152.md)

Reusable component (not TopBar-private); typed item model; click trigger (not hover); one flat level (no nested submenus v1); absolute panel + scrim; full role=menu a11y; component-local state via id-keyed PageLocalState.

Verification

oxygen-ui-web/compile ✅, example-ui-web/compile ✅, oxygen-ui-web/test ✅ (45 passed). Not browser-tested.

Confidence: 7/10

Compiles across lib + example, tests green, no flat-TopBar regression, typed a11y/keyboard wired. Unverified: live browser behaviour (focus/roving rely on rAF + DOM queries); absolute panel could be clipped by an ancestor overflow:hidden (portal variant deferred); id-based state is a new caller contract.

Full notes + confidence in report/OXY-152.md.

🤖 Generated with Claude Code

Kalin-Rudnicki and others added 2 commits August 13, 2026 18:45
Add a first-class action/nav popup menu:
- New component/DropdownMenu.scala: click-to-open menu of typed items
  (label, icon, disabled, separator; onClickPush / onSelectAction / onSelect),
  self-contained open state via a per-instance PageLocalState keyed by a stable id,
  fixed transparent scrim for outside-click, Escape/Tab/select close, arrow-key roving,
  Home/End, Enter/Space activate, focus-first-on-open + focus-restore.
- A11y: role=button/menu/menuitem, aria-haspopup/expanded/disabled, roving tabindex.
- Stylesheet O.DropdownMenu (Trigger/Caret/Scrim/Panel[+align]/Item[+disabled]/Separator/Open),
  theme tokens only, via existing OxygenStyleSheet.compiled (coreOxygenStyleSheets).
- ZIndices.dropdownMenuScrim/Panel (below modals, above content).
- TopBar.Item.dropdown / dropdownWithIcon delegate to DropdownMenu (trigger reuses bar chrome),
  TopBar.menuItem / menuSeparator helpers, right-section menus auto-align end. Flat items unchanged.
- Removed DropdownMenu from the component package TODO.
- Showcase DropdownMenuPage (TopBar left + user menu, disabled item, separator, standalone) + nav/registration.
- Docs: agent-guide component table row.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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