Navigation Menuv1.0.5Documentation Under Review
A collection of links for navigating internal applications with accessible multi-level dropdown support and customizable styling.
The Navigation Menu component provides an accessible, keyboard-navigable menu system built on Radix UI Navigation Menu primitives. It supports multi-level dropdowns, smooth animations, active page tracking, and custom theming for internal product applications.
Installation
Install the Navigation Menu component from the Catalyst component library:
npm install @pmi/catalyst-navigation-menuAnatomy
The Navigation Menu is a compound component system with 9 primitives:
import {
NavigationMenuRoot,
NavigationMenuList,
NavigationMenuItem,
NavigationMenuTrigger,
NavigationMenuContent,
NavigationMenuLink,
NavigationMenuSub,
NavigationMenuViewport,
NavigationMenuIndicator,
} from '@pmi/catalyst-navigation-menu'
<NavigationMenuRoot>
<NavigationMenuList>
<NavigationMenuItem>
<NavigationMenuLink href="/">Dashboard</NavigationMenuLink>
</NavigationMenuItem>
<NavigationMenuItem>
<NavigationMenuTrigger>Settings</NavigationMenuTrigger>
<NavigationMenuContent>
{/* Dropdown content */}
</NavigationMenuContent>
</NavigationMenuItem>
<NavigationMenuIndicator />
</NavigationMenuList>
<NavigationMenuViewport />
</NavigationMenuRoot>Examples
Default
A complete navigation menu with certification cards and dropdown content:
Default Opened
Navigation menu with the first dropdown pre-opened, featuring a certification card:
Disabled
All navigation triggers are disabled, preventing interaction:
Custom Styles
Apply custom aqua theme colors for product applications, featuring certification cards with the custom styling:
Advanced Examples
API Reference
NavigationMenuRoot
The root container for the navigation menu system.
Prop
Type
Data Attributes:
data-orientation- "horizontal" | "vertical"
NavigationMenuList
Contains all menu items in a horizontal or vertical list.
Prop
Type
NavigationMenuItem
A single navigation menu item that can contain a link or trigger.
Prop
Type
NavigationMenuTrigger
The button that toggles the dropdown content.
Prop
Type
Data Attributes:
data-state- "open" | "closed"data-disabled- Present when disableddata-active- Present when the trigger is active
NavigationMenuContent
The component that contains the content shown in the dropdown.
Prop
Type
Data Attributes:
data-state- "open" | "closed"data-motion- "from-start" | "from-end" | "to-start" | "to-end"
NavigationMenuLink
A navigational link that can be used standalone or inside dropdown content.
Prop
Type
Data Attributes:
data-active- Present when the link is active
NavigationMenuViewport
The viewport that contains the dropdown content with smooth animations.
Prop
Type
Data Attributes:
data-state- "open" | "closed"
CSS Variables:
--radix-navigation-menu-viewport-width- The width of the viewport--radix-navigation-menu-viewport-height- The height of the viewport
NavigationMenuIndicator
An optional arrow indicator that highlights the active item.
Prop
Type
Data Attributes:
data-state- "visible" | "hidden"data-orientation- "horizontal" | "vertical"
NavigationMenuSub
Used to create sub-navigation within dropdown content.
Prop
Type
Animations
The Navigation Menu includes smooth animations powered by Tailwind CSS:
Content Animations
- Enter from right/left: Content slides in from the side (250ms)
- Exit to right/left: Content slides out to the side (250ms)
Viewport Animations
- Scale in: Viewport scales in with a 3D rotation effect (200ms)
- Scale out: Viewport scales out smoothly (200ms)
Indicator Animations
- Fade in/out: Arrow indicator fades in and out (200ms)
All animations respect the prefers-reduced-motion media query for accessibility.
Accessibility
WCAG 2.1 Compliance
The Navigation Menu component meets WCAG 2.1 Level AA standards:
- ✅ Keyboard Navigation: Full support for Arrow keys, Tab, Enter, and Escape
- ✅ Focus Management: Visible focus indicators and proper focus trapping
- ✅ Screen Reader Support: Proper ARIA attributes and announcements
- ✅ Active Page Indicators: Uses
aria-current="page"for the current page - ✅ Color Contrast: Meets 4.5:1 minimum contrast ratio
- ✅ Reduced Motion: Respects
prefers-reduced-motionpreference
Keyboard Shortcuts
| Key | Action |
|---|---|
Tab | Move focus to next interactive element |
Shift + Tab | Move focus to previous interactive element |
Arrow Down | Open dropdown or move focus to next item |
Arrow Up | Move focus to previous item |
Arrow Right | Move focus to next trigger |
Arrow Left | Move focus to previous trigger |
Enter or Space | Activate focused trigger or link |
Escape | Close open dropdown |
Best Practices
- Always provide
aria-labelonNavigationMenuRootto describe the navigation - Use
aria-current="page"to indicate the current page - Add descriptive text for icon-only triggers using
aria-label - Ensure sufficient contrast for hover and active states (especially with custom colors)
- Test with keyboard to ensure all items are reachable
- Test with screen readers (NVDA, JAWS, VoiceOver)
Performance Considerations
Optimizing navigation menu performance ensures fast page loads and smooth interactions:
Code Splitting
Navigation menu content can be lazy-loaded using React's dynamic imports:
import dynamic from 'next/dynamic'
const NavigationMenuContent = dynamic(() =>
import('@pmi/catalyst-navigation-menu').then(mod => mod.NavigationMenuContent),
{ ssr: true }
)Image Optimization
Use Next.js Image component for course and certification card images to optimize loading:
import Image from 'next/image'
const CourseCard = ({ image, title }) => (
<div className="aspect-video w-full overflow-hidden">
<Image
src={image}
alt={title}
width={400}
height={225}
loading="lazy"
className="h-full w-full object-cover"
/>
</div>
)Hover Delay Optimization
Use the delayDuration prop to optimize hover behavior for large menus:
<NavigationMenuRoot
delayDuration={300} // Slightly longer delay reduces unnecessary opens
skipDelayDuration={200} // Faster transitions between menus
>
{/* menu content */}
</NavigationMenuRoot>Data Memoization
Use useMemo for large menu data structures to prevent unnecessary re-renders:
const categories = useMemo(() => [
{ id: 'certifications', name: 'Certifications', /* ... */ },
{ id: 'courses', name: 'All Courses', /* ... */ },
{ id: 'learning-paths', name: 'Learning Paths', /* ... */ }
], []) // Empty deps array - data doesn't changeBundle Size
- Component Bundle: ~8KB gzipped (including Radix UI primitives)
- With Icons: ~12KB gzipped (when using 5-10 icons)
- Tree Shaking: Import only the components you need
Best Practices
- Avoid rendering large lists (>50 items) in a single dropdown - use search/filtering instead
- Defer loading non-critical menu content until user interaction
- Use CSS transforms for animations (already implemented) for better performance
- Monitor menu opening time - should be <100ms for good UX
- Consider using a service worker to cache navigation menu data
Design Tokens
The component uses the following Catalyst design tokens:
Colors (Default)
pmi-off-black-800- Text and outline colorspmi-off-black-50- Hover background (light mode)pmi-violet-700- Hover background (dark mode)white- Text and background colors
Colors (Custom - Aqua Theme)
neutral-800- Text and background colorspmi-aqua-50- Hover background (light mode)pmi-aqua-800- Hover background (dark mode)pmi-aqua-500- Focus ring color
Spacing
h-8(32px) - Height for triggers and linksh-10(40px) - Height for the list containerpx-3(12px) - Horizontal padding for itemsp-6(24px) - Padding for dropdown content
Typography
font-aeonik- Font familytext-base(16px) - Base text sizefont-medium(500) - Font weightleading-6(24px) - Line height
Border Radius
rounded-lg(8px) - Item and list border radiusrounded-xl(12px) - Link item border radius
Related Components
- Horizontal Bar - Application header with navigation
- Dropdown Menu - Action menus and commands
- Tabs - Alternative content navigation pattern
- Link - Standalone link component
Menubar
A horizontal menu bar component for creating application-style navigation menus with submenus, keyboard shortcuts, checkboxes, and radio items. Built on Radix UI primitives.
Pagination
A navigation component for traversing paged content. Built on Radix UI Slot with CVA variants, accessible ARIA semantics, and full asChild polymorphic composition.