生态产品多个设计器现已发布正式版

查看生态总览
跳转到内容

ContextMenu 上下文菜单 ​

通过右键或长按在指针位置打开命令菜单。

用法 ​

在目标区域右键打开命令菜单

设计规范.pdf右键打开菜单

组件结构 ​

加粗的是必需部件。

data-scope="context-menu":root · trigger · positioner · content · item · item-icon · item-text · item-description · item-shortcut · item-suffix · item-indicator · separator · group · group-label · arrow

示例 ​

分组 ​

使用标题与分隔线组织命令

右键设置文件视图

图标与快捷键 ​

在命令两侧补充识别信息

右键编辑 notes.md

子菜单 ​

将相关命令收进下一层

右键管理项目

视图设置 ​

上下文菜单中的 checkbox 与 radio 切换后保持展开

右键调整视图

设计指引 ​

何时使用 ​

  • 为文件、表格行或画布对象提供快捷操作。

何时不用 ​

  • 主要操作应保留可见入口。
  • 以触摸操作为主的界面不应只依赖长按。
  • 选择值时使用选择器。

特性 ​

  • 菜单默认贴近指针位置。
  • 不写结构时照标准结构铺:触发区(内容归作者),定位层里的条目、分组与分隔线;条目的 item 插槽只接管条目文字,带 children 的条目是一个嵌套的子菜单,入口与普通条目一样铺图标(icon)与文字。Vue / React 不写默认插槽与 Web Components 不写部件(或只写 root)时生成的节点出自同一个结构函数;Web Components 里触发区的内容与条目文字可用宿主直接子节点 slot="trigger"、slot="item:<值>"、slot="item-prefix:<值>"、slot="item-suffix:<值>" 给出,子菜单生成嵌套的 <xh-menu submenu>。指向锚点的箭头要手写结构时自己摆。
  • 支持分组、分隔线、勾选与单选条目和子菜单。数据驱动时节点写 children(一组菜单条目)即为子菜单入口,默认树按 children 递归铺出下一层,深度不限;子层条目按数据铺,不经本层的插槽。子菜单那一层的勾选值与单选值写在带 children 的条目上(checkboxValue / radioValue),与子菜单自己的同名属性同义,写了即受控;按数据铺时子层的勾选改动不另外上报,勾选条目写 closeOnSelect,由根上的 item-select 得知。
  • 条目可逐条声明语气,删除一类命令自带该族字色与高亮底。
  • 说明与快捷键提示都可写进 collection;快捷键贴行尾,与说明同档同色。快捷键提示只是看的,读屏不念;要读屏念出快捷键,条目再写 keyshortcuts,落成条目的 aria-keyshortcuts。勾选与单选条目的勾是条目的最后一个部件,排在正文、说明与快捷键之后,与子菜单箭头同列,图标与普通条目左缘对齐;手写部件时写在哪都排到行尾。同一层有勾选条目时,普通条目的快捷键与它们同列。
  • typeahead 控制首字符检索,longPressDelay 设置长按时间。
  • 条目可组合图标、文字、说明和快捷键提示。同一层(跨分组与分隔线,子菜单另算)里只要有一条带图标,所有条目都空出图标那一格,正文左缘对齐;整层都没有图标就不留。
  • CheckboxItem 与 RadioGroup / RadioItem 可直接修改视图开关和互斥选项,默认切换后保持上下文菜单展开。
  • 选中任意层级的命令后发出根级 item-select 并关闭菜单链。
  • 触发区里的内容自带 Tab 位时(可聚焦的画布、列表),触发区不再另占一个:菜单键与 Shift+F10 在那个元素上照常展开,关闭后焦点回到打开前的持有者。判据只看 DOM:原生可聚焦或 tabindex ≥ 0 的元素,禁用的、hidden 或 inert 子树里的与菜单自己的浮层不算;内容里没有 Tab 位时触发区自己占一个。
  • disabled 让整张菜单失效:右键、长按、菜单键与 Shift+F10 都不再展开,浏览器自己的右键菜单照常出现;触发区退出 Tab 序列,展开途中转为禁用即收起。

组合 ​

  • 使用 XhContextMenuSub 创建子菜单。

最佳实践 ​

  • 上下文菜单只作为快捷入口,不替代页面上的主要操作。
  • 条目较多时按功能分组。
  • 仅为有意义的命令添加图标或快捷键提示。
  • 持久设置使用勾选或单选条目,对号由库画在行尾,不在普通条目里另画装饰性的勾。

反模式 ​

  • 不要在整页范围覆盖浏览器原生右键菜单。
  • 不要移除复制、打开链接等原生能力而不提供等价入口。

API 参考 ​

产物 ​

层值
自定义元素<xh-context-menu>
Vue 组件XhContextMenuArrow XhContextMenuCheckboxItem XhContextMenuContent XhContextMenuGroup XhContextMenuGroupLabel XhContextMenuItem XhContextMenuItemDescription XhContextMenuItemIcon XhContextMenuItemIndicator XhContextMenuItemShortcut XhContextMenuItemSuffix XhContextMenuItemText XhContextMenuPositioner XhContextMenuRadioGroup XhContextMenuRadioItem XhContextMenuRoot XhContextMenuSeparator XhContextMenuSub XhContextMenuSubTrigger XhContextMenuTrigger
组合式函数useContextMenu
状态机contextMenuMachine
皮肤@xihan-ui/styles/context-menu.css

Props ​

属性类型必填说明
collectionContextMenuNode[]条目数据,显示文本、禁用、图标与分组的事实源。提供后条目部件只需声明 value。 未提供时回到文本与禁用全部写在条目部件上的方式。
checkboxValuestring[]
defaultCheckboxValuestring[]
radioValueMenuRadioValue
defaultRadioValueMenuRadioValue
openboolean展开态。提供即受控:内部不再自行修改,只发 onOpenChange。
defaultOpenboolean
placementPlacement相对光标位置的首选放置位,默认 bottom-start。
offsetnumber浮层与光标的间距(px),默认 0:上下文菜单需要贴近光标。
loopboolean方向键到达末尾是否回绕,默认 true。
dirDirection文字方向,默认 ltr。
typeaheadboolean连打检索,默认开启。关闭后可打印字符一律放行给页面。
translationsPartial<ContextMenuTranslations>读屏文案,默认英文。
longPressDelaynumber触摸端长按多久视为触发(ms),默认 700。
disabledboolean整张菜单禁用:右键、长按、菜单键与 Shift+F10 都不再展开,也不拦截浏览器自己的右键菜单; 触发区退出 Tab 序列,条目全部为 aria-disabled,展开途中转为禁用即收起。与 Menu 的 disabled 同名同义。
toneTone整张菜单的语气:brand / neutral / success / warning / danger / info。 只为浮层与作者放进来的内容备好该族颜色,不下发给条目——条目保持中性档, 逐条的语气写在 collection 的 tone 上(见 ContextMenuNode)。
sizeSize尺寸:sm / md / lg,决定条目高度、内边距与字号档位。
onOpenChange(details: ContextMenuOpenChangeDetails) => voidopen 变化意图回调;受控时是唯一出口,非受控时随内部转移一并通知。
onItemSelect(details: ContextMenuItemSelectDetails) => void条目被选中;菜单随之关闭。
onCheckboxValueChange(details: MenuCheckboxValueChangeDetails) => void
onRadioValueChange(details: MenuRadioValueChangeDetails) => void

ContextMenuNode ​

collection 的元素。

字段类型必填说明
valuestring是
kindMenuChoiceKind
labelstring展示文本,也是连打检索的取字来源;默认回退为 value。
disabledboolean条目禁用:方向键跳过它,但它仍可聚焦、仍是导航起点。
toneTone该条命令自身动作的性质:删除写 danger、停用写 warning。不写即与其余条目同档。 只换字色与悬停 / 按下的面,不改字重与缩进,也不表达选中或校验;禁用压过它。 红字不是唯一通道,破坏性命令仍要配图标。整张菜单的 tone 不下发给条目。
iconIconRecord图标,写入 item-icon 部件,排在条目文字之前;未提供时本条不铺该部件。 纯装饰:读屏从条目文字取意,不念它。勾选与单选条目的勾仍在 item-indicator,两者各占一格。
descriptionstring副文本,写入 item-description 部件;未提供时本条不铺该部件。
shortcutstring快捷键提示,写入 item-shortcut 部件;未提供时本条不铺该部件。 纯装饰:读屏从条目文字取意,不念它;只为真正注册了的组合写提示。
keyshortcutsstring条目的 aria-keyshortcuts:读屏念的快捷键,写法照 ARIA(修饰键在前,如 Control+S、Meta+Shift+Z,几组用空格隔开), 未提供时不写。与 shortcut 各管各:shortcut 是看得见的提示、读屏不念,这一项只给读屏,两处说的应是同一组键。
groupstring归属分组的身份值;相邻同值的条目收进同一个 group 部件。未提供时本条直接落在 content 上。
groupLabelstring分组标题文字,取本组首个提供它的条目;本组无人提供时不铺 group-label。
separatorBeforeboolean本条之前绘制一条分隔线;写在首条上不产出分隔线。本条领头一个分组时,分隔线绘制在分组外。
closeOnSelectboolean选择型条目激活后是否关闭菜单;checkbox / radio 默认 false。
childrenMenuNode[]子菜单的条目:给了 children 这一条就是子菜单的入口,Vue / React 的默认树按 children 递归铺出下一层, 深度不限;本条只能是普通条目(kind 为 item)。子层的选中经菜单树汇到根上,勾选与单选由各层自持。 手写部件时改用 Sub 部件;Web Components 由作者写 Light DOM,不读这一项。
checkboxValuestring[]子菜单那一层的勾选值:只在带 children 的条目上读取,交给按数据铺出的那一层,与子菜单自己的 checkboxValue 同义, 写了即受控。按数据铺时子层的勾选改动不另外上报,勾选条目写 closeOnSelect,由根上的 item-select 得知。
radioValueMenuRadioValue子菜单那一层的单选值(组 → 选中的值):只在带 children 的条目上读取,其余同 checkboxValue。

事件 ​

自定义元素将载荷放在 detail;Vue 使用同名 emit。

事件载荷说明
open-changeContextMenuOpenChangeDetailsopen 状态变化;detail 为 { open: boolean }
item-selectContextMenuItemSelectDetails条目被选中(菜单随之关闭);detail 为 { value: string }
checkbox-value-changeContextMenuCheckboxValueChangeDetailscheckbox 选中集合变化
radio-value-changeContextMenuRadioValueChangeDetailsRadioGroup 选中映射变化

插槽 ​

仅列出带载荷的插槽。

Vue 组件插槽载荷说明
XhContextMenuRootdefaultContextMenuRootSlotProps
XhContextMenuRoottrigger—
XhContextMenuRootitemContextMenuNodeMeta只填条目的文字槽,标记位、副文本与快捷键照旧由数据铺
XhContextMenuRootitem-prefixContextMenuNodeMeta只接管行首那一格,其余槽照旧由数据铺
XhContextMenuRootitem-suffixContextMenuNodeMeta只接管行尾那一格(计数、徽标、次级图标),其余槽照旧由数据铺
XhContextMenuSubdefaultContextMenuSubSlotProps

React 适配器 props ​

只列各组件自己声明的那些:继承自 ComponentPropsWithRef 的 DOM 属性不在其中,根组件上与上面 Props 表同名的也不重复列。Vue 的对应物是上面的插槽表。

React 组件属性类型必填说明
XhContextMenuGroupvaluestring是
XhContextMenuItemvaluestring是
XhContextMenuItemdisabledboolean默认交给 connect 查询 collection,写死 false 会覆盖数据中的禁用。
XhContextMenuPositionercontainer() => Element | null浮层挂载的容器;未提供时按全局配置,再未提供时挂载到 body。
XhContextMenuRadioGroupvaluestring是
XhContextMenuRoottriggerReactNode触发区中放置的内容;不给 children 时由标准结构的触发区承载。
XhContextMenuRootrenderItem(node: ContextMenuNodeMeta) => ReactNode每个条目的自定义内容;未提供时使用 collection 中的 label。
XhContextMenuRootrenderItemPrefix(node: ContextMenuNodeMeta) => ReactNode只接管条目行首那一格;其余槽仍由数据铺。
XhContextMenuRootrenderItemSuffix(node: ContextMenuNodeMeta) => ReactNode只接管条目行尾那一格(计数、徽标、次级图标);其余槽仍由数据铺。
XhContextMenuRootchildrenSlotChildren<ContextMenuRootSlotProps>
XhContextMenuSubvaluestring是它在父上下文菜单中的条目身份。
XhContextMenuSublabelstring按数据铺设时触发条目的文字;缺省取父层 collection 里这一条的 label。
XhContextMenuSubiconIconRecord按数据铺设时触发条目的图标;缺省取父层 collection 里这一条的 icon。
XhContextMenuSubdisabledboolean
XhContextMenuSubcollectionMenuNode[]
XhContextMenuSubcheckboxValuestring[]
XhContextMenuSubdefaultCheckboxValuestring[]
XhContextMenuSubradioValueContextMenuRadioValue
XhContextMenuSubdefaultRadioValueContextMenuRadioValue
XhContextMenuSubplacementPlacement
XhContextMenuSuboffsetnumber
XhContextMenuSubloopboolean
XhContextMenuSubopenOnHoverboolean
XhContextMenuSubhoverOpenDelaynumber
XhContextMenuSubhoverCloseDelaynumber
XhContextMenuSubdirDirection文字方向;默认继承父层。子层被迁移到浮层落点,无法继承父层的方向。
XhContextMenuSubtoneTone语气;默认继承父层。子层是浮层落点下的同级节点,CSS 私有槽无法继承。
XhContextMenuSubsizeSize尺寸;默认继承父层,理由同 tone。
XhContextMenuSubonCheckboxValueChangeMenuSchema['props']['onCheckboxValueChange']
XhContextMenuSubonRadioValueChangeMenuSchema['props']['onRadioValueChange']
XhContextMenuSubchildrenSlotChildren<ContextMenuSubSlotProps>

状态 ​

公开状态写入 data-state。

部件取值
root'open' | 'closed'
trigger'open' | 'closed'
positioner'open' | 'closed'
content'open' | 'closed'
item-indicator'checked' | 'unchecked' | 'checked' | 'unchecked' | undefined

以下名称仅用于内部状态机。

状态:closed · pressing · open

事件:CONTEXT.MENU · OPEN · CLOSE · PRESS.START · PRESS.MOVE · PRESS.END · after.longPressDelay · ITEM.PRESS.START · ITEM.PRESS.END · CHECKBOX.VALUE.SET · RADIO.VALUE.SET · CONTROLLED.OPEN · CONTROLLED.CLOSE · ITEM.FOCUS · FOCUS.CLEAR · ITEM.LOST · ITEM.SELECT

判据:isOpenControlled · movedBeyondTolerance · canPressItem · keepsMenuOpen · isDisabled

connect API ​

getXxxProps() 返回对应部件的宿主属性。

成员类型说明
openboolean
disabledboolean整张菜单是否禁用。
collectionreadonly ContextMenuNodeMeta[]由 collection 推导的条目元信息,按数据顺序排列;未提供 collection 时为空数组。
pressingboolean长按计时进行中;触发区据此提供按压反馈。
pointContextMenuPoint | null当前锚点坐标;从未打开过时为 null。
focusedValuestring | null焦点锚点;收起时为 null。
checkboxValuereadonly string[]
radioValueReadonly<MenuRadioValue>
isCheckboxItemChecked(value: string) => boolean
isRadioItemChecked(group: string, value: string) => boolean
setCheckboxValue(next: string[]) => void
setRadioValue(next: MenuRadioValue) => void
setOpen(next: boolean) => void收起经 CLOSE;展开沿用最近一次锚点坐标,从未有过坐标时锚定在触发区的起始角。
openAt(x: number, y: number) => void命令式展开到指定视口坐标。
getRootProps() => T['element']
getTriggerProps() => T['element']
getPositionerProps() => T['element']
getContentProps() => T['element']
getItemProps(props: ContextMenuItemProps) => T['element']
getCheckboxItemProps(props: ContextMenuCheckboxItemProps) => T['element']
getRadioItemProps(props: ContextMenuRadioItemProps) => T['element']
getItemIconProps(props: ContextMenuAnyItemProps) => T['element']条目文字之前的图标格;装饰态,读屏不念。
getItemTextProps(props: ContextMenuAnyItemProps) => T['element']
getItemIndicatorProps(props: ContextMenuAnyItemProps) => T['element']
getItemDescriptionProps(props: ContextMenuAnyItemProps) => T['element']
getItemShortcutProps(props: ContextMenuAnyItemProps) => T['element']
getItemSuffixProps(props: ContextMenuAnyItemProps) => T['element']
getSeparatorProps() => T['element']
getGroupProps(props: ContextMenuGroupProps) => T['element']
getRadioGroupProps(props: ContextMenuGroupProps) => T['element']
getGroupLabelProps(props: ContextMenuGroupProps) => T['element']
getArrowProps() => T['element']

无障碍 ​

键盘 ​

规格出处:W3C APG

按键生效条件行为
ContextMenu / Shift+F10focus in trigger在触发区起始角展开菜单并把焦点落到首个可用条目
ArrowDownopen, focus in content焦点移到下一个条目(禁用项跳过、尽头按 loop 回绕)
ArrowUpopen, focus in content焦点移到上一个条目(禁用项跳过、尽头按 loop 回绕)
Homeopen, focus in content焦点移到首个可用条目
Endopen, focus in content焦点移到末个可用条目
单个可打印字符open, typeahead 未关连打检索把焦点移到首字母匹配的条目,不选中它
Enter / Spacefocus in item, not disabled派发选中详情并关闭菜单,焦点归还触发区(触发区里的内容自带 Tab 位时归还打开前的持有者)
Enter / Spaceheld in item, not disabled按住期间该条目投影 data-pressed,与指针 :active 同一副按压面;抬起、失焦或菜单收起撤下
Escapeopen关闭菜单并把焦点归还触发区(触发区里的内容自带 Tab 位时归还打开前的持有者)
Tab / Shift+Tabopen关闭菜单,焦点不归还触发区,按 Tab 序列自然离开

ARIA ​

以下属性由 connect 生成。

部件属性值
triggeraria-controlsundefined | content 部件的 id
triggeraria-haspopupundefined | 'menu'
triggeraria-keyshortcutsundefined | 'Shift+F10'
contentaria-hidden!open || undefined
contentaria-labeltranslations.content
contentrole'menu'
item-iconaria-hidden'true'
item-shortcutaria-hidden'true'
item-indicatoraria-hidden'true'
separatoraria-orientation'horizontal'
separatorrole'separator'
grouparia-labelledbygroup-label 部件的 id
grouprole'group'
arrowaria-hidden'true'
radio-grouparia-labelledbygroup-label 部件的 id
radio-grouprole'group'

样式参考 ​

皮肤 ​

@xihan-ui/styles/context-menu.css 按 [data-scope="context-menu"][data-part="root"] 部件选择器书写,发布产物以挂载类 .xh-scope-context-menu 代替其中的 data-scope(特异性相同),位于 xihan.components 与 xihan.motion 层。覆盖样式使用 xihan.overrides,部件选择器照常可用。

forced-colors: active 下另有一套规则:颜色交给系统,边框与状态标记改用系统色关键字。

数据属性 ​

由 connect 生成;条件不成立时不输出无值属性。

部件属性值
rootdata-sizeprops.size
rootdata-state'open' | 'closed'
rootdata-toneprops.tone
triggerdata-disabled''(条件成立时才出现)
triggerdata-pressing''(条件成立时才出现)
triggerdata-state'open' | 'closed'
positionerdata-hidden''(条件成立时才出现)
positionerdata-placement定位引擎算出的实际落位
positionerdata-positioned''(条件成立时才出现)
positionerdata-sizeprops.size
positionerdata-state'open' | 'closed'
positionerdata-toneprops.tone
contentdata-instant''(条件成立时才出现)
contentdata-placement定位引擎算出的实际落位
contentdata-state'open' | 'closed'
contentdata-xh-material'frosted'
itemdata-xh-collection-context'overlay'
itemdata-xh-collection-item''
item-icondata-disabled''(条件成立时才出现)
item-icondata-highlighted''(条件成立时才出现)
item-icondata-xh-collection-slot'icon'
item-textdata-disabled''(条件成立时才出现)
item-textdata-highlighted''(条件成立时才出现)
item-textdata-xh-collection-slot'text'
item-descriptiondata-disabled''(条件成立时才出现)
item-descriptiondata-highlighted''(条件成立时才出现)
item-descriptiondata-xh-collection-slot'description'
item-shortcutdata-disabled''(条件成立时才出现)
item-shortcutdata-highlighted''(条件成立时才出现)
item-shortcutdata-xh-collection-slot'shortcut'
item-suffixdata-disabled''(条件成立时才出现)
item-suffixdata-highlighted''(条件成立时才出现)
item-suffixdata-xh-collection-slot'suffix'
item-indicatordata-disabled''(条件成立时才出现)
item-indicatordata-highlighted''(条件成立时才出现)
item-indicatordata-state'checked' | 'unchecked' | 'checked' | 'unchecked' | undefined
item-indicatordata-xh-collection-slot'indicator'
item-indicatordata-xh-menu-choice-indicatoritem.kind | undefined
separatordata-xh-collection-separator''
arrowdata-placement定位引擎算出的实际落位
radio-groupdata-valuegroup.value

CSS 变量 ​

本组件公开覆盖槽由独立皮肤的实际消费位生成;默认来源、作用部件和状态均与 CSS 同源。

变量部件CSS 属性状态默认来源说明
--xh-context-menu-arrow-sizearrow--xh-_overlay-arrow-sizedefault--xh-overlay-arrow-sizecontext-menu 的 arrow 部件 --xh-_overlay-arrow-size 覆盖槽。
--xh-context-menu-backdropcontent-webkit-backdrop-filter
backdrop-filter
xh-material=frosted--xh-_material-backdropcontext-menu 的 content 部件 -webkit-backdrop-filter、backdrop-filter 覆盖槽。
--xh-context-menu-borderarrow
content
borderdefault
not([data-xh-action-control])
xh-material=frosted
--xh-_material-border
--xh-material-frosted-border
context-menu 的 arrow、content 部件 border 覆盖槽。
--xh-context-menu-content-bgarrow
content
backgrounddefault
not([data-xh-action-control])
xh-material=frosted
--xh-_material-bg
--xh-material-frosted-bg
context-menu 的 arrow、content 部件 background 覆盖槽。
--xh-context-menu-content-fgcontentcolornot([data-xh-action-control])
xh-material=frosted
--xh-_material-fgcontext-menu 的 content 部件 color 覆盖槽。
--xh-context-menu-content-gapcontentgapdefault--xh-list-option-gapcontext-menu 的 content 部件 gap 覆盖槽。
--xh-context-menu-content-pxcontentpadding-inlinedefault--xh-space-1context-menu 的 content 部件 padding-inline 覆盖槽。
--xh-context-menu-content-pycontentpadding-blockdefault--xh-surface-pad-xscontext-menu 的 content 部件 padding-block 覆盖槽。
--xh-context-menu-content-radiuscontentborder-radiusdefault--xh-shape-overlaycontext-menu 的 content 部件 border-radius 覆盖槽。
--xh-context-menu-content-shadowcontentbox-shadownot([data-xh-action-control])
xh-material=frosted
--xh-_material-shadowcontext-menu 的 content 部件 box-shadow 覆盖槽。
--xh-context-menu-group-gapgroupgapdefault--xh-list-option-gapcontext-menu 的 group 部件 gap 覆盖槽。
--xh-context-menu-group-label-fggroup-labelcolordefault--xh-material-frosted-fg-mutedcontext-menu 的 group-label 部件 color 覆盖槽。
--xh-context-menu-group-label-font-sizegroup-labelfont-sizedefault--xh-text-caption-sizecontext-menu 的 group-label 部件 font-size 覆盖槽。
--xh-context-menu-group-label-font-weightgroup-labelfont-weightdefault--xh-font-weight-regularcontext-menu 的 group-label 部件 font-weight 覆盖槽。
--xh-context-menu-group-label-mtgroup-labelmargin-block-startdefault--xh-space-2context-menu 的 group-label 部件 margin-block-start 覆盖槽。
--xh-context-menu-group-label-pxgroup-labelpadding-inlinedefault--xh-_context-menu-item-pxcontext-menu 的 group-label 部件 padding-inline 覆盖槽。
--xh-context-menu-group-label-pygroup-labelpadding-blockdefault--xh-space-1context-menu 的 group-label 部件 padding-block 覆盖槽。
--xh-context-menu-highlightcontentbackgroundnot([data-xh-action-control])
xh-material=frosted
--xh-_material-highlightcontext-menu 的 content 部件 background 覆盖槽。
--xh-context-menu-icon-sizepositioner
root
--xh-icon-sizeis([data-part='root'], [data-part='positioner'])
size=lg
size=sm
--xh-glyph-size-lg
--xh-glyph-size-md
--xh-glyph-size-sm
context-menu 的 positioner、root 部件 --xh-icon-size 覆盖槽。
--xh-context-menu-item-bg-activeitembackground-colorin-path--xh-bg-subtlecontext-menu 的 item 部件 background-color 覆盖槽。
--xh-context-menu-item-bg-hoveritembackground-colordisabled
error
highlighted
hover
is(:focus-visible, [data-highlighted])
not([aria-disabled='true'], [data-disabled], [aria-busy='true'], [data-error])
--xh-bg-subtlecontext-menu 的 item 部件 background-color 覆盖槽。
--xh-context-menu-item-bg-presseditembackground-colordisabled
error
is(:active, [data-pressed])
not([aria-disabled='true'], [data-disabled], [aria-busy='true'], [data-error])
pressed
--xh-bg-subtle-hovercontext-menu 的 item 部件 background-color 覆盖槽。
--xh-context-menu-item-description-fgitem-descriptioncolordefault--xh-material-frosted-fg-mutedcontext-menu 的 item-description 部件 color 覆盖槽。
--xh-context-menu-item-description-font-sizeitem-descriptionfont-sizedefault--xh-control-caption-mdcontext-menu 的 item-description 部件 font-size 覆盖槽。
--xh-context-menu-item-fgitemcolordefault
disabled
error
highlighted
hover
in-path
is(:active, [data-pressed])
is(:focus-visible, [data-highlighted])
not([aria-disabled='true'], [data-disabled], [aria-busy='true'], [data-error])
pressed
--xh-material-frosted-fgcontext-menu 的 item 部件 color 覆盖槽。
--xh-context-menu-item-font-sizeitemfont-sizedefault--xh-_context-menu-font-sizecontext-menu 的 item 部件 font-size 覆盖槽。
--xh-context-menu-item-gapitemgapdefault--xh-_context-menu-item-gapcontext-menu 的 item 部件 gap 覆盖槽。
--xh-context-menu-item-hitemmin-block-sizedefault--xh-_context-menu-item-hcontext-menu 的 item 部件 min-block-size 覆盖槽。
--xh-context-menu-item-indicator-fgitem-indicatorcolordefault--xh-_tonecontext-menu 的 item-indicator 部件 color 覆盖槽。
--xh-context-menu-item-indicator-sizecontent
group
item
item-indicator
--xh-icon-size
block-size
inline-size
default
has(> [data-scope='context-menu'][data-part='item'] > [data-xh-menu-choice-indicator], > [data-scope='context-menu'][data-part='group'] > [data-scope='context-menu'][data-part='item'] > [data-xh-menu-choice-indicator])
not([aria-haspopup='menu'], [aria-checked])
xh-menu-choice-indicator
--xh-control-indicator-sizecontext-menu 的 content、group、item、item-indicator 部件 --xh-icon-size、block-size、inline-size 覆盖槽。
--xh-context-menu-item-leadingitemline-heightdefault--xh-leading-normalcontext-menu 的 item 部件 line-height 覆盖槽。
--xh-context-menu-item-pxitempadding-inlinedefault--xh-_context-menu-item-pxcontext-menu 的 item 部件 padding-inline 覆盖槽。
--xh-context-menu-item-pyitempadding-blockdefault--xh-_context-menu-item-pycontext-menu 的 item 部件 padding-block 覆盖槽。
--xh-context-menu-item-radiusitemborder-radiusdefault--xh-shape-insetcontext-menu 的 item 部件 border-radius 覆盖槽。
--xh-context-menu-layerpositionerz-indexdefault--xh-_layercontext-menu 的 positioner 部件 z-index 覆盖槽。
--xh-context-menu-max-hcontentmax-block-sizedefault--xh-_context-menu-max-hcontext-menu 的 content 部件 max-block-size 覆盖槽。
--xh-context-menu-max-wcontentmax-inline-sizedefault--xh-overlay-max-wcontext-menu 的 content 部件 max-inline-size 覆盖槽。
--xh-context-menu-min-wcontentmin-inline-sizedefault--xh-overlay-menu-min-wcontext-menu 的 content 部件 min-inline-size 覆盖槽。
--xh-context-menu-separator-colorseparatorbackgrounddefault--xh-material-frosted-separatorcontext-menu 的 separator 部件 background 覆盖槽。
--xh-context-menu-separator-myseparatormargin-blockdefault--xh-space-0_5context-menu 的 separator 部件 margin-block 覆盖槽。
--xh-context-menu-separator-radiusseparatorborder-radiusdefault--xh-shape-pillcontext-menu 的 separator 部件 border-radius 覆盖槽。
--xh-context-menu-separator-thicknessseparatorblock-sizedefault--xh-stroke-thincontext-menu 的 separator 部件 block-size 覆盖槽。
--xh-context-menu-submenu-indicator-fgitembackground-colordefaultcurrentColorcontext-menu 的 item 部件 background-color 覆盖槽。
--xh-context-menu-submenu-indicator-sizeitemblock-size
inline-size
default--xh-control-indicator-sizecontext-menu 的 item 部件 block-size、inline-size 覆盖槽。
--xh-context-menu-trigger-bg-pressingtriggerbackgroundpressing--xh-bg-subtlecontext-menu 的 trigger 部件 background 覆盖槽。

动效 ​

动效角色:按压 · 状态 · 出现(见动效规范)。

共享关键帧 xh-overlay-pop-in · xh-pop-out 由 family/motion.css 提供,皮肤 @import 它,单独引入仍成立;background-color 走 transition 过渡。时长与缓动读动效令牌,改令牌即改全局节奏。

皮肤之外还有一段:退场由适配器的退场闸门把关,动画播完才真收起。

系统开启减弱动效时由令牌层统一收敛,皮肤不另作判断。

RTL ​

皮肤用逻辑属性排布(inline-start 一族),dir="rtl" 下自动镜像;另有按 dir 分支的规则。

Released under The MIT License