完全跑通1.0版本

This commit is contained in:
2026-05-26 12:56:03 +08:00
parent 2ece5174a7
commit 93c714a93b
11557 changed files with 1648225 additions and 36 deletions

View File

@@ -0,0 +1,17 @@
import _default from "./menu.js";
import _default$1 from "./menu-item.vue.js";
import _default$2 from "./menu-item-group.vue.js";
import _default$3 from "./sub-menu.js";
//#region ../../packages/components/menu/src/instance.d.ts
type MenuInstance = InstanceType<typeof _default> & {
open: (index: string) => void;
close: (index: string) => void;
handleResize: () => void;
updateActiveIndex: (index: string) => void;
};
type MenuItemInstance = InstanceType<typeof _default$1> & unknown;
type MenuItemGroupInstance = InstanceType<typeof _default$2> & unknown;
type SubMenuInstance = InstanceType<typeof _default$3> & unknown;
//#endregion
export { MenuInstance, MenuItemGroupInstance, MenuItemInstance, SubMenuInstance };

View File

@@ -0,0 +1,7 @@
import menu_collapse_transition_vue_vue_type_script_setup_true_lang_default from "./menu-collapse-transition.vue_vue_type_script_setup_true_lang.mjs";
//#region ../../packages/components/menu/src/menu-collapse-transition.vue
var menu_collapse_transition_default = menu_collapse_transition_vue_vue_type_script_setup_true_lang_default;
//#endregion
export { menu_collapse_transition_default as default };
//# sourceMappingURL=menu-collapse-transition.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"menu-collapse-transition.mjs","names":[],"sources":["../../../../../../packages/components/menu/src/menu-collapse-transition.vue"],"sourcesContent":["<template>\n <transition mode=\"out-in\" v-bind=\"listeners\">\n <slot />\n </transition>\n</template>\n\n<script lang=\"ts\" setup>\nimport { useNamespace } from '@element-plus/hooks'\nimport { addClass, hasClass, removeClass } from '@element-plus/utils'\n\nimport type { BaseTransitionProps, TransitionProps } from 'vue'\n\ndefineOptions({\n name: 'ElMenuCollapseTransition',\n})\n\nconst ns = useNamespace('menu')\nconst listeners = {\n onBeforeEnter: (el) => (el.style.opacity = '0.2'),\n onEnter(el, done) {\n addClass(el, `${ns.namespace.value}-opacity-transition`)\n el.style.opacity = '1'\n done()\n },\n\n onAfterEnter(el) {\n removeClass(el, `${ns.namespace.value}-opacity-transition`)\n el.style.opacity = ''\n },\n\n onBeforeLeave(el) {\n if (!el.dataset) (el as any).dataset = {}\n\n if (hasClass(el, ns.m('collapse'))) {\n removeClass(el, ns.m('collapse'))\n el.dataset.oldOverflow = el.style.overflow\n el.dataset.scrollWidth = el.clientWidth.toString()\n addClass(el, ns.m('collapse'))\n } else {\n addClass(el, ns.m('collapse'))\n el.dataset.oldOverflow = el.style.overflow\n el.dataset.scrollWidth = el.clientWidth.toString()\n removeClass(el, ns.m('collapse'))\n }\n\n el.style.width = `${el.scrollWidth}px`\n el.style.overflow = 'hidden'\n },\n\n onLeave(el: HTMLElement) {\n addClass(el, 'horizontal-collapse-transition')\n el.style.width = `${el.dataset.scrollWidth}px`\n },\n} as BaseTransitionProps<HTMLElement> as TransitionProps\n</script>\n"],"mappings":""}

View File

@@ -0,0 +1,17 @@
import * as _$vue from "vue";
//#region ../../packages/components/menu/src/menu-collapse-transition.vue.d.ts
declare var __VLS_7: {};
type __VLS_Slots = {} & {
default?: (props: typeof __VLS_7) => any;
};
declare const __VLS_base: _$vue.DefineComponent<{}, {}, {}, {}, {}, _$vue.ComponentOptionsMixin, _$vue.ComponentOptionsMixin, {}, string, _$vue.PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, _$vue.ComponentProvideOptions, true, {}, any>;
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
declare const _default: typeof __VLS_export;
type __VLS_WithSlots<T, S> = T & {
new (): {
$slots: S;
};
};
//#endregion
export { _default as default };

View File

@@ -0,0 +1,53 @@
import { addClass, hasClass, removeClass } from "../../../utils/dom/style.mjs";
import { useNamespace } from "../../../hooks/use-namespace/index.mjs";
import { Transition, createBlock, defineComponent, mergeProps, openBlock, renderSlot, withCtx } from "vue";
//#region ../../packages/components/menu/src/menu-collapse-transition.vue?vue&type=script&setup=true&lang.ts
var menu_collapse_transition_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
name: "ElMenuCollapseTransition",
__name: "menu-collapse-transition",
setup(__props) {
const ns = useNamespace("menu");
const listeners = {
onBeforeEnter: (el) => el.style.opacity = "0.2",
onEnter(el, done) {
addClass(el, `${ns.namespace.value}-opacity-transition`);
el.style.opacity = "1";
done();
},
onAfterEnter(el) {
removeClass(el, `${ns.namespace.value}-opacity-transition`);
el.style.opacity = "";
},
onBeforeLeave(el) {
if (!el.dataset) el.dataset = {};
if (hasClass(el, ns.m("collapse"))) {
removeClass(el, ns.m("collapse"));
el.dataset.oldOverflow = el.style.overflow;
el.dataset.scrollWidth = el.clientWidth.toString();
addClass(el, ns.m("collapse"));
} else {
addClass(el, ns.m("collapse"));
el.dataset.oldOverflow = el.style.overflow;
el.dataset.scrollWidth = el.clientWidth.toString();
removeClass(el, ns.m("collapse"));
}
el.style.width = `${el.scrollWidth}px`;
el.style.overflow = "hidden";
},
onLeave(el) {
addClass(el, "horizontal-collapse-transition");
el.style.width = `${el.dataset.scrollWidth}px`;
}
};
return (_ctx, _cache) => {
return openBlock(), createBlock(Transition, mergeProps({ mode: "out-in" }, listeners), {
default: withCtx(() => [renderSlot(_ctx.$slots, "default")]),
_: 3
}, 16);
};
}
});
//#endregion
export { menu_collapse_transition_vue_vue_type_script_setup_true_lang_default as default };
//# sourceMappingURL=menu-collapse-transition.vue_vue_type_script_setup_true_lang.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"menu-collapse-transition.vue_vue_type_script_setup_true_lang.mjs","names":[],"sources":["../../../../../../packages/components/menu/src/menu-collapse-transition.vue"],"sourcesContent":["<template>\n <transition mode=\"out-in\" v-bind=\"listeners\">\n <slot />\n </transition>\n</template>\n\n<script lang=\"ts\" setup>\nimport { useNamespace } from '@element-plus/hooks'\nimport { addClass, hasClass, removeClass } from '@element-plus/utils'\n\nimport type { BaseTransitionProps, TransitionProps } from 'vue'\n\ndefineOptions({\n name: 'ElMenuCollapseTransition',\n})\n\nconst ns = useNamespace('menu')\nconst listeners = {\n onBeforeEnter: (el) => (el.style.opacity = '0.2'),\n onEnter(el, done) {\n addClass(el, `${ns.namespace.value}-opacity-transition`)\n el.style.opacity = '1'\n done()\n },\n\n onAfterEnter(el) {\n removeClass(el, `${ns.namespace.value}-opacity-transition`)\n el.style.opacity = ''\n },\n\n onBeforeLeave(el) {\n if (!el.dataset) (el as any).dataset = {}\n\n if (hasClass(el, ns.m('collapse'))) {\n removeClass(el, ns.m('collapse'))\n el.dataset.oldOverflow = el.style.overflow\n el.dataset.scrollWidth = el.clientWidth.toString()\n addClass(el, ns.m('collapse'))\n } else {\n addClass(el, ns.m('collapse'))\n el.dataset.oldOverflow = el.style.overflow\n el.dataset.scrollWidth = el.clientWidth.toString()\n removeClass(el, ns.m('collapse'))\n }\n\n el.style.width = `${el.scrollWidth}px`\n el.style.overflow = 'hidden'\n },\n\n onLeave(el: HTMLElement) {\n addClass(el, 'horizontal-collapse-transition')\n el.style.width = `${el.dataset.scrollWidth}px`\n },\n} as BaseTransitionProps<HTMLElement> as TransitionProps\n</script>\n"],"mappings":";;;;;;;;EAgBA,MAAM,KAAK,aAAa,OAAM;EAC9B,MAAM,YAAY;GAChB,gBAAgB,OAAQ,GAAG,MAAM,UAAU;GAC3C,QAAQ,IAAI,MAAM;IAChB,SAAS,IAAI,GAAG,GAAG,UAAU,MAAM,qBAAoB;IACvD,GAAG,MAAM,UAAU;IACnB,MAAK;;GAGP,aAAa,IAAI;IACf,YAAY,IAAI,GAAG,GAAG,UAAU,MAAM,qBAAoB;IAC1D,GAAG,MAAM,UAAU;;GAGrB,cAAc,IAAI;IAChB,IAAI,CAAC,GAAG,SAAS,GAAY,UAAU,EAAC;IAExC,IAAI,SAAS,IAAI,GAAG,EAAE,WAAW,CAAC,EAAE;KAClC,YAAY,IAAI,GAAG,EAAE,WAAW,CAAA;KAChC,GAAG,QAAQ,cAAc,GAAG,MAAM;KAClC,GAAG,QAAQ,cAAc,GAAG,YAAY,UAAS;KACjD,SAAS,IAAI,GAAG,EAAE,WAAW,CAAA;WACxB;KACL,SAAS,IAAI,GAAG,EAAE,WAAW,CAAA;KAC7B,GAAG,QAAQ,cAAc,GAAG,MAAM;KAClC,GAAG,QAAQ,cAAc,GAAG,YAAY,UAAS;KACjD,YAAY,IAAI,GAAG,EAAE,WAAW,CAAA;;IAGlC,GAAG,MAAM,QAAQ,GAAG,GAAG,YAAY;IACnC,GAAG,MAAM,WAAW;;GAGtB,QAAQ,IAAiB;IACvB,SAAS,IAAI,iCAAgC;IAC7C,GAAG,MAAM,QAAQ,GAAG,GAAG,QAAQ,YAAY;;GAE9C;;uBApDC,YAEa,YAFb,WAEa,EAFD,MAAK,UAAQ,EAAS,UAAS,EAAA;2BACjC,CAAR,WAAQ,KAAA,QAAA,UAAA,CAAA,CAAA"}

View File

@@ -0,0 +1,24 @@
import { ExtractPublicPropTypes } from "vue";
//#region ../../packages/components/menu/src/menu-item-group.d.ts
interface MenuItemGroupProps {
/**
* @description group title
*/
title?: string;
}
/**
* @deprecated Removed after 3.0.0, Use `MenuItemGroupProps` instead.
*/
declare const menuItemGroupProps: {
/**
* @description group title
*/
readonly title: StringConstructor;
};
/**
* @deprecated Removed after 3.0.0, Use `MenuItemGroupProps` instead.
*/
type MenuItemGroupPropsPublic = ExtractPublicPropTypes<typeof menuItemGroupProps>;
//#endregion
export { MenuItemGroupProps, MenuItemGroupPropsPublic, menuItemGroupProps };

View File

@@ -0,0 +1,13 @@
//#region ../../packages/components/menu/src/menu-item-group.ts
/**
* @deprecated Removed after 3.0.0, Use `MenuItemGroupProps` instead.
*/
const menuItemGroupProps = {
/**
* @description group title
*/
title: String };
//#endregion
export { menuItemGroupProps };
//# sourceMappingURL=menu-item-group.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"menu-item-group.mjs","names":[],"sources":["../../../../../../packages/components/menu/src/menu-item-group.ts"],"sourcesContent":["import type { ExtractPublicPropTypes } from 'vue'\n\nexport interface MenuItemGroupProps {\n /**\n * @description group title\n */\n title?: string\n}\n\n/**\n * @deprecated Removed after 3.0.0, Use `MenuItemGroupProps` instead.\n */\nexport const menuItemGroupProps = {\n /**\n * @description group title\n */\n title: String,\n} as const\n\n/**\n * @deprecated Removed after 3.0.0, Use `MenuItemGroupProps` instead.\n */\nexport type MenuItemGroupPropsPublic = ExtractPublicPropTypes<\n typeof menuItemGroupProps\n>\n"],"mappings":";;;;AAYA,MAAa,qBAAqB;;;;AAIhC,OAAO,QACR"}

View File

@@ -0,0 +1,20 @@
import { MenuItemGroupProps } from "./menu-item-group.js";
import * as _$vue from "vue";
//#region ../../packages/components/menu/src/menu-item-group.vue.d.ts
declare var __VLS_1: {}, __VLS_3: {};
type __VLS_Slots = {} & {
title?: (props: typeof __VLS_1) => any;
} & {
default?: (props: typeof __VLS_3) => any;
};
declare const __VLS_base: _$vue.DefineComponent<MenuItemGroupProps, {}, {}, {}, {}, _$vue.ComponentOptionsMixin, _$vue.ComponentOptionsMixin, {}, string, _$vue.PublicProps, Readonly<MenuItemGroupProps> & Readonly<{}>, {}, {}, {}, {}, string, _$vue.ComponentProvideOptions, false, {}, any>;
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
declare const _default: typeof __VLS_export;
type __VLS_WithSlots<T, S> = T & {
new (): {
$slots: S;
};
};
//#endregion
export { _default as default };

View File

@@ -0,0 +1,19 @@
import { useNamespace } from "../../../hooks/use-namespace/index.mjs";
import { menuItemGroupProps } from "./menu-item-group.mjs";
import { Fragment, createElementBlock, createElementVNode, createTextVNode, defineComponent, normalizeClass, openBlock, renderSlot, toDisplayString, unref } from "vue";
//#region ../../packages/components/menu/src/menu-item-group.vue?vue&type=script&setup=true&lang.ts
var menu_item_group_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
name: "ElMenuItemGroup",
__name: "menu-item-group",
props: menuItemGroupProps,
setup(__props) {
const ns = useNamespace("menu-item-group");
return (_ctx, _cache) => {
return openBlock(), createElementBlock("li", { class: normalizeClass(unref(ns).b()) }, [createElementVNode("div", { class: normalizeClass(unref(ns).e("title")) }, [!_ctx.$slots.title ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [createTextVNode(toDisplayString(__props.title), 1)], 64)) : renderSlot(_ctx.$slots, "title", { key: 1 })], 2), createElementVNode("ul", null, [renderSlot(_ctx.$slots, "default")])], 2);
};
}
});
//#endregion
export { menu_item_group_vue_vue_type_script_setup_true_lang_default as default };
//# sourceMappingURL=menu-item-group.vue_vue_type_script_setup_true_lang.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"menu-item-group.vue_vue_type_script_setup_true_lang.mjs","names":["$slots"],"sources":["../../../../../../packages/components/menu/src/menu-item-group.vue"],"sourcesContent":["<template>\n <li :class=\"ns.b()\">\n <div :class=\"ns.e('title')\">\n <template v-if=\"!$slots.title\">{{ title }}</template>\n <slot v-else name=\"title\" />\n </div>\n <ul>\n <slot />\n </ul>\n </li>\n</template>\n\n<script lang=\"ts\" setup>\nimport { useNamespace } from '@element-plus/hooks'\n\nimport type { MenuItemGroupProps } from './menu-item-group'\n\ndefineOptions({\n name: 'ElMenuItemGroup',\n})\ndefineProps<MenuItemGroupProps>()\n\nconst ns = useNamespace('menu-item-group')\n</script>\n"],"mappings":";;;;;;;;;EAsBA,MAAM,KAAK,aAAa,kBAAiB;;uBArBvC,mBAQK,MAAA,EARA,OAAK,eAAE,MAAA,GAAE,CAAC,GAAC,CAAA,EAAA,EAAA,CACd,mBAGM,OAAA,EAHA,OAAK,eAAE,MAAA,GAAE,CAAC,EAAC,QAAA,CAAA,EAAA,EAAA,CAAA,CACEA,KAAAA,OAAO,SAAA,WAAA,EAAxB,mBAAqD,UAAA,EAAA,KAAA,GAAA,EAAA,CAAA,gBAAA,gBAAnB,QAAA,MAAK,EAAA,EAAA,CAAA,EAAA,GAAA,IACvC,WAA4B,KAAA,QAAA,SAAA,EAAA,KAAA,GAAA,CAAA,CAAA,EAAA,EAAA,EAE9B,mBAEK,MAAA,MAAA,CADH,WAAQ,KAAA,QAAA,UAAA,CAAA,CAAA,CAAA,EAAA,EAAA"}

View File

@@ -0,0 +1,7 @@
import menu_item_group_vue_vue_type_script_setup_true_lang_default from "./menu-item-group.vue_vue_type_script_setup_true_lang.mjs";
//#region ../../packages/components/menu/src/menu-item-group.vue
var menu_item_group_default = menu_item_group_vue_vue_type_script_setup_true_lang_default;
//#endregion
export { menu_item_group_default as default };
//# sourceMappingURL=menu-item-group2.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"menu-item-group2.mjs","names":[],"sources":["../../../../../../packages/components/menu/src/menu-item-group.vue"],"sourcesContent":["<template>\n <li :class=\"ns.b()\">\n <div :class=\"ns.e('title')\">\n <template v-if=\"!$slots.title\">{{ title }}</template>\n <slot v-else name=\"title\" />\n </div>\n <ul>\n <slot />\n </ul>\n </li>\n</template>\n\n<script lang=\"ts\" setup>\nimport { useNamespace } from '@element-plus/hooks'\n\nimport type { MenuItemGroupProps } from './menu-item-group'\n\ndefineOptions({\n name: 'ElMenuItemGroup',\n})\ndefineProps<MenuItemGroupProps>()\n\nconst ns = useNamespace('menu-item-group')\n</script>\n"],"mappings":""}

View File

@@ -0,0 +1,50 @@
import { EpPropMergeType } from "../../../utils/vue/props/types.js";
import { MenuItemRegistered } from "./types.js";
import * as _$vue from "vue";
import { ExtractPublicPropTypes } from "vue";
import * as _$vue_router0 from "vue-router";
import { RouteLocationRaw } from "vue-router";
//#region ../../packages/components/menu/src/menu-item.d.ts
interface MenuItemProps {
/**
* @description unique identification
*/
index: string;
/**
* @description Vue Router object
*/
route?: RouteLocationRaw;
/**
* @description whether disabled
*/
disabled?: boolean;
}
/**
* @deprecated Removed after 3.0.0, Use `MenuItemProps` instead.
*/
declare const menuItemProps: {
readonly index: {
readonly type: _$vue.PropType<string>;
readonly required: true;
readonly validator: ((val: unknown) => boolean) | undefined;
__epPropKey: true;
};
readonly route: {
readonly type: _$vue.PropType<EpPropMergeType<(new (...args: any[]) => string | _$vue_router0.RouteLocationAsRelativeGeneric | _$vue_router0.RouteLocationAsPathGeneric) | (() => string | _$vue_router0.RouteLocationAsRelativeGeneric | _$vue_router0.RouteLocationAsPathGeneric) | (((new (...args: any[]) => string | _$vue_router0.RouteLocationAsRelativeGeneric | _$vue_router0.RouteLocationAsPathGeneric) | (() => string | _$vue_router0.RouteLocationAsRelativeGeneric | _$vue_router0.RouteLocationAsPathGeneric)) | null)[], unknown, unknown>>;
readonly required: false;
readonly validator: ((val: unknown) => boolean) | undefined;
__epPropKey: true;
};
readonly disabled: BooleanConstructor;
};
/**
* @deprecated Removed after 3.0.0, Use `MenuItemProps` instead.
*/
type MenuItemPropsPublic = ExtractPublicPropTypes<typeof menuItemProps>;
declare const menuItemEmits: {
click: (item: MenuItemRegistered) => boolean;
};
type MenuItemEmits = typeof menuItemEmits;
//#endregion
export { MenuItemEmits, MenuItemProps, MenuItemPropsPublic, menuItemEmits, menuItemProps };

View File

@@ -0,0 +1,28 @@
import { isArray, isString } from "../../../utils/types.mjs";
import { buildProps, definePropType } from "../../../utils/vue/props/runtime.mjs";
//#region ../../packages/components/menu/src/menu-item.ts
/**
* @deprecated Removed after 3.0.0, Use `MenuItemProps` instead.
*/
const menuItemProps = buildProps({
/**
* @description unique identification
*/
index: {
type: String,
required: true
},
/**
* @description Vue Router object
*/
route: { type: definePropType([String, Object]) },
/**
* @description whether disabled
*/
disabled: Boolean
});
const menuItemEmits = { click: (item) => isString(item.index) && isArray(item.indexPath) };
//#endregion
export { menuItemEmits, menuItemProps };
//# sourceMappingURL=menu-item.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"menu-item.mjs","names":[],"sources":["../../../../../../packages/components/menu/src/menu-item.ts"],"sourcesContent":["import {\n buildProps,\n definePropType,\n isArray,\n isString,\n} from '@element-plus/utils'\n\nimport type { ExtractPublicPropTypes } from 'vue'\nimport type { RouteLocationRaw } from 'vue-router'\nimport type { MenuItemRegistered } from './types'\n\nexport interface MenuItemProps {\n /**\n * @description unique identification\n */\n index: string\n /**\n * @description Vue Router object\n */\n route?: RouteLocationRaw\n /**\n * @description whether disabled\n */\n disabled?: boolean\n}\n\n/**\n * @deprecated Removed after 3.0.0, Use `MenuItemProps` instead.\n */\nexport const menuItemProps = buildProps({\n /**\n * @description unique identification\n */\n index: {\n type: String,\n required: true,\n },\n /**\n * @description Vue Router object\n */\n route: {\n type: definePropType<RouteLocationRaw>([String, Object]),\n },\n /**\n * @description whether disabled\n */\n disabled: Boolean,\n} as const)\n\n/**\n * @deprecated Removed after 3.0.0, Use `MenuItemProps` instead.\n */\nexport type MenuItemPropsPublic = ExtractPublicPropTypes<typeof menuItemProps>\n\nexport const menuItemEmits = {\n click: (item: MenuItemRegistered) =>\n isString(item.index) && isArray(item.indexPath),\n}\nexport type MenuItemEmits = typeof menuItemEmits\n"],"mappings":";;;;;;AA6BA,MAAa,gBAAgB,WAAW;;;;CAItC,OAAO;EACL,MAAM;EACN,UAAU;EACX;;;;CAID,OAAO,EACL,MAAM,eAAiC,CAAC,QAAQ,OAAO,CAAC,EACzD;;;;CAID,UAAU;CACX,CAAU;AAOX,MAAa,gBAAgB,EAC3B,QAAQ,SACN,SAAS,KAAK,MAAM,IAAI,QAAQ,KAAK,UAAU,EAClD"}

View File

@@ -0,0 +1,70 @@
import { MenuItemRegistered, MenuProvider } from "./types.js";
import { MenuItemProps } from "./menu-item.js";
import * as _$vue from "vue";
//#region ../../packages/components/menu/src/menu-item.vue.d.ts
declare var __VLS_8: {}, __VLS_10: {}, __VLS_12: {}, __VLS_14: {};
type __VLS_Slots = {} & {
title?: (props: typeof __VLS_8) => any;
} & {
default?: (props: typeof __VLS_10) => any;
} & {
default?: (props: typeof __VLS_12) => any;
} & {
title?: (props: typeof __VLS_14) => any;
};
declare const __VLS_base: _$vue.DefineComponent<MenuItemProps, {
parentMenu: _$vue.ComputedRef<_$vue.ComponentInternalInstance>;
rootMenu: MenuProvider;
active: _$vue.ComputedRef<boolean>;
nsMenu: {
namespace: _$vue.ComputedRef<string>;
b: (blockSuffix?: string) => string;
e: (element?: string) => string;
m: (modifier?: string) => string;
be: (blockSuffix?: string, element?: string) => string;
em: (element?: string, modifier?: string) => string;
bm: (blockSuffix?: string, modifier?: string) => string;
bem: (blockSuffix?: string, element?: string, modifier?: string) => string;
is: {
(name: string, state: boolean | undefined): string;
(name: string): string;
};
cssVar: (object: Record<string, string>) => Record<string, string>;
cssVarName: (name: string) => string;
cssVarBlock: (object: Record<string, string>) => Record<string, string>;
cssVarBlockName: (name: string) => string;
};
nsMenuItem: {
namespace: _$vue.ComputedRef<string>;
b: (blockSuffix?: string) => string;
e: (element?: string) => string;
m: (modifier?: string) => string;
be: (blockSuffix?: string, element?: string) => string;
em: (element?: string, modifier?: string) => string;
bm: (blockSuffix?: string, modifier?: string) => string;
bem: (blockSuffix?: string, element?: string, modifier?: string) => string;
is: {
(name: string, state: boolean | undefined): string;
(name: string): string;
};
cssVar: (object: Record<string, string>) => Record<string, string>;
cssVarName: (name: string) => string;
cssVarBlock: (object: Record<string, string>) => Record<string, string>;
cssVarBlockName: (name: string) => string;
};
handleClick: () => void;
}, {}, {}, {}, _$vue.ComponentOptionsMixin, _$vue.ComponentOptionsMixin, {
click: (item: MenuItemRegistered) => void;
}, string, _$vue.PublicProps, Readonly<MenuItemProps> & Readonly<{
onClick?: ((item: MenuItemRegistered) => any) | undefined;
}>, {}, {}, {}, {}, string, _$vue.ComponentProvideOptions, false, {}, any>;
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
declare const _default: typeof __VLS_export;
type __VLS_WithSlots<T, S> = T & {
new (): {
$slots: S;
};
};
//#endregion
export { _default as default };

View File

@@ -0,0 +1,93 @@
import { throwError } from "../../../utils/error.mjs";
import { useNamespace } from "../../../hooks/use-namespace/index.mjs";
import { ElTooltip } from "../../tooltip/index.mjs";
import useMenu from "./use-menu.mjs";
import { MENU_INJECTION_KEY, SUB_MENU_INJECTION_KEY } from "./tokens.mjs";
import { menuItemEmits, menuItemProps } from "./menu-item.mjs";
import { Fragment, computed, createBlock, createElementBlock, createElementVNode, defineComponent, getCurrentInstance, inject, normalizeClass, onBeforeUnmount, onMounted, openBlock, reactive, renderSlot, toRef, unref, withCtx } from "vue";
//#region ../../packages/components/menu/src/menu-item.vue?vue&type=script&setup=true&lang.ts
const COMPONENT_NAME = "ElMenuItem";
var menu_item_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
name: COMPONENT_NAME,
__name: "menu-item",
props: menuItemProps,
emits: menuItemEmits,
setup(__props, { expose: __expose, emit: __emit }) {
const props = __props;
const emit = __emit;
const instance = getCurrentInstance();
const rootMenu = inject(MENU_INJECTION_KEY);
const nsMenu = useNamespace("menu");
const nsMenuItem = useNamespace("menu-item");
if (!rootMenu) throwError(COMPONENT_NAME, "can not inject root menu");
const { parentMenu, indexPath } = useMenu(instance, toRef(props, "index"));
const subMenu = inject(`${SUB_MENU_INJECTION_KEY}${parentMenu.value.uid}`);
if (!subMenu) throwError(COMPONENT_NAME, "can not inject sub menu");
const active = computed(() => props.index === rootMenu.activeIndex);
const item = reactive({
index: props.index,
indexPath,
active
});
const handleClick = () => {
if (!props.disabled) {
rootMenu.handleMenuItemClick({
index: props.index,
indexPath: indexPath.value,
route: props.route
});
emit("click", item);
}
};
onMounted(() => {
subMenu.addSubMenu(item);
rootMenu.addMenuItem(item);
});
onBeforeUnmount(() => {
subMenu.removeSubMenu(item);
rootMenu.removeMenuItem(item);
});
__expose({
parentMenu,
rootMenu,
active,
nsMenu,
nsMenuItem,
handleClick
});
return (_ctx, _cache) => {
return openBlock(), createElementBlock("li", {
class: normalizeClass([
unref(nsMenuItem).b(),
unref(nsMenuItem).is("active", active.value),
unref(nsMenuItem).is("disabled", __props.disabled)
]),
role: "menuitem",
tabindex: "-1",
onClick: handleClick
}, [unref(parentMenu).type.name === "ElMenu" && unref(rootMenu).props.collapse && _ctx.$slots.title ? (openBlock(), createBlock(unref(ElTooltip), {
key: 0,
effect: unref(rootMenu).props.popperEffect,
placement: "right",
"fallback-placements": ["left"],
"popper-class": unref(rootMenu).props.popperClass,
"popper-style": unref(rootMenu).props.popperStyle,
persistent: unref(rootMenu).props.persistent,
"focus-on-target": ""
}, {
content: withCtx(() => [renderSlot(_ctx.$slots, "title")]),
default: withCtx(() => [createElementVNode("div", { class: normalizeClass(unref(nsMenu).be("tooltip", "trigger")) }, [renderSlot(_ctx.$slots, "default")], 2)]),
_: 3
}, 8, [
"effect",
"popper-class",
"popper-style",
"persistent"
])) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [renderSlot(_ctx.$slots, "default"), renderSlot(_ctx.$slots, "title")], 64))], 2);
};
}
});
//#endregion
export { menu_item_vue_vue_type_script_setup_true_lang_default as default };
//# sourceMappingURL=menu-item.vue_vue_type_script_setup_true_lang.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"menu-item.vue_vue_type_script_setup_true_lang.mjs","names":["$slots"],"sources":["../../../../../../packages/components/menu/src/menu-item.vue"],"sourcesContent":["<template>\n <li\n :class=\"[\n nsMenuItem.b(),\n nsMenuItem.is('active', active),\n nsMenuItem.is('disabled', disabled),\n ]\"\n role=\"menuitem\"\n tabindex=\"-1\"\n @click=\"handleClick\"\n >\n <el-tooltip\n v-if=\"\n parentMenu.type.name === 'ElMenu' &&\n rootMenu.props.collapse &&\n $slots.title\n \"\n :effect=\"rootMenu.props.popperEffect\"\n placement=\"right\"\n :fallback-placements=\"['left']\"\n :popper-class=\"rootMenu.props.popperClass\"\n :popper-style=\"rootMenu.props.popperStyle\"\n :persistent=\"rootMenu.props.persistent\"\n focus-on-target\n >\n <template #content>\n <slot name=\"title\" />\n </template>\n <div :class=\"nsMenu.be('tooltip', 'trigger')\">\n <slot />\n </div>\n </el-tooltip>\n <template v-else>\n <slot />\n <slot name=\"title\" />\n </template>\n </li>\n</template>\n\n<script lang=\"ts\" setup>\nimport {\n computed,\n getCurrentInstance,\n inject,\n onBeforeUnmount,\n onMounted,\n reactive,\n toRef,\n} from 'vue'\nimport ElTooltip from '@element-plus/components/tooltip'\nimport { throwError } from '@element-plus/utils'\nimport { useNamespace } from '@element-plus/hooks'\nimport useMenu from './use-menu'\nimport { menuItemEmits } from './menu-item'\nimport { MENU_INJECTION_KEY, SUB_MENU_INJECTION_KEY } from './tokens'\n\nimport type { MenuItemProps } from './menu-item'\nimport type { MenuItemRegistered, MenuProvider, SubMenuProvider } from './types'\n\nconst COMPONENT_NAME = 'ElMenuItem'\ndefineOptions({\n name: COMPONENT_NAME,\n})\nconst props = defineProps<MenuItemProps>()\nconst emit = defineEmits(menuItemEmits)\n\nconst instance = getCurrentInstance()!\nconst rootMenu = inject<MenuProvider>(MENU_INJECTION_KEY)!\nconst nsMenu = useNamespace('menu')\nconst nsMenuItem = useNamespace('menu-item')\nif (!rootMenu) throwError(COMPONENT_NAME, 'can not inject root menu')\n\nconst { parentMenu, indexPath } = useMenu(instance, toRef(props, 'index'))\n\nconst subMenu = inject<SubMenuProvider>(\n `${SUB_MENU_INJECTION_KEY}${parentMenu.value.uid}`\n)\nif (!subMenu) throwError(COMPONENT_NAME, 'can not inject sub menu')\n\nconst active = computed(() => props.index === rootMenu.activeIndex)\nconst item: MenuItemRegistered = reactive({\n index: props.index,\n indexPath,\n active,\n})\n\nconst handleClick = () => {\n if (!props.disabled) {\n rootMenu.handleMenuItemClick({\n index: props.index,\n indexPath: indexPath.value,\n route: props.route,\n })\n emit('click', item)\n }\n}\n\nonMounted(() => {\n subMenu.addSubMenu(item)\n rootMenu.addMenuItem(item)\n})\n\nonBeforeUnmount(() => {\n subMenu.removeSubMenu(item)\n rootMenu.removeMenuItem(item)\n})\n\ndefineExpose({\n parentMenu,\n rootMenu,\n active,\n nsMenu,\n nsMenuItem,\n handleClick,\n})\n</script>\n"],"mappings":";;;;;;;;AA2DA,MAAM,iBAAiB;;;;;;;EAIvB,MAAM,QAAQ;EACd,MAAM,OAAO;EAEb,MAAM,WAAW,oBAAoB;EACrC,MAAM,WAAW,OAAqB,mBAAmB;EACzD,MAAM,SAAS,aAAa,OAAM;EAClC,MAAM,aAAa,aAAa,YAAW;EAC3C,IAAI,CAAC,UAAU,WAAW,gBAAgB,2BAA0B;EAEpE,MAAM,EAAE,YAAY,cAAc,QAAQ,UAAU,MAAM,OAAO,QAAQ,CAAA;EAEzE,MAAM,UAAU,OACd,GAAG,yBAAyB,WAAW,MAAM,MAC/C;EACA,IAAI,CAAC,SAAS,WAAW,gBAAgB,0BAAyB;EAElE,MAAM,SAAS,eAAe,MAAM,UAAU,SAAS,YAAW;EAClE,MAAM,OAA2B,SAAS;GACxC,OAAO,MAAM;GACb;GACA;GACD,CAAA;EAED,MAAM,oBAAoB;GACxB,IAAI,CAAC,MAAM,UAAU;IACnB,SAAS,oBAAoB;KAC3B,OAAO,MAAM;KACb,WAAW,UAAU;KACrB,OAAO,MAAM;KACd,CAAA;IACD,KAAK,SAAS,KAAI;;;EAItB,gBAAgB;GACd,QAAQ,WAAW,KAAI;GACvB,SAAS,YAAY,KAAI;IAC1B;EAED,sBAAsB;GACpB,QAAQ,cAAc,KAAI;GAC1B,SAAS,eAAe,KAAI;IAC7B;EAED,SAAa;GACX;GACA;GACA;GACA;GACA;GACA;GACD,CAAA;;uBAjHC,mBAmCK,MAAA;IAlCF,OAAK,eAAA;KAAU,MAAA,WAAU,CAAC,GAAC;KAAU,MAAA,WAAU,CAAC,GAAE,UAAW,OAAA,MAAM;KAAS,MAAA,WAAU,CAAC,GAAE,YAAa,QAAA,SAAQ;;IAK/G,MAAK;IACL,UAAS;IACR,SAAO;OAGS,MAAA,WAAU,CAAC,KAAK,SAAI,YAAyB,MAAA,SAAQ,CAAC,MAAM,YAAoBA,KAAAA,OAAO,SAAA,WAAA,EADxG,YAoBa,MAAA,UAAA,EAAA;;IAdV,QAAQ,MAAA,SAAQ,CAAC,MAAM;IACxB,WAAU;IACT,uBAAqB,CAAA,OAAQ;IAC7B,gBAAc,MAAA,SAAQ,CAAC,MAAM;IAC7B,gBAAc,MAAA,SAAQ,CAAC,MAAM;IAC7B,YAAY,MAAA,SAAQ,CAAC,MAAM;IAC5B,mBAAA;;IAEW,SAAO,cACK,CAArB,WAAqB,KAAA,QAAA,QAAA,CAAA,CAAA;2BAIjB,CAFN,mBAEM,OAAA,EAFA,OAAK,eAAE,MAAA,OAAM,CAAC,GAAE,WAAA,UAAA,CAAA,EAAA,EAAA,CACpB,WAAQ,KAAA,QAAA,UAAA,CAAA,EAAA,EAAA,CAAA,CAAA;;;;;;;uBAGZ,mBAGW,UAAA,EAAA,KAAA,GAAA,EAAA,CAFT,WAAQ,KAAA,QAAA,UAAA,EACR,WAAqB,KAAA,QAAA,QAAA,CAAA,EAAA,GAAA,EAAA,EAAA,EAAA"}

View File

@@ -0,0 +1,7 @@
import menu_item_vue_vue_type_script_setup_true_lang_default from "./menu-item.vue_vue_type_script_setup_true_lang.mjs";
//#region ../../packages/components/menu/src/menu-item.vue
var menu_item_default = menu_item_vue_vue_type_script_setup_true_lang_default;
//#endregion
export { menu_item_default as default };
//# sourceMappingURL=menu-item2.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"menu-item2.mjs","names":[],"sources":["../../../../../../packages/components/menu/src/menu-item.vue"],"sourcesContent":["<template>\n <li\n :class=\"[\n nsMenuItem.b(),\n nsMenuItem.is('active', active),\n nsMenuItem.is('disabled', disabled),\n ]\"\n role=\"menuitem\"\n tabindex=\"-1\"\n @click=\"handleClick\"\n >\n <el-tooltip\n v-if=\"\n parentMenu.type.name === 'ElMenu' &&\n rootMenu.props.collapse &&\n $slots.title\n \"\n :effect=\"rootMenu.props.popperEffect\"\n placement=\"right\"\n :fallback-placements=\"['left']\"\n :popper-class=\"rootMenu.props.popperClass\"\n :popper-style=\"rootMenu.props.popperStyle\"\n :persistent=\"rootMenu.props.persistent\"\n focus-on-target\n >\n <template #content>\n <slot name=\"title\" />\n </template>\n <div :class=\"nsMenu.be('tooltip', 'trigger')\">\n <slot />\n </div>\n </el-tooltip>\n <template v-else>\n <slot />\n <slot name=\"title\" />\n </template>\n </li>\n</template>\n\n<script lang=\"ts\" setup>\nimport {\n computed,\n getCurrentInstance,\n inject,\n onBeforeUnmount,\n onMounted,\n reactive,\n toRef,\n} from 'vue'\nimport ElTooltip from '@element-plus/components/tooltip'\nimport { throwError } from '@element-plus/utils'\nimport { useNamespace } from '@element-plus/hooks'\nimport useMenu from './use-menu'\nimport { menuItemEmits } from './menu-item'\nimport { MENU_INJECTION_KEY, SUB_MENU_INJECTION_KEY } from './tokens'\n\nimport type { MenuItemProps } from './menu-item'\nimport type { MenuItemRegistered, MenuProvider, SubMenuProvider } from './types'\n\nconst COMPONENT_NAME = 'ElMenuItem'\ndefineOptions({\n name: COMPONENT_NAME,\n})\nconst props = defineProps<MenuItemProps>()\nconst emit = defineEmits(menuItemEmits)\n\nconst instance = getCurrentInstance()!\nconst rootMenu = inject<MenuProvider>(MENU_INJECTION_KEY)!\nconst nsMenu = useNamespace('menu')\nconst nsMenuItem = useNamespace('menu-item')\nif (!rootMenu) throwError(COMPONENT_NAME, 'can not inject root menu')\n\nconst { parentMenu, indexPath } = useMenu(instance, toRef(props, 'index'))\n\nconst subMenu = inject<SubMenuProvider>(\n `${SUB_MENU_INJECTION_KEY}${parentMenu.value.uid}`\n)\nif (!subMenu) throwError(COMPONENT_NAME, 'can not inject sub menu')\n\nconst active = computed(() => props.index === rootMenu.activeIndex)\nconst item: MenuItemRegistered = reactive({\n index: props.index,\n indexPath,\n active,\n})\n\nconst handleClick = () => {\n if (!props.disabled) {\n rootMenu.handleMenuItemClick({\n index: props.index,\n indexPath: indexPath.value,\n route: props.route,\n })\n emit('click', item)\n }\n}\n\nonMounted(() => {\n subMenu.addSubMenu(item)\n rootMenu.addMenuItem(item)\n})\n\nonBeforeUnmount(() => {\n subMenu.removeSubMenu(item)\n rootMenu.removeMenuItem(item)\n})\n\ndefineExpose({\n parentMenu,\n rootMenu,\n active,\n nsMenu,\n nsMenuItem,\n handleClick,\n})\n</script>\n"],"mappings":""}

View File

@@ -0,0 +1,128 @@
import { EpPropFinalized, EpPropMergeType } from "../../../utils/vue/props/types.js";
import { PopperEffect } from "../../popper/src/popper.js";
import { MenuItemClicked } from "./types.js";
import * as _$vue from "vue";
import { CSSProperties, Component, ExtractPropTypes, ExtractPublicPropTypes, VNode } from "vue";
import { NavigationFailure } from "vue-router";
//#region ../../packages/components/menu/src/menu.d.ts
declare const menuProps: {
readonly mode: EpPropFinalized<StringConstructor, "horizontal" | "vertical", unknown, "vertical", boolean>;
readonly defaultActive: EpPropFinalized<StringConstructor, unknown, unknown, "", boolean>;
readonly defaultOpeneds: EpPropFinalized<(new (...args: any[]) => string[]) | (() => string[]) | (((new (...args: any[]) => string[]) | (() => string[])) | null)[], unknown, unknown, () => [], boolean>;
readonly uniqueOpened: BooleanConstructor;
readonly router: BooleanConstructor;
readonly menuTrigger: EpPropFinalized<StringConstructor, "click" | "hover", unknown, "hover", boolean>;
readonly collapse: BooleanConstructor;
readonly backgroundColor: StringConstructor;
readonly textColor: StringConstructor;
readonly activeTextColor: StringConstructor;
readonly closeOnClickOutside: BooleanConstructor;
readonly collapseTransition: EpPropFinalized<BooleanConstructor, unknown, unknown, true, boolean>;
readonly ellipsis: EpPropFinalized<BooleanConstructor, unknown, unknown, true, boolean>;
readonly popperOffset: EpPropFinalized<NumberConstructor, unknown, unknown, 6, boolean>;
readonly ellipsisIcon: EpPropFinalized<(new (...args: any[]) => (string | Component) & {}) | (() => string | Component) | (((new (...args: any[]) => (string | Component) & {}) | (() => string | Component)) | null)[], unknown, unknown, () => _$vue.DefineComponent<{}, void, {}, {}, {}, _$vue.ComponentOptionsMixin, _$vue.ComponentOptionsMixin, {}, string, _$vue.PublicProps, Readonly<{}>, {}, {}, {}, {}, string, _$vue.ComponentProvideOptions, true, {}, any>, boolean>;
readonly popperEffect: EpPropFinalized<(new (...args: any[]) => string) | (() => PopperEffect) | (((new (...args: any[]) => string) | (() => PopperEffect)) | null)[], unknown, unknown, "dark", boolean>;
readonly popperClass: StringConstructor;
readonly popperStyle: {
readonly type: _$vue.PropType<EpPropMergeType<(new (...args: any[]) => string | CSSProperties) | (() => string | CSSProperties) | (((new (...args: any[]) => string | CSSProperties) | (() => string | CSSProperties)) | null)[], unknown, unknown>>;
readonly required: false;
readonly validator: ((val: unknown) => boolean) | undefined;
__epPropKey: true;
};
readonly showTimeout: EpPropFinalized<NumberConstructor, unknown, unknown, 300, boolean>;
readonly hideTimeout: EpPropFinalized<NumberConstructor, unknown, unknown, 300, boolean>;
readonly persistent: EpPropFinalized<BooleanConstructor, unknown, unknown, true, boolean>;
};
type MenuProps = ExtractPropTypes<typeof menuProps>;
type MenuPropsPublic = ExtractPublicPropTypes<typeof menuProps>;
declare const menuEmits: {
close: (index: string, indexPath: string[]) => boolean;
open: (index: string, indexPath: string[]) => boolean;
select: (index: string, indexPath: string[], item: MenuItemClicked, routerResult?: Promise<void | NavigationFailure>) => boolean;
};
type MenuEmits = typeof menuEmits;
declare const _default: _$vue.DefineComponent<ExtractPropTypes<{
readonly mode: EpPropFinalized<StringConstructor, "horizontal" | "vertical", unknown, "vertical", boolean>;
readonly defaultActive: EpPropFinalized<StringConstructor, unknown, unknown, "", boolean>;
readonly defaultOpeneds: EpPropFinalized<(new (...args: any[]) => string[]) | (() => string[]) | (((new (...args: any[]) => string[]) | (() => string[])) | null)[], unknown, unknown, () => [], boolean>;
readonly uniqueOpened: BooleanConstructor;
readonly router: BooleanConstructor;
readonly menuTrigger: EpPropFinalized<StringConstructor, "click" | "hover", unknown, "hover", boolean>;
readonly collapse: BooleanConstructor;
readonly backgroundColor: StringConstructor;
readonly textColor: StringConstructor;
readonly activeTextColor: StringConstructor;
readonly closeOnClickOutside: BooleanConstructor;
readonly collapseTransition: EpPropFinalized<BooleanConstructor, unknown, unknown, true, boolean>;
readonly ellipsis: EpPropFinalized<BooleanConstructor, unknown, unknown, true, boolean>;
readonly popperOffset: EpPropFinalized<NumberConstructor, unknown, unknown, 6, boolean>;
readonly ellipsisIcon: EpPropFinalized<(new (...args: any[]) => (string | Component) & {}) | (() => string | Component) | (((new (...args: any[]) => (string | Component) & {}) | (() => string | Component)) | null)[], unknown, unknown, () => _$vue.DefineComponent<{}, void, {}, {}, {}, _$vue.ComponentOptionsMixin, _$vue.ComponentOptionsMixin, {}, string, _$vue.PublicProps, Readonly<{}>, {}, {}, {}, {}, string, _$vue.ComponentProvideOptions, true, {}, any>, boolean>;
readonly popperEffect: EpPropFinalized<(new (...args: any[]) => string) | (() => PopperEffect) | (((new (...args: any[]) => string) | (() => PopperEffect)) | null)[], unknown, unknown, "dark", boolean>;
readonly popperClass: StringConstructor;
readonly popperStyle: {
readonly type: _$vue.PropType<EpPropMergeType<(new (...args: any[]) => string | CSSProperties) | (() => string | CSSProperties) | (((new (...args: any[]) => string | CSSProperties) | (() => string | CSSProperties)) | null)[], unknown, unknown>>;
readonly required: false;
readonly validator: ((val: unknown) => boolean) | undefined;
__epPropKey: true;
};
readonly showTimeout: EpPropFinalized<NumberConstructor, unknown, unknown, 300, boolean>;
readonly hideTimeout: EpPropFinalized<NumberConstructor, unknown, unknown, 300, boolean>;
readonly persistent: EpPropFinalized<BooleanConstructor, unknown, unknown, true, boolean>;
}>, () => VNode<_$vue.RendererNode, _$vue.RendererElement, {
[key: string]: any;
}>, {}, {}, {}, _$vue.ComponentOptionsMixin, _$vue.ComponentOptionsMixin, {
close: (index: string, indexPath: string[]) => boolean;
open: (index: string, indexPath: string[]) => boolean;
select: (index: string, indexPath: string[], item: MenuItemClicked, routerResult?: Promise<void | NavigationFailure>) => boolean;
}, string, _$vue.PublicProps, Readonly<ExtractPropTypes<{
readonly mode: EpPropFinalized<StringConstructor, "horizontal" | "vertical", unknown, "vertical", boolean>;
readonly defaultActive: EpPropFinalized<StringConstructor, unknown, unknown, "", boolean>;
readonly defaultOpeneds: EpPropFinalized<(new (...args: any[]) => string[]) | (() => string[]) | (((new (...args: any[]) => string[]) | (() => string[])) | null)[], unknown, unknown, () => [], boolean>;
readonly uniqueOpened: BooleanConstructor;
readonly router: BooleanConstructor;
readonly menuTrigger: EpPropFinalized<StringConstructor, "click" | "hover", unknown, "hover", boolean>;
readonly collapse: BooleanConstructor;
readonly backgroundColor: StringConstructor;
readonly textColor: StringConstructor;
readonly activeTextColor: StringConstructor;
readonly closeOnClickOutside: BooleanConstructor;
readonly collapseTransition: EpPropFinalized<BooleanConstructor, unknown, unknown, true, boolean>;
readonly ellipsis: EpPropFinalized<BooleanConstructor, unknown, unknown, true, boolean>;
readonly popperOffset: EpPropFinalized<NumberConstructor, unknown, unknown, 6, boolean>;
readonly ellipsisIcon: EpPropFinalized<(new (...args: any[]) => (string | Component) & {}) | (() => string | Component) | (((new (...args: any[]) => (string | Component) & {}) | (() => string | Component)) | null)[], unknown, unknown, () => _$vue.DefineComponent<{}, void, {}, {}, {}, _$vue.ComponentOptionsMixin, _$vue.ComponentOptionsMixin, {}, string, _$vue.PublicProps, Readonly<{}>, {}, {}, {}, {}, string, _$vue.ComponentProvideOptions, true, {}, any>, boolean>;
readonly popperEffect: EpPropFinalized<(new (...args: any[]) => string) | (() => PopperEffect) | (((new (...args: any[]) => string) | (() => PopperEffect)) | null)[], unknown, unknown, "dark", boolean>;
readonly popperClass: StringConstructor;
readonly popperStyle: {
readonly type: _$vue.PropType<EpPropMergeType<(new (...args: any[]) => string | CSSProperties) | (() => string | CSSProperties) | (((new (...args: any[]) => string | CSSProperties) | (() => string | CSSProperties)) | null)[], unknown, unknown>>;
readonly required: false;
readonly validator: ((val: unknown) => boolean) | undefined;
__epPropKey: true;
};
readonly showTimeout: EpPropFinalized<NumberConstructor, unknown, unknown, 300, boolean>;
readonly hideTimeout: EpPropFinalized<NumberConstructor, unknown, unknown, 300, boolean>;
readonly persistent: EpPropFinalized<BooleanConstructor, unknown, unknown, true, boolean>;
}>> & Readonly<{
onSelect?: ((index: string, indexPath: string[], item: MenuItemClicked, routerResult?: Promise<void | NavigationFailure> | undefined) => any) | undefined;
onClose?: ((index: string, indexPath: string[]) => any) | undefined;
onOpen?: ((index: string, indexPath: string[]) => any) | undefined;
}>, {
readonly collapse: boolean;
readonly ellipsis: EpPropMergeType<BooleanConstructor, unknown, unknown>;
readonly persistent: EpPropMergeType<BooleanConstructor, unknown, unknown>;
readonly mode: EpPropMergeType<StringConstructor, "horizontal" | "vertical", unknown>;
readonly showTimeout: number;
readonly hideTimeout: number;
readonly defaultActive: string;
readonly defaultOpeneds: string[];
readonly menuTrigger: EpPropMergeType<StringConstructor, "click" | "hover", unknown>;
readonly collapseTransition: EpPropMergeType<BooleanConstructor, unknown, unknown>;
readonly popperOffset: number;
readonly ellipsisIcon: EpPropMergeType<(new (...args: any[]) => (string | Component) & {}) | (() => string | Component) | (((new (...args: any[]) => (string | Component) & {}) | (() => string | Component)) | null)[], unknown, unknown>;
readonly popperEffect: EpPropMergeType<(new (...args: any[]) => string) | (() => PopperEffect) | (((new (...args: any[]) => string) | (() => PopperEffect)) | null)[], unknown, unknown>;
readonly uniqueOpened: boolean;
readonly router: boolean;
readonly closeOnClickOutside: boolean;
}, {}, {}, {}, string, _$vue.ComponentProvideOptions, true, {}, any>;
//#endregion
export { MenuEmits, MenuProps, MenuPropsPublic, _default as default, menuEmits, menuProps };

View File

@@ -0,0 +1,382 @@
import { isArray, isObject, isString, isUndefined as isUndefined$1 } from "../../../utils/types.mjs";
import { buildProps, definePropType } from "../../../utils/vue/props/runtime.mjs";
import { iconPropType } from "../../../utils/vue/icon.mjs";
import { flattedChildren } from "../../../utils/vue/vnode.mjs";
import { mutable } from "../../../utils/typescript.mjs";
import { useNamespace } from "../../../hooks/use-namespace/index.mjs";
import { ElIcon } from "../../icon/index.mjs";
import ClickOutside from "../../../directives/click-outside/index.mjs";
import Menu from "./utils/menu-bar.mjs";
import menu_collapse_transition_default from "./menu-collapse-transition.mjs";
import { useMenuCssVar } from "./use-menu-css-var.mjs";
import { MENU_INJECTION_KEY, SUB_MENU_INJECTION_KEY } from "./tokens.mjs";
import sub_menu_default from "./sub-menu.mjs";
import { unrefElement, useResizeObserver } from "@vueuse/core";
import { isNil } from "lodash-unified";
import { More } from "@element-plus/icons-vue";
import { computed, defineComponent, getCurrentInstance, h, nextTick, onMounted, provide, reactive, ref, watch, watchEffect, withDirectives } from "vue";
//#region ../../packages/components/menu/src/menu.ts
const menuProps = buildProps({
/**
* @description menu display mode
*/
mode: {
type: String,
values: ["horizontal", "vertical"],
default: "vertical"
},
/**
* @description index of active menu on page load
*/
defaultActive: {
type: String,
default: ""
},
/**
* @description array that contains indexes of currently active sub-menus
*/
defaultOpeneds: {
type: definePropType(Array),
default: () => mutable([])
},
/**
* @description whether only one sub-menu can be active
*/
uniqueOpened: Boolean,
/**
* @description whether `vue-router` mode is activated. If true, index will be used as 'path' to activate the route action. Use with `default-active` to set the active item on load.
*/
router: Boolean,
/**
* @description how sub-menus are triggered, only works when `mode` is 'horizontal'
*/
menuTrigger: {
type: String,
values: ["hover", "click"],
default: "hover"
},
/**
* @description whether the menu is collapsed (available only in vertical mode)
*/
collapse: Boolean,
/**
* @description background color of Menu (hex format) (deprecated, use `--bg-color` instead)
* @deprecated use `--bg-color` instead
*/
backgroundColor: String,
/**
* @description text color of Menu (hex format) (deprecated, use `--text-color` instead)
* @deprecated use `--text-color` instead
*/
textColor: String,
/**
* @description text color of currently active menu item (hex format) (deprecated, use `--active-color` instead)
* @deprecated use `--active-color` instead
*/
activeTextColor: String,
/**
* @description optional, whether menu is collapsed when clicking outside
*/
closeOnClickOutside: Boolean,
/**
* @description whether to enable the collapse transition
*/
collapseTransition: {
type: Boolean,
default: true
},
/**
* @description whether the menu is ellipsis (available only in horizontal mode)
*/
ellipsis: {
type: Boolean,
default: true
},
/**
* @description offset of the popper (effective for all submenus)
*/
popperOffset: {
type: Number,
default: 6
},
/**
* @description custom ellipsis icon (available only in horizontal mode and ellipsis is true)
*/
ellipsisIcon: {
type: iconPropType,
default: () => More
},
/**
* @description Tooltip theme, built-in theme: `dark` / `light` when menu is collapsed
*/
popperEffect: {
type: definePropType(String),
default: "dark"
},
/**
* @description custom class name for all popup menus
*/
popperClass: String,
/**
* @description custom style for all popup menus
*/
popperStyle: { type: definePropType([String, Object]) },
/**
* @description control timeout for all menus before showing
*/
showTimeout: {
type: Number,
default: 300
},
/**
* @description control timeout for all menus before hiding
*/
hideTimeout: {
type: Number,
default: 300
},
/**
* @description when menu inactive and `persistent` is `false` , dropdown menu will be destroyed
*/
persistent: {
type: Boolean,
default: true
}
});
const checkIndexPath = (indexPath) => isArray(indexPath) && indexPath.every((path) => isString(path));
const menuEmits = {
close: (index, indexPath) => isString(index) && checkIndexPath(indexPath),
open: (index, indexPath) => isString(index) && checkIndexPath(indexPath),
select: (index, indexPath, item, routerResult) => isString(index) && checkIndexPath(indexPath) && isObject(item) && (isUndefined$1(routerResult) || routerResult instanceof Promise)
};
const DEFAULT_MORE_ITEM_WIDTH = 64;
var menu_default = defineComponent({
name: "ElMenu",
props: menuProps,
emits: menuEmits,
setup(props, { emit, slots, expose }) {
const instance = getCurrentInstance();
const router = instance.appContext.config.globalProperties.$router;
const menu = ref();
const subMenu = ref();
const nsMenu = useNamespace("menu");
const nsSubMenu = useNamespace("sub-menu");
let moreItemWidth = DEFAULT_MORE_ITEM_WIDTH;
const sliceIndex = ref(-1);
const openedMenus = ref(props.defaultOpeneds && !props.collapse ? props.defaultOpeneds.slice(0) : []);
const activeIndex = ref(props.defaultActive);
const items = ref({});
const subMenus = ref({});
const isMenuPopup = computed(() => props.mode === "horizontal" || props.mode === "vertical" && props.collapse);
const initMenu = () => {
const activeItem = activeIndex.value && items.value[activeIndex.value];
if (!activeItem || props.mode === "horizontal" || props.collapse) return;
activeItem.indexPath.forEach((index) => {
const subMenu = subMenus.value[index];
subMenu && openMenu(index, subMenu.indexPath);
});
};
const openMenu = (index, indexPath) => {
if (openedMenus.value.includes(index)) return;
if (props.uniqueOpened) openedMenus.value = openedMenus.value.filter((index) => indexPath.includes(index));
openedMenus.value.push(index);
emit("open", index, indexPath);
};
const close = (index) => {
const i = openedMenus.value.indexOf(index);
if (i !== -1) openedMenus.value.splice(i, 1);
};
const closeMenu = (index, indexPath) => {
close(index);
emit("close", index, indexPath);
};
const handleSubMenuClick = ({ index, indexPath }) => {
openedMenus.value.includes(index) ? closeMenu(index, indexPath) : openMenu(index, indexPath);
};
const handleMenuItemClick = (menuItem) => {
if (props.mode === "horizontal" || props.collapse) openedMenus.value = [];
const { index, indexPath } = menuItem;
if (isNil(index) || isNil(indexPath)) return;
if (props.router && router) {
const route = menuItem.route || index;
const routerResult = router.push(route).then((res) => {
if (!res) activeIndex.value = index;
return res;
});
emit("select", index, indexPath, {
index,
indexPath,
route
}, routerResult);
} else {
activeIndex.value = index;
emit("select", index, indexPath, {
index,
indexPath
});
}
};
const updateActiveIndex = (val) => {
const itemsInData = items.value;
activeIndex.value = (itemsInData[val] || activeIndex.value && itemsInData[activeIndex.value] || itemsInData[props.defaultActive])?.index ?? val;
};
const calcMenuItemWidth = (menuItem) => {
const computedStyle = getComputedStyle(menuItem);
const marginLeft = Number.parseInt(computedStyle.marginLeft, 10);
const marginRight = Number.parseInt(computedStyle.marginRight, 10);
return menuItem.offsetWidth + marginLeft + marginRight || 0;
};
const calcSliceIndex = () => {
if (!menu.value) return -1;
const items = Array.from(menu.value.childNodes).filter((item) => item.nodeName !== "#comment" && (item.nodeName !== "#text" || item.nodeValue));
const computedMenuStyle = getComputedStyle(menu.value);
const paddingLeft = Number.parseInt(computedMenuStyle.paddingLeft, 10);
const paddingRight = Number.parseInt(computedMenuStyle.paddingRight, 10);
const menuWidth = menu.value.clientWidth - paddingLeft - paddingRight;
let calcWidth = 0;
let sliceIndex = 0;
items.forEach((item, index) => {
calcWidth += calcMenuItemWidth(item);
if (calcWidth <= menuWidth - moreItemWidth) sliceIndex = index + 1;
});
return sliceIndex === items.length ? -1 : sliceIndex;
};
const getIndexPath = (index) => subMenus.value[index].indexPath;
const debounce = (fn, wait = 33.34) => {
let timer;
return () => {
timer && clearTimeout(timer);
timer = setTimeout(() => {
fn();
}, wait);
};
};
let isFirstTimeRender = true;
const handleResize = () => {
const el = unrefElement(subMenu);
if (el) moreItemWidth = calcMenuItemWidth(el) || DEFAULT_MORE_ITEM_WIDTH;
if (sliceIndex.value === calcSliceIndex()) return;
const callback = () => {
sliceIndex.value = -1;
nextTick(() => {
sliceIndex.value = calcSliceIndex();
});
};
isFirstTimeRender ? callback() : debounce(callback)();
isFirstTimeRender = false;
};
watch(() => props.defaultActive, (currentActive) => {
if (!items.value[currentActive]) activeIndex.value = "";
updateActiveIndex(currentActive);
});
watch(() => props.collapse, (value) => {
if (value) openedMenus.value = [];
});
watch(items.value, initMenu);
let resizeStopper;
watchEffect(() => {
if (props.mode === "horizontal" && props.ellipsis) resizeStopper = useResizeObserver(menu, handleResize).stop;
else resizeStopper?.();
});
const mouseInChild = ref(false);
{
const addSubMenu = (item) => {
subMenus.value[item.index] = item;
};
const removeSubMenu = (item) => {
delete subMenus.value[item.index];
};
const addMenuItem = (item) => {
items.value[item.index] = item;
};
const removeMenuItem = (item) => {
delete items.value[item.index];
};
provide(MENU_INJECTION_KEY, reactive({
props,
openedMenus,
items,
subMenus,
activeIndex,
isMenuPopup,
addMenuItem,
removeMenuItem,
addSubMenu,
removeSubMenu,
openMenu,
closeMenu,
handleMenuItemClick,
handleSubMenuClick
}));
provide(`${SUB_MENU_INJECTION_KEY}${instance.uid}`, {
addSubMenu,
removeSubMenu,
mouseInChild,
level: 0
});
}
onMounted(() => {
if (props.mode === "horizontal") new Menu(instance.vnode.el, nsMenu.namespace.value);
});
{
const open = (index) => {
const { indexPath } = subMenus.value[index];
indexPath.forEach((i) => openMenu(i, indexPath));
};
expose({
open,
close,
updateActiveIndex,
handleResize
});
}
const ulStyle = useMenuCssVar(props, 0);
return () => {
let slot = slots.default?.() ?? [];
const vShowMore = [];
if (props.mode === "horizontal" && menu.value) {
const originalSlot = flattedChildren(slot).filter((vnode) => {
return vnode?.shapeFlag !== 8;
});
const slotDefault = sliceIndex.value === -1 ? originalSlot : originalSlot.slice(0, sliceIndex.value);
const slotMore = sliceIndex.value === -1 ? [] : originalSlot.slice(sliceIndex.value);
if (slotMore?.length && props.ellipsis) {
slot = slotDefault;
vShowMore.push(h(sub_menu_default, {
ref: subMenu,
index: "sub-menu-more",
class: nsSubMenu.e("hide-arrow"),
popperOffset: props.popperOffset
}, {
title: () => h(ElIcon, { class: nsSubMenu.e("icon-more") }, { default: () => h(props.ellipsisIcon) }),
default: () => slotMore
}));
}
}
const directives = props.closeOnClickOutside ? [[ClickOutside, () => {
if (!openedMenus.value.length) return;
if (!mouseInChild.value) {
openedMenus.value.forEach((openedMenu) => emit("close", openedMenu, getIndexPath(openedMenu)));
openedMenus.value = [];
}
}]] : [];
const vMenu = withDirectives(h("ul", {
key: String(props.collapse),
role: "menubar",
ref: menu,
style: ulStyle.value,
class: {
[nsMenu.b()]: true,
[nsMenu.m(props.mode)]: true,
[nsMenu.m("collapse")]: props.collapse
}
}, [...slot, ...vShowMore]), directives);
if (props.collapseTransition && props.mode === "vertical") return h(menu_collapse_transition_default, () => vMenu);
return vMenu;
};
}
});
//#endregion
export { menu_default as default, menuEmits, menuProps };
//# sourceMappingURL=menu.mjs.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,145 @@
import { EpPropFinalized, EpPropMergeType } from "../../../utils/vue/props/types.js";
import * as _$vue from "vue";
import { CSSProperties, ExtractPropTypes, ExtractPublicPropTypes } from "vue";
//#region ../../packages/components/menu/src/sub-menu.d.ts
declare const subMenuProps: {
readonly index: {
readonly type: _$vue.PropType<string>;
readonly required: true;
readonly validator: ((val: unknown) => boolean) | undefined;
__epPropKey: true;
};
readonly showTimeout: NumberConstructor;
readonly hideTimeout: NumberConstructor;
readonly popperClass: StringConstructor;
readonly popperStyle: {
readonly type: _$vue.PropType<EpPropMergeType<(new (...args: any[]) => string | CSSProperties) | (() => string | CSSProperties) | (((new (...args: any[]) => string | CSSProperties) | (() => string | CSSProperties)) | null)[], unknown, unknown>>;
readonly required: false;
readonly validator: ((val: unknown) => boolean) | undefined;
__epPropKey: true;
};
readonly disabled: BooleanConstructor;
readonly teleported: EpPropFinalized<BooleanConstructor, unknown, unknown, undefined, boolean>;
readonly popperOffset: NumberConstructor;
readonly expandCloseIcon: {
readonly type: _$vue.PropType<EpPropMergeType<(new (...args: any[]) => (string | _$vue.Component) & {}) | (() => string | _$vue.Component) | (((new (...args: any[]) => (string | _$vue.Component) & {}) | (() => string | _$vue.Component)) | null)[], unknown, unknown>>;
readonly required: false;
readonly validator: ((val: unknown) => boolean) | undefined;
__epPropKey: true;
};
readonly expandOpenIcon: {
readonly type: _$vue.PropType<EpPropMergeType<(new (...args: any[]) => (string | _$vue.Component) & {}) | (() => string | _$vue.Component) | (((new (...args: any[]) => (string | _$vue.Component) & {}) | (() => string | _$vue.Component)) | null)[], unknown, unknown>>;
readonly required: false;
readonly validator: ((val: unknown) => boolean) | undefined;
__epPropKey: true;
};
readonly collapseCloseIcon: {
readonly type: _$vue.PropType<EpPropMergeType<(new (...args: any[]) => (string | _$vue.Component) & {}) | (() => string | _$vue.Component) | (((new (...args: any[]) => (string | _$vue.Component) & {}) | (() => string | _$vue.Component)) | null)[], unknown, unknown>>;
readonly required: false;
readonly validator: ((val: unknown) => boolean) | undefined;
__epPropKey: true;
};
readonly collapseOpenIcon: {
readonly type: _$vue.PropType<EpPropMergeType<(new (...args: any[]) => (string | _$vue.Component) & {}) | (() => string | _$vue.Component) | (((new (...args: any[]) => (string | _$vue.Component) & {}) | (() => string | _$vue.Component)) | null)[], unknown, unknown>>;
readonly required: false;
readonly validator: ((val: unknown) => boolean) | undefined;
__epPropKey: true;
};
};
type SubMenuProps = ExtractPropTypes<typeof subMenuProps>;
type SubMenuPropsPublic = ExtractPublicPropTypes<typeof subMenuProps>;
declare const _default: _$vue.DefineComponent<ExtractPropTypes<{
readonly index: {
readonly type: _$vue.PropType<string>;
readonly required: true;
readonly validator: ((val: unknown) => boolean) | undefined;
__epPropKey: true;
};
readonly showTimeout: NumberConstructor;
readonly hideTimeout: NumberConstructor;
readonly popperClass: StringConstructor;
readonly popperStyle: {
readonly type: _$vue.PropType<EpPropMergeType<(new (...args: any[]) => string | CSSProperties) | (() => string | CSSProperties) | (((new (...args: any[]) => string | CSSProperties) | (() => string | CSSProperties)) | null)[], unknown, unknown>>;
readonly required: false;
readonly validator: ((val: unknown) => boolean) | undefined;
__epPropKey: true;
};
readonly disabled: BooleanConstructor;
readonly teleported: EpPropFinalized<BooleanConstructor, unknown, unknown, undefined, boolean>;
readonly popperOffset: NumberConstructor;
readonly expandCloseIcon: {
readonly type: _$vue.PropType<EpPropMergeType<(new (...args: any[]) => (string | _$vue.Component) & {}) | (() => string | _$vue.Component) | (((new (...args: any[]) => (string | _$vue.Component) & {}) | (() => string | _$vue.Component)) | null)[], unknown, unknown>>;
readonly required: false;
readonly validator: ((val: unknown) => boolean) | undefined;
__epPropKey: true;
};
readonly expandOpenIcon: {
readonly type: _$vue.PropType<EpPropMergeType<(new (...args: any[]) => (string | _$vue.Component) & {}) | (() => string | _$vue.Component) | (((new (...args: any[]) => (string | _$vue.Component) & {}) | (() => string | _$vue.Component)) | null)[], unknown, unknown>>;
readonly required: false;
readonly validator: ((val: unknown) => boolean) | undefined;
__epPropKey: true;
};
readonly collapseCloseIcon: {
readonly type: _$vue.PropType<EpPropMergeType<(new (...args: any[]) => (string | _$vue.Component) & {}) | (() => string | _$vue.Component) | (((new (...args: any[]) => (string | _$vue.Component) & {}) | (() => string | _$vue.Component)) | null)[], unknown, unknown>>;
readonly required: false;
readonly validator: ((val: unknown) => boolean) | undefined;
__epPropKey: true;
};
readonly collapseOpenIcon: {
readonly type: _$vue.PropType<EpPropMergeType<(new (...args: any[]) => (string | _$vue.Component) & {}) | (() => string | _$vue.Component) | (((new (...args: any[]) => (string | _$vue.Component) & {}) | (() => string | _$vue.Component)) | null)[], unknown, unknown>>;
readonly required: false;
readonly validator: ((val: unknown) => boolean) | undefined;
__epPropKey: true;
};
}>, () => _$vue.VNode<_$vue.RendererNode, _$vue.RendererElement, {
[key: string]: any;
}>, {}, {}, {}, _$vue.ComponentOptionsMixin, _$vue.ComponentOptionsMixin, {}, string, _$vue.PublicProps, Readonly<ExtractPropTypes<{
readonly index: {
readonly type: _$vue.PropType<string>;
readonly required: true;
readonly validator: ((val: unknown) => boolean) | undefined;
__epPropKey: true;
};
readonly showTimeout: NumberConstructor;
readonly hideTimeout: NumberConstructor;
readonly popperClass: StringConstructor;
readonly popperStyle: {
readonly type: _$vue.PropType<EpPropMergeType<(new (...args: any[]) => string | CSSProperties) | (() => string | CSSProperties) | (((new (...args: any[]) => string | CSSProperties) | (() => string | CSSProperties)) | null)[], unknown, unknown>>;
readonly required: false;
readonly validator: ((val: unknown) => boolean) | undefined;
__epPropKey: true;
};
readonly disabled: BooleanConstructor;
readonly teleported: EpPropFinalized<BooleanConstructor, unknown, unknown, undefined, boolean>;
readonly popperOffset: NumberConstructor;
readonly expandCloseIcon: {
readonly type: _$vue.PropType<EpPropMergeType<(new (...args: any[]) => (string | _$vue.Component) & {}) | (() => string | _$vue.Component) | (((new (...args: any[]) => (string | _$vue.Component) & {}) | (() => string | _$vue.Component)) | null)[], unknown, unknown>>;
readonly required: false;
readonly validator: ((val: unknown) => boolean) | undefined;
__epPropKey: true;
};
readonly expandOpenIcon: {
readonly type: _$vue.PropType<EpPropMergeType<(new (...args: any[]) => (string | _$vue.Component) & {}) | (() => string | _$vue.Component) | (((new (...args: any[]) => (string | _$vue.Component) & {}) | (() => string | _$vue.Component)) | null)[], unknown, unknown>>;
readonly required: false;
readonly validator: ((val: unknown) => boolean) | undefined;
__epPropKey: true;
};
readonly collapseCloseIcon: {
readonly type: _$vue.PropType<EpPropMergeType<(new (...args: any[]) => (string | _$vue.Component) & {}) | (() => string | _$vue.Component) | (((new (...args: any[]) => (string | _$vue.Component) & {}) | (() => string | _$vue.Component)) | null)[], unknown, unknown>>;
readonly required: false;
readonly validator: ((val: unknown) => boolean) | undefined;
__epPropKey: true;
};
readonly collapseOpenIcon: {
readonly type: _$vue.PropType<EpPropMergeType<(new (...args: any[]) => (string | _$vue.Component) & {}) | (() => string | _$vue.Component) | (((new (...args: any[]) => (string | _$vue.Component) & {}) | (() => string | _$vue.Component)) | null)[], unknown, unknown>>;
readonly required: false;
readonly validator: ((val: unknown) => boolean) | undefined;
__epPropKey: true;
};
}>> & Readonly<{}>, {
readonly disabled: boolean;
readonly teleported: EpPropMergeType<BooleanConstructor, unknown, unknown>;
}, {}, {}, {}, string, _$vue.ComponentProvideOptions, true, {}, any>;
//#endregion
export { SubMenuProps, SubMenuPropsPublic, _default as default, subMenuProps };

View File

@@ -0,0 +1,274 @@
import { focusElement } from "../../../utils/dom/aria.mjs";
import { isString, isUndefined } from "../../../utils/types.mjs";
import { throwError } from "../../../utils/error.mjs";
import { buildProps, definePropType } from "../../../utils/vue/props/runtime.mjs";
import { iconPropType } from "../../../utils/vue/icon.mjs";
import { useNamespace } from "../../../hooks/use-namespace/index.mjs";
import { ElIcon } from "../../icon/index.mjs";
import { ElTooltip } from "../../tooltip/index.mjs";
import { ElCollapseTransition } from "../../collapse-transition/index.mjs";
import useMenu from "./use-menu.mjs";
import { useMenuCssVar } from "./use-menu-css-var.mjs";
import { MENU_INJECTION_KEY, SUB_MENU_INJECTION_KEY } from "./tokens.mjs";
import { useTimeoutFn } from "@vueuse/core";
import { ArrowDown, ArrowRight } from "@element-plus/icons-vue";
import { Fragment, computed, defineComponent, getCurrentInstance, h, inject, nextTick, onBeforeUnmount, onMounted, provide, reactive, ref, vShow, watch, withDirectives } from "vue";
//#region ../../packages/components/menu/src/sub-menu.ts
const subMenuProps = buildProps({
/**
* @description unique identification
*/
index: {
type: String,
required: true
},
/**
* @description timeout before showing a sub-menu(inherit `show-timeout` of the menu by default.)
*/
showTimeout: Number,
/**
* @description timeout before hiding a sub-menu(inherit `hide-timeout` of the menu by default.)
*/
hideTimeout: Number,
/**
* @description custom class name for the popup menu
*/
popperClass: String,
/**
* @description custom style for the popup menu
*/
popperStyle: { type: definePropType([String, Object]) },
/**
* @description whether the sub-menu is disabled
*/
disabled: Boolean,
/**
* @description whether popup menu is teleported to the body
*/
teleported: {
type: Boolean,
default: void 0
},
/**
* @description offset of the popper (overrides the `popper` of menu)
*/
popperOffset: Number,
/**
* @description Icon when menu are expanded and submenu are closed, `expand-close-icon` and `expand-open-icon` need to be passed together to take effect
*/
expandCloseIcon: { type: iconPropType },
/**
* @description Icon when menu are expanded and submenu are opened, `expand-open-icon` and `expand-close-icon` need to be passed together to take effect
*/
expandOpenIcon: { type: iconPropType },
/**
* @description Icon when menu are collapsed and submenu are closed, `collapse-close-icon` and `collapse-open-icon` need to be passed together to take effect
*/
collapseCloseIcon: { type: iconPropType },
/**
* @description Icon when menu are collapsed and submenu are opened, `collapse-open-icon` and `collapse-close-icon` need to be passed together to take effect
*/
collapseOpenIcon: { type: iconPropType }
});
const COMPONENT_NAME = "ElSubMenu";
var sub_menu_default = defineComponent({
name: COMPONENT_NAME,
props: subMenuProps,
setup(props, { slots, expose }) {
const instance = getCurrentInstance();
const { indexPath, parentMenu } = useMenu(instance, computed(() => props.index));
const nsMenu = useNamespace("menu");
const nsSubMenu = useNamespace("sub-menu");
const rootMenu = inject(MENU_INJECTION_KEY);
if (!rootMenu) throwError(COMPONENT_NAME, "can not inject root menu");
const subMenu = inject(`${SUB_MENU_INJECTION_KEY}${parentMenu.value.uid}`);
if (!subMenu) throwError(COMPONENT_NAME, "can not inject sub menu");
const items = ref({});
const subMenus = ref({});
let timeout;
const mouseInChild = ref(false);
const verticalTitleRef = ref();
const vPopper = ref();
const isFirstLevel = computed(() => subMenu.level === 0);
const currentPlacement = computed(() => mode.value === "horizontal" && isFirstLevel.value ? "bottom-start" : "right-start");
const subMenuTitleIcon = computed(() => {
if (mode.value === "horizontal" && isFirstLevel.value || mode.value === "vertical" && !rootMenu.props.collapse) {
if (props.expandCloseIcon && props.expandOpenIcon) return opened.value ? props.expandOpenIcon : props.expandCloseIcon;
return ArrowDown;
} else {
if (props.collapseCloseIcon && props.collapseOpenIcon) return opened.value ? props.collapseOpenIcon : props.collapseCloseIcon;
return ArrowRight;
}
});
const appendToBody = computed(() => {
const value = props.teleported;
return isUndefined(value) ? isFirstLevel.value : value;
});
const menuTransitionName = computed(() => rootMenu.props.collapse ? `${nsMenu.namespace.value}-zoom-in-left` : `${nsMenu.namespace.value}-zoom-in-top`);
const fallbackPlacements = computed(() => mode.value === "horizontal" && isFirstLevel.value ? [
"bottom-start",
"bottom-end",
"top-start",
"top-end",
"right-start",
"left-start"
] : [
"right-start",
"right",
"right-end",
"left-start",
"bottom-start",
"bottom-end",
"top-start",
"top-end"
]);
const opened = computed(() => rootMenu.openedMenus.includes(props.index));
const active = computed(() => [...Object.values(items.value), ...Object.values(subMenus.value)].some(({ active }) => active));
const mode = computed(() => rootMenu.props.mode);
const persistent = computed(() => rootMenu.props.persistent);
const item = reactive({
index: props.index,
indexPath,
active
});
const ulStyle = useMenuCssVar(rootMenu.props, subMenu.level + 1);
const subMenuPopperOffset = computed(() => props.popperOffset ?? rootMenu.props.popperOffset);
const subMenuPopperClass = computed(() => props.popperClass ?? rootMenu.props.popperClass);
const subMenuPopperStyle = computed(() => props.popperStyle ?? rootMenu.props.popperStyle);
const subMenuShowTimeout = computed(() => props.showTimeout ?? rootMenu.props.showTimeout);
const subMenuHideTimeout = computed(() => props.hideTimeout ?? rootMenu.props.hideTimeout);
const doDestroy = () => vPopper.value?.popperRef?.popperInstanceRef?.destroy();
const handleCollapseToggle = (value) => {
if (!value) doDestroy();
};
const handleClick = () => {
if (rootMenu.props.menuTrigger === "hover" && rootMenu.props.mode === "horizontal" || rootMenu.props.collapse && rootMenu.props.mode === "vertical" || props.disabled) return;
rootMenu.handleSubMenuClick({
index: props.index,
indexPath: indexPath.value,
active: active.value
});
};
const handleMouseenter = (event, showTimeout = subMenuShowTimeout.value) => {
if (event.type === "focus") return;
if (rootMenu.props.menuTrigger === "click" && rootMenu.props.mode === "horizontal" || !rootMenu.props.collapse && rootMenu.props.mode === "vertical" || props.disabled) {
subMenu.mouseInChild.value = true;
return;
}
subMenu.mouseInChild.value = true;
timeout?.();
({stop: timeout} = useTimeoutFn(() => {
rootMenu.openMenu(props.index, indexPath.value);
}, showTimeout));
if (appendToBody.value) parentMenu.value.vnode.el?.dispatchEvent(new MouseEvent("mouseenter"));
if (event.type === "mouseenter" && event.target) nextTick(() => {
focusElement(event.target, { preventScroll: true });
});
};
const handleMouseleave = (deepDispatch = false) => {
if (rootMenu.props.menuTrigger === "click" && rootMenu.props.mode === "horizontal" || !rootMenu.props.collapse && rootMenu.props.mode === "vertical") {
subMenu.mouseInChild.value = false;
return;
}
timeout?.();
subMenu.mouseInChild.value = false;
({stop: timeout} = useTimeoutFn(() => !mouseInChild.value && rootMenu.closeMenu(props.index, indexPath.value), subMenuHideTimeout.value));
if (appendToBody.value && deepDispatch) subMenu.handleMouseleave?.(true);
};
watch(() => rootMenu.props.collapse, (value) => handleCollapseToggle(Boolean(value)));
{
const addSubMenu = (item) => {
subMenus.value[item.index] = item;
};
const removeSubMenu = (item) => {
delete subMenus.value[item.index];
};
provide(`${SUB_MENU_INJECTION_KEY}${instance.uid}`, {
addSubMenu,
removeSubMenu,
handleMouseleave,
mouseInChild,
level: subMenu.level + 1
});
}
expose({ opened });
onMounted(() => {
rootMenu.addSubMenu(item);
subMenu.addSubMenu(item);
});
onBeforeUnmount(() => {
subMenu.removeSubMenu(item);
rootMenu.removeSubMenu(item);
});
return () => {
const titleTag = [slots.title?.(), h(ElIcon, {
class: nsSubMenu.e("icon-arrow"),
style: { transform: opened.value ? props.expandCloseIcon && props.expandOpenIcon || props.collapseCloseIcon && props.collapseOpenIcon && rootMenu.props.collapse ? "none" : "rotateZ(180deg)" : "none" }
}, { default: () => isString(subMenuTitleIcon.value) ? h(instance.appContext.components[subMenuTitleIcon.value]) : h(subMenuTitleIcon.value) })];
const child = rootMenu.isMenuPopup ? h(ElTooltip, {
ref: vPopper,
visible: opened.value,
effect: "light",
pure: true,
offset: subMenuPopperOffset.value,
showArrow: false,
persistent: persistent.value,
popperClass: subMenuPopperClass.value,
popperStyle: subMenuPopperStyle.value,
placement: currentPlacement.value,
teleported: appendToBody.value,
fallbackPlacements: fallbackPlacements.value,
transition: menuTransitionName.value,
gpuAcceleration: false
}, {
content: () => h("div", {
class: [
nsMenu.m(mode.value),
nsMenu.m("popup-container"),
subMenuPopperClass.value
],
onMouseenter: (evt) => handleMouseenter(evt, 100),
onMouseleave: () => handleMouseleave(true),
onFocus: (evt) => handleMouseenter(evt, 100)
}, [h("ul", {
class: [
nsMenu.b(),
nsMenu.m("popup"),
nsMenu.m(`popup-${currentPlacement.value}`)
],
style: ulStyle.value
}, [slots.default?.()])]),
default: () => h("div", {
class: nsSubMenu.e("title"),
onClick: handleClick
}, titleTag)
}) : h(Fragment, {}, [h("div", {
class: nsSubMenu.e("title"),
ref: verticalTitleRef,
onClick: handleClick
}, titleTag), h(ElCollapseTransition, {}, { default: () => withDirectives(h("ul", {
role: "menu",
class: [nsMenu.b(), nsMenu.m("inline")],
style: ulStyle.value
}, [slots.default?.()]), [[vShow, opened.value]]) })]);
return h("li", {
class: [
nsSubMenu.b(),
nsSubMenu.is("active", active.value),
nsSubMenu.is("opened", opened.value),
nsSubMenu.is("disabled", props.disabled)
],
role: "menuitem",
ariaHaspopup: true,
ariaExpanded: opened.value,
onMouseenter: handleMouseenter,
onMouseleave: () => handleMouseleave(),
onFocus: handleMouseenter
}, [child]);
};
}
});
//#endregion
export { sub_menu_default as default, subMenuProps };
//# sourceMappingURL=sub-menu.mjs.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,5 @@
//#region ../../packages/components/menu/src/tokens.d.ts
declare const MENU_INJECTION_KEY = "rootMenu";
declare const SUB_MENU_INJECTION_KEY = "subMenu:";
//#endregion
export { MENU_INJECTION_KEY, SUB_MENU_INJECTION_KEY };

View File

@@ -0,0 +1,7 @@
//#region ../../packages/components/menu/src/tokens.ts
const MENU_INJECTION_KEY = "rootMenu";
const SUB_MENU_INJECTION_KEY = "subMenu:";
//#endregion
export { MENU_INJECTION_KEY, SUB_MENU_INJECTION_KEY };
//# sourceMappingURL=tokens.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"tokens.mjs","names":[],"sources":["../../../../../../packages/components/menu/src/tokens.ts"],"sourcesContent":["export const MENU_INJECTION_KEY = 'rootMenu'\n\nexport const SUB_MENU_INJECTION_KEY = 'subMenu:'\n"],"mappings":";AAAA,MAAa,qBAAqB;AAElC,MAAa,yBAAyB"}

View File

@@ -0,0 +1,40 @@
import { MenuProps } from "./menu.js";
import { Ref } from "vue";
import { RouteLocationRaw } from "vue-router";
//#region ../../packages/components/menu/src/types.d.ts
interface MenuItemRegistered {
index: string;
indexPath: string[];
active: boolean;
}
interface MenuItemClicked {
index: string;
indexPath: string[];
route?: RouteLocationRaw;
}
interface MenuProvider {
openedMenus: string[];
items: Record<string, MenuItemRegistered>;
subMenus: Record<string, MenuItemRegistered>;
activeIndex?: string;
isMenuPopup: boolean;
props: MenuProps;
addMenuItem: (item: MenuItemRegistered) => void;
removeMenuItem: (item: MenuItemRegistered) => void;
addSubMenu: (item: MenuItemRegistered) => void;
removeSubMenu: (item: MenuItemRegistered) => void;
openMenu: (index: string, indexPath: string[]) => void;
closeMenu: (index: string, indexPath: string[]) => void;
handleMenuItemClick: (item: MenuItemClicked) => void;
handleSubMenuClick: (subMenu: MenuItemRegistered) => void;
}
interface SubMenuProvider {
addSubMenu: (item: MenuItemRegistered) => void;
removeSubMenu: (item: MenuItemRegistered) => void;
handleMouseleave?: (deepDispatch: boolean) => void;
mouseInChild: Ref<boolean>;
level: number;
}
//#endregion
export { MenuItemClicked, MenuItemRegistered, MenuProvider, SubMenuProvider };

View File

View File

@@ -0,0 +1,7 @@
import { MenuProps } from "./menu.js";
import * as _$vue from "vue";
//#region ../../packages/components/menu/src/use-menu-color.d.ts
declare function useMenuColor(props: MenuProps): _$vue.ComputedRef<string>;
//#endregion
export { useMenuColor as default };

View File

@@ -0,0 +1,13 @@
import { computed } from "vue";
import { TinyColor } from "@ctrl/tinycolor";
//#region ../../packages/components/menu/src/use-menu-color.ts
function useMenuColor(props) {
return computed(() => {
const color = props.backgroundColor;
return color ? new TinyColor(color).shade(20).toString() : "";
});
}
//#endregion
export { useMenuColor as default };
//# sourceMappingURL=use-menu-color.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"use-menu-color.mjs","names":[],"sources":["../../../../../../packages/components/menu/src/use-menu-color.ts"],"sourcesContent":["import { computed } from 'vue'\nimport { TinyColor } from '@ctrl/tinycolor'\n\nimport type { MenuProps } from './menu'\n\nexport default function useMenuColor(props: MenuProps) {\n const menuBarColor = computed(() => {\n const color = props.backgroundColor\n return color ? new TinyColor(color).shade(20).toString() : ''\n })\n return menuBarColor\n}\n"],"mappings":";;;AAKA,SAAwB,aAAa,OAAkB;CAKrD,OAJqB,eAAe;EAClC,MAAM,QAAQ,MAAM;EACpB,OAAO,QAAQ,IAAI,UAAU,MAAM,CAAC,MAAM,GAAG,CAAC,UAAU,GAAG;GAE1C"}

View File

@@ -0,0 +1,7 @@
import { MenuProps } from "./menu.js";
import * as _$vue from "vue";
//#region ../../packages/components/menu/src/use-menu-css-var.d.ts
declare const useMenuCssVar: (props: MenuProps, level: number) => _$vue.ComputedRef<Record<string, string>>;
//#endregion
export { useMenuCssVar };

View File

@@ -0,0 +1,19 @@
import { useNamespace } from "../../../hooks/use-namespace/index.mjs";
import useMenuColor from "./use-menu-color.mjs";
import { computed } from "vue";
//#region ../../packages/components/menu/src/use-menu-css-var.ts
const useMenuCssVar = (props, level) => {
const ns = useNamespace("menu");
return computed(() => ns.cssVarBlock({
"text-color": props.textColor || "",
"hover-text-color": props.textColor || "",
"bg-color": props.backgroundColor || "",
"hover-bg-color": useMenuColor(props).value || "",
"active-color": props.activeTextColor || "",
level: `${level}`
}));
};
//#endregion
export { useMenuCssVar };
//# sourceMappingURL=use-menu-css-var.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"use-menu-css-var.mjs","names":[],"sources":["../../../../../../packages/components/menu/src/use-menu-css-var.ts"],"sourcesContent":["import { computed } from 'vue'\nimport { useNamespace } from '@element-plus/hooks'\nimport useMenuColor from './use-menu-color'\n\nimport type { MenuProps } from './menu'\n\nexport const useMenuCssVar = (props: MenuProps, level: number) => {\n const ns = useNamespace('menu')\n return computed(() =>\n ns.cssVarBlock({\n 'text-color': props.textColor || '',\n 'hover-text-color': props.textColor || '',\n 'bg-color': props.backgroundColor || '',\n 'hover-bg-color': useMenuColor(props).value || '',\n 'active-color': props.activeTextColor || '',\n level: `${level}`,\n })\n )\n}\n"],"mappings":";;;;AAMA,MAAa,iBAAiB,OAAkB,UAAkB;CAChE,MAAM,KAAK,aAAa,OAAO;CAC/B,OAAO,eACL,GAAG,YAAY;EACb,cAAc,MAAM,aAAa;EACjC,oBAAoB,MAAM,aAAa;EACvC,YAAY,MAAM,mBAAmB;EACrC,kBAAkB,aAAa,MAAM,CAAC,SAAS;EAC/C,gBAAgB,MAAM,mBAAmB;EACzC,OAAO,GAAG;EACX,CAAC,CACH"}

View File

@@ -0,0 +1,10 @@
import * as _$vue from "vue";
import { ComponentInternalInstance, Ref } from "vue";
//#region ../../packages/components/menu/src/use-menu.d.ts
declare function useMenu(instance: ComponentInternalInstance, currentIndex: Ref<string>): {
parentMenu: _$vue.ComputedRef<ComponentInternalInstance>;
indexPath: _$vue.ComputedRef<string[]>;
};
//#endregion
export { useMenu as default };

View File

@@ -0,0 +1,25 @@
import { computed } from "vue";
//#region ../../packages/components/menu/src/use-menu.ts
function useMenu(instance, currentIndex) {
const indexPath = computed(() => {
let parent = instance.parent;
const path = [currentIndex.value];
while (parent.type.name !== "ElMenu") {
if (parent.props.index) path.unshift(parent.props.index);
parent = parent.parent;
}
return path;
});
return {
parentMenu: computed(() => {
let parent = instance.parent;
while (parent && !["ElMenu", "ElSubMenu"].includes(parent.type.name)) parent = parent.parent;
return parent;
}),
indexPath
};
}
//#endregion
export { useMenu as default };
//# sourceMappingURL=use-menu.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"use-menu.mjs","names":[],"sources":["../../../../../../packages/components/menu/src/use-menu.ts"],"sourcesContent":["import { computed } from 'vue'\n\nimport type { ComponentInternalInstance, Ref } from 'vue'\n\nexport default function useMenu(\n instance: ComponentInternalInstance,\n currentIndex: Ref<string>\n) {\n const indexPath = computed(() => {\n let parent = instance.parent!\n const path = [currentIndex.value]\n while (parent.type.name !== 'ElMenu') {\n if (parent.props.index) {\n path.unshift(parent.props.index as string)\n }\n parent = parent.parent!\n }\n return path\n })\n\n const parentMenu = computed(() => {\n let parent = instance.parent\n while (parent && !['ElMenu', 'ElSubMenu'].includes(parent.type.name!)) {\n parent = parent.parent\n }\n return parent!\n })\n\n return {\n parentMenu,\n indexPath,\n }\n}\n"],"mappings":";;AAIA,SAAwB,QACtB,UACA,cACA;CACA,MAAM,YAAY,eAAe;EAC/B,IAAI,SAAS,SAAS;EACtB,MAAM,OAAO,CAAC,aAAa,MAAM;EACjC,OAAO,OAAO,KAAK,SAAS,UAAU;GACpC,IAAI,OAAO,MAAM,OACf,KAAK,QAAQ,OAAO,MAAM,MAAgB;GAE5C,SAAS,OAAO;;EAElB,OAAO;GACP;CAUF,OAAO;EACL,YATiB,eAAe;GAChC,IAAI,SAAS,SAAS;GACtB,OAAO,UAAU,CAAC,CAAC,UAAU,YAAY,CAAC,SAAS,OAAO,KAAK,KAAM,EACnE,SAAS,OAAO;GAElB,OAAO;IAIG;EACV;EACD"}

View File

@@ -0,0 +1,10 @@
import { RendererNode } from "vue";
//#region ../../packages/components/menu/src/utils/menu-bar.d.ts
declare class Menu {
domNode: RendererNode;
constructor(domNode: RendererNode, namespace: string);
init(namespace: string): void;
}
//#endregion
export { Menu as default };

View File

@@ -0,0 +1,18 @@
import MenuItem from "./menu-item.mjs";
//#region ../../packages/components/menu/src/utils/menu-bar.ts
var Menu = class {
constructor(domNode, namespace) {
this.domNode = domNode;
this.init(namespace);
}
init(namespace) {
const menuChildren = this.domNode.childNodes;
Array.from(menuChildren).forEach((child) => {
if (child.nodeType === 1) new MenuItem(child, namespace);
});
}
};
//#endregion
export { Menu as default };
//# sourceMappingURL=menu-bar.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"menu-bar.mjs","names":[],"sources":["../../../../../../../packages/components/menu/src/utils/menu-bar.ts"],"sourcesContent":["import MenuItem from './menu-item'\n\nimport type { RendererNode } from 'vue'\n\nclass Menu {\n constructor(\n public domNode: RendererNode,\n namespace: string\n ) {\n this.init(namespace)\n }\n init(namespace: string) {\n const menuChildren = this.domNode.childNodes\n Array.from<Node>(menuChildren).forEach((child) => {\n if (child.nodeType === 1) {\n new MenuItem(child as HTMLElement, namespace)\n }\n })\n }\n}\n\nexport default Menu\n"],"mappings":";;AAIA,IAAM,OAAN,MAAW;CACT,YACE,SACA,WACA;EAFO,KAAA,UAAA;EAGP,KAAK,KAAK,UAAU;;CAEtB,KAAK,WAAmB;EACtB,MAAM,eAAe,KAAK,QAAQ;EAClC,MAAM,KAAW,aAAa,CAAC,SAAS,UAAU;GAChD,IAAI,MAAM,aAAa,GACrB,IAAI,SAAS,OAAsB,UAAU;IAE/C"}

View File

@@ -0,0 +1,12 @@
import SubMenu from "./submenu.js";
//#region ../../packages/components/menu/src/utils/menu-item.d.ts
declare class MenuItem {
domNode: HTMLElement;
submenu: SubMenu | null;
constructor(domNode: HTMLElement, namespace: string);
init(namespace: string): void;
addListeners(): void;
}
//#endregion
export { MenuItem as default };

View File

@@ -0,0 +1,50 @@
import { triggerEvent } from "../../../../utils/dom/aria.mjs";
import { EVENT_CODE } from "../../../../constants/aria.mjs";
import { getEventCode } from "../../../../utils/dom/event.mjs";
import SubMenu from "./submenu.mjs";
//#region ../../packages/components/menu/src/utils/menu-item.ts
var MenuItem = class {
constructor(domNode, namespace) {
this.domNode = domNode;
this.submenu = null;
this.init(namespace);
}
init(namespace) {
this.domNode.setAttribute("tabindex", "0");
const menuChild = this.domNode.querySelector(`.${namespace}-menu`);
if (menuChild) this.submenu = new SubMenu(this, menuChild);
this.addListeners();
}
addListeners() {
this.domNode.addEventListener("keydown", (event) => {
const code = getEventCode(event);
let prevDef = false;
switch (code) {
case EVENT_CODE.down:
triggerEvent(event.currentTarget, "mouseenter");
this.submenu?.gotoSubIndex(0);
prevDef = true;
break;
case EVENT_CODE.up:
triggerEvent(event.currentTarget, "mouseenter");
this.submenu?.gotoSubIndex(this.submenu.subMenuItems.length - 1);
prevDef = true;
break;
case EVENT_CODE.tab:
triggerEvent(event.currentTarget, "mouseleave");
break;
case EVENT_CODE.enter:
case EVENT_CODE.numpadEnter:
case EVENT_CODE.space:
prevDef = true;
event.currentTarget.click();
break;
}
if (prevDef) event.preventDefault();
});
}
};
//#endregion
export { MenuItem as default };
//# sourceMappingURL=menu-item.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"menu-item.mjs","names":[],"sources":["../../../../../../../packages/components/menu/src/utils/menu-item.ts"],"sourcesContent":["import { getEventCode, triggerEvent } from '@element-plus/utils'\nimport { EVENT_CODE } from '@element-plus/constants'\nimport SubMenu from './submenu'\n\nclass MenuItem {\n public submenu: SubMenu | null\n constructor(\n public domNode: HTMLElement,\n namespace: string\n ) {\n this.submenu = null\n this.init(namespace)\n }\n\n init(namespace: string): void {\n this.domNode.setAttribute('tabindex', '0')\n const menuChild = this.domNode.querySelector(`.${namespace}-menu`)\n if (menuChild) {\n this.submenu = new SubMenu(this, menuChild)\n }\n this.addListeners()\n }\n\n addListeners() {\n this.domNode.addEventListener('keydown', (event: KeyboardEvent) => {\n const code = getEventCode(event)\n let prevDef = false\n\n switch (code) {\n case EVENT_CODE.down: {\n triggerEvent(event.currentTarget as HTMLElement, 'mouseenter')\n this.submenu?.gotoSubIndex(0)\n prevDef = true\n break\n }\n case EVENT_CODE.up: {\n triggerEvent(event.currentTarget as HTMLElement, 'mouseenter')\n this.submenu?.gotoSubIndex(this.submenu.subMenuItems.length - 1)\n prevDef = true\n break\n }\n case EVENT_CODE.tab: {\n triggerEvent(event.currentTarget as HTMLElement, 'mouseleave')\n break\n }\n case EVENT_CODE.enter:\n case EVENT_CODE.numpadEnter:\n case EVENT_CODE.space: {\n prevDef = true\n ;(event.currentTarget as HTMLElement).click()\n break\n }\n }\n if (prevDef) {\n event.preventDefault()\n }\n })\n }\n}\n\nexport default MenuItem\n"],"mappings":";;;;;AAIA,IAAM,WAAN,MAAe;CAEb,YACE,SACA,WACA;EAFO,KAAA,UAAA;EAGP,KAAK,UAAU;EACf,KAAK,KAAK,UAAU;;CAGtB,KAAK,WAAyB;EAC5B,KAAK,QAAQ,aAAa,YAAY,IAAI;EAC1C,MAAM,YAAY,KAAK,QAAQ,cAAc,IAAI,UAAU,OAAO;EAClE,IAAI,WACF,KAAK,UAAU,IAAI,QAAQ,MAAM,UAAU;EAE7C,KAAK,cAAc;;CAGrB,eAAe;EACb,KAAK,QAAQ,iBAAiB,YAAY,UAAyB;GACjE,MAAM,OAAO,aAAa,MAAM;GAChC,IAAI,UAAU;GAEd,QAAQ,MAAR;IACE,KAAK,WAAW;KACd,aAAa,MAAM,eAA8B,aAAa;KAC9D,KAAK,SAAS,aAAa,EAAE;KAC7B,UAAU;KACV;IAEF,KAAK,WAAW;KACd,aAAa,MAAM,eAA8B,aAAa;KAC9D,KAAK,SAAS,aAAa,KAAK,QAAQ,aAAa,SAAS,EAAE;KAChE,UAAU;KACV;IAEF,KAAK,WAAW;KACd,aAAa,MAAM,eAA8B,aAAa;KAC9D;IAEF,KAAK,WAAW;IAChB,KAAK,WAAW;IAChB,KAAK,WAAW;KACd,UAAU;KACT,MAAO,cAA8B,OAAO;KAC7C;;GAGJ,IAAI,SACF,MAAM,gBAAgB;IAExB"}

View File

@@ -0,0 +1,14 @@
import MenuItem from "./menu-item.js";
//#region ../../packages/components/menu/src/utils/submenu.d.ts
declare class SubMenu {
parent: MenuItem;
domNode: ParentNode;
subMenuItems: NodeListOf<HTMLLIElement>;
subIndex: number;
constructor(parent: MenuItem, domNode: ParentNode);
gotoSubIndex(idx: number): void;
addListeners(): void;
}
//#endregion
export { SubMenu as default };

View File

@@ -0,0 +1,56 @@
import { triggerEvent } from "../../../../utils/dom/aria.mjs";
import { EVENT_CODE } from "../../../../constants/aria.mjs";
import { getEventCode } from "../../../../utils/dom/event.mjs";
//#region ../../packages/components/menu/src/utils/submenu.ts
var SubMenu = class {
constructor(parent, domNode) {
this.parent = parent;
this.domNode = domNode;
this.subIndex = 0;
this.subMenuItems = this.domNode.querySelectorAll("li");
this.addListeners();
}
gotoSubIndex(idx) {
if (idx === this.subMenuItems.length) idx = 0;
else if (idx < 0) idx = this.subMenuItems.length - 1;
this.subMenuItems[idx].focus();
this.subIndex = idx;
}
addListeners() {
const parentNode = this.parent.domNode;
this.subMenuItems.forEach((el) => {
el.addEventListener("keydown", (event) => {
const code = getEventCode(event);
let prevDef = false;
switch (code) {
case EVENT_CODE.down:
this.gotoSubIndex(this.subIndex + 1);
prevDef = true;
break;
case EVENT_CODE.up:
this.gotoSubIndex(this.subIndex - 1);
prevDef = true;
break;
case EVENT_CODE.tab:
triggerEvent(parentNode, "mouseleave");
break;
case EVENT_CODE.enter:
case EVENT_CODE.numpadEnter:
case EVENT_CODE.space:
prevDef = true;
event.currentTarget.click();
break;
}
if (prevDef) {
event.preventDefault();
event.stopPropagation();
}
return false;
});
});
}
};
//#endregion
export { SubMenu as default };
//# sourceMappingURL=submenu.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"submenu.mjs","names":[],"sources":["../../../../../../../packages/components/menu/src/utils/submenu.ts"],"sourcesContent":["import { getEventCode, triggerEvent } from '@element-plus/utils'\nimport { EVENT_CODE } from '@element-plus/constants'\n\nimport type MenuItem from './menu-item'\n\nclass SubMenu {\n public subMenuItems: NodeListOf<HTMLLIElement>\n public subIndex: number\n constructor(\n public parent: MenuItem,\n public domNode: ParentNode\n ) {\n this.subIndex = 0\n this.subMenuItems = this.domNode.querySelectorAll('li')\n this.addListeners()\n }\n\n gotoSubIndex(idx: number) {\n if (idx === this.subMenuItems.length) {\n idx = 0\n } else if (idx < 0) {\n idx = this.subMenuItems.length - 1\n }\n this.subMenuItems[idx].focus()\n this.subIndex = idx\n }\n\n addListeners() {\n const parentNode = this.parent.domNode\n this.subMenuItems.forEach((el) => {\n el.addEventListener('keydown', (event: KeyboardEvent) => {\n const code = getEventCode(event)\n let prevDef = false\n\n switch (code) {\n case EVENT_CODE.down: {\n this.gotoSubIndex(this.subIndex + 1)\n prevDef = true\n break\n }\n case EVENT_CODE.up: {\n this.gotoSubIndex(this.subIndex - 1)\n prevDef = true\n break\n }\n case EVENT_CODE.tab: {\n triggerEvent(parentNode, 'mouseleave')\n break\n }\n case EVENT_CODE.enter:\n case EVENT_CODE.numpadEnter:\n case EVENT_CODE.space: {\n prevDef = true\n ;(event.currentTarget as HTMLElement).click()\n break\n }\n }\n if (prevDef) {\n event.preventDefault()\n event.stopPropagation()\n }\n return false\n })\n })\n }\n}\n\nexport default SubMenu\n"],"mappings":";;;;AAKA,IAAM,UAAN,MAAc;CAGZ,YACE,QACA,SACA;EAFO,KAAA,SAAA;EACA,KAAA,UAAA;EAEP,KAAK,WAAW;EAChB,KAAK,eAAe,KAAK,QAAQ,iBAAiB,KAAK;EACvD,KAAK,cAAc;;CAGrB,aAAa,KAAa;EACxB,IAAI,QAAQ,KAAK,aAAa,QAC5B,MAAM;OACD,IAAI,MAAM,GACf,MAAM,KAAK,aAAa,SAAS;EAEnC,KAAK,aAAa,KAAK,OAAO;EAC9B,KAAK,WAAW;;CAGlB,eAAe;EACb,MAAM,aAAa,KAAK,OAAO;EAC/B,KAAK,aAAa,SAAS,OAAO;GAChC,GAAG,iBAAiB,YAAY,UAAyB;IACvD,MAAM,OAAO,aAAa,MAAM;IAChC,IAAI,UAAU;IAEd,QAAQ,MAAR;KACE,KAAK,WAAW;MACd,KAAK,aAAa,KAAK,WAAW,EAAE;MACpC,UAAU;MACV;KAEF,KAAK,WAAW;MACd,KAAK,aAAa,KAAK,WAAW,EAAE;MACpC,UAAU;MACV;KAEF,KAAK,WAAW;MACd,aAAa,YAAY,aAAa;MACtC;KAEF,KAAK,WAAW;KAChB,KAAK,WAAW;KAChB,KAAK,WAAW;MACd,UAAU;MACT,MAAO,cAA8B,OAAO;MAC7C;;IAGJ,IAAI,SAAS;KACX,MAAM,gBAAgB;KACtB,MAAM,iBAAiB;;IAEzB,OAAO;KACP;IACF"}