Menubar 菜单栏
用于桌面应用的横向命令菜单栏。
用法
在一条菜单栏中组织应用命令
组件结构
加粗的是必需部件。
data-scope="menubar":root · trigger · positioner · content · item · item-icon · item-text · item-description · item-shortcut · item-suffix · item-indicator · separator · group · group-label · arrow
示例
分组
在菜单内组织相关命令
图标与快捷键
补充常用命令的识别信息
子菜单
在菜单栏命令中打开下一层
菜单栏设置
checkbox 与 radio 的值独立于当前展开菜单
设计指引
何时使用
- 在编辑器或桌面应用中按“文件、编辑、视图”组织命令。
何时不用
特性
- 同一时间只展开一个顶层菜单。
- 展开后移向相邻入口会直接切换菜单。
- 不写结构时照标准结构铺:一排入口按钮(文字取入口的
label),其后是各自菜单的定位层,里面按这张菜单的items铺条目、分组与分隔线;条目的item插槽只接管条目文字,带children的条目是一个嵌套的子菜单,入口与普通条目一样铺图标(icon)与文字。Vue / React 不写默认插槽与 Web Components 不写部件(或只写 root)时生成的节点出自同一个结构函数;Web Components 里条目文字、行首、行尾可用宿主直接子节点slot="item:<值>"、slot="item-prefix:<值>"、slot="item-suffix:<值>"给出,子菜单生成嵌套的<xh-menu submenu>。指向锚点的箭头要手写结构时自己摆。 - 支持方向键、首字符检索、禁用项、分组与子菜单。数据驱动时菜单里的条目写
children(一组菜单条目)即为子菜单入口,默认树按children递归铺出下一层,深度不限;子层条目按数据铺,不经本层的插槽。手写时用XhMenubarSub。子菜单那一层的勾选值与单选值写在带children的条目上(checkboxValue/radioValue),与子菜单自己的同名属性同义,写了即受控;按数据铺时子层的勾选改动不另外上报,勾选条目写closeOnSelect,由根上的item-select得知。 - 条目可逐条声明语气;顶层入口表达的是位置,不接语气。
- 说明与快捷键提示都可写进
collection;快捷键贴行尾,与说明同档同色。快捷键提示只是看的,读屏不念;要读屏念出快捷键,条目再写keyshortcuts,落成条目的aria-keyshortcuts。勾选与单选条目的勾是条目的最后一个部件,排在正文、说明与快捷键之后,与子菜单箭头同列,图标与普通条目左缘对齐;手写部件时写在哪都排到行尾。同一层有勾选条目时,普通条目的快捷键与它们同列。 - 条目可组合图标、文字、说明和快捷键提示。同一层(跨分组与分隔线,子菜单另算)里只要有一条带图标,所有条目都空出图标那一格,正文左缘对齐;整层都没有图标就不留。
- 下拉与它的子菜单只按落定那一侧的可用高度封顶(留出与视口边缘的间距),和桌面应用的菜单栏一样,不叠菜单 20rem 那一档;要收矮写
--xh-menubar-max-h。 - 菜单内支持
CheckboxItem与RadioGroup / RadioItem;选择值独立于当前展开的顶层菜单,切换后默认保持菜单栏展开。 - 首次展开与最终关闭使用短距离淡变,顶层菜单切换不播放交叉动画。
组合
- 菜单栏应放在宽度稳定的应用顶栏中。
最佳实践
- 顶层入口使用单个名词,并控制在少量常用分类内。
- 破坏性命令放在菜单末尾并与普通命令分隔。
- 仅为已注册的快捷键显示提示。
- “视图”等设置菜单优先使用选择型条目,状态由
aria-checked与可见标记同时表达。
反模式
- 不要在菜单栏中堆积过多顶层入口。
- 不要用菜单栏代替持久选项控件。
API 参考
产物
| 层 | 值 |
|---|---|
| 自定义元素 | <xh-menubar> |
| Vue 组件 | XhMenubarArrow XhMenubarCheckboxItem XhMenubarContent XhMenubarGroup XhMenubarGroupLabel XhMenubarItem XhMenubarItemDescription XhMenubarItemIcon XhMenubarItemIndicator XhMenubarItemShortcut XhMenubarItemSuffix XhMenubarItemText XhMenubarPositioner XhMenubarRadioGroup XhMenubarRadioItem XhMenubarRoot XhMenubarSeparator XhMenubarSub XhMenubarSubTrigger XhMenubarTrigger |
| 组合式函数 | useMenubar |
| 状态机 | menubarMachine |
| 皮肤 | @xihan-ui/styles/menubar.css |
Props
| 属性 | 类型 | 必填 | 说明 |
|---|---|---|---|
collection | MenubarNode[] | 菜单栏数据,显示文本与禁用的事实源。提供后入口与条目部件只需声明 value。 未提供时回到文本与禁用逐个写在部件上的方式。 | |
checkboxValue | string[] | ||
defaultCheckboxValue | string[] | ||
radioValue | MenuRadioValue | ||
defaultRadioValue | MenuRadioValue | ||
value | string | null | 当前展开项,提供即受控;null 表示全部收起。 | |
defaultValue | string | null | ||
orientation | Orientation | 菜单栏排布轴,默认 horizontal。 | |
loop | boolean | 方向键到达末尾是否回绕,默认 true。 | |
dir | Direction | 文字方向,默认 ltr。 | |
disabled | boolean | 整条菜单栏禁用,展开与选中都不发生。 | |
typeahead | boolean | 菜单内的连打检索,默认开启。 | |
placement | Placement | ||
offset | number | ||
tone | Tone | 语气:brand / neutral / success / warning / danger / info,决定使用哪族颜色。 | |
size | Size | 尺寸:sm / md / lg。 | |
translations | Partial<MenubarTranslations> | ||
onValueChange | (details: MenubarValueChangeDetails) => void | value 变化回调。 | |
onItemSelect | (details: MenubarItemSelectDetails) => void | 条目被选中;菜单随之收起。 | |
onCheckboxValueChange | (details: MenuCheckboxValueChangeDetails) => void | ||
onRadioValueChange | (details: MenuRadioValueChangeDetails) => void |
MenubarNode
collection 的元素。
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
value | string | 是 | |
kind | MenuChoiceKind | items 中的条目语义;顶层入口忽略该字段。 | |
label | string | 展示文本,也是菜单内连打检索的取字来源;默认回退为 value。 | |
icon | IconRecord | 图标,写入 item-icon 部件,排在条目文字之前;只在条目上读取,未提供时本条不铺该部件。 纯装饰:读屏从条目文字取意,不念它。勾选与单选条目的勾仍在 item-indicator,两者各占一格。 | |
description | string | 副文本,写入 item-description 部件;只在条目上读取。 | |
shortcut | string | 快捷键提示,写入 item-shortcut 部件;未提供时本条不铺该部件。 纯装饰:读屏从条目文字取意,不念它;只为真正注册了的组合写提示。 | |
keyshortcuts | string | 条目的 aria-keyshortcuts:读屏念的快捷键,写法照 ARIA(修饰键在前,如 Control+S、Meta+Shift+Z,几组用空格隔开), 未提供时不写。与 shortcut 各管各:shortcut 是看得见的提示、读屏不念,这一项只给读屏,两处说的应是同一组键。 | |
disabled | boolean | 禁用:方向键跳过它,但它仍可聚焦、仍是导航起点。 | |
tone | Tone | 该条命令自身动作的性质:删除写 danger、停用写 warning。只在条目上读取—— 顶层入口表达的是位置不是动作,写了也不产出语气面。 只换字色与悬停 / 按下的面,不改字重与缩进;禁用压过它,破坏性命令仍要配图标。 | |
group | string | 所属分组的身份;相邻同值的条目合并为一个 group。只在条目上读取。 | |
groupLabel | string | 本组的标题文本,写在组内任意一条上即可。只在条目上读取。 | |
separatorBefore | boolean | 本条之前绘制一条分隔线;写在首条上不产出分隔线。只在条目上读取。 | |
closeOnSelect | boolean | 选择型条目激活后是否关闭菜单栏;checkbox / radio 默认 false。 | |
items | MenubarNode[] | 该菜单中的条目;只在顶层节点上读取。 | |
children | MenuNode[] | 子菜单的条目:只在条目上读取。给了 children 这一条就是子菜单的入口,Vue / React 的默认树按 children 递归铺出下一层,深度不限;本条只能是普通条目(kind 为 item)。子层的选中经菜单树汇到菜单栏上。 手写部件时改用 XhMenubarSub;Web Components 由作者写 Light DOM,不读这一项。 | |
checkboxValue | string[] | 子菜单那一层的勾选值:只在带 children 的条目上读取,交给按数据铺出的那一层,与子菜单自己的 checkboxValue 同义, 写了即受控。按数据铺时子层的勾选改动不另外上报,勾选条目写 closeOnSelect,由根上的 item-select 得知。 | |
radioValue | MenuRadioValue | 子菜单那一层的单选值(组 → 选中的值):只在带 children 的条目上读取,其余同 checkboxValue。 |
事件
自定义元素将载荷放在 detail;Vue 使用同名 emit。
| 事件 | 载荷 | 说明 |
|---|---|---|
value-change | MenubarValueChangeDetails | 展开项变化;detail 为 { value: string | null } |
item-select | MenubarItemSelectDetails | 条目被选中(菜单随之收起);detail 为 { menu: string, value: string } |
checkbox-value-change | MenubarCheckboxValueChangeDetails | checkbox 选中集合变化 |
radio-value-change | MenubarRadioValueChangeDetails | RadioGroup 选中映射变化 |
插槽
仅列出带载荷的插槽。
| Vue 组件 | 插槽 | 载荷 | 说明 |
|---|---|---|---|
XhMenubarRoot | default | MenubarRootSlotProps | |
XhMenubarRoot | item | MenubarNodeMeta | 只填条目的文字槽,标记位、副文本与快捷键照旧由数据铺 |
XhMenubarRoot | item-prefix | MenubarNodeMeta | 只接管行首那一格,其余槽照旧由数据铺 |
XhMenubarRoot | item-suffix | MenubarNodeMeta | 只接管行尾那一格(计数、徽标、次级图标),其余槽照旧由数据铺 |
XhMenubarSub | default | MenubarSubSlotProps |
React 适配器 props
只列各组件自己声明的那些:继承自 ComponentPropsWithRef 的 DOM 属性不在其中,根组件上与上面 Props 表同名的也不重复列。Vue 的对应物是上面的插槽表。
| React 组件 | 属性 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
XhMenubarContent | value | string | 默认时沿用外层 positioner 提供的身份,无 positioner 时必填。 | |
XhMenubarGroup | value | string | 是 | |
XhMenubarItem | value | string | 是 | |
XhMenubarItem | disabled | boolean | 默认交给 connect 查询 collection,写死 false 会覆盖数据中的禁用。 | |
XhMenubarPositioner | value | string | 是 | |
XhMenubarPositioner | container | () => Element | null | 浮层挂载的容器;未提供时按全局配置,再未提供时挂载到 body。 | |
XhMenubarRadioGroup | value | string | 是 | |
XhMenubarRoot | renderItem | (node: MenubarNodeMeta) => ReactNode | 每个条目的自定义内容;未提供时使用 collection 中的 label。 | |
XhMenubarRoot | renderItemPrefix | (node: MenubarNodeMeta) => ReactNode | 只接管条目行首那一格;其余槽仍由数据铺。 | |
XhMenubarRoot | renderItemSuffix | (node: MenubarNodeMeta) => ReactNode | 只接管条目行尾那一格(计数、徽标、次级图标);其余槽仍由数据铺。 | |
XhMenubarRoot | children | SlotChildren<MenubarRootSlotProps> | ||
XhMenubarSub | value | string | 是 | 它在所属菜单中的条目身份。 |
XhMenubarSub | label | string | 按数据铺设时触发条目的文字;缺省取所属菜单 items 里这一条的 label。 | |
XhMenubarSub | icon | IconRecord | 按数据铺设时触发条目的图标;缺省取所属菜单 items 里这一条的 icon。 | |
XhMenubarSub | disabled | boolean | ||
XhMenubarSub | collection | MenuNode[] | 子层的条目数据:显示文本与禁用的事实源,按数据铺子层时由默认树代填。 | |
XhMenubarSub | checkboxValue | string[] | ||
XhMenubarSub | defaultCheckboxValue | string[] | ||
XhMenubarSub | radioValue | MenubarRadioValue | ||
XhMenubarSub | defaultRadioValue | MenubarRadioValue | ||
XhMenubarSub | placement | Placement | ||
XhMenubarSub | offset | number | ||
XhMenubarSub | loop | boolean | ||
XhMenubarSub | openOnHover | boolean | ||
XhMenubarSub | hoverOpenDelay | number | ||
XhMenubarSub | hoverCloseDelay | number | ||
XhMenubarSub | dir | Direction | 文字方向;默认继承父层。子层被迁移到浮层落点,无法继承父层的方向。 | |
XhMenubarSub | tone | Tone | 语气;默认继承父层。子层是浮层落点下的同级节点,CSS 私有槽无法继承。 | |
XhMenubarSub | size | Size | 尺寸;默认继承父层,理由同 tone。 | |
XhMenubarSub | onCheckboxValueChange | MenuSchema['props']['onCheckboxValueChange'] | ||
XhMenubarSub | onRadioValueChange | MenuSchema['props']['onRadioValueChange'] | ||
XhMenubarSub | children | SlotChildren<MenubarSubSlotProps> | ||
XhMenubarTrigger | value | string | 是 | |
XhMenubarTrigger | disabled | boolean | 默认交给 connect 查询 collection,写死 false 会覆盖数据中的禁用。 |
状态
公开状态写入 data-state。
| 部件 | 取值 |
|---|---|
root | 'open' | 'closed' |
trigger | 'open' | 'closed' |
positioner | 'open' | 'closed' |
content | 'open' | 'closed' |
item-indicator | 'checked' | 'unchecked' | 'checked' | 'unchecked' | undefined |
以下名称仅用于内部状态机。
状态:idle · open
事件:TRIGGER.TOGGLE · TRIGGER.OPEN · TRIGGER.POINTER · TRIGGER.FOCUS · CLOSE · MENUBAR.BLUR · VALUE.SET · PRESENCE.SET · ITEM.FOCUS · ITEM.LOST · ITEM.SELECT · CHECKBOX.VALUE.SET · RADIO.VALUE.SET · PRESS.START · PRESS.END · SYNC.OPEN · SYNC.CLOSE
判据:hasValue · isCurrent · shouldAbsorbToggle · shouldSwitch · canPress · keepsMenuOpen
connect API
getXxxProps() 返回对应部件的宿主属性。
| 成员 | 类型 | 说明 |
|---|---|---|
value | string | null | 当前展开的项;全部收起时为 null。 |
collection | readonly MenubarNodeMeta[] | 由 collection 推导的入口元信息(各自附带该菜单的条目),按数据顺序排列;未提供 collection 时为空数组。 |
open | boolean | 是否有菜单展开。 |
focusedValue | string | null | trigger 的 roving 锚点;焦点不在菜单栏内时为 null。 |
focusedItem | string | null | 展开菜单内持有焦点的条目;无锚点时为 null。 |
orientation | Orientation | |
disabled | boolean | |
checkboxValue | readonly string[] | |
radioValue | Readonly<MenuRadioValue> | |
isCheckboxItemChecked | (value: string) => boolean | |
isRadioItemChecked | (group: string, value: string) => boolean | |
setCheckboxValue | (next: string[]) => void | |
setRadioValue | (next: MenuRadioValue) => void | |
isOpen | (value: string) => boolean | |
setValue | (next: string | null) => void | |
getRootProps | () => T['element'] | |
getTriggerProps | (props: MenubarTriggerProps) => T['button'] | |
getPositionerProps | (props: MenubarContentProps) => T['element'] | |
getContentProps | (props: MenubarContentProps) => T['element'] | |
getItemProps | (props: MenubarItemProps) => T['element'] | |
getCheckboxItemProps | (props: MenubarCheckboxItemProps) => T['element'] | |
getRadioItemProps | (props: MenubarRadioItemProps) => T['element'] | |
getItemIconProps | (props: MenubarAnyItemProps) => T['element'] | 条目文字之前的图标格;装饰态,读屏不念。 |
getItemTextProps | (props: MenubarAnyItemProps) => T['element'] | |
getItemIndicatorProps | (props: MenubarAnyItemProps) => T['element'] | |
getItemDescriptionProps | (props: MenubarAnyItemProps) => T['element'] | |
getItemShortcutProps | (props: MenubarAnyItemProps) => T['element'] | |
getItemSuffixProps | (props: MenubarAnyItemProps) => T['element'] | |
getSeparatorProps | () => T['element'] | |
getGroupProps | (props: MenubarGroupProps) => T['element'] | |
getRadioGroupProps | (props: MenubarGroupProps) => T['element'] | |
getGroupLabelProps | (props: MenubarGroupProps) => T['element'] | |
getArrowProps | (props: MenubarContentProps) => T['element'] |
无障碍
键盘
规格出处:W3C APG
| 按键 | 生效条件 | 行为 |
|---|---|---|
ArrowRight | focus in trigger, horizontal | 焦点移到下一个 trigger(禁用项跳过、尽头按 loop 回绕);已有菜单展开着则展开项跟着切过去 |
ArrowLeft | focus in trigger, horizontal | 焦点移到上一个 trigger(禁用项跳过、尽头按 loop 回绕);已有菜单展开着则展开项跟着切过去 |
Home | focus in trigger | 焦点移到首个可用 trigger |
End | focus in trigger | 焦点移到末个可用 trigger |
ArrowDown / Enter / Space | focus in trigger, horizontal | 展开本项的菜单;方向键入口把焦点落到首个可用条目,Enter/Space 让焦点留在 trigger 上 |
ArrowUp | focus in trigger, horizontal | 展开本项的菜单并把焦点落到末个可用条目 |
ArrowDown | open, focus in content | 焦点移到下一个条目(禁用项跳过、尽头按 loop 回绕) |
ArrowUp | open, focus in content | 焦点移到上一个条目(禁用项跳过、尽头按 loop 回绕) |
Home | open, focus in content | 焦点移到本张菜单的首个可用条目 |
End | open, focus in content | 焦点移到本张菜单的末个可用条目 |
ArrowRight / ArrowLeft | open, focus in content | 切到相邻菜单并保持展开,焦点落到那一项的 trigger 上 |
a-z / 0-9 | open, focus in content | 连打检索:焦点跳到首字母匹配的条目(同字符连打则在候选间轮换) |
Enter / Space | focus in item, not disabled | 派发选中详情并收起菜单,焦点归还 trigger |
Enter / Space | held in trigger / item, not disabled | 按住期间该部件投影 data-pressed,与指针 :active 同一副按压面;抬起或失焦撤下,条目随菜单收起一并撤下 |
Escape | open | 收起菜单并把焦点留在 trigger 上 |
Tab / Shift+Tab | open | 收起菜单,焦点不被抢回 trigger,按 Tab 序列自然离开 |
ARIA
以下属性由 connect 生成。
| 部件 | 属性 | 值 |
|---|---|---|
root | aria-disabled | 'true' | 'false' |
root | aria-label | translations.root |
root | aria-orientation | props.orientation |
root | role | 'menubar' |
trigger | aria-controls | content 部件的 id |
trigger | aria-disabled | 'true' | 'false' |
trigger | aria-expanded | 'true' | 'false' |
trigger | aria-haspopup | 'menu' |
trigger | role | 'menuitem' |
content | aria-hidden | !isOpen || undefined |
content | aria-labelledby | trigger 部件的 id |
content | role | 'menu' |
item-icon | aria-hidden | 'true' |
item-shortcut | aria-hidden | 'true' |
item-indicator | aria-hidden | 'true' |
separator | aria-orientation | 'horizontal' |
separator | role | 'separator' |
group | aria-labelledby | group-label 部件的 id |
group | role | 'group' |
arrow | aria-hidden | 'true' |
radio-group | aria-labelledby | group-label 部件的 id |
radio-group | role | 'group' |
样式参考
皮肤
@xihan-ui/styles/menubar.css 按 [data-scope="menubar"][data-part="root"] 部件选择器书写,发布产物以挂载类 .xh-scope-menubar 代替其中的 data-scope(特异性相同),位于 xihan.components 层。覆盖样式使用 xihan.overrides,部件选择器照常可用。
forced-colors: active 下另有一套规则:颜色交给系统,边框与状态标记改用系统色关键字。
数据属性
由 connect 生成;条件不成立时不输出无值属性。
| 部件 | 属性 | 值 |
|---|---|---|
root | data-disabled | ''(条件成立时才出现) |
root | data-orientation | props.orientation |
root | data-size | props.size |
root | data-state | 'open' | 'closed' |
root | data-tone | props.tone |
trigger | data-disabled | ''(条件成立时才出现) |
trigger | data-in-path | ''(条件成立时才出现) |
trigger | data-pressed | ''(条件成立时才出现) |
trigger | data-state | 'open' | 'closed' |
trigger | data-xh-collection-context | 'nav' |
trigger | data-xh-collection-item | '' |
trigger | data-xh-collection-size | props.size |
positioner | data-hidden | ''(条件成立时才出现) |
positioner | data-placement | 定位引擎算出的实际落位 | undefined |
positioner | data-positioned | ''(条件成立时才出现) |
positioner | data-size | props.size |
positioner | data-state | 'open' | 'closed' |
positioner | data-tone | props.tone |
content | data-instant | ''(条件成立时才出现) |
content | data-placement | 定位引擎算出的实际落位 | undefined |
content | data-state | 'open' | 'closed' |
content | data-xh-material | 'frosted' |
item | data-xh-collection-context | 'overlay' |
item | data-xh-collection-item | '' |
item-icon | data-disabled | ''(条件成立时才出现) |
item-icon | data-highlighted | ''(条件成立时才出现) |
item-icon | data-xh-collection-slot | 'icon' |
item-text | data-disabled | ''(条件成立时才出现) |
item-text | data-highlighted | ''(条件成立时才出现) |
item-text | data-xh-collection-slot | 'text' |
item-description | data-disabled | ''(条件成立时才出现) |
item-description | data-highlighted | ''(条件成立时才出现) |
item-description | data-xh-collection-slot | 'description' |
item-shortcut | data-disabled | ''(条件成立时才出现) |
item-shortcut | data-highlighted | ''(条件成立时才出现) |
item-shortcut | data-xh-collection-slot | 'shortcut' |
item-suffix | data-disabled | ''(条件成立时才出现) |
item-suffix | data-highlighted | ''(条件成立时才出现) |
item-suffix | data-xh-collection-slot | 'suffix' |
item-indicator | data-disabled | ''(条件成立时才出现) |
item-indicator | data-highlighted | ''(条件成立时才出现) |
item-indicator | data-state | 'checked' | 'unchecked' | 'checked' | 'unchecked' | undefined |
item-indicator | data-xh-collection-slot | 'indicator' |
item-indicator | data-xh-menu-choice-indicator | item.kind | undefined |
separator | data-xh-collection-separator | '' |
arrow | data-placement | 定位引擎算出的实际落位 |
radio-group | data-value | group.value |
CSS 变量
本组件公开覆盖槽由独立皮肤的实际消费位生成;默认来源、作用部件和状态均与 CSS 同源。
| 变量 | 部件 | CSS 属性 | 状态 | 默认来源 | 说明 |
|---|---|---|---|---|---|
--xh-menubar-arrow-size | arrow | --xh-_overlay-arrow-size | default | --xh-overlay-arrow-size | menubar 的 arrow 部件 --xh-_overlay-arrow-size 覆盖槽。 |
--xh-menubar-backdrop | content | -webkit-backdrop-filterbackdrop-filter | xh-material=frosted | --xh-_material-backdrop | menubar 的 content 部件 -webkit-backdrop-filter、backdrop-filter 覆盖槽。 |
--xh-menubar-bg | root | background | default | transparent | menubar 的 root 部件 background 覆盖槽。 |
--xh-menubar-border | arrowcontent | border | defaultnot([data-xh-action-control])xh-material=frosted | --xh-_material-border--xh-material-frosted-border | menubar 的 arrow、content 部件 border 覆盖槽。 |
--xh-menubar-content-bg | arrowcontent | background | defaultnot([data-xh-action-control])xh-material=frosted | --xh-_material-bg--xh-material-frosted-bg | menubar 的 arrow、content 部件 background 覆盖槽。 |
--xh-menubar-content-fg | content | color | not([data-xh-action-control])xh-material=frosted | --xh-_material-fg | menubar 的 content 部件 color 覆盖槽。 |
--xh-menubar-content-gap | content | gap | default | --xh-list-option-gap | menubar 的 content 部件 gap 覆盖槽。 |
--xh-menubar-content-px | content | padding-inline | default | --xh-space-1 | menubar 的 content 部件 padding-inline 覆盖槽。 |
--xh-menubar-content-py | content | padding-block | default | --xh-surface-pad-xs | menubar 的 content 部件 padding-block 覆盖槽。 |
--xh-menubar-content-radius | content | border-radius | default | --xh-shape-overlay | menubar 的 content 部件 border-radius 覆盖槽。 |
--xh-menubar-content-shadow | content | box-shadow | not([data-xh-action-control])xh-material=frosted | --xh-_material-shadow | menubar 的 content 部件 box-shadow 覆盖槽。 |
--xh-menubar-fg | root | color | default | --xh-fg-default | menubar 的 root 部件 color 覆盖槽。 |
--xh-menubar-gap | root | gap | default | --xh-space-1 | menubar 的 root 部件 gap 覆盖槽。 |
--xh-menubar-group-gap | group | gap | default | --xh-list-option-gap | menubar 的 group 部件 gap 覆盖槽。 |
--xh-menubar-group-label-fg | group-label | color | default | --xh-material-frosted-fg-muted | menubar 的 group-label 部件 color 覆盖槽。 |
--xh-menubar-group-label-font-size | group-label | font-size | default | --xh-text-caption-size | menubar 的 group-label 部件 font-size 覆盖槽。 |
--xh-menubar-group-label-font-weight | group-label | font-weight | default | --xh-font-weight-regular | menubar 的 group-label 部件 font-weight 覆盖槽。 |
--xh-menubar-group-label-mt | group-label | margin-block-start | default | --xh-space-2 | menubar 的 group-label 部件 margin-block-start 覆盖槽。 |
--xh-menubar-group-label-px | group-label | padding-inline | default | --xh-_menubar-item-px | menubar 的 group-label 部件 padding-inline 覆盖槽。 |
--xh-menubar-group-label-py | group-label | padding-block | default | --xh-space-1 | menubar 的 group-label 部件 padding-block 覆盖槽。 |
--xh-menubar-highlight | content | background | not([data-xh-action-control])xh-material=frosted | --xh-_material-highlight | menubar 的 content 部件 background 覆盖槽。 |
--xh-menubar-icon-size | positionerroot | --xh-icon-size | is([data-part='root'], [data-part='positioner'])size=lgsize=sm | --xh-glyph-size-lg--xh-glyph-size-md--xh-glyph-size-sm | menubar 的 positioner、root 部件 --xh-icon-size 覆盖槽。 |
--xh-menubar-item-bg-active | item | background-color | in-pathxh-collection-context=nav | --xh-bg-subtle | menubar 的 item 部件 background-color 覆盖槽。 |
--xh-menubar-item-bg-hover | item | background-color | disablederrorhighlightedhoveris(:focus-visible, [data-highlighted])not([aria-disabled='true'], [data-disabled], [aria-busy='true'], [data-error])xh-collection-context=nav | --xh-bg-subtle | menubar 的 item 部件 background-color 覆盖槽。 |
--xh-menubar-item-bg-pressed | item | background-color | disablederroris(:active, [data-pressed])not([aria-disabled='true'], [data-disabled], [aria-busy='true'], [data-error])pressedxh-collection-context=nav | --xh-bg-subtle-hover | menubar 的 item 部件 background-color 覆盖槽。 |
--xh-menubar-item-description-fg | item-description | color | default | --xh-material-frosted-fg-muted | menubar 的 item-description 部件 color 覆盖槽。 |
--xh-menubar-item-description-font-size | item-description | font-size | default | --xh-control-caption-md | menubar 的 item-description 部件 font-size 覆盖槽。 |
--xh-menubar-item-fg | item | color | defaultdisablederrorhighlightedhoverin-pathis(:active, [data-pressed])is(:focus-visible, [data-highlighted])not([aria-disabled='true'], [data-disabled], [aria-busy='true'], [data-error])pressedxh-collection-context=nav | --xh-material-frosted-fg | menubar 的 item 部件 color 覆盖槽。 |
--xh-menubar-item-font-size | item | font-size | default | --xh-_menubar-font-size | menubar 的 item 部件 font-size 覆盖槽。 |
--xh-menubar-item-gap | item | gap | default | --xh-_menubar-item-gap | menubar 的 item 部件 gap 覆盖槽。 |
--xh-menubar-item-h | item | min-block-size | default | --xh-_menubar-item-h | menubar 的 item 部件 min-block-size 覆盖槽。 |
--xh-menubar-item-indicator-fg | item-indicator | color | default | --xh-_tone | menubar 的 item-indicator 部件 color 覆盖槽。 |
--xh-menubar-item-indicator-size | contentgroupitemitem-indicator | --xh-icon-sizeblock-sizeinline-size | defaulthas(> [data-scope='menubar'][data-part='item'] > [data-xh-menu-choice-indicator], > [data-scope='menubar'][data-part='group'] > [data-scope='menubar'][data-part='item'] > [data-xh-menu-choice-indicator])not([aria-haspopup='menu'], [aria-checked])xh-menu-choice-indicator | --xh-control-indicator-size | menubar 的 content、group、item、item-indicator 部件 --xh-icon-size、block-size、inline-size 覆盖槽。 |
--xh-menubar-item-leading | item | line-height | default | --xh-leading-normal | menubar 的 item 部件 line-height 覆盖槽。 |
--xh-menubar-item-px | item | padding-inline | default | --xh-_menubar-item-px | menubar 的 item 部件 padding-inline 覆盖槽。 |
--xh-menubar-item-py | item | padding-block | default | --xh-_menubar-item-py | menubar 的 item 部件 padding-block 覆盖槽。 |
--xh-menubar-item-radius | item | border-radius | default | --xh-shape-inset | menubar 的 item 部件 border-radius 覆盖槽。 |
--xh-menubar-layer | positioner | z-index | default | --xh-_layer | menubar 的 positioner 部件 z-index 覆盖槽。 |
--xh-menubar-max-h | content | max-block-size | default | --xh-_menubar-max-h | menubar 的 content 部件 max-block-size 覆盖槽。 |
--xh-menubar-max-w | content | max-inline-size | default | --xh-overlay-max-w | menubar 的 content 部件 max-inline-size 覆盖槽。 |
--xh-menubar-min-w | content | min-inline-size | default | --xh-overlay-menu-min-w | menubar 的 content 部件 min-inline-size 覆盖槽。 |
--xh-menubar-px | root | padding-inline | default | --xh-space-1 | menubar 的 root 部件 padding-inline 覆盖槽。 |
--xh-menubar-py | root | padding-block | default | --xh-space-1 | menubar 的 root 部件 padding-block 覆盖槽。 |
--xh-menubar-radius | root | border-radius | default | --xh-shape-control | menubar 的 root 部件 border-radius 覆盖槽。 |
--xh-menubar-separator-color | separator | background | default | --xh-material-frosted-separator | menubar 的 separator 部件 background 覆盖槽。 |
--xh-menubar-separator-my | separator | margin-block | default | --xh-space-0_5 | menubar 的 separator 部件 margin-block 覆盖槽。 |
--xh-menubar-separator-radius | separator | border-radius | default | --xh-shape-pill | menubar 的 separator 部件 border-radius 覆盖槽。 |
--xh-menubar-separator-thickness | separator | block-size | default | --xh-stroke-thin | menubar 的 separator 部件 block-size 覆盖槽。 |
--xh-menubar-submenu-indicator-fg | item | background-color | default | currentColor | menubar 的 item 部件 background-color 覆盖槽。 |
--xh-menubar-submenu-indicator-size | item | block-sizeinline-size | default | --xh-control-indicator-size | menubar 的 item 部件 block-size、inline-size 覆盖槽。 |
--xh-menubar-trigger-bg-active | trigger | background-color | in-pathxh-collection-context=nav | --xh-bg-subtle | menubar 的 trigger 部件 background-color 覆盖槽。 |
--xh-menubar-trigger-bg-hover | trigger | background-color | disablederrorhovernot([aria-disabled='true'], [data-disabled], [aria-busy='true'], [data-error])xh-collection-context=nav | --xh-bg-subtle | menubar 的 trigger 部件 background-color 覆盖槽。 |
--xh-menubar-trigger-bg-pressed | trigger | background-color | disablederroris(:active, [data-pressed])not([aria-disabled='true'], [data-disabled], [aria-busy='true'], [data-error])pressedxh-collection-context=nav | --xh-bg-subtle-hover | menubar 的 trigger 部件 background-color 覆盖槽。 |
--xh-menubar-trigger-fg | trigger | color | defaultxh-collection-context=nav | --xh-fg-default | menubar 的 trigger 部件 color 覆盖槽。 |
--xh-menubar-trigger-font-size | trigger | font-size | default | --xh-_menubar-font-size | menubar 的 trigger 部件 font-size 覆盖槽。 |
--xh-menubar-trigger-gap | trigger | gap | default | --xh-control-gap-sm | menubar 的 trigger 部件 gap 覆盖槽。 |
--xh-menubar-trigger-px | trigger | padding-inline | default | --xh-_menubar-trigger-px | menubar 的 trigger 部件 padding-inline 覆盖槽。 |
--xh-menubar-trigger-py | trigger | padding-block | default | --xh-_menubar-trigger-py | menubar 的 trigger 部件 padding-block 覆盖槽。 |
--xh-menubar-trigger-radius | trigger | border-radius | default | --xh-shape-control | menubar 的 trigger 部件 border-radius 覆盖槽。 |
动效
动效角色:按压 · 状态 · 出现(见动效规范)。
共享关键帧 xh-overlay-pop-in · xh-pop-out 由 family/motion.css 提供,皮肤 @import 它,单独引入仍成立。时长与缓动读动效令牌,改令牌即改全局节奏。
皮肤之外还有一段:退场由适配器的退场闸门把关,动画播完才真收起。
系统开启减弱动效时由令牌层统一收敛,皮肤不另作判断。
RTL
皮肤用逻辑属性排布(inline-start 一族),dir="rtl" 下自动镜像;另有按 dir 分支的规则。
