hongluan-ui
Version:
Hongluan Component Library for Vue 3
322 lines (317 loc) • 11.4 kB
JavaScript
;
Object.defineProperty(exports, '__esModule', { value: true });
var vue = require('vue');
var core = require('@vueuse/core');
var index$4 = require('../../collapse-transition/index.js');
var index$3 = require('../../tooltip/index.js');
require('../../../utils/index.js');
require('../../system-icon/index.js');
var index$2 = require('../../icon/index.js');
require('../../../hooks/index.js');
var useMenu = require('./use-menu.js');
var runtime = require('../../../utils/vue/props/runtime.js');
var index = require('../../../hooks/use-deprecated/index.js');
var index$1 = require('../../../hooks/use-namespace/index.js');
var error = require('../../../utils/error.js');
var arrowRight = require('../../system-icon/src/arrow-right.js');
const subMenuProps = runtime.buildProps({
index: {
type: String,
required: true
},
showTimeout: Number,
hideTimeout: Number,
fallbackPlacements: {
type: runtime.definePropType(Array)
},
popperClass: String,
disabled: Boolean,
teleported: {
type: Boolean,
default: void 0
},
popperAppendToBody: {
type: Boolean,
default: void 0
},
popperOffset: Number
});
const COMPONENT_NAME = "SubMenu";
var SubMenu = vue.defineComponent({
name: COMPONENT_NAME,
props: subMenuProps,
setup(props, { slots, expose }) {
var _a;
index.useDeprecated({
from: "popper-append-to-body",
replacement: "teleported",
scope: COMPONENT_NAME,
version: "2.5.0",
ref: "https://element-plus.org/en-US/component/menu.html#submenu-attributes"
}, vue.computed(() => props.popperAppendToBody !== void 0));
const instance = vue.getCurrentInstance();
const { namespace } = index$1.useNamespace();
const { indexPath, parentMenu } = useMenu["default"](instance, vue.computed(() => props.index));
const rootMenu = vue.inject("rootMenu");
if (!rootMenu)
error.throwError(COMPONENT_NAME, "can not inject root menu");
const subMenu = vue.inject(`subMenu:${(_a = parentMenu.value) == null ? void 0 : _a.uid}`);
if (!subMenu)
error.throwError(COMPONENT_NAME, "can not inject sub menu");
const items = vue.ref({});
const subMenus = vue.ref({});
let timeout;
const mouseInChild = vue.ref(false);
const verticalTitleRef = vue.ref();
const vPopper = vue.ref(null);
const currentPlacement = vue.computed(() => mode.value === "horizontal" && isFirstLevel.value ? "bottom-start" : "right-start");
const isFirstLevel = vue.computed(() => {
let isFirstLevel2 = true;
let parent = instance.parent;
while (parent && parent.type.name !== "Menu") {
if (["SubMenu", "MenuItemGroup"].includes(parent.type.name)) {
isFirstLevel2 = false;
break;
} else {
parent = parent.parent;
}
}
return isFirstLevel2;
});
const appendToBody = vue.computed(() => {
var _a2;
const value = (_a2 = props.teleported) != null ? _a2 : props.popperAppendToBody;
return value === void 0 ? isFirstLevel.value : value;
});
const menuTransitionName = vue.computed(() => rootMenu.finalCollapse ? "zoom-in-left" : "zoom-in-top");
const fallbackPlacements = vue.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 = vue.computed(() => rootMenu.openedMenus.includes(props.index));
const active = vue.computed(() => {
let isActive = false;
Object.values(items.value).forEach((item2) => {
if (item2.active) {
isActive = true;
}
});
Object.values(subMenus.value).forEach((subItem) => {
if (subItem.active) {
isActive = true;
}
});
return isActive;
});
const backgroundColor = vue.computed(() => rootMenu.props.backgroundColor || "");
const activeTextColor = vue.computed(() => rootMenu.props.activeTextColor || "");
const textColor = vue.computed(() => rootMenu.props.textColor || "");
const mode = vue.computed(() => rootMenu.props.mode);
const item = vue.reactive({
index: props.index,
indexPath,
active
});
const titleStyle = vue.computed(() => {
if (mode.value !== "horizontal") {
return {
color: textColor.value
};
}
return {
borderBottomColor: active.value ? rootMenu.props.activeTextColor ? activeTextColor.value : "" : "transparent",
color: active.value ? activeTextColor.value : textColor.value
};
});
const subMenuPopperOffset = vue.computed(() => {
var _a2;
return (_a2 = props.popperOffset) != null ? _a2 : rootMenu.props.popperOffset;
});
const subMenuPopperClass = vue.computed(() => {
var _a2;
return (_a2 = props.popperClass) != null ? _a2 : rootMenu.props.popperClass;
});
const subMenuShowTimeout = vue.computed(() => {
var _a2;
return (_a2 = props.showTimeout) != null ? _a2 : rootMenu.props.showTimeout;
});
const subMenuHideTimeout = vue.computed(() => {
var _a2;
return (_a2 = props.hideTimeout) != null ? _a2 : rootMenu.props.hideTimeout;
});
const doDestroy = () => {
var _a2, _b, _c;
return (_c = (_b = (_a2 = vPopper.value) == null ? void 0 : _a2.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.finalCollapse && 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 _a2;
if (event.type === "focus") {
return;
}
if (rootMenu.props.menuTrigger === "click" && rootMenu.props.mode === "horizontal" || !rootMenu.finalCollapse && rootMenu.props.mode === "vertical" || props.disabled) {
subMenu.mouseInChild.value = true;
return;
}
subMenu.mouseInChild.value = true;
timeout == null ? void 0 : timeout();
({ stop: timeout } = core.useTimeoutFn(() => {
rootMenu.openMenu(props.index, indexPath.value);
}, showTimeout));
if (appendToBody.value) {
(_a2 = parentMenu.value.vnode.el) == null ? void 0 : _a2.dispatchEvent(new MouseEvent("mouseenter"));
}
};
const handleMouseleave = (deepDispatch = false) => {
var _a2;
if (rootMenu.props.menuTrigger === "click" && rootMenu.props.mode === "horizontal" || !rootMenu.finalCollapse && rootMenu.props.mode === "vertical") {
subMenu.mouseInChild.value = false;
return;
}
timeout == null ? void 0 : timeout();
subMenu.mouseInChild.value = false;
({ stop: timeout } = core.useTimeoutFn(() => !mouseInChild.value && rootMenu.closeMenu(props.index, indexPath.value), subMenuHideTimeout.value));
if (appendToBody.value && deepDispatch) {
(_a2 = subMenu.handleMouseleave) == null ? void 0 : _a2.call(subMenu, true);
}
};
vue.watch(() => rootMenu.finalCollapse, (value) => handleCollapseToggle(Boolean(value)));
{
const addSubMenu = (item2) => {
subMenus.value[item2.index] = item2;
};
const removeSubMenu = (item2) => {
delete subMenus.value[item2.index];
};
vue.provide(`subMenu:${instance.uid}`, {
addSubMenu,
removeSubMenu,
handleMouseleave,
mouseInChild
});
}
expose({
opened
});
vue.onMounted(() => {
rootMenu.addSubMenu(item);
subMenu.addSubMenu(item);
});
vue.onBeforeUnmount(() => {
subMenu.removeSubMenu(item);
rootMenu.removeSubMenu(item);
});
return () => {
var _a2, _b, _c;
const titleTag = [
(_a2 = slots.title) == null ? void 0 : _a2.call(slots),
slots.icon ? (_b = slots.icon) == null ? void 0 : _b.call(slots, { opened: opened.value, collapse: rootMenu.finalCollapse }) : vue.h(index$2.HlIcon, {
class: ["menu-arrow"]
}, { default: () => vue.h(arrowRight["default"]) })
];
const child = rootMenu.isMenuPopup ? vue.h(index$3.HlTooltip, {
ref: vPopper,
manualMode: true,
visible: opened.value,
offset: subMenuPopperOffset.value,
showArrow: false,
persistent: true,
popperClass: `${(_c = subMenuPopperClass.value) != null ? _c : ""} ${namespace.value}-menu-popper`,
placement: currentPlacement.value,
teleported: appendToBody.value,
fallbackPlacements: fallbackPlacements.value,
transition: menuTransitionName.value,
gpuAcceleration: false
}, {
content: () => {
var _a3;
return vue.h("div", {
class: [`menu-${mode.value}`, subMenuPopperClass.value],
onMouseenter: (evt) => handleMouseenter(evt, 100),
onMouseleave: () => handleMouseleave(true),
onFocus: (evt) => handleMouseenter(evt, 100)
}, [
vue.h("ul", {
class: [
namespace.value + "-menu menu-dropdown",
`popup-${currentPlacement.value}`
]
}, [(_a3 = slots.default) == null ? void 0 : _a3.call(slots)])
]);
},
default: () => vue.h("div", {
class: "item-content",
style: [
titleStyle.value,
{ backgroundColor: backgroundColor.value }
],
onClick: handleClick
}, titleTag)
}) : vue.h(vue.Fragment, {}, [
vue.h("div", {
class: "item-content",
style: [
titleStyle.value,
{ backgroundColor: backgroundColor.value }
],
ref: verticalTitleRef,
onClick: handleClick
}, titleTag),
vue.h(index$4.HlCollapseTransition, {}, {
default: () => {
var _a3;
return vue.withDirectives(vue.h("ul", {
role: "menu",
class: namespace.value + "-menu menu-inline"
}, [(_a3 = slots.default) == null ? void 0 : _a3.call(slots)]), [[vue.vShow, opened.value]]);
}
})
]);
return vue.h("li", {
class: [
`${namespace.value}-menu-item ${namespace.value}-sub-menu`,
{
"is-active": active.value,
"is-opened": opened.value,
"is-disabled": props.disabled
}
],
role: "menuitem",
ariaHaspopup: true,
ariaExpanded: opened.value,
onMouseenter: handleMouseenter,
onMouseleave: () => handleMouseleave(),
onFocus: handleMouseenter
}, [child]);
};
}
});
exports["default"] = SubMenu;
exports.subMenuProps = subMenuProps;
//# sourceMappingURL=sub-menu.js.map