Registry

Command Palette

Search for a command to run...

Login
registry:component

Navigation Menu

v1.0.0ga

Top-level navigation primitive with trigger/content panels.

Registry Endpoint
Open JSON

npx shadcn@latest add @aavya/ui-navigation-menu

One-time setup — add the @aavya registry to your components.json so branded dependencies resolve to Aavya (not stock shadcn):

"registries": { "@aavya": "https://registry-dev.aavya.com/r/{name}.json" }

Or install by full URL: npx shadcn@latest add https://registry-dev.aavya.com/r/ui-navigation-menu.json

Live Preview
Props
PropTypeDefault
viewport?booleantrue

NavigationMenu forwards remaining props to NavigationMenuPrimitive.Root props.

Guidelines

Do

  • Use it for top-level site navigation, with optional single-level dropdown sections.
  • Keep labels short and parallel; group related destinations under one trigger.
  • Mark the current page so users know where they are.

Don’t

  • Don't use it for in-page actions or a command menu — use a Dropdown Menu.
  • Don't build deep, multi-level trees; keep to one dropdown level.
  • Don't hide primary destinations behind hover-only triggers on touch devices.
Accessibility

Role

Navigation region with menu semantics (handled by Radix).

Keyboard

Tab moves between top-level items; arrow keys move within an open section; Esc closes it. (handled)

Screen reader

Announced as a navigation landmark; triggers announce expanded/collapsed. Give the nav an aria-label when there's more than one on the page — you provide this.

Focus

Focus returns to the trigger when a section closes. (handled)

Gotcha

Links must be real anchors — render items asChild wrapping a Link so browser and AT navigation work.

Usage Snippet
import { NavigationMenu } from '@/components/ui/navigation-menu'

export default function Example() {
  return (
    <div className="p-6">
      <NavigationMenu />
    </div>
  )
}
Source Preview
import * as React from 'react'

import * as NavigationMenuPrimitive from '@radix-ui/react-navigation-menu'
import { cva } from 'class-variance-authority'
import { ChevronDownIcon } from 'lucide-react'

import { cn } from '@/lib/utils'

function NavigationMenu({
  className,
  children,
  viewport = true,
  ...props
}: React.ComponentProps<typeof NavigationMenuPrimitive.Root> & {
  viewport?: boolean
}) {
  return (
    <NavigationMenuPrimitive.Root
      data-slot='navigation-menu'
      data-viewport={viewport}
      className={cn('group/navigation-menu relative flex max-w-max flex-1 items-center justify-center', className)}
      {...props}
    >
      {children}
      {viewport && <NavigationMenuViewport />}
    </NavigationMenuPrimitive.Root>
  )
}

function NavigationMenuList({ className, ...props }: React.ComponentProps<typeof NavigationMenuPrimitive.List>) {
  return (
    <NavigationMenuPrimitive.List
      data-slot='navigation-menu-list'
      className={cn('group flex flex-1 list-none items-center justify-center gap-1', className)}
      {...props}
    />
  )
}

function NavigationMenuItem({ className, ...props }: React.ComponentProps<typeof NavigationMenuPrimitive.Item>) {
  return (
    <NavigationMenuPrimitive.Item data-slot='navigation-menu-item' className={cn('relative', className)} {...props} />
  )
}

const navigationMenuTriggerStyle = cva(
  'group bg-backgro