NavigationMenu
用于构建站点顶部导航、产品导航和带预览面板的多级导航菜单
NavigationMenu 用于构建横向导航菜单。组件基于 Radix Navigation Menu 封装,既支持通过 items 数据快速渲染链接和下拉内容,也支持使用结构组件手动组合复杂导航。
import {
NavigationMenu,
NavigationMenuChildLink,
NavigationMenuContent,
NavigationMenuItem,
NavigationMenuLink,
NavigationMenuList,
NavigationMenuRoot,
NavigationMenuTrigger,
NavigationMenuViewport
} from '@skyroc/web-ui';架构说明
NavigationMenu 提供两层使用方式:
NavigationMenu:数据驱动入口,接收items后自动渲染顶层链接、带子菜单的触发器、子链接列表、指示器和视口。- 结构组件:
NavigationMenuRoot、NavigationMenuList、NavigationMenuItem、NavigationMenuTrigger、NavigationMenuContent、NavigationMenuLink等,适合需要完全控制 DOM 结构时使用。
主组件会把 size 传递给列表、触发器、链接、子列表、指示器和视口,使导航整体保持统一尺寸。classNames 用于按 slot 覆盖样式,例如 list、trigger、subLink、viewport。
何时使用
- 页面顶部需要展示站点级导航或产品导航。
- 顶层导航包含链接和可展开的二级链接面板。
- 需要键盘可访问、带 active 指示器和 viewport 动画的导航菜单。
- 简单面包屑路径优先使用 Breadcrumb;应用菜单栏和命令菜单优先使用 Menubar 或 DropdownMenu。
基础用法
通过 items 描述顶层导航。带 children 的项会渲染为触发器和下拉内容;没有 children 或 type: 'link' 的项会渲染为直接跳转链接。
导航项类型
items 支持两类顶层导航项:
| 类型 | 说明 |
|---|---|
item | 带子菜单的导航项,children 渲染为二级链接列表 |
link | 顶层直接链接;没有 children 时也按链接处理 |
<NavigationMenu
items={[
{
value: 'guide',
label: 'Guide',
children: [
{
label: 'Introduction',
href: '/docs',
description: 'Start with the core concepts.'
}
]
},
{
type: 'link',
label: 'GitHub',
href: 'https://github.com'
}
]}
/>自定义链接组件
顶层链接和子链接都支持 component,可传入路由组件,例如 Next.js Link。组件会通过 Radix asChild 组合到底层链接上。
<NavigationMenu
items={[
{
label: 'Components',
children: [
{
label: 'Button',
component: Link,
href: '/components/button',
description: 'Trigger actions and submit forms.'
}
]
}
]}
/>插槽与样式
通过 leading 和 trailing 为触发器或链接加入前后内容。没有传入 trailing 时,顶层链接默认展示外链箭头,带子菜单的触发器默认展示向下箭头。
classNames 可精确覆盖内部 slot:
<NavigationMenu
classNames={{
trigger: 'px-3',
subLink: 'w-80',
viewport: 'shadow-xl'
}}
items={items}
/>API
NavigationMenu
通用属性参考:基于 Radix Navigation Menu Root,并使用 items 渲染数据驱动导航。
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| items* | 顶层导航项数据 | NavigationMenuItemOption[] | - |
| size | 尺寸,影响列表间距、链接字号、子菜单间距、指示器和 viewport 间距 | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | 'md' |
| classNames | 导航菜单各 slot 的自定义 class | NavigationMenuClassNames | - |
| childLinkProps | 传递给每个子链接的额外属性 | NavigationMenuChildLinkProps | - |
| childListItemProps | 传递给每个子链接 li 容器的额外属性 | NavigationMenuChildListItemProps | - |
| childListProps | 传递给子链接 ul 容器的额外属性 | NavigationMenuChildListProps | - |
| contentProps | 传递给下拉内容容器的额外属性 | NavigationMenuContentProps | - |
| itemProps | 传递给每个顶层 item 容器的额外属性 | NavigationMenuItemProps | - |
| linkProps | 传递给顶层直接链接的额外属性 | NavigationMenuLinkProps | - |
| listProps | 传递给顶层列表容器的额外属性 | NavigationMenuListProps | - |
| triggerProps | 传递给带子菜单的顶层触发器的额外属性 | NavigationMenuTriggerProps | - |
| showArrow | 保留字段;当前实现中不会改变 Indicator 的渲染 | boolean | - |
| value | 受控模式下当前打开的顶层导航项 value | string | - |
| defaultValue | 非受控模式下默认打开的顶层导航项 value | string | - |
| onValueChange | 打开的顶层导航项变化时触发 | (value: string) => void | - |
| delayDuration | 鼠标进入触发器后打开内容的延迟时间 | number | - |
| skipDelayDuration | 从一个触发器移动到另一个触发器时跳过延迟的时间窗口 | number | - |
| dir | 文本方向 | 'ltr' | 'rtl' | - |
顶层导航项
NavigationMenuItemOption 描述 items 中的每个顶层导航项。
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| label* | 顶层导航项显示内容 | ReactNode | - |
| type | 导航项类型;带 children 时通常省略 | 'item' | 'link' | - |
| children | 二级导航链接数据;存在时渲染为下拉内容 | NavigationMenuItemChildOption[] | - |
| value | 带子菜单导航项的标识,用于 Radix 受控状态 | string | - |
| href | 链接地址;顶层直接链接和子链接均可使用 | string | - |
| component | 自定义链接渲染组件,例如 Next.js Link | ElementType | - |
| description | 子链接描述文本;顶层 item 类型中也保留该字段 | ReactNode | - |
| disabled | 是否禁用链接交互样式 | boolean | - |
| leading | 前置插槽,常用于图标 | ReactNode | - |
| trailing | 后置插槽;未提供时链接或触发器会渲染默认图标 | ReactNode | - |
| className | 当前项根元素的自定义 class | ClassValue | - |
| classNames | 当前链接或触发器可覆盖的 slot class | NavigationMenuClassNames | NavigationMenuChildLinkClassNames | - |
结构组件
NavigationMenu 同时导出 Radix 风格结构组件,适合手动组织导航结构。
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| NavigationMenuRoot | 根导航容器,基于 Radix Root | NavigationMenuRootProps | - |
| NavigationMenuList | 顶层列表容器,基于 Radix List | NavigationMenuListProps | - |
| NavigationMenuItem | 顶层导航项容器,基于 Radix Item | NavigationMenuItemProps | - |
| NavigationMenuTrigger | 带子菜单导航项的触发器 | NavigationMenuTriggerProps | - |
| NavigationMenuContent | 展开后的下拉内容容器 | NavigationMenuContentProps | - |
| NavigationMenuLink | 顶层直接链接,基于 Radix Link asChild | NavigationMenuLinkProps | - |
| NavigationMenuChildList | 二级链接列表 ul 容器 | NavigationMenuChildListProps | - |
| NavigationMenuChildListItem | 二级链接列表 li 容器 | NavigationMenuChildListItemProps | - |
| NavigationMenuChildLink | 二级导航链接,支持描述文本 | NavigationMenuChildLinkProps | - |
| NavigationMenuIndicator | 当前触发项下方的箭头指示器 | NavigationMenuIndicatorProps | - |
| NavigationMenuViewport | 承载下拉内容动画与尺寸的 viewport | NavigationMenuViewportProps | - |
类型
NavigationMenuProps
主组件属性。继承 Radix Navigation Menu Root props,并通过 items 渲染数据驱动导航。
| 字段 | 类型 | 说明 |
|---|---|---|
| items* | NavigationMenuItemOption[] | 顶层导航项数据。 |
| size | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | 组件尺寸。 |
| className | ClassValue | 根导航容器 class。 |
| classNames | NavigationMenuClassNames | 导航菜单各 slot 的自定义 class。 |
| childLinkProps | NavigationMenuChildLinkProps | 传递给每个子链接的属性。 |
| childListItemProps | NavigationMenuChildListItemProps | 传递给每个子链接 li 容器的属性。 |
| childListProps | NavigationMenuChildListProps | 传递给二级链接列表容器的属性。 |
| contentProps | NavigationMenuContentProps | 传递给下拉内容容器的属性。 |
| itemProps | NavigationMenuItemProps | 传递给顶层 item 容器的属性。 |
| linkProps | NavigationMenuLinkProps | 传递给顶层直接链接的属性。 |
| listProps | NavigationMenuListProps | 传递给顶层列表容器的属性。 |
| triggerProps | NavigationMenuTriggerProps | 传递给带子菜单触发器的属性。 |
| showArrow | boolean | 保留字段;当前实现中不会改变 Indicator 的渲染。 |
| value | string | 受控打开项 value。 |
| defaultValue | string | 默认打开项 value。 |
| onValueChange | (value: string) => void | 打开项变化回调。 |
| delayDuration | number | 打开延迟时间。 |
| skipDelayDuration | number | 跳过延迟的时间窗口。 |
| dir | 'ltr' | 'rtl' | 文本方向。 |
NavigationMenuItemBaseOption
带子菜单的顶层导航项。继承 NavigationMenuTriggerProps 的可用字段。
| 字段 | 类型 | 说明 |
|---|---|---|
| label* | ReactNode | 顶层触发器内容。 |
| type | 'item' | 导航项类型,可省略。 |
| children | NavigationMenuItemChildOption[] | 二级导航链接数据。 |
| description | ReactNode | 描述文本,当前主组件不会直接渲染该字段。 |
| value | string | 顶层导航项标识。 |
| leading | ReactNode | 触发器前置内容。 |
| trailing | ReactNode | 触发器后置内容;未提供时显示默认下拉图标。 |
| disabled | boolean | 是否禁用触发器。 |
| className | ClassValue | 触发器 class。 |
| classNames | Pick<NavigationMenuClassNames, 'trigger' | 'triggerIcon'> | 触发器相关 slot class。 |
NavigationMenuLinkBaseOption
顶层直接链接。继承 NavigationMenuLinkProps 的可用字段。
| 字段 | 类型 | 说明 |
|---|---|---|
| label* | ReactNode | 链接显示内容。 |
| type* | 'link' | 标识为顶层直接链接。 |
| href | string | 链接地址。 |
| component | ElementType | 自定义链接渲染组件。 |
| disabled | boolean | 是否禁用链接交互样式。 |
| leading | ReactNode | 链接前置内容。 |
| trailing | ReactNode | 链接后置内容;未提供时显示默认外链图标。 |
| className | ClassValue | 链接 class。 |
| classNames | Pick<NavigationMenuClassNames, 'itemIcon' | 'link' | 'linkIcon'> | 链接相关 slot class。 |
NavigationMenuItemChildOption
二级导航链接数据。继承 NavigationMenuChildLinkProps 的可用字段。
| 字段 | 类型 | 说明 |
|---|---|---|
| label* | ReactNode | 子链接显示内容。 |
| href | string | 链接地址。 |
| component | ElementType | 自定义链接渲染组件。 |
| description | ReactNode | 显示在 label 下方的描述文本。 |
| disabled | boolean | 是否禁用链接交互样式。 |
| leading | ReactNode | 子链接前置内容。 |
| trailing | ReactNode | 子链接后置内容;未提供时显示默认图标。 |
| className | ClassValue | 子链接 class。 |
| classNames | NavigationMenuChildLinkClassNames | 子链接相关 slot class。 |
NavigationMenuClassNames
导航菜单各 slot 的自定义 class,用于精细化覆盖内部样式。
| 字段 | 类型 | 说明 |
|---|---|---|
| root | ClassValue | 根导航容器 class。 |
| viewportRoot | ClassValue | viewport 外层定位容器 class。 |
| viewport | ClassValue | viewport 容器 class。 |
| content | ClassValue | 下拉内容容器 class。 |
| arrow | ClassValue | 指示器箭头 class。 |
| list | ClassValue | 顶层列表 class。 |
| subList | ClassValue | 二级链接列表 class。 |
| item | ClassValue | 顶层 item 容器 class。 |
| subItem | ClassValue | 二级链接 li 容器 class。 |
| itemIcon | ClassValue | 链接前置图标 class。 |
| trigger | ClassValue | 触发器 class。 |
| subItemContent | ClassValue | 保留 slot,当前实现中未直接使用。 |
| triggerIcon | ClassValue | 触发器默认下拉图标 class。 |
| indicator | ClassValue | 指示器容器 class。 |
| link | ClassValue | 顶层直接链接 class。 |
| subLink | ClassValue | 二级链接 class。 |
| linkIcon | ClassValue | 链接默认后置图标 class。 |
| subLinkContent | ClassValue | 二级链接文本容器 class。 |
| subLinkLabel | ClassValue | 二级链接标题 class。 |
| subLinkDescription | ClassValue | 二级链接描述 class。 |
NavigationMenuChildLinkClassNames
二级链接可覆盖的 slot class。类型上与 NavigationMenuClassNames 保持同一组 slot。
| 字段 | 类型 | 说明 |
|---|---|---|
| subLink | ClassValue | 二级链接 class。 |
| subLinkContent | ClassValue | 二级链接文本容器 class。 |
| subLinkLabel | ClassValue | 二级链接标题 class。 |
| subLinkDescription | ClassValue | 二级链接描述 class。 |
| itemIcon | ClassValue | 前置图标 class。 |
| linkIcon | ClassValue | 后置图标 class。 |
NavigationMenuRootProps
根导航容器属性,继承 Radix Navigation Menu Root props。
| 字段 | 类型 | 说明 |
|---|---|---|
| className | ClassValue | 根容器 class。 |
| size | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | 组件尺寸字段,根容器当前不直接使用。 |
| value | string | 受控打开项 value。 |
| defaultValue | string | 默认打开项 value。 |
| onValueChange | (value: string) => void | 打开项变化回调。 |
| delayDuration | number | 打开延迟时间。 |
| skipDelayDuration | number | 跳过延迟的时间窗口。 |
| dir | 'ltr' | 'rtl' | 文本方向。 |
NavigationMenuListProps
顶层列表容器属性,继承 Radix Navigation Menu List props。
| 字段 | 类型 | 说明 |
|---|---|---|
| className | ClassValue | 列表容器 class。 |
| size | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | 列表尺寸,影响 gap 与字号。 |
NavigationMenuItemProps
顶层 item 容器属性,继承 Radix Navigation Menu Item props。
| 字段 | 类型 | 说明 |
|---|---|---|
| className | ClassValue | item 容器 class。 |
| value | string | item 标识。 |
NavigationMenuTriggerProps
触发器属性,继承 Radix Trigger props 并增加前后插槽。
| 字段 | 类型 | 说明 |
|---|---|---|
| children | ReactNode | 触发器文本或内容。 |
| className | ClassValue | 触发器 class。 |
| classNames | Pick<NavigationMenuClassNames, 'trigger' | 'triggerIcon'> | 触发器相关 slot class。 |
| leading | ReactNode | 前置插槽。 |
| trailing | ReactNode | 后置插槽;未提供时显示默认下拉图标。 |
| size | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | 触发器尺寸。 |
| disabled | boolean | 是否禁用触发器。 |
NavigationMenuLinkProps
顶层直接链接属性,继承 Radix Link props 并通过 asChild 渲染自定义组件。
| 字段 | 类型 | 说明 |
|---|---|---|
| children | ReactNode | 链接显示内容。 |
| className | ClassValue | 链接 class。 |
| classNames | Pick<NavigationMenuClassNames, 'itemIcon' | 'link' | 'linkIcon'> | 链接相关 slot class。 |
| component | ElementType | 自定义链接渲染组件。 |
| disabled | boolean | 是否禁用链接交互样式。 |
| leading | ReactNode | 前置插槽。 |
| trailing | ReactNode | 后置插槽;未提供时显示默认外链图标。 |
| size | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | 链接尺寸。 |
| href | string | 链接地址。 |
NavigationMenuChildLinkProps
二级导航链接属性,继承 Radix Link props 并支持描述文本。
| 字段 | 类型 | 说明 |
|---|---|---|
| children | ReactNode | 子链接显示内容。 |
| className | ClassValue | 子链接 class。 |
| classNames | NavigationMenuChildLinkClassNames | 子链接相关 slot class。 |
| component | ElementType | 自定义链接渲染组件,默认 a。 |
| description | ReactNode | 显示在 label 下方的描述文本。 |
| disabled | boolean | 是否禁用链接交互样式。 |
| leading | ReactNode | 前置插槽。 |
| trailing | ReactNode | 后置插槽;未提供时显示默认图标。 |
| size | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | 子链接尺寸。 |
| href | string | 链接地址。 |
NavigationMenuChildListProps
二级链接列表容器属性,继承原生 ul 元素属性。
| 字段 | 类型 | 说明 |
|---|---|---|
| className | ClassValue | 列表容器 class。 |
| size | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | 列表尺寸,影响 gap、padding 与字号。 |
NavigationMenuContentProps
下拉内容容器属性,继承 Radix Navigation Menu Content props。
| 字段 | 类型 | 说明 |
|---|---|---|
| className | ClassValue | 内容容器 class。 |
NavigationMenuIndicatorProps
指示器属性,继承 Radix Indicator props;当前封装固定渲染内部箭头元素。
| 字段 | 类型 | 说明 |
|---|---|---|
| className | ClassValue | 指示器容器 class。 |
| classNames | Pick<NavigationMenuClassNames, 'arrow' | 'indicator'> | 指示器与箭头 slot class。 |
| size | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | 指示器尺寸。 |
NavigationMenuViewportProps
viewport 属性,继承 Radix Navigation Menu Viewport props。
| 字段 | 类型 | 说明 |
|---|---|---|
| className | ClassValue | viewport class。 |
| classNames | Pick<NavigationMenuClassNames, 'viewport' | 'viewportRoot'> | viewport 与外层容器 slot class。 |
| size | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | viewport 尺寸。 |
NavigationMenuItemOption
顶层导航项联合类型。带 children 的项渲染为触发器和内容面板;type 为 link 或没有 children 的项渲染为直接链接。
ElementType
可作为链接渲染目标的 React 元素或组件类型,例如 'a' 或 Next.js Link。