Skip to content

Instantly share code, notes, and snippets.

@eins78
Last active February 23, 2026 09:54
Show Gist options
  • Select an option

  • Save eins78/522fe8c5a58161528d1df1005ff54e98 to your computer and use it in GitHub Desktop.

Select an option

Save eins78/522fe8c5a58161528d1df1005ff54e98 to your computer and use it in GitHub Desktop.
Header Keyboard Navigation — MeteoSwiss header flyout (WAI-ARIA Disclosure pattern)

Header Keyboard Navigation

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.

Keyboard Interactions

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

Focus Management

  • 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.

Screenshots

1. Flyout opens — close button receives focus

Flyout open with close button focused

2. ArrowDown moves focus to the title link

ArrowDown moves focus to title link

3. ArrowRight drills into a submenu

ArrowRight drills into submenu

E2E Test Coverage

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)

Key Implementation Files

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).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment