UNPKG

@farris/ui-vue

Version:

Farris Vue, a Farris Design based Vue3 component library.

456 lines (455 loc) 14 kB
import { isMobilePhone as W, withInstall as X } from "../common/index.esm.js"; import { computed as S, ref as O, createVNode as C, onMounted as U, nextTick as A, defineComponent as Y, watch as E } from "vue"; import N from "bignumber.js"; import { LocaleService as $ } from "../locale/index.esm.js"; import { useInputExpand as ee } from "../common/index.esm.js/text-box/use-input-expand"; const te = { /** * 组件标识 */ id: String, /** * 是否禁用 */ disabled: { type: Boolean, default: !1 }, /** * 是否只读 */ readonly: { type: Boolean, default: !1 }, /** * 是否可编辑 */ editable: { type: Boolean, default: !0 }, /** * 格式化 formatter 和 parser 必须同时存在 * formatter: (val: number) => string; * parser: (val: string | number) => number; */ formatter: { type: Function }, parser: { type: Function }, /** * 空白提示文本 */ placeholder: { type: String, default: "请输入数字" }, /** * up or down 步长 */ step: { type: Number, default: 1 }, /** * 最大值 */ max: { type: [Number, String] }, /** * 最小值 */ min: { type: [Number, String] }, /** * 是否显示加减按钮 */ showButton: { type: Boolean, default: !0 }, /** * 是否使用千分值 */ useThousands: { type: Boolean, default: !0 }, /** * 文本方向 */ textAlign: { type: String, default: "left" }, /** * 自动补全小数---未实现 */ autoDecimal: { type: Boolean, default: !0 }, /** * 允许为空 */ nullable: { type: Boolean, default: !1 }, /** * 精度 */ precision: { type: Number, default: 0 }, /** * 前缀 */ prefix: { type: String, default: "" }, /** * 后缀 */ suffix: { type: String, default: "" }, /** * 小数点符号 */ decimalSeparator: { type: String, default: "." }, /** 始终显示占位符文本 */ forcePlaceholder: { Type: Boolean, default: !1 }, /** * 千分位符号 */ groupSeparator: { type: String, default: "," }, /** * 使用千分位时,每组显示的字符数 */ groupSize: { type: Number, default: 3 }, /** * 值 */ value: { type: [Number, String], default: "" }, /** * 显示0值 */ showZero: { type: Boolean, default: !0 }, /** * 组件值 */ modelValue: { type: [Number, String], default: "" }, /** * 作为内嵌编辑器被创建后默认获得焦点 */ focusOnCreated: { type: Boolean, default: !1 }, /** * 作为内嵌编辑器被创建后默认选中文本 */ selectOnCreated: { type: Boolean, default: !1 }, /** * 是否启用快捷键 */ keyboard: { type: Boolean, default: !0 }, /** * 是否启用大数 */ bigNumber: { type: Boolean, default: !1 }, /** 是否需要验证 */ needValid: { type: Boolean, default: !1 }, /** 更新方式 blur | change */ updateOn: { type: String, default: "change" }, /** 是否可扩展 */ expandable: { type: Boolean, default: !1 }, /** 扩展模式 text | button */ expandMode: { type: String, default: "text" }, /** 扩展文本内容 */ expandContent: { type: String, default: "" }, /** 扩展按钮是否禁用 */ expandDisabled: { type: Boolean, default: !1 } }; function ne(e, c, b, g) { const { format: f } = b, { displayValue: m, getRealValue: y, modelValue: l, onNumberValueChanged: d } = g; function n() { const u = new N(l.value || 0); return !((e.max || e.max === 0) && !new N(e.max).isNaN() && u.gte(new N(e.max)) && (l.value || l.value === 0)); } function x() { const u = new N(l.value || 0); return !((e.min || e.min === 0) && !new N(e.min).isNaN() && u.lte(new N(e.min)) && (l.value || l.value === 0)); } function t(u) { if (e.readonly || e.disabled) return; const V = u === "up" ? n : x, j = u === "up" ? "plus" : "minus"; if (V()) { const p = new N(l.value || 0)[j](Number(e.step)), D = p.toFixed(); m.value = f(D), d(y(p)); } } function o() { t("up"); } function i() { t("down"); } function v(u) { o(); } function h(u) { i(); } return { canDownward: x, canUpward: n, downward: i, onClickDownButton: h, onClickUpButton: v, upward: o }; } function ae(e, c, b) { const g = S(() => ({ prefix: e.prefix, suffix: e.suffix, decimalSeparator: e.decimalSeparator, groupSeparator: e.useThousands ? e.groupSeparator : "", groupSize: e.groupSize })), { getValidNumberObject: f, precision: m } = b; function y(n) { return n = n == null || n === "" ? "" : String(n), n = n.replace(new RegExp(e.prefix, "g"), "").replace(new RegExp(e.suffix, "g"), "").replace(/,/g, ""), e.groupSeparator && e.groupSeparator !== "," && (n = n.replace(new RegExp(`\\${e.groupSeparator}`, "g"), "")), e.decimalSeparator && e.decimalSeparator !== "." && (n = n.replace(new RegExp(`\\${e.decimalSeparator}`, "g"), ".")), n; } function l(n, x) { return e.precision !== null && e.precision !== void 0 ? n.toFormat(m.value, x) : n.toFormat(x); } function d(n, x = !0) { const t = y(n), o = new N(t, 10); let i = o; return x && (i = f(o)), i.valueOf() === "0" && !e.showZero || i.isNaN() ? "" : e.formatter ? e.formatter(i.toNumber()) : l(i, g.value); } return { cleanFormat: y, format: d }; } function ue(e, c) { const b = O(""), g = O(e.modelValue), f = S(() => Number(e.precision) || 0), m = O(e.bigNumber); function y(t) { return t.toFixed(f.value); } function l(t) { return isNaN(t) || t === null || t === void 0 || t === ""; } function d(t) { const o = l(e.max) ? null : new N(String(e.max), 10), i = l(e.min) ? null : new N(String(e.min), 10); return o && t.gt(o) ? o : i && t.lt(i) ? i : t; } function n(t, o = !0) { if (e.parser) return isNaN(Number(t)) ? e.parser(t) : t; let i = new N(t, 10); if (o && (i = d(i)), i.isNaN()) { if (e.nullable) return null; if (e.showZero) return 0; if (!o) return null; const h = new N("" + e.min, 10), u = new N("" + e.max, 10); if (!h.isNaN()) i = h; else if (!u.isNaN()) i = u; else return 0; } return y(i); } function x(t) { let o = m.value ? t : Number(t); e.nullable && t === null && (o = null), o !== e.modelValue && (c.emit("update:modelValue", o), c.emit("valueChange", o), c.emit("change", o)); } return { displayValue: b, getRealValue: n, modelValue: g, isEmpty: l, onNumberValueChanged: x, precision: f, getValidNumberObject: d, toFixed: y }; } function le(e, c, b, g, f) { const { cleanFormat: m, format: y } = b, { displayValue: l, getRealValue: d, modelValue: n, isEmpty: x, onNumberValueChanged: t, getValidNumberObject: o, toFixed: i } = g, { downward: v, upward: h } = f, u = O(!1), V = S(() => l.value); function j(a) { var B; if (a.stopPropagation(), u.value = !1, e.readonly || e.disabled) return; const r = (B = a.target) == null ? void 0 : B.value, s = m(r); let w = d(s, e.needValid); e.needValid && w != null && (w = i(o(new N(w, 10)))), l.value = y(w, e.needValid), e.updateOn === "blur" && t(w), c.emit("blur", { event: a, formatted: l.value, value: n.value }); } function P() { const a = n.value; if (x(a) || !e.showZero && a === 0) return ""; const r = d(a, e.needValid); if (!r && r !== 0) return ""; try { const s = new N(r, 10); return s.isNaN() || !s.isFinite() ? "" : s.toFixed(); } catch { return ""; } } function p(a) { if (a.stopPropagation(), u.value = !0, e.readonly || e.disabled) return; const r = d(n.value, e.needValid); l.value = P(), c.emit("focus", { event: a, formatted: r, value: n.value }); } function D(a) { var B; a.stopPropagation(); let r = (B = a.target) == null ? void 0 : B.value; e.nullable || (r = r || 0); const s = m(r); let w = d(s, e.needValid); e.updateOn === "change" && (e.needValid && (w = i(o(new N(w, 10)))), l.value = r, t(w)), c.emit("input", w); } function Z(a) { const r = a; return r.value.substring((r == null ? void 0 : r.selectionStart) || 0, (r == null ? void 0 : r.selectionEnd) || 0); } function L(a) { const { key: r, keyCode: s, target: w, ctrlKey: B, metaKey: z, shiftKey: R } = a; if (!w) return; const I = w, F = I.value, G = Number(e.precision), _ = /* @__PURE__ */ new Set([".", "-", "%"]), q = Z(w); if (_.has(r) && F.includes(r) && !q.includes(r) || e.precision === 0 && [110, 190].includes(s)) { a.preventDefault(); return; } const H = /* @__PURE__ */ new Set([46, 8, 9, 27, 13, 110, 190, 173]), J = /* @__PURE__ */ new Set([65, 67, 86, 88]), Q = /* @__PURE__ */ new Set([...Array.from({ length: 5 }, (k, T) => 35 + T), 189, 109]); if (H.has(s) || J.has(s) && (B || z) || Q.has(s)) return; if (!(!R && (s >= 48 && s <= 57 || s >= 96 && s <= 105))) { a.preventDefault(); return; } if ((R || s < 48 || s > 57) && (s < 96 || s > 105) && a.preventDefault(), F.includes(".") && e.precision) { const k = F.indexOf("."), T = F.length - k - 1; if ((I.selectionStart || 0) > k && T >= G) return a.preventDefault(), !1; } } const K = (a) => { var w; let r = (w = a.target) == null ? void 0 : w.value; e.nullable || (r = r || 0); const s = m(r); n.value = d(s); }; function M(a) { return e.keyboard && a.key === "ArrowDown" && (a.preventDefault(), K(a), v(), a.stopPropagation()), e.keyboard && a.key === "ArrowUp" && (a.preventDefault(), K(a), h(), a.stopPropagation()), L(a); } return { textBoxValue: V, onBlurTextBox: j, onFocusTextBox: p, onInput: D, onKeyDown: M, isFocus: u }; } function re(e, c, b) { const { canDownward: g, canUpward: f, onClickDownButton: m, onClickUpButton: y } = b, l = S(() => ({ "f-cmp-inputgroup": !0, "input-group-append": !0, "btn-group": !0, "btn-group-number": !0 })), d = S(() => ({ btn: !0, "btn-secondary": !0, "btn-number-flag": !0 })), n = S(() => ({ cursor: f() ? "pointer" : "not-allowed", "margin-left": 0 })), x = S(() => ({ cursor: g() ? "pointer" : "not-allowed", "margin-left": 0 })); return () => C("div", { class: l.value }, [C("button", { class: d.value, style: n.value, onClick: y, disabled: !f() }, [C("span", { class: "f-icon f-icon-arrow-chevron-up number-arrow-chevron", style: "cursor: inherit" }, null)]), C("button", { class: d.value, style: x.value, onClick: m, disabled: !g() }, [C("span", { class: "f-icon f-icon-arrow-chevron-down number-arrow-chevron", style: "cursor: inherit" }, null)])]); } function ie(e) { function c(f, m, y) { return m === y ? $.getLocaleValue(f) : m || ""; } const b = c("numberSpinner.placeholder", e.placeholder, "请输入数字"), g = { begin: c("numberSpinner.range.begin", e.beginPlaceholder, "开始数字"), end: c("numberSpinner.range.end", e.endPlaceholder, "结束数字") }; return { placeholder: b, range: g }; } function oe(e, c, b) { const g = ie(e), f = O(), { onBlurTextBox: m, onFocusTextBox: y, onInput: l, onKeyDown: d, textBoxValue: n } = b, x = S(() => (e.disabled || e.readonly || !e.editable) && !e.forcePlaceholder ? "" : g.placeholder), t = S(() => ({ "form-control": !0, "f-utils-fill": !0 })), o = S(() => ({ "text-align": e.textAlign })); function i(u) { u.stopPropagation(); } function v() { var u, V; e.selectOnCreated && ((u = f.value) == null || u.select()), e.focusOnCreated && ((V = f.value) == null || V.focus({ preventScroll: !0 })); } async function h(u) { y(u), await A, v(); } return U(async () => { await A, v(); }), () => C("input", { ref: f, class: t.value, style: o.value, type: "text", value: n.value, disabled: e.disabled, readonly: e.readonly || !e.editable, placeholder: x.value, onBlur: m, onChange: i, onFocus: h, onInput: l, onKeydown: d, title: n.value }, null); } const ce = /* @__PURE__ */ Y({ name: "FNumberSpinner", props: te, emits: ["update:modelValue", "valueChange", "change", "blur", "focus", "click", "input", "expandClick"], setup(e, c) { const b = ue(e, c), g = ae(e, c, b), f = ne(e, c, g, b), m = le(e, c, g, b, f), y = re(e, c, f), { displayValue: l, modelValue: d, getRealValue: n } = b, x = oe(e, c, m), { format: t } = g, { isFocus: o } = m, i = S(() => !e.disabled && !e.readonly && e.showButton && !W()), v = S(() => ({ "f-cmp-inputgroup": !0, "input-group": !0, "flex-row": !0, "f-cmp-number-spinner": !0, "f-state-disabled": e.disable, "f-state-readonly": e.readonly && !e.disable, "f-state-focus": o.value && !e.readonly && !e.disable, "spinner-hidden": !i.value })); U(() => { const u = n(e.modelValue, !1); l.value = t(u, !1); }), E(() => [e.value], ([u]) => { const V = n(u, !1); d.value = V, l.value = t(V, !1); }), E(() => [e.modelValue], ([u]) => { u !== d.value && (d.value = u, !o.value && (l.value = t(n(u, !1), !1))); }), E(() => [e.precision, e.useThousands, e.prefix, e.suffix, e.showZero], () => { l.value = t(d.value, !1); }); const { renderExpandContent: h } = ee(e, c); return () => C("div", { class: v.value, id: e.id }, [x(), i.value && y(), h(e.expandMode === "button" ? { "padding-left": "8px" } : void 0)]); } }), we = X(ce); export { ce as FNumberSpinner, we as default, oe as getNumberTextBoxRender, re as getSpinnerRender, te as numberSpinnerProps, ae as useFormat, ue as useNumber, ie as useNumberLocales, ne as useSpinner, le as useTextBox };