MiHCM
navigation/@mihcm/ui·v0.21.0·stable

TopBar

Segmented app header with Logo, home/back parallelogram segments, notifications, profile, dividers, and utility actions. Universal across web and native with a simplified native bar.

WCAG 2.1 AA — release blocker

Web (React DOM)

  • Renders as <header> so it lands in the page landmarks (screen readers can jump to it with the "Banner" shortcut).
  • The slots are pass-through — every interactive child must satisfy its own a11y rules:
    • The logo: prefer <a href="/"> over a <button> so the home shortcut works.
    • TopBarMenuButton: ships with aria-label="Open menu" (override via ariaLabel), aria-haspopup="menu", type=button, focus-visible ring, and a 40×40 hit area. Visually lg:hidden (mobile + tablet only); on desktop it's display: none and unfocusable, so the keyboard tab order on desktop is unchanged.
    • The bell: a <button> with aria-label="Notifications, N unread" (the NotificationBadge itself is decorative).
    • The avatar: a <button> if it opens a menu, else a plain <img> with alt.
    • "What's new" / "Logout": <button> if they open a UI, <a> if they navigate.

Keyboard navigation

  • Tab moves between focusable children in DOM order.
  • Each child handles its own activation.
  • For dropdowns triggered from the end slot (profile menu, notifications panel), use a headless popover primitive with managed focus.

Reduced motion

The bar has no transitions; nothing to honour beyond the system default.

Color is never the only signal

  • The shadow under the bar uses shadow-mi-soft — a soft drop that's still visible to users with reduced colour perception.
  • Dividers use a 15 px line in border colour, not just lighter text spacing.

Audit checklist

  • Every interactive child has a real role (<button> / <a>) and an accessible name.
  • Icon-only buttons have aria-label.
  • Tab order matches visual order.
  • Bar contrast ≥ 4.5:1 between bg-card and text-foreground × light/dark.