mui / mui/base-ui

[navigation-menu][docs] Clarify purpose + focus behaviour, and point disclosure-style nav dropdowns to Popover

Open Beginner friendly
#5,413 1 comment 1 reaction 0 assignees View on GitHub
component: navigation menu
Dominant language
TypeScript
Stars
10.9k
Forks
543
Avg merge
1d 20h
Merged PRs (30d)
101

Description

Hey there BaseUI team!
I came across a topic that, when improved a bit might genuinely be useful to the next person hitting this. We are using BaseUI for our dropdown components. What we had to do is to implement NavigationDropdown that is using WAI-ARIA **Disclosure Navigation Menu**. First thought was to use your `NavigationMenu` component for that, but that wasn't the choice as I learned on the way.

Your `NavigationMenu` implements the ARIA **menubar / mega-menu** pattern (hover-first, composite arrow-key navigation, and focus moves *into* the content panel on keyboard open). That's a different pattern from the WAI-ARIA **Disclosure Navigation Menu** (a single button that shows/hides a list of links, where **focus stays on the button** and the user Tabs into the links).

The names are easy to confuse, and the docs don't currently distinguish them, so it's easy to pick `NavigationMenu` for a simple "button → dropdown of links" and then be unable to get disclosure behaviour. And that's exactly what I did.

### What the docs currently say

- **NavigationMenu**: only "A collection of links and menus for website navigation." No mention of the intended pattern, the keyboard model, or that **focus moves into the panel on keyboard open** (and that this isn't configurable).
- **Popover**: documents `initialFocus` (incl. `false` to keep focus on the trigger) but has no use-case guidance — nothing indicates it's the right primitive for a disclosure-style navigation dropdown.

### Why it matters

For a disclosure navigation menu, the [WAI-ARIA APG](https://www.w3.org/WAI/ARIA/apg/patterns/disclosure/examples/disclosure-navigation/) specifies that opening the disclosure **keeps focus on the button**, and it deliberately avoids the `menu` role/menubar keyboard model. `NavigationMenu`'s force-focus-into-content behaviour (no opt-out I could find) can't express that, whereas `Popover` + `initialFocus={false}` can.

### Suggested docs improvements

1. **NavigationMenu**: add a short "When to use" note — it's for menubar/mega-menu site navigation; describe the keyboard/focus model (focus enters the panel on keyboard open).
2. Point users who want the **disclosure navigation** pattern (single button revealing a list of links, focus stays on the trigger) to **Popover** with `initialFocus={false}` + a `` landmark and real `` links.
3. Optionally, add "disclosure navigation" as a listed use-case on the **Popover** page maybe? This is actually the only component that I think would do the trick for this use case, but maybe there is something else in the lib that I didn't see. Let me know 🙂

### References
- WAI-ARIA APG — [Disclosure Navigation Menu example](https://www.w3.org/WAI/ARIA/apg/patterns/disclosure/examples/disclosure-navigation/) (focus stays on the button; arrow keys optional; no `menu` role)
- WAI-ARIA APG — [Navigation Menubar example](https://www.w3.org/WAI/ARIA/apg/patterns/menubar/examples/menubar-navigation/) (the pattern `NavigationMenu` implements)
- Base UI — [NavigationMenu](https://base-ui.com/react/components/navigation-menu) · [Popover](https://base-ui.com/react/components/popover)
- Related: [#1761](https://github.com/mui/base-ui/issues/1761) (keep focus indicator on trigger while popup open)

Hope this is somehow helpful. 🤞
Cheers,
Patrycja

PS: if you accept contributions, then I can, of course, also submit a PR with those changes.

Contributor guide

Open the contributing guide

Research direction

Start with the NavigationMenu and Popover documentation pages linked in the issue, then compare their documented focus behavior with the two WAI-ARIA APG references. Done means the NavigationMenu pattern and focus model are clarified, and disclosure navigation is pointed to Popover with initialFocus={false}, a landmark, and real links.

Written by the indexing model from the issue text.

Assessment

Tech stack
react, typescript
Domain
accessibility, documentation
Issue type
Documentation
Difficulty
2/5
Estimated time
Half a day
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
72/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.