UNPKG

@farris/ui-vue

Version:

Farris Vue, a Farris Design based Vue3 component library.

1,796 lines (1,795 loc) 241 kB
var Zt = Object.defineProperty; var Qt = (e, t, n) => t in e ? Zt(e, t, { enumerable: !0, configurable: !0, writable: !0, value: n }) : e[t] = n; var Q = (e, t, n) => Qt(e, typeof t != "symbol" ? t + "" : t, n); import { ref as m, computed as D, defineComponent as U, provide as et, createVNode as p, watch as $, inject as _, onMounted as X, reactive as ce, onBeforeUnmount as tt, nextTick as ee, createTextVNode as se, withDirectives as nt, vModelText as en, Teleport as at, createApp as Re, onUnmounted as Ce, Fragment as oe, onBeforeMount as tn, watchEffect as nn, Transition as lt, shallowRef as an, render as Oe, h as ln, cloneVNode as on, mergeProps as Ve, vShow as sn, onUpdated as rn } from "vue"; import { resolveAppearance as it, createPropsResolver as ke, getPropsResolverGenerator as un } from "../dynamic-resolver/index.esm.js"; import { getCustomClass as cn, getCustomStyle as dn, useTouchMomentum as fn, useTouch as mn, useCommonUtils as xe, useBem as ot, useFarrisConfig as yn, FormSchemaEntityFieldType$Type as ve, EVENT_PROPERTY_TAB_IDS as pn, withInstall as vn, isMobilePhone as de, getMaxZIndex as qe, useGuid as hn } from "../common/index.esm.js"; import { useDesignerComponent as Le, useDragulaCommonRule as gn } from "../designer-canvas/index.esm.js"; import bn, { FButtonEdit as st } from "../button-edit/index.esm.js"; import { LocaleService as J } from "../locale/index.esm.js"; import Cn from "../list-view/index.esm.js"; import { isUndefined as kn, cloneDeep as Ie, debounce as rt } from "lodash-es"; import "bignumber.js"; import xn from "../../designer/button-edit/index.esm.js"; import { InputBaseProperty as wn } from "../property-panel/index.esm.js"; import Fn from "../tree-view/index.esm.js"; import "../button/index.esm.js"; import "../field-selector/index.esm.js"; import "../collection-property-editor/index.esm.js/src/use-button-items.designer"; import Sn from "../tags/index.esm.js"; import { useInputExpand as Tn } from "../common/index.esm.js/text-box/use-input-expand"; import Mn from "../popover/index.esm.js"; import On from "../drawer/index.esm.js"; const Bn = { modelValue: { type: String, default: "" }, singleExpand: { type: Boolean, default: !0 }, entities: { type: Array, default: [] }, variables: { type: Array, default: [] }, disabledFunctions: { type: Object, default: null }, esprimaPath: { type: String, default: "assets/esprima-config.json" }, showMessage: { type: Boolean, default: !1 }, validateMessage: { type: String, default: "" }, messageType: { type: String, default: "info" }, showMessageType: { type: Boolean, default: !1 }, showDataPanel: { type: Boolean, default: !0 }, isServerSide: { type: Boolean, default: !1 } }, ut = /* @__PURE__ */ new Map([ ["appearance", it] ]); function ct(e, t, n) { return t; } const En = "https://json-schema.org/draft/2020-12/schema", Dn = "https://farris-design.gitee.io/layout.schema.json", Pn = "layout", In = "A Farris Container Component", Nn = "object", jn = { id: { description: "The unique identifier for layout component", type: "string" }, type: { description: "The type string of layout component", type: "string", default: "layout" }, appearance: { description: "", type: "object", properties: { class: { type: "string" }, style: { type: "string" } }, default: {} }, contents: { description: "", type: "array", default: [] }, collapsable: { description: "", type: "boolean", default: !1 }, resizable: { description: "", type: "boolean", default: !0 }, visible: { description: "", type: "boolean", default: !0 } }, Rn = [ "id", "type", "contents" ], Vn = { $schema: En, $id: Dn, title: Pn, description: In, type: Nn, properties: jn, required: Rn }, Ln = "layout", Hn = "A Farris Component", zn = "object", An = { basic: { description: "Basic Infomation", title: "基本信息", properties: { id: { description: "组件标识", title: "标识", type: "string", readonly: !0 }, type: { description: "类型", title: "类型", type: "string", readonly: !0 } } }, behavior: { description: "Basic Infomation", title: "行为", properties: { collapsable: { description: "", title: "可收折", type: "boolean" }, resizable: { description: "", title: "可调整尺寸", type: "boolean" } } } }, $n = { title: Ln, description: Hn, type: zn, categories: An }, He = { customStyle: { type: String, defaut: "" }, customClass: { type: String, defaut: "" } }, dt = ke(He, Vn, ut, ct, $n); function ft(e) { const t = m(-1), n = m(-1), a = m(0), l = m(0), o = m(!1), i = m(!1), c = D(() => ({ display: o.value ? "block" : "none", left: `${a.value}px`, cursor: "e-resize" })), f = D(() => ({ display: i.value ? "block" : "none", top: `${l.value}px`, cursor: "n-resize" })), v = D(() => { const y = { display: i.value || o.value ? "block" : "none" }; return l.value > 0 && (y.cursor = "n-resize"), y; }); function b(y, r, u, k) { const g = e.value; if (g) { const { left: s, right: d, width: C } = g.getBoundingClientRect(); let x = y.clientX - s; k === "right" && (x = d - y.clientX), x > r && (x = r), x < u && (x = u), k === "right" && (x = C - x), a.value = x; } } function h(y, r, u, k) { const g = e.value; if (g) { const { top: s, bottom: d, height: C } = g.getBoundingClientRect(); let x = y.clientY - s; k === "bottom" && (x = d - y.clientY), x > r && (x = r), x < u && (x = u), k === "bottom" && (x = C - x), l.value = x; } } function w() { const y = e.value; if (y) { const { width: r, height: u } = y.getBoundingClientRect(); return { width: r, height: u }; } return null; } function T() { const y = e.value; return y ? Array.from(y.querySelectorAll("[data-position]")).reduce((r, u) => { const k = u.getAttribute("data-position"); return r = Object.assign(r, { [k]: u }), r; }, {}) : null; } function F(y, r) { const u = w(), k = T(); if (u && k) { const g = k == null ? void 0 : k.right, s = k == null ? void 0 : k.left; if (y === "left" && s) return g ? u.width - g.clientWidth - r : u.width - r; if (y === "right" && g) return s ? u.width - s.clientWidth - r : u.width - r; } } function M(y, r) { const u = w(), k = T(); if (u && k) { const g = k == null ? void 0 : k.bottom, s = k == null ? void 0 : k.top; if (y === "top" && s) return g ? u.height - g.clientHeight - r : u.height - r; if (y === "bottom" && g) return s ? u.height - s.clientHeight - r : u.height - r; } } return { horizontalResizeHandleStyle: c, verticalResizeHandleStyle: f, resizeOverlayStyle: v, showHorizontalResizeHandle: o, showVerticalResizeHandle: i, horizontalResizeBarPosition: t, verticalResizeBarPosition: n, verticalResizeHandleOffset: l, horizontalResizeHandleOffset: a, draggingHorizontalResizeHandle: b, draggingVerticalResizeHandle: h, getPanelMaxHeight: M, getPanelMaxWidth: F }; } const te = /* @__PURE__ */ U({ name: "FLayout", props: He, emits: [], setup(e, t) { const n = m(), a = ft(n), { horizontalResizeHandleStyle: l, verticalResizeHandleStyle: o, resizeOverlayStyle: i } = a; et("layout", { useResizeHandleComposition: a }); const c = D(() => cn({ "f-layout": !0 }, e == null ? void 0 : e.customClass)), f = D(() => dn({}, e == null ? void 0 : e.customStyle)); return () => p("div", { class: c.value, style: f.value, ref: n }, [t.slots.default && t.slots.default(), p("div", { class: "f-layout-resize-overlay", style: i.value }, null), p("div", { class: "f-layout-horizontal-resize-proxy", style: l.value }, null), p("div", { class: "f-layout-vertical-resize-proxy", style: o.value }, null)]); } }), Wn = "https://json-schema.org/draft/2020-12/schema", Yn = "https://farris-design.gitee.io/layout-pane.schema.json", qn = "layout-pane", Un = "A Farris Container Component", Gn = "object", Kn = { id: { description: "The unique identifier for a layout pane", type: "string" }, type: { description: "The type string of layout paney", type: "string", default: "layout-pane" }, appearance: { description: "", type: "object", properties: { class: { type: "string" }, style: { type: "string" } }, default: {} }, collapsable: { description: "", type: "boolean", default: !1 }, contents: { description: "", type: "array", default: [] }, height: { description: "", type: "number" }, position: { description: "", type: "string", default: "left", enum: [ "left", "center", "right", "top", "bottom" ] }, resizeable: { description: "", type: "boolean", default: !0 }, width: { description: "", type: "number" }, visible: { description: "", type: "number", default: !0 } }, Xn = [ "id", "type", "contents" ], _n = { $schema: Wn, $id: Yn, title: qn, description: Un, type: Gn, properties: Kn, required: Xn }, Jn = "layout-pane", Zn = "A Farris Container Component", Qn = "object", ea = { basic: { description: "Basic Infomation", title: "基本信息", properties: { id: { description: "组件标识", title: "标识", type: "string", readonly: !0 }, type: { description: "组件类型", title: "控件类型", type: "enum" }, width: { description: "", type: "number", title: "宽度" }, height: { description: "", type: "number", title: "高度" } } }, appearance: { title: "样式", description: "Appearance", properties: { class: { title: "class样式", type: "string", description: "" }, style: { title: "style", type: "string", description: "" } } }, behavior: { description: "", title: "行为", properties: { collapsable: { description: "", type: "boolean", title: "允许收折" }, position: { description: "", type: "enum", title: "位置", editor: { type: "combo-list", data: [ { id: "left", name: "左侧" }, { id: "center", name: "居中" }, { id: "right", name: "右侧" }, { id: "top", name: "顶部" }, { id: "bottom", name: "底部" } ] } }, resizeable: { description: "", type: "boolean", title: "允许调整尺寸" }, visible: { description: "运行时组件是否可见", type: "boolean", title: "是否可见" } } } }, ta = { title: Jn, description: Zn, type: Qn, categories: ea }, ze = { customClass: { type: String, defaut: "" }, customStyle: { type: String, defaut: "" }, /** 记录原始定义宽度 */ width: { type: Number, default: -1 }, /** 记录原始定义高度 */ height: { type: Number, default: -1 }, /** 面板位置 */ position: { type: String, default: "left" }, /** 是否显示 */ visible: { type: Boolean, default: !0 }, /** True to allow the pane can be resized. */ resizable: { type: Boolean, default: !0 }, /** True to allow the pane can be collapsed. */ collapsable: { type: Boolean, default: !1 }, /** 面板最小宽度 */ minWidth: { type: Number, default: 100 }, /** 面板最小高度 */ minHeight: { type: Number, default: 100 }, maxWidth: { type: Number, default: null } }, mt = ke(ze, _n, ut, ct, ta); function yt(e, t, n, a, l, o) { const { horizontalResizeBarPosition: i, horizontalResizeHandleOffset: c, showHorizontalResizeHandle: f, showVerticalResizeHandle: v, verticalResizeBarPosition: b, verticalResizeHandleOffset: h, draggingHorizontalResizeHandle: w, draggingVerticalResizeHandle: T, getPanelMaxHeight: F, getPanelMaxWidth: M } = l; let y = "", r, u, k; const g = () => o.maxWidth ? o.maxWidth : M(y, n.value) || 0; function s(x) { if ((y === "left" || y === "right") && u) { const { left: I } = u.getBoundingClientRect(), { width: R } = r.getBoundingClientRect(), N = x.clientX - I; let P = y === "left" ? (R || 0) + (N - i.value) : (R || 0) - (N - i.value); P = n.value > 0 ? Math.max(n.value, P) : P; const S = g(); S != null && (P = S > P ? P : S), e.value = P; } if ((y === "top" || y === "bottom") && u) { const { top: I } = u.getBoundingClientRect(), { height: R } = r.getBoundingClientRect(), N = x.clientY - I; let P = y === "top" ? (R || 0) + (N - b.value) : (R || 0) - (N - b.value); P = a.value > 0 ? Math.max(a.value, P) : P; const S = F(y, a.value); S != null && (P = S > P ? P : S), t.value = P; } c.value = 0, h.value = 0, i.value = -1, b.value = -1, f.value = !1, v.value = !1, document.removeEventListener("mousemove", k), document.removeEventListener("mouseup", s), document.body.style.userSelect = "", y = "", r = null, u = null; } function d(x, I, R) { if (y = I, r = R, f.value = !0, u = x.composedPath().find((P) => (P.className || "").split(" ")[0] === "f-layout"), u) { const { left: P } = u.getBoundingClientRect(), S = x.clientX - P; c.value = S, i.value = S; const j = g(); k = (z) => w(z, j, n.value, y), document.addEventListener("mousemove", k), document.addEventListener("mouseup", s), document.body.style.userSelect = "none"; } } function C(x, I, R) { if (y = I, r = R, v.value = !0, u = x.composedPath().find((P) => (P.className || "").split(" ")[0] === "f-layout"), u) { const { top: P } = u.getBoundingClientRect(); h.value = x.clientY - P, b.value = x.clientY - P; const S = F(y, a.value) || 0; k = (j) => T(j, S, a.value, y), document.addEventListener("mousemove", k), document.addEventListener("mouseup", s), document.body.style.userSelect = "none"; } } return { onClickHorizontalResizeBar: d, onClickVerticalResizeBar: C }; } const Z = /* @__PURE__ */ U({ name: "FLayoutPane", props: ze, emits: [], setup(e, t) { const n = m(e.minHeight <= 0 ? 100 : e.minHeight), a = m(e.minWidth <= 0 ? 100 : e.minWidth), l = m(e.width <= 0 ? 100 : e.width), o = m(e.height <= 0 ? 100 : e.height), i = m(Math.max(n.value, o.value)), c = m(Math.max(a.value, l.value)), f = m(), v = m(e.position), b = m(e.resizable); $(() => e.resizable, (s) => { b.value = s; }); const h = _("layout"), { useResizeHandleComposition: w } = h, T = yt(c, i, a, n, w, e), { onClickHorizontalResizeBar: F, onClickVerticalResizeBar: M } = T, y = D(() => ({ "f-layout-resize-bar": !0, "f-layout-resize-bar-e": v.value === "left", "f-layout-resize-bar-n": v.value === "bottom", "f-layout-resize-bar-s": v.value === "top", "f-layout-resize-bar-w": v.value === "right" })), r = D(() => v.value !== "center" && b.value); function u(s, d) { (d === "left" || d === "right") && F(s, d, f.value), (d === "top" || d === "bottom") && M(s, d, f.value); } const k = D(() => { const s = { "f-layout-pane": !0, "f-page-content-nav": v.value === "left" || v.value === "right", "f-page-content-main": v.value === "center" }; return e.customClass && String(e.customClass).split(" ").reduce((d, C) => (d[C] = !0, d), s), s; }), g = D(() => { const s = {}; return (c.value && v.value === "left" || v.value === "right") && (s.width = `${c.value}px`), (i.value && v.value === "bottom" || v.value === "top") && (s.height = `${i.value}px`), e.visible || (s.display = "none"), s; }); return () => p("div", { ref: f, class: k.value, style: g.value, "data-position": v.value }, [t.slots.default && t.slots.default(), r.value && p("span", { class: y.value, onMousedown: (s) => u(s, v.value) }, null)]); } }); function na(e, t) { function n() { return !1; } return { canAccepts: n }; } const aa = /* @__PURE__ */ U({ name: "FLayoutDesign", props: He, emits: [], setup(e, t) { var b; const n = m(), a = _("design-item-context"), l = na(a.schema, (b = a.parent) == null ? void 0 : b.schema), o = Le(n, a, l); o.value.canNested = !1; const i = ft(n), { horizontalResizeHandleStyle: c, verticalResizeHandleStyle: f, resizeOverlayStyle: v } = i; return et("layout", { useResizeHandleComposition: i }), X(() => { n.value.componentInstance = o; }), t.expose(o.value), () => p("div", { class: "f-layout f-page-content", ref: n }, [t.slots.default && t.slots.default(), p("div", { class: "f-layout-resize-overlay", style: v.value }, null), p("div", { class: "f-layout-horizontal-resize-proxy", style: c.value }, null), p("div", { class: "f-layout-vertical-resize-proxy", style: f.value }, null)]); } }); function la(e, t) { const n = e.schema; function a(o) { return !!gn().basalDragulaRuleForContainer(o); } function l() { const o = ["f-layout-pane"]; return (n.position === "left" || n.position === "right") && o.push("f-page-content-nav"), n.position === "center" && o.push("f-page-content-main"), o.join(" "); } return { canAccepts: a, getDesignerClass: l }; } const ia = /* @__PURE__ */ U({ name: "FLayoutPaneDesign", props: ze, emits: [], setup(e, t) { const n = m(), a = m(); _("designer-host-service"); const l = _("design-item-context"), o = la(l), i = Le(a, l, o); i.value.canNested = !1, i.value.canMove = !1, i.value.canDelete = !1, X(() => { a.value.componentInstance = i; }), t.expose(i.value); const c = m(Math.max(e.minHeight, e.height)), f = m(Math.max(e.minWidth, e.width)), v = m(e.minHeight), b = m(e.minWidth), h = m(e.position), w = _("layout"), { useResizeHandleComposition: T } = w, F = yt(f, c, b, v, T, e), { onClickHorizontalResizeBar: M, onClickVerticalResizeBar: y } = F, r = D(() => ({ "f-layout-resize-bar": !0, "f-layout-resize-bar-e": h.value === "left", "f-layout-resize-bar-n": h.value === "bottom", "f-layout-resize-bar-s": h.value === "top", "f-layout-resize-bar-w": h.value === "right" })); function u(s, d) { (d === "left" || d === "right") && M(s, d, n.value), (d === "top" || d === "bottom") && y(s, d, n.value); } const k = D(() => { const s = { "f-layout-pane": !0, "f-page-content-nav": h.value === "left" || h.value === "right", "f-page-content-main": h.value === "center" }; return e.customClass && String(e.customClass).split(" ").reduce((d, C) => (d[C] = !0, d), s), s; }), g = D(() => { const s = { flex: "1" }; return (f.value && h.value === "left" || h.value === "right") && (s.width = `${f.value}px`), (c.value && h.value === "bottom" || h.value === "top") && (s.height = `${c.value}px`), s; }); return () => p("div", { ref: n, class: k.value, style: g.value }, [p("div", { ref: a, class: "drag-container", "data-dragref": `${l.schema.id}-container` }, [t.slots.default && t.slots.default()]), p("span", { class: r.value, onMousedown: (s) => u(s, h.value) }, null)]); } }); te.install = (e) => { e.component(te.name, te), e.component(Z.name, Z); }; te.register = (e, t, n, a) => { e.layout = te, t.layout = dt, e["layout-pane"] = Z, t["layout-pane"] = mt; }; te.registerDesigner = (e, t, n) => { e.layout = aa, t.layout = dt, e["layout-pane"] = ia, t["layout-pane"] = mt; }; const pt = /* @__PURE__ */ new Map([ ["appearance", it] ]), oa = "https://json-schema.org/draft/2020-12/schema", sa = "https://farris-design.gitee.io/combo-list.schema.json", ra = "combo-list", ua = "A Farris Input Component", ca = "object", da = { id: { description: "The unique identifier for a combo list", type: "string" }, type: { description: "The type string of number combo list component", type: "string", default: "combo-list" }, appearance: { description: "", type: "object", properties: { class: { type: "string" }, style: { type: "string" } }, default: {} }, binding: { description: "", type: "object", default: {} }, disabled: { description: "", type: "boolean", default: !1 }, enableClear: { description: "", type: "boolean", default: !1 }, editable: { description: "", type: "boolean", default: !1 }, enableLinkLabel: { description: "", type: "boolean", default: !1 }, label: { description: "", type: "string", default: "" }, lableWidth: { description: "", type: "number" }, placeholder: { description: "", type: "string", default: "请选择" }, idField: { description: "", type: "string", default: "id" }, valueField: { description: "", type: "string", default: "id" }, titleField: { description: "", type: "string", default: "name" }, textField: { description: "", type: "string", default: "name" }, dataSourceType: { description: "", type: "string", default: "static" }, data: { description: "", type: "array" }, dataSource: { description: "", type: "string" }, remote: { description: "", type: "string" }, readonly: { description: "", type: "boolean", default: !1 }, required: { description: "", type: "boolean", default: !1 }, tabindex: { description: "", type: "number", default: -1 }, textAlign: { description: "", type: "string", enum: [ "left", "middle", "right" ], default: "left" }, multiSelect: { description: "", type: "boolean", default: !1 }, maxLength: { description: "", type: "number", default: null }, visible: { description: "", type: "boolean", default: !0 }, onBlur: { description: "", type: "string", default: "" }, onClickLinkLabel: { description: "", type: "string", default: "" }, maxHeight: { description: "", type: "number", default: 350 }, minPanelWidth: { description: "", type: "number", default: 160 }, popupOnClick: { description: "", type: "boolean", default: !0 }, separator: { description: "", type: "string", default: "," }, viewType: { description: "", type: "string", default: "tag" }, enableSearch: { description: "启用搜索", type: "boolean", default: !0 }, enableHighlightSearch: { description: "启用高亮搜索", type: "boolean", default: !1 }, beforeOpen: { description: "打开下拉面板前回调", type: "string" }, beforeHide: { description: "关闭下拉面板前回调", type: "string" }, onShown: { description: "面板打开事件", type: "string" }, onHidden: { description: "面板关闭事件", type: "string" }, onChange: { description: "值变化事件", type: "string", default: "" }, onInput: { description: "输入事件", type: "string", default: "" }, onClear: { description: "清空事件", type: "string", default: "" }, onDataChanged: { description: "清空事件", type: "string", default: "" }, hideDisabledItems: { description: "隐藏禁用项", type: "boolean", default: !1 }, expandable: { description: "", type: "boolean", default: !1 }, expandMode: { description: "", type: "string", default: "text" }, expandContent: { description: "", type: "string", default: "" }, expandDisabled: { description: "", type: "boolean", default: !1 }, onExpandClick: { description: "", type: "string", default: "" } }, fa = [ "type" ], ma = [ "id", "appearance", "binding", "visible" ], ya = { onClear: "清空事件", onShown: "面板打开事件", onHidden: "面板关闭事件", onChange: "值变化事件", beforeOpen: "打开面板前事件", beforeHide: "关闭面板前事件" }, vt = { $schema: oa, $id: sa, title: ra, description: ua, type: ca, properties: da, required: fa, ignore: ma, events: ya }; function ht(e, t, n) { return t; } function pa() { function e(t, n, a) { const l = {}; return l.beforeOpen = (o) => n.call("beforeOpen", t, [o, t], a), l; } return { resolve: e }; } const we = { /** * 组件标识 */ id: { type: String }, /** * 下拉数据源 */ data: { type: Array, default: [] }, /** * 可选,展示文本 * 默认为空字符串 -----内部需要根据value重新生成展示文本,此属性不生效 * displayText: { type: String, default: '' }, */ /** * 可选,是否禁用 * 默认为`false` */ disabled: { default: !1, type: Boolean }, /** * 可选,下拉图标 * 默认为'<span class="f-icon f-icon-arrow-60-down"></span>' */ dropDownIcon: { type: String, default: '<span class="f-icon f-icon-arrow-chevron-down"></span>' }, /** * 可选,是否可编辑 * 默认`false` */ editable: { default: !1, type: Boolean }, /** * 可选,是否启用清空 * 默认启用 */ enableClear: { default: !0, type: Boolean }, /** * 可选,启用搜索 * 默认为`false` */ enableSearch: { type: Boolean, default: !1 }, /** * 可选,鼠标悬停时是否显示控件值 * 默认显示 */ enableTitle: { default: !0, type: Boolean }, fitEditor: { default: !1, type: Boolean }, /** * 可选,强制显示占位符 * 默认`false` */ forcePlaceholder: { default: !1, type: Boolean }, /** * 可选,清空值时隐藏面板 * 默认`true` */ hidePanelOnClear: { default: !0, type: Boolean }, /** * 可选,数据源id字段 * 默认为`id` */ idField: { default: "id", type: String }, /** * 可选,字段映射 */ mapFields: { type: Object }, /** * 可选,最大高度 * 默认`350` */ maxHeight: { default: 350, type: Number }, /** * 最大输入长度 */ maxLength: { type: Number }, /** * 可选,是否支持多选 * 默认`false` */ multiSelect: { type: Boolean, default: !1 }, /** * 绑定值 */ modelValue: { type: String, default: "" }, /** * 占位符 */ placeholder: { type: String, default: "请选择" }, /** * 可选,下拉面板展示位置 * 默认为`auto` */ placement: { type: String, default: "auto" /* auto */ }, /** * 可选,是否只读 * 默认为`false` */ readonly: { default: !1, type: Boolean }, /** * 远端数据源信息 */ remote: { default: null, type: Object }, /** * 可选,是否支持远端过滤 * 默认`false` */ remoteSearch: { default: !1, type: Boolean }, /** * 可选,分隔符 * 默认`,` */ separator: { default: ",", type: String }, /** * tabIndex */ tabIndex: { type: Number, default: -1 }, /** * 可选,数据源显示字段 * 默认为`name` */ textField: { default: "name", type: String }, /** * 可选,数据源的title * 默认为`name` */ titleField: { default: "name", type: String }, /** * 可选,数据源值字段 * 默认为`id` */ valueField: { default: "id", type: String }, /** * 可选,启用多选下,下拉列表值在输入框中的展示方式 * 支持text | tag * 因为ButtonEdit内部处理类型只有在批量的情况下才会有展示类型区分 */ viewType: { default: "tag", type: String }, /** * 值变化事件 */ change: { type: Function, default: () => { } }, /** * 作为内嵌编辑器被创建后默认获得焦点 */ focusOnCreated: { type: Boolean, default: !1 }, /** * 作为内嵌编辑器被创建后默认选中文本 */ selectOnCreated: { type: Boolean, default: !1 }, /** * 此属性废弃 */ autoHeight: { type: Boolean, default: !0 }, /** * 打开前 */ beforeOpen: { type: Function, default: null }, load: { type: Function }, searchOption: { type: [Boolean, Function], default: !1 }, // 搜索启用高亮 enableHighlightSearch: { type: Boolean, default: !0 }, minPanelWidth: { type: Number, default: 160 }, popupOnClick: { type: Boolean, default: !0 }, /** 是否可扩展 */ expandable: { type: Boolean, default: !1 }, /** 扩展模式 text | button */ expandMode: { type: String, default: "text" }, /** 扩展文本内容 */ expandContent: { type: String, default: "" }, /** 扩展按钮是否禁用 */ expandDisabled: { type: Boolean, default: !1 }, popupClass: { type: String, default: "" }, /** * 可选,是否隐藏禁用的数据项 * 默认`false`(禁用项显示为置灰状态) * 设置为`true`时,禁用的数据项将不会在下拉列表中显示 */ hideDisabledItems: { type: Boolean, default: !1 } }, va = Object.assign({}, we, { readonly: {} }); ke(we, vt, pt, ht); const gt = un( we, vt, pt, ht ), ha = pa(), ga = { dataSource: { type: Array, default: [] }, enableSearch: { type: Boolean, default: !1 }, idField: { type: String, default: "id" }, multiSelect: { type: Boolean, default: !1 }, selectedValues: { type: String, default: "" }, separator: { type: String, default: "," }, textField: { type: String, default: "name" }, titleField: { type: String, default: "name" }, width: { type: Number }, maxHeight: { type: Number }, valueField: { type: String, default: "id" }, /** 值变化事件 */ onSelectionChange: { type: Function, default: () => { } }, searchOption: { type: [Boolean, Function], default: !1 }, // 搜索启用高亮 enableHighlightSearch: { type: Boolean, default: !0 } }, ba = /* @__PURE__ */ U({ name: "FComboListContainer", props: ga, emits: ["selectionChange"], setup(e, t) { const n = m(), a = m(e.dataSource), l = m(e.dataSource), o = m([]), i = m(e.separator), c = m(e.width), f = m(e.maxHeight), v = D(() => e.multiSelect), b = m(e.multiSelect ? String(e.selectedValues).split(i.value) : [e.selectedValues]), h = D(() => ({ enableSelectRow: !0, multiSelect: e.multiSelect, multiSelectMode: "OnCheckAndClick", showCheckbox: v.value, showSelectAll: !1, showSelection: !0 })); $(e.dataSource, () => { a.value = e.dataSource, l.value = e.dataSource; }), D(() => e.enableSearch ? "SearchBar" : "ContentHeader"); const w = D(() => { const r = {}; return c.value !== void 0 && (r.width = `${c.value}px`), f.value !== void 0 && f.value > 0 && (r.maxHeight = `${f.value}px`), r; }); function T(r) { n.value.search(r); } function F(r) { o.value = r.map((u) => Object.assign({}, u)), b.value = r.map((u) => u[e.idField]), t.emit("selectionChange", o.value); } function M(r) { if (e.enableHighlightSearch) return; let u = []; const { searchOption: k } = e; typeof k == "function" ? u = a.value.filter((g) => k(r, g)) : u = a.value.filter((g) => g[e.valueField].indexOf(r) > -1 || g[e.textField].indexOf(r) > -1), n.value.updateDataSource(u); } $([() => e.selectedValues], ([r]) => { e.multiSelect ? b.value = r.split(i.value) : b.value = [r]; }); function y(r) { n.value.activeRowById(r); } return X(() => { var r, u; if (!e.multiSelect) { const k = (r = b.value) == null ? void 0 : r[0]; let g = k; const s = a.value.map((d) => d[e.valueField || e.idField]); if (!kn(k) && s.includes(k)) { const d = typeof k, C = typeof ((u = a.value[0]) == null ? void 0 : u[e.valueField || e.idField]); C === "number" && d !== C && (g = Number(k)), C === "boolean" && d !== C && (g = k === "true" ? !0 : k === "false" ? !1 : k), y(g); } } }), t.expose({ search: T, activeRowById: y }), () => p("div", { class: "f-combo-list-container", style: w.value }, [p(Cn, { ref: n, size: "small", itemClass: "f-combo-list-item", itemContentClass: "text-truncate", header: "ContentHeader", headerClass: "f-combo-list-search-box", data: a.value, idField: e.idField, textField: e.textField, titleField: e.titleField, multiSelect: e.multiSelect, selection: h.value, enableHighlightSearch: e.enableHighlightSearch, selectionValues: b.value, onSelectionUpdate: F, onAfterSearch: M }, null)]); } }), Ue = { property: "all", duration: 0.3, timingFunction: "cubic-bezier(0.17, 0.89, 0.45, 1)", delay: 0 }, Ca = (e, t) => { const n = e.lineHeight / 2, a = fn({ maxOverflowY: 44 }), l = ce({ ...Ue }), o = (g) => { t.emit("change", g); }, i = ce({ value: 0, max: 0, min: 0, start: 0, index: 0, currentItem: void 0, active: !1 }), c = () => { i.max = e.visiableOptionCount / 2 * e.lineHeight; const g = e.column.length * e.lineHeight; i.min = i.max - g + e.lineHeight; }, f = (g = 0) => { c(), i.index = g, i.value = i.max - g * e.lineHeight, i.currentItem = e.column[g]; }, v = (g) => { const s = e.column.length - 1, d = Math.min(i.index, s), C = e.column.findIndex((x) => x[e.valueField] === g); return C >= 0 ? C : d; }, b = (g) => { const s = e.column.length - 1; return i.index > s ? e.column[s] : e.column[g]; }, h = (g) => { g && (i.currentItem = g, l.duration = 0); const s = i.currentItem[e.valueField], d = v(s), C = b(i.index)[e.valueField]; f(d), s !== C && setTimeout(() => { o(i.currentItem); }, l.duration * 1e3); }, w = () => { const g = Array.isArray(e.value) ? e.value[0] : e.value; f(v(g)); }; w(), $(() => e.value, () => { e.multiSelect || w(); }), $(() => e.column, () => h()); const T = (g, s = i.max, d = i.min) => { const C = i.start + g; i.value = C > n ? Math.min(C, s) : Math.max(C, d), i.index = Math.round((i.max - i.value) / e.lineHeight), i.currentItem = b(i.index); }, F = mn(), M = (g) => { F.start(g), i.active = !0, i.start = i.value, a.start(i.start), l.duration = 0; }, y = (g) => { g.preventDefault(), F.move(g), T( F.deltaY.value, i.max + e.lineHeight, i.min - e.lineHeight ), a.move(F.deltaY.value), l.duration = Ue.duration; }, r = (g) => { const s = g < 0, d = g % e.lineHeight > n ? 1 : 0, C = Math.floor(g / e.lineHeight); return (s ? C - d : C + d) * e.lineHeight + n; }; return { translateY: i, transition: l, onTouchStart: M, onTouchMove: y, onTouchEnd: () => { i.start = 0; const g = a.end(); let s = 0; if (g) { const { destination: d, duration: C } = a.get(i.value, i.min, i.max); s = d, l.duration = C / 1e3; } else s = i.value; T(r(s)), o(i.currentItem); }, onTransitionend: () => { i.active = !1; }, updateTranslate: h }; }, ka = { column: { type: Array, default: () => [] }, valueField: { type: String, default: "value" }, textField: { type: String, default: "text" }, value: { type: [Array, String, Number], default: () => [] }, multiSelect: { type: Boolean, default: !1 }, showIcon: { type: Boolean, default: !1 }, lineHeight: { type: Number, default: 0 }, visiableOptionCount: { type: Number, default: 5 } }, xa = /* @__PURE__ */ U({ props: ka, emits: ["change", "click"], setup(e, t) { const { addUnit: n } = xe(), { bem: a } = ot("FComboTouchList"), { translateY: l, transition: o, onTouchStart: i, onTouchMove: c, onTouchEnd: f, onTransitionend: v } = Ca(e, t), b = (T) => { t.emit("click", T); }, h = D(() => ({ transform: `translateY(${n(l.value)})`, transition: `all ${l.active ? o.duration : 0}s ${o.timingFunction} 0s` })), w = (T) => e.showIcon ? Array.isArray(e.value) && e.value.includes(T[e.valueField]) : !1; return () => p("div", { class: a("column"), style: h.value, onTouchstart: i, onTouchmove: c, onTouchend: f, onTransitionend: v }, [e.column.map((T) => p("div", { class: a("column-item"), onClick: () => b(T) }, [p("span", null, [T[e.textField]]), w(T) && p("span", { class: `f-icon f-icon-check ${a("column-item-icon")}` }, null)]))]); } }), wa = { modelValue: { type: [String, Array], default: "" }, columns: { type: Array, default: () => [] }, title: { type: String, default: "" }, valueField: { type: String, default: "value" }, textField: { type: String, default: "text" }, childrenField: { type: String, default: "children" }, multiSelect: { type: Boolean, default: !1 }, lineHeight: { type: Number, default: 44 }, cancelText: { type: String, default: "取消" }, confirmText: { type: String, default: "确定" }, optionFormatter: { type: Function, default: void 0 }, visiableOptionCount: { type: Number, default: 5 }, showToolbar: { type: Boolean, default: !0 }, separator: { type: String, default: "," } }, Fa = (e, t) => { const { finalValue: n, initValue: a, setSelectedByIndex: l, getSelectedValueByIndex: o } = t, { isArray: i, isFunction: c, isObject: f } = xe(), v = (s) => s && s[0], b = D(() => { var s; return ((s = e.columns) == null ? void 0 : s.length) > 0 && i(e.columns[0]); }), h = (s) => { if ((s == null ? void 0 : s.length) === 0) return !1; const d = v(s); return d && i(d[e.childrenField]); }, w = (s, d) => { const C = v(s), x = o(d); let I = s.find((N) => N[e.valueField] === x); I = I || C; const R = I[e.childrenField] || []; if (h(R)) { const N = w(R, d + 1); return [R, ...N]; } return [R]; }, T = () => { const s = e.columns, d = w(s, 0); return [s, ...d]; }, F = (s, d) => { const C = s[e.textField]; return c(e.optionFormatter) ? e.optionFormatter(d, s) : C; }, M = (s, d) => s.map((C) => { const x = f(C) ? C : { [e.valueField]: C, [e.textField]: C }; return x[e.textField] = F(x, d), x; }), y = D(() => { let s = []; return b.value ? s = e.columns : h(e.columns) ? s = T() : s = [e.columns], s.map(M); }), r = () => y.value.map((s, d) => { const C = n.value[d]; return s.find((I) => I[e.valueField] === C); }).filter((s) => s), u = () => r().map((s) => s[e.valueField]), k = () => r().map((s) => s[e.textField]).join("-"), g = () => { y.value.forEach((s, d) => { if (e.multiSelect) n.value[d].forEach((x) => { const I = s.find((R) => R[e.valueField] === x); I && l(d, I); }); else { const C = n.value[d], x = s.find((I) => I[e.valueField] === C); x ? l(d, x) : l(d, v(s)); } }); }; return $( () => e.modelValue, () => { a(e.modelValue), g(); }, { immediate: !0 } ), { columns: y, getPickeds: r, getValue: u, getTextValue: k }; }, Sa = (e) => { const { isArray: t, isMultiArray: n, isString: a, isDef: l } = xe(), o = (r) => { let u = []; return t(r) ? u = r : a(r) ? u = r.split(e.separator) : l(r) && (u = [r]), e.multiSelect ? n(u) ? u : [u] : u; }, i = m([]), c = (r) => { i.value = o(r); }, f = ce([]), v = D(() => f.map((r) => r[e.valueField])), b = ce([]), h = D(() => b.map((r) => r.map((u) => u[e.valueField]))); return { finalValue: i, initValue: c, getSelected: () => e.multiSelect ? b : f, getSelectedValue: () => e.multiSelect ? h.value : v.value, setSelectedByIndex: (r, u) => { if (e.multiSelect) { const k = b[r] || []; k.includes(u) ? b[r] = k.filter((g) => g !== u) : b[r] = [...k, u]; } else f[r] = u; }, getSelectedByIndex: (r) => e.multiSelect ? b[r] : f[r], getSelectedValueByIndex: (r) => e.multiSelect ? h.value[r] : v.value[r] }; }, Ta = /* @__PURE__ */ U({ props: wa, emits: ["change", "confirm", "cancel", "update:modelValue"], setup(e, t) { const { emit: n } = t, { addUnit: a } = xe(), l = Sa(e), { finalValue: o, getSelectedValue: i, getSelectedValueByIndex: c, getSelected: f, setSelectedByIndex: v } = l, { columns: b } = Fa(e, l), h = (k, g = !0) => { const { value: s, index: d } = k; (g && !e.multiSelect || !g && e.multiSelect) && (n("change", k), v(d, s)); }, w = () => { o.value = i(), n("confirm", f()), n("update:modelValue", o.value); }, T = () => { n("cancel"); }, { bem: F } = ot("FComboTouchList"), M = () => p("div", { class: F("toolbar") }, [p("div", { class: F("toolbar-left"), onClick: T }, [p("span", null, [e.cancelText])]), p("div", { class: F("toolbar-title") }, [p("span", null, [e.title])]), p("div", { class: F("toolbar-right"), onClick: w }, [p("span", null, [e.confirmText])])]), y = D(() => { const k = (e.visiableOptionCount + 1) * e.lineHeight; return { height: a(k) }; }), r = D(() => { const k = e.visiableOptionCount * e.lineHeight / 2; return { backgroundSize: `100% ${a(k)}` }; }), u = () => p("div", { class: F("content") }, [p("div", { class: F("columns"), style: y.value }, [b.value.map((k, g) => p(xa, { column: k, value: c(g), showIcon: e.multiSelect, textField: e.textField, multiSelect: e.multiSelect, valueField: e.valueField, lineHeight: e.lineHeight, visiableOptionCount: e.visiableOptionCount, onChange: (s) => h({ value: s, index: g }), onClick: (s) => h({ value: s, index: g }, !1) }, null)), !e.multiSelect && p("div", { class: F("mask"), style: r.value }, null), p("div", { class: F("frame") }, null)])]); return () => p("div", { class: F("") }, [e.showToolbar && M(), u()]); } }); function Ma(e, t) { const n = m(""), a = m(e.modelValue), l = m(e.data || []), o = m(e.editable), i = D(() => e.hideDisabledItems ? l.value.filter((r) => !r.disabled) : l.value); function c(r) { const u = e.multiSelect ? String(r).split(e.separator) : [String(r)], k = u.map((d) => [d, !0]), g = new Map(k); return l.value.filter((d) => g.has(String(d[e.valueField]))).sort((d, C) => { const x = u.indexOf(d[e.valueField]), I = u.indexOf(C[e.valueField]); return x - I; }); } function f(r) { const u = c(r).map((k) => k[e.textField]).join(e.separator); n.value = o.value ? u || r : u; } function v(r) { if (e.multiSelect) { const u = r.split(e.separator).map((g) => [g, !0]), k = new Map(u); return l.value.filter((g) => k.has(g[e.textField])); } return l.value.filter((u) => "" + u[e.textField] === r); } function b(r) { const u = {}; return u[e.idField] = r, u[e.textField] = r, [u]; } function h(r) { let u = v(r); const k = u && u.length > 0; return o.value && !k && (u = b(r)), u; } function w() { const { url: r, method: u = "GET", headers: k = { "Content-Type": "application/json;charset=utf-8;" }, body: g = null } = e.remote; if (!r) return; const { basePath: s } = yn().value, d = u.toLowerCase() === "get" ? { method: u, headers: k } : { method: u, headers: k, body: g }; let C = !1; fetch(new Request(s + r, d)).then((x) => { var R, N; if (x.status === 200) return C = !!((N = (R = x.headers) == null ? void 0 : R.get("content-type")) != null && N.includes("application/json")), C ? x.text() : x.json(); throw x.status === 405 ? new Error(J.getLocaleValue("comboList.remoteError")) : new Error(x.statusText); }).then((x) => { x.length && (l.value = C ? JSON.parse(x) : x, a.value && f(a.value)); }).catch((x) => { console.warn(x); }); } e.remote && (e.load ? e.load().then((r) => { l.value = r; }).catch((r) => { console.log(r); }) : w()), $(() => e.data, () => { l.value = e.data; }), $([l], ([r], [u]) => { if (e.modelValue != null && !e.multiSelect) { const k = r.find((g) => g[e.valueField] === a.value); k ? k[e.valueField] !== a.value ? (a.value = k[e.valueField], n.value = k[e.textField], t.emit("update:modelValue", k[e.valueField]), t.emit("change", [k], k[e.valueField])) : n.value !== k[e.textField] && (n.value = k[e.textField]) : a.value !== "" && (a.value = "", n.value = "", t.emit("update:modelValue", ""), t.emit("change", [], "")); } }), $(() => e.modelValue, (r, u) => { u !== r && (a.value = r, f(r)); }); function T(r) { l.value = r, t.emit("dataChanged", r); } function F() { return l.value; } function M() { return n.value; } async function y() { const r = typeof e.beforeOpen == "function"; return !e.beforeOpen || !r ? Promise.resolve(!0) : Promise.resolve().then(() => e.beforeOpen({ instance: { updateDataSource: T, getData: F, getDisplayText: M } })).then((u) => typeof (u == null ? void 0 : u.canOpen) == "boolean" ? u == null ? void 0 : u.canOpen : !0); } return f(e.modelValue), { dataSource: l, filteredDataSource: i, displayText: n, editable: o, modelValue: a, beforeOpenList: y, getItemsByDisplayText: v, getItemsByValue: c, getSelectedItemsByDisplayText: h }; } const Oa = ["moz", "ms", "webkit"]; function Ba() { let e = 0; return (t) => { const n = (/* @__PURE__ */ new Date()).getTime(), a = Math.max(0, 16 - (n - e)), l = setTimeout(() => { t(n + a); }, a); return e = n + a, l; }; } function Ea() { if (typeof window > "u") return () => 0; if (window.requestAnimationFrame) return window.requestAnimationFrame.bind(window); const e = Oa.filter((t) => `${t}RequestAnimationFrame` in window)[0]; return e ? window[`${e}RequestAnimationFrame`] : Ba(); } Ea(); m(""); function Ne() { const e = navigator.userAgent || navigator.vendor || window.opera, t = [ /iPhone/i, /iPod/i, /Android.*Mobile/i, // Android 手机通常包含 "Mobile" 字样,而平板不包含 /webOS/i, /BlackBerry/i, /IEMobile/i, /Opera Mini/i, /Harmony/i ], n = [ /iPad/i, /Android(?!.*Mobile)/i, // Android 平板通常不含 "Mobile" /Tablet/i, /PlayBook/i, /Kindle/i, /Silk/i ]; for (const c of n) if (c.test(e)) return !1; for (const c of t) if (c.test(e)) return !0; const a = "ontouchstart" in window || navigator.maxTouchPoints > 0, l = screen.width, o = screen.height, i = Math.min(l, o); return !!(a && i <= 768); } const fe = /* @__PURE__ */ U({ name: "FComboList", props: we, emits: ["clear", "update:modelValue", "change", "input", "dataChanged", "expandClick"], setup(e, t) { const n = m(), a = m(), l = m(e.disabled || e.readonly), o = m(e.enableClear), i = m(e.enableSearch), c = m(e.readonly), { dataSource: f, displayText: v, editable: b, modelValue: h, filteredDataSource: w, getItemsByDisplayText: T, getItemsByValue: F, beforeOpenList: M } = Ma(e, t), y = m(e.dropDownIcon); y.value === '<span class="f-icon f-icon-arrow-chevron-down"></span>' && (y.value = '<span id="' + e.id + '-icon-dropdown" class="f-icon f-icon-arrow-chevron-down"></span>'); const r = D(() => e.multiSelect), u = D(() => a.value ? a.value.elementRef.getBoundingClientRect().width : 0); function k() { !r.value && a.value && a.value.hidePopup(); } function g(V) { v.value = V.map((E) => E[e.textField]).join(e.separator) || h.value; let O = ""; V.length === 1 ? O = V[0][e.valueField] : O = V.map((E) => E[e.valueField]).join(e.separator), h.value !== O && (h.value = O, t.emit("update:modelValue", h.value), t.emit("change", V, h.value)); } function s() { const V = F(h.value); g(V); } function d() { c.value || v.value; } function C(V) { var O; h.value = "", (O = n.value) == null || O.activeRowById(""), t.emit("clear"); } function x(V) { var O, E; e.enableSearch && e.enableHighlightSearch && ((O = n.value) == null || O.search(V)), (E = n.value) == null || E.activeRowById(V), t.emit("change", [h.value], h.value); } function I(V) { if (e.multiSelect) { const O = T(V); e.viewType; const L = O.map((A) => A[e.idField || e.valueField]).join(e.separator); h.value !== L && (h.value = L, t.emit("update:modelValue", h.value), t.emit("change", O, h.value)); } else V !== h.value && (h.value = V, t.emit("update:modelValue", h.value), t.emit("change", [], V)); } function R() { return v.value; } function N(V) { const { value: O } = V.target; x(O), t.emit("input", O); } function P() { a.value.hidePopup(); } function S(V) { f.value = V; } function j() { return f.value; } const z = { getDisplayText: R, hidePopup: P, updateDataSource: S, getData: j }; t.expose(z), $([() => e.disabled, () => e.editable, () => e.enableClear, () => e.enableSearch, () => e.readonly], ([V, O, E, L, A]) => { l.value = V, b.value = O, o.value = E, i.value = L, c.value = A; }); const Y = () => { t.emit("expandClick"); }; return () => p(bn, { ref: a, id: e.id, disable: l.value, readonly: c.value, forcePlaceholder: e.forcePlaceholder, editable: b.value, buttonContent: y.value, placeholder: e.placeholder === "请选择" ? J.getLocaleValue("comboList.placeholder") : e.placeholder, enableClear: o.value, maxLength: e.maxLength, tabIndex: e.tabIndex, enableTitle: e.enableTitle,