컴포넌트
Navigation Menu
하위 링크가 있는 탐색 메뉴를 표시합니다.
설치
pnpm dlx ply-ui add navigation-menu icon공통 설치 설정을 먼저 적용합니다.
사용법
Content 안에 Link를 두고, 공유 Portal/Viewport에서 펼친 내용을 표시합니다.
단순한 세로 링크 목록에는 Sidebar/NavigationLink를 사용할 수 있습니다.
구성
| 구성 요소 | 역할 |
|---|---|
Root | 탐색 메뉴 상태를 관리합니다. |
List / Item | 메뉴 목록과 하나의 항목입니다. |
Trigger | 하위 탐색 내용을 펼칩니다. |
Content | 항목에 연결된 하위 탐색 내용입니다. |
Link | 실제 이동할 주소를 가진 링크입니다. |
Portal / Positioner / Popup | 하위 내용의 위치와 표면을 구성합니다. |
구현 코드
components/ui/navigation-menu.tsx
"use client";
import type { ComponentProps } from "react";
import { NavigationMenu as Primitive } from "@base-ui/react/navigation-menu";
import { withClassName } from "../../lib/cx";
import "./navigation-menu.css";
// 동작과 접근성은 Base UI가 담당합니다. 이 파일은 스타일 연결만 담당합니다.
function NavigationMenuRoot({
className,
...props
}: ComponentProps<typeof Primitive.Root>) {
return (
<Primitive.Root
{...props}
className={withClassName("rbx-navigation-menu", className)}
/>
);
}
function NavigationMenuList({
className,
...props
}: ComponentProps<typeof Primitive.List>) {
return (
<Primitive.List
{...props}
className={withClassName("rbx-nav-list", className)}
/>
);
}
function NavigationMenuTrigger({
className,
...props
}: ComponentProps<typeof Primitive.Trigger>) {
return (
<Primitive.Trigger
{...props}
className={withClassName("rbx-button", className)}
/>
);
}
function NavigationMenuLink({
className,
...props
}: ComponentProps<typeof Primitive.Link>) {
return (
<Primitive.Link
{...props}
className={withClassName("rbx-nav-link", className)}
/>
);
}
function NavigationMenuContent({
className,
...props
}: ComponentProps<typeof Primitive.Content>) {
return (
<Primitive.Content
{...props}
className={withClassName("rbx-nav-content", className)}
/>
);
}
function NavigationMenuPopup({
className,
...props
}: ComponentProps<typeof Primitive.Popup>) {
return (
<Primitive.Popup
{...props}
className={withClassName("rbx-popup", className)}
/>
);
}
function NavigationMenuPositioner({
className,
...props
}: ComponentProps<typeof Primitive.Positioner>) {
return (
<Primitive.Positioner
{...props}
className={withClassName("rbx-positioner", className)}
/>
);
}
// Root/Portal 등 스타일 없는 파트와 제네릭 API는 원본을 그대로 보존합니다.
export const NavigationMenu = {
...Primitive,
Root: NavigationMenuRoot,
List: NavigationMenuList,
Trigger: NavigationMenuTrigger,
Link: NavigationMenuLink,
Content: NavigationMenuContent,
Popup: NavigationMenuPopup,
Positioner: NavigationMenuPositioner,
};
components/ui/navigation-menu.css
@import "./button.css";
/* NavigationMenu: 공통 구조는 theme.css, 컴포넌트 전용 조정은 아래에 작성합니다. */
.rbx-nav-list {
display: flex;
list-style: none;
gap: 8px;
padding: 0;
margin: 0;
}
.rbx-nav-content {
padding: 16px;
display: grid;
gap: 12px;
}
/* 링크를 버튼 표면으로 합성할 때 전경도 같은 action 역할을 사용합니다. */
.rbx-nav-link.rbx-button {
color: var(--rbx-color-action-standard-foreground);
}