@farris/ui-vue
Version:
Farris Vue, a Farris Design based Vue3 component library.
1,770 lines • 223 kB
JavaScript
var At = Object.defineProperty;
var $t = (e, t, n) => t in e ? At(e, t, { enumerable: !0, configurable: !0, writable: !0, value: n }) : e[t] = n;
var ee = (e, t, n) => $t(e, typeof t != "symbol" ? t + "" : t, n);
import { ref as c, computed as D, defineComponent as U, provide as Xe, createVNode as v, watch as W, inject as J, onMounted as K, onBeforeUnmount as Ke, nextTick as te, createTextVNode as ve, withDirectives as _e, vModelText as Wt, Teleport as Je, createApp as Pe, onUnmounted as ge, Fragment as ie, onBeforeMount as Yt, watchEffect as qt, Transition as Ze, shallowRef as Gt, render as Se, h as Ut, cloneVNode as Xt, mergeProps as Ne, vShow as Kt, onUpdated as _t, reactive as Jt } from "vue";
import { resolveAppearance as Qe, createPropsResolver as be, getPropsResolverGenerator as Zt } from "../dynamic-resolver/index.esm.js";
import { getCustomClass as Qt, getCustomStyle as en, FormSchemaEntityFieldType$Type as me, withInstall as tn, isMobilePhone as nn, getMaxZIndex as He, useGuid as an } from "../common/index.esm.js";
import { useDesignerComponent as Ie, useDragulaCommonRule as ln } from "../designer-canvas/index.esm.js";
import on, { FButtonEdit as et } from "../button-edit/index.esm.js";
import { LocaleService as Z } from "../locale/index.esm.js";
import { isUndefined as sn, cloneDeep as Ee, debounce as rn } from "lodash-es";
import un from "../list-view/index.esm.js";
import cn from "../../designer/button-edit/index.esm.js";
import { InputBaseProperty as dn } from "../property-panel/index.esm.js";
import fn from "../tree-view/index.esm.js";
import mn from "../tags/index.esm.js";
import yn from "../popover/index.esm.js";
const pn = {
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
}
}, tt = /* @__PURE__ */ new Map([
["appearance", Qe]
]);
function nt(e, t, n) {
return t;
}
const vn = "https://json-schema.org/draft/2020-12/schema", hn = "https://farris-design.gitee.io/layout.schema.json", gn = "layout", bn = "A Farris Container Component", kn = "object", Cn = {
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
}
}, wn = [
"id",
"type",
"contents"
], xn = {
$schema: vn,
$id: hn,
title: gn,
description: bn,
type: kn,
properties: Cn,
required: wn
}, Fn = "layout", Sn = "A Farris Component", Tn = "object", Mn = {
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"
}
}
}
}, On = {
title: Fn,
description: Sn,
type: Tn,
categories: Mn
}, je = {
customStyle: { type: String, defaut: "" },
customClass: { type: String, defaut: "" }
}, at = be(je, xn, tt, nt, On);
function lt(e) {
const t = c(-1), n = c(-1), a = c(0), l = c(0), o = c(!1), s = c(!1), r = D(() => ({
display: o.value ? "block" : "none",
left: `${a.value}px`,
cursor: "e-resize"
})), d = D(() => ({
display: s.value ? "block" : "none",
top: `${l.value}px`,
cursor: "n-resize"
})), y = D(() => {
const i = {
display: s.value || o.value ? "block" : "none"
};
return l.value > 0 && (i.cursor = "n-resize"), i;
});
function g(i, m, f, C) {
const M = e.value;
if (M) {
const { left: u, right: p, width: k } = M.getBoundingClientRect();
let w = i.clientX - u;
C === "right" && (w = p - i.clientX), w > m && (w = m), w < f && (w = f), C === "right" && (w = k - w), a.value = w;
}
}
function h(i, m, f, C) {
const M = e.value;
if (M) {
const { top: u, bottom: p, height: k } = M.getBoundingClientRect();
let w = i.clientY - u;
C === "bottom" && (w = p - i.clientY), w > m && (w = m), w < f && (w = f), C === "bottom" && (w = k - w), l.value = w;
}
}
function b() {
const i = e.value;
if (i) {
const { width: m, height: f } = i.getBoundingClientRect();
return { width: m, height: f };
}
return null;
}
function O() {
const i = e.value;
return i ? Array.from(i.querySelectorAll("[data-position]")).reduce((m, f) => {
const C = f.getAttribute("data-position");
return m = Object.assign(m, { [C]: f }), m;
}, {}) : null;
}
function x(i, m) {
const f = b(), C = O();
if (f && C) {
const M = C == null ? void 0 : C.right, u = C == null ? void 0 : C.left;
if (i === "left" && u)
return M ? f.width - M.clientWidth - m : f.width - m;
if (i === "right" && M)
return u ? f.width - u.clientWidth - m : f.width - m;
}
}
function T(i, m) {
const f = b(), C = O();
if (f && C) {
const M = C == null ? void 0 : C.bottom, u = C == null ? void 0 : C.top;
if (i === "top" && u)
return M ? f.height - M.clientHeight - m : f.height - m;
if (i === "bottom" && M)
return u ? f.height - u.clientHeight - m : f.height - m;
}
}
return {
horizontalResizeHandleStyle: r,
verticalResizeHandleStyle: d,
resizeOverlayStyle: y,
showHorizontalResizeHandle: o,
showVerticalResizeHandle: s,
horizontalResizeBarPosition: t,
verticalResizeBarPosition: n,
verticalResizeHandleOffset: l,
horizontalResizeHandleOffset: a,
draggingHorizontalResizeHandle: g,
draggingVerticalResizeHandle: h,
getPanelMaxHeight: T,
getPanelMaxWidth: x
};
}
const ne = /* @__PURE__ */ U({
name: "FLayout",
props: je,
emits: [],
setup(e, t) {
const n = c(), a = lt(n), {
horizontalResizeHandleStyle: l,
verticalResizeHandleStyle: o,
resizeOverlayStyle: s
} = a;
Xe("layout", {
useResizeHandleComposition: a
});
const r = D(() => Qt({
"f-layout": !0
}, e == null ? void 0 : e.customClass)), d = D(() => en({}, e == null ? void 0 : e.customStyle));
return () => v("div", {
class: r.value,
style: d.value,
ref: n
}, [t.slots.default && t.slots.default(), v("div", {
class: "f-layout-resize-overlay",
style: s.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)]);
}
}), Bn = "https://json-schema.org/draft/2020-12/schema", En = "https://farris-design.gitee.io/layout-pane.schema.json", Dn = "layout-pane", Pn = "A Farris Container Component", Nn = "object", In = {
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
}
}, jn = [
"id",
"type",
"contents"
], Rn = {
$schema: Bn,
$id: En,
title: Dn,
description: Pn,
type: Nn,
properties: In,
required: jn
}, Ln = "layout-pane", zn = "A Farris Container Component", Vn = "object", Hn = {
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: "是否可见"
}
}
}
}, An = {
title: Ln,
description: zn,
type: Vn,
categories: Hn
}, Re = {
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 }
}, ot = be(Re, Rn, tt, nt, An);
function it(e, t, n, a, l, o) {
const {
horizontalResizeBarPosition: s,
horizontalResizeHandleOffset: r,
showHorizontalResizeHandle: d,
showVerticalResizeHandle: y,
verticalResizeBarPosition: g,
verticalResizeHandleOffset: h,
draggingHorizontalResizeHandle: b,
draggingVerticalResizeHandle: O,
getPanelMaxHeight: x,
getPanelMaxWidth: T
} = l;
let i = "", m, f, C;
const M = () => o.maxWidth ? o.maxWidth : T(i, n.value) || 0;
function u(w) {
if ((i === "left" || i === "right") && f) {
const { left: R } = f.getBoundingClientRect(), { width: V } = m.getBoundingClientRect(), P = w.clientX - R;
let E = i === "left" ? (V || 0) + (P - s.value) : (V || 0) - (P - s.value);
E = n.value > 0 ? Math.max(n.value, E) : E;
const F = M();
F != null && (E = F > E ? E : F), e.value = E;
}
if ((i === "top" || i === "bottom") && f) {
const { top: R } = f.getBoundingClientRect(), { height: V } = m.getBoundingClientRect(), P = w.clientY - R;
let E = i === "top" ? (V || 0) + (P - g.value) : (V || 0) - (P - g.value);
E = a.value > 0 ? Math.max(a.value, E) : E;
const F = x(i, a.value);
F != null && (E = F > E ? E : F), t.value = E;
}
r.value = 0, h.value = 0, s.value = -1, g.value = -1, d.value = !1, y.value = !1, document.removeEventListener("mousemove", C), document.removeEventListener("mouseup", u), document.body.style.userSelect = "", i = "", m = null, f = null;
}
function p(w, R, V) {
if (i = R, m = V, d.value = !0, f = w.composedPath().find((E) => (E.className || "").split(" ")[0] === "f-layout"), f) {
const { left: E } = f.getBoundingClientRect(), F = w.clientX - E;
r.value = F, s.value = F;
const N = M();
C = (I) => b(I, N, n.value, i), document.addEventListener("mousemove", C), document.addEventListener("mouseup", u), document.body.style.userSelect = "none";
}
}
function k(w, R, V) {
if (i = R, m = V, y.value = !0, f = w.composedPath().find((E) => (E.className || "").split(" ")[0] === "f-layout"), f) {
const { top: E } = f.getBoundingClientRect();
h.value = w.clientY - E, g.value = w.clientY - E;
const F = x(i, a.value) || 0;
C = (N) => O(N, F, a.value, i), document.addEventListener("mousemove", C), document.addEventListener("mouseup", u), document.body.style.userSelect = "none";
}
}
return { onClickHorizontalResizeBar: p, onClickVerticalResizeBar: k };
}
const Q = /* @__PURE__ */ U({
name: "FLayoutPane",
props: Re,
emits: [],
setup(e, t) {
const n = c(e.minHeight <= 0 ? 100 : e.minHeight), a = c(e.minWidth <= 0 ? 100 : e.minWidth), l = c(e.width <= 0 ? 100 : e.width), o = c(e.height <= 0 ? 100 : e.height), s = c(Math.max(n.value, o.value)), r = c(Math.max(a.value, l.value)), d = c(), y = c(e.position), g = c(e.resizable);
W(() => e.resizable, (u) => {
g.value = u;
});
const h = J("layout"), {
useResizeHandleComposition: b
} = h, O = it(r, s, a, n, b, e), {
onClickHorizontalResizeBar: x,
onClickVerticalResizeBar: T
} = O, i = D(() => ({
"f-layout-resize-bar": !0,
"f-layout-resize-bar-e": y.value === "left",
"f-layout-resize-bar-n": y.value === "bottom",
"f-layout-resize-bar-s": y.value === "top",
"f-layout-resize-bar-w": y.value === "right"
})), m = D(() => y.value !== "center" && g.value);
function f(u, p) {
(p === "left" || p === "right") && x(u, p, d.value), (p === "top" || p === "bottom") && T(u, p, d.value);
}
const C = D(() => {
const u = {
"f-layout-pane": !0,
"f-page-content-nav": y.value === "left" || y.value === "right",
"f-page-content-main": y.value === "center"
};
return e.customClass && String(e.customClass).split(" ").reduce((p, k) => (p[k] = !0, p), u), u;
}), M = D(() => {
const u = {};
return (r.value && y.value === "left" || y.value === "right") && (u.width = `${r.value}px`), (s.value && y.value === "bottom" || y.value === "top") && (u.height = `${s.value}px`), e.visible || (u.display = "none"), u;
});
return () => v("div", {
ref: d,
class: C.value,
style: M.value,
"data-position": y.value
}, [t.slots.default && t.slots.default(), m.value && v("span", {
class: i.value,
onMousedown: (u) => f(u, y.value)
}, null)]);
}
});
function $n(e, t) {
function n() {
return !1;
}
return { canAccepts: n };
}
const Wn = /* @__PURE__ */ U({
name: "FLayoutDesign",
props: je,
emits: [],
setup(e, t) {
var g;
const n = c(), a = J("design-item-context"), l = $n(a.schema, (g = a.parent) == null ? void 0 : g.schema), o = Ie(n, a, l);
o.value.canNested = !1;
const s = lt(n), {
horizontalResizeHandleStyle: r,
verticalResizeHandleStyle: d,
resizeOverlayStyle: y
} = s;
return Xe("layout", {
useResizeHandleComposition: s
}), 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: y.value
}, null), v("div", {
class: "f-layout-horizontal-resize-proxy",
style: r.value
}, null), v("div", {
class: "f-layout-vertical-resize-proxy",
style: d.value
}, null)]);
}
});
function Yn(e, t) {
const n = e.schema;
function a(o) {
return !!ln().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 qn = /* @__PURE__ */ U({
name: "FLayoutPaneDesign",
props: Re,
emits: [],
setup(e, t) {
const n = c(), a = c();
J("designer-host-service");
const l = J("design-item-context"), o = Yn(l), s = Ie(a, l, o);
s.value.canNested = !1, s.value.canMove = !1, s.value.canDelete = !1, K(() => {
a.value.componentInstance = s;
}), t.expose(s.value);
const r = c(Math.max(e.minHeight, e.height)), d = c(Math.max(e.minWidth, e.width)), y = c(e.minHeight), g = c(e.minWidth), h = c(e.position), b = J("layout"), {
useResizeHandleComposition: O
} = b, x = it(d, r, g, y, O, e), {
onClickHorizontalResizeBar: T,
onClickVerticalResizeBar: i
} = x, m = 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 f(u, p) {
(p === "left" || p === "right") && T(u, p, n.value), (p === "top" || p === "bottom") && i(u, p, n.value);
}
const C = D(() => {
const u = {
"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((p, k) => (p[k] = !0, p), u), u;
}), M = D(() => {
const u = {
flex: "1"
};
return (d.value && h.value === "left" || h.value === "right") && (u.width = `${d.value}px`), (r.value && h.value === "bottom" || h.value === "top") && (u.height = `${r.value}px`), u;
});
return () => v("div", {
ref: n,
class: C.value,
style: M.value
}, [v("div", {
ref: a,
class: "drag-container",
"data-dragref": `${l.schema.id}-container`
}, [t.slots.default && t.slots.default()]), v("span", {
class: m.value,
onMousedown: (u) => f(u, h.value)
}, null)]);
}
});
ne.install = (e) => {
e.component(ne.name, ne), e.component(Q.name, Q);
};
ne.register = (e, t, n, a) => {
e.layout = ne, t.layout = at, e["layout-pane"] = Q, t["layout-pane"] = ot;
};
ne.registerDesigner = (e, t, n) => {
e.layout = Wn, t.layout = at, e["layout-pane"] = qn, t["layout-pane"] = ot;
};
const st = /* @__PURE__ */ new Map([
["appearance", Qe]
]), Gn = "https://json-schema.org/draft/2020-12/schema", Un = "https://farris-design.gitee.io/combo-list.schema.json", Xn = "combo-list", Kn = "A Farris Input Component", _n = "object", Jn = {
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"
},
onChange: {
description: "值变化事件",
type: "string",
default: ""
},
onInput: {
description: "输入事件",
type: "string",
default: ""
},
onClear: {
description: "清空事件",
type: "string",
default: ""
},
onDataChanged: {
description: "清空事件",
type: "string",
default: ""
}
}, Zn = [
"type"
], Qn = [
"id",
"appearance",
"binding",
"visible"
], ea = {
onClear: "清空事件",
onChange: "值变化事件",
beforeOpen: "打开下拉面板前事件"
}, rt = {
$schema: Gn,
$id: Un,
title: Xn,
description: Kn,
type: _n,
properties: Jn,
required: Zn,
ignore: Qn,
events: ea
};
function ut(e, t, n) {
return t;
}
function ta() {
function e(t, n, a) {
const l = {};
return l.beforeOpen = (o) => n.call("beforeOpen", t, [o, t], a), l;
}
return {
resolve: e
};
}
const ke = {
/**
* 组件标识
*/
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: {},
/**
* 占位符
*/
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 }
}, na = Object.assign({}, ke, {
readonly: {}
});
be(ke, rt, st, ut);
const ct = Zt(
ke,
rt,
st,
ut
), aa = ta(), la = {
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 }
}, oa = /* @__PURE__ */ U({
name: "FComboListContainer",
props: la,
emits: ["selectionChange"],
setup(e, t) {
const n = c(), a = c(e.dataSource), l = c([]), o = c(e.separator), s = c(e.width), r = c(e.maxHeight), d = D(() => e.multiSelect), y = c(e.multiSelect ? String(e.selectedValues).split(o.value) : [e.selectedValues]), g = D(() => ({
enableSelectRow: !0,
multiSelect: e.multiSelect,
multiSelectMode: "OnCheckAndClick",
showCheckbox: d.value,
showSelectAll: !1,
showSelection: !0
}));
W(e.dataSource, () => {
a.value = e.dataSource;
}), D(() => e.enableSearch ? "SearchBar" : "ContentHeader");
const h = D(() => {
const i = {};
return s.value !== void 0 && (i.width = `${s.value}px`), r.value !== void 0 && r.value > 0 && (i.maxHeight = `${r.value}px`), i;
});
function b(i) {
n.value.search(i);
}
function O(i) {
l.value = i.map((m) => Object.assign({}, m)), y.value = i.map((m) => m[e.idField]), t.emit("selectionChange", l.value);
}
function x(i) {
if (e.enableHighlightSearch)
return;
let m = [];
const {
searchOption: f
} = e;
typeof f == "function" ? m = a.value.filter((C) => f(i, C)) : m = a.value.filter((C) => C[e.valueField].indexOf(i) > -1 || C[e.textField].indexOf(i) > -1), n.value.updateDataSource(m);
}
W([() => e.selectedValues], ([i]) => {
e.multiSelect ? y.value = i.split(o.value) : y.value = [i];
});
function T(i) {
n.value.activeRowById(i);
}
return K(() => {
var i, m;
if (!e.multiSelect) {
const f = (i = y.value) == null ? void 0 : i[0];
let C = f;
const M = a.value.map((u) => u[e.valueField || e.idField]);
if (!sn(f) && M.includes(f)) {
const u = typeof f, p = typeof ((m = a.value[0]) == null ? void 0 : m[e.valueField || e.idField]);
p === "number" && u !== p && (C = Number(f)), p === "boolean" && u !== p && (C = f === "true" ? !0 : f === "false" ? !1 : f), T(C);
}
}
}), t.expose({
search: b,
activeRowById: T
}), () => v("div", {
class: "f-combo-list-container",
style: h.value
}, [v(un, {
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: g.value,
enableHighlightSearch: e.enableHighlightSearch,
selectionValues: y.value,
onSelectionUpdate: O,
onAfterSearch: x
}, null)]);
}
});
function ia(e, t) {
const n = c(""), a = c(e.modelValue), l = c(e.data || []), o = c(e.editable);
function s(i) {
const m = e.multiSelect ? String(i).split(e.separator) : [String(i)], f = m.map((u) => [u, !0]), C = new Map(f);
return l.value.filter((u) => C.has(String(u[e.valueField]))).sort((u, p) => {
const k = m.indexOf(u[e.valueField]), w = m.indexOf(p[e.valueField]);
return k - w;
});
}
function r(i) {
const m = s(i).map((f) => f[e.textField]).join(e.separator);
n.value = o.value ? m || i : m;
}
function d(i) {
if (e.multiSelect) {
const m = i.split(e.separator).map((C) => [C, !0]), f = new Map(m);
return l.value.filter((C) => f.has(C[e.textField]));
}
return l.value.filter((m) => "" + m[e.textField] === i);
}
function y(i) {
const m = {};
return m[e.idField] = i, m[e.textField] = i, [m];
}
function g(i) {
let m = d(i);
const f = m && m.length > 0;
return o.value && !f && (m = y(i)), m;
}
function h() {
const { url: i, method: m = "GET", headers: f = { "Content-Type": "application/json;charset=utf-8;" }, body: C = null } = e.remote;
if (!i)
return;
const M = m.toLowerCase() === "get" ? { method: m, headers: f } : { method: m, headers: f, body: C };
let u = !1;
fetch(new Request(i, M)).then((p) => {
var w, R;
if (p.status === 200)
return u = !!((R = (w = p.headers) == null ? void 0 : w.get("content-type")) != null && R.includes("application/json")), u ? p.text() : p.json();
throw p.status === 405 ? new Error(Z.getLocaleValue("comboList.remoteError")) : new Error(p.statusText);
}).then((p) => {
p.length && (l.value = u ? JSON.parse(p) : p, a.value && r(a.value));
}).catch((p) => {
console.warn(p);
});
}
e.remote && (e.load ? e.load().then((i) => {
l.value = i;
}).catch((i) => {
console.log(i);
}) : h()), W(() => e.data, () => {
l.value = e.data;
}), W([l], ([i], [m]) => {
if (e.modelValue != null && !e.multiSelect) {
const f = i.find((C) => C[e.valueField] === a.value);
f ? f[e.valueField] !== a.value ? (a.value = f[e.valueField], n.value = f[e.textField], t.emit("update:modelValue", f[e.valueField]), t.emit("change", [f], f[e.valueField])) : n.value !== f[e.textField] && (n.value = f[e.textField]) : a.value !== "" && (a.value = "", n.value = "", t.emit("update:modelValue", ""), t.emit("change", [], ""));
}
}), W(() => e.modelValue, (i, m) => {
m !== i && (a.value = i, r(i));
});
function b(i) {
l.value = i, t.emit("dataChanged", i);
}
function O() {
return l.value;
}
function x() {
return n.value;
}
function T() {
const i = typeof e.beforeOpen == "function";
return !e.beforeOpen || !i ? Promise.resolve(!0) : Promise.resolve().then(() => e.beforeOpen({ instance: { updateDataSource: b, getData: O, getDisplayText: x } })).then((m) => typeof (m == null ? void 0 : m.canOpen) == "boolean" ? m == null ? void 0 : m.canOpen : !0);
}
return r(e.modelValue), {
dataSource: l,
displayText: n,
editable: o,
modelValue: a,
beforeOpenList: T,
getItemsByDisplayText: d,
getItemsByValue: s,
getSelectedItemsByDisplayText: g
};
}
const ue = /* @__PURE__ */ U({
name: "FComboList",
props: ke,
emits: ["clear", "update:modelValue", "change", "input", "dataChanged"],
setup(e, t) {
const n = c(), a = c(), l = c(e.disabled || e.readonly), o = c(e.enableClear), s = c(e.enableSearch), r = c(e.readonly), {
dataSource: d,
displayText: y,
editable: g,
modelValue: h,
getItemsByDisplayText: b,
getItemsByValue: O,
beforeOpenList: x
} = ia(e, t), T = c(e.dropDownIcon);
T.value === '<span class="f-icon f-icon-arrow-chevron-down"></span>' && (T.value = '<span id="' + e.id + '-icon-dropdown" class="f-icon f-icon-arrow-chevron-down"></span>');
const i = D(() => e.multiSelect), m = D(() => a.value ? a.value.elementRef.getBoundingClientRect().width : 0);
function f() {
!i.value && a.value && a.value.hidePopup();
}
function C(I) {
y.value = I.map((H) => H[e.textField]).join(e.separator) || h.value;
let L = "";
I.length === 1 ? L = I[0][e.valueField] : L = I.map((H) => H[e.valueField]).join(e.separator), h.value !== L && (h.value = L, t.emit("update:modelValue", h.value), t.emit("change", I, h.value));
}
function M() {
const I = O(h.value);
C(I);
}
function u() {
r.value || y.value;
}
function p(I) {
var L;
h.value = "", (L = n.value) == null || L.activeRowById(""), t.emit("clear");
}
function k(I) {
var L, H;
e.enableSearch && e.enableHighlightSearch && ((L = n.value) == null || L.search(I)), (H = n.value) == null || H.activeRowById(I), t.emit("change", [h.value], h.value);
}
function w(I) {
if (e.multiSelect) {
const L = b(I);
e.viewType;
const B = L.map((j) => j[e.idField || e.valueField]).join(e.separator);
h.value !== B && (h.value = B, t.emit("update:modelValue", h.value), t.emit("change", L, h.value));
} else I !== h.value && (h.value = I, t.emit("update:modelValue", h.value), t.emit("change", [], I));
}
function R() {
return y.value;
}
function V(I) {
const {
value: L
} = I.target;
k(L), t.emit("input", L);
}
function P() {
a.value.hidePopup();
}
function E(I) {
d.value = I;
}
function F() {
return d.value;
}
const N = {
getDisplayText: R,
hidePopup: P,
updateDataSource: E,
getData: F
};
return t.expose(N), W([() => e.disabled, () => e.editable, () => e.enableClear, () => e.enableSearch, () => e.readonly], ([I, L, H, B, j]) => {
l.value = I, g.value = L, o.value = H, s.value = B, r.value = j;
}), () => v(on, {
ref: a,
id: e.id,
disable: l.value,
readonly: r.value,
forcePlaceholder: e.forcePlaceholder,
editable: g.value,
buttonContent: T.value,
placeholder: e.placeholder === "请选择" ? Z.getLocaleValue("comboList.placeholder") : e.placeholder,
enableClear: o.value,
maxLength: e.maxLength,
tabIndex: e.tabIndex,
enableTitle: e.enableTitle,
multiSelect: e.multiSelect,
inputType: e.multiSelect ? e.viewType : "text",
modelValue: y.value,
"onUpdate:modelValue": (I) => y.value = I,
focusOnCreated: e.focusOnCreated,
selectOnCreated: e.selectOnCreated,
onClear: p,
onClick: u,
onChange: w,
onBlur: M,
onInput: V,
beforeOpen: x,
placement: e.placement,
popupMinWidth: e.minPanelWidth,
popupClass: "f-combo-list-wrapper",
popupOnClick: e.popupOnClick,
limitContentBySpace: !0
}, {
default: () => [v(oa, {
ref: n,
idField: e.idField,
valueField: e.valueField,
textField: e.textField,
titleField: e.titleField,
dataSource: d.value,
selectedValues: h.value,
separator: e.separator,
multiSelect: e.multiSelect,
enableSearch: s.value,
maxHeight: e.maxHeight,
enableHighlightSearch: e.enableHighlightSearch,
width: e.fitEditor ? m.value : void 0,
onSelectionChange: (I) => {
C(I), f();
}
}, null)]
});
}
}), Ae = {
convertFrom: (e, t) => (e.editor.remote || {})[t],
convertTo: (e, t, n) => {
e.editor.remote = e.editor.remote || {}, e.editor.remote[t] = n;
}
};
class sa extends dn {
constructor(t, n) {
super(t, n);
}
getCommonEditorProperties(t) {
var n, a, l;
return {
viewType: {
visible: !!((n = t.editor) != null && n.multiSelect),
description: "数据展示类型,有标签和文本两种方式",
title: "数据展示类型",
type: "enum",
editor: {
data: [
{ id: "tag", name: "标签" },
{ id: "text", name: "文本" }
]
},
refreshPanelAfterChanged: !0
},
separator: {
visible: !!((a = t.editor) != null && a.multiSelect) && ((l = t.editor) == null ? void 0 : l.viewType) === "text",
description: "下拉列表启用多选且数据展示类型为文本时的分隔符",
title: "分隔符",
type: "enum",
editor: {
data: [
{ id: ",", name: "逗号(,)" },
{ id: "#", name: "井号(#)" },
{ id: ".", name: "句号(.)" },
{ id: "|", name: "竖线(|)" }
]
}
},
editable: {
description: "",
title: "允许编辑",
type: "boolean",
refreshPanelAfterChanged: !0,
readonly: !0
// readonly: !!propertyData.editor?.multiSelect && (propertyData.editor?.viewType === 'tag' || !propertyData.editor!.viewType)
}
// enableHighlightSearch: {
// visible: !!propertyData.editor?.editable,
// description: "编辑状态下启用高亮搜索",
// title: "启用高亮搜索",
// type: "boolean"
// },
};
}
getEditorProperties(t) {
var d, y, g, h, b, O, x, T, i, m, f, C, M;
const n = this;
let a = "";
if (((d = t == null ? void 0 : t.binding) == null ? void 0 : d.type) === "Form") {
const u = this.schemaService.getFieldByIDAndVMID(t.binding.field, this.viewModelId);
(y = u == null ? void 0 : u.schemaField) != null && y.type && (a = u.schemaField.type.$type);
}
const l = this.getPropertyEditorParams(t, ["Variable"]), o = !t.editor.dataSourceType || t.editor.dataSourceType === "static", s = (((h = (g = this.designViewModelField) == null ? void 0 : g.type) == null ? void 0 : h.$type) === me.StringType || !!this.formRule && ((b = this.designerHostService.schemaService.getFieldByID(t.binding.field)) == null ? void 0 : b.type.$type) === me.StringType) && ((O = t.editor) == null ? void 0 : O.type) === "combo-list" && ((x = t.editor) == null ? void 0 : x.dataSourceType) === "dynamic" && !((i = (T = t.editor) == null ? void 0 : T.remote) != null && i.url) && !((m = t.editor) != null && m.multiSelect);
return n.getComponentConfig(t, { type: "combo-list" }, {
// enableSearch: {
// description: "编辑状态下启用搜索",
// title: "允许编辑",
// type: "boolean",
// },
enableClear: {
description: "",
title: "启用清空",
type: "boolean"
},
dataSourceType: {
description: "",
title: "数据源类型",
type: "enum",
editor: {
default: "static",
data: [
{ id: "static", name: "静态" },
{ id: "dynamic", name: "动态" }
]
},
refreshPanelAfterChanged: !0
},
dataSource: {
description: "动态数据源绑定变量",
visible: s,
title: "数据",
editor: {
...l,
controlName: "",
enableClear: !0
},
refreshPanelAfterChanged: !0
},
data: {
description: "",
title: "数据",
type: "array",
visible: o,
...n.getItemCollectionEditor(t, t.editor.valueField, t.editor.textField),
// 这个属性,标记当属性变更得时候触发重新更新属性
refreshPanelAfterChanged: !0
},
url: {
visible: t.editor.dataSourceType === "dynamic" && !((f = t.editor) != null && f.dataSource),
$converter: Ae,
description: "",
title: "服务端API",
type: "string",
refreshPanelAfterChanged: !0
},
// method: {
// visible: propertyData.editor.dataSourceType === "dynamic",
// $converter: comboListRemoteConverter,
// description: "",
// title: "服务端API类型",
// type: "enum",
// editor: {
// default: "GET",
// data: [
// { id: "GET", name: "GET" },
// { id: "PUT", name: "PUT" },
// { id: "POST", name: "POST" }
// ]
// },
// },
body: {
visible: !1,
$converter: Ae,
description: "",
title: "服务端API参数",
type: "string"
},
textField: {
description: "",
title: "数据源显示字段",
type: "string",
readonly: t.editor.dataSourceType !== "dynamic"
},
valueField: {
description: "",
title: "数据源值字段",
type: "string",
readonly: t.editor.dataSourceType !== "dynamic"
},
multiSelect: {
description: "",
title: "启用多选",
visible: !a || a === "StringType",
readonly: ((C = t.editor) == null ? void 0 : C.dataSourceType) === "dynamic" && !!((M = t.editor) != null && M.dataSource),
type: "boolean",
refreshPanelAfterChanged: !0
},
maxLength: {
description: "",
title: "最大输入长度",
type: "number",
editor: {
nullable: !0,
min: 0,
useThousands: !1,
needValid: !0
}
},
...this.getCommonEditorProperties(t)
}, (u, p) => {
if (!u || !p.editor)
return;
const k = this;
switch (u.propertyID) {
case "dataSourceType": {
u.propertyValue === "static" ? (p.editor.valueField = "value", p.editor.textField = "name", p.editor.remote = null) : u.propertyValue === "dynamic" && (p.editor.remote = { method: "GET" }, p.editor.valueField = "value", p.editor.textField = "name");
break;
}
case "data": {
!k.checkEnumDataReadonly(p) && p.formatter && (p.formatter.data = [...u.propertyValue]);
break;
}
case "viewType": {
u.propertyValue === "tag" && (p.editor.editable = !1);
break;
}
case "dataSource":
k.afterMutilEditorChanged(p, u);
}
});
}
getGridFieldEdtiorProperties(t, n) {
var d, y, g, h, b, O, x, T, i, m, f, C, M;
const a = this;
let l = "";
if (((d = t == null ? void 0 : t.binding) == null ? void 0 : d.type) === "Form") {
const u = this.schemaService.getFieldByIDAndVMID(t.binding.field, this.viewModelId);
(y = u == null ? void 0 : u.schemaField) != null && y.type && (l = u.schemaField.type.$type);
}
const o = ((h = (g = this.designViewModelField) == null ? void 0 : g.type) == null ? void 0 : h.$type) === me.StringType && ((b = t.editor) == null ? void 0 : b.type) === "combo-list" && ((O = t.editor) == null ? void 0 : O.dataSourceType) === "dynamic" && !((x = t.editor) != null && x.multiSelect), s = this.getPropertyEditorParams(t, ["Variable"]);
return a.getComponentConfig(t, { type: "combo-list" }, {
// editable: {
// description: "",
// title: "允许编辑",
// type: "boolean",
// readonly: propertyData.editor?.type === 'combo-list'
// },
enableClear: {
description: "",
title: "启用清空",
type: "boolean"
},
dataSourceType: {
description: "",
title: "数据源类型",
type: "enum",
editor: {
default: "static",
data: [
{ id: "static", name: "静态" },
{ id: "dynamic", name: "动态" }
]
},
refreshPanelAfterChanged: !0
},
dataSource: {
description: "动态数据源绑定变量",
visible: o,
title: "数据",
editor: {
...s,
controlName: "",
enableClear: !0
},
refreshPanelAfterChanged: !0
},
data: {
description: "",
title: "数据",
type: "array",
visible: !((T = t.editor) != null && T.dataSourceType) || ((i = t.editor) == null ? void 0 : i.dataSourceType) === "static",
...a.getItemCollectionEditor(t, (m = t.editor) == null ? void 0 : m.valueField, (f = t.editor) == null ? void 0 : f.textField),
// 这个属性,标记当属性变更得时候触发重新更新属性
refreshPanelAfterChanged: !0
},
textField: {
description: "",
title: "数据源显示字段",
type: "string",
readonly: !0
},
valueField: {
description: "",
title: "数据源值字段",
type: "string",
readonly: !0
},
multiSelect: {
description: "",
title: "启用多选",
visible: l === "StringType",
readonly: ((C = t.editor) == null ? void 0 : C.dataSourceType) === "dynamic" && !!((M = t.editor) != null && M.dataSource),
type: "boolean",
refreshPanelAfterChanged: !0
},
maxLength: {
description: "",
title: "最大输入长度",
type: "number",
editor: {
nullable: !0,
min: 0,
useThousands: !1,
needValid: !0
}
},
...this.getCommonEditorProperties(t)
}, (u, p) => {
if (!u || !p.editor)
return;
const k = this;
switch (u.propertyID) {
case "dataSourceType": {
u.propertyValue === "static" ? (p.editor.valueField = "value", p.editor.textField = "name", p.editor.remote = null) : u.propertyValue === "dynamic" && (p.editor.remote = { method: "GET" }, p.editor.valueField = "value", p.editor.textField = "name");
break;
}
case "data": {
!k.checkEnumDataReadonly(p) && p.formatter && (p.formatter.data = [...u.propertyValue]);
break;
}
case "dataSource":
k.afterMutilEditorChanged(p, u);
}
});
}
setEditorPropertyRelates(t, n, a) {
if (!t || !n.editor)
return;
const l = this;
switch (t.propertyID) {
case "dataSourceType": {
t.propertyValue === "static" && (n.editor.valueField = "value", n.editor.textField = "name", n.editor.remote = {});
break;
}
case "data": {
!l.checkEnumDataReadonly(n) && n.formatter && (n.formatter.data = [...t.propertyValue]);
break;
}
}
}
/**
* 切换绑定属性
*/
changeBindingField(t, n, a) {
var o;
super.changeBindingField(t, n);
const l = a;
t.editor && ((o = l == null ? void 0 : l.type) == null ? void 0 : o.$type) === me.EnumType && (t.editor.data = l.type.enumValues || []);
}
/**
* 组装输入类控件的交互面板:包含标签超链、绑定字段值变化前后事件等。
* @param propertyData 属性值
* @param viewModelId 视图模型id
* @param showPosition 面板展示位置
* @param customEvent 输入控件特有的事件配置
*/
getEventPropertyConfig(t, n = "card", a, l) {
const o = this;
let s = [
{
label: "onChange",
name: "值变化事件"
},
// {
// label: 'onClear',
// name: '清空事件'
// },
{
label: "beforeOpen",
name: "下拉面板前事件"
}
];
s = [...s, ...this.getInputCommonEvents(t)], a && (s = s.concat(a)), this.formRule && (s = s.filter((g) => g.label !== "onChange")), this.appendFieldValueChangeEvents(t, s);
const r = o.eventsEditorUtils.formProperties(t, o.viewModelId, s);
return {
title: "事件",
hideTitle: !0,
properties: o.createBaseEventProperty(r),
tabId: "commands",
tabName: "交互",
setPropertyRelates(g, h) {
const b = g.propertyValue;
delete t[o.viewModel