UNPKG

@farris/ui-vue

Version:

Farris Vue, a Farris Design based Vue3 component library.

513 lines (512 loc) 14.6 kB
import { ref as u, onMounted as E, defineComponent as W, createVNode as n, withDirectives as L, vShow as T, Teleport as O, inject as V, Fragment as Z } from "vue"; import { resolveAppearance as G, createPropsResolver as J } from "../dynamic-resolver/index.esm.js"; import { useDesignerComponent as K } from "../designer-canvas/index.esm.js"; function M(e, l, a) { return l; } const Q = /* @__PURE__ */ new Map([ ["appearance", G] ]), U = "https://json-schema.org/draft/2020-12/schema", _ = "https://farris-design.gitee.io/dropdown.schema.json", P = "dropdown", ee = "A Farris Component", te = "object", oe = { id: { description: "The unique identifier for dropdown", type: "string" }, type: { description: "The type string of dropdown", type: "string", default: "dropdown" }, appearance: { description: "", type: "object", properties: { class: { type: "string" }, style: { type: "string" } }, default: {} }, binding: { description: "", type: "object", default: {} }, disable: { type: "string", default: !1 }, editable: { description: "", type: "boolean", default: !0 }, placeholder: { description: "", type: "string", default: "" }, readonly: { description: "", type: "boolean", default: !1 }, require: { description: "", type: "boolean", default: !1 }, tabindex: { description: "", type: "number", default: -1 }, visible: { description: "", type: "boolean", default: !0 } }, ne = [ "id", "type" ], ie = { $schema: U, $id: _, title: P, description: ee, type: te, properties: oe, required: ne }, se = "dropdown", le = "A Farris Component", re = "object", ae = { basic: { description: "Basic Infomation", title: "基本信息", properties: { id: { description: "组件标识", title: "标识", type: "string", readonly: !0 }, type: { description: "组件类型", title: "控件类型", type: "select", editor: { type: "waiting for modification", enum: [] } } } }, behavior: { description: "Basic Infomation", title: "行为", properties: { readonly: { description: "", title: "只读", type: "string" }, required: { description: "", title: "必填", type: "boolean" }, visible: { description: "", title: "可见", type: "boolean" }, placeholder: { description: "", title: "提示文本", type: "string" }, tabindex: { description: "", title: "tab索引", type: "number" } } } }, de = { title: se, description: le, type: re, categories: ae }, z = { /** 默认展开或折叠 * 注意: * 1、这个属性在出现滚动条的情况下,滚动会导致收折,看不到展开的面板。 * 2、如果是放置在没有滚动条的界面,可有实际效果 */ show: { type: Boolean, default: !1 }, /** 下拉按钮是否禁用 */ disabled: { type: Boolean, default: !1 }, /** 下拉按钮对应文字 */ title: { type: String, default: "下拉示例" }, /** 下拉按钮大小 */ size: { type: String, default: "" }, /** 下拉按钮类型 */ type: { type: String, default: "primary" }, /** 图标样式 */ iconClass: { type: String, default: "" }, /** 下拉框内容是否被选中 * ---未被使用 */ active: { type: Boolean, default: !1 }, /** 下拉按钮是否分开展示 */ splitButton: { type: Boolean, default: !1 }, /** 下拉框展示方向 */ position: { type: String, default: "bottom" }, /** 下拉框内容 */ model: { type: Array, default: [ { label: "项目一", value: "XM1" }, { label: "项目二", value: "XM2" }, { label: "项目三", value: "XM3" } ] }, onSelect: { type: Function, default: () => { } } }, N = J(z, ie, Q, M, de); function X(e, l) { let a; const i = u(e.show), m = u(), p = u(), w = u(), s = 10; E(() => { a = p.value; }); const b = (o = 1) => { const t = [ "body>.f-datagrid-settings-simple-host", "body>div", "body>farris-dialog>.farris-modal.show", "body>.farris-modal.show", "body>farris-filter-panel>.f-filter-panel-wrapper", "body .f-sidebar-show>.f-sidebar-main", "body>.popover.show", "body>filter-row-panel>.f-datagrid-filter-panel", "body>.f-section-maximize" ], f = Array.from(document.body.querySelectorAll(t.join(","))).filter((r) => r).map((r) => { const { display: R, zIndex: S } = window.getComputedStyle(r); return R === "none" ? 0 : parseInt(S, 10); }).filter((r) => r); let c = Math.max(...f); return c < 1040 && (c = 1040), c + o; }, x = (o, t) => { const { height: f, left: c, top: r, width: R } = o.getBoundingClientRect(), { width: S, height: A, top: pe } = t.getBoundingClientRect(); if (o.className.indexOf("dropdown-submenu") > -1 || o.closest(".dropdown-submenu") || o.classList.contains("dropright")) { const H = window.innerWidth - c - o.offsetWidth, k = window.innerHeight - r, { position: h } = getComputedStyle(t); if (h === "fixed") { let y = c + o.offsetWidth; t.offsetWidth > H && c > H && (y = c - S), t.style.left = y + "px", t.style.right = "auto", window.innerHeight - 2 * s < t.offsetHeight ? (t.style.top = s + "px", t.style.bottom = s + "px", t.style.maxHeight = window.innerHeight - 2 * s + "px", t.style.overflowY = "auto", t.className += " dropdown-menu-maxheight") : k < t.offsetHeight ? (t.style.top = "auto", t.style.bottom = s + "px") : (t.style.top = r + "px", t.style.bottom = "auto"); } else { if (t.offsetWidth > H) { const y = -S; t.style.left = y + "px"; } window.innerHeight - 2 * s < t.offsetHeight ? (t.style.top = -1 * (r - s) + "px", t.style.bottom = "auto", t.style.maxHeight = window.innerHeight - 2 * s + "px", t.style.overflowY = "auto", t.className += " dropdown-menu-maxheight") : k < t.offsetHeight && (t.style.top = k - t.offsetHeight - s + "px", t.style.bottom = "auto"); } } else { const { marginTop: H, marginBottom: k } = getComputedStyle(t); let h = 0; const y = Math.ceil(parseFloat(H)) + Math.ceil(parseFloat(k)); let g = r + f, q = c; window.innerHeight - g - y < A && (g = r - A, g < 0 && (window.innerHeight - r - f > r ? (g = r + f, h = window.innerHeight - g - y - s) : (g = s, h = r - g - y))), window.innerWidth - c < S && window.innerWidth - c < c + R && (q = c - S + R), document.body.append(t), t.style.cssText = `position:fixed;bottom:unset;left:${q}px !important;top:${g}px !important;right: unset;${h ? "max-height:" + h + "px;overflow-y:auto;" : ""}`, h && (t.className += " dropdown-menu-maxheight"), t.style.zIndex = b().toString(); } }, v = () => { x(m.value, p.value); }, d = () => { e.hover || (i.value = !1, p.value.style = null, document.removeEventListener("click", d), a.removeEventListener("click", d), document.removeEventListener("scroll", d), a.removeEventListener("scroll", d)); }, C = (o = null, t = !1) => { e.hover || e.disabled || (o == null || o.stopPropagation(), t ? (setTimeout(() => { v(); }), i.value = !0) : (i.value || setTimeout(() => { v(); }), i.value = !i.value), document.addEventListener("click", d), document.addEventListener("scroll", d), e.hideOnClick || (a.addEventListener("click", (f) => { f.stopPropagation(); }), a.addEventListener("scroll", (f) => { f.stopPropagation(); }))); }; return { show: i, dropdownRef: m, dropdownMenuRef: p, clickEventRef: w, showDropMenu: (o) => { C(o, !1); }, showDropMenuByForce: C, hoverDropdown: (o) => { e.hover && (i.value || setTimeout(() => { }), i.value = !i.value); }, leftButtonClick: () => { }, closeDropMenu: d, selectItem: (o) => { l.emit("select", o); }, resolveSize: (o) => { const t = /px|em|rem|pt|%/; return t.test(o) ? `${parseInt(o, 10)}${o.match(t)[0]}` : `${o}px`; } }; } const ce = { /** 下拉框标签 */ label: { type: String, default: "XM1" }, /** 下拉框名称 */ value: { type: String || Number, default: "项目一" }, /** 是否禁用该下拉框属性 */ disabled: { type: Boolean, default: !1 }, active: { type: Boolean, default: !1 }, divide: { type: Boolean, default: !1 }, onSelect: { type: Function, default: () => { } } }, Y = /* @__PURE__ */ W({ name: "FDropdownItem", props: ce, emits: ["select"], setup(e, l) { const a = u(e.value), i = u(e.label), m = u(e.disabled), p = u(e.active), w = u(e.divide), s = () => { m.value || l.emit("select", e); }; return () => n("div", null, [L(n("div", { class: "dropdown-divider" }, null), [[T, w.value]]), n("li", { class: `dropdown-item${p.value ? " active" : ""} ${m.value ? " disabled" : ""}`, onClick: s, title: a.value.toString() }, [i.value])]); } }), F = /* @__PURE__ */ W({ name: "FDropdown", props: z, emits: ["select"], setup(e, l) { const a = u(e.model), i = u(!1), { show: m, dropdownMenuRef: p, dropdownRef: w, clickEventRef: s, showDropMenu: b, hoverDropdown: x, leftButtonClick: v, showDropMenuByForce: d, closeDropMenu: C } = X(e, l); function $(B) { C(), l.emit("select", B); } function D() { return [{ "dropdown-item": e.nest }, { "btn-lg": e.size === "large" }, { "btn-sm": e.size === "small" }, { "btn-primary": e.type === "primary" }, { "btn-success": e.type === "success" }, { "btn-warning": e.type === "warning" }, { "btn-danger": e.type === "danger" }, { "btn-info": e.type === "info" }, { "btn-secondary": e.type === "secondary" }, { "btn-link": e.type === "link" }, { disabled: e.disabled }]; } return E(() => { i.value = !0, m.value && d(null, !0); }), () => n("div", { ref: w }, [n("div", { class: ["farris-dropdown", "btn-group", { dropup: e.position === "top" }, { dropdown: e.position === "bottom" }, { dropleft: e.position === "left" }, { dropright: e.position === "right" }] }, [e.splitButton && n("span", { class: ["btn", ...D()], style: "width:100%", onClick: v }, [e.title]), n("span", { ref: s, class: ["dropdown-toggle", { btn: !e.nest }, { "dropdown-toggle-split": e.splitButton }, ...D()], style: "width:100%", onClick: b, onMouseenter: x, onMouseleave: x }, [e.splitButton ? "" : e.title, e.iconClass && n("span", { class: `f-icon ${e.iconClass}` }, null)]), i.value && n(O, { to: "body" }, { default: () => [n("div", { ref: p, class: `dropdown-menu${m.value ? " show" : ""}` }, [a.value.map(({ label: B, value: I, disabled: j, active: o, divide: t }) => n(Y, { value: I.toString(), label: B, disabled: j, active: o, divide: t, onSelect: (f) => $(f) }, null))])] })])]); } }), ue = /* @__PURE__ */ W({ name: "FDropdownDesign", props: z, emits: ["select"], setup(e, l) { const a = u(e.model), { show: i, showDropMenu: m, hoverDropdown: p, leftButtonClick: w } = X(e, l); function s(d) { l.emit("select", d); } const b = u(), x = V("design-item-context"), v = K(b, x); return E(() => { b.value.componentInstance = v; }), l.expose(v.value), () => n("div", { ref: b }, [n("div", { class: ["farris-dropdown", "btn-group", { dropup: e.position === "top" }, { dropdown: e.position === "bottom" }, { dropleft: e.position === "left" }, { dropright: e.position === "right" }], style: { width: e.width } }, [e.splitButton && n("span", { class: ["btn", { "dropdown-item": e.nest }, { "btn-lg": e.size === "large" }, { "btn-sm": e.size === "small" }, { "btn-primary": e.type === "primary" }, { "btn-success": e.type === "success" }, { "btn-warning": e.type === "warning" }, { "btn-danger": e.type === "danger" }, { "btn-info": e.type === "info" }], style: "width:100%", onClick: w }, [e.title]), n("span", { class: ["dropdown-toggle", { btn: !e.nest }, { "dropdown-item": e.nest }, { "dropdown-toggle-split": e.splitButton }, { "btn-lg": e.size === "large" }, { "btn-sm": e.size === "small" }, { "btn-primary": e.type === "primary" }, { "btn-success": e.type === "success" }, { "btn-warning": e.type === "warning" }, { "btn-danger": e.type === "danger" }, { "btn-info": e.type === "info" }, { "btn-secondary": e.type === "secondary" }, { "btn-link": e.type === "link" }, { disabled: e.disabled }], style: "width:100%", onClick: m, onMouseenter: p, onMouseleave: p }, [L(n("span", { class: "sr-only" }, null), [[T, e.splitButton]]), e.splitButton ? "" : e.title, L(n("span", { class: `f-icon ${e.iconClass.toString()}` }, null), [[T, e.iconClass]])]), n("div", { class: `dropdown-menu${i.value ? " show" : ""}` }, [n(Z, null, [a.value.map(({ label: d, value: C, disabled: $, active: D, divide: B }) => n(Y, { value: C.toString(), label: d, disabled: $, active: D, divide: B, onSelect: (I) => s(I) }, null))])])])]); } }), we = { install(e) { e.component(F.name, F); }, register(e, l, a, i) { e.dropdown = F, l.dropdown = N; }, registerDesigner(e, l, a) { e.dropdown = ue, l.dropdown = N; } }; export { F as Dropdown, we as default, z as dropdownProps, N as propsResolver };