UNPKG

@farris/ui-vue

Version:

Farris Vue, a Farris Design based Vue3 component library.

1,856 lines 245 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 v, watch as $, inject as _, onMounted as K, 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 ke, Fragment as oe, onBeforeMount as tn, watchEffect as nn, Transition as lt, shallowRef as an, render as Be, h as ln, cloneVNode as on, mergeProps as Ve, vShow as sn, onUpdated as rn } from "vue"; import { resolveAppearance as it, createPropsResolver as xe, getPropsResolverGenerator as un } from "../dynamic-resolver/index.esm.js"; import { getCustomClass as cn, getCustomStyle as dn, useTouchMomentum as fn, useTouch as mn, useCommonUtils as we, 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 Ne, 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 = xe(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), f = D(() => ({ display: o.value ? "block" : "none", left: `${a.value}px`, cursor: "e-resize" })), c = D(() => ({ display: i.value ? "block" : "none", top: `${l.value}px`, cursor: "n-resize" })), p = D(() => { const y = { display: i.value || o.value ? "block" : "none" }; return l.value > 0 && (y.cursor = "n-resize"), y; }); function g(y, r, u, k) { const b = e.value; if (b) { const { left: s, right: d, width: C } = b.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 b = e.value; if (b) { const { top: s, bottom: d, height: C } = b.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 b = k == null ? void 0 : k.right, s = k == null ? void 0 : k.left; if (y === "left" && s) return b ? u.width - b.clientWidth - r : u.width - r; if (y === "right" && b) return s ? u.width - s.clientWidth - r : u.width - r; } } function M(y, r) { const u = w(), k = T(); if (u && k) { const b = k == null ? void 0 : k.bottom, s = k == null ? void 0 : k.top; if (y === "top" && s) return b ? u.height - b.clientHeight - r : u.height - r; if (y === "bottom" && b) return s ? u.height - s.clientHeight - r : u.height - r; } } return { horizontalResizeHandleStyle: f, verticalResizeHandleStyle: c, resizeOverlayStyle: p, showHorizontalResizeHandle: o, showVerticalResizeHandle: i, horizontalResizeBarPosition: t, verticalResizeBarPosition: n, verticalResizeHandleOffset: l, horizontalResizeHandleOffset: a, draggingHorizontalResizeHandle: g, 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 f = D(() => cn({ "f-layout": !0 }, e == null ? void 0 : e.customClass)), c = D(() => dn({}, e == null ? void 0 : e.customStyle)); return () => v("div", { class: f.value, style: c.value, ref: n }, [t.slots.default && t.slots.default(), v("div", { class: "f-layout-resize-overlay", style: i.value }, null), v("div", { class: "f-layout-horizontal-resize-proxy", style: l.value }, null), v("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", Xn = { 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 } }, Kn = [ "id", "type", "contents" ], _n = { $schema: Wn, $id: Yn, title: qn, description: Un, type: Gn, properties: Xn, required: Kn }, 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 = xe(ze, _n, ut, ct, ta); function yt(e, t, n, a, l, o) { const { horizontalResizeBarPosition: i, horizontalResizeHandleOffset: f, showHorizontalResizeHandle: c, showVerticalResizeHandle: p, verticalResizeBarPosition: g, verticalResizeHandleOffset: h, draggingHorizontalResizeHandle: w, draggingVerticalResizeHandle: T, getPanelMaxHeight: F, getPanelMaxWidth: M } = l; let y = "", r, u, k; const b = () => 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 = b(); 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 - g.value) : (R || 0) - (N - g.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; } f.value = 0, h.value = 0, i.value = -1, g.value = -1, c.value = !1, p.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, c.value = !0, u = x.composedPath().find((P) => (P.className || "").split(" ")[0] === "f-layout"), u) { const { left: P } = u.getBoundingClientRect(), S = x.clientX - P; f.value = S, i.value = S; const j = b(); 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, p.value = !0, u = x.composedPath().find((P) => (P.className || "").split(" ")[0] === "f-layout"), u) { const { top: P } = u.getBoundingClientRect(); h.value = x.clientY - P, g.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)), f = m(Math.max(a.value, l.value)), c = m(), p = m(e.position), g = m(e.resizable); $(() => e.resizable, (s) => { g.value = s; }); const h = _("layout"), { useResizeHandleComposition: w } = h, T = yt(f, i, a, n, w, e), { onClickHorizontalResizeBar: F, onClickVerticalResizeBar: M } = T, y = D(() => ({ "f-layout-resize-bar": !0, "f-layout-resize-bar-e": p.value === "left", "f-layout-resize-bar-n": p.value === "bottom", "f-layout-resize-bar-s": p.value === "top", "f-layout-resize-bar-w": p.value === "right" })), r = D(() => p.value !== "center" && g.value); function u(s, d) { (d === "left" || d === "right") && F(s, d, c.value), (d === "top" || d === "bottom") && M(s, d, c.value); } const k = D(() => { const s = { "f-layout-pane": !0, "f-page-content-nav": p.value === "left" || p.value === "right", "f-page-content-main": p.value === "center" }; return e.customClass && String(e.customClass).split(" ").reduce((d, C) => (d[C] = !0, d), s), s; }), b = D(() => { const s = {}; return (f.value && p.value === "left" || p.value === "right") && (s.width = `${f.value}px`), (i.value && p.value === "bottom" || p.value === "top") && (s.height = `${i.value}px`), e.visible || (s.display = "none"), s; }); return () => v("div", { ref: c, class: k.value, style: b.value, "data-position": p.value }, [t.slots.default && t.slots.default(), r.value && v("span", { class: y.value, onMousedown: (s) => u(s, p.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 g; const n = m(), a = _("design-item-context"), l = na(a.schema, (g = a.parent) == null ? void 0 : g.schema), o = Le(n, a, l); o.value.canNested = !1; const i = ft(n), { horizontalResizeHandleStyle: f, verticalResizeHandleStyle: c, resizeOverlayStyle: p } = i; return et("layout", { useResizeHandleComposition: i }), K(() => { n.value.componentInstance = o; }), t.expose(o.value), () => v("div", { class: "f-layout f-page-content", ref: n }, [t.slots.default && t.slots.default(), v("div", { class: "f-layout-resize-overlay", style: p.value }, null), v("div", { class: "f-layout-horizontal-resize-proxy", style: f.value }, null), v("div", { class: "f-layout-vertical-resize-proxy", style: c.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, K(() => { a.value.componentInstance = i; }), t.expose(i.value); const f = m(Math.max(e.minHeight, e.height)), c = m(Math.max(e.minWidth, e.width)), p = m(e.minHeight), g = m(e.minWidth), h = m(e.position), w = _("layout"), { useResizeHandleComposition: T } = w, F = yt(c, f, g, p, 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; }), b = D(() => { const s = { flex: "1" }; return (c.value && h.value === "left" || h.value === "right") && (s.width = `${c.value}px`), (f.value && h.value === "bottom" || h.value === "top") && (s.height = `${f.value}px`), s; }); return () => v("div", { ref: n, class: k.value, style: b.value }, [v("div", { ref: a, class: "drag-container", "data-dragref": `${l.schema.id}-container` }, [t.slots.default && t.slots.default()]), v("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: "" }, showSelectAll: { description: "", type: "boolean", default: !1 } }, 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 Fe = { /** * 组件唯一标识。 */ id: { type: String }, /** * 下拉列表数据源。 * * @default [] */ data: { type: Array, default: [] }, /** * 是否禁用组件。 * * @default false */ disabled: { default: !1, type: Boolean }, /** * 下拉按钮图标 HTML 字符串。 * * @default '<span class="f-icon f-icon-arrow-chevron-down"></span>' */ dropDownIcon: { type: String, default: '<span class="f-icon f-icon-arrow-chevron-down"></span>' }, /** * 是否允许在输入框中直接编辑文本。 * * @default false */ editable: { default: !1, type: Boolean }, /** * 是否启用清空按钮。 * * @default true */ enableClear: { default: !0, type: Boolean }, /** * 是否启用下拉面板搜索。 * * @default false */ enableSearch: { type: Boolean, default: !1 }, /** * 鼠标悬停时是否显示控件值提示。 * * @default true */ enableTitle: { default: !0, type: Boolean }, /** * 是否自适应编辑器宽度。 * * @default false */ fitEditor: { default: !1, type: Boolean }, /** * 是否在禁用或只读状态下强制显示占位符。 * * @default false */ forcePlaceholder: { default: !1, type: Boolean }, /** * 清空值时是否隐藏下拉面板。 * * @default true */ hidePanelOnClear: { default: !0, type: Boolean }, /** * 数据源中作为唯一标识的字段名。 * * @default 'id' */ idField: { default: "id", type: String }, /** * 字段映射配置。 */ mapFields: { type: Object }, /** * 下拉面板最大高度,单位 px。 * * @default 350 */ maxHeight: { default: 350, type: Number }, /** * 可编辑状态下的最大输入长度。 */ maxLength: { type: Number }, /** * 是否支持多选。 * * @default false */ multiSelect: { type: Boolean, default: !1 }, /** * 可选,多选模式下是否显示全选复选框 * 默认`false` */ showSelectAll: { type: Boolean, default: !1 }, /** * 绑定值 * 组件绑定值。 * * @default '' */ modelValue: { type: String, default: "" }, /** * 值为空时的占位符文本。 * * @default '请选择' */ placeholder: { type: String, default: "请选择" }, /** * 下拉面板展示位置。 * * @default Placement.auto */ placement: { type: String, default: "auto" /* auto */ }, /** * 是否只读。 * * @default false */ readonly: { default: !1, type: Boolean }, /** * 远端数据源配置,设置后将优先从远端加载数据。 * * @default null */ remote: { default: null, type: Object }, /** * 是否支持远端过滤搜索。 * * @default false */ remoteSearch: { default: !1, type: Boolean }, /** * 多选时多个值之间的分隔符。 * * @default ',' */ separator: { default: ",", type: String }, /** * 组件的 tab 索引。 * * @default -1 */ tabIndex: { type: Number, default: -1 }, /** * 数据源中作为显示文本的字段名。 * * @default 'name' */ textField: { default: "name", type: String }, /** * 数据源中作为 title 提示的字段名。 * * @default 'name' */ titleField: { default: "name", type: String }, /** * 数据源中作为绑定值的字段名。 * * @default 'id' */ valueField: { default: "id", type: String }, /** * 多选时选中值在输入框中的展示方式。 * * @remarks * 支持 `text`(文本)和 `tag`(标签)两种模式。 * * @default 'tag' */ viewType: { default: "tag", type: String }, /** * 值变化回调函数。 * * @default () => {} */ change: { type: Function, default: () => { } }, /** * 作为内嵌编辑器创建后是否自动获得焦点。 * * @default false */ focusOnCreated: { type: Boolean, default: !1 }, /** * 作为内嵌编辑器创建后是否默认选中文本。 * * @default false */ selectOnCreated: { type: Boolean, default: !1 }, /** * 是否根据内容自动计算高度。 * * @deprecated 该属性已废弃。 * @default true */ autoHeight: { type: Boolean, default: !0 }, /** * 下拉面板打开前的回调函数,返回 false 可阻止打开。 * * @default null */ beforeOpen: { type: Function, default: null }, /** * 自定义远端数据加载函数,返回 Promise。 */ load: { type: Function }, /** * 搜索过滤配置,可传入布尔值或自定义过滤函数。 * * @default false */ searchOption: { type: [Boolean, Function], default: !1 }, /** * 搜索时是否高亮匹配文本。 * * @default true */ enableHighlightSearch: { type: Boolean, default: !0 }, /** * 下拉面板最小宽度,单位 px。 * * @default 160 */ minPanelWidth: { type: Number, default: 160 }, /** * 是否在点击输入框时弹出下拉面板。 * * @default true */ popupOnClick: { type: Boolean, default: !0 }, /** * 是否可扩展(显示扩展按钮/文本)。 * * @default false */ expandable: { type: Boolean, default: !1 }, /** * 扩展模式,可选 `text` 或 `button`。 * * @default 'text' */ expandMode: { type: String, default: "text" }, /** * 扩展区域显示的文本内容。 * * @default '' */ expandContent: { type: String, default: "" }, /** * 扩展按钮是否禁用。 * * @default false */ expandDisabled: { type: Boolean, default: !1 }, /** * 下拉面板的自定义 CSS 类名。 * * @default '' */ popupClass: { type: String, default: "" }, /** * 是否隐藏禁用的数据项。 * * @remarks * 默认 `false`,禁用项显示为置灰状态;设置为 `true` 时禁用项不显示。 * * @default false */ hideDisabledItems: { type: Boolean, default: !1 } }, va = Object.assign({}, Fe, { readonly: {} }); xe(Fe, vt, pt, ht); const gt = un( Fe, 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 }, /** 多选模式下是否显示全选复选框 */ showSelectAll: { 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), f = m(e.width), c = m(e.maxHeight), p = D(() => e.multiSelect), g = m(e.multiSelect ? String(e.selectedValues).split(i.value) : [e.selectedValues]), h = D(() => ({ enableSelectRow: !0, multiSelect: e.multiSelect, multiSelectMode: "OnCheckAndClick", showCheckbox: p.value, showSelectAll: e.showSelectAll, showSelection: !0 })); $(e.dataSource, () => { a.value = e.dataSource, l.value = e.dataSource; }), D(() => e.enableSearch ? "SearchBar" : "ContentHeader"); const w = D(() => { const r = {}; return f.value !== void 0 && (r.width = `${f.value}px`), c.value !== void 0 && c.value > 0 && (r.maxHeight = `${c.value}px`), r; }); function T(r) { n.value.search(r); } function F(r) { o.value = r.map((u) => Object.assign({}, u)), g.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((b) => k(r, b)) : u = a.value.filter((b) => b[e.valueField].indexOf(r) > -1 || b[e.textField].indexOf(r) > -1), n.value.updateDataSource(u); } $([() => e.selectedValues], ([r]) => { e.multiSelect ? r === null ? g.value = [] : g.value = r.split(i.value) : r === null ? g.value = [] : g.value = [r]; }); function y(r) { n.value.activeRowById(r); } return K(() => { var r, u; if (!e.multiSelect) { const k = (r = g.value) == null ? void 0 : r[0]; let b = 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 && (b = Number(k)), C === "boolean" && d !== C && (b = k === "true" ? !0 : k === "false" ? !1 : k), y(b); } } }), t.expose({ search: T, activeRowById: y }), () => v("div", { class: "f-combo-list-container", style: w.value }, [v(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: g.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 = (b) => { t.emit("change", b); }, i = ce({ value: 0, max: 0, min: 0, start: 0, index: 0, currentItem: void 0, active: !1 }), f = () => { i.max = e.visiableOptionCount / 2 * e.lineHeight; const b = e.column.length * e.lineHeight; i.min = i.max - b + e.lineHeight; }, c = (b = 0) => { f(), i.index = b, i.value = i.max - b * e.lineHeight, i.currentItem = e.column[b]; }, p = (b) => { const s = e.column.length - 1, d = Math.min(i.index, s), C = e.column.findIndex((x) => x[e.valueField] === b); return C >= 0 ? C : d; }, g = (b) => { const s = e.column.length - 1; return i.index > s ? e.column[s] : e.column[b]; }, h = (b) => { b && (i.currentItem = b, l.duration = 0); const s = i.currentItem[e.valueField], d = p(s), C = g(i.index)[e.valueField]; c(d), s !== C && setTimeout(() => { o(i.currentItem); }, l.duration * 1e3); }, w = () => { const b = Array.isArray(e.value) ? e.value[0] : e.value; c(p(b)); }; w(), $(() => e.value, () => { e.multiSelect || w(); }), $(() => e.column, () => h()); const T = (b, s = i.max, d = i.min) => { const C = i.start + b; i.value = C > n ? Math.min(C, s) : Math.max(C, d), i.index = Math.round((i.max - i.value) / e.lineHeight), i.currentItem = g(i.index); }, F = mn(), M = (b) => { F.start(b), i.active = !0, i.start = i.value, a.start(i.start), l.duration = 0; }, y = (b) => { b.preventDefault(), F.move(b), T( F.deltaY.value, i.max + e.lineHeight, i.min - e.lineHeight ), a.move(F.deltaY.value), l.duration = Ue.duration; }, r = (b) => { const s = b < 0, d = b % e.lineHeight > n ? 1 : 0, C = Math.floor(b / 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 b = a.end(); let s = 0; if (b) { 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 } = we(), { bem: a } = ot("FComboTouchList"), { translateY: l, transition: o, onTouchStart: i, onTouchMove: f, onTouchEnd: c, onTransitionend: p } = Ca(e, t), g = (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 () => v("div", { class: a("column"), style: h.value, onTouchstart: i, onTouchmove: f, onTouchend: c, onTransitionend: p }, [e.column.map((T) => v("div", { class: a("column-item"), onClick: () => g(T) }, [v("span", null, [T[e.textField]]), w(T) && v("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: f, isObject: c } = we(), p = (s) => s && s[0], g = 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 = p(s); return d && i(d[e.childrenField]); }, w = (s, d) => { const C = p(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 f(e.optionFormatter) ? e.optionFormatter(d, s) : C; }, M = (s, d) => s.map((C) => { const x = c(C) ? C : { [e.valueField]: C, [e.textField]: C }; return x[e.textField] = F(x, d), x; }), y = D(() => { let s = []; return g.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("-"), b = () => { 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, p(s)); } }); }; return $( () => e.modelValue, () => { a(e.modelValue), b(); }, { immediate: !0 } ), { columns: y, getPickeds: r, getValue: u, getTextValue: k }; }, Sa = (e) => { const { isArray: t, isMultiArray: n, isString: a, isDef: l } = we(), 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([]), f = (r) => { i.value = o(r); }, c = ce([]), p = D(() => c.map((r) => r[e.valueField])), g = ce([]), h = D(() => g.map((r) => r.map((u) => u[e.valueField]))); return { finalValue: i, initValue: f, getSelected: () => e.multiSelect ? g : c, getSelectedValue: () => e.multiSelect ? h.value : p.value, setSelectedByIndex: (r, u) => { if (e.multiSelect) { const k = g[r] || []; k.includes(u) ? g[r] = k.filter((b) => b !== u) : g[r] = [...k, u]; } else c[r] = u; }, getSelectedByIndex: (r) => e.multiSelect ? g[r] : c[r], getSelectedValueByIndex: (r) => e.multiSelect ? h.value[r] : p.value[r] }; }, Ta = /* @__PURE__ */ U({ props: wa, emits: ["change", "confirm", "cancel", "update:modelValue"], setup(e, t) { const { emit: n } = t, { addUnit: a } = we(), l = Sa(e), { finalValue: o, getSelectedValue: i, getSelectedValueByIndex: f, getSelected: c, setSelectedByIndex: p } = l, { columns: g } = Fa(e, l), h = (k, b = !0) => { const { value: s, index: d } = k; (b && !e.multiSelect || !b && e.multiSelect) && (n("change", k), p(d, s)); }, w = () => { o.value = i(), n("confirm", c()), n("update:modelValue", o.value); }, T = () => { n("cancel"); }, { bem: F } = ot("FComboTouchList"), M = () => v("div", { class: F("toolbar") }, [v("div", { class: F("toolbar-left"), onClick: T }, [v("span", null, [e.cancelText])]), v("div", { class: F("toolbar-title") }, [v("span", null, [e.title])]), v("div", { class: F("toolbar-right"), onClick: w }, [v("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 = () => v("div", { class: F("content") }, [v("div", { class: F("columns"), style: y.value }, [g.value.map((k, b) => v(xa, { column: k, value: f(b), showIcon: e.multiSelect, textField: e.textField, multiSelect: e.multiSelect, valueField: e.valueField, lineHeight: e.lineHeight, visiableOptionCount: e.visiableOptionCount, onChange: (s) => h({ value: s, index: b }), onClick: (s) => h({ value: s, index: b }, !1) }, null)), !e.multiSelect && v("div", { class: F("mask"), style: r.value }, null), v("div", { class: F("frame") }, null)])]); return () => v("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 f(r) { const u = e.multiSelect ? String(r).split(e.separator) : [String(r)], k = u.map((d) => [d, !0]), b = new Map(k); return l.value.filter((d) => b.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 c(r) { const u = f(r).map((k) => k[e.textField]).join(e.separator); n.value = o.value ? u || r : u; } function p(r) { if (e.multiSelect) { const u = r.split(e.separator).map((b) => [b, !0]), k = new Map(u); return l.value.filter((b) => k.has(b[e.textField])); } return l.value.filter((u) => "" + u[e.textField] === r); } function g(r) { const u = {}; return u[e.idField] = r, u[e.textField] = r, [u]; } function h(r) { let u = p(r); const k = u && u.length > 0; return o.value && !k && (u = g(r)), u; } function w() { const { url: r, method: u = "GET", headers: k = { "Content-Type": "application/json;charset=utf-8;" }, body: b = null } = e.remote; if (!r) return; const { basePath: s } = yn().value, d = u.toLowerCase() === "get" ? { method: u, headers: k } : { method: u, headers: k, body: b }; 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 && c(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((b) => b[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, c(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 c(e.modelValue), { dataSource: l, filteredDataSource: i, displayText: n, editable: o, modelValue: a, beforeOpenList: y, getItemsByDisplayText: p, getItemsByValue: f, 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 be() { if (typeof window > "u" || typeof navigator > "u") return !1; 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; if (typeof screen > "u") return !1; const a = "ontouchstart" in window || navigator.maxTouchPoints > 0, l = screen.width, o = screen.height, i = Math.min(l, o); return !!(a && i <= 768); } function Da() { const e = be(); return e && document.body.classList.add("f-mobile"), e; } typeof document < "u" && Da(); const fe = /* @__PURE__ */ U({ name: "FComboList", props: Fe, emits: ["clear", "update:modelValue", "change", "input", "dataChanged", "expandClick", "hidden", "shown"], setup(e, t) { const n = m(), a = m(), l = m(e.disabled || e.readonly), o = m(e.enableClear), i = m(e.enableSearch), f = m(e.readonly), { dataSource: c, displayText: p, editable: g, 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 b(V) { p.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); b(V); } function d() { f.value || p.value; } function C(V) { var O; h.value = "", (O = n.value) == null || O.activeRowById(""), t.emit("clear"); } function x(V) { var O, E; e.enableSe