UNPKG

double-ui-vue

Version:
1,625 lines (1,624 loc) 45 kB
import { openBlock, createElementBlock, createElementVNode, defineComponent, computed, isRef, createVNode, Transition, withDirectives, Fragment, vShow, render as render$3, reactive, watch, onBeforeUnmount, ref, getCurrentInstance, nextTick, onMounted, createTextVNode, createStaticVNode, toRaw } from "vue"; var style$4 = ""; var style$3 = ""; var V = (e, t) => { let r = e.tagName.toLocaleLowerCase(); return r === "body" || t.some((o) => o.toLocaleLowerCase() === r) ? e : V(e.parentNode, t); }, M = V; var Ze = ({ trigger: e, dom: t, offset: r = 8, isRight: o = false }) => { let n, a, i = true, { clientWidth: s, clientHeight: l } = document.documentElement, { pageXOffset: c, pageYOffset: f } = window, h = document.body, g = t.cloneNode(true); g.style.position = "absolute", g.style.left = "0", g.style.top = "0", g.style.display = "inline-block", h.appendChild(g); let { width: u, height: b } = g.getBoundingClientRect(); h.removeChild(g), g = null; let { left: m, top: w, width: D, height: L } = e.getBoundingClientRect(), K = w, X = l - w - L - r, p = m + D, x = s - m, T = m < 0, k = m + D > s; return o ? k && T ? n = s - u : k ? (x = s - m, x > u ? n = m : n = s - u) : T ? (p = D + m, p >= u ? n = p - u : n = 0) : p >= u ? n = p - u : x >= u ? n = m : n = s - u : T && k ? n = 0 : m < 0 ? (p = D + m, p >= u ? n = p - u : n = 0) : m + D > s ? (x = s - m, x >= u ? n = m : n = s - u) : x >= u ? n = m : p >= u ? n = p - u : n = s - u, X >= b ? a = w + L + r : K >= b ? (a = w - b - r, i = false) : a = l - b, n = n + c, a = a + f, { left: n, top: a, isDown: i }; }, qe = Ze; var _t = (e, t) => { let r = e.target; t && (r = M(r, [t])); let { clientWidth: o, scrollWidth: n } = r; n > o ? r.title = r.innerText : r.title = ""; }, Kt = _t; const _hoisted_1$2 = { viewBox: "0 0 16 16", xmlns: "http://www.w3.org/2000/svg" }; const _hoisted_2$2 = /* @__PURE__ */ createElementVNode("path", { d: "m8.39 5.988 2.96 3.7a.5.5 0 0 1-.39.812H5.04a.5.5 0 0 1-.39-.812l2.96-3.7a.5.5 0 0 1 .78 0Z", class: "svg-fill-grey-500" }, null, -1); const _hoisted_3$2 = [ _hoisted_2$2 ]; function render$2(_ctx, _cache) { return openBlock(), createElementBlock("svg", _hoisted_1$2, _hoisted_3$2); } var TriangleIcon = { render: render$2 }; const _hoisted_1$1 = { viewBox: "0 0 16 16", xmlns: "http://www.w3.org/2000/svg" }; const _hoisted_2$1 = /* @__PURE__ */ createElementVNode("path", { d: "M8 1a7 7 0 1 0 0 14A7 7 0 0 0 8 1Zm2.784 8.637a.656.656 0 0 1-.928.929L8 8.709l-1.856 1.857a.656.656 0 0 1-.928-.929l1.856-1.856-1.856-1.856a.656.656 0 0 1 .928-.928L8 6.853l1.856-1.856a.656.656 0 0 1 .928.928L8.928 7.781l1.856 1.856Z", class: "svg-fill-grey-500", "fill-rule": "evenodd" }, null, -1); const _hoisted_3$1 = [ _hoisted_2$1 ]; function render$1(_ctx, _cache) { return openBlock(), createElementBlock("svg", _hoisted_1$1, _hoisted_3$1); } var DeleteIcon = { render: render$1 }; const _hoisted_1 = { viewBox: "0 0 16 16", xmlns: "http://www.w3.org/2000/svg" }; const _hoisted_2 = /* @__PURE__ */ createElementVNode("path", { d: "m8.027 7.074 5.387-5.388 1.078 1.078L9.104 8.15l5.388 5.388-1.078 1.077L8.027 9.23l-5.388 5.387-1.077-1.077L6.949 8.15 1.562 2.764l1.077-1.078 5.388 5.388Z", class: "svg-fill-grey-500" }, null, -1); const _hoisted_3 = [ _hoisted_2 ]; function render(_ctx, _cache) { return openBlock(), createElementBlock("svg", _hoisted_1, _hoisted_3); } var CloseIcon = { render }; const GetScrollbarWidth = () => { const oDiv = document.createElement("div"); oDiv.style.cssText = "position:absolute;top:-1000px;width:100px;height:100px;overflow:hidden;opacity:0;"; const noScroll = document.body.appendChild(oDiv).clientWidth; oDiv.style.overflowY = "scroll"; const scroll = oDiv.clientWidth; document.body.removeChild(oDiv); const bw = noScroll - scroll; return bw < 6 ? 6 : bw; }; var style$2 = ""; const TipModal = defineComponent({ name: "TipModal", props: { tag: { type: Object, default: () => ({}) }, countTag: { type: Object, default: () => ({}) }, position: { type: Boolean, default: false }, tipShow: { type: Boolean, default: false }, dropShow: { type: Boolean, default: false }, content: { type: String, default: "" }, split: { type: Boolean, default: true }, changeTipShow: { type: Function, default: () => { } }, tipHandle: { type: Function, default: () => { } } }, setup(props) { const getScrollWidth = (text) => { const maxWidth = 452; const div = document.createElement("div"); div.innerText = text; div.style.position = "absolute"; div.style.left = "0"; div.style.bottom = "0"; div.style.zIndex = "-100"; div.style.display = "inline-block"; div.style.height = "0"; div.style.opacity = "0"; div.style.overflow = "hidden"; div.style.whiteSpace = "nowrap"; div.style.fontSize = "14px"; document.body.appendChild(div); const { scrollWidth } = div; document.body.removeChild(div); return scrollWidth > maxWidth ? scrollWidth - maxWidth : 0; }; const contentArr = computed(() => { const content = isRef(props.content) ? props.content.value : props.content; if (!content) return []; return content.split("\u3001").map((d, i) => ({ id: `content-${i}`, text: d, scroll: d.length > 32 ? getScrollWidth(d) : 0 })); }); const popoverTipHandle = (str) => { if (!props.split) return; props.tipHandle(str); }; const contentEnter = () => { if (props.split) return; props.changeTipShow(false); }; return () => { const { split, content, tipShow, position } = props; return createVNode(Transition, { "name": position ? "selectDownUpExtend" : "selectDownUpExtendTop" }, { default: () => [withDirectives(createVNode("div", { "class": ["d-popover-tip", split ? "d-popover-tip-split" : "d-popover-tip-words", position ? "d-popover-tip-bottom" : "d-popover-tip-top"], "onWheel": (e) => e.stopPropagation(), "onMouseenter": () => popoverTipHandle("enter"), "onMouseleave": () => popoverTipHandle("leave") }, [createVNode("section", { "class": "d-popover-tip-content", "onMouseenter": contentEnter }, [split ? createVNode(Fragment, null, [contentArr.value.map((item) => createVNode("article", { "class": ["d-popover-tip-content-item", item.scroll && "d-popover-tip-content-item-before"] }, [createVNode("span", { "key": item.id, "class": "d-popover-tip-item-text", "style": { transform: `translateX(${-item.scroll}px)` } }, [item.text])]))]) : createVNode("article", { "class": "d-popover-tip-content-words" }, [isRef(content) ? content.value : content])]), createVNode("section", { "class": "d-popover-tip-triangle" }, null)]), [[vShow, tipShow]])] }); }; } }); const CountWh = (vm) => { const { content, split } = vm.component.props; const contentArr = (isRef(content) ? content.value : content).split("\u3001"); const { body } = document; const element = document.createElement("div"); element.className = "d-popover-tip"; element.style.left = "0"; element.style.bottom = "0"; element.style.opacity = "0"; element.style.zIndex = "-100"; let html = '<section class="d-popover-tip-content">'; if (split) { contentArr.forEach((d) => { html += `<article class="d-popover-tip-content-item"><span class="d-popover-tip-item-text">${d}</span></article>`; }); } else { html += `<article class="d-popover-tip-content-words">${content}</article>`; } html += "</section>"; element.innerHTML = html; body.appendChild(element); const { width, height } = element.getBoundingClientRect(); body.removeChild(element); const scrollWidth = GetScrollbarWidth(); return { width, height, scrollWidth }; }; const createArticle = (str) => { const article = document.createElement("article"); article.className = "d-popover-tip-content-item"; article.style.display = "inline-block"; article.style.height = "0"; article.style.opacity = "0"; article.innerHTML = `<span class="d-popover-tip-item-text">${str}</span>`; document.body.appendChild(article); const w = article.clientWidth + 4; document.body.removeChild(article); return w; }; const countContentWidth = (vm) => { const { component: { props: { content } } } = vm; const contentArr = (isRef(content) ? content.value : content).split("\u3001"); const numArr = []; const len = contentArr.length; let num = 0; for (let i = 0; i < len; i++) { const iw = createArticle(contentArr[i]); num += iw; if (num > 468) { numArr.push(num - iw); if (i === len - 1) numArr.push(num); else num = iw; } else if (num === 468) { return 468; } } return numArr && numArr.length ? Math.max(...numArr) : num; }; const CalcPopoverTipPosition = (triggerDom, targetHeight) => { const { clientHeight } = document.body; const { pageYOffset } = window; const { top, height } = triggerDom.getBoundingClientRect(); let targetOffsetY; let P = true; const triggerPositionTop = top - 8; const triggerPositionBtm = clientHeight - (top + height + 8); if (triggerPositionTop >= targetHeight) { targetOffsetY = triggerPositionTop - targetHeight + pageYOffset; P = false; } else if (triggerPositionBtm >= targetHeight) { targetOffsetY = top + height + 8 + pageYOffset; } else { targetOffsetY = clientHeight - targetHeight + pageYOffset; } return { Y: targetOffsetY, P }; }; const resetPosition$1 = (instance) => { const { vm, tag, countTag } = instance; const isr = isRef(vm.component.props.content); if (!(isr ? vm.component.props.content.value : vm.component.props.content)) { return; } const { innerWidth, pageXOffset } = window; const tagEle = isRef(tag) ? tag.value : tag; const countTagEle = isRef(countTag) ? countTag.value : countTag; const { left: tagLeft, width: tagWidth } = tagEle.getBoundingClientRect(); const { left: cLeft, width: cWidth } = countTagEle.getBoundingClientRect(); if (innerWidth <= cLeft + cWidth / 2 || innerWidth <= cWidth || cLeft < 0) return; const { width, height, scrollWidth } = CountWh(vm); const { Y, P } = CalcPopoverTipPosition(tagEle, height); if (vm.component.props.split) { const maxWidth = countContentWidth(vm) + 13; vm.el.style.maxWidth = `${maxWidth}px`; } vm.component.props.position = P; vm.el.style.top = `${Y}px`; const triangle = vm.el.lastChild; let popoverLeft = 0; let triangleLeft; if (width === innerWidth) { if (pageXOffset > 0) popoverLeft = 0; triangleLeft = cLeft + cWidth / 2 - 6; } else { if (tagLeft === 0) { popoverLeft = 0; } else { const discoverWidth = innerWidth - tagLeft; const centerPlace = cLeft + cWidth / 2; const popoverLeftWidth = width / 2; if (centerPlace < popoverLeftWidth) { popoverLeft = 0; } else if (width <= tagWidth) { if (width <= discoverWidth) popoverLeft = centerPlace - popoverLeftWidth; else popoverLeft = innerWidth - width; } else { if (centerPlace >= popoverLeftWidth) { if (innerWidth - centerPlace <= popoverLeftWidth) { popoverLeft = innerWidth - width - scrollWidth; } else popoverLeft = centerPlace - popoverLeftWidth; } else { popoverLeft = 0; } } } triangleLeft = cLeft - popoverLeft + cWidth / 2 - 6; } vm.el.style.left = `${popoverLeft + pageXOffset}px`; triangle.style.left = `${triangleLeft}px`; instance.setShow(true); }; let dom$1; const TipModalHandle = (options) => { const { tipShow, props, changeTipShow, tipHandle } = options; const { tag, countTag } = props; if (!dom$1) { dom$1 = document.createElement("div"); document.body.appendChild(dom$1); } const vm = createVNode(TipModal, { tipShow, ...props, changeTipShow, tipHandle }); const instance = { vm, tag, countTag, setContent(content) { vm.component.props.content = content; }, setShow: changeTipShow, resetPosition() { resetPosition$1(instance); }, remove() { if (vm.component.isUnmounted) return; render$3(null, dom$1); } }; render$3(vm, dom$1); return instance; }; const PopoverTip = defineComponent({ name: "PopoverTip", props: { tag: { type: Object, default: () => ({}) }, countTag: { type: Object, default: () => ({}) }, content: { type: String, default: "" }, split: { type: Boolean, default: true }, dropShow: { type: Boolean, default: false } }, setup(props, { slots }) { let tipModal; let enterTimer; let leaveTimer; const state = reactive({ tipShow: false }); const changeTipShow = (status) => { state.tipShow = status; if (tipModal) tipModal.vm.component.props.tipShow = status; }; PopoverTip.changeTipShow = changeTipShow; const tipHandle = (str) => { if (str === "enter") { clearTimeout(leaveTimer); leaveTimer = null; } else { leaveTimer = window.setTimeout(() => { changeTipShow(false); }, 500); } }; const mouseEnter = () => { if (leaveTimer) { clearTimeout(leaveTimer); leaveTimer = null; } if (!props.content || props.dropShow || state.tipShow) return; enterTimer = window.setTimeout(() => { if (tipModal) { tipModal.resetPosition(); } else { tipModal = TipModalHandle({ tipShow: state.tipShow, props, changeTipShow, tipHandle }); if (tipModal) tipModal.resetPosition(); PopoverTip.tipModal = tipModal; } }, 360); }; const mouseLeave = () => { if (!props.content) return; if (enterTimer) { clearTimeout(enterTimer); enterTimer = null; } leaveTimer = window.setTimeout(() => { if (tipModal) tipModal.setShow(false); }, 500); }; watch(() => props.content, (n, o) => { if (n === o || !tipModal) return; tipModal.vm.component.props.content = n; }); onBeforeUnmount(() => { if (enterTimer) clearTimeout(enterTimer); if (leaveTimer) clearTimeout(leaveTimer); if (tipModal) tipModal.remove(); }); return () => createVNode("span", { "onMouseenter": mouseEnter, "onMouseleave": mouseLeave }, [slots.default()]); } }); const GetCaptionWidth = (str) => { const { body } = document; const div = document.createElement("div"); div.className = "d-drop-trigger-caption"; div.innerText = str; div.style.position = "absolute"; div.style.zIndex = "-1"; div.style.left = "0"; div.style.bottom = "0"; div.style.height = "0px"; body.appendChild(div); const { width } = div.getBoundingClientRect(); const w = Math.ceil(width); body.removeChild(div); if (w > 98) return 98; return w; }; const GetPopoverContent = (data) => { if (data instanceof Array && JSON.stringify(data).length > 4) { const names = []; data.forEach((d) => { names.push(d.name); }); return names.toString().replace(/,/g, "\u3001"); } return ""; }; const DropTrigger = defineComponent({ name: "DropTrigger", props: { width: { type: [String, Number], default: "" }, type: { type: String, default: "normal" }, placeholder: { type: String, default: "\u8BF7\u9009\u62E9" }, caption: { type: String, default: "" }, disabled: { type: Boolean, default: false }, clearHide: { type: Boolean, default: false }, openSearch: { type: Boolean, default: true }, dropSearch: { type: Boolean, default: false }, multiple: { type: Boolean, default: false }, selectedData: { type: Object || Array, default: [] }, dropShow: { type: Boolean, default: false }, errorText: { type: String, default: "" }, errorShow: { type: Boolean, default: false }, onClick: { type: Function, default: () => { } }, onGetInputText: { type: Function, default: () => { } }, delHandle: { type: Function, default: () => { } } }, emits: ["getInputText", "click", "clearItem"], setup(props, { emit }) { const state = reactive({ inputText: "", readonlyActive: true, inputShow: false, inputStatus: null, captionWidth: 0, scrollbarWidth: 6, errorTop: 0, popoverTipContent: "" }); state.popoverTipContent = GetPopoverContent(props.selectedData); const tag = ref(null); const countTag = ref(null); const popoverTip = ref(null); const { proxy } = getCurrentInstance(); const hasColon = computed(() => { const { caption } = props; return caption.includes(":") || caption.includes("\uFF1A"); }); const hasSelected = computed(() => { const { multiple, selectedData = {} } = props; const len = JSON.stringify(selectedData).length; if (multiple) return len > 4; return len > 2; }); const tabMaxWidth = computed(() => { const { width = 120 } = props; const { scrollbarWidth = 6 } = state; const w = Number(width); return w - scrollbarWidth - 64; }); let timerInputText = null; watch(() => state.inputText, (n, o) => { if (n === o) return; if (timerInputText) clearTimeout(timerInputText); timerInputText = window.setTimeout(() => { emit("getInputText", n); }, 500); }); watch(() => props.caption, (n, o) => { if (n === o) return; if (props.type === "tag") return; if (n) state.captionWidth = GetCaptionWidth(n); }); watch(() => props.dropShow, (n, o) => { if (n === o) return; if (props.type === "tag") return; setTimeout(() => { state.inputShow = n; if (n) { if (!props.multiple || !popoverTip.value) return; popoverTip.value.$options.changeTipShow(false); } else { state.inputStatus = null; state.inputText = ""; } }, 300); }); watch(() => props.selectedData, (n, o) => { const nd = JSON.stringify(n); const od = JSON.stringify(o); if (nd === od) return; state.popoverTipContent = GetPopoverContent(n); const { type } = props; nextTick(() => { if (type === "tag") state.errorTop = proxy.$el.clientHeight + 6; }); }, { deep: true }); onMounted(() => { const { caption, type } = props; if (caption) state.captionWidth = GetCaptionWidth(caption); if (type === "tag") state.scrollbarWidth = GetScrollbarWidth(); }); const inputHandle = (e) => { const { data } = e; const { value } = e.target; state.inputStatus = data || value; state.inputText = value; }; const dropOpenClick = (flag) => { emit("click", flag); }; const triangleHandle = () => { dropOpenClick("triangle"); }; const delHandle = () => { state.inputStatus = null; props.delHandle(); }; const focusHandle = () => { state.readonlyActive = false; }; const blurHandle = () => { state.readonlyActive = true; }; const tagCloseHandle = (item) => { if (item.disabled) return; emit("clearItem", item); }; return () => { const { disabled, errorShow, type, width, caption, openSearch, dropSearch, placeholder, multiple, selectedData, dropShow, clearHide, errorText } = props; const { captionWidth, inputStatus, inputShow, readonlyActive, inputText, errorTop, popoverTipContent } = state; return createVNode("div", { "class": ["d-drop-trigger", `d-drop-trigger-${type}`, disabled ? "d-drop-trigger-disabled" : "d-drop-trigger-active", errorShow && "p-trigger-error"], "style": { width: `${width}px` } }, [createVNode("div", { "class": ["d-drop-trigger-main", `d-drop-trigger-main-${type}`], "onClick": () => { dropOpenClick(); } }, [caption && createVNode("div", { "class": "d-drop-trigger-caption d-drop-trigger-text-overflow", "style": { width: `${captionWidth}px` } }, [caption]), type === "normal" ? createVNode("section", { "class": { "d-drop-trigger-label": true, "d-drop-trigger-label-pl": caption && !hasColon.value }, "style": { width: `calc(100% - ${captionWidth}px)` } }, [!inputStatus && createVNode(Fragment, null, [hasSelected.value ? createVNode("span", { "class": { "d-drop-trigger-selected": true, "d-drop-trigger-selected-focus": !readonlyActive } }, [multiple ? createVNode(PopoverTip, { "ref": popoverTip, "tag": tag, "countTag": countTag, "content": popoverTipContent, "dropShow": dropShow }, { default: () => [createVNode("span", { "class": "d-drop-trigger-selected-m", "ref": tag }, [createTextVNode("\u5DF2\u9009\u62E9"), createVNode("span", { "class": "d-drop-trigger-selected-m-c", "ref": countTag }, [selectedData.length]), createTextVNode("\u9879")])] }) : createVNode("span", { "class": "d-drop-trigger-selected-s", "onMouseenter": Kt }, [selectedData.name])]) : createVNode("span", { "class": "d-drop-trigger-placeholder d-drop-trigger-text-overflow" }, [placeholder])]), openSearch && !disabled && !dropSearch && inputShow && createVNode("input", { "type": "text", "class": { "d-drop-trigger-input": true, "d-drop-trigger-text-overflow": true, "d-drop-trigger-input-readonly": readonlyActive && !dropShow, "d-drop-trigger-label-pl": caption && !hasColon.value }, "value": inputText, "onInput": inputHandle, "onFocus": focusHandle, "onBlur": blurHandle }, null)]) : createVNode(Fragment, null, [selectedData && JSON.stringify(selectedData).length > 4 ? createVNode("div", { "class": "d-drop-trigger-main-tag-box", "style": { width: `calc(100% - ${captionWidth}px)` } }, [createVNode("section", { "class": "d-drop-trigger-tag-list" }, [selectedData.map((sd) => createVNode("article", { "class": "d-drop-trigger-tag-list-item", "key": sd.id }, [createVNode("span", { "class": "d-drop-trigger-tag-list-text d-drop-trigger-text-overflow", "style": { maxWidth: `${tabMaxWidth.value}px` }, "onMouseenter": Kt }, [sd.name]), createVNode("i", { "class": ["d-drop-trigger-tag-list-svg", sd.disabled ? "d-drop-trigger-tag-list-svg-disabled" : "d-drop-trigger-tag-list-svg-normal"], "onClick": (e) => { e.stopPropagation(); tagCloseHandle(sd); } }, [createVNode(CloseIcon, null, null)])]))])]) : createVNode("section", { "class": "d-drop-trigger-label", "style": { width: `calc(100% - ${captionWidth}px)` } }, [createVNode("span", { "class": "d-drop-trigger-placeholder d-drop-trigger-text-overflow" }, [placeholder])])])]), createVNode("div", { "class": { "d-drop-trigger-icon": true, "d-drop-trigger-icon-clear": !clearHide && hasSelected.value && !disabled } }, [createVNode("i", { "class": { "d-drop-trigger-svg": true, "d-drop-trigger-tgl": true, "d-drop-trigger-tgl-open": !dropShow }, "onClick": (e) => { e.stopPropagation(); triangleHandle(); } }, [createVNode(TriangleIcon, null, null)]), createVNode("i", { "class": "d-drop-trigger-svg d-drop-trigger-del", "onClick": (e) => { e.stopPropagation(); delHandle(); } }, [createVNode(DeleteIcon, null, null)])]), errorShow && createVNode("span", { "class": "p-trigger-error-text", "style": { top: `${errorTop}px` } }, [errorText])]); }; } }); const AddClassNameForText = (text1, text2, className) => { const tArr1 = text1.split(""); const tArr2 = Array.from(new Set(text2.split(""))); const formatArr = tArr1.map((d) => { if (tArr2.includes(d)) return `<span class="${className}">${d}</span>`; return d; }); return formatArr.join(""); }; const GetSameItem = (text1, text2) => { const tArr1 = text1.split(""); const tArr2 = text2.split(""); return tArr1.filter((d) => tArr2.includes(d)).join(""); }; let dom; const CreateInstance = (options) => { const { tag, props, component, resetPosition: resetPosition2 } = options; if (!dom) { dom = document.createElement("div"); document.body.appendChild(dom); } const vm = createVNode(component, props); const instance = { vm, tag, resetPosition() { if (resetPosition2) resetPosition2(instance); }, remove() { if (vm.component.isUnmounted) return; render$3(null, dom); } }; render$3(vm, dom); return instance; }; const ClickOutside = (e, dom2, cb) => { if (!dom2.contains(e.target)) cb(); }; const RegHtml = /<[^<>]+>/g; var style$1 = ""; const GetTextHideWidth = (maxWidth = 0, text) => { const div = document.createElement("div"); div.style.display = "inline-block"; div.style.position = "absolute"; div.style.height = "0"; div.style.fontSize = "14px"; div.innerText = text; document.body.appendChild(div); const { width } = div.getBoundingClientRect(), w = Math.ceil(width); document.body.removeChild(div); if (w <= maxWidth) return 0; return w - maxWidth; }; const CheckHtml = (htmlStr) => /<[^>]+>/g.test(htmlStr); var style = ""; const Checkbox = defineComponent({ name: "DCheckbox", props: { checked: { type: String, default: "uncheck" }, disabled: { type: Boolean, default: false }, stopPropagation: { type: Boolean, default: false }, attr: { type: String }, onChange: { type: Function, default: () => { } } }, setup(props, { emit }) { const { vnode } = getCurrentInstance(); const handleChange = (e) => { const { disabled, checked, stopPropagation, attr } = props; if (stopPropagation) e.stopPropagation(); if (disabled) return; let status; if (checked === "checked") status = "uncheck"; else status = "checked"; if (vnode.props.onChange) emit("change", status, attr, e); else emit("update:checked", status); }; return { handleChange }; }, render() { const { $slots: slots, disabled, checked, handleChange } = this; return createVNode("div", { "class": ["d-checkbox", disabled && "d-checkbox-disabled"], "onClick": handleChange }, [createVNode("i", { "class": ["d-checkbox-box", `d-checkbox-${checked}`] }, null), slots.default && createVNode("span", { "class": "d-checkbox-text", "onMouseenter": Kt }, [slots.default()])]); } }); const SelectCheckbox = defineComponent({ name: "SelectCheckbox", props: { data: { type: Array, default: () => [] }, childDisable: { type: Boolean, default: false }, width: { type: [String, Number], default: 280 }, textIndent: { type: Boolean, default: true }, stopPropagation: { type: Boolean, default: false }, onChange: { type: Function, default: () => { } } }, emits: ["change"], setup(props, { emit }) { const state = reactive({ scrollBar: 0, selectData: [] }); onMounted(() => { state.scrollBar = GetScrollbarWidth(); }); const getTextWidth = (text = "") => { const reg = /<\/?.+?\/?>/g; const { width } = props; const maxWidth = width - 49; return GetTextHideWidth(maxWidth, text.replace(reg, "")); }; watch(() => props.data, (n) => { const { textIndent } = props; if (JSON.stringify(n).length < 4) return; state.selectData = n.map((d) => { if (textIndent) d.excess = -getTextWidth(d.name); return d; }); }, { deep: true, immediate: true }); const setHtmlTagTitle = (e, { excess, name }) => { const { textIndent } = props; const reg = /<\/?.+?\/?>/g; if (textIndent) { if (excess) e.target.title = name.replace(reg, ""); } else { Kt(e); } }; const optionClick = (id, checked) => { let selectedData = {}; let unselectData = {}; state.selectData = state.selectData.map((d) => { if (d.id === id && !d.disabled) { d.checked = checked; if (checked.startsWith("c")) selectedData = d; else unselectData = d; } return d; }); emit("change", selectedData, unselectData); }; const change = (checked, id) => { optionClick(id, checked); }; return () => { const { data, stopPropagation } = props; const { scrollBar, selectData } = state; return withDirectives(createVNode("div", { "class": "d-select-checkbox" }, [selectData.map((item, ind) => createVNode("div", { "key": item.id, "class": { "d-select-checkbox-item": true, "d-select-checkbox-disabled": item.disabled } }, [createVNode(Checkbox, { "key": `${item.id}-${ind}`, "checked": item.checked, "onUpdate:checked": ($event) => item.checked = $event, "disabled": item.disabled, "stopPropagation": stopPropagation, "attr": item.id, "onChange": change }, { default: () => [createVNode("span", { "class": { "d-select-checkbox-text": true, "d-select-checkbox-text-ellipsis-start": item.excess }, "style": { textIndent: `${item.excess - (item.excess && scrollBar)}px` }, "onMouseenter": (e) => setHtmlTagTitle(e, item) }, [CheckHtml(item.name) ? createStaticVNode(item.name, 0) : item.name])] })]))]), [[vShow, data && data.length]]); }; } }); const DropBox$1 = defineComponent({ name: "DropBox", props: { parentState: { type: Object, default: () => ({}) }, width: { type: [String, Number], default: "" }, position: { type: Boolean, default: true }, alignRight: { type: Boolean, default: true }, multiple: { type: Boolean, default: false }, selectedId: { type: [String, Array] }, data: { type: Array, default: () => [] }, maxCount: { type: [String, Number], default: 5 }, change: { type: Function, default: () => { } }, cancel: { type: Function, default: () => { } } }, setup(props, { expose }) { const state = reactive({ confirmDisable: true, selectedData: [], selectedDataHistory: [], dropData: [] }); expose({ state }); const { proxy } = getCurrentInstance(); watch(() => props.parentState.dropShow, (n, o) => { if (n === o) return; const { confirmDisable, selectedDataHistory } = state; if (n || confirmDisable) return; setTimeout(() => { state.selectedData = JSON.parse(JSON.stringify(selectedDataHistory)); state.confirmDisable = true; const ids = selectedDataHistory.map((d) => d.id); state.dropData = props.data.map((d) => { if (ids.includes(d.id)) d.checked = "checked"; else d.checked = "uncheck"; return d; }); }, 300); }); watch(() => props.data, (n) => { state.dropData = JSON.parse(JSON.stringify(n)); }, { deep: true, immediate: true }); const hasDropData = computed(() => { var _a; return (_a = state.dropData) == null ? void 0 : _a.length; }); const closeDrop = () => { const { parentState } = props; parentState.dropShow = false; }; const clickOutSide = (e) => { ClickOutside(e, proxy.$el, closeDrop); }; onMounted(() => { const { multiple, data, selectedId = [] } = props; const selectedData = multiple ? data.filter((d) => selectedId.includes(d.id)) : data.find((d) => d.id === selectedId); if (selectedData) { state.selectedData = selectedData; state.selectedDataHistory = JSON.parse(JSON.stringify(selectedData)); } window.addEventListener("click", clickOutSide, true); window.addEventListener("blur", closeDrop, true); }); onBeforeUnmount(() => { window.removeEventListener("click", clickOutSide); window.removeEventListener("blur", closeDrop); }); const optionHandle = (item) => { if (item.disabled) return; const obj = JSON.parse(JSON.stringify(item)); obj.name = obj.name.replace(RegHtml, ""); props.change(obj); }; const change = (selected, unselect) => { const { selectedData, selectedDataHistory } = state; let sd; if (JSON.stringify(selected).length > 4) { selectedData.push(selected); sd = selectedData; } else { sd = selectedData.filter((d) => d.id !== unselect.id); } state.selectedData = sd; const cur = sd.map((d) => d.id).sort().join(""); const his = selectedDataHistory.map((d) => d.id).sort().join(""); state.confirmDisable = cur || his ? cur === his : !cur || !his; }; const cancel = () => { props.cancel(); }; const confirm = () => { const { confirmDisable, selectedData } = state; if (confirmDisable) return; state.selectedDataHistory = JSON.parse(JSON.stringify(selectedData)); state.confirmDisable = true; props.change(selectedData); }; return () => { const { width, position, maxCount, multiple, selectedId, parentState: { dropShow } } = props; const { confirmDisable, dropData } = state; return createVNode(Transition, { "name": position ? "selectDownUpExtend" : "selectDownUpExtendTop" }, { default: () => [withDirectives(createVNode("div", { "class": ["d-drop-box", `d-drop-box-shadow-${position ? "bottom" : "top"}`], "style": { width: `${width}px` } }, [createVNode("div", { "class": ["d-drop-box-content", `d-drop-box-content-${maxCount <= 5 ? "normal" : "max"}`] }, [(hasDropData == null ? void 0 : hasDropData.value) ? multiple ? createVNode(SelectCheckbox, { "textIndent": false, "data": dropData, "stopPropagation": true, "onChange": change }, null) : dropData.map((d, i) => createVNode("div", { "key": `${d.id}-${i}`, "class": ["d-drop-option", d.id === selectedId && "d-drop-option-selected", d.disabled ? "d-drop-option-disabled" : "d-drop-option-normal"], "onClick": () => optionHandle(d) }, [createVNode("section", { "class": "d-drop-option-text", "onMouseenter": Kt }, [createStaticVNode(d.name, 0)])])) : createVNode("div", { "class": "d-drop-option-none" }, [createTextVNode("\u6CA1\u6709\u627E\u5230\u4EFB\u4F55\u5185\u5BB9")])]), multiple && createVNode("div", { "class": ["d-drop-handle", dropData.length > maxCount && "d-drop-handle-shadow"] }, [createVNode("span", { "class": "d-drop-btn d-drop-btn-cancel", "onClick": cancel }, [createTextVNode("\u53D6\u6D88")]), createVNode("span", { "class": ["d-drop-btn", confirmDisable ? "d-drop-btn-disabled" : "d-drop-btn-confirm"], "onClick": confirm }, [createTextVNode("\u786E\u5B9A")])])]), [[vShow, dropShow]])] }); }; } }); const resetPosition = (instance) => { const { vm, tag } = instance; const { props: { alignRight = false }, el } = vm; const { left, top, isDown } = qe({ trigger: tag, dom: el, isRight: !!alignRight }); vm.component.props.position = isDown; el.style.top = `${top}px`; el.style.left = `${left}px`; }; const DropBox = ({ tag, props }) => CreateInstance({ tag, props, component: DropBox$1, resetPosition }); const Select = defineComponent({ name: "DSelect", props: { width: { type: [String, Number], default: "120" }, dropWidth: { type: [String, Number], default: "120" }, caption: { type: String, default: "" }, placeholder: { type: String, default: "\u8BF7\u9009\u62E9" }, disabled: { type: Boolean, default: false }, clearHide: { type: Boolean, default: false }, openSearch: { type: Boolean, default: true }, alignRight: { type: Boolean, default: false }, multiple: { type: Boolean, default: false }, modelValue: { type: [String, Array] }, data: { type: Array, default: () => [], required: true }, maxCount: { type: [String, Number], default: 5 }, errorText: { type: String, default: "" }, errorShow: { type: Boolean, default: false }, onChange: { type: Function, default: () => { } } }, emits: ["update:modelValue", "change"], setup(props, { emit }) { const state = reactive({ activeClose: true, dropShow: false, dropData: [], selectedData: [], searchData: [] }); const dropTrigger = ref(null); let dropBox; watch(() => props.modelValue, (n, o) => { const { multiple, data } = props; let selectedData; let dropData; if (multiple) { const nVal = String(n); const oVal = String(o); if (nVal === oVal) return; selectedData = data.filter((d) => n.includes(d.id)); dropData = data.map((d) => { if (n.includes(d.id)) d.checked = "checked"; else d.checked = "uncheck"; return d; }); state.dropData = dropData; } else { if (n === o) return; selectedData = data.find((d) => d.id === n); } state.selectedData = selectedData; if (dropBox) { dropBox.vm.component.props.selectedId = n; if (multiple) dropBox.vm.component.props.data = dropData; } }, { deep: true, immediate: true }); watch(() => props.data, (n) => { const { multiple, modelValue } = props; const nData = JSON.stringify(n); const dropData = JSON.parse(nData); if (multiple) { dropData.forEach((d) => { if (modelValue.includes(d.id)) d.checked = "checked"; else d.checked = "uncheck"; }); } state.dropData = dropData; if (dropBox) dropBox.vm.component.props.data = dropData; }, { deep: true, immediate: true }); const changeDropShow = (status) => { state.dropShow = status; if (status) dropBox.resetPosition(); }; const openDropHandle = (flag) => { const { disabled } = props; const { dropShow } = state; if (disabled) return; if (flag === "triangle" && dropShow) { changeDropShow(false); return; } if (dropBox) { changeDropShow(true); } else { const { width, dropWidth, multiple, alignRight, modelValue: selectedId, maxCount } = props; const { dropData: data } = state; dropBox = DropBox({ tag: dropTrigger.value, props: { parentState: state, width: dropWidth < width ? width : dropWidth, multiple, alignRight, data, selectedId, maxCount, change(item) { state.selectedData = item; if (item instanceof Array) { const ids = item.map((d) => d.id); emit("update:modelValue", ids); emit("change", ids, item.map((d) => toRaw(d))); } else { emit("update:modelValue", item.id); emit("change", item.id, toRaw(item)); } changeDropShow(false); }, cancel() { changeDropShow(false); } } }); changeDropShow(true); } }; const getInputText = (val) => { if (val) { const { dropData } = state; if (!dropData || !dropData.length) return; const searchData = JSON.parse(JSON.stringify(dropData)).filter((d) => { if (!d.disabled && GetSameItem(d.name, val)) { d.name = AddClassNameForText(d.name, val, "d-drop-option-text-highlight"); return d; } return null; }); state.searchData = searchData; if (dropBox) dropBox.vm.component.props.data = searchData; } else { state.searchData = []; if (dropBox) dropBox.vm.component.props.data = state.dropData; } }; const delHandle = () => { state.selectedData = []; if (props.multiple) { emit("update:modelValue", ""); emit("change", "", {}); } else { emit("update:modelValue", []); emit("change", [], []); } if (dropBox) { dropBox.vm.component.exposeProxy.state.selectedData = []; dropBox.vm.component.exposeProxy.state.selectedDataHistory = []; } }; return () => { const { caption, width, placeholder, disabled, clearHide, openSearch, multiple, errorText, errorShow } = props; const { selectedData, dropShow } = state; return createVNode("div", { "class": "d-select", "ref": dropTrigger }, [createVNode(DropTrigger, { "caption": caption, "width": width, "placeholder": placeholder, "disabled": disabled, "clearHide": clearHide, "openSearch": openSearch, "multiple": multiple, "dropShow": dropShow, "errorText": errorText, "errorShow": errorShow, "selectedData": selectedData, "onGetInputText": getInputText, "onClick": openDropHandle, "delHandle": delHandle }, null)]); }; } }); export { Select as default };