NavigationMenu
NavigationMenu는 사이트나 앱의 섹션 간 이동을 위한 내비게이션 컴포넌트입니다. 수평 바와 사이드바를 모두 지원하며, 서브메뉴와 접기 모드를 제공합니다.
Playground
<NavigationMenu>
<NavigationMenu.List>
<NavigationMenu.Item>
<NavigationMenu.Link href="#" active icon={<Home className="icon-sm" />}>Home</NavigationMenu.Link>
</NavigationMenu.Item>
<NavigationMenu.Item value="products">
<NavigationMenu.Trigger icon={<Package className="icon-sm" />}>Products</NavigationMenu.Trigger>
<NavigationMenu.Content>
<NavigationMenu.Link href="#">All Products</NavigationMenu.Link>
<NavigationMenu.Link href="#">Featured</NavigationMenu.Link>
<NavigationMenu.Link href="#">New Arrivals</NavigationMenu.Link>
</NavigationMenu.Content>
</NavigationMenu.Item>
<NavigationMenu.Item value="resources">
<NavigationMenu.Trigger icon={<BookOpen className="icon-sm" />}>Resources</NavigationMenu.Trigger>
<NavigationMenu.Content>
<NavigationMenu.Link href="#">Documentation</NavigationMenu.Link>
<NavigationMenu.Link href="#">Blog</NavigationMenu.Link>
<NavigationMenu.Link href="#">Support</NavigationMenu.Link>
</NavigationMenu.Content>
</NavigationMenu.Item>
<NavigationMenu.Item>
<NavigationMenu.Link href="#" icon={<Tag className="icon-sm" />}>Pricing</NavigationMenu.Link>
</NavigationMenu.Item>
<NavigationMenu.Item>
<NavigationMenu.Link href="#" icon={<Users className="icon-sm" />}>About</NavigationMenu.Link>
</NavigationMenu.Item>
<NavigationMenu.Item>
<NavigationMenu.Link href="#" icon={<Mail className="icon-sm" />}>Contact</NavigationMenu.Link>
</NavigationMenu.Item>
</NavigationMenu.List>
</NavigationMenu>Variants
Sizes
smmddefaultlg| Size | 높이 | 가로 패딩 | Gap | 아이콘 | 폰트 | 미리보기 |
|---|---|---|---|---|---|---|
sm | 32px | 12px | 8px | 14px | 13px | |
md | 36px | 14px | 8px | 16px | 14px | |
default | 40px | 16px | 8px | 16px | 14px | |
lg | 48px | 24px | 8px | 16px | 16px |
Features
Sub Menus
수평 모드에서는 호버 시 드롭다운이 열리고, 수직 모드에서는 클릭 시 아코디언 방식으로 펼쳐집니다.
<NavigationMenu.Item value="products">
<NavigationMenu.Trigger>Products</NavigationMenu.Trigger>
<NavigationMenu.Content>
<NavigationMenu.Link href="#">All Products</NavigationMenu.Link>
<NavigationMenu.Link href="#">Featured</NavigationMenu.Link>
</NavigationMenu.Content>
</NavigationMenu.Item>Collapsed Mode
collapsed prop으로 아이콘만 표시할 수 있습니다. collapsedWidth prop으로 너비를 커스터마이징할 수 있습니다(기본값: 64px).
<NavigationMenu orientation="vertical" collapsed>
<NavigationMenu.List>
<NavigationMenu.Item>
<NavigationMenu.Link href="#"
icon={<Home className="icon-sm" />}>
Home
</NavigationMenu.Link>
</NavigationMenu.Item>
</NavigationMenu.List>
</NavigationMenu>Active State
active prop으로 현재 페이지를 시각적으로 강조 표시하고 aria-current="page"를 자동 설정합니다.
<NavigationMenu.Link href="#" active
icon={<Home className="icon-sm" />}>
Home
</NavigationMenu.Link>Group Label
NavigationMenu.Group으로 아이템을 섹션으로 나누고, label prop으로 그룹 헤더를 표시할 수 있습니다.
<NavigationMenu orientation="vertical">
<NavigationMenu.List>
<NavigationMenu.Group label="Main">
<NavigationMenu.Item>
<NavigationMenu.Link href="#">Home</NavigationMenu.Link>
</NavigationMenu.Item>
</NavigationMenu.Group>
<NavigationMenu.Group label="Settings">
<NavigationMenu.Item>
<NavigationMenu.Link href="#">General</NavigationMenu.Link>
</NavigationMenu.Item>
</NavigationMenu.Group>
</NavigationMenu.List>
</NavigationMenu>Custom Link (asChild)
asChild prop으로 Next.js Link 등 커스텀 링크 컴포넌트를 합성할 수 있습니다.
import Link from 'next/link'
<NavigationMenu.Link asChild active>
<Link href="/dashboard">Dashboard</Link>
</NavigationMenu.Link>API
Component Structure
NavigationMenu— Radix NavigationMenu + Collapsible.List리스트 컨테이너.ItemProps메뉴 아이템 (value, defaultOpen).TriggerProps서브메뉴 트리거 (icon, chevronIcon).Content서브메뉴 콘텐츠.LinkProps링크 (active, asChild, icon).GroupProps그룹 (label 지원).Indicator활성 인디케이터.Viewport뷰포트 (수평 전용)Props
NavigationMenu
orientation"horizontal""horizontal" | "vertical"레이아웃 방향
size"default""sm" | "md" | "default" | "lg"메뉴 아이템 크기
collapsedfalsebooleanvertical 전용: 아이콘만 표시(접힌 사이드바)
width256number | stringvertical 전용: 사이드바 너비(px 숫자 또는 CSS 문자열)
collapsedWidthsm:56 / md:60 / default:64 / lg:72number | stringvertical 전용: 접혔을 때 너비(크기에 따라 자동 계산, px 숫자 또는 CSS 문자열로 덮어쓰기 가능)
radius"lg""sm" | "md" | "lg" | "xl"테두리 반경(horizontal: 컨테이너/아이템 동심, vertical: 직접 적용)
fontWeight"normal""normal" | "semibold"메뉴 아이템 폰트 굵기(active 상태는 항상 semibold)
delayDuration200numberhorizontal 전용: 호버 시 열리기까지 지연(ms)
skipDelayDuration300numberhorizontal 전용: 트리거 간 이동 시 스킵 지연(ms)
valueundefinedstring활성 메뉴 아이템 값(제어 모드)
defaultValueundefinedstring기본 활성 값(비제어 모드)
onValueChangeundefined(value: string) => void활성 아이템 변경 시 콜백
| Name | Type | Default | Description |
|---|---|---|---|
orientation | "horizontal" | "vertical" | "horizontal" | 레이아웃 방향 |
size | "sm" | "md" | "default" | "lg" | "default" | 메뉴 아이템 크기 |
collapsed | boolean | false | vertical 전용: 아이콘만 표시(접힌 사이드바) |
width | number | string | 256 | vertical 전용: 사이드바 너비(px 숫자 또는 CSS 문자열) |
collapsedWidth | number | string | sm:56 / md:60 / default:64 / lg:72 | vertical 전용: 접혔을 때 너비(크기에 따라 자동 계산, px 숫자 또는 CSS 문자열로 덮어쓰기 가능) |
radius | "sm" | "md" | "lg" | "xl" | "lg" | 테두리 반경(horizontal: 컨테이너/아이템 동심, vertical: 직접 적용) |
fontWeight | "normal" | "semibold" | "normal" | 메뉴 아이템 폰트 굵기(active 상태는 항상 semibold) |
delayDuration | number | 200 | horizontal 전용: 호버 시 열리기까지 지연(ms) |
skipDelayDuration | number | 300 | horizontal 전용: 트리거 간 이동 시 스킵 지연(ms) |
value | string | undefined | 활성 메뉴 아이템 값(제어 모드) |
defaultValue | string | undefined | 기본 활성 값(비제어 모드) |
onValueChange | (value: string) => void | undefined | 활성 아이템 변경 시 콜백 |
NavigationMenu.Item
valueundefinedstringRadix 식별자(horizontal 전용)
defaultOpenfalsebooleanvertical 전용: 서브메뉴 초기 펼침 상태
| Name | Type | Default | Description |
|---|---|---|---|
value | string | undefined | Radix 식별자(horizontal 전용) |
defaultOpen | boolean | false | vertical 전용: 서브메뉴 초기 펼침 상태 |
NavigationMenu.Trigger
iconundefinedReactNode레이블 앞에 표시할 아이콘
chevronIcon内蔵SVGReactNode셰브론 아이콘 커스터마이징(horizontal: ▼, vertical: ▶)
| Name | Type | Default | Description |
|---|---|---|---|
icon | ReactNode | undefined | 레이블 앞에 표시할 아이콘 |
chevronIcon | ReactNode | 内蔵SVG | 셰브론 아이콘 커스터마이징(horizontal: ▼, vertical: ▶) |
NavigationMenu.Link
activefalseboolean현재 페이지를 나타냄(aria-current="page")
asChildfalseboolean커스텀 링크 컴포넌트와의 합성(Radix Slot)
iconundefinedReactNode레이블 앞에 표시할 아이콘
hrefundefinedstring링크 대상 URL
| Name | Type | Default | Description |
|---|---|---|---|
active | boolean | false | 현재 페이지를 나타냄(aria-current="page") |
asChild | boolean | false | 커스텀 링크 컴포넌트와의 합성(Radix Slot) |
icon | ReactNode | undefined | 레이블 앞에 표시할 아이콘 |
href | string | undefined | 링크 대상 URL |
NavigationMenu.Group
labelundefinedstring그룹 헤더 레이블
| Name | Type | Default | Description |
|---|---|---|---|
label | string | undefined | 그룹 헤더 레이블 |
Customization
NavigationMenu.Content 안에 자유로운 JSX를 배치하여 메가메뉴, 카드형 레이아웃 등을 유연하게 커스터마이징할 수 있습니다.
메가메뉴
<NavigationMenu.Content>
<div className="grid grid-cols-3 gap-4 p-4 w-[480px]">
<div>
<h4 className="text-xs font-semibold uppercase mb-2">
Electronics
</h4>
<NavigationMenu.Link href="#">
Smartphones
</NavigationMenu.Link>
<NavigationMenu.Link href="#">
Laptops
</NavigationMenu.Link>
</div>
{/* ...more columns */}
</div>
</NavigationMenu.Content>카드형 레이아웃
<NavigationMenu.Content>
<div className="grid grid-cols-2 gap-2 p-3 w-[400px]">
<a href="#" className="block p-3 rounded-lg
hover:bg-background-muted">
<div className="text-sm font-semibold">
Documentation
</div>
<div className="text-xs text-text-muted">
Getting started guides and API references.
</div>
</a>
{/* ...more cards */}
</div>
</NavigationMenu.Content>Tip:NavigationMenu.Content 내의 레이아웃은 완전히 자유입니다. 그리드, 플렉스, 카드 등 프로젝트에 맞게 커스터마이징하세요.chevronIcon prop으로 셰브론 아이콘도 교체할 수 있습니다.
Anatomy
h-10 (40px)px-4 (16px)gap-2 (8px)Best Practices
권장
- ✓사이트의 주요 섹션 이동에 사용하세요
- ✓active로 현재 페이지를 명시하세요
- ✓사이드바에는 아이콘과 레이블을 함께 사용하세요
- ✓관련 링크는 Group으로 섹션을 나누세요
지양
- ✗3단계 이상의 중첩을 피하세요
- ✗수평 모드에 아이템을 너무 많이 넣지 마세요
- ✗collapsed 모드에서 툴팁 없이 아이콘만 사용하지 마세요
- ✗액션 실행 용도로 사용하지 마세요. Dropdown을 대신 사용하세요
Accessibility
키보드 조작
Tab메뉴로 포커스 이동Arrow Keys트리거/링크 간 이동Enter / Space링크 활성화 / 콘텐츠 열기Escape콘텐츠 닫고 트리거로 돌아가기ARIA / WCAG
aria-label="navigation"nav 요소에 설정aria-current="page"활성 링크에 자동 설정- Radix NavigationMenu + Collapsible을 통한 완전한 키보드 지원
- WAI-ARIA Disclosure Navigation Pattern 준수