@zhsz/cool-design-crud
Version:
216 lines (215 loc) • 5.98 kB
JavaScript
;
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
const vue = require("vue");
const index = require("../../utils/index.js");
require("../../utils/test.js");
const core = require("../../hooks/core.js");
require("@formily/core");
const lodashEs = require("lodash-es");
require("../../hooks/table.js");
const isComponent = (obj) => {
if (obj && typeof obj.render === "function") {
return true;
} else {
return false;
}
};
const ClContextMenu = /* @__PURE__ */ vue.defineComponent({
name: "cl-context-menu",
props: {
show: Boolean,
options: {
type: Object,
default: () => {
return {};
}
},
customVnode: [Function, Object],
customClass: String,
event: {
type: Object,
default: () => {
return {};
}
}
},
setup(props, {
expose,
slots
}) {
const {
refs,
setRefs
} = core.useRefs();
const visible = vue.ref(props.show || false);
const list = vue.ref([]);
const style = vue.reactive({
left: "0px",
top: "0px"
});
const customVnode = vue.ref(false);
const customClass = vue.ref("");
const ids = vue.ref("");
function stopDefault(e) {
if (e.preventDefault) {
e.preventDefault();
}
if (e.stopPropagation) {
e.stopPropagation();
}
}
function parseList(list2) {
function deep(list3) {
list3.forEach((e) => {
e.showChildren = false;
if (e.children) {
deep(e.children);
}
});
}
deep(list2);
return list2;
}
let targetEl = null;
function close() {
visible.value = false;
ids.value = "";
index.removeClass(targetEl, "cl-context-menu__target");
}
function open(event, options) {
let left = event.pageX;
let top = event.pageY;
if (!options) {
options = {};
}
if (options.hover) {
const d = options.hover === true ? {} : options.hover;
targetEl = event.target;
if (targetEl && index.isString(targetEl.className)) {
if (d.target) {
while (!targetEl.className.includes(d.target)) {
targetEl = targetEl.parentNode;
}
}
index.addClass(targetEl, d.className || "cl-context-menu__target");
}
}
if (options.list) {
list.value = parseList(options.list);
}
if (options.customVnode) {
if (lodashEs.isFunction(options.customVnode)) {
customVnode.value = options.customVnode();
}
if (isComponent(options.customVnode)) {
customVnode.value = vue.h(options.customVnode);
}
}
if (options.customClass) {
customClass.value = options.customClass;
}
stopDefault(event);
visible.value = true;
vue.nextTick(() => {
const {
clientHeight: h1,
clientWidth: w1
} = event.target.ownerDocument.body;
const {
clientHeight: h2,
clientWidth: w2
} = refs["context-menu"].querySelector(".cl-context-menu__box");
if (top + h2 > h1) {
top = h1 - h2 - 5;
}
if (left + w2 > w1) {
left = w1 - w2 - 5;
}
style.left = `${left}px`;
style.top = `${top}px`;
});
return {
close
};
}
function rowClick(item, id) {
ids.value = id;
if (item.disabled) {
return false;
}
if (item.callback) {
return item.callback(close);
}
if (item.children) {
item.showChildren = !item.showChildren;
} else {
close();
}
}
expose({
open,
close
});
vue.onMounted(() => {
if (visible.value) {
const {
body,
documentElement
} = props.event.target.ownerDocument;
body.appendChild(refs["context-menu"]);
(documentElement || body).addEventListener("mousedown", (e) => {
const el = refs["context-menu"];
if (!index.contains(el, e.target) && el !== e.target) {
close();
}
});
open(props.event, props.options);
}
});
return () => {
function deep(list2, pId, level) {
return vue.createVNode("div", {
"class": ["cl-context-menu__box", level > 1 && "is-append"]
}, [list2.filter((e) => !e.hidden).map((e, i) => {
const id = `${pId}-${i}`;
return vue.createVNode("div", {
"class": {
"is-active": ids.value.includes(id),
"is-ellipsis": e.ellipsis,
"is-disabled": e.disabled
}
}, [e.prefixIcon && vue.createVNode("i", {
"class": e.prefixIcon
}, null), vue.createVNode("span", {
"onClick": () => {
rowClick(e, id);
}
}, [e.label]), e.suffixIcon && vue.createVNode("i", {
"class": e.suffixIcon
}, null), e.children && e.showChildren && deep(e.children, id, level + 1)]);
})]);
}
return visible.value && vue.createVNode("div", {
"class": ["cl-context-menu", `${customClass.value}_parent`],
"ref": setRefs("context-menu"),
"style": style,
"onContextmenu": stopDefault
}, [slots.default ? slots.default() : customVnode.value === false ? deep(list.value, "0", 1) : vue.createVNode("div", {
"class": ["cl-context-menu__box", customClass.value]
}, [customVnode.value])]);
};
}
});
const ContextMenu = {
open(event, options) {
const vm = vue.h(ClContextMenu, {
show: true,
event,
options
});
vue.render(vm, event.target.ownerDocument.createElement("div"));
}
};
exports.ContextMenu = ContextMenu;
exports.default = ClContextMenu;
exports.isComponent = isComponent;