Full keyboard navigation for the MeteoSwiss header flyout menu, following the WAI-ARIA Disclosure Navigation Menu pattern. The implementation matches the BFS reference at bfs.admin.ch.
| Key | Action |
|---|---|
| Click / Enter on nav button | Opens the flyout; focus lands on the close button |
| ArrowDown | Move to next flyout item (wraps to top) |
| ArrowUp | Move to previous flyout item (wraps to bottom) |
| ArrowRight | Drill into submenu (on items with children) |
| ArrowLeft | Go back to parent level |
| Tab / Shift+Tab | Cycle through focusable elements (focus is trapped inside the flyout) |
| Escape | Close flyout; return focus to the trigger button |
- On open: The close button receives focus (desktop). This gives the user an immediate escape hatch.
- After drill-in: The close button receives focus again. The back button is first in Tab order, the close button last — so Shift+Tab immediately reaches the back button.
- On close (Escape): Focus returns to the nav button that opened the flyout, so the user never loses their place.
All keyboard interactions are covered by automated Playwright tests. The full header test suite (47 tests) passes:
Running 47 tests using 5 workers
✓ header-keyboard-nav.spec.ts › auto-focuses the close button when the flyout opens
✓ header-keyboard-nav.spec.ts › closes the flyout when pressing Escape
✓ header-keyboard-nav.spec.ts › restores focus to the trigger nav button when pressing Escape
✓ header-keyboard-nav.spec.ts › moves focus through flyout items with ArrowDown
✓ header-keyboard-nav.spec.ts › moves focus backward with ArrowUp
✓ header-keyboard-nav.spec.ts › wraps focus around at the boundaries with ArrowDown
✓ header-keyboard-nav.spec.ts › wraps focus around at the boundaries with ArrowUp
✓ header-keyboard-nav.spec.ts › drills into a submenu when pressing ArrowRight on an item with children
✓ header-keyboard-nav.spec.ts › navigates back to parent level when pressing ArrowLeft
✓ header-keyboard-nav.spec.ts › traps Tab focus inside the flyout (wraps at boundaries)
✓ header-keyboard-nav.spec.ts › focuses the close button after drilling in
✓ header-keyboard-nav.spec.ts › focuses the title link on ArrowDown after drilling in
✓ header-keyboard-nav.spec.ts › places the back button first in Tab order after drilling in
✓ header-keyboard-nav.spec.ts › places the close button last in Tab order
+ 33 more (desktop nav, mobile nav, search, smoke)
47 passed (19.0s)
| File | Purpose |
|---|---|
header/hooks/useRovingFocus.ts |
Manages roving keyboard focus within a container |
header/reducer/navReducer.ts |
Navigation state machine (OPEN / CLOSE / DRILL_IN / DRILL_OUT) |
header/utils/focusShadowedElement.ts |
Focus traversal across shadow DOM boundaries |
navigation-flyout/NavigationFlyout.tsx |
Flyout component with keyboard event handling |
e2e-tests/tests/header/header-keyboard-nav.spec.ts |
Keyboard navigation E2E tests |
All paths are relative to mchweb-components/src/components/static/ (except E2E tests).





