123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282 |
- import { defineComponent, getCurrentInstance, computed, inject, ref, reactive, watch, provide, onMounted, onBeforeUnmount, h, Fragment, withDirectives, vShow } from 'vue';
- import { useTimeoutFn } from '@vueuse/core';
- import { ElCollapseTransition } from '../../collapse-transition/index.mjs';
- import { ElTooltip } from '../../tooltip/index.mjs';
- import { ArrowDown, ArrowRight } from '@element-plus/icons-vue';
- import { ElIcon } from '../../icon/index.mjs';
- import useMenu from './use-menu.mjs';
- import { useMenuCssVar } from './use-menu-css-var.mjs';
- import { buildProps } from '../../../utils/vue/props/runtime.mjs';
- import { iconPropType } from '../../../utils/vue/icon.mjs';
- import { useNamespace } from '../../../hooks/use-namespace/index.mjs';
- import { throwError } from '../../../utils/error.mjs';
- import { isUndefined } from '../../../utils/types.mjs';
- import { isString } from '@vue/shared';
- const subMenuProps = buildProps({
- index: {
- type: String,
- required: true
- },
- showTimeout: Number,
- hideTimeout: Number,
- popperClass: String,
- disabled: Boolean,
- teleported: {
- type: Boolean,
- default: void 0
- },
- popperOffset: Number,
- expandCloseIcon: {
- type: iconPropType
- },
- expandOpenIcon: {
- type: iconPropType
- },
- collapseCloseIcon: {
- type: iconPropType
- },
- collapseOpenIcon: {
- type: iconPropType
- }
- });
- const COMPONENT_NAME = "ElSubMenu";
- var SubMenu = 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("rootMenu");
- if (!rootMenu)
- throwError(COMPONENT_NAME, "can not inject root menu");
- const subMenu = inject(`subMenu:${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 currentPlacement = computed(() => mode.value === "horizontal" && isFirstLevel.value ? "bottom-start" : "right-start");
- const subMenuTitleIcon = computed(() => {
- return mode.value === "horizontal" && isFirstLevel.value || mode.value === "vertical" && !rootMenu.props.collapse ? props.expandCloseIcon && props.expandOpenIcon ? opened.value ? props.expandOpenIcon : props.expandCloseIcon : ArrowDown : props.collapseCloseIcon && props.collapseOpenIcon ? opened.value ? props.collapseOpenIcon : props.collapseCloseIcon : ArrowRight;
- });
- const isFirstLevel = computed(() => subMenu.level === 0);
- 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: active2 }) => active2));
- 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(() => {
- var _a;
- return (_a = props.popperOffset) != null ? _a : rootMenu.props.popperOffset;
- });
- const subMenuPopperClass = computed(() => {
- var _a;
- return (_a = props.popperClass) != null ? _a : rootMenu.props.popperClass;
- });
- const subMenuShowTimeout = computed(() => {
- var _a;
- return (_a = props.showTimeout) != null ? _a : rootMenu.props.showTimeout;
- });
- const subMenuHideTimeout = computed(() => {
- var _a;
- return (_a = props.hideTimeout) != null ? _a : rootMenu.props.hideTimeout;
- });
- const doDestroy = () => {
- var _a, _b, _c;
- return (_c = (_b = (_a = vPopper.value) == null ? void 0 : _a.popperRef) == null ? void 0 : _b.popperInstanceRef) == null ? void 0 : _c.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) => {
- var _a;
- 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 == null ? void 0 : timeout();
- ({ stop: timeout } = useTimeoutFn(() => {
- rootMenu.openMenu(props.index, indexPath.value);
- }, showTimeout));
- if (appendToBody.value) {
- (_a = parentMenu.value.vnode.el) == null ? void 0 : _a.dispatchEvent(new MouseEvent("mouseenter"));
- }
- };
- const handleMouseleave = (deepDispatch = false) => {
- var _a;
- if (rootMenu.props.menuTrigger === "click" && rootMenu.props.mode === "horizontal" || !rootMenu.props.collapse && rootMenu.props.mode === "vertical") {
- subMenu.mouseInChild.value = false;
- return;
- }
- timeout == null ? void 0 : timeout();
- subMenu.mouseInChild.value = false;
- ({ stop: timeout } = useTimeoutFn(() => !mouseInChild.value && rootMenu.closeMenu(props.index, indexPath.value), subMenuHideTimeout.value));
- if (appendToBody.value && deepDispatch) {
- (_a = subMenu.handleMouseleave) == null ? void 0 : _a.call(subMenu, true);
- }
- };
- watch(() => rootMenu.props.collapse, (value) => handleCollapseToggle(Boolean(value)));
- {
- const addSubMenu = (item2) => {
- subMenus.value[item2.index] = item2;
- };
- const removeSubMenu = (item2) => {
- delete subMenus.value[item2.index];
- };
- provide(`subMenu:${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 () => {
- var _a;
- const titleTag = [
- (_a = slots.title) == null ? void 0 : _a.call(slots),
- 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,
- placement: currentPlacement.value,
- teleported: appendToBody.value,
- fallbackPlacements: fallbackPlacements.value,
- transition: menuTransitionName.value,
- gpuAcceleration: false
- }, {
- content: () => {
- var _a2;
- return 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
- }, [(_a2 = slots.default) == null ? void 0 : _a2.call(slots)])
- ]);
- },
- 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: () => {
- var _a2;
- return withDirectives(h("ul", {
- role: "menu",
- class: [nsMenu.b(), nsMenu.m("inline")],
- style: ulStyle.value
- }, [(_a2 = slots.default) == null ? void 0 : _a2.call(slots)]), [[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]);
- };
- }
- });
- export { SubMenu as default, subMenuProps };
- //# sourceMappingURL=sub-menu.mjs.map
|