跳转到内容

导航菜单 navigation-menu

导航组件。三层同源:无头内核给出解剖与状态机,Vue 组件与自定义元素只是它的两层外壳,行为完全一致。

示例

基础用法

入口写在 collection 里、面板内容走 panel 插槽;面板落在同一个 li 里、紧跟 trigger 之后,展开时按 Tab 就走得进去,里面的条目是链接不是命令,点了就跳走

受控

传了 value 就由宿主说了算,null 表示都收起;v-model:value 是它的语法糖

展开的面板:(都收着)

展开延时

delay-duration 是悬停多久才展开,防的是指针横穿导航时一路闪出面板;skip-delay-duration 是收起后的静默窗口,窗口内再碰任意入口直接展开

竖排

orientation="vertical" 把入口排成一列、面板改从侧边长出来,方向键随之改收上下键

语气

tone 换的是入口的高亮底与指示条、当前链接的文字色,静止态一样:悬停到入口上、或用方向键把焦点移过去才显现

尺寸

size 一档换掉入口的高度、内边距与字号,写在 root 上、面板里的链接一并跟着变

直达入口

没有下级的去处不必套面板:数据里写了 href 的那一项铺成一条 link,它不进方向键那一组(那一组只认 trigger),按 Tab 一样到得了

共享面板外壳

面板整批塞进 viewport 后落位归外壳管:几个入口的面板落在同一处,宽窄不同也不再各贴各的入口

默认展开项

defaultValue 只定首帧展开哪一项,之后照常由交互接管;指针移开、Escape 或点回入口都收得起来

收窄成一列图标

竖排时面板本就从入口侧边长出来;收窄只是把文字从入口里撤掉、把它挪进面板,指针停上去才露出来

产物

自定义元素<xh-navigation-menu>
Vue 组件XhNavigationMenuContent XhNavigationMenuIndicator XhNavigationMenuItem XhNavigationMenuLink XhNavigationMenuList XhNavigationMenuRoot XhNavigationMenuTrigger XhNavigationMenuViewport
组合式函数useNavigationMenu
状态机navigationMenuMachine
皮肤@xihan-ui/styles/navigation-menu.css

解剖

部件名即 data-part 属性值,也是皮肤的选择器。加粗的是必备部件,不渲染它组件不工作(Web Components 适配器会在诊断通道上报 wc.missing-part)。

data-scope="navigation-menu"root · list · item · trigger · content · link · indicator · viewport

Props

属性类型必填说明
collectionNavigationMenuNode[]入口数据,入口文本与禁用的事实源。给了它,trigger 部件只需报 value。 缺省即回到「文本与禁用都写在部件上」的老路。
valuestring | null当前展开项,给定即受控;null 表示都收起。
defaultValuestring | null
orientationOrientation方向键轴向,默认 horizontal。
delayDurationnumber悬停/聚焦到 trigger 后等多久才展开,默认 200ms。
skipDelayDurationnumber收起之后的静默窗口,默认 300ms;窗口内再碰任意 trigger 直接展开。
dirDirection文字方向,默认 ltr。
loopboolean方向键走到尽头是否回绕,默认 true。
translationsPartial<NavigationMenuTranslations>
toneTone语气:brand / neutral / success / warning / danger / info,决定用哪族颜色。
sizeSize尺寸:sm / md / lg。
onValueChange(details: NavigationMenuValueChangeDetails) => voidvalue 变化回调。

状态机

状态idle · opening · skipping

事件TRIGGER.POINTER · TRIGGER.FOCUS · TRIGGER.TOGGLE · DISMISS · VALUE.SET · after.delayDuration · after.skipDelayDuration

判据hasValue · isCurrent · shouldKeepOpen

connect API

useNavigationMenu 产出的对象。getXxxProps() 铺到对应部件的宿主元素上,其余是可读状态与操作入口。

成员类型说明
valuestring | null当前展开的那一项;都收起时为 null。
collectionreadonly NavigationMenuNodeMeta[]collection 推出的入口元信息,按数据顺序排列;没给 collection 即空数组。
openboolean有没有面板展开着。
isOpen(value: string) => boolean
setValue(next: string | null) => void
getRootProps() => T['element']
getListProps() => T['element']
getItemProps() => T['element']
getTriggerProps(props: NavigationMenuTriggerProps) => T['button']
getContentProps(props: NavigationMenuContentProps) => T['element']
getLinkProps(props: NavigationMenuLinkProps) => T['element']
getIndicatorProps() => T['element']
getViewportProps() => T['element']

键盘

规格出处:W3C APG

按键生效条件行为
ArrowRight / ArrowDownfocus in trigger, 按键与 orientation 同轴焦点移到下一个 trigger(禁用项跳过、尽头按 loop 回绕);随后的自动展开走 delayDuration
ArrowLeft / ArrowUpfocus in trigger, 按键与 orientation 同轴焦点移到上一个 trigger
Homefocus in trigger焦点移到首个可停留 trigger
Endfocus in trigger焦点移到末个可停留 trigger
Enter / Spacefocus in trigger, not disabled立即展开对应面板(不走 delayDuration);面板是自动弹出来的那一次不收起,再按一次才收起
Escapeopen收起面板并把焦点归还对应 trigger;静默窗口内这一次归还不会把面板重新弹出来
Tab / Shift+Tabopen, focus in trigger走进展开的面板:面板就在 trigger 之后,收起的面板带 hidden 因而被整个跳过

Released under The MIT License