UNPKG

@farris/ui-vue

Version:

Farris Vue, a Farris Design based Vue3 component library.

1,503 lines 56.7 kB
var ge = Object.defineProperty; var be = (e, t, n) => t in e ? ge(e, t, { enumerable: !0, configurable: !0, writable: !0, value: n }) : e[t] = n; var Y = (e, t, n) => be(e, typeof t != "symbol" ? t + "" : t, n); import { defineComponent as $, ref as O, inject as G, onMounted as j, createVNode as m, computed as S, createTextVNode as K, watch as k, withDirectives as te, vModelText as ye, resolveDirective as he, Fragment as _, reactive as xe, createApp as Ce, onUnmounted as Te, Transition as we, mergeProps as Se, toRefs as Be } from "vue"; import { useDesignerComponent as Fe } from "../designer-canvas/index.esm.js"; import { InputBaseProperty as Oe } from "../property-panel/index.esm.js"; import Pe from "../button-edit/index.esm.js"; import { createPropsResolver as Ne, getPropsResolverGenerator as Ie } from "../dynamic-resolver/index.esm.js"; import { isPlainObject as ee, cloneDeep as Z } from "lodash-es"; import { FInputGroup as ke } from "../input-group/index.esm.js"; import { LocaleService as A } from "../locale/index.esm.js"; import { useTextBox as Le, useClear as Ee, withInstall as Re, isMobilePhone as Me } from "../common/index.esm.js"; import { useNumber as je, useFormat as De, useSpinner as Ve, useTextBox as $e, getSpinnerRender as Ae, getNumberTextBoxRender as ze } from "../number-spinner/index.esm.js"; class He extends Oe { constructor(t, n) { super(t, n); } getEditorProperties(t) { return this.getComponentConfig(t, { type: "language-textbox" }, { maxLength: { description: "文本字数最大长度", title: "最大长度", type: "number", editor: { nullable: !0, min: 0, useThousands: !1, max: t.editor.maxLength, needValid: !0 } } }); } } function Ge(e, t) { function n(o, r) { const p = e.schema; return new He(o, t).getPropertyConfig(p, r); } return { getPropsConfig: n }; } const _e = /* @__PURE__ */ $({ name: "FLanguageTextboxDesign", props: { placeholder: { type: String, default: "" } }, setup(e, t) { const n = O(), o = G("design-item-context"), r = G("designer-host-service"), p = Ge(o, r), i = Fe(n, o, p); return j(() => { n.value.componentInstance = i; }), t.expose(i.value), () => m("div", { class: "f-button-edit f-cmp-inputgroup f-button-edit-nowrap", ref: n }, [m("div", { class: "input-group" }, [m("input", { autocomplete: "off", class: "text-left form-control f-utils-fill", readonly: "true", type: "text", placeholder: e.placeholder }, null), m("div", { class: "input-group-append" }, [m("span", { class: "input-group-text input-group-append-button" }, [m("i", { class: "f-icon f-icon-yxs_earth" }, null)])])])]); } }); function ne(e, t) { let n; function o(l) { const { properties: d, title: v, ignore: a } = l, s = a && Array.isArray(a), f = Object.keys(d).reduce((h, b) => ((!s || !a.find((F) => F === b)) && (h[b] = d[b].type === "object" && d[b].properties ? o(d[b]) : Z(d[b].default)), h), {}); if (v && (!s || !a.find((h) => h === "id"))) { const h = v.toLowerCase().replace(/-/g, "_"); f.id = `${h}_${Math.random().toString().slice(2, 6)}`; } return f; } function r(l) { const { properties: d, title: v, required: a } = l; if (a && Array.isArray(a)) { const s = a.reduce((f, h) => (f[h] = d[h].type === "object" && d[h].properties ? o(d[h]) : Z(d[h].default), f), {}); if (v && a.find((f) => f === "id")) { const f = v.toLowerCase().replace(/-/g, "_"); s.id = `${f}_${Math.random().toString().slice(2, 6)}`; } return s; } return { type: v }; } function p(l, d = {}, v) { const a = e[l]; if (a) { let s = r(a); const f = t[l]; return s = f ? f({ getSchemaByType: p }, s, d, v) : s, n != null && n.appendIdentifyForNewControl && n.appendIdentifyForNewControl(s), s; } return null; } function i(l, d) { const v = o(d); return Object.keys(v).reduce((a, s) => (Object.prototype.hasOwnProperty.call(l, s) && (a[s] && ee(a[s]) && ee(l[s] || !l[s]) ? Object.assign(a[s], l[s] || {}) : a[s] = l[s]), a), v), v; } function y(l, d) { return Object.keys(l).filter((a) => l[a] != null).reduce((a, s) => { if (d.has(s)) { const f = d.get(s); if (typeof f == "string") a[f] = l[s]; else { const h = f(s, l[s], l); Object.assign(a, h); } } else a[s] = l[s]; return a; }, {}); } function x(l, d, v = /* @__PURE__ */ new Map()) { const a = i(l, d); return y(a, v); } function u(l) { var v; const d = l.type; if (d) { const a = e[d]; if (!a) return l; const s = i(l, a), f = ((v = l.editor) == null ? void 0 : v.type) || ""; if (f) { const h = e[f], b = i(l.editor, h); s.editor = b; } return s; } return l; } function g(l) { n = l; } return { getSchemaByType: p, resolveSchemaWithDefaultValue: u, resolveSchemaToProps: x, mappingSchemaToProps: y, setDesignerContext: g }; } const We = {}, qe = {}, { resolveSchemaWithDefaultValue: Ue } = ne(We, qe); function Ye(e = {}) { function t(u, g, l, d) { if (typeof l == "number") return d[u].length === l; if (typeof l == "object") { const v = Object.keys(l)[0], a = l[v]; if (v === "not") return Number(d[u].length) !== Number(a); if (v === "moreThan") return Number(d[u].length) >= Number(a); if (v === "lessThan") return Number(d[u].length) <= Number(a); } return !1; } function n(u, g, l, d) { return d[u] && d[u].propertyValue && String(d[u].propertyValue.value) === String(l); } const o = /* @__PURE__ */ new Map([ ["length", t], ["getProperty", n] ]); Object.keys(e).reduce((u, g) => (u.set(g, e[g]), u), o); function r(u, g) { const l = u; return typeof g == "number" ? [{ target: l, operator: "length", param: null, value: Number(g) }] : typeof g == "boolean" ? [{ target: l, operator: "getProperty", param: u, value: !!g }] : typeof g == "object" ? Object.keys(g).map((d) => { if (d === "length") return { target: l, operator: "length", param: null, value: g[d] }; const v = d, a = g[d]; return { target: l, operator: "getProperty", param: v, value: a }; }) : []; } function p(u) { return Object.keys(u).reduce((l, d) => { const v = r(d, u[d]); return l.push(...v), l; }, []); } function i(u, g) { if (o.has(u.operator)) { const l = o.get(u.operator); return l && l(u.target, u.param, u.value, g) || !1; } return !1; } function y(u, g) { return p(u).reduce((v, a) => v && i(a, g), !0); } function x(u, g) { const l = Object.keys(u), d = l.includes("allOf"), v = l.includes("anyOf"), a = d || v, h = (a ? u[a ? d ? "allOf" : "anyOf" : "allOf"] : [u]).map((F) => y(F, g)); return d ? !h.includes(!1) : h.includes(!0); } return { parseValueSchema: x }; } const Ze = { convertTo: (e, t, n, o) => { e.appearance || (e.appearance = {}), e.appearance[t] = n; }, convertFrom: (e, t, n) => e.appearance ? e.appearance[t] : e[t] }, Je = { convertFrom: (e, t, n) => e.buttons && e.buttons.length ? `共 ${e.buttons.length} 项` : "无" }, Qe = { convertTo: (e, t, n, o) => { e.editor && (e.editor[t] = n); }, convertFrom: (e, t, n) => e.editor && Object.prototype.hasOwnProperty.call(e.editor, t) ? e.editor[t] : e[t] }, Xe = { button: { type: "button", name: "按钮" }, "response-toolbar": { type: "response-toolbar", name: "工具栏" }, "response-toolbar-item": { type: "response-toolbar-item", name: "按钮" }, "content-container": { type: "content-container", name: "容器" }, "input-group": { type: "input-group", name: "文本" }, textarea: { type: "textarea", name: "多行文本" }, lookup: { type: "lookup", name: "帮助" }, "number-spinner": { type: "number-spinner", name: "数值" }, "date-picker": { type: "date-picker", name: "日期" }, switch: { type: "switch", name: "开关" }, "radio-group": { type: "radio-group", name: "单选组" }, "check-box": { type: "check-box", name: "复选框" }, "check-group": { type: "check-group", name: "复选框组" }, "combo-list": { type: "combo-list", name: "下拉列表" }, "response-form": { type: "response-form", name: "卡片面板" }, "response-layout": { type: "response-layout", name: "布局容器", icon: "response-layout-3" }, "response-layout-item": { type: "response-layout-item", name: "布局", icon: "response-layout-1" }, "tree-grid": { type: "tree-grid", name: "树表格" }, "tree-grid-column": { type: "tree-grid-column", name: "树表格列" }, "data-grid": { type: "data-grid", name: "表格" }, "data-grid-column": { type: "data-grid-column", name: "表格列" }, module: { type: "Module", name: "模块" }, component: { type: "component", name: "组件" }, tabs: { type: "tabs", name: "标签页" }, "tab-page": { type: "tab-page", name: "标签页项", dependentParentControl: "Tab" }, "tab-toolbar-item": { type: "tab-toolbar-item", name: "标签页工具栏按钮" }, "drawer-toolbar-item": { type: "drawer-toolbar-item", name: "抽屉工具栏按钮" }, "html-template": { type: "html-template", name: "模板容器" }, "time-picker": { type: "time-picker", name: "时间选择" }, section: { type: "section", name: "分组面板" }, "section-toolbar": { type: "section-toolbar", name: "分组面板工具栏" }, "section-toolbar-item": { type: "section-toolbar-item", name: "分组面板按钮" }, splitter: { type: "splitter", name: "分栏面板" }, "splitter-pane": { type: "splitter-pane", name: "分栏面板项", dependentParentControl: "Splitter" }, "component-ref": { type: "component-ref", name: "组件引用节点" }, uploader: { type: "uploader", name: "附件上传" }, "page-header": { type: "page-header", name: "页头" }, "page-footer": { type: "page-footer", name: "页脚" }, "tab-toolbar": { type: "tab-toolbar", name: "标签页工具栏" }, "drawer-toolbar": { type: "drawer-toolbar", name: "抽屉工具栏" }, fieldset: { type: "fieldset", name: "分组" }, "query-solution": { type: "query-solution", name: "筛选方案" }, drawer: { type: "drawer", name: "抽屉" }, "external-container": { type: "external-container", name: "外部容器", icon: "content-container" }, "list-nav": { type: "list-nav", name: "列表导航" }, "list-view": { type: "list-view", name: "列表" }, "filter-bar": { type: "filter-bar", name: "筛选条" }, "language-textbox": { type: "language-textbox", name: "多语输入框" }, image: { type: "image", name: "图像" }, "discussion-editor": { type: "discussion-editor", name: "评论编辑区" }, "discussion-list": { type: "discussion-list", name: "评论列表" }, comment: { type: "comment", name: "评论区" }, "rich-text-editor": { type: "rich-text-editor", name: "富文本", icon: "rich-text-box" }, calendar: { type: "calendar", name: "日历", icon: "date-picker" }, wizard: { type: "wizard", name: "向导", icon: "wizard" }, "wizard-page": { type: "wizard-page", name: "向导页", icon: "wizard" }, "wizard-page-detail": { type: "wizard-page-detail", name: "向导详情", icon: "wizard" }, step: { type: "step", name: "步骤条", icon: "step" }, "dynamic-form": { type: "dynamic-form", name: "动态表单" } }, Ke = { convertFrom: (e, t, n) => { var r; const o = e.editor && e.editor[t] ? e.editor[t] : e[t]; return ((r = Xe[o]) == null ? void 0 : r.name) || o; } }, et = { convertTo: (e, t, n, o) => { e[t] = e[t]; }, convertFrom: (e, t, n) => e.editor ? n.getRealEditorType(e.editor.type) : "" }, tt = { convertTo: (e, t, n, o) => { (e.type === "data-grid-column" || e.type === "tree-grid-column") && (e.formatter ? e.formatter[t] = n : e.formatter = { [t]: n }); }, convertFrom: (e, t, n) => { if (e.formatter) { if (t === "trueText") return e.formatter.trueText; if (t === "falseText") return e.formatter.falseText; if (t === "prefix") return e.formatter.prefix; if (t === "suffix") return e.formatter.suffix; if (t === "precision") return e.formatter.precision; if (t === "decimal") return e.formatter.decimal; if (t === "thousand") return e.formatter.thousand; if (t === "dateFormat") return e.formatter.dateFormat || "yyyy-MM-dd"; if (t === "customFormat") return e.formatter.customFormat; if (t === "type") return e.formatter.type || "none"; if (t === "customFormat") return e.formmater.customFormat; } return "none"; } }, nt = { convertTo: (e, t, n, o) => { e.command ? e.command[t] = n : e.command = { [t]: n }, t === "enableType" && n === "default" && (e.command.enable = !0, e.command.commands = [ { text: "编辑", type: "primary", command: "edit" }, { text: "删除", type: "danger", command: "remove" } ]), t === "enableType" && n === "custom" && (e.command.enable = !0, e.command.commands = [ { value: "add", text: "增加", type: "link" }, { value: "edit", text: "编辑", type: "danger" }, { value: "remove", text: "删除", type: "remove" } ]), t === "enableType" && n === "unable" && (e.command.enable = !1); }, convertFrom: (e, t, n) => { var o, r; if (e.command) { if (t === "enableType") { const p = (r = (o = e.command) == null ? void 0 : o.commands) == null ? void 0 : r.find((i) => i.command === "edit" && i.type === "primary"); return e.command.enable ? p ? "default" : "custom" : "unable"; } if (t === "commands") return e.command.enableType === "custom" ? e.command.commands : []; if (t === "formatter") return e.command.formatter; if (t === "count") return e.command.count; if (t === "columnWidth") return e.command.columnWidth || 200; } return ""; } }, ot = { convertTo: (e, t, n, o) => { e.column ? e.column[t] = n : e.column = { [t]: n }, t === "fitColumns" && n && (e.column.fitMode || (e.column.fitMode = "average")); }, convertFrom: (e, t, n) => { if (e.column) { if (t === "fitColumns") return e.column.fitColumns; if (t === "fitMode") return e.column.fitMode; } return ""; } }, rt = { convertTo: (e, t, n, o) => { e.summary ? e.summary[t] = n : e.summary = { [t]: n }, t === "enable" && n && (e.summary ? e.summary.groupFields || (e.summary.groupFields = []) : e.summary = { enable: n, groupFields: [] }); }, convertFrom: (e, t, n) => { var o, r; return t === "customSummaryStyle" ? e.summary.customSummaryStyle : t === "position" ? ((o = e.summary) == null ? void 0 : o[t]) || "bottom" : t === "customRender" ? ((r = e.summary) == null ? void 0 : r[t]) || "" : e.summary && t === "enable" ? e.summary.enable : e.type === "data-grid-column" ? e.enableSummary === void 0 ? !1 : e.enableSummary : ""; } }, at = { convertTo: (e, t, n, o) => { e.group ? e.group[t] = n : e.group = { [t]: n }, t === "enable" && n && (e.group ? e.group.groupFields || (e.group.groupFields = []) : e.group = { enable: n, groupFields: [], showSummary: !1, customRender: "" }); }, convertFrom: (e, t, n) => { if (e.group) { if (t === "enable") return e.group.enable; if (t === "showSummary") return e.group.showSummary; if (t === "customRender") return e.group.customRender; if (t === "groupFields") return e.group.groupFields; } } }, lt = { convertFrom: (e, t) => e.binding ? e.binding.path : "", convertTo: (e, t, n) => { if (n && n.length > 0) { const o = n[0]; e.binding || (e.binding = {}), e.binding.type = "Form", e.binding.path = o.bindingField, e.binding.field = o.id, e.binding.fullPath = o.path, e.path = o.bindingPath; } } }, it = { convertTo: (e, t, n, o) => { e.pagination || (e.pagination = {}), t === "sizeLimits" ? e.pagination.sizeLimits = n.split(",") : e.pagination[t] = n; }, convertFrom: (e, t, n) => e.pagination ? t === "sizeLimits" ? e.pagination.sizeLimits.join(",") : e.pagination[t] : e[t] }, ut = { convertTo: (e, t, n, o) => { e.rowNumber || (e.rowNumber = {}), e.rowNumber[t] = n; }, convertFrom: (e, t, n) => e.rowNumber ? e.rowNumber[t] : e[t] }, st = { convertTo: (e, t, n, o) => { e.selection || (e.selection = {}), e.selection[t] = n; }, convertFrom: (e, t, n) => { var o, r; return t === "showCheckbox" ? (o = e.selection) != null && o.multiSelect ? !0 : (r = e.selection) == null ? void 0 : r.showCheckbox : e.selection ? e.selection[t] : e[t]; } }, ct = { convertFrom: (e, t, n) => e[t] && e[t].length ? `共 ${e[t].length} 项` : "" }, dt = { convertFrom: (e, t) => e[t] || "", convertTo: (e, t, n) => { e[t] = n; } }, ft = { convertTo: (e, t, n, o) => { e.size || (e.size = {}), e.size[t] = n; }, convertFrom: (e, t, n) => e.size ? e.size[t] : e[t] }, mt = { convertFrom: (e, t, n) => { var o, r; return (o = e.formatter) != null && o.data && t === "formatterEnumData" && !e.formatterEnumData ? (r = e.formatter) == null ? void 0 : r.data : e.formatterEnumData; } }, pt = { convertTo: (e, t, n, o) => { e.sort || (e.sort = {}), e.sort[t] = n; }, convertFrom: (e, t, n) => { var o, r; if (t === "mode") return ((o = e.sort) == null ? void 0 : o.mode) || "client"; if (t === "multiSort") return !!((r = e.sort) != null && r.multiSort); } }, vt = { convertTo: (e, t, n, o) => { e.filter || (e.filter = {}), e.filter[t] = n; }, convertFrom: (e, t, n) => { var o; if (t === "mode") return ((o = e.filter) == null ? void 0 : o.mode) || "client"; } }, gt = { convertTo: (e, t, n, o) => { e.rowOption ? e.rowOption[t] = n : e.rowOption = { [t]: n }; }, convertFrom: (e, t, n) => { if (e.rowOption) { if (t === "customRowStyle") return e.rowOption.customRowStyle; if (t === "customCellStyle") return e.rowOption.customCellStyle; if (t === "height") return e.rowOption.height; } return ""; } }, bt = { convertTo: (e, t, n, o) => { (e.type === "data-grid-column" || e.type === "tree-grid-column") && (e[t] = n, t === "columnTemplateType" && n === "hyperlink" && (e.onClickLinkCommand ? e.columnTemplate = ` <span class="f-pretend-link f-cursor-pointer" @click="(ctx)=>viewModel.current.${e.onClickLinkCommand || ""}({id: rowData.id,context: ctx})"> {{rowData.${e.field}}} </span>` : e.columnTemplate = ` <span class="f-pretend-link f-cursor-pointer"> {{rowData.${e.field}}} </span>`), t === "columnTemplateType" && n === "default" && (e.columnTemplate = ""), t === "columnTemplateType" && n === "custom" && (e.columnTemplate = "")); }, convertFrom: (e, t, n) => t === "columnTemplate" ? e.columnTemplate : t === "columnTemplateType" ? e.columnTemplateType ? e.columnTemplateType || "default" : e.columnTemplate && !e.onClickLinkCommand ? "custom" : e.columnTemplate && e.onClickLinkCommand ? "hyperlink" : "default" : "" }; function oe(e, t, n) { const o = /* @__PURE__ */ new Map([ ["/converter/appearance.converter", Ze], ["/converter/buttons.converter", Je], ["/converter/property-editor.converter", Qe], ["/converter/items-count.converter", ct], ["/converter/type.converter", Ke], ["/converter/change-editor.converter", et], ["/converter/change-formatter.converter", tt], ["/converter/column-command.converter", nt], ["/converter/column-option.converter", ot], ["/converter/summary.converter", rt], ["/converter/group.converter", at], ["/converter/form-group-label.converter", dt], ["/converter/field-selector.converter", lt], ["/converter/pagination.converter", it], ["/converter/row-number.converter", ut], ["/converter/grid-selection.converter", st], ["/converter/size.converter", ft], ["/converter/change-formatter-enum.converter", mt], ["/converter/grid-sort.converter", pt], ["/converter/grid-filter.converter", vt], ["/converter/row-option.converter", gt], ["/converter/change-formatter-type.converter", bt] ]), r = /* @__PURE__ */ new Map([ ["string", { type: "input-group", enableClear: !1 }], ["boolean", { type: "combo-list", textField: "name", valueField: "value", idField: "value", enableClear: !1, editable: !1, data: [ { value: !0, name: "是" }, { value: !1, name: "否" } ] }], ["enum", { type: "combo-list", maxHeight: 128, enableClear: !1, editable: !1 }], ["array", { type: "button-edit" }], ["number", { type: "number-spinner", placeholder: "" }], ["events-editor", { type: "events-editor", hide: !0 }], ["multiLanguage", { type: "language-textbox" }] ]), p = Ye(); function i(a, s) { return () => p.parseValueSchema(a, s); } function y(a, s, f) { return a.includes("visible") && s.visible !== void 0 ? typeof s.visible == "boolean" ? () => !!s.visible : s.visible === void 0 ? !0 : i(s.visible, f) : () => !0; } function x(a, s, f) { return a.includes("readonly") && s.readonly !== void 0 ? typeof s.readonly == "boolean" ? () => !!s.readonly : i(s.readonly, f) : () => !1; } function u(a, s) { const f = a.$converter || s; return typeof f == "string" && f && o.has(f) ? o.get(f) || null : f || null; } function g(a, s, f, h, b, F = "", P = "") { return Object.keys(a).map((C) => { const c = O(1), B = C, w = a[C], T = Object.keys(w), L = w.title, I = w.type, D = r.get(I) || { type: "input-group", enableClear: !1 }, M = w.editor ? Object.assign({}, D, w.editor) : Object.assign({}, D), W = y(T, w, s), z = x(T, w, s); M.readonly = M.readonly === void 0 ? z() : M.readonly; const q = w.type === "cascade" ? g(w.properties, s, f, h, b, F, P) : [], U = !0; let E = u(w, P); const ce = S({ get() { if (c.value) { if (["class", "style"].find((ve) => ve === B) && !E && (E = o.get("/converter/appearance.converter") || null), E && E.convertFrom) return E.convertFrom(f, C, b, F); const R = f[C]; return Object.prototype.hasOwnProperty.call(w, "defaultValue") && (R === void 0 || typeof R == "string" && R === "") ? w.type === "boolean" ? w.defaultValue : w.defaultValue || "" : R; } return null; }, set(R) { c.value += 1, E && E.convertTo ? (E.convertTo(h, C, R, b, F), E.convertTo(f, C, R, b, F)) : (h[C] = R, f[C] = R); } }), { refreshPanelAfterChanged: de, description: fe, isExpand: me, parentPropertyID: pe } = w, X = { propertyID: B, propertyName: L, propertyType: I, propertyValue: ce, editor: M, visible: W, readonly: z, cascadeConfig: q, hideCascadeTitle: U, refreshPanelAfterChanged: de, description: fe, isExpand: me, parentPropertyID: pe }; return s[B] = X, X; }); } function l(a, s, f = {}) { const h = {}, b = e[a]; return b && b.categories ? Object.keys(b.categories).map((P) => { const N = b.categories[P], C = N == null ? void 0 : N.title, c = g(N.properties || {}, h, {}, f, s); return { categoryId: P, categoryName: C, properties: c }; }) : []; } function d(a, s, f, h, b = "") { const F = s.$ref.schema, P = s.$ref.converter, N = f[F], C = N.type, c = n(N), B = {}, w = e[C]; if (w && w.categories) { const T = w.categories[a], L = T == null ? void 0 : T.title; P && Object.keys(T.properties).forEach((M) => { T.properties[M].$converter = P; }); const I = (T == null ? void 0 : T.properties) || {}, D = g(I, B, c, N, h, b); return { categoryId: a, categoryName: L, properties: D }; } return { categoryId: a, categoryName: "", properties: [] }; } function v(a, s, f, h, b) { const F = a.type, P = n(a), N = {}; let C = b || e[F]; if (!(C && Object.keys(C).length > 0) && f && f.getPropConfig && (C = f.getPropConfig(h)), C && C.categories) { const B = []; return Object.keys(C.categories).map((w) => { const T = C.categories[w]; if (T.$ref) { B.push(d(w, T, a, s, h)); return; } const L = T == null ? void 0 : T.title, I = T == null ? void 0 : T.tabId, D = T == null ? void 0 : T.tabName, M = T == null ? void 0 : T.hide, W = T == null ? void 0 : T.hideTitle, z = g(T.properties || {}, N, P, a, s, h, T.$converter), { setPropertyRelates: q } = T, U = T == null ? void 0 : T.parentPropertyID; B.push({ categoryId: w, categoryName: L, tabId: I, tabName: D, hide: M, properties: z, hideTitle: W, setPropertyRelates: q, parentPropertyID: U }); }), B; } return []; } return { getPropertyConfigBySchema: v, getPropertyConfigByType: l, propertyConverterMap: o }; } const yt = {}, ht = {}; oe(yt, ht, Ue); const xt = {}, Ct = {}, { resolveSchemaWithDefaultValue: Tt } = ne(xt, Ct), wt = {}, St = {}; oe(wt, St, Tt); function Bt(e, t) { return { customClass: t.class, customStyle: t.style }; } const re = /* @__PURE__ */ new Map([ ["appearance", Bt] ]), Ft = "https://json-schema.org/draft/2020-12/schema", Ot = "https://farris-design.gitee.io/input-group.schema.json", Pt = "language-textbox", Nt = "A Farris Input Component", It = "object", kt = { id: { description: "The unique identifier for a Input Group", type: "string" }, type: { description: "The type string of Input Group component", type: "string", default: "language-textbox" }, appearance: { description: "", type: "object", properties: { class: { type: "string" }, style: { type: "string" } }, default: {} }, binding: { description: "", type: "object", default: {} }, formatValidation: { description: "", type: "object", default: {} }, editable: { description: "", type: "boolean", default: !0 }, enableLinkLabel: { description: "", type: "boolean", default: !1 }, label: { description: "", type: "string", default: "" }, labelWidth: { description: "", type: "number" }, placeholder: { description: "", type: "string", default: "" }, readonly: { description: "", type: "boolean", default: !1 }, disabled: { description: "", type: "boolean", default: !1 }, required: { description: "", type: "boolean", default: !1 }, tabIndex: { description: "", type: "number", default: -1 }, maxLength: { description: "", type: "number", default: "" }, visible: { description: "", type: "boolean", default: !0 }, onBlur: { description: "", type: "string", default: "" }, onClickLinkLabel: { description: "", type: "string", default: "" }, languages: { description: "语种列表", type: "array", default: [] }, modelValue: { description: "绑定值", type: "object", default: {} }, enableClear: { description: "", type: "boolean", default: !0 }, maxWords: { description: "各语种最大字符数", type: "object", default: null }, needConfirm: { description: "是否需要确认", type: "boolean", default: !1 }, beforeSubmit: { description: "提交前回调", type: "object", default: null } }, Lt = [ "type" ], Et = [ "id", "appearance", "binding", "visible" ], ae = { $schema: Ft, $id: Ot, title: Pt, description: Nt, type: It, properties: kt, required: Lt, ignore: Et }; function le(e, t, n) { return t; } const Q = { id: { type: String, required: !0 }, languages: { type: Array, default: [] }, disabled: { type: Boolean, default: !1 }, editable: { type: Boolean, default: !1 }, readonly: { type: Boolean, default: !1 }, placeholder: { type: String, default: "" }, maxWords: { type: Object, default: null }, modelValue: { type: Object, default: null }, dropDownIcon: { type: String, default: '<span class="f-icon f-icon-yxs_earth"></span>' }, tabIndex: { type: Number, default: -1 }, enableClear: { type: Boolean, default: !0 }, enableTitle: { type: Boolean, default: !0 }, maxLength: { type: Number, default: null }, needConfirm: { type: Boolean, default: !1 }, beforeSubmit: { type: Function }, allowShowLanguage: { type: Boolean, default: !0 } }, rn = Ne(Q, ae, re, le), ie = Ie( Q, ae, re, le ), Rt = /* @__PURE__ */ $({ name: "LanguageContents", props: { languages: { type: Array, default: [] }, modelValue: { type: Object, default: null }, id: { type: String, default: "" }, maxLength: { type: Number, default: void 0 }, needConfirm: { type: Boolean, default: !1 }, readonly: { type: Boolean, default: !1 } }, emits: ["update:modelValue", "confirm", "cancel"], setup(e, t) { const n = O(e.languages), o = O(e.modelValue || {}), r = O(); j(() => { setTimeout(() => { var x, u; (u = (x = r.value) == null ? void 0 : x.querySelector("input")) == null || u.focus(); }, 130), e.needConfirm && (o.value = Z(e.modelValue || {})); }); function p(x, u) { o.value[u.code] = x, !e.needConfirm && t.emit("update:modelValue", o.value); } function i() { t.emit("cancel", e.modelValue); } function y() { t.emit("confirm", o.value); } return () => { var x; return m("ul", { class: "list-group", style: "background: white;", ref: r }, [(x = n.value) == null ? void 0 : x.map((u) => m("li", { class: "list-group-item border-0 p-2 px-2" }, [m("div", { class: "farris-group-wrap form-inline farris-form-inline" }, [m("div", { class: "form-group farris-form-group" }, [m("label", { for: "hpinput01", class: "col-form-label" }, [m("span", { class: "farris-label-text", title: u.name }, [u.name])]), m("div", { class: "farris-input-wrap" }, [m(ke, { id: e.id + "_" + u.code, modelValue: o.value[u.code], readonly: e.readonly, "onUpdate:modelValue": (g) => { p(g, u); }, updateOn: "change", maxLength: e.maxLength }, null)])])])])), e.needConfirm && !e.readonly && m("li", { class: "list-group-item border-0 p-2 px-2", style: "text-align: right;" }, [m("button", { type: "button", class: "btn btn-secondary mr-3", onClick: i }, [K("取消")]), m("button", { type: "button", class: "btn btn-primary", onClick: y }, [K("确定")])])]); }; } }), Mt = { id: { Type: String, default: "" }, /** 是否自动完成 */ autocomplete: { Type: String, default: "off" }, /** 自定义CLASS */ customClass: { Type: String, default: "" }, /** 禁用 */ disabled: { Type: Boolean, default: !1 }, /** 允许编辑 */ editable: { Type: Boolean, default: !0 }, /** 启用清除按钮 */ enableClear: { Type: Boolean, default: !0 }, /** 启用提示文本 */ enableTitle: { Type: Boolean, default: !0 }, /** 能否查看密码 */ enableViewPassword: { Type: Boolean, default: !0 }, /** 始终显示占位符文本 */ forcePlaceholder: { Type: Boolean, default: !1 }, /** 扩展按钮 */ groupText: { Type: String, default: "" }, /** 密码模式 */ showType: { Type: String, default: "text" }, /** 密码模式 --废弃*/ type: { Type: String, default: "text" }, /** 最大值 */ max: { type: [Number, String] }, /** 最小值 */ min: { type: [Number, String] }, /** 最大长度 */ maxLength: { Type: Number || void 0, default: void 0 }, /** 最小长度 */ minLength: { Type: Number || void 0, default: void 0 }, /** 组件值 */ modelValue: { Type: String || Boolean, default: "" }, /** 隐藏边线 */ showBorder: { Type: Boolean, default: !0 }, /** 步长 */ step: { Type: Number, default: 1 }, /** 启用提示信息 */ placeholder: { Type: String, default: "" }, precision: { Type: Number, default: 0 }, /** 只读 */ readonly: { Type: Boolean, default: !1 }, /** 当组件禁用或只读时显示后边的按钮 */ showButtonWhenDisabled: { Type: Boolean, default: !1 }, /** tab索引 */ tabIndex: { Type: Number, default: 0 }, /** 文本在输入框中的对齐方式 */ textAlign: { Type: String, default: "left" }, /** 是否启用前置扩展信息;在输入框前面 显示 ① 图标鼠标滑过后显示 */ useExtendInfo: { Type: Boolean, default: !1 }, /** 前置扩展信息 */ extendInfo: { Type: String, default: "" }, /** 输入值 */ value: { Type: String, default: "" }, /** 是否撑开高度 */ autoHeight: { type: Boolean, default: !1 }, /** 自动聚焦 */ autofocus: { type: Boolean, default: !1 }, /** 文本区域可见的行数 */ rows: { type: Number, default: 2 }, /** 展示输入文本数量 */ showCount: { type: Boolean, default: !1 }, showZero: { type: Boolean, default: !1 }, /** * 作为内嵌编辑器被创建后默认获得焦点 */ focusOnCreated: { type: Boolean, default: !1 }, /** * 作为内嵌编辑器被创建后默认选中文本 */ selectOnCreated: { type: Boolean, default: !1 }, /** * modelValue 更新时机, 默认 blur; 可选值:blur | input * - blur: 离开焦点时更新 * - change: 输入时更新 */ updateOn: { type: String, default: "blur" }, formatValidation: { type: Object, default: {} }, /** * 是否启用快捷键 */ keyboard: { type: Boolean, default: !0 } }; function jt(e, t) { const n = O(e.groupText), o = S(() => e.showButtonWhenDisabled && (e.readonly || e.disabled)), r = S(() => e.type === "password" || e.showType === "password" || e.enableClear || !!e.groupText || o.value); return { appendedButtonClass: S(() => ({ "input-group-append": !0, "append-force-show": o.value })), appendedContent: n, shouldShowAppendedButton: r }; } function Dt(e, t, n, o) { const { appendedContent: r } = o, p = O(e.enableViewPassword), i = S(() => e.type === "password" || e.showType === "password"), y = '<span class="f-icon f-icon-eye" style="color: rgb(56, 143, 255);"></span>', x = '<span class="f-icon f-icon-eye"></span>', u = O(!1); k(() => [e.readonly, e.disabled], ([d, v]) => { i.value && (n.value = d || v ? "password" : n.value, r.value = e.readonly || e.disabled ? "" : p.value ? x : ""); }); function g() { return u.value = !u.value, n.value = u.value ? "text" : "password", r.value = u.value ? y : x, !1; } function l() { n.value = i.value ? "password" : n.value, i.value && (r.value = e.readonly || e.disabled ? "" : p.value ? x : ""); } return l(), { isPassword: i, onClickAppendedButton: g }; } function Vt(e, t) { const n = je(e, t), o = De(e, t, n), r = Ve(e, t, o, n), p = $e(e, t, o, n, r), i = Ae(e, t, r), { displayValue: y, modelValue: x, getRealValue: u } = n, g = ze(e, t, p), { format: l } = o, { isFocus: d } = p, v = S(() => !e.disabled && !e.readonly); return j(() => { const a = u(e.modelValue); y.value = l(a); }), k(() => [e.value], ([a]) => { const s = u(a); x.value = s, y.value = l(s); }), k(() => [e.modelValue], ([a]) => { a !== x.value && (x.value = a, !d.value && (y.value = l(u(a)))); }), k(() => [e.precision, e.useThousands, e.prefix, e.suffix, e.showZero], () => { y.value = l(x.value); }), () => m("div", { class: "input-group flex-row f-cmp-number-spinner", style: "border:none;" }, [g(), v.value && i()]); } function $t(e) { return e ? A.getRealPropertyValue(e, "请输入", "input-group.placeholder") : ""; } function At(e, t, n, o) { const r = O(), { inputGroupClass: p, onBlur: i, onFocus: y } = o, { clearButtonClass: x, clearButtonStyle: u } = n, g = S(() => e.maxLength ? e.maxLength : e.modelValue ? e.modelValue.length : 0), l = (C) => { var c, B; C.stopPropagation(), t.emit("update:modelValue", (c = C.target) == null ? void 0 : c.value), t.emit("valueChange", (B = C.target) == null ? void 0 : B.value); }, d = S(() => ({ "form-control": !0, "h-100": e.autoHeight })), v = S(() => e.enableClear && !e.readonly && !e.disabled), a = $t(e.placeholder), s = S(() => e.disabled || e.readonly ? "" : a), f = S(() => ({ ...u.value, position: "absolute", right: "5px", top: "50%", transform: "translateY(-50%)", "background-color": "rgb(199, 207, 221)", "border-radius": "100%", width: "16px", height: "16px" })), h = S(() => { const C = { resize: "none", "padding-right": "15px" }; return e.rows > 2 ? { height: "auto", ...C } : C; }), b = (C) => { C.stopPropagation(), r.value.value = "", t.emit("update:modelValue", ""), t.emit("valueChange", ""); }; function F() { return te(m("textarea", { class: d.value, id: e.id, "onUpdate:modelValue": (C) => e.modelValue = C, ref: r, minlength: e.minLength, maxlength: e.maxLength ? e.maxLength : null, tabindex: e.tabIndex, disabled: e.disabled, readonly: e.readonly, autocomplete: e.autocomplete, placeholder: s.value, autofocus: e.autofocus, rows: e.rows, onInput: l, onFocus: y, onBlur: i, style: h.value }, null), [[ye, e.modelValue]]); } function P() { return e.showCount && m("span", { style: "position: absolute;bottom: 0;right: 5px;z-index:999;font-size:12px" }, [`${e.modelValue ? e.modelValue.length : 0}/${g.value}`]); } function N() { return v.value && m("span", { id: "clearIcon", class: x.value, style: f.value, onClick: (C) => b(C) }, [m("i", { class: "f-icon modal_close", style: "font-size:8px;color:#fff" }, null)]); } return { renderTextarea: F, renderCount: P, renderClear: N }; } function zt(e, t, n, o) { const r = O(), p = O(e.autocomplete), i = O(e.enableTitle), { isPassword: y } = n, x = O(e.minLength), u = O(e.maxLength), g = O(e.tabIndex), { disabled: l, displayText: d, inputType: v, onBlur: a, onFocus: s, onInput: f, onClick: h, onKeydown: b, onKeyup: F, onMousedown: P, onMouseup: N, onTextBoxValueChange: C, readonly: c, placeholder: B, textBoxClass: w, textBoxTitle: T } = o; return j(() => { var L, I; e.selectOnCreated && ((L = r.value) == null || L.select()), e.focusOnCreated && ((I = r.value) == null || I.focus({ preventScroll: !0 })); }), () => m("input", { id: e.id + "_textbox", ref: r, name: "input-group-value", autocomplete: p.value, class: w.value, disabled: l == null ? void 0 : l.value, maxlength: u.value, minlength: x.value, placeholder: B.value, readonly: c == null ? void 0 : c.value, tabindex: g.value, title: i.value && !y.value ? T.value : "", type: v.value, value: d == null ? void 0 : d.value, onBlur: a, onClick: h, onChange: C, onFocus: s, onInput: f, onKeydown: b, onKeyup: F, onMousedown: P, onMouseup: N }, null); } function Ht(e, t) { const n = O(e.extendInfo), o = S(() => e.useExtendInfo && !!e.extendInfo), r = S(() => ({ content: n.value })); k(() => e.extendInfo, (i) => { n.value = i; }); function p() { t.emit("updateExtendInfo"); } return () => o.value && te(m("span", { class: "input-group-before-tips", onMouseenter: p }, [m("i", { class: "f-icon f-icon-info-circle" }, null), m("b", { class: "tips-arrow" }, null)]), [[he("tooltip"), r.value]]); } function Gt(e, t, n, o, r) { const { appendedButtonClass: p, appendedContent: i } = n, y = S(() => !e.readonly && !e.disabled), x = S(() => i.value && !t.slots.groupTextTemplate), u = S(() => !!t.slots.groupTextTemplate), { clearButtonClass: g, clearButtonStyle: l, onClearValue: d, shouldShowClearButton: v } = o, a = O(0); k(i, (c) => { a.value++; }); function s() { return m("span", { id: "clearIcon", class: g.value, style: l.value, onClick: (c) => d(c) }, [m("i", { class: "f-icon modal_close" }, null)]); } function f(c) { t.emit("iconMouseEnter", c); } function h(c) { t.emit("iconMouseLeave", c); } function b(c) { y.value && t.emit("clickHandle", { originalEvent: c }), c.stopPropagation(); } const F = e.type === "password" || e.showType === "password" ? r.onClickAppendedButton : b; function P() { return m(_, null, [(e.showButtonWhenDisabled || !e.disabled && !e.readonly) && m("span", { class: "input-group-text", onMouseenter: (c) => f(c), onMouseleave: (c) => h(c), innerHTML: i.value, onClick: (c) => F(c) }, null)]); } function N() { return t.slots.groupTextTemplate && t.slots.groupTextTemplate(); } function C() { return x.value ? P() : u.value ? N() : ""; } return () => m("div", { class: p.value, key: "append-button-" + a.value }, [v.value && s(), C()]); } const ue = /* @__PURE__ */ $({ name: "FInputGroup", props: Mt, emits: ["clear", "change", "blur", "click", "clickHandle", "focus", "input", "keydown", "keyup", "iconMouseEnter", "iconMouseLeave", "update:modelValue", "update:value", "updateExtendInfo", "valueChange", "mousedownEvent", "mouseupEvent"], setup(e, t) { const n = O(), o = O(e.modelValue), r = O(e.modelValue), p = Le(e, t, o, r, n), { inputGroupClass: i, inputType: y, inputGroupStyle: x } = p, u = jt(e), { shouldShowAppendedButton: g } = u, l = Ee(e, t, p), { onMouseEnter: d, onMouseLeave: v } = l, a = Dt(e, t, y, u), s = Vt(e, t), { renderTextarea: f, renderCount: h, renderClear: b } = At(e, t, l, p), F = zt(e, t, a, p), P = Gt(e, t, u, l, a), N = Ht(e, t), C = S(() => y.value === "number"), c = S(() => y.value === "textarea"); k(() => [e.value], ([w]) => { o.value = w, r.value = w; }), k(() => [e.modelValue], ([w]) => { o.value = w, r.value = w; }), j(() => { e.value && (o.value = e.value, r.value = e.value); }); const B = () => m("div", { ref: n, id: e.id, class: i.value, style: x.value, onMouseenter: d, onMouseleave: v }, [C.value ? s() : c.value ? f() : m(_, null, [N(), F()]), !c.value && !C.value && g.value && P(), c.value && b(), c.value && h()]); return () => B(); } }); Re(ue); const _t = { showCloseButton: { type: Boolean, default: !0 }, position: { type: String, default: "top-center" }, timeout: { type: Number, default: 3e3 }, theme: { type: String, default: "bootstrap" }, left: { type: Number }, right: { type: Number }, top: { type: Number }, bottom: { type: Number }, id: { type: String }, animate: { type: String, default: "fadeIn" }, options: { type: Object }, safeHtml: { type: Boolean, default: !0 } }, Wt = { showCloseButton: { type: Boolean, default: !0 }, animate: { type: String, default: "fadeIn" }, options: { type: Object } }, J = /* @__PURE__ */ $({ name: "Toast", props: Wt, emits: ["close", "click"], setup: (e, t) => { const n = O(e.animate), o = "fadeOut", r = S(() => e.options), p = O(!1), i = S(() => r.value.title && r.value.message), y = S(() => !r.value.title && r.value.message), x = S(() => { const b = { animated: p.value, toast: !0, "toast--only-content": !i.value }; return b[e.animate] = !1, b[o] = p.value, b["toasty-type-" + r.value.type] = !0, r.value.theme && (b[r.value.theme] = !0), b; }), u = S(() => { const P = `f-icon-${r.value && r.value.type ? r.value.type.replace("toasty-type-", "") : "default"}`, N = { "f-icon": !0 }; return N[P] = !0, N; }), g = S(() => r.value.title || r.value.message), l = S(() => e.showCloseButton), d = S(() => !!r.value.buttons || !!t.slots.default), v = S(() => A.getLocale() === "en" ? { wordBreak: "keep-all", overflowWrap: "break-word" } : {}); function a(b) { b.stopPropagation(), b.preventDefault(), p.value = !1, setTimeout(() => { t.emit("close", r.value); }, 200); } function s(b, F) { } function f(b) { return `f-preten-link ${b.customClass ? b.customClass : ""}`; } k(n, () => { n.value; }); const h = () => { var b; return m(_, null, [m("div", { class: "after-toast-msg text-right" }, [!t.slots.default && ((b = r.value.buttons) == null ? void 0 : b.map((F) => m("span", { class: f(F), onClick: (P) => void 0 }, [F.text]))), t.slots.default && t.slots.default()])]); }; return () => m("div", { class: x.value, style: "min-height:44px" }, [l.value && m("button", { title: A.getLocaleValue("messageBox.close"), class: "toast-close f-btn-icon f-bare", onClick: a }, [m("span", { class: "f-icon modal_close" }, null)]), g.value && m("section", { class: "modal-tips" }, [!i.value && m("div", { class: "float-left modal-tips-iconwrap" }, [m("span", { class: u.value }, null)]), m("div", { class: "modal-tips-content" }, [i.value && m(_, null, [m("h5", { class: "toast-title modal-tips-title", innerHTML: r.value.title }, null), m("p", { class: "toast-msg", innerHTML: r.value.message, style: v.value }, null), d.value && h()]), y.value && (r.value.buttons ? m("div", { class: "toast-title-btns-wrapper d-flex" }, [m("h5", { class: "toast-title modal-tips-title only-toast-msg", style: v.value, innerHTML: r.value.message }, null), m("div", { class: "after-toast-title text-right ml-auto" }, [h()])]) : m("h5", { class: "toast-title modal-tips-title only-toast-msg", style: v.value, innerHTML: r.value.message }, null))])])]); } }), H = /* @__PURE__ */ $({ name: "Notify", props: _t, emits: ["close", "empty"], setup(e, t) { const n = S(() => ({ "farris-notify": !0 })), o = { left: 12, right: 12, top: 20, bottom: 12 }, r = O(), p = O(e.options), i = O(e.showCloseButton), y = S(() => e.position || "bottom-right"), x = S(() => e.timeout != null ? e.timeout : 3e3), u = S(() => { const d = e.bottom ? e.bottom : o.bottom, v = e.top ? e.top : o.top, a = { transition: "all 0.2s ease", left: y.value.indexOf("left") > -1 ? `${e.left ? e.left : o.left}px` : "", right: y.value.indexOf("right") > -1 ? `${e.right ? e.right : o.right}px` : "", top: y.value.indexOf("top") > -1 ? `${v}px` : "", bottom: y.value.indexOf("bottom") > -1 ? `${d}px` : "" }; return y.value.indexOf("center") > -1 && (a.left = "50%", a.marginLeft = "calc(-24rem / 2)", y.value === "center-center" && (a.top = "50%", a.transform = "translate(-50%, -50%)")), a; }); function g(d) { t.emit("close"); } x.value && setTimeout(() => { g(); }, x.value), t.expose({ closeToast: g, container: r, notifyPosition: y }); function l(d, v) { g(); } return () => m("div", { class: n.value, style: u.value, ref: r }, [m(J, { options: p.value, showCloseButton: i.value, animate: e.animate, onClose: (d) => l(d, p.value) }, null)]); } }); class qt { constructor() { Y(this, "notifyRefs", []); Y(this, "globalConfig", xe({})); } escapeAllHtml(t) { if (typeof t != "string" || !t) return ""; const n = document.createElement("div"); return n.textContent = t || "", n.innerHTML.replace(/\\n/g, "<br>").replace(/\\t/g, "&nbsp;&nbsp;&nbsp;&nbsp;").replace(/\\r/g, ""); } createNotifyInstance(t) { const n = this, r = Object.assign({ timeout: 3e3, position: "bottom-right", showCloseButton: !0, safeHtml: !0 }, this.globalConfig, { ...t }), p = document.createElement("div"); p.style.display = "contents"; const i = Ce({ setup() { var u; const y = O(); function x() { y.value.container.style.transform = "scale(0)", setTimeout(() => { n.updateNotifyPositionForClose(r, y), i.unmount(); }, 220); } if (r.position.indexOf("top") > -1) { const g = n.getNotifyInstances(r.position), l = g[g.length - 1]; if (l) { const d = l.value.container.getBoundingClientRect(); r.top = d.bottom; } } return r.safeHtml && ((u = r.options) != null && u.message) && (r.options.message = n.escapeAllHtml(r.options.message)), Te(() => { document.body.removeChild(p); }), j(() => { n.updateNotifyPositionForCreate(r, y); }), () => m(we, { mode: "out-in", name: "fade", appear: !0 }, { default: () => [m(H, Se({ ref: y }, r, { onClose: x }), null)] }); } }); return i.provide("NotifyService", this), document.body.appendChild(p), i.use(A.i18n), i.mount(p), i; } getNotifyInstances(t) { return this.notifyRefs.filter((n) => n.value.notifyPosition === t); } updateNotifyPositionForCreate(t, n) { if (this.notifyRefs && this.notifyRefs.length) { const o = window.innerHeight; t.position.indexOf("bottom") > -1 && this.getNotifyInstances(t.position).forEach((r) => { const p = r.value.container.getBoundingClientRect(); r.value.container.style.bottom = p.height + o - p.bottom + "px"; }); } this.notifyRefs = [...this.notifyRefs, n]; } updateNotifyPositionForClose(t, n) { const o = this.notifyRefs.indexOf(n); if (t.position.indexOf("top