@xihan-ui/vue 2.0.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +258 -0
- package/dist/components/avatar-group/avatar-group.d.ts.map +1 -1
- package/dist/components/avatar-group/avatar-group.js +2 -1
- package/dist/components/avatar-group/avatar-group.js.map +1 -1
- package/dist/components/card/card.d.ts.map +1 -1
- package/dist/components/card/card.js +2 -1
- package/dist/components/card/card.js.map +1 -1
- package/dist/components/cascader/cascader.d.ts +9 -1
- package/dist/components/cascader/cascader.d.ts.map +1 -1
- package/dist/components/cascader/cascader.js +19 -1
- package/dist/components/cascader/cascader.js.map +1 -1
- package/dist/components/combobox/combobox.d.ts +18 -1
- package/dist/components/combobox/combobox.d.ts.map +1 -1
- package/dist/components/combobox/combobox.js +37 -4
- package/dist/components/combobox/combobox.js.map +1 -1
- package/dist/components/command/command.d.ts +23 -2
- package/dist/components/command/command.d.ts.map +1 -1
- package/dist/components/command/command.js +46 -4
- package/dist/components/command/command.js.map +1 -1
- package/dist/components/context-menu/context-menu.d.ts +14 -1
- package/dist/components/context-menu/context-menu.d.ts.map +1 -1
- package/dist/components/context-menu/context-menu.js +42 -12
- package/dist/components/context-menu/context-menu.js.map +1 -1
- package/dist/components/input-group/input-group.d.ts.map +1 -1
- package/dist/components/input-group/input-group.js +2 -1
- package/dist/components/input-group/input-group.js.map +1 -1
- package/dist/components/json-viewer/json-viewer.js.map +1 -1
- package/dist/components/kbd/kbd.d.ts.map +1 -1
- package/dist/components/kbd/kbd.js +27 -10
- package/dist/components/kbd/kbd.js.map +1 -1
- package/dist/components/listbox/listbox.d.ts +18 -1
- package/dist/components/listbox/listbox.d.ts.map +1 -1
- package/dist/components/listbox/listbox.js +37 -4
- package/dist/components/listbox/listbox.js.map +1 -1
- package/dist/components/mention/mention.d.ts +17 -1
- package/dist/components/mention/mention.d.ts.map +1 -1
- package/dist/components/mention/mention.js +36 -4
- package/dist/components/mention/mention.js.map +1 -1
- package/dist/components/menu/menu.d.ts +14 -1
- package/dist/components/menu/menu.d.ts.map +1 -1
- package/dist/components/menu/menu.js +63 -8
- package/dist/components/menu/menu.js.map +1 -1
- package/dist/components/menubar/menubar.d.ts +14 -2
- package/dist/components/menubar/menubar.d.ts.map +1 -1
- package/dist/components/menubar/menubar.js +43 -11
- package/dist/components/menubar/menubar.js.map +1 -1
- package/dist/components/page-header/page-header.d.ts.map +1 -1
- package/dist/components/page-header/page-header.js +2 -1
- package/dist/components/page-header/page-header.js.map +1 -1
- package/dist/components/pagination/pagination.js.map +1 -1
- package/dist/components/reasoning/reasoning.d.ts +1 -1
- package/dist/components/select/select.d.ts +18 -1
- package/dist/components/select/select.d.ts.map +1 -1
- package/dist/components/select/select.js +37 -4
- package/dist/components/select/select.js.map +1 -1
- package/dist/components/sortable/sortable.d.ts +1 -1
- package/dist/components/statistic/statistic.d.ts.map +1 -1
- package/dist/components/statistic/statistic.js +2 -1
- package/dist/components/statistic/statistic.js.map +1 -1
- package/dist/components/table/table.d.ts +2 -2
- package/dist/components/table/table.d.ts.map +1 -1
- package/dist/components/tag-group/tag-group.js +1 -1
- package/dist/components/tag-group/tag-group.js.map +1 -1
- package/dist/components/timeline/timeline.d.ts.map +1 -1
- package/dist/components/timeline/timeline.js +2 -1
- package/dist/components/timeline/timeline.js.map +1 -1
- package/dist/components/timer/timer.d.ts +1 -1
- package/dist/components/tour/tour.d.ts +1 -1
- package/dist/components/transfer/transfer.d.ts +9 -1
- package/dist/components/transfer/transfer.d.ts.map +1 -1
- package/dist/components/transfer/transfer.js +19 -1
- package/dist/components/transfer/transfer.js.map +1 -1
- package/dist/components/tree/tree.d.ts +9 -7
- package/dist/components/tree/tree.d.ts.map +1 -1
- package/dist/components/tree/tree.js +17 -15
- package/dist/components/tree/tree.js.map +1 -1
- package/dist/components/tree-select/tree-select.d.ts +9 -1
- package/dist/components/tree-select/tree-select.d.ts.map +1 -1
- package/dist/components/tree-select/tree-select.js +19 -1
- package/dist/components/tree-select/tree-select.js.map +1 -1
- package/dist/components/typography/typography.d.ts.map +1 -1
- package/dist/components/typography/typography.js +2 -1
- package/dist/components/typography/typography.js.map +1 -1
- package/dist/index.d.ts +13 -13
- package/dist/index.js +13 -13
- package/dist/package.js +1 -1
- package/dist/runtime/use-machine.js +3 -2
- package/dist/runtime/use-machine.js.map +1 -1
- package/dist/runtime/use-scrollbars.js +3 -1
- package/dist/runtime/use-scrollbars.js.map +1 -1
- package/package.json +14 -14
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mention.js","names":[],"sources":["../../../src/components/mention/mention.ts"],"sourcesContent":["/*\n * Copyright (c) 2021-Present XiHanFun and contributors.\n * Licensed under the MIT License. See LICENSE in the project root for license information.\n */\n\n// 提供 mention 相关实现。\n\nimport type { ControlVariant, Direction, Placement, Size, Tone } from '@xihan-ui/core'\nimport type { MentionApi, MentionInputEl, MentionItemProps, MentionNode, MentionNodeMeta, MentionSchema, MentionTranslations } from '@xihan-ui/headless'\nimport type { PropType, SlotsType, VNode } from 'vue'\nimport type { PayloadOf } from '../../runtime/payload'\nimport { computed, defineComponent, h, mergeProps, onMounted, onUnmounted, onUpdated, watch } from 'vue'\nimport { withXhConfig } from '../../config/config'\nimport { XhPortal } from '../../runtime/portal'\nimport { useScrollbars } from '../../runtime/use-scrollbars'\nimport { useFieldLabelWiring, useFieldStateWiring } from '../field/use-field-control'\nimport { useFormControlProps } from '../form/use-form-control'\nimport { provideMention, provideMentionItem, useMentionContext, useMentionItemContext } from './context'\nimport { useMention } from './use-mention'\n\ntype MentionProps = MentionSchema['props']\n\n/** 默认插槽的载荷:浮层开合、正文与查询串、高亮候选,以及改写正文与收起浮层的句柄。 */\nexport type MentionRootSlotProps = Pick<\n MentionApi,\n | 'open'\n | 'value'\n | 'query'\n | 'activePrefix'\n | 'highlightedValue'\n | 'setValue'\n | 'close'\n>\n\nexport const XhMentionRoot = defineComponent({\n name: 'XhMentionRoot',\n // 有 connect 兜底的 prop:普通类型省略 default,Boolean 显式保留 undefined\n props: {\n triggerPrefix: { type: [String, Array] as PropType<string | string[]> },\n collection: { type: Array as PropType<MentionNode[]> },\n value: { type: String },\n defaultValue: { type: String },\n disabled: { type: Boolean, default: undefined },\n loading: Boolean,\n name: { type: String },\n readOnly: { type: Boolean, default: undefined },\n invalid: { type: Boolean, default: undefined },\n placeholder: { type: String },\n loop: { type: Boolean, default: undefined },\n placement: { type: String as PropType<Placement> },\n offset: { type: Number },\n /** 文字方向;浮层迁移到落点后无法继承作者子树上的方向,需要 RTL 时显式提供。 */\n dir: { type: String as PropType<Direction> },\n translations: { type: Object as PropType<MentionTranslations> },\n variant: { type: String as PropType<ControlVariant> },\n tone: { type: String as PropType<Tone> },\n size: { type: String as PropType<Size> },\n },\n // *-change 携带 details 对象,update:* 携带裸值\n emits: {\n 'value-change': (_details: PayloadOf<MentionProps, 'onValueChange'>) => true,\n 'query-change': (_details: PayloadOf<MentionProps, 'onQueryChange'>) => true,\n 'select': (_details: PayloadOf<MentionProps, 'onSelect'>) => true,\n 'open-change': (_details: PayloadOf<MentionProps, 'onOpenChange'>) => true,\n 'update:value': (_value: PayloadOf<MentionProps, 'onValueChange'>['value']) => true,\n },\n slots: Object as SlotsType<{\n default?: (props: MentionRootSlotProps) => VNode[]\n /** 铺开 collection 时每条候选的文本插槽。 */\n item?: (props: MentionNodeMeta) => VNode[]\n /** 铺开 collection 时空态中的文案;未写时使用内建英文。 */\n empty?: () => VNode[]\n }>,\n setup(props, { slots, emit }) {\n const notifyValue: MentionProps['onValueChange'] = (details) => {\n emit('value-change', details)\n emit('update:value', details.value)\n }\n const notifyQuery: MentionProps['onQueryChange'] = details => emit('query-change', details)\n const notifySelect: MentionProps['onSelect'] = details => emit('select', details)\n const notifyOpen: MentionProps['onOpenChange'] = details => emit('open-change', details)\n\n const ctx = useMention(withXhConfig('mention', useFormControlProps(props)) as MentionProps, {\n onValueChange: notifyValue,\n onQueryChange: notifyQuery,\n onSelect: notifySelect,\n onOpenChange: notifyOpen,\n })\n provideMention(ctx)\n\n // 首帧结算一次候选条数,之后的增删由条目自己上报\n onMounted(ctx.syncItems)\n onUpdated(ctx.syncItems)\n\n return () => h(\n 'div',\n ctx.api.value.getRootProps() as Record<string, unknown>,\n slots.default\n ? slots.default({\n open: ctx.api.value.open,\n value: ctx.api.value.value,\n query: ctx.api.value.query,\n activePrefix: ctx.api.value.activePrefix,\n highlightedValue: ctx.api.value.highlightedValue,\n setValue: ctx.api.value.setValue,\n close: ctx.api.value.close,\n })\n : props.collection\n ? renderDefaultTree(ctx.api.value.collection, slots.item, slots.empty)\n : [],\n )\n },\n})\n\n/** 标题;必须是原生 label,getLabelProps 的 for 恒指向输入框。 */\nexport const XhMentionLabel = defineComponent({\n name: 'XhMentionLabel',\n setup(_, { slots }) {\n const ctx = useMentionContext()\n return () => h('label', ctx.api.value.getLabelProps() as Record<string, unknown>, slots.default?.())\n },\n})\n\n/** 单行输入框;正文写在它上面,候选浮层贴着它落位。 */\nexport const XhMentionInput = defineComponent({\n name: 'XhMentionInput',\n setup() {\n // 字段的说明与校验状态要落在真控件上,不能停在封装根的 div 上\n const fieldWiring = useFieldStateWiring()\n // 字段的标签也得并进名字链:控件自带的那条指的是它自己那个没渲染的 label 部件\n const fieldLabel = useFieldLabelWiring()\n const ctx = useMentionContext()\n return () => h('input', fieldLabel.value({\n ...fieldWiring.value,\n ...ctx.api.value.getInputProps() as Record<string, unknown>,\n ref: (el: unknown) => { ctx.inputRef.value = el as MentionInputEl },\n }))\n },\n})\n\nexport const XhMentionPositioner = defineComponent({\n name: 'XhMentionPositioner',\n props: {\n /** 本实例的 Portal 容器;优先于应用级配置。 */\n container: { type: Object as PropType<Element> },\n },\n // 根是 Teleport,Vue 不会把直通属性合上去,作者写的 class 与 style 得自己接住落到 positioner 上\n inheritAttrs: false,\n setup(props, { slots, attrs }) {\n const ctx = useMentionContext()\n // 候选列表的自绘条:与 content 同级、绝对定位不占布局,壳是这层已经 fixed 的 positioner,条子走浮层 4px 档\n const bars = useScrollbars({ scrollable: () => ctx.contentRef.value, props: { size: 'sm' } })\n // 定位层搬到 portal 落点,逃开祖先的层叠上下文\n return () => h(XhPortal, { to: props.container ?? ctx.portalTarget.value, source: ctx.inputRef }, () => [\n h('div', {\n ...mergeProps(ctx.api.value.getPositionerProps() as Record<string, unknown>, attrs),\n ref: (el: unknown) => { ctx.positionerRef.value = el as HTMLElement },\n }, [...(slots.default?.() ?? []), ...bars.render()]),\n ])\n },\n})\n\nexport const XhMentionContent = defineComponent({\n name: 'XhMentionContent',\n setup(_, { slots }) {\n const ctx = useMentionContext()\n return () => h('div', {\n ...ctx.api.value.getContentProps() as Record<string, unknown>,\n // 收起跟着退场闸门走:皮肤刻意没给 content 补 [hidden]{display:none}(补了退场\n // 就一帧都播不出来),所以真正的收起落成内联 display——节点始终留在原地\n style: ctx.visible.value ? undefined : { display: 'none' },\n ref: (el: unknown) => { ctx.contentRef.value = el as HTMLElement },\n }, slots.default?.())\n },\n})\n\n/** 没有任何候选时显示的空态;与候选面板同级。 */\nexport const XhMentionEmpty = defineComponent({\n name: 'XhMentionEmpty',\n setup(_, { slots }) {\n const ctx = useMentionContext()\n return () => h('div', ctx.api.value.getEmptyProps() as Record<string, unknown>, slots.default?.())\n },\n})\n\n/** 候选仍在获取时显示的在途占位;与候选面板同级。 */\nexport const XhMentionLoading = defineComponent({\n name: 'XhMentionLoading',\n setup(_, { slots }) {\n const ctx = useMentionContext()\n return () => h('div', ctx.api.value.getLoadingProps() as Record<string, unknown>, slots.default?.())\n },\n})\n\nexport const XhMentionItem = defineComponent({\n name: 'XhMentionItem',\n props: {\n value: { type: String, required: true },\n // 缺省交给 connect 回 collection 里查,写死 false 会盖掉数据里的禁用\n disabled: { type: Boolean, default: undefined },\n },\n setup(props, { slots }) {\n const ctx = useMentionContext()\n const item = computed<MentionItemProps>(() => ({ value: props.value, disabled: props.disabled }))\n provideMentionItem({ item })\n // 候选的进出与改名由条目自己上报,机器据此结算条数并摘掉悬空高亮\n onMounted(ctx.syncItems)\n onUnmounted(ctx.syncItems)\n // 节点就地复用时数量不变但身份换了,需按 value 另行上报\n watch(() => props.value, ctx.syncItems)\n return () => h('div', ctx.api.value.getItemProps(item.value) as Record<string, unknown>, slots.default?.())\n },\n})\n\nexport const XhMentionItemText = defineComponent({\n name: 'XhMentionItemText',\n setup(_, { slots }) {\n const ctx = useMentionContext()\n const { item } = useMentionItemContext()\n return () => h('span', ctx.api.value.getItemTextProps(item.value) as Record<string, unknown>, slots.default?.())\n },\n})\n\n/**\n * 未写默认插槽时按 collection 铺开的整套结构,作者只提供数据。\n * 与手写部件产出的 DOM 完全一致,需要修改结构时写默认插槽,行为不变。\n * 过滤仍归调用方:collection 就是当前应显示的候选。\n */\nfunction renderDefaultTree(\n collection: readonly MentionNodeMeta[],\n itemSlot?: (node: MentionNodeMeta) => VNode[],\n emptySlot?: () => VNode[],\n): VNode[] {\n const emptyText = emptySlot?.() ?? 'No results'\n return [\n h(XhMentionInput),\n h(XhMentionPositioner, null, () => [\n h(XhMentionContent, null, () => collection.map(node =>\n h(XhMentionItem, { key: node.value, value: node.value }, () => [\n h(XhMentionItemText, null, () => itemSlot?.(node) ?? node.label),\n ]),\n )),\n h(XhMentionEmpty, null, () => emptyText),\n ]),\n ]\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"mention.js","names":[],"sources":["../../../src/components/mention/mention.ts"],"sourcesContent":["/*\n * Copyright (c) 2021-Present XiHanFun and contributors.\n * Licensed under the MIT License. See LICENSE in the project root for license information.\n */\n\n// 提供 mention 相关实现。\n\nimport type { ControlVariant, Direction, Placement, Size, Tone } from '@xihan-ui/core'\nimport type { MentionApi, MentionInputEl, MentionItemProps, MentionNode, MentionNodeMeta, MentionSchema, MentionTranslations } from '@xihan-ui/headless'\nimport type { PropType, SlotsType, VNode } from 'vue'\nimport type { PayloadOf } from '../../runtime/payload'\nimport { computed, defineComponent, h, mergeProps, onMounted, onUnmounted, onUpdated, watch } from 'vue'\nimport { withXhConfig } from '../../config/config'\nimport { XhPortal } from '../../runtime/portal'\nimport { useScrollbars } from '../../runtime/use-scrollbars'\nimport { useFieldLabelWiring, useFieldStateWiring } from '../field/use-field-control'\nimport { useFormControlProps } from '../form/use-form-control'\nimport { provideMention, provideMentionItem, useMentionContext, useMentionItemContext } from './context'\nimport { useMention } from './use-mention'\n\ntype MentionProps = MentionSchema['props']\n\n/** 默认插槽的载荷:浮层开合、正文与查询串、高亮候选,以及改写正文与收起浮层的句柄。 */\nexport type MentionRootSlotProps = Pick<\n MentionApi,\n | 'open'\n | 'value'\n | 'query'\n | 'activePrefix'\n | 'highlightedValue'\n | 'setValue'\n | 'close'\n>\n\nexport const XhMentionRoot = defineComponent({\n name: 'XhMentionRoot',\n // 有 connect 兜底的 prop:普通类型省略 default,Boolean 显式保留 undefined\n props: {\n triggerPrefix: { type: [String, Array] as PropType<string | string[]> },\n collection: { type: Array as PropType<MentionNode[]> },\n value: { type: String },\n defaultValue: { type: String },\n disabled: { type: Boolean, default: undefined },\n loading: Boolean,\n name: { type: String },\n readOnly: { type: Boolean, default: undefined },\n invalid: { type: Boolean, default: undefined },\n placeholder: { type: String },\n loop: { type: Boolean, default: undefined },\n placement: { type: String as PropType<Placement> },\n offset: { type: Number },\n /** 文字方向;浮层迁移到落点后无法继承作者子树上的方向,需要 RTL 时显式提供。 */\n dir: { type: String as PropType<Direction> },\n translations: { type: Object as PropType<MentionTranslations> },\n variant: { type: String as PropType<ControlVariant> },\n tone: { type: String as PropType<Tone> },\n size: { type: String as PropType<Size> },\n },\n // *-change 携带 details 对象,update:* 携带裸值\n emits: {\n 'value-change': (_details: PayloadOf<MentionProps, 'onValueChange'>) => true,\n 'query-change': (_details: PayloadOf<MentionProps, 'onQueryChange'>) => true,\n 'select': (_details: PayloadOf<MentionProps, 'onSelect'>) => true,\n 'open-change': (_details: PayloadOf<MentionProps, 'onOpenChange'>) => true,\n 'update:value': (_value: PayloadOf<MentionProps, 'onValueChange'>['value']) => true,\n },\n slots: Object as SlotsType<{\n 'default'?: (props: MentionRootSlotProps) => VNode[]\n /** 铺开 collection 时每条候选的文本插槽。 */\n 'item'?: (props: MentionNodeMeta) => VNode[]\n /** 只接管行首那一格,其余槽照旧由数据铺 */\n 'item-prefix'?: (props: MentionNodeMeta) => VNode[]\n /** 只接管行尾那一格(计数、徽标、次级图标),其余槽照旧由数据铺 */\n 'item-suffix'?: (props: MentionNodeMeta) => VNode[]\n /** 铺开 collection 时空态中的文案;未写时使用内建英文。 */\n 'empty'?: () => VNode[]\n }>,\n setup(props, { slots, emit }) {\n const notifyValue: MentionProps['onValueChange'] = (details) => {\n emit('value-change', details)\n emit('update:value', details.value)\n }\n const notifyQuery: MentionProps['onQueryChange'] = details => emit('query-change', details)\n const notifySelect: MentionProps['onSelect'] = details => emit('select', details)\n const notifyOpen: MentionProps['onOpenChange'] = details => emit('open-change', details)\n\n const ctx = useMention(withXhConfig('mention', useFormControlProps(props)) as MentionProps, {\n onValueChange: notifyValue,\n onQueryChange: notifyQuery,\n onSelect: notifySelect,\n onOpenChange: notifyOpen,\n })\n provideMention(ctx)\n\n // 首帧结算一次候选条数,之后的增删由条目自己上报\n onMounted(ctx.syncItems)\n onUpdated(ctx.syncItems)\n\n return () => h(\n 'div',\n ctx.api.value.getRootProps() as Record<string, unknown>,\n slots.default\n ? slots.default({\n open: ctx.api.value.open,\n value: ctx.api.value.value,\n query: ctx.api.value.query,\n activePrefix: ctx.api.value.activePrefix,\n highlightedValue: ctx.api.value.highlightedValue,\n setValue: ctx.api.value.setValue,\n close: ctx.api.value.close,\n })\n : props.collection\n ? renderDefaultTree(ctx.api.value.collection, slots.item, slots['item-prefix'], slots['item-suffix'], slots.empty)\n : [],\n )\n },\n})\n\n/** 标题;必须是原生 label,getLabelProps 的 for 恒指向输入框。 */\nexport const XhMentionLabel = defineComponent({\n name: 'XhMentionLabel',\n setup(_, { slots }) {\n const ctx = useMentionContext()\n return () => h('label', ctx.api.value.getLabelProps() as Record<string, unknown>, slots.default?.())\n },\n})\n\n/** 单行输入框;正文写在它上面,候选浮层贴着它落位。 */\nexport const XhMentionInput = defineComponent({\n name: 'XhMentionInput',\n setup() {\n // 字段的说明与校验状态要落在真控件上,不能停在封装根的 div 上\n const fieldWiring = useFieldStateWiring()\n // 字段的标签也得并进名字链:控件自带的那条指的是它自己那个没渲染的 label 部件\n const fieldLabel = useFieldLabelWiring()\n const ctx = useMentionContext()\n return () => h('input', fieldLabel.value({\n ...fieldWiring.value,\n ...ctx.api.value.getInputProps() as Record<string, unknown>,\n ref: (el: unknown) => { ctx.inputRef.value = el as MentionInputEl },\n }))\n },\n})\n\nexport const XhMentionPositioner = defineComponent({\n name: 'XhMentionPositioner',\n props: {\n /** 本实例的 Portal 容器;优先于应用级配置。 */\n container: { type: Object as PropType<Element> },\n },\n // 根是 Teleport,Vue 不会把直通属性合上去,作者写的 class 与 style 得自己接住落到 positioner 上\n inheritAttrs: false,\n setup(props, { slots, attrs }) {\n const ctx = useMentionContext()\n // 候选列表的自绘条:与 content 同级、绝对定位不占布局,壳是这层已经 fixed 的 positioner,条子走浮层 4px 档\n const bars = useScrollbars({ scrollable: () => ctx.contentRef.value, props: { size: 'sm' } })\n // 定位层搬到 portal 落点,逃开祖先的层叠上下文\n return () => h(XhPortal, { to: props.container ?? ctx.portalTarget.value, source: ctx.inputRef }, () => [\n h('div', {\n ...mergeProps(ctx.api.value.getPositionerProps() as Record<string, unknown>, attrs),\n ref: (el: unknown) => { ctx.positionerRef.value = el as HTMLElement },\n }, [...(slots.default?.() ?? []), ...bars.render()]),\n ])\n },\n})\n\nexport const XhMentionContent = defineComponent({\n name: 'XhMentionContent',\n setup(_, { slots }) {\n const ctx = useMentionContext()\n return () => h('div', {\n ...ctx.api.value.getContentProps() as Record<string, unknown>,\n // 收起跟着退场闸门走:皮肤刻意没给 content 补 [hidden]{display:none}(补了退场\n // 就一帧都播不出来),所以真正的收起落成内联 display——节点始终留在原地\n style: ctx.visible.value ? undefined : { display: 'none' },\n ref: (el: unknown) => { ctx.contentRef.value = el as HTMLElement },\n }, slots.default?.())\n },\n})\n\n/** 没有任何候选时显示的空态;与候选面板同级。 */\nexport const XhMentionEmpty = defineComponent({\n name: 'XhMentionEmpty',\n setup(_, { slots }) {\n const ctx = useMentionContext()\n return () => h('div', ctx.api.value.getEmptyProps() as Record<string, unknown>, slots.default?.())\n },\n})\n\n/** 候选仍在获取时显示的在途占位;与候选面板同级。 */\nexport const XhMentionLoading = defineComponent({\n name: 'XhMentionLoading',\n setup(_, { slots }) {\n const ctx = useMentionContext()\n return () => h('div', ctx.api.value.getLoadingProps() as Record<string, unknown>, slots.default?.())\n },\n})\n\nexport const XhMentionItem = defineComponent({\n name: 'XhMentionItem',\n props: {\n value: { type: String, required: true },\n // 缺省交给 connect 回 collection 里查,写死 false 会盖掉数据里的禁用\n disabled: { type: Boolean, default: undefined },\n },\n setup(props, { slots }) {\n const ctx = useMentionContext()\n const item = computed<MentionItemProps>(() => ({ value: props.value, disabled: props.disabled }))\n provideMentionItem({ item })\n // 候选的进出与改名由条目自己上报,机器据此结算条数并摘掉悬空高亮\n onMounted(ctx.syncItems)\n onUnmounted(ctx.syncItems)\n // 节点就地复用时数量不变但身份换了,需按 value 另行上报\n watch(() => props.value, ctx.syncItems)\n return () => h('div', ctx.api.value.getItemProps(item.value) as Record<string, unknown>, slots.default?.())\n },\n})\n\nexport const XhMentionItemText = defineComponent({\n name: 'XhMentionItemText',\n setup(_, { slots }) {\n const ctx = useMentionContext()\n const { item } = useMentionItemContext()\n return () => h('span', ctx.api.value.getItemTextProps(item.value) as Record<string, unknown>, slots.default?.())\n },\n})\n\n/** 条目行首的作者内容(图标、色块、头像),对读屏隐藏 */\nexport const XhMentionItemPrefix = defineComponent({\n name: 'XhMentionItemPrefix',\n setup(_, { slots }) {\n const ctx = useMentionContext()\n const { item } = useMentionItemContext()\n return () => h('span', ctx.api.value.getItemPrefixProps(item.value) as Record<string, unknown>, slots.default?.())\n },\n})\n\n/** 条目行尾的作者内容(计数、徽标) */\nexport const XhMentionItemSuffix = defineComponent({\n name: 'XhMentionItemSuffix',\n setup(_, { slots }) {\n const ctx = useMentionContext()\n const { item } = useMentionItemContext()\n return () => h('span', ctx.api.value.getItemSuffixProps(item.value) as Record<string, unknown>, slots.default?.())\n },\n})\n\n/** 条目的第 2 行副文本,跨文字槽、走 muted 档 */\nexport const XhMentionItemDescription = defineComponent({\n name: 'XhMentionItemDescription',\n setup(_, { slots }) {\n const ctx = useMentionContext()\n const { item } = useMentionItemContext()\n return () => h('span', ctx.api.value.getItemDescriptionProps(item.value) as Record<string, unknown>, slots.default?.())\n },\n})\n\n/**\n * 未写默认插槽时按 collection 铺开的整套结构,作者只提供数据。\n * 与手写部件产出的 DOM 完全一致,需要修改结构时写默认插槽,行为不变。\n * 过滤仍归调用方:collection 就是当前应显示的候选。\n */\nfunction renderDefaultTree(\n collection: readonly MentionNodeMeta[],\n itemSlot?: (node: MentionNodeMeta) => VNode[],\n prefixSlot?: (node: MentionNodeMeta) => VNode[],\n suffixSlot?: (node: MentionNodeMeta) => VNode[],\n emptySlot?: () => VNode[],\n): VNode[] {\n const emptyText = emptySlot?.() ?? 'No results'\n return [\n h(XhMentionInput),\n h(XhMentionPositioner, null, () => [\n h(XhMentionContent, null, () => collection.map(node =>\n h(XhMentionItem, { key: node.value, value: node.value }, () => [\n ...(prefixSlot ? [h(XhMentionItemPrefix, null, () => prefixSlot(node))] : []),\n h(XhMentionItemText, null, () => itemSlot?.(node) ?? node.label),\n ...(node.description != null ? [h(XhMentionItemDescription, null, () => node.description)] : []),\n ...(suffixSlot ? [h(XhMentionItemSuffix, null, () => suffixSlot(node))] : []),\n ]),\n )),\n h(XhMentionEmpty, null, () => emptyText),\n ]),\n ]\n}\n"],"mappings":"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"}
|
|
@@ -135,7 +135,12 @@ declare const XhMenuRoot: import("vue").DefineComponent<import("vue").ExtractPro
|
|
|
135
135
|
}, SlotsType<{
|
|
136
136
|
default?: (props: MenuRootSlotProps) => VNode[];
|
|
137
137
|
trigger?: () => VNode[];
|
|
138
|
+
/** 整条的接管口:写了它,代铺的各格一概不铺,作者自己放置部件 */
|
|
138
139
|
item?: (node: MenuNodeMeta) => VNode[];
|
|
140
|
+
/** 只接管行首那一格,其余槽照旧由数据铺 */
|
|
141
|
+
'item-prefix'?: (node: MenuNodeMeta) => VNode[];
|
|
142
|
+
/** 只接管行尾那一格(计数、徽标、次级图标),其余槽照旧由数据铺 */
|
|
143
|
+
'item-suffix'?: (node: MenuNodeMeta) => VNode[];
|
|
139
144
|
}>, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
140
145
|
declare const XhMenuTrigger: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
141
146
|
/** 借用作者的子节点作为触发器,不再渲染自己的包裹元素;子节点须恰好一个。 */
|
|
@@ -307,6 +312,14 @@ declare const XhMenuItemIndicator: import("vue").DefineComponent<{}, () => VNode
|
|
|
307
312
|
declare const XhMenuItemDescription: import("vue").DefineComponent<{}, () => VNode<import("vue").RendererNode, import("vue").RendererElement, {
|
|
308
313
|
[key: string]: any;
|
|
309
314
|
}>, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
315
|
+
/** 条目中的快捷键提示,贴行尾;纯装饰,读屏从条目文字取意 */
|
|
316
|
+
declare const XhMenuItemShortcut: import("vue").DefineComponent<{}, () => VNode<import("vue").RendererNode, import("vue").RendererElement, {
|
|
317
|
+
[key: string]: any;
|
|
318
|
+
}>, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
319
|
+
/** 条目行尾的作者内容(计数、徽标、次级图标);家族只管落位,不规定字号与颜色 */
|
|
320
|
+
declare const XhMenuItemSuffix: import("vue").DefineComponent<{}, () => VNode<import("vue").RendererNode, import("vue").RendererElement, {
|
|
321
|
+
[key: string]: any;
|
|
322
|
+
}>, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
310
323
|
declare const XhMenuGroup: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
311
324
|
value: {
|
|
312
325
|
type: StringConstructor;
|
|
@@ -330,5 +343,5 @@ declare const XhMenuArrow: import("vue").DefineComponent<{}, () => VNode<import(
|
|
|
330
343
|
[key: string]: any;
|
|
331
344
|
}>, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
332
345
|
//#endregion
|
|
333
|
-
export { MenuRootSlotProps, MenuSubSlotProps, XhMenuArrow, XhMenuContent, XhMenuGroup, XhMenuGroupLabel, XhMenuItem, XhMenuItemDescription, XhMenuItemIndicator, XhMenuItemText, XhMenuPositioner, XhMenuRoot, XhMenuSeparator, XhMenuSub, XhMenuSubTrigger, XhMenuTrigger };
|
|
346
|
+
export { MenuRootSlotProps, MenuSubSlotProps, XhMenuArrow, XhMenuContent, XhMenuGroup, XhMenuGroupLabel, XhMenuItem, XhMenuItemDescription, XhMenuItemIndicator, XhMenuItemShortcut, XhMenuItemSuffix, XhMenuItemText, XhMenuPositioner, XhMenuRoot, XhMenuSeparator, XhMenuSub, XhMenuSubTrigger, XhMenuTrigger };
|
|
334
347
|
//# sourceMappingURL=menu.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"menu.d.ts","names":[],"sources":["../../../src/components/menu/menu.ts"],"mappings":";;;;;KAqBK,YAAY;;KAGL,oBAAoB,KAAK;
|
|
1
|
+
{"version":3,"file":"menu.d.ts","names":[],"sources":["../../../src/components/menu/menu.ts"],"mappings":";;;;;KAqBK,YAAY;;KAGL,oBAAoB,KAAK;cAYxB,0BAAU,8BAAA;;IAIU,MAAA,SAAS;;;;;;;;IAGT,MAAA,SAAS;;;;;;;;;;IAGf,MAAA,SAAS;;;IACR,MAAA,SAAS;;;IACT,MAAA,SAAS;;;;;;;;;;;IAGD,MAAA,SAAS,QAAQ;;;;;;;;;;;;;;;;;;;;EAYvB,gBAAA,UAAA,UAAU;EACf,SAAA,UAAA,UAAU;EACR,gBAAA,OAAA,UAAU;;;IAzBJ,MAAA,SAAS;;;;;;;;IAGT,MAAA,SAAS;;;;;;;;;;IAGf,MAAA,SAAS;;;IACR,MAAA,SAAS;;;IACT,MAAA,SAAS;;;;;;;;;;;IAGD,MAAA,SAAS,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiBrC,WAAC,OAAO,sBAAsB;EAC9B,gBAAM;;EAET,QAAC,MAAM,iBAAiB;;EAEjB,iBAAC,MAAM,iBAAiB;;EAExB,iBAAC,MAAM,iBAAiB;kCAgB1C;cAEW,6BAAa,8BAAA;;;;;;;;;;qCAyBxB;cAEW,gCAAgB,8BAAA;;;IAII,MAAA,SAAS;;;;;;;IAAT,MAAA,SAAS;;MAgBxC,oDAAA;cAEW,6BAAa,0BAAA,oBAAA,4BAAA;;8BAYxB,qCAAA,iDAAA,aAAA,eAAA,oDAAA;cAEW,0BAAU,8BAAA;;;;;;;;;;;;;;;;;;;;;;qCAqCrB;;KAGU,mBAAmB,KAAK;;;;;cAMvB,yBAAS,8BAAA;;;;;;;;;;;IAMW,MAAA,SAAS;;;IACT,MAAA,SAAS;;;;;;;;;;;;;;;;;;IAMf,MAAA,SAAS;;;;IAER,MAAA,SAAS;;;;IAET,MAAA,SAAS;;;;;;;;;;;;;;;;;;IAXJ,MAAA,SAAS;;;IACT,MAAA,SAAS;;;;;;;;;;;;;;;;;;IAMf,MAAA,SAAS;;;;IAER,MAAA,SAAS;;;;IAET,MAAA,SAAS;;;;;;;;;;EAIvB,WAAC,OAAO,qBAAqB;kCAyBzC;cAEW,gCAAgB,0BAAA,oBAAA,4BAAA;;8BAgB3B,qCAAA,iDAAA,aAAA,eAAA,oDAAA;;cAGW,8BAAc,0BAAA,oBAAA,4BAAA;;8BAOzB,qCAAA,iDAAA,aAAA,eAAA,oDAAA;;cAGW,mCAAmB,0BAAA,oBAAA,4BAAA;;8BAO9B,qCAAA,iDAAA,aAAA,eAAA,oDAAA;;cAGW,qCAAqB,0BAAA,oBAAA,4BAAA;;8BAOhC,qCAAA,iDAAA,aAAA,eAAA,oDAAA;;cAGW,kCAAkB,0BAAA,oBAAA,4BAAA;;8BAO7B,qCAAA,iDAAA,aAAA,eAAA,oDAAA;;cAGW,gCAAgB,0BAAA,oBAAA,4BAAA;;8BAO3B,qCAAA,iDAAA,aAAA,eAAA,oDAAA;cAEW,2BAAW,8BAAA;;;;;;;;;;;;MAWtB,oDAAA;cAEW,gCAAgB,0BAAA,oBAAA,4BAAA;;8BAO3B,qCAAA,iDAAA,aAAA,eAAA,oDAAA;cAEW,+BAAe,0BAAA,oBAAA,4BAAA;;8BAM1B,qCAAA,iDAAA,aAAA,eAAA,oDAAA;cAEW,2BAAW,0BAAA,oBAAA,4BAAA;;8BAMtB,qCAAA,iDAAA,aAAA,eAAA,oDAAA"}
|
|
@@ -6,7 +6,7 @@ import { mergeIntoChild } from "../../runtime/as-child.js";
|
|
|
6
6
|
import { provideMenu, provideMenuGroup, provideMenuItem, provideMenuSub, useMenuContext, useMenuGroupContext, useMenuItemContext, useMenuSubContext } from "./context.js";
|
|
7
7
|
import { useMenu, useMenuWithParent } from "./use-menu.js";
|
|
8
8
|
import { computed, defineComponent, h, mergeProps, onBeforeUnmount, ref, watch } from "vue";
|
|
9
|
-
import { mergeProps as mergeProps$1 } from "@xihan-ui/core";
|
|
9
|
+
import { groupAdjacentRuns, mergeProps as mergeProps$1 } from "@xihan-ui/core";
|
|
10
10
|
//#region src/components/menu/menu.ts
|
|
11
11
|
const XhMenuRoot = /* @__PURE__ */ defineComponent({
|
|
12
12
|
name: "XhMenuRoot",
|
|
@@ -64,7 +64,11 @@ const XhMenuRoot = /* @__PURE__ */ defineComponent({
|
|
|
64
64
|
return () => slots.default ? slots.default({
|
|
65
65
|
open: ctx.api.value.open,
|
|
66
66
|
setOpen: ctx.api.value.setOpen
|
|
67
|
-
}) : props.collection ? renderDefaultTree(ctx.api.value.collection, slots.trigger?.() ?? null,
|
|
67
|
+
}) : props.collection ? renderDefaultTree(ctx.api.value.collection, slots.trigger?.() ?? null, {
|
|
68
|
+
"item": slots.item,
|
|
69
|
+
"item-prefix": slots["item-prefix"],
|
|
70
|
+
"item-suffix": slots["item-suffix"]
|
|
71
|
+
}, props.triggerAsChild) : [];
|
|
68
72
|
}
|
|
69
73
|
});
|
|
70
74
|
const XhMenuTrigger = /* @__PURE__ */ defineComponent({
|
|
@@ -276,6 +280,24 @@ const XhMenuItemDescription = /* @__PURE__ */ defineComponent({
|
|
|
276
280
|
return () => h("span", ctx.api.value.getItemDescriptionProps(item.value), slots.default?.());
|
|
277
281
|
}
|
|
278
282
|
});
|
|
283
|
+
/** 条目中的快捷键提示,贴行尾;纯装饰,读屏从条目文字取意 */
|
|
284
|
+
const XhMenuItemShortcut = /* @__PURE__ */ defineComponent({
|
|
285
|
+
name: "XhMenuItemShortcut",
|
|
286
|
+
setup(_, { slots }) {
|
|
287
|
+
const ctx = useMenuContext();
|
|
288
|
+
const { item } = useMenuItemContext();
|
|
289
|
+
return () => h("span", ctx.api.value.getItemShortcutProps(item.value), slots.default?.());
|
|
290
|
+
}
|
|
291
|
+
});
|
|
292
|
+
/** 条目行尾的作者内容(计数、徽标、次级图标);家族只管落位,不规定字号与颜色 */
|
|
293
|
+
const XhMenuItemSuffix = /* @__PURE__ */ defineComponent({
|
|
294
|
+
name: "XhMenuItemSuffix",
|
|
295
|
+
setup(_, { slots }) {
|
|
296
|
+
const ctx = useMenuContext();
|
|
297
|
+
const { item } = useMenuItemContext();
|
|
298
|
+
return () => h("span", ctx.api.value.getItemSuffixProps(item.value), slots.default?.());
|
|
299
|
+
}
|
|
300
|
+
});
|
|
279
301
|
const XhMenuGroup = /* @__PURE__ */ defineComponent({
|
|
280
302
|
name: "XhMenuGroup",
|
|
281
303
|
props: { value: {
|
|
@@ -316,13 +338,46 @@ const XhMenuArrow = /* @__PURE__ */ defineComponent({
|
|
|
316
338
|
* 与手写部件产出的 DOM 完全一致,需要修改结构时写默认插槽,行为不变。
|
|
317
339
|
* 触发器内容归作者,由 trigger 插槽承载;条目内容默认是 label,可由 item 插槽接管。
|
|
318
340
|
*/
|
|
319
|
-
function renderDefaultTree(collection, trigger,
|
|
320
|
-
return [h(XhMenuTrigger, { asChild: triggerAsChild }, () => trigger ?? []), h(XhMenuPositioner, null, () => [h(XhMenuContent, null, () => collection
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
341
|
+
function renderDefaultTree(collection, trigger, itemSlots, triggerAsChild) {
|
|
342
|
+
return [h(XhMenuTrigger, { asChild: triggerAsChild }, () => trigger ?? []), h(XhMenuPositioner, null, () => [h(XhMenuContent, null, () => renderNodes(collection, itemSlots))])];
|
|
343
|
+
}
|
|
344
|
+
/** content 的内容:分组段铺为 group,段首的分隔线落在 group 外面。 */
|
|
345
|
+
function renderNodes(collection, itemSlots) {
|
|
346
|
+
return groupAdjacentRuns(collection, (node) => node.group).flatMap((run, runIndex) => {
|
|
347
|
+
const head = run[0];
|
|
348
|
+
const lead = runIndex > 0 && head.separatorBefore ? [h(XhMenuSeparator, { key: `separator:${head.value}` })] : [];
|
|
349
|
+
if (head.group == null) return [...lead, renderItem(head, itemSlots)];
|
|
350
|
+
const groupLabel = run.find((node) => node.groupLabel != null)?.groupLabel ?? null;
|
|
351
|
+
return [...lead, h(XhMenuGroup, {
|
|
352
|
+
key: `group:${head.group}`,
|
|
353
|
+
value: head.group
|
|
354
|
+
}, () => [...groupLabel != null ? [h(XhMenuGroupLabel, null, () => groupLabel)] : [], ...run.flatMap((node, index) => [...index > 0 && node.separatorBefore ? [h(XhMenuSeparator, { key: `separator:${node.value}` })] : [], renderItem(node, itemSlots)])])];
|
|
355
|
+
});
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* 单个条目:按数据铺标记位、文字、说明与快捷键,未提供的那几个不铺对应部件。
|
|
359
|
+
*
|
|
360
|
+
* 三个插槽各管一段,不必为了改一处把整条重搭:
|
|
361
|
+
* - `item-prefix` / `item-suffix` 只接管行首与行尾那一格,其余槽照旧由数据铺。
|
|
362
|
+
* 行首那一格与数据里的 `indicator` 同一个部件,插槽在场时以它为准。
|
|
363
|
+
* - `item` 是整条的接管口:写了它,上面几格一概不铺,作者自己放置 XhMenuItemText 等部件
|
|
364
|
+
* (与 ContextMenu 的 item 插槽语义不同,那边填的是文字槽)。
|
|
365
|
+
*/
|
|
366
|
+
function renderItem(meta, itemSlots) {
|
|
367
|
+
const prefix = itemSlots["item-prefix"];
|
|
368
|
+
const suffix = itemSlots["item-suffix"];
|
|
369
|
+
return h(XhMenuItem, {
|
|
370
|
+
key: meta.value,
|
|
371
|
+
value: meta.value
|
|
372
|
+
}, () => itemSlots.item?.(meta) ?? [
|
|
373
|
+
...prefix ? [h(XhMenuItemIndicator, null, () => prefix(meta))] : meta.indicator != null ? [h(XhMenuItemIndicator, null, () => meta.indicator)] : [],
|
|
374
|
+
h(XhMenuItemText, null, () => meta.label),
|
|
375
|
+
...meta.description != null ? [h(XhMenuItemDescription, null, () => meta.description)] : [],
|
|
376
|
+
...meta.shortcut != null ? [h(XhMenuItemShortcut, null, () => meta.shortcut)] : [],
|
|
377
|
+
...suffix ? [h(XhMenuItemSuffix, null, () => suffix(meta))] : []
|
|
378
|
+
]);
|
|
324
379
|
}
|
|
325
380
|
//#endregion
|
|
326
|
-
export { XhMenuArrow, XhMenuContent, XhMenuGroup, XhMenuGroupLabel, XhMenuItem, XhMenuItemDescription, XhMenuItemIndicator, XhMenuItemText, XhMenuPositioner, XhMenuRoot, XhMenuSeparator, XhMenuSub, XhMenuSubTrigger, XhMenuTrigger };
|
|
381
|
+
export { XhMenuArrow, XhMenuContent, XhMenuGroup, XhMenuGroupLabel, XhMenuItem, XhMenuItemDescription, XhMenuItemIndicator, XhMenuItemShortcut, XhMenuItemSuffix, XhMenuItemText, XhMenuPositioner, XhMenuRoot, XhMenuSeparator, XhMenuSub, XhMenuSubTrigger, XhMenuTrigger };
|
|
327
382
|
|
|
328
383
|
//# sourceMappingURL=menu.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"menu.js","names":["mergeVueProps","mergeProps"],"sources":["../../../src/components/menu/menu.ts"],"sourcesContent":["/*\n * Copyright (c) 2021-Present XiHanFun and contributors.\n * Licensed under the MIT License. See LICENSE in the project root for license information.\n */\n\n// 提供 menu 相关实现。\n\nimport type { Direction, Placement, Size, Tone } from '@xihan-ui/core'\nimport type { MenuApi, MenuGroupProps, MenuItemProps, MenuNode, MenuNodeMeta, MenuSchema, MenuTranslations } from '@xihan-ui/headless'\nimport type { PropType, SlotsType, VNode } from 'vue'\nimport type { PayloadOf } from '../../runtime/payload'\nimport { mergeProps } from '@xihan-ui/core'\nimport { computed, defineComponent, h, mergeProps as mergeVueProps, onBeforeUnmount, ref, watch } from 'vue'\nimport { withXhConfig } from '../../config/config'\nimport { mergeIntoChild } from '../../runtime/as-child'\nimport { mergePartProps } from '../../runtime/merge-props'\nimport { XhPortal } from '../../runtime/portal'\nimport { useScrollbars } from '../../runtime/use-scrollbars'\nimport { provideMenu, provideMenuGroup, provideMenuItem, provideMenuSub, useMenuContext, useMenuGroupContext, useMenuItemContext, useMenuSubContext } from './context'\nimport { useMenu, useMenuWithParent } from './use-menu'\n\ntype MenuProps = MenuSchema['props']\n\n/** 默认插槽的载荷:展开态与修改展开的动作。 */\nexport type MenuRootSlotProps = Pick<MenuApi, 'open' | 'setOpen'>\n\nexport const XhMenuRoot = /* @__PURE__ */ defineComponent({\n name: 'XhMenuRoot',\n // 缺省值由 connect 给出;普通类型省略 default,Boolean 显式保留 undefined\n props: {\n collection: { type: Array as PropType<MenuNode[]> },\n open: { type: Boolean, default: undefined },\n defaultOpen: Boolean,\n placement: { type: String as PropType<Placement> },\n offset: { type: Number },\n loop: { type: Boolean, default: undefined },\n dir: { type: String as PropType<Direction> },\n tone: { type: String as PropType<Tone> },\n size: { type: String as PropType<Size> },\n typeahead: { type: Boolean, default: undefined },\n disabled: { type: Boolean, default: undefined },\n translations: { type: Object as PropType<Partial<MenuTranslations>> },\n openOnHover: { type: Boolean, default: undefined },\n hoverOpenDelay: { type: Number },\n hoverCloseDelay: { type: Number },\n /**\n * 只提供 collection 时,触发器插槽给出的节点直接作为触发器使用,不再外包一个 <button>。\n * 放置部件的写法有 XhMenuTrigger 自己的 asChild,该 prop 是自动铺设路径的同一能力。\n */\n triggerAsChild: Boolean,\n },\n // open-change 携带 { open }、select 携带 { value },update:open 携带裸布尔\n emits: {\n 'open-change': (_details: PayloadOf<MenuProps, 'onOpenChange'>) => true,\n 'select': (_details: PayloadOf<MenuProps, 'onSelect'>) => true,\n 'update:open': (_open: PayloadOf<MenuProps, 'onOpenChange'>['open']) => true,\n },\n slots: Object as SlotsType<{\n default?: (props: MenuRootSlotProps) => VNode[]\n trigger?: () => VNode[]\n item?: (node: MenuNodeMeta) => VNode[]\n }>,\n setup(props, { slots, emit }) {\n const notifyOpen: MenuProps['onOpenChange'] = (details) => {\n emit('open-change', details)\n emit('update:open', details.open)\n }\n const notifySelect: MenuProps['onSelect'] = details => emit('select', details)\n const ctx = useMenu(withXhConfig('menu', props) as MenuProps, notifyOpen, notifySelect)\n provideMenu(ctx)\n return () => (slots.default\n ? slots.default({ open: ctx.api.value.open, setOpen: ctx.api.value.setOpen })\n : props.collection\n ? renderDefaultTree(ctx.api.value.collection, slots.trigger?.() ?? null, slots.item, props.triggerAsChild)\n : [])\n },\n})\n\nexport const XhMenuTrigger = /* @__PURE__ */ defineComponent({\n name: 'XhMenuTrigger',\n // 直通属性自己合:Vue 默认把作者的处理器排在部件的后面,这里改成作者先跑\n inheritAttrs: false,\n props: {\n /** 借用作者的子节点作为触发器,不再渲染自己的包裹元素;子节点须恰好一个。 */\n asChild: Boolean,\n },\n setup(props, { slots, attrs }) {\n const ctx = useMenuContext()\n return () => {\n const part = mergePartProps({\n ...ctx.api.value.getTriggerProps() as Record<string, unknown>,\n ref: (el: unknown) => { ctx.triggerRef.value = el as HTMLElement },\n }, attrs)\n const children = slots.default?.()\n // asChild:把触发器属性合到作者的节点上,不再自己渲染包裹元素\n if (props.asChild) {\n const merged = mergeIntoChild(children, part, 'menu')\n if (merged)\n return merged\n }\n return h('button', part, children)\n }\n },\n})\n\nexport const XhMenuPositioner = /* @__PURE__ */ defineComponent({\n name: 'XhMenuPositioner',\n props: {\n /** 本实例的 Portal 容器;优先于应用级配置。 */\n container: { type: Object as PropType<Element> },\n },\n // 根是 Teleport,Vue 不会把直通属性合上去,作者写的 class 与 style 得自己接住落到 positioner 上\n inheritAttrs: false,\n setup(props, { slots, attrs }) {\n const ctx = useMenuContext()\n // 条目列表的自绘条:与 content 同级、绝对定位不占布局,壳是这层已经 fixed 的 positioner;浮层里的条子走 4px 档\n const bars = useScrollbars({ scrollable: () => ctx.contentRef.value, props: { size: 'sm' } })\n // 定位层搬到 portal 落点,逃开祖先的层叠上下文\n return () => h(XhPortal, { to: props.container ?? ctx.portalTarget.value, source: ctx.triggerRef }, () => [\n h('div', {\n ...mergeVueProps(ctx.api.value.getPositionerProps() as Record<string, unknown>, attrs),\n ref: (el: unknown) => { ctx.positionerRef.value = el as HTMLElement },\n }, [...(slots.default?.() ?? []), ...bars.render()]),\n ])\n },\n})\n\nexport const XhMenuContent = /* @__PURE__ */ defineComponent({\n name: 'XhMenuContent',\n setup(_, { slots }) {\n const ctx = useMenuContext()\n return () => h('div', {\n ...ctx.api.value.getContentProps() as Record<string, unknown>,\n // 收起跟着退场闸门走:皮肤刻意没给 content 补 [hidden]{display:none}(补了退场\n // 就一帧都播不出来),所以真正的收起落成内联 display——节点始终留在原地\n style: ctx.visible.value ? undefined : { display: 'none' },\n ref: (el: unknown) => { ctx.contentRef.value = el as HTMLElement },\n }, slots.default?.())\n },\n})\n\nexport const XhMenuItem = /* @__PURE__ */ defineComponent({\n name: 'XhMenuItem',\n props: {\n value: { type: String, required: true },\n // 缺省交给 connect 回 collection 里查,写死 false 会盖掉数据里的禁用\n disabled: { type: Boolean, default: undefined },\n },\n setup(props, { slots }) {\n const ctx = useMenuContext()\n const item = computed<MenuItemProps>(() => ({ value: props.value, disabled: props.disabled }))\n provideMenuItem({ item })\n // 本条目持有焦点时,value 变更按新值重报焦点条目,卸载时上报焦点丢失\n const itemEl = ref<HTMLElement | null>(null)\n watch(() => props.value, (next, prev) => {\n if (next === prev)\n return\n const svc = ctx.service\n if (svc.getStatus() !== 'Started')\n return\n if (itemEl.value && svc.scope.getActiveElement() === itemEl.value)\n svc.send({ type: 'ITEM.FOCUS', value: next })\n })\n onBeforeUnmount(() => {\n const { service } = ctx\n // 根已停机时不再送事件\n if (service.getStatus() !== 'Started')\n return\n // 按「本节点当下正持有焦点」判定,不按 value 比对\n if (itemEl.value && service.scope.getActiveElement() === itemEl.value)\n service.send({ type: 'ITEM.LOST' })\n })\n return () => h(\n 'div',\n { ...ctx.api.value.getItemProps({ value: props.value, disabled: props.disabled }) as Record<string, unknown>, ref: itemEl },\n slots.default?.(),\n )\n },\n})\n\n/** 默认插槽的载荷:本层子菜单的展开态与修改展开的动作。 */\nexport type MenuSubSlotProps = Pick<MenuApi, 'open' | 'setOpen'>\n\n/**\n * 子菜单:内部再运行一台 menu 状态机(submenu 模式),触发条目由 XhMenuSubTrigger\n * 渲染为父菜单条目与本子菜单触发器的双重身份。本身不渲染节点。\n */\nexport const XhMenuSub = /* @__PURE__ */ defineComponent({\n name: 'XhMenuSub',\n props: {\n /** 它在父菜单中的条目身份。 */\n value: { type: String, required: true },\n disabled: { type: Boolean, default: undefined },\n collection: { type: Array as PropType<MenuNode[]> },\n placement: { type: String as PropType<Placement> },\n offset: { type: Number },\n loop: { type: Boolean, default: undefined },\n openOnHover: { type: Boolean, default: undefined },\n hoverOpenDelay: { type: Number },\n /** 文字方向;默认继承父层。子层被迁移到浮层落点,无法继承父层的方向。 */\n dir: { type: String as PropType<Direction> },\n /** 语气;默认继承父层。子层是浮层落点下的同级节点,CSS 私有槽无法继承。 */\n tone: { type: String as PropType<Tone> },\n /** 尺寸;默认继承父层,理由同 tone。 */\n size: { type: String as PropType<Size> },\n hoverCloseDelay: { type: Number },\n },\n slots: Object as SlotsType<{\n default?: (props: MenuSubSlotProps) => VNode[]\n }>,\n setup(props, { slots }) {\n const parent = useMenuContext()\n const ctx = useMenuWithParent(\n {\n ...props,\n submenu: true,\n dir: props.dir ?? parent.service.prop('dir'),\n tone: props.tone ?? parent.service.prop('tone'),\n size: props.size ?? parent.service.prop('size'),\n } as MenuProps,\n undefined,\n parent.tree,\n )\n // 覆盖菜单上下文:本子树内的部件都归子机器\n provideMenu(ctx)\n provideMenuSub({ parent, value: props.value, disabled: props.disabled })\n // 父层收起(Escape、外点、选中)时本层跟着收,层层传导\n watch(() => parent.api.value.open, (open) => {\n if (!open)\n ctx.api.value.setOpen(false)\n })\n return () => slots.default?.({ open: ctx.api.value.open, setOpen: ctx.api.value.setOpen })\n },\n})\n\nexport const XhMenuSubTrigger = /* @__PURE__ */ defineComponent({\n name: 'XhMenuSubTrigger',\n setup(_, { slots }) {\n const sub = useMenuSubContext()\n const ctx = useMenuContext()\n return () => h('div', {\n ...mergeProps(\n sub.parent.api.value.getItemProps({ value: sub.value, disabled: sub.disabled }) as Record<string, unknown>,\n ctx.api.value.getSubmenuTriggerProps({ value: sub.value, disabled: sub.disabled }) as Record<string, unknown>,\n ),\n // 子菜单的定位锚点就是这一条\n ref: (el: unknown) => {\n ctx.triggerRef.value = el as HTMLElement\n },\n }, slots.default?.())\n },\n})\n\n/** 条目中的文字载体:连打检索取它,图标与副文本的文字因此不进入检索串 */\nexport const XhMenuItemText = /* @__PURE__ */ defineComponent({\n name: 'XhMenuItemText',\n setup(_, { slots }) {\n const ctx = useMenuContext()\n const { item } = useMenuItemContext()\n return () => h('span', ctx.api.value.getItemTextProps(item.value) as Record<string, unknown>, slots.default?.())\n },\n})\n\n/** 条目中的标记位(勾选、图标),纯装饰 */\nexport const XhMenuItemIndicator = /* @__PURE__ */ defineComponent({\n name: 'XhMenuItemIndicator',\n setup(_, { slots }) {\n const ctx = useMenuContext()\n const { item } = useMenuItemContext()\n return () => h('span', ctx.api.value.getItemIndicatorProps(item.value) as Record<string, unknown>, slots.default?.())\n },\n})\n\n/** 条目中的副文本,排在文字下一行 */\nexport const XhMenuItemDescription = /* @__PURE__ */ defineComponent({\n name: 'XhMenuItemDescription',\n setup(_, { slots }) {\n const ctx = useMenuContext()\n const { item } = useMenuItemContext()\n return () => h('span', ctx.api.value.getItemDescriptionProps(item.value) as Record<string, unknown>, slots.default?.())\n },\n})\n\nexport const XhMenuGroup = /* @__PURE__ */ defineComponent({\n name: 'XhMenuGroup',\n props: {\n value: { type: String, required: true },\n },\n setup(props, { slots }) {\n const ctx = useMenuContext()\n const group = computed<MenuGroupProps>(() => ({ value: props.value }))\n provideMenuGroup({ group })\n return () => h('div', ctx.api.value.getGroupProps(group.value) as Record<string, unknown>, slots.default?.())\n },\n})\n\nexport const XhMenuGroupLabel = /* @__PURE__ */ defineComponent({\n name: 'XhMenuGroupLabel',\n setup(_, { slots }) {\n const ctx = useMenuContext()\n const { group } = useMenuGroupContext()\n return () => h('span', ctx.api.value.getGroupLabelProps(group.value) as Record<string, unknown>, slots.default?.())\n },\n})\n\nexport const XhMenuSeparator = /* @__PURE__ */ defineComponent({\n name: 'XhMenuSeparator',\n setup() {\n const ctx = useMenuContext()\n return () => h('div', ctx.api.value.getSeparatorProps() as Record<string, unknown>)\n },\n})\n\nexport const XhMenuArrow = /* @__PURE__ */ defineComponent({\n name: 'XhMenuArrow',\n setup() {\n const ctx = useMenuContext()\n return () => h('div', ctx.api.value.getArrowProps() as Record<string, unknown>)\n },\n})\n\n/**\n * 未写默认插槽时按 collection 铺开的整套结构,作者只提供数据。\n * 与手写部件产出的 DOM 完全一致,需要修改结构时写默认插槽,行为不变。\n * 触发器内容归作者,由 trigger 插槽承载;条目内容默认是 label,可由 item 插槽接管。\n */\nfunction renderDefaultTree(\n collection: readonly MenuNodeMeta[],\n trigger: (VNode | string)[] | null,\n itemSlot?: (node: MenuNodeMeta) => VNode[],\n triggerAsChild?: boolean,\n): VNode[] {\n return [\n h(XhMenuTrigger, { asChild: triggerAsChild }, () => trigger ?? []),\n h(XhMenuPositioner, null, () => [\n h(XhMenuContent, null, () => collection.flatMap((node, index) => [\n // 首条上的标记不产出分隔线:菜单开头不留一道空隔\n ...(index > 0 && node.separatorBefore ? [h(XhMenuSeparator, { key: `separator:${node.value}` })] : []),\n h(XhMenuItem, { key: node.value, value: node.value }, () => itemSlot?.(node) ?? node.label),\n ])),\n ]),\n ]\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"menu.js","names":["mergeVueProps","mergeProps"],"sources":["../../../src/components/menu/menu.ts"],"sourcesContent":["/*\n * Copyright (c) 2021-Present XiHanFun and contributors.\n * Licensed under the MIT License. See LICENSE in the project root for license information.\n */\n\n// 提供 menu 相关实现。\n\nimport type { Direction, Placement, Size, Tone } from '@xihan-ui/core'\nimport type { MenuApi, MenuGroupProps, MenuItemProps, MenuNode, MenuNodeMeta, MenuSchema, MenuTranslations } from '@xihan-ui/headless'\nimport type { PropType, SlotsType, VNode } from 'vue'\nimport type { PayloadOf } from '../../runtime/payload'\nimport { groupAdjacentRuns, mergeProps } from '@xihan-ui/core'\nimport { computed, defineComponent, h, mergeProps as mergeVueProps, onBeforeUnmount, ref, watch } from 'vue'\nimport { withXhConfig } from '../../config/config'\nimport { mergeIntoChild } from '../../runtime/as-child'\nimport { mergePartProps } from '../../runtime/merge-props'\nimport { XhPortal } from '../../runtime/portal'\nimport { useScrollbars } from '../../runtime/use-scrollbars'\nimport { provideMenu, provideMenuGroup, provideMenuItem, provideMenuSub, useMenuContext, useMenuGroupContext, useMenuItemContext, useMenuSubContext } from './context'\nimport { useMenu, useMenuWithParent } from './use-menu'\n\ntype MenuProps = MenuSchema['props']\n\n/** 默认插槽的载荷:展开态与修改展开的动作。 */\nexport type MenuRootSlotProps = Pick<MenuApi, 'open' | 'setOpen'>\n\n/** 代铺条目时可逐槽接管的三个插槽;三个都不写即完全按数据铺。 */\nexport interface MenuItemSlots {\n /** 整条的接管口:写了它,代铺的标记位、文字、说明与快捷键一概不铺。 */\n 'item'?: (node: MenuNodeMeta) => VNode[]\n /** 只接管行首那一格(与数据里的 indicator 同一个部件),其余槽照旧由数据铺。 */\n 'item-prefix'?: (node: MenuNodeMeta) => VNode[]\n /** 只接管行尾那一格(计数、徽标、次级图标),其余槽照旧由数据铺。 */\n 'item-suffix'?: (node: MenuNodeMeta) => VNode[]\n}\n\nexport const XhMenuRoot = /* @__PURE__ */ defineComponent({\n name: 'XhMenuRoot',\n // 缺省值由 connect 给出;普通类型省略 default,Boolean 显式保留 undefined\n props: {\n collection: { type: Array as PropType<MenuNode[]> },\n open: { type: Boolean, default: undefined },\n defaultOpen: Boolean,\n placement: { type: String as PropType<Placement> },\n offset: { type: Number },\n loop: { type: Boolean, default: undefined },\n dir: { type: String as PropType<Direction> },\n tone: { type: String as PropType<Tone> },\n size: { type: String as PropType<Size> },\n typeahead: { type: Boolean, default: undefined },\n disabled: { type: Boolean, default: undefined },\n translations: { type: Object as PropType<Partial<MenuTranslations>> },\n openOnHover: { type: Boolean, default: undefined },\n hoverOpenDelay: { type: Number },\n hoverCloseDelay: { type: Number },\n /**\n * 只提供 collection 时,触发器插槽给出的节点直接作为触发器使用,不再外包一个 <button>。\n * 放置部件的写法有 XhMenuTrigger 自己的 asChild,该 prop 是自动铺设路径的同一能力。\n */\n triggerAsChild: Boolean,\n },\n // open-change 携带 { open }、select 携带 { value },update:open 携带裸布尔\n emits: {\n 'open-change': (_details: PayloadOf<MenuProps, 'onOpenChange'>) => true,\n 'select': (_details: PayloadOf<MenuProps, 'onSelect'>) => true,\n 'update:open': (_open: PayloadOf<MenuProps, 'onOpenChange'>['open']) => true,\n },\n slots: Object as SlotsType<{\n 'default'?: (props: MenuRootSlotProps) => VNode[]\n 'trigger'?: () => VNode[]\n /** 整条的接管口:写了它,代铺的各格一概不铺,作者自己放置部件 */\n 'item'?: (node: MenuNodeMeta) => VNode[]\n /** 只接管行首那一格,其余槽照旧由数据铺 */\n 'item-prefix'?: (node: MenuNodeMeta) => VNode[]\n /** 只接管行尾那一格(计数、徽标、次级图标),其余槽照旧由数据铺 */\n 'item-suffix'?: (node: MenuNodeMeta) => VNode[]\n }>,\n setup(props, { slots, emit }) {\n const notifyOpen: MenuProps['onOpenChange'] = (details) => {\n emit('open-change', details)\n emit('update:open', details.open)\n }\n const notifySelect: MenuProps['onSelect'] = details => emit('select', details)\n const ctx = useMenu(withXhConfig('menu', props) as MenuProps, notifyOpen, notifySelect)\n provideMenu(ctx)\n return () => (slots.default\n ? slots.default({ open: ctx.api.value.open, setOpen: ctx.api.value.setOpen })\n : props.collection\n ? renderDefaultTree(ctx.api.value.collection, slots.trigger?.() ?? null, { 'item': slots.item, 'item-prefix': slots['item-prefix'], 'item-suffix': slots['item-suffix'] }, props.triggerAsChild)\n : [])\n },\n})\n\nexport const XhMenuTrigger = /* @__PURE__ */ defineComponent({\n name: 'XhMenuTrigger',\n // 直通属性自己合:Vue 默认把作者的处理器排在部件的后面,这里改成作者先跑\n inheritAttrs: false,\n props: {\n /** 借用作者的子节点作为触发器,不再渲染自己的包裹元素;子节点须恰好一个。 */\n asChild: Boolean,\n },\n setup(props, { slots, attrs }) {\n const ctx = useMenuContext()\n return () => {\n const part = mergePartProps({\n ...ctx.api.value.getTriggerProps() as Record<string, unknown>,\n ref: (el: unknown) => { ctx.triggerRef.value = el as HTMLElement },\n }, attrs)\n const children = slots.default?.()\n // asChild:把触发器属性合到作者的节点上,不再自己渲染包裹元素\n if (props.asChild) {\n const merged = mergeIntoChild(children, part, 'menu')\n if (merged)\n return merged\n }\n return h('button', part, children)\n }\n },\n})\n\nexport const XhMenuPositioner = /* @__PURE__ */ defineComponent({\n name: 'XhMenuPositioner',\n props: {\n /** 本实例的 Portal 容器;优先于应用级配置。 */\n container: { type: Object as PropType<Element> },\n },\n // 根是 Teleport,Vue 不会把直通属性合上去,作者写的 class 与 style 得自己接住落到 positioner 上\n inheritAttrs: false,\n setup(props, { slots, attrs }) {\n const ctx = useMenuContext()\n // 条目列表的自绘条:与 content 同级、绝对定位不占布局,壳是这层已经 fixed 的 positioner;浮层里的条子走 4px 档\n const bars = useScrollbars({ scrollable: () => ctx.contentRef.value, props: { size: 'sm' } })\n // 定位层搬到 portal 落点,逃开祖先的层叠上下文\n return () => h(XhPortal, { to: props.container ?? ctx.portalTarget.value, source: ctx.triggerRef }, () => [\n h('div', {\n ...mergeVueProps(ctx.api.value.getPositionerProps() as Record<string, unknown>, attrs),\n ref: (el: unknown) => { ctx.positionerRef.value = el as HTMLElement },\n }, [...(slots.default?.() ?? []), ...bars.render()]),\n ])\n },\n})\n\nexport const XhMenuContent = /* @__PURE__ */ defineComponent({\n name: 'XhMenuContent',\n setup(_, { slots }) {\n const ctx = useMenuContext()\n return () => h('div', {\n ...ctx.api.value.getContentProps() as Record<string, unknown>,\n // 收起跟着退场闸门走:皮肤刻意没给 content 补 [hidden]{display:none}(补了退场\n // 就一帧都播不出来),所以真正的收起落成内联 display——节点始终留在原地\n style: ctx.visible.value ? undefined : { display: 'none' },\n ref: (el: unknown) => { ctx.contentRef.value = el as HTMLElement },\n }, slots.default?.())\n },\n})\n\nexport const XhMenuItem = /* @__PURE__ */ defineComponent({\n name: 'XhMenuItem',\n props: {\n value: { type: String, required: true },\n // 缺省交给 connect 回 collection 里查,写死 false 会盖掉数据里的禁用\n disabled: { type: Boolean, default: undefined },\n },\n setup(props, { slots }) {\n const ctx = useMenuContext()\n const item = computed<MenuItemProps>(() => ({ value: props.value, disabled: props.disabled }))\n provideMenuItem({ item })\n // 本条目持有焦点时,value 变更按新值重报焦点条目,卸载时上报焦点丢失\n const itemEl = ref<HTMLElement | null>(null)\n watch(() => props.value, (next, prev) => {\n if (next === prev)\n return\n const svc = ctx.service\n if (svc.getStatus() !== 'Started')\n return\n if (itemEl.value && svc.scope.getActiveElement() === itemEl.value)\n svc.send({ type: 'ITEM.FOCUS', value: next })\n })\n onBeforeUnmount(() => {\n const { service } = ctx\n // 根已停机时不再送事件\n if (service.getStatus() !== 'Started')\n return\n // 按「本节点当下正持有焦点」判定,不按 value 比对\n if (itemEl.value && service.scope.getActiveElement() === itemEl.value)\n service.send({ type: 'ITEM.LOST' })\n })\n return () => h(\n 'div',\n { ...ctx.api.value.getItemProps({ value: props.value, disabled: props.disabled }) as Record<string, unknown>, ref: itemEl },\n slots.default?.(),\n )\n },\n})\n\n/** 默认插槽的载荷:本层子菜单的展开态与修改展开的动作。 */\nexport type MenuSubSlotProps = Pick<MenuApi, 'open' | 'setOpen'>\n\n/**\n * 子菜单:内部再运行一台 menu 状态机(submenu 模式),触发条目由 XhMenuSubTrigger\n * 渲染为父菜单条目与本子菜单触发器的双重身份。本身不渲染节点。\n */\nexport const XhMenuSub = /* @__PURE__ */ defineComponent({\n name: 'XhMenuSub',\n props: {\n /** 它在父菜单中的条目身份。 */\n value: { type: String, required: true },\n disabled: { type: Boolean, default: undefined },\n collection: { type: Array as PropType<MenuNode[]> },\n placement: { type: String as PropType<Placement> },\n offset: { type: Number },\n loop: { type: Boolean, default: undefined },\n openOnHover: { type: Boolean, default: undefined },\n hoverOpenDelay: { type: Number },\n /** 文字方向;默认继承父层。子层被迁移到浮层落点,无法继承父层的方向。 */\n dir: { type: String as PropType<Direction> },\n /** 语气;默认继承父层。子层是浮层落点下的同级节点,CSS 私有槽无法继承。 */\n tone: { type: String as PropType<Tone> },\n /** 尺寸;默认继承父层,理由同 tone。 */\n size: { type: String as PropType<Size> },\n hoverCloseDelay: { type: Number },\n },\n slots: Object as SlotsType<{\n default?: (props: MenuSubSlotProps) => VNode[]\n }>,\n setup(props, { slots }) {\n const parent = useMenuContext()\n const ctx = useMenuWithParent(\n {\n ...props,\n submenu: true,\n dir: props.dir ?? parent.service.prop('dir'),\n tone: props.tone ?? parent.service.prop('tone'),\n size: props.size ?? parent.service.prop('size'),\n } as MenuProps,\n undefined,\n parent.tree,\n )\n // 覆盖菜单上下文:本子树内的部件都归子机器\n provideMenu(ctx)\n provideMenuSub({ parent, value: props.value, disabled: props.disabled })\n // 父层收起(Escape、外点、选中)时本层跟着收,层层传导\n watch(() => parent.api.value.open, (open) => {\n if (!open)\n ctx.api.value.setOpen(false)\n })\n return () => slots.default?.({ open: ctx.api.value.open, setOpen: ctx.api.value.setOpen })\n },\n})\n\nexport const XhMenuSubTrigger = /* @__PURE__ */ defineComponent({\n name: 'XhMenuSubTrigger',\n setup(_, { slots }) {\n const sub = useMenuSubContext()\n const ctx = useMenuContext()\n return () => h('div', {\n ...mergeProps(\n sub.parent.api.value.getItemProps({ value: sub.value, disabled: sub.disabled }) as Record<string, unknown>,\n ctx.api.value.getSubmenuTriggerProps({ value: sub.value, disabled: sub.disabled }) as Record<string, unknown>,\n ),\n // 子菜单的定位锚点就是这一条\n ref: (el: unknown) => {\n ctx.triggerRef.value = el as HTMLElement\n },\n }, slots.default?.())\n },\n})\n\n/** 条目中的文字载体:连打检索取它,图标与副文本的文字因此不进入检索串 */\nexport const XhMenuItemText = /* @__PURE__ */ defineComponent({\n name: 'XhMenuItemText',\n setup(_, { slots }) {\n const ctx = useMenuContext()\n const { item } = useMenuItemContext()\n return () => h('span', ctx.api.value.getItemTextProps(item.value) as Record<string, unknown>, slots.default?.())\n },\n})\n\n/** 条目中的标记位(勾选、图标),纯装饰 */\nexport const XhMenuItemIndicator = /* @__PURE__ */ defineComponent({\n name: 'XhMenuItemIndicator',\n setup(_, { slots }) {\n const ctx = useMenuContext()\n const { item } = useMenuItemContext()\n return () => h('span', ctx.api.value.getItemIndicatorProps(item.value) as Record<string, unknown>, slots.default?.())\n },\n})\n\n/** 条目中的副文本,排在文字下一行 */\nexport const XhMenuItemDescription = /* @__PURE__ */ defineComponent({\n name: 'XhMenuItemDescription',\n setup(_, { slots }) {\n const ctx = useMenuContext()\n const { item } = useMenuItemContext()\n return () => h('span', ctx.api.value.getItemDescriptionProps(item.value) as Record<string, unknown>, slots.default?.())\n },\n})\n\n/** 条目中的快捷键提示,贴行尾;纯装饰,读屏从条目文字取意 */\nexport const XhMenuItemShortcut = /* @__PURE__ */ defineComponent({\n name: 'XhMenuItemShortcut',\n setup(_, { slots }) {\n const ctx = useMenuContext()\n const { item } = useMenuItemContext()\n return () => h('span', ctx.api.value.getItemShortcutProps(item.value) as Record<string, unknown>, slots.default?.())\n },\n})\n\n/** 条目行尾的作者内容(计数、徽标、次级图标);家族只管落位,不规定字号与颜色 */\nexport const XhMenuItemSuffix = /* @__PURE__ */ defineComponent({\n name: 'XhMenuItemSuffix',\n setup(_, { slots }) {\n const ctx = useMenuContext()\n const { item } = useMenuItemContext()\n return () => h('span', ctx.api.value.getItemSuffixProps(item.value) as Record<string, unknown>, slots.default?.())\n },\n})\n\nexport const XhMenuGroup = /* @__PURE__ */ defineComponent({\n name: 'XhMenuGroup',\n props: {\n value: { type: String, required: true },\n },\n setup(props, { slots }) {\n const ctx = useMenuContext()\n const group = computed<MenuGroupProps>(() => ({ value: props.value }))\n provideMenuGroup({ group })\n return () => h('div', ctx.api.value.getGroupProps(group.value) as Record<string, unknown>, slots.default?.())\n },\n})\n\nexport const XhMenuGroupLabel = /* @__PURE__ */ defineComponent({\n name: 'XhMenuGroupLabel',\n setup(_, { slots }) {\n const ctx = useMenuContext()\n const { group } = useMenuGroupContext()\n return () => h('span', ctx.api.value.getGroupLabelProps(group.value) as Record<string, unknown>, slots.default?.())\n },\n})\n\nexport const XhMenuSeparator = /* @__PURE__ */ defineComponent({\n name: 'XhMenuSeparator',\n setup() {\n const ctx = useMenuContext()\n return () => h('div', ctx.api.value.getSeparatorProps() as Record<string, unknown>)\n },\n})\n\nexport const XhMenuArrow = /* @__PURE__ */ defineComponent({\n name: 'XhMenuArrow',\n setup() {\n const ctx = useMenuContext()\n return () => h('div', ctx.api.value.getArrowProps() as Record<string, unknown>)\n },\n})\n\n/**\n * 未写默认插槽时按 collection 铺开的整套结构,作者只提供数据。\n * 与手写部件产出的 DOM 完全一致,需要修改结构时写默认插槽,行为不变。\n * 触发器内容归作者,由 trigger 插槽承载;条目内容默认是 label,可由 item 插槽接管。\n */\nfunction renderDefaultTree(\n collection: readonly MenuNodeMeta[],\n trigger: (VNode | string)[] | null,\n itemSlots: MenuItemSlots,\n triggerAsChild?: boolean,\n): VNode[] {\n return [\n h(XhMenuTrigger, { asChild: triggerAsChild }, () => trigger ?? []),\n h(XhMenuPositioner, null, () => [\n h(XhMenuContent, null, () => renderNodes(collection, itemSlots)),\n ]),\n ]\n}\n\n/** content 的内容:分组段铺为 group,段首的分隔线落在 group 外面。 */\nfunction renderNodes(\n collection: readonly MenuNodeMeta[],\n itemSlots: MenuItemSlots,\n): VNode[] {\n return groupAdjacentRuns(collection, node => node.group).flatMap((run, runIndex) => {\n const head = run[0]!\n // 首条上的标记不产出分隔线:菜单开头不留一道空隔\n const lead = runIndex > 0 && head.separatorBefore\n ? [h(XhMenuSeparator, { key: `separator:${head.value}` })]\n : []\n if (head.group == null)\n return [...lead, renderItem(head, itemSlots)]\n const groupLabel = run.find(node => node.groupLabel != null)?.groupLabel ?? null\n return [\n ...lead,\n h(XhMenuGroup, { key: `group:${head.group}`, value: head.group }, () => [\n ...(groupLabel != null ? [h(XhMenuGroupLabel, null, () => groupLabel)] : []),\n ...run.flatMap((node, index) => [\n ...(index > 0 && node.separatorBefore ? [h(XhMenuSeparator, { key: `separator:${node.value}` })] : []),\n renderItem(node, itemSlots),\n ]),\n ]),\n ]\n })\n}\n\n/**\n * 单个条目:按数据铺标记位、文字、说明与快捷键,未提供的那几个不铺对应部件。\n *\n * 三个插槽各管一段,不必为了改一处把整条重搭:\n * - `item-prefix` / `item-suffix` 只接管行首与行尾那一格,其余槽照旧由数据铺。\n * 行首那一格与数据里的 `indicator` 同一个部件,插槽在场时以它为准。\n * - `item` 是整条的接管口:写了它,上面几格一概不铺,作者自己放置 XhMenuItemText 等部件\n * (与 ContextMenu 的 item 插槽语义不同,那边填的是文字槽)。\n */\nfunction renderItem(\n meta: MenuNodeMeta,\n itemSlots: MenuItemSlots,\n): VNode {\n const prefix = itemSlots['item-prefix']\n const suffix = itemSlots['item-suffix']\n return h(XhMenuItem, { key: meta.value, value: meta.value }, () => itemSlots.item?.(meta) ?? [\n ...(prefix\n ? [h(XhMenuItemIndicator, null, () => prefix(meta))]\n : meta.indicator != null ? [h(XhMenuItemIndicator, null, () => meta.indicator)] : []),\n h(XhMenuItemText, null, () => meta.label),\n ...(meta.description != null ? [h(XhMenuItemDescription, null, () => meta.description)] : []),\n ...(meta.shortcut != null ? [h(XhMenuItemShortcut, null, () => meta.shortcut)] : []),\n ...(suffix ? [h(XhMenuItemSuffix, null, () => suffix(meta))] : []),\n ])\n}\n"],"mappings":"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"}
|
|
@@ -6,7 +6,6 @@ import { MenubarApi, MenubarNode, MenubarNodeMeta, MenubarSchema } from "@xihan-
|
|
|
6
6
|
type MenubarProps = MenubarSchema['props'];
|
|
7
7
|
/** 默认插槽的载荷:当前展开的菜单项、是否有菜单展开,以及切换展开项的命令。 */
|
|
8
8
|
type MenubarRootSlotProps = Pick<MenubarApi, 'value' | 'open' | 'setValue'>;
|
|
9
|
-
/** role=menubar 根节点:trigger 的 roving tabindex 作用域,各菜单浮层也挂在其内 */
|
|
10
9
|
declare const XhMenubarRoot: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
11
10
|
collection: {
|
|
12
11
|
type: PropType<MenubarNode[]>;
|
|
@@ -109,7 +108,12 @@ declare const XhMenubarRoot: import("vue").DefineComponent<import("vue").Extract
|
|
|
109
108
|
typeahead: boolean;
|
|
110
109
|
}, SlotsType<{
|
|
111
110
|
default?: (props: MenubarRootSlotProps) => VNode[];
|
|
111
|
+
/** 只填条目的文字槽,标记位、副文本与快捷键照旧由数据铺 */
|
|
112
112
|
item?: (node: MenubarNodeMeta) => VNode[];
|
|
113
|
+
/** 只接管行首那一格,其余槽照旧由数据铺 */
|
|
114
|
+
'item-prefix'?: (node: MenubarNodeMeta) => VNode[];
|
|
115
|
+
/** 只接管行尾那一格(计数、徽标、次级图标),其余槽照旧由数据铺 */
|
|
116
|
+
'item-suffix'?: (node: MenubarNodeMeta) => VNode[];
|
|
113
117
|
}>, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
114
118
|
declare const XhMenubarTrigger: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
115
119
|
value: {
|
|
@@ -220,6 +224,14 @@ declare const XhMenubarItemIndicator: import("vue").DefineComponent<{}, () => VN
|
|
|
220
224
|
declare const XhMenubarItemDescription: import("vue").DefineComponent<{}, () => VNode<import("vue").RendererNode, import("vue").RendererElement, {
|
|
221
225
|
[key: string]: any;
|
|
222
226
|
}>, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
227
|
+
/** 条目中的快捷键提示,贴行尾;纯装饰,读屏从条目文字取意 */
|
|
228
|
+
declare const XhMenubarItemShortcut: import("vue").DefineComponent<{}, () => VNode<import("vue").RendererNode, import("vue").RendererElement, {
|
|
229
|
+
[key: string]: any;
|
|
230
|
+
}>, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
231
|
+
/** 条目行尾的作者内容(计数、徽标、次级图标);家族只管落位,不规定字号与颜色 */
|
|
232
|
+
declare const XhMenubarItemSuffix: import("vue").DefineComponent<{}, () => VNode<import("vue").RendererNode, import("vue").RendererElement, {
|
|
233
|
+
[key: string]: any;
|
|
234
|
+
}>, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
223
235
|
/** 指向本菜单锚点的箭头,纯装饰;须写在同一菜单的 positioner 中 */
|
|
224
236
|
declare const XhMenubarArrow: import("vue").DefineComponent<{}, () => VNode<import("vue").RendererNode, import("vue").RendererElement, {
|
|
225
237
|
[key: string]: any;
|
|
@@ -329,5 +341,5 @@ declare const XhMenubarSubTrigger: import("vue").DefineComponent<{}, () => VNode
|
|
|
329
341
|
[key: string]: any;
|
|
330
342
|
}>, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
331
343
|
//#endregion
|
|
332
|
-
export { MenubarRootSlotProps, MenubarSubSlotProps, XhMenubarArrow, XhMenubarContent, XhMenubarGroup, XhMenubarGroupLabel, XhMenubarItem, XhMenubarItemDescription, XhMenubarItemIndicator, XhMenubarItemText, XhMenubarPositioner, XhMenubarRoot, XhMenubarSeparator, XhMenubarSub, XhMenubarSubTrigger, XhMenubarTrigger };
|
|
344
|
+
export { MenubarRootSlotProps, MenubarSubSlotProps, XhMenubarArrow, XhMenubarContent, XhMenubarGroup, XhMenubarGroupLabel, XhMenubarItem, XhMenubarItemDescription, XhMenubarItemIndicator, XhMenubarItemShortcut, XhMenubarItemSuffix, XhMenubarItemText, XhMenubarPositioner, XhMenubarRoot, XhMenubarSeparator, XhMenubarSub, XhMenubarSubTrigger, XhMenubarTrigger };
|
|
333
345
|
//# sourceMappingURL=menubar.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"menubar.d.ts","names":[],"sources":["../../../src/components/menubar/menubar.ts"],"mappings":";;;;;KAqCK,eAAe;;KAmBR,uBAAuB,KAAK
|
|
1
|
+
{"version":3,"file":"menubar.d.ts","names":[],"sources":["../../../src/components/menubar/menubar.ts"],"mappings":";;;;;KAqCK,eAAe;;KAmBR,uBAAuB,KAAK;cAa3B,6BAAa,8BAAA;;IAIO,MAAA,SAAS;;;IACb,MAAA;;;IACO,MAAA;;;IACD,MAAA,SAAS;;;;;;;IAEjB,MAAA,SAAS;;;;;;;;;;;IAGH,MAAA,SAAS;;;;;;IAEd,MAAA,SAAS;;;IACT,MAAA,SAAS;;;IACD,MAAA,SAAS;;;;;EAId,iBAAA,UAAA,UAAU;EAChB,SAAA,UAAA,UAAU;EACN,iBAAA,QAAA,UAAU;;;IAlBN,MAAA,SAAS;;;IACb,MAAA;;;IACO,MAAA;;;IACD,MAAA,SAAS;;;;;;;IAEjB,MAAA,SAAS;;;;;;;;;;;IAGH,MAAA,SAAS;;;;;;IAEd,MAAA,SAAS;;;IACT,MAAA,SAAS;;;IACD,MAAA,SAAS;;;;;;;;;;;EAS7B,WAAC,OAAO,yBAAyB;;EAEpC,QAAC,MAAM,oBAAoB;;EAEpB,iBAAC,MAAM,oBAAoB;;EAE3B,iBAAC,MAAM,oBAAoB;kCAuB7C;cAEW,gCAAgB,8BAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;qCAqD3B;cAEW,mCAAmB,8BAAA;;;;;;;IAKC,MAAA,SAAS;;;;;;;;;;;IAAT,MAAA,SAAS;;MAsBxC,oDAAA;cAEW,gCAAgB,8BAAA;;;;;;;;;;MAyD3B,oDAAA;cAEW,8BAAc,8BAAA;;;;;;;;;;;;MAWzB,oDAAA;cAEW,mCAAmB,0BAAA,oBAAA,4BAAA;;8BAO9B,qCAAA,iDAAA,aAAA,eAAA,oDAAA;cAEW,6BAAa,8BAAA;;;;;;;;;;;;;;;;;;;;;;qCAqCxB;cAEW,iCAAiB,0BAAA,oBAAA,4BAAA;;8BAO5B,qCAAA,iDAAA,aAAA,eAAA,oDAAA;cAEW,sCAAsB,0BAAA,oBAAA,4BAAA;;8BAOjC,qCAAA,iDAAA,aAAA,eAAA,oDAAA;;cAGW,wCAAwB,0BAAA,oBAAA,4BAAA;;8BAOnC,qCAAA,iDAAA,aAAA,eAAA,oDAAA;;cAGW,qCAAqB,0BAAA,oBAAA,4BAAA;;8BAOhC,qCAAA,iDAAA,aAAA,eAAA,oDAAA;;cAGW,mCAAmB,0BAAA,oBAAA,4BAAA;;8BAO9B,qCAAA,iDAAA,aAAA,eAAA,oDAAA;;cAGW,8BAAc,0BAAA,oBAAA,4BAAA;;8BASzB,qCAAA,iDAAA,aAAA,eAAA,oDAAA;cAEW,kCAAkB,0BAAA,oBAAA,4BAAA;;8BAM7B,qCAAA,iDAAA,aAAA,eAAA,oDAAA;;UAsEe;EACf;EACA,UAAU;;cAGC,4BAAY,8BAAA;;;;;;;;;;;IAMQ,MAAA,SAAS;;;;;;;;;;;;;;;;;;;;;IAOf,MAAA,SAAS;;;;IAER,MAAA,SAAS;;;;IAET,MAAA,SAAS;;;;;;;;;;;;;;;IAXJ,MAAA,SAAS;;;;;;;;;;;;;;;;;;;;;IAOf,MAAA,SAAS;;;;IAER,MAAA,SAAS;;;;IAET,MAAA,SAAS;;;;;;;EAGvB,WAAC,OAAO,wBAAwB;kCA6B5C;cAEW,mCAAmB,0BAAA,oBAAA,4BAAA;;8BAkB9B,qCAAA,iDAAA,aAAA,eAAA,oDAAA"}
|
|
@@ -25,7 +25,6 @@ function useMenubarPart(register, value) {
|
|
|
25
25
|
register(value(), el);
|
|
26
26
|
};
|
|
27
27
|
}
|
|
28
|
-
/** role=menubar 根节点:trigger 的 roving tabindex 作用域,各菜单浮层也挂在其内 */
|
|
29
28
|
const XhMenubarRoot = defineComponent({
|
|
30
29
|
name: "XhMenubarRoot",
|
|
31
30
|
props: {
|
|
@@ -75,7 +74,11 @@ const XhMenubarRoot = defineComponent({
|
|
|
75
74
|
value: ctx.api.value.value,
|
|
76
75
|
open: ctx.api.value.open,
|
|
77
76
|
setValue: ctx.api.value.setValue
|
|
78
|
-
}) : props.collection ? renderDefaultTree(ctx.api.value.collection,
|
|
77
|
+
}) : props.collection ? renderDefaultTree(ctx.api.value.collection, {
|
|
78
|
+
"item": slots.item,
|
|
79
|
+
"item-prefix": slots["item-prefix"],
|
|
80
|
+
"item-suffix": slots["item-suffix"]
|
|
81
|
+
}) : []);
|
|
79
82
|
}
|
|
80
83
|
});
|
|
81
84
|
const XhMenubarTrigger = defineComponent({
|
|
@@ -304,6 +307,24 @@ const XhMenubarItemDescription = defineComponent({
|
|
|
304
307
|
return () => h("span", ctx.api.value.getItemDescriptionProps(item.value), slots.default?.());
|
|
305
308
|
}
|
|
306
309
|
});
|
|
310
|
+
/** 条目中的快捷键提示,贴行尾;纯装饰,读屏从条目文字取意 */
|
|
311
|
+
const XhMenubarItemShortcut = defineComponent({
|
|
312
|
+
name: "XhMenubarItemShortcut",
|
|
313
|
+
setup(_, { slots }) {
|
|
314
|
+
const ctx = useMenubarContext();
|
|
315
|
+
const { item } = useMenubarItemContext();
|
|
316
|
+
return () => h("span", ctx.api.value.getItemShortcutProps(item.value), slots.default?.());
|
|
317
|
+
}
|
|
318
|
+
});
|
|
319
|
+
/** 条目行尾的作者内容(计数、徽标、次级图标);家族只管落位,不规定字号与颜色 */
|
|
320
|
+
const XhMenubarItemSuffix = defineComponent({
|
|
321
|
+
name: "XhMenubarItemSuffix",
|
|
322
|
+
setup(_, { slots }) {
|
|
323
|
+
const ctx = useMenubarContext();
|
|
324
|
+
const { item } = useMenubarItemContext();
|
|
325
|
+
return () => h("span", ctx.api.value.getItemSuffixProps(item.value), slots.default?.());
|
|
326
|
+
}
|
|
327
|
+
});
|
|
307
328
|
/** 指向本菜单锚点的箭头,纯装饰;须写在同一菜单的 positioner 中 */
|
|
308
329
|
const XhMenubarArrow = defineComponent({
|
|
309
330
|
name: "XhMenubarArrow",
|
|
@@ -326,33 +347,44 @@ const XhMenubarSeparator = defineComponent({
|
|
|
326
347
|
* 一排入口排在前、各自菜单的浮层排在后,与手写部件产出的 DOM 完全一致;
|
|
327
348
|
* 需要修改结构时写默认插槽,行为不变。
|
|
328
349
|
*/
|
|
329
|
-
function renderDefaultTree(collection,
|
|
350
|
+
function renderDefaultTree(collection, itemSlots) {
|
|
330
351
|
return [...collection.map((menu) => h(XhMenubarTrigger, {
|
|
331
352
|
key: `trigger:${menu.value}`,
|
|
332
353
|
value: menu.value
|
|
333
354
|
}, () => menu.label)), ...collection.map((menu) => h(XhMenubarPositioner, {
|
|
334
355
|
key: `positioner:${menu.value}`,
|
|
335
356
|
value: menu.value
|
|
336
|
-
}, () => [h(XhMenubarContent, null, () => renderNodes(menu.items,
|
|
357
|
+
}, () => [h(XhMenubarContent, null, () => renderNodes(menu.items, itemSlots))]))];
|
|
337
358
|
}
|
|
338
|
-
/**
|
|
339
|
-
|
|
359
|
+
/**
|
|
360
|
+
* 单个条目:文字在上,副文本在下,未提供副文本时不铺设该部件。
|
|
361
|
+
* `item-prefix` / `item-suffix` 插槽各接管首尾一格,其余槽照旧由数据铺。
|
|
362
|
+
*/
|
|
363
|
+
function renderNode(meta, itemSlots) {
|
|
364
|
+
const prefix = itemSlots["item-prefix"];
|
|
365
|
+
const suffix = itemSlots["item-suffix"];
|
|
340
366
|
return h(XhMenubarItem, {
|
|
341
367
|
key: meta.value,
|
|
342
368
|
value: meta.value
|
|
343
|
-
}, () => [
|
|
369
|
+
}, () => [
|
|
370
|
+
...prefix ? [h(XhMenubarItemIndicator, null, () => prefix(meta))] : [],
|
|
371
|
+
h(XhMenubarItemText, null, () => itemSlots.item?.(meta) ?? meta.label),
|
|
372
|
+
...meta.description != null ? [h(XhMenubarItemDescription, null, () => meta.description)] : [],
|
|
373
|
+
...meta.shortcut != null ? [h(XhMenubarItemShortcut, null, () => meta.shortcut)] : [],
|
|
374
|
+
...suffix ? [h(XhMenubarItemSuffix, null, () => suffix(meta))] : []
|
|
375
|
+
]);
|
|
344
376
|
}
|
|
345
377
|
/** content 的内容:分组段铺为 group,段首的分隔线落在 group 外面。 */
|
|
346
|
-
function renderNodes(collection,
|
|
378
|
+
function renderNodes(collection, itemSlots) {
|
|
347
379
|
return groupAdjacentRuns(collection, (node) => node.group).flatMap((run, runIndex) => {
|
|
348
380
|
const head = run[0];
|
|
349
381
|
const lead = runIndex > 0 && head.separatorBefore ? [h(XhMenubarSeparator, { key: `separator:${head.value}` })] : [];
|
|
350
|
-
if (head.group == null) return [...lead, renderNode(head,
|
|
382
|
+
if (head.group == null) return [...lead, renderNode(head, itemSlots)];
|
|
351
383
|
const groupLabel = run.find((node) => node.groupLabel != null)?.groupLabel ?? null;
|
|
352
384
|
return [...lead, h(XhMenubarGroup, {
|
|
353
385
|
key: `group:${head.group}`,
|
|
354
386
|
value: head.group
|
|
355
|
-
}, () => [...groupLabel != null ? [h(XhMenubarGroupLabel, null, () => groupLabel)] : [], ...run.flatMap((node, index) => [...index > 0 && node.separatorBefore ? [h(XhMenubarSeparator, { key: `separator:${node.value}` })] : [], renderNode(node,
|
|
387
|
+
}, () => [...groupLabel != null ? [h(XhMenubarGroupLabel, null, () => groupLabel)] : [], ...run.flatMap((node, index) => [...index > 0 && node.separatorBefore ? [h(XhMenubarSeparator, { key: `separator:${node.value}` })] : [], renderNode(node, itemSlots)])])];
|
|
356
388
|
});
|
|
357
389
|
}
|
|
358
390
|
const XhMenubarSub = defineComponent({
|
|
@@ -433,6 +465,6 @@ const XhMenubarSubTrigger = defineComponent({
|
|
|
433
465
|
}
|
|
434
466
|
});
|
|
435
467
|
//#endregion
|
|
436
|
-
export { XhMenubarArrow, XhMenubarContent, XhMenubarGroup, XhMenubarGroupLabel, XhMenubarItem, XhMenubarItemDescription, XhMenubarItemIndicator, XhMenubarItemText, XhMenubarPositioner, XhMenubarRoot, XhMenubarSeparator, XhMenubarSub, XhMenubarSubTrigger, XhMenubarTrigger };
|
|
468
|
+
export { XhMenubarArrow, XhMenubarContent, XhMenubarGroup, XhMenubarGroupLabel, XhMenubarItem, XhMenubarItemDescription, XhMenubarItemIndicator, XhMenubarItemShortcut, XhMenubarItemSuffix, XhMenubarItemText, XhMenubarPositioner, XhMenubarRoot, XhMenubarSeparator, XhMenubarSub, XhMenubarSubTrigger, XhMenubarTrigger };
|
|
437
469
|
|
|
438
470
|
//# sourceMappingURL=menubar.js.map
|