@gx-design-vue/pro-layout 0.1.0-alpha.20 → 0.1.0-alpha.21
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/dist/ProLayout.js +1 -1
- package/dist/components/Breadcrumb/index.js +3 -2
- package/dist/components/Breadcrumb/interface.d.ts +1 -1
- package/dist/components/Header/index.js +6 -14
- package/dist/components/Logo/index.js +6 -1
- package/dist/components/Menu/iconRender.d.ts +1 -1
- package/dist/components/Menu/iconRender.js +1 -1
- package/dist/components/Menu/index.d.ts +9 -10
- package/dist/components/Menu/index.js +670 -114
- package/dist/components/Menu/interface.d.ts +11 -11
- package/dist/components/Menu/interface.js +3 -3
- package/dist/components/Menu/overflow.d.ts +39 -0
- package/dist/components/Menu/overflow.js +81 -0
- package/dist/components/Menu/style/base.d.ts +12 -0
- package/dist/components/Menu/style/base.js +36 -0
- package/dist/components/Menu/style/horizontal.d.ts +19 -0
- package/dist/components/Menu/style/horizontal.js +303 -0
- package/dist/components/Menu/style/{siderMenu.d.ts → index.d.ts} +64 -5
- package/dist/components/Menu/style/index.js +147 -0
- package/dist/components/Menu/style/inline.d.ts +13 -0
- package/dist/components/Menu/style/{siderMenu.js → inline.js} +29 -115
- package/dist/components/PageContainer/index.js +2 -2
- package/dist/components/PageContainer/style.js +9 -6
- package/dist/components/Sider/index.js +18 -11
- package/dist/defaultConfig.js +1 -2
- package/dist/hooks/useLayoutBase.d.ts +15 -15
- package/dist/hooks/useMenu.d.ts +5 -5
- package/dist/hooks/useMenu.js +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.js +3 -3
- package/dist/interface.d.ts +2 -6
- package/dist/interface.js +2 -2
- package/dist/pro-layout.esm.js +4777 -4469
- package/dist/pro-layout.js +3 -2
- package/dist/style/breadcrumb.js +2 -1
- package/dist/style/logo.js +6 -1
- package/dist/style/menu.d.ts +1 -1
- package/dist/style/menu.js +1 -1
- package/dist/theme/augment.d.ts +2 -2
- package/dist/theme/interface/components.d.ts +2 -2
- package/dist/utils/menu.d.ts +3 -3
- package/dist/utils/menu.js +2 -2
- package/dist/utils/themeComponents.d.ts +8 -4
- package/dist/utils/themeComponents.js +14 -4
- package/package.json +15 -15
- package/dist/components/Menu/SiderMenu.d.ts +0 -29
- package/dist/components/Menu/SiderMenu.js +0 -666
- package/dist/components/Menu/convert.d.ts +0 -14
- package/dist/components/Menu/convert.js +0 -50
|
@@ -1,156 +1,622 @@
|
|
|
1
1
|
import { useLayoutBase } from "../../hooks/useLayoutBase.js";
|
|
2
2
|
import { renderMenuIcon } from "./iconRender.js";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import
|
|
3
|
+
import { buildHeaderProMenuTokens, buildSiderProMenuTokens } from "../../utils/themeComponents.js";
|
|
4
|
+
import { PRO_MENU_SLOT_KEYS } from "./interface.js";
|
|
5
|
+
import { useMenuOverflow } from "./overflow.js";
|
|
6
|
+
import style_default from "./style/index.js";
|
|
7
|
+
import { Transition, computed, createTextVNode, createVNode, defineComponent, isVNode, mergeProps, nextTick, onBeforeUnmount, ref, vShow, watch, withDirectives } from "vue";
|
|
7
8
|
import { useProToken } from "@gx-design-vue/pro-provider";
|
|
8
9
|
import { classNames, getSlotsProps } from "@gx-design-vue/pro-utils";
|
|
9
|
-
import { ConfigProvider,
|
|
10
|
+
import { ConfigProvider, Popover, Tooltip } from "antdv-next";
|
|
11
|
+
import { useBaseConfig } from "antdv-next/config-provider/context";
|
|
12
|
+
import useCSSVarCls from "antdv-next/config-provider/hooks/useCSSVarCls";
|
|
13
|
+
import { omit } from "es-toolkit";
|
|
10
14
|
//#region src/components/Menu/index.tsx
|
|
11
|
-
|
|
15
|
+
function _isSlot(s) {
|
|
16
|
+
return typeof s === "function" || Object.prototype.toString.call(s) === "[object Object]" && !isVNode(s);
|
|
17
|
+
}
|
|
18
|
+
const DEFAULT_INLINE_INDENT = 24;
|
|
19
|
+
const POPUP_CLOSE_DELAY = 120;
|
|
20
|
+
/** horizontal 模式溢出「...」submenu 的合成 key */
|
|
21
|
+
const OVERFLOW_MENU_KEY = "__overflow__";
|
|
22
|
+
/** horizontal 模式溢出隐藏态:脱离文档流(不挤占可见项)但保留 offsetWidth 可测(参考 @v-c/overflow Item) */
|
|
23
|
+
const OVERFLOW_HIDDEN_STYLE = {
|
|
24
|
+
opacity: 0,
|
|
25
|
+
position: "absolute",
|
|
26
|
+
height: 0,
|
|
27
|
+
overflow: "hidden",
|
|
28
|
+
pointerEvents: "none"
|
|
29
|
+
};
|
|
30
|
+
const SIDER_POPUP_BUILTIN_PLACEMENTS = { rightTop: {
|
|
31
|
+
points: ["tl", "tr"],
|
|
32
|
+
offset: [0, 0],
|
|
33
|
+
overflow: {
|
|
34
|
+
adjustX: true,
|
|
35
|
+
adjustY: true
|
|
36
|
+
},
|
|
37
|
+
autoArrow: false
|
|
38
|
+
} };
|
|
39
|
+
const SIDER_NESTED_POPUP_BUILTIN_PLACEMENTS = { rightTop: {
|
|
40
|
+
points: ["tl", "tr"],
|
|
41
|
+
offset: [-4, 0],
|
|
42
|
+
overflow: {
|
|
43
|
+
adjustX: true,
|
|
44
|
+
adjustY: true
|
|
45
|
+
},
|
|
46
|
+
autoArrow: false
|
|
47
|
+
} };
|
|
48
|
+
/** horizontal 模式一级子菜单向下展开(bottomLeft),参考 vue-components placements.ts */
|
|
49
|
+
const HEADER_POPUP_BUILTIN_PLACEMENTS = { bottomLeft: {
|
|
50
|
+
points: ["tl", "bl"],
|
|
51
|
+
offset: [0, 0],
|
|
52
|
+
overflow: {
|
|
53
|
+
adjustX: true,
|
|
54
|
+
adjustY: true
|
|
55
|
+
},
|
|
56
|
+
autoArrow: false
|
|
57
|
+
} };
|
|
58
|
+
let hasProMenuInitialAutoScrolled = false;
|
|
59
|
+
function isPathPrefix(prefix, path) {
|
|
60
|
+
return prefix.length <= path.length && prefix.every((key, index) => key === path[index]);
|
|
61
|
+
}
|
|
62
|
+
function isSamePath(path, target) {
|
|
63
|
+
return path.length === target.length && isPathPrefix(path, target);
|
|
64
|
+
}
|
|
65
|
+
function getPathKey(path) {
|
|
66
|
+
return path.join("\0");
|
|
67
|
+
}
|
|
12
68
|
function getMenuTitleSymbol(title) {
|
|
13
69
|
return title ? title.charAt(0).toUpperCase() : null;
|
|
14
70
|
}
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
function
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
71
|
+
function getVisibleChildren(route) {
|
|
72
|
+
return route.children?.filter((child) => !child.meta?.hideInMenu) ?? [];
|
|
73
|
+
}
|
|
74
|
+
function hasSelectedDescendant(route, selectedKeys) {
|
|
75
|
+
if (selectedKeys.has(route.name)) return true;
|
|
76
|
+
return getVisibleChildren(route).some((child) => hasSelectedDescendant(child, selectedKeys));
|
|
77
|
+
}
|
|
78
|
+
function toMenuRenderItem(route, type) {
|
|
79
|
+
return {
|
|
80
|
+
key: route.name,
|
|
81
|
+
label: route.meta?.title,
|
|
82
|
+
icon: route.meta?.icon,
|
|
83
|
+
disabled: route.meta?.disabled,
|
|
84
|
+
title: route.meta?.title,
|
|
85
|
+
type,
|
|
86
|
+
route
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
function getMenuRenderItemIcon(item, route) {
|
|
90
|
+
return item.icon ?? route.meta?.icon;
|
|
91
|
+
}
|
|
92
|
+
function resetCollapseStyle(el) {
|
|
93
|
+
el.style.maxHeight = "";
|
|
94
|
+
el.style.overflow = el.dataset.oldOverflow ?? "";
|
|
29
95
|
}
|
|
30
96
|
/**
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
* 直接吃路由分支 `menus`,内部经 `buildMenuItems` 转 antdv-next 菜单项;
|
|
34
|
-
* 视觉定制通过 `menuItemIcon`/`menuItemLabel`/`menuItemExtra`(prop 或同名 slot,prop 优先)
|
|
35
|
-
* 注入 antdv-next 的 `iconRender`/`labelRender`/`extraRender`。可脱离 GProLayout 独立使用。
|
|
97
|
+
* Vue 3 <Transition> 在 JSX 中只认 onXxx 前缀的 props。
|
|
98
|
+
* 参考 Vue 源码 getTransitionRawProps —— 只收集 key.startsWith('on') 的函数。
|
|
36
99
|
*/
|
|
37
|
-
const
|
|
38
|
-
|
|
100
|
+
const collapseTransitionHooks = {
|
|
101
|
+
onBeforeEnter(el) {
|
|
102
|
+
const target = el;
|
|
103
|
+
target.dataset.oldOverflow = target.style.overflow;
|
|
104
|
+
target.style.maxHeight = "0";
|
|
105
|
+
target.style.overflow = "hidden";
|
|
106
|
+
},
|
|
107
|
+
onEnter(el) {
|
|
108
|
+
const target = el;
|
|
109
|
+
requestAnimationFrame(() => {
|
|
110
|
+
target.style.maxHeight = target.scrollHeight === 0 ? "0" : `${target.scrollHeight}px`;
|
|
111
|
+
target.style.overflow = "hidden";
|
|
112
|
+
});
|
|
113
|
+
},
|
|
114
|
+
onAfterEnter(el) {
|
|
115
|
+
resetCollapseStyle(el);
|
|
116
|
+
},
|
|
117
|
+
onEnterCancelled(el) {
|
|
118
|
+
resetCollapseStyle(el);
|
|
119
|
+
},
|
|
120
|
+
onBeforeLeave(el) {
|
|
121
|
+
const target = el;
|
|
122
|
+
target.dataset.oldOverflow = target.style.overflow;
|
|
123
|
+
target.style.maxHeight = `${target.scrollHeight}px`;
|
|
124
|
+
target.style.overflow = "hidden";
|
|
125
|
+
},
|
|
126
|
+
onLeave(el) {
|
|
127
|
+
const target = el;
|
|
128
|
+
if (target.scrollHeight !== 0) target.style.maxHeight = "0";
|
|
129
|
+
},
|
|
130
|
+
onAfterLeave(el) {
|
|
131
|
+
resetCollapseStyle(el);
|
|
132
|
+
},
|
|
133
|
+
onLeaveCancelled(el) {
|
|
134
|
+
resetCollapseStyle(el);
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
const ProMenuContent = /* @__PURE__ */ defineComponent((props, { emit, slots }) => {
|
|
138
|
+
const { proClasses, proStyles, collapsed } = useLayoutBase(props);
|
|
139
|
+
const { prefixCls } = useBaseConfig("pro-menu", props);
|
|
140
|
+
const rootCls = useCSSVarCls(prefixCls);
|
|
141
|
+
const [hashId, cssVarCls] = style_default(prefixCls, rootCls);
|
|
39
142
|
const { proLayoutToken } = useProToken();
|
|
40
143
|
const mode = computed(() => props.mode ?? (props.placement === "header" ? "horizontal" : "inline"));
|
|
41
|
-
const
|
|
42
|
-
const
|
|
43
|
-
const
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
const
|
|
51
|
-
const
|
|
52
|
-
|
|
144
|
+
const isHorizontal = computed(() => mode.value === "horizontal");
|
|
145
|
+
const inlineCollapsed = computed(() => !isHorizontal.value && collapsed.value);
|
|
146
|
+
const popupOpenPath = ref([]);
|
|
147
|
+
const menuRef = ref();
|
|
148
|
+
const overflow = useMenuOverflow({
|
|
149
|
+
enabled: isHorizontal,
|
|
150
|
+
totalCount: computed(() => (props.menus ?? []).filter((route) => !route.meta?.hideInMenu).length)
|
|
151
|
+
});
|
|
152
|
+
const hasInitialScrolled = ref(false);
|
|
153
|
+
const popupCloseTimers = /* @__PURE__ */ new Map();
|
|
154
|
+
const pendingPopupCloseKeys = /* @__PURE__ */ new Set();
|
|
155
|
+
let initialScrollFrame;
|
|
156
|
+
const selectedKeySet = computed(() => new Set(props.selectedKeys ?? []));
|
|
157
|
+
const openKeySet = computed(() => new Set(props.openKeys ?? []));
|
|
53
158
|
const customRenders = computed(() => getSlotsProps({
|
|
54
159
|
slots,
|
|
55
160
|
props,
|
|
56
|
-
keys:
|
|
161
|
+
keys: PRO_MENU_SLOT_KEYS,
|
|
57
162
|
render: false
|
|
58
163
|
}));
|
|
59
|
-
|
|
60
|
-
|
|
164
|
+
const menuClassNames = computed(() => classNames(`${prefixCls.value}`, `${prefixCls.value}-root`, proClasses.value.menu, hashId.value, cssVarCls.value, rootCls.value, {
|
|
165
|
+
[`${prefixCls.value}-collapsed`]: inlineCollapsed.value,
|
|
166
|
+
[`${prefixCls.value}-inline`]: !isHorizontal.value,
|
|
167
|
+
[`${prefixCls.value}-horizontal`]: isHorizontal.value
|
|
168
|
+
}, props.class));
|
|
169
|
+
const popupClassName = computed(() => classNames(`${prefixCls.value}-popover`, hashId.value, cssVarCls.value, rootCls.value));
|
|
170
|
+
function isPopupInteraction(ctx) {
|
|
171
|
+
return inlineCollapsed.value || ctx.popup;
|
|
172
|
+
}
|
|
173
|
+
function getPopupPath(route, ctx) {
|
|
174
|
+
return ctx.popup ? [...ctx.popupPath, route.name] : [route.name];
|
|
175
|
+
}
|
|
176
|
+
function isPopupPathOpen(path) {
|
|
177
|
+
return isPathPrefix(path, popupOpenPath.value);
|
|
178
|
+
}
|
|
179
|
+
function isSubMenuOpen(route, ctx) {
|
|
180
|
+
if (ctx.popup) return isPopupPathOpen(getPopupPath(route, ctx));
|
|
181
|
+
if (inlineCollapsed.value && ctx.depth === 0) return isPopupPathOpen([route.name]);
|
|
182
|
+
return openKeySet.value.has(route.name);
|
|
183
|
+
}
|
|
184
|
+
function getInlineIndent(route, ctx) {
|
|
185
|
+
return route.meta?.inlineIndent ?? ctx.inlineIndent;
|
|
186
|
+
}
|
|
187
|
+
function getItemStyle(route, ctx) {
|
|
188
|
+
const indent = getInlineIndent(route, ctx);
|
|
189
|
+
return {
|
|
190
|
+
"--pro-menu-level": ctx.depth,
|
|
191
|
+
"--pro-menu-indent": `${indent}px`
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
function emitOpenKeys(nextKeys) {
|
|
195
|
+
emit("openChange", nextKeys);
|
|
196
|
+
emit("update:openKeys", nextKeys);
|
|
197
|
+
}
|
|
198
|
+
function cancelPopupClose(path) {
|
|
199
|
+
(path ? Array.from({ length: path.length }, (_, index) => getPathKey(path.slice(0, index + 1))) : Array.from(popupCloseTimers.keys())).forEach((key) => {
|
|
200
|
+
const timer = popupCloseTimers.get(key);
|
|
201
|
+
if (timer !== void 0) {
|
|
202
|
+
clearTimeout(timer);
|
|
203
|
+
popupCloseTimers.delete(key);
|
|
204
|
+
}
|
|
205
|
+
pendingPopupCloseKeys.delete(key);
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
function openPopupPath(path) {
|
|
209
|
+
cancelPopupClose(path);
|
|
210
|
+
popupOpenPath.value = path;
|
|
211
|
+
}
|
|
212
|
+
function closePopupPath(path) {
|
|
213
|
+
const key = getPathKey(path);
|
|
214
|
+
pendingPopupCloseKeys.delete(key);
|
|
215
|
+
if (isSamePath(path, popupOpenPath.value)) {
|
|
216
|
+
const nextPath = path.slice(0, -1);
|
|
217
|
+
popupOpenPath.value = nextPath;
|
|
218
|
+
const nextKey = getPathKey(nextPath);
|
|
219
|
+
if (nextPath.length > 0 && pendingPopupCloseKeys.has(nextKey)) closePopupPath(nextPath);
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
if (isPathPrefix(path, popupOpenPath.value)) pendingPopupCloseKeys.add(key);
|
|
223
|
+
}
|
|
224
|
+
function schedulePopupPathClose(path) {
|
|
225
|
+
const key = getPathKey(path);
|
|
226
|
+
cancelPopupClose(path);
|
|
227
|
+
const timer = setTimeout(() => {
|
|
228
|
+
popupCloseTimers.delete(key);
|
|
229
|
+
closePopupPath(path);
|
|
230
|
+
}, POPUP_CLOSE_DELAY);
|
|
231
|
+
popupCloseTimers.set(key, timer);
|
|
232
|
+
}
|
|
233
|
+
function clearPopupPath() {
|
|
234
|
+
cancelPopupClose();
|
|
235
|
+
pendingPopupCloseKeys.clear();
|
|
236
|
+
popupOpenPath.value = [];
|
|
61
237
|
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
if (
|
|
238
|
+
function handleSubMenuClick(route, ctx) {
|
|
239
|
+
if (route.meta?.disabled) return;
|
|
240
|
+
if (isPopupInteraction(ctx)) {
|
|
241
|
+
openPopupPath(getPopupPath(route, ctx));
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
emitOpenKeys(openKeySet.value.has(route.name) ? (props.openKeys ?? []).filter((key) => key !== route.name) : [...props.openKeys ?? [], route.name]);
|
|
245
|
+
}
|
|
246
|
+
function handleItemClick(route, ctx) {
|
|
247
|
+
if (route.meta?.disabled) return;
|
|
248
|
+
const keyPath = [route.name, ...ctx.parentKeys].filter(Boolean);
|
|
249
|
+
const selectedKeys = [route.name];
|
|
250
|
+
emit("select", {
|
|
251
|
+
key: route.name,
|
|
252
|
+
keys: selectedKeys,
|
|
253
|
+
keyPath,
|
|
254
|
+
route
|
|
255
|
+
});
|
|
256
|
+
emit("update:selectedKeys", selectedKeys);
|
|
257
|
+
if (ctx.popup) clearPopupPath();
|
|
258
|
+
}
|
|
259
|
+
function handleKeydown(event, action) {
|
|
260
|
+
if (event.key !== "Enter" && event.key !== " ") return;
|
|
261
|
+
event.preventDefault();
|
|
262
|
+
action();
|
|
263
|
+
}
|
|
264
|
+
function scrollSelectedIntoView() {
|
|
265
|
+
if (hasInitialScrolled.value || hasProMenuInitialAutoScrolled || inlineCollapsed.value) return;
|
|
266
|
+
const menuEl = menuRef.value;
|
|
267
|
+
if (!menuEl) return;
|
|
268
|
+
const scrollContainer = props.getScrollContainer?.() ?? menuEl.closest(`.${prefixCls.value}-container`);
|
|
269
|
+
const selectedItem = menuEl.querySelector(`.${prefixCls.value}-item-selected`);
|
|
270
|
+
if (!scrollContainer || !selectedItem) return;
|
|
271
|
+
hasInitialScrolled.value = true;
|
|
272
|
+
hasProMenuInitialAutoScrolled = true;
|
|
273
|
+
const containerRect = scrollContainer.getBoundingClientRect();
|
|
274
|
+
const selectedRect = selectedItem.getBoundingClientRect();
|
|
275
|
+
if (selectedRect.top >= containerRect.top && selectedRect.bottom <= containerRect.bottom) return;
|
|
276
|
+
const nextTop = selectedRect.top - containerRect.top + scrollContainer.scrollTop - scrollContainer.clientHeight / 2 + selectedItem.offsetHeight / 2;
|
|
277
|
+
scrollContainer.scrollTo({
|
|
278
|
+
top: Math.max(0, nextTop),
|
|
279
|
+
behavior: "auto"
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
function scheduleInitialScroll() {
|
|
283
|
+
if (hasInitialScrolled.value || hasProMenuInitialAutoScrolled) return;
|
|
284
|
+
nextTick(() => {
|
|
285
|
+
if (hasInitialScrolled.value || hasProMenuInitialAutoScrolled) return;
|
|
286
|
+
if (initialScrollFrame !== void 0) cancelAnimationFrame(initialScrollFrame);
|
|
287
|
+
initialScrollFrame = requestAnimationFrame(() => {
|
|
288
|
+
initialScrollFrame = void 0;
|
|
289
|
+
scrollSelectedIntoView();
|
|
290
|
+
});
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
watch(() => [
|
|
294
|
+
props.menus?.length ?? 0,
|
|
295
|
+
props.selectedKeys?.join("|") ?? "",
|
|
296
|
+
props.openKeys?.join("|") ?? ""
|
|
297
|
+
], scheduleInitialScroll, {
|
|
298
|
+
immediate: true,
|
|
299
|
+
flush: "post"
|
|
300
|
+
});
|
|
301
|
+
onBeforeUnmount(() => {
|
|
302
|
+
if (initialScrollFrame !== void 0) cancelAnimationFrame(initialScrollFrame);
|
|
303
|
+
cancelPopupClose();
|
|
304
|
+
});
|
|
305
|
+
function renderIcon(route, item, firstLevelCollapsed) {
|
|
306
|
+
if (customRenders.value.menuItemIcon) return customRenders.value.menuItemIcon({
|
|
65
307
|
item,
|
|
66
308
|
route
|
|
67
309
|
});
|
|
68
|
-
const icon = renderMenuIcon(item
|
|
69
|
-
const iconNode = !icon &&
|
|
310
|
+
const icon = renderMenuIcon(getMenuRenderItemIcon(item, route));
|
|
311
|
+
const iconNode = !icon && firstLevelCollapsed ? getMenuTitleSymbol(route.meta?.title) : icon;
|
|
70
312
|
if (!iconNode) return null;
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
"class": iconClass,
|
|
75
|
-
"style": iconStyle
|
|
313
|
+
return createVNode("span", {
|
|
314
|
+
"class": classNames(`${prefixCls.value}-icon`, route.meta?.classNames?.itemIcon),
|
|
315
|
+
"style": route.meta?.styles?.itemIcon
|
|
76
316
|
}, [iconNode]);
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
const route = getRouteFromItem(item);
|
|
81
|
-
if (customRenders.value.menuItemLabel && route) return customRenders.value.menuItemLabel({
|
|
317
|
+
}
|
|
318
|
+
function renderLabel(route, item) {
|
|
319
|
+
const label = customRenders.value.menuItemLabel ? customRenders.value.menuItemLabel({
|
|
82
320
|
item,
|
|
83
321
|
route
|
|
84
|
-
})
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
const textClass = route?.meta?.classNames?.itemTitleText;
|
|
88
|
-
const textStyle = route?.meta?.styles?.itemTitleText;
|
|
89
|
-
const label = textClass || textStyle ? createVNode("span", {
|
|
90
|
-
"class": textClass,
|
|
91
|
-
"style": textStyle
|
|
322
|
+
}) : route.meta?.classNames?.itemTitleText || route.meta?.styles?.itemTitleText ? createVNode("span", {
|
|
323
|
+
"class": route.meta?.classNames?.itemTitleText,
|
|
324
|
+
"style": route.meta?.styles?.itemTitleText
|
|
92
325
|
}, [item.label]) : item.label;
|
|
93
|
-
|
|
94
|
-
"class":
|
|
95
|
-
"style":
|
|
326
|
+
return createVNode("span", {
|
|
327
|
+
"class": classNames(`${prefixCls.value}-title`, route.meta?.classNames?.itemTitle),
|
|
328
|
+
"style": route.meta?.styles?.itemTitle
|
|
96
329
|
}, [label]);
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
const route = getRouteFromItem(item);
|
|
101
|
-
if (customRenders.value.menuItemExtra && route) return customRenders.value.menuItemExtra({
|
|
330
|
+
}
|
|
331
|
+
function renderExtra(route, item) {
|
|
332
|
+
if (customRenders.value.menuItemExtra) return customRenders.value.menuItemExtra({
|
|
102
333
|
item,
|
|
103
334
|
route
|
|
104
335
|
});
|
|
105
|
-
if (route
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
336
|
+
if (!route.meta?.rightContent) return null;
|
|
337
|
+
const extra = route.meta.rightContent(route.meta);
|
|
338
|
+
if (extra == null || extra === false) return null;
|
|
339
|
+
return createVNode("span", {
|
|
340
|
+
"class": classNames(`${prefixCls.value}-extra`, route.meta.classNames?.itemRight),
|
|
341
|
+
"style": route.meta.styles?.itemRight
|
|
342
|
+
}, [extra]);
|
|
343
|
+
}
|
|
344
|
+
function renderMenuItem(route, ctx) {
|
|
345
|
+
const item = toMenuRenderItem(route, "item");
|
|
346
|
+
const firstLevelCollapsed = inlineCollapsed.value && !ctx.popup && ctx.depth === 0;
|
|
347
|
+
const selected = selectedKeySet.value.has(route.name);
|
|
348
|
+
const disabled = !!route.meta?.disabled;
|
|
349
|
+
const showCollapsedTooltip = firstLevelCollapsed && !!route.meta?.title;
|
|
350
|
+
const itemNode = createVNode("div", {
|
|
351
|
+
"class": classNames(`${prefixCls.value}-item`, route.meta?.classNames?.item, {
|
|
352
|
+
[`${prefixCls.value}-item-selected`]: selected,
|
|
353
|
+
[`${prefixCls.value}-item-disabled`]: disabled,
|
|
354
|
+
[`${prefixCls.value}-item-collapsed`]: firstLevelCollapsed
|
|
355
|
+
}),
|
|
356
|
+
"style": {
|
|
357
|
+
...getItemStyle(route, ctx),
|
|
358
|
+
...route.meta?.styles?.item
|
|
359
|
+
},
|
|
360
|
+
"role": "menuitem",
|
|
361
|
+
"tabindex": disabled ? -1 : 0,
|
|
362
|
+
"onClick": () => handleItemClick(route, ctx),
|
|
363
|
+
"onKeydown": (event) => handleKeydown(event, () => handleItemClick(route, ctx))
|
|
364
|
+
}, [
|
|
365
|
+
renderIcon(route, item, firstLevelCollapsed),
|
|
366
|
+
!firstLevelCollapsed && renderLabel(route, item),
|
|
367
|
+
!firstLevelCollapsed && renderExtra(route, item)
|
|
368
|
+
]);
|
|
369
|
+
return createVNode("li", {
|
|
370
|
+
"key": route.name,
|
|
371
|
+
"class": `${prefixCls.value}-node`,
|
|
372
|
+
"data-overflow-item": ctx.overflowTopLevel ? "" : void 0,
|
|
373
|
+
"style": ctx.overflowHidden ? OVERFLOW_HIDDEN_STYLE : void 0,
|
|
374
|
+
"role": "none"
|
|
375
|
+
}, [showCollapsedTooltip ? createVNode(Tooltip, {
|
|
376
|
+
"title": route.meta?.title,
|
|
377
|
+
"placement": "right",
|
|
378
|
+
"classes": { root: `${prefixCls.value}-inline-collapsed-tooltip` }
|
|
379
|
+
}, _isSlot(itemNode) ? itemNode : { default: () => [itemNode] }) : itemNode]);
|
|
380
|
+
}
|
|
381
|
+
function renderSubMenuTitle(route, ctx, opened, active) {
|
|
382
|
+
const item = toMenuRenderItem(route, "submenu");
|
|
383
|
+
const firstLevelCollapsed = inlineCollapsed.value && !ctx.popup && ctx.depth === 0;
|
|
384
|
+
const disabled = !!route.meta?.disabled;
|
|
385
|
+
return createVNode("div", {
|
|
386
|
+
"class": classNames(`${prefixCls.value}-item`, `${prefixCls.value}-submenu-title`, {
|
|
387
|
+
[`${prefixCls.value}-item-open`]: opened,
|
|
388
|
+
[`${prefixCls.value}-item-active`]: active,
|
|
389
|
+
[`${prefixCls.value}-item-disabled`]: disabled,
|
|
390
|
+
[`${prefixCls.value}-item-collapsed`]: firstLevelCollapsed,
|
|
391
|
+
[`${prefixCls.value}-submenu-title-popup`]: ctx.popup
|
|
392
|
+
}),
|
|
393
|
+
"style": getItemStyle(route, ctx),
|
|
394
|
+
"role": "menuitem",
|
|
395
|
+
"aria-expanded": opened,
|
|
396
|
+
"tabindex": disabled ? -1 : 0,
|
|
397
|
+
"title": firstLevelCollapsed ? route.meta?.title : void 0,
|
|
398
|
+
"onClick": () => handleSubMenuClick(route, ctx),
|
|
399
|
+
"onKeydown": (event) => handleKeydown(event, () => handleSubMenuClick(route, ctx))
|
|
400
|
+
}, [
|
|
401
|
+
renderIcon(route, item, firstLevelCollapsed),
|
|
402
|
+
!firstLevelCollapsed && renderLabel(route, item),
|
|
403
|
+
!firstLevelCollapsed && renderExtra(route, item),
|
|
404
|
+
!firstLevelCollapsed && createVNode("i", { "class": `${prefixCls.value}-arrow` }, null)
|
|
405
|
+
]);
|
|
406
|
+
}
|
|
407
|
+
function renderSubMenu(route, children, ctx) {
|
|
408
|
+
let _slot;
|
|
409
|
+
const opened = isSubMenuOpen(route, ctx);
|
|
410
|
+
const active = hasSelectedDescendant(route, selectedKeySet.value);
|
|
411
|
+
const disabled = !!route.meta?.disabled;
|
|
412
|
+
const titleNode = renderSubMenuTitle(route, ctx, opened, active);
|
|
413
|
+
const popupPlacement = ctx.horizontal && ctx.depth === 0 && !ctx.popup ? "bottomLeft" : "rightTop";
|
|
414
|
+
const popupBuiltinPlacements = popupPlacement === "bottomLeft" ? HEADER_POPUP_BUILTIN_PLACEMENTS : ctx.popup ? SIDER_NESTED_POPUP_BUILTIN_PLACEMENTS : SIDER_POPUP_BUILTIN_PLACEMENTS;
|
|
415
|
+
const usePopup = ctx.popup || !ctx.popup && ctx.depth === 0 && (inlineCollapsed.value || ctx.horizontal);
|
|
416
|
+
const nextCtx = {
|
|
417
|
+
depth: ctx.depth + 1,
|
|
418
|
+
parentKeys: [route.name, ...ctx.parentKeys],
|
|
419
|
+
popup: ctx.popup,
|
|
420
|
+
popupPath: ctx.popupPath,
|
|
421
|
+
inlineIndent: getInlineIndent(route, ctx),
|
|
422
|
+
horizontal: ctx.horizontal
|
|
423
|
+
};
|
|
424
|
+
if (usePopup) {
|
|
425
|
+
const popupPath = getPopupPath(route, ctx);
|
|
426
|
+
const popoverOpen = isPopupPathOpen(popupPath);
|
|
427
|
+
return createVNode("li", {
|
|
428
|
+
"key": route.name,
|
|
429
|
+
"class": classNames(`${prefixCls.value}-node`, `${prefixCls.value}-submenu`, route.meta?.classNames?.subMenu, {
|
|
430
|
+
[`${prefixCls.value}-submenu-open`]: popoverOpen,
|
|
431
|
+
[`${prefixCls.value}-submenu-active`]: active
|
|
432
|
+
}),
|
|
433
|
+
"data-overflow-item": ctx.overflowTopLevel ? "" : void 0,
|
|
434
|
+
"style": {
|
|
435
|
+
...ctx.overflowHidden ? OVERFLOW_HIDDEN_STYLE : null,
|
|
436
|
+
...route.meta?.styles?.subMenu
|
|
437
|
+
},
|
|
438
|
+
"role": "none"
|
|
439
|
+
}, [createVNode(Popover, {
|
|
440
|
+
"trigger": "hover",
|
|
441
|
+
"placement": popupPlacement,
|
|
442
|
+
"builtinPlacements": popupBuiltinPlacements,
|
|
443
|
+
"arrow": false,
|
|
444
|
+
"open": popoverOpen,
|
|
445
|
+
"classes": {
|
|
446
|
+
root: classNames(popupClassName.value, `${prefixCls.value}-submenu-placement-${popupPlacement}`, `${prefixCls.value}-${ctx.horizontal ? "horizontal" : "inline"}-popover`, { [`${prefixCls.value}-submenu-placement-nested`]: ctx.popup }, route.meta?.classNames?.subMenuPopup),
|
|
447
|
+
container: `${prefixCls.value}-popover-container`,
|
|
448
|
+
content: `${prefixCls.value}-popover-content`
|
|
449
|
+
},
|
|
450
|
+
"onOpenChange": (open) => {
|
|
451
|
+
if (disabled) return;
|
|
452
|
+
if (open) openPopupPath(popupPath);
|
|
453
|
+
else schedulePopupPathClose(popupPath);
|
|
454
|
+
}
|
|
455
|
+
}, {
|
|
456
|
+
default: () => [titleNode],
|
|
457
|
+
content: () => createVNode("div", { "class": `${prefixCls.value}-submenu-popup` }, [renderMenuList(children, {
|
|
458
|
+
depth: 0,
|
|
459
|
+
parentKeys: [route.name, ...ctx.parentKeys],
|
|
460
|
+
popup: true,
|
|
461
|
+
popupPath,
|
|
462
|
+
inlineIndent: getInlineIndent(route, ctx),
|
|
463
|
+
horizontal: ctx.horizontal
|
|
464
|
+
})])
|
|
465
|
+
})]);
|
|
112
466
|
}
|
|
113
|
-
return
|
|
114
|
-
|
|
467
|
+
return createVNode("li", {
|
|
468
|
+
"key": route.name,
|
|
469
|
+
"class": classNames(`${prefixCls.value}-node`, `${prefixCls.value}-submenu`, route.meta?.classNames?.subMenu, {
|
|
470
|
+
[`${prefixCls.value}-submenu-open`]: opened,
|
|
471
|
+
[`${prefixCls.value}-submenu-active`]: active
|
|
472
|
+
}),
|
|
473
|
+
"style": route.meta?.styles?.subMenu,
|
|
474
|
+
"role": "none"
|
|
475
|
+
}, [titleNode, createVNode(Transition, mergeProps({ "name": `${prefixCls.value}-collapse` }, collapseTransitionHooks), _isSlot(_slot = withDirectives(renderMenuList(children, nextCtx), [[vShow, opened]])) ? _slot : { default: () => [_slot] })]);
|
|
476
|
+
}
|
|
477
|
+
function renderGroup(route, children, ctx) {
|
|
478
|
+
const item = toMenuRenderItem(route, "group");
|
|
479
|
+
return createVNode("li", {
|
|
480
|
+
"key": route.name,
|
|
481
|
+
"class": classNames(`${prefixCls.value}-group`, route.meta?.classNames?.subMenu),
|
|
482
|
+
"style": route.meta?.styles?.subMenu,
|
|
483
|
+
"role": "presentation"
|
|
484
|
+
}, [createVNode("div", {
|
|
485
|
+
"class": `${prefixCls.value}-group-title`,
|
|
486
|
+
"style": getItemStyle(route, ctx)
|
|
487
|
+
}, [renderLabel(route, item)]), renderMenuList(children, {
|
|
488
|
+
depth: ctx.depth + 1,
|
|
489
|
+
parentKeys: [route.name, ...ctx.parentKeys],
|
|
490
|
+
popup: ctx.popup,
|
|
491
|
+
popupPath: ctx.popupPath,
|
|
492
|
+
inlineIndent: getInlineIndent(route, ctx),
|
|
493
|
+
horizontal: ctx.horizontal
|
|
494
|
+
})]);
|
|
495
|
+
}
|
|
496
|
+
function renderRoute(route, ctx) {
|
|
497
|
+
if (route.meta?.hideInMenu) return null;
|
|
498
|
+
const children = getVisibleChildren(route);
|
|
499
|
+
const divider = route.meta?.divider ? createVNode("li", {
|
|
500
|
+
"key": `${route.name}-divider`,
|
|
501
|
+
"class": `${prefixCls.value}-divider`,
|
|
502
|
+
"role": "separator"
|
|
503
|
+
}, null) : null;
|
|
504
|
+
const node = children.length > 0 ? route.meta?.menuItemType === "group" ? renderGroup(route, children, ctx) : renderSubMenu(route, children, ctx) : renderMenuItem(route, ctx);
|
|
505
|
+
return divider ? [divider, node] : node;
|
|
506
|
+
}
|
|
507
|
+
function renderMenuList(menus, ctx) {
|
|
508
|
+
return createVNode("ul", {
|
|
509
|
+
"class": classNames(`${prefixCls.value}`, {
|
|
510
|
+
[`${prefixCls.value}-inline`]: !ctx.horizontal,
|
|
511
|
+
[`${prefixCls.value}-horizontal`]: ctx.horizontal && !ctx.popup,
|
|
512
|
+
[`${prefixCls.value}-sub`]: ctx.depth > 0 || ctx.popup,
|
|
513
|
+
[`${prefixCls.value}-popup-list`]: ctx.popup,
|
|
514
|
+
[`${prefixCls.value}-${ctx.horizontal ? "horizontal" : "inline"}-popup-list`]: ctx.popup
|
|
515
|
+
}),
|
|
516
|
+
"role": ctx.popup ? "menu" : void 0
|
|
517
|
+
}, [menus.map((route) => renderRoute(route, ctx))]);
|
|
518
|
+
}
|
|
519
|
+
/** horizontal 模式溢出「...」触发器,popup 内容为被收起的一级项 */
|
|
520
|
+
function renderOverflowRest(allRoutes) {
|
|
521
|
+
const hiddenRoutes = overflow.hiddenIndexes.value.map((index) => allRoutes[index]).filter(Boolean);
|
|
522
|
+
if (hiddenRoutes.length === 0) return null;
|
|
523
|
+
const restActive = hiddenRoutes.some((route) => selectedKeySet.value.has(route.name) || hasSelectedDescendant(route, selectedKeySet.value));
|
|
524
|
+
const popupPath = [OVERFLOW_MENU_KEY];
|
|
525
|
+
const popoverOpen = isPopupPathOpen(popupPath);
|
|
526
|
+
return createVNode("li", {
|
|
527
|
+
"key": OVERFLOW_MENU_KEY,
|
|
528
|
+
"class": classNames(`${prefixCls.value}-node`, `${prefixCls.value}-submenu`, {
|
|
529
|
+
[`${prefixCls.value}-submenu-open`]: popoverOpen,
|
|
530
|
+
[`${prefixCls.value}-submenu-active`]: restActive
|
|
531
|
+
}),
|
|
532
|
+
"data-overflow-rest": "",
|
|
533
|
+
"role": "none"
|
|
534
|
+
}, [createVNode(Popover, {
|
|
535
|
+
"trigger": "hover",
|
|
536
|
+
"placement": "bottomLeft",
|
|
537
|
+
"builtinPlacements": HEADER_POPUP_BUILTIN_PLACEMENTS,
|
|
538
|
+
"arrow": false,
|
|
539
|
+
"open": popoverOpen,
|
|
540
|
+
"classes": {
|
|
541
|
+
root: classNames(popupClassName.value, `${prefixCls.value}-submenu-placement-bottomLeft`, `${prefixCls.value}-horizontal-popover`),
|
|
542
|
+
container: `${prefixCls.value}-popover-container`,
|
|
543
|
+
content: `${prefixCls.value}-popover-content`
|
|
544
|
+
},
|
|
545
|
+
"onOpenChange": (open) => {
|
|
546
|
+
if (open) openPopupPath(popupPath);
|
|
547
|
+
else schedulePopupPathClose(popupPath);
|
|
548
|
+
}
|
|
549
|
+
}, {
|
|
550
|
+
default: () => [createVNode("div", {
|
|
551
|
+
"class": classNames(`${prefixCls.value}-item`, `${prefixCls.value}-submenu-title`, { [`${prefixCls.value}-item-active`]: restActive }),
|
|
552
|
+
"role": "menuitem",
|
|
553
|
+
"tabindex": 0
|
|
554
|
+
}, [createVNode("span", { "class": `${prefixCls.value}-title` }, [createTextVNode("···")])])],
|
|
555
|
+
content: () => createVNode("div", { "class": `${prefixCls.value}-submenu-popup` }, [renderMenuList(hiddenRoutes, {
|
|
556
|
+
depth: 0,
|
|
557
|
+
parentKeys: [],
|
|
558
|
+
popup: true,
|
|
559
|
+
popupPath,
|
|
560
|
+
inlineIndent: DEFAULT_INLINE_INDENT,
|
|
561
|
+
horizontal: true
|
|
562
|
+
})])
|
|
563
|
+
})]);
|
|
564
|
+
}
|
|
115
565
|
return () => {
|
|
116
|
-
const
|
|
117
|
-
if (
|
|
118
|
-
|
|
566
|
+
const menus = props.menus ?? [];
|
|
567
|
+
if (menus.length === 0) return null;
|
|
568
|
+
if (!isHorizontal.value) return createVNode("ul", {
|
|
569
|
+
"ref": menuRef,
|
|
119
570
|
"class": menuClassNames.value,
|
|
120
571
|
"style": {
|
|
121
572
|
...props.style,
|
|
122
573
|
...proStyles.value.menu
|
|
123
574
|
},
|
|
124
|
-
"
|
|
125
|
-
"
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
route
|
|
142
|
-
});
|
|
143
|
-
emit("update:selectedKeys", info.selectedKeys);
|
|
575
|
+
"role": "menu",
|
|
576
|
+
"data-pro-menu-token-key": proLayoutToken.value.key
|
|
577
|
+
}, [menus.map((route) => renderRoute(route, {
|
|
578
|
+
depth: 0,
|
|
579
|
+
parentKeys: [],
|
|
580
|
+
popup: false,
|
|
581
|
+
popupPath: [],
|
|
582
|
+
inlineIndent: DEFAULT_INLINE_INDENT,
|
|
583
|
+
horizontal: false
|
|
584
|
+
}))]);
|
|
585
|
+
const visibleMenus = menus.filter((route) => !route.meta?.hideInMenu);
|
|
586
|
+
return createVNode("ul", {
|
|
587
|
+
"ref": overflow.containerRef,
|
|
588
|
+
"class": classNames(menuClassNames.value, `${prefixCls.value}-overflow`),
|
|
589
|
+
"style": {
|
|
590
|
+
...props.style,
|
|
591
|
+
...proStyles.value.menu
|
|
144
592
|
},
|
|
145
|
-
"
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
593
|
+
"role": "menubar",
|
|
594
|
+
"data-pro-menu-token-key": proLayoutToken.value.key
|
|
595
|
+
}, [visibleMenus.map((route, index) => renderRoute(route, {
|
|
596
|
+
depth: 0,
|
|
597
|
+
parentKeys: [],
|
|
598
|
+
popup: false,
|
|
599
|
+
popupPath: [],
|
|
600
|
+
inlineIndent: DEFAULT_INLINE_INDENT,
|
|
601
|
+
horizontal: true,
|
|
602
|
+
overflowTopLevel: true,
|
|
603
|
+
overflowHidden: overflow.isItemHidden(index)
|
|
604
|
+
})), overflow.restVisible.value && renderOverflowRest(visibleMenus)]);
|
|
151
605
|
};
|
|
152
606
|
}, {
|
|
153
607
|
props: {
|
|
608
|
+
prefixCls: {
|
|
609
|
+
type: String,
|
|
610
|
+
required: false
|
|
611
|
+
},
|
|
612
|
+
placement: {
|
|
613
|
+
type: String,
|
|
614
|
+
required: false
|
|
615
|
+
},
|
|
616
|
+
getScrollContainer: {
|
|
617
|
+
type: Function,
|
|
618
|
+
required: false
|
|
619
|
+
},
|
|
154
620
|
class: {
|
|
155
621
|
type: String,
|
|
156
622
|
required: false
|
|
@@ -159,9 +625,99 @@ const LayoutMenu = /* @__PURE__ */ defineComponent((props, { emit, slots }) => {
|
|
|
159
625
|
type: Object,
|
|
160
626
|
required: false
|
|
161
627
|
},
|
|
628
|
+
menus: {
|
|
629
|
+
type: Array,
|
|
630
|
+
required: false
|
|
631
|
+
},
|
|
632
|
+
selectedKeys: {
|
|
633
|
+
type: Array,
|
|
634
|
+
required: false
|
|
635
|
+
},
|
|
636
|
+
openKeys: {
|
|
637
|
+
type: Array,
|
|
638
|
+
required: false
|
|
639
|
+
},
|
|
640
|
+
theme: {
|
|
641
|
+
type: String,
|
|
642
|
+
required: false
|
|
643
|
+
},
|
|
644
|
+
mode: {
|
|
645
|
+
type: String,
|
|
646
|
+
required: false
|
|
647
|
+
},
|
|
648
|
+
collapsed: {
|
|
649
|
+
type: Boolean,
|
|
650
|
+
required: false,
|
|
651
|
+
default: void 0
|
|
652
|
+
},
|
|
653
|
+
proClasses: {
|
|
654
|
+
type: Object,
|
|
655
|
+
required: false
|
|
656
|
+
},
|
|
657
|
+
proStyles: {
|
|
658
|
+
type: Object,
|
|
659
|
+
required: false
|
|
660
|
+
},
|
|
661
|
+
menuItemIcon: {
|
|
662
|
+
type: Function,
|
|
663
|
+
required: false
|
|
664
|
+
},
|
|
665
|
+
menuItemLabel: {
|
|
666
|
+
type: Function,
|
|
667
|
+
required: false
|
|
668
|
+
},
|
|
669
|
+
menuItemExtra: {
|
|
670
|
+
type: Function,
|
|
671
|
+
required: false
|
|
672
|
+
}
|
|
673
|
+
},
|
|
674
|
+
emits: [
|
|
675
|
+
"select",
|
|
676
|
+
"openChange",
|
|
677
|
+
"update:selectedKeys",
|
|
678
|
+
"update:openKeys"
|
|
679
|
+
],
|
|
680
|
+
name: "ProMenuContent",
|
|
681
|
+
inheritAttrs: false
|
|
682
|
+
});
|
|
683
|
+
const ProMenu = /* @__PURE__ */ defineComponent((props, { emit, slots }) => {
|
|
684
|
+
const { token, proLayoutToken } = useProToken();
|
|
685
|
+
const mode = computed(() => props.mode ?? (props.placement === "header" ? "horizontal" : "inline"));
|
|
686
|
+
const isHorizontal = computed(() => mode.value === "horizontal");
|
|
687
|
+
const proMenuTokens = computed(() => isHorizontal.value ? buildHeaderProMenuTokens(proLayoutToken.value, token.value.Menu) : buildSiderProMenuTokens(proLayoutToken.value, token.value.Menu));
|
|
688
|
+
return () => createVNode(ConfigProvider, { "theme": { components: { ProMenu: proMenuTokens.value } } }, { default: () => [createVNode(ProMenuContent, mergeProps(omit(props, [
|
|
689
|
+
"onSelect",
|
|
690
|
+
"onOpenChange",
|
|
691
|
+
"onUpdate:selectedKeys",
|
|
692
|
+
"onUpdate:openKeys"
|
|
693
|
+
]), {
|
|
694
|
+
"onSelect": (info) => emit("select", info),
|
|
695
|
+
"onOpenChange": (keys) => emit("openChange", keys)
|
|
696
|
+
}, {
|
|
697
|
+
"onUpdate:selectedKeys": (keys) => emit("update:selectedKeys", keys),
|
|
698
|
+
"onUpdate:openKeys": (keys) => emit("update:openKeys", keys)
|
|
699
|
+
}), slots)] });
|
|
700
|
+
}, {
|
|
701
|
+
props: {
|
|
702
|
+
prefixCls: {
|
|
703
|
+
type: String,
|
|
704
|
+
required: false
|
|
705
|
+
},
|
|
162
706
|
placement: {
|
|
163
707
|
type: String,
|
|
164
|
-
required:
|
|
708
|
+
required: false
|
|
709
|
+
},
|
|
710
|
+
getScrollContainer: {
|
|
711
|
+
type: Function,
|
|
712
|
+
required: false
|
|
713
|
+
},
|
|
714
|
+
class: {
|
|
715
|
+
type: String,
|
|
716
|
+
required: false
|
|
717
|
+
},
|
|
718
|
+
style: {
|
|
719
|
+
type: Object,
|
|
720
|
+
required: false
|
|
165
721
|
},
|
|
166
722
|
menus: {
|
|
167
723
|
type: Array,
|
|
@@ -215,8 +771,8 @@ const LayoutMenu = /* @__PURE__ */ defineComponent((props, { emit, slots }) => {
|
|
|
215
771
|
"update:selectedKeys",
|
|
216
772
|
"update:openKeys"
|
|
217
773
|
],
|
|
218
|
-
name: "
|
|
774
|
+
name: "ProMenu",
|
|
219
775
|
inheritAttrs: false
|
|
220
776
|
});
|
|
221
777
|
//#endregion
|
|
222
|
-
export {
|
|
778
|
+
export { ProMenu as default };
|