@farris/ui-vue
Version:
Farris Vue, a Farris Design based Vue3 component library.
439 lines (438 loc) • 13.3 kB
JavaScript
import { withInstall as W } from "../common/index.esm.js";
import { computed as v, ref as O, createVNode as B, onMounted as U, nextTick as A, defineComponent as X, watch as P } from "vue";
import x from "bignumber.js";
import { LocaleService as Y } from "../locale/index.esm.js";
const $ = {
/**
* 组件标识
*/
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" }
};
function ee(e, s, b, g) {
const { format: f } = b, { displayValue: m, getRealValue: y, modelValue: u, onNumberValueChanged: d } = g;
function n() {
const o = new x(u.value || 0);
return !((e.max || e.max === 0) && !new x(e.max).isNaN() && o.gte(new x(e.max)) && (u.value || u.value === 0));
}
function w() {
const o = new x(u.value || 0);
return !((e.min || e.min === 0) && !new x(e.min).isNaN() && o.lte(new x(e.min)) && (u.value || u.value === 0));
}
function t(o) {
if (e.readonly || e.disabled)
return;
const C = o === "up" ? n : w, D = o === "up" ? "plus" : "minus";
if (C()) {
const F = new x(u.value || 0)[D](Number(e.step)), T = F.toFixed();
m.value = f(T), d(y(F));
}
}
function r() {
t("up");
}
function i() {
t("down");
}
function h(o) {
r();
}
function N(o) {
i();
}
return { canDownward: w, canUpward: n, downward: i, onClickDownButton: N, onClickUpButton: h, upward: r };
}
function te(e, s, b) {
const g = v(() => ({
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 u(n, w) {
return e.precision !== null && e.precision !== void 0 ? n.toFormat(m.value, w) : n.toFormat(w);
}
function d(n, w = !0) {
const t = y(n), r = new x(t, 10);
let i = r;
return w && (i = f(r)), i.valueOf() === "0" && !e.showZero || i.isNaN() ? "" : e.formatter ? e.formatter(i.toNumber()) : u(i, g.value);
}
return { cleanFormat: y, format: d };
}
function ne(e, s) {
const b = O(""), g = O(e.modelValue), f = v(() => Number(e.precision) || 0), m = O(e.bigNumber);
function y(t) {
return t.toFixed(f.value);
}
function u(t) {
return isNaN(t) || t === null || t === void 0 || t === "";
}
function d(t) {
const r = u(e.max) ? null : new x(String(e.max), 10), i = u(e.min) ? null : new x(String(e.min), 10);
return r && t.gt(r) ? r : i && t.lt(i) ? i : t;
}
function n(t, r = !0) {
if (e.parser)
return isNaN(Number(t)) ? e.parser(t) : t;
let i = new x(t, 10);
if (r && (i = d(i)), i.isNaN()) {
if (e.nullable)
return null;
if (e.showZero && r)
return 0;
if (!r)
return null;
const N = new x("" + e.min, 10), o = new x("" + e.max, 10);
if (!N.isNaN())
i = N;
else if (!o.isNaN())
i = o;
else
return 0;
}
return y(i);
}
function w(t) {
let r = m.value ? t : Number(t);
e.nullable && t === null && (r = null), r !== e.modelValue && (s.emit("update:modelValue", r), s.emit("valueChange", r), s.emit("change", r));
}
return { displayValue: b, getRealValue: n, modelValue: g, isEmpty: u, onNumberValueChanged: w, precision: f, getValidNumberObject: d, toFixed: y };
}
function ae(e, s, b, g, f) {
const { cleanFormat: m, format: y } = b, { displayValue: u, getRealValue: d, modelValue: n, isEmpty: w, onNumberValueChanged: t, getValidNumberObject: r, toFixed: i } = g, { downward: h, upward: N } = f, o = O(!1), C = v(() => u.value);
function D(a) {
var V;
if (a.stopPropagation(), o.value = !1, e.readonly || e.disabled)
return;
const l = (V = a.target) == null ? void 0 : V.value, c = m(l);
let S = d(c, e.needValid);
e.needValid && S != null && (S = i(r(new x(S, 10)))), u.value = y(S, e.needValid), e.updateOn === "blur" && t(S), s.emit("blur", { event: a, formatted: u.value, value: n.value });
}
function R() {
const a = n.value;
if (w(a) || !e.showZero && a === 0)
return "";
const l = d(a, e.needValid);
if (!l && l !== 0)
return "";
try {
const c = new x(l, 10);
return c.isNaN() || !c.isFinite() ? "" : c.toFixed();
} catch {
return "";
}
}
function F(a) {
if (a.stopPropagation(), o.value = !0, e.readonly || e.disabled)
return;
const l = d(n.value, e.needValid);
u.value = R(), s.emit("focus", { event: a, formatted: l, value: n.value });
}
function T(a) {
var V;
a.stopPropagation();
let l = (V = a.target) == null ? void 0 : V.value;
e.nullable || (l = l || 0);
const c = m(l);
let S = d(c, e.needValid);
e.updateOn === "change" && (e.needValid && (S = i(r(new x(S, 10)))), u.value = l, t(S)), s.emit("input", S);
}
function Z(a) {
const l = a;
return l.value.substring((l == null ? void 0 : l.selectionStart) || 0, (l == null ? void 0 : l.selectionEnd) || 0);
}
function L(a) {
const { key: l, keyCode: c, target: S, ctrlKey: V, metaKey: G, shiftKey: I } = a;
if (!S)
return;
const p = S, j = p.value, M = Number(e.precision), _ = /* @__PURE__ */ new Set([".", "-", "%"]), q = Z(S);
if (_.has(l) && j.includes(l) && !q.includes(l) || e.precision === 0 && [110, 190].includes(c)) {
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, K) => 35 + K), 189, 109]);
if (H.has(c) || J.has(c) && (V || G) || Q.has(c))
return;
if (!(!I && (c >= 48 && c <= 57 || c >= 96 && c <= 105))) {
a.preventDefault();
return;
}
if ((I || c < 48 || c > 57) && (c < 96 || c > 105) && a.preventDefault(), j.includes(".") && e.precision) {
const k = j.indexOf("."), K = j.length - k - 1;
if ((p.selectionStart || 0) > k && K >= M)
return a.preventDefault(), !1;
}
}
const E = (a) => {
var S;
let l = (S = a.target) == null ? void 0 : S.value;
e.nullable || (l = l || 0);
const c = m(l);
n.value = d(c);
};
function z(a) {
return e.keyboard && a.key === "ArrowDown" && (a.preventDefault(), E(a), h(), a.stopPropagation()), e.keyboard && a.key === "ArrowUp" && (a.preventDefault(), E(a), N(), a.stopPropagation()), L(a);
}
return { textBoxValue: C, onBlurTextBox: D, onFocusTextBox: F, onInput: T, onKeyDown: z, isFocus: o };
}
function ue(e, s, b) {
const {
canDownward: g,
canUpward: f,
onClickDownButton: m,
onClickUpButton: y
} = b, u = v(() => ({
"input-group-append": !0,
"btn-group": !0,
"btn-group-number": !0
})), d = v(() => ({
btn: !0,
"btn-secondary": !0,
"btn-number-flag": !0
})), n = v(() => ({
cursor: f() ? "pointer" : "not-allowed",
"margin-left": 0
})), w = v(() => ({
cursor: g() ? "pointer" : "not-allowed",
"margin-left": 0
}));
return () => B("div", {
class: u.value
}, [B("button", {
class: d.value,
style: n.value,
onClick: y,
disabled: !f()
}, [B("span", {
class: "f-icon f-icon-arrow-chevron-up number-arrow-chevron",
style: "cursor: inherit"
}, null)]), B("button", {
class: d.value,
style: w.value,
onClick: m,
disabled: !g()
}, [B("span", {
class: "f-icon f-icon-arrow-chevron-down number-arrow-chevron",
style: "cursor: inherit"
}, null)])]);
}
function le(e) {
function s(f, m, y) {
return m === y ? Y.getLocaleValue(f) : m || "";
}
const b = s("numberSpinner.placeholder", e.placeholder, "请输入数字"), g = {
begin: s("numberSpinner.range.begin", e.beginPlaceholder, "开始数字"),
end: s("numberSpinner.range.end", e.endPlaceholder, "结束数字")
};
return { placeholder: b, range: g };
}
function re(e, s, b) {
const g = le(e), f = O(), {
onBlurTextBox: m,
onFocusTextBox: y,
onInput: u,
onKeyDown: d,
textBoxValue: n
} = b, w = v(() => (e.disabled || e.readonly || !e.editable) && !e.forcePlaceholder ? "" : g.placeholder), t = v(() => ({
"form-control": !0,
"f-utils-fill": !0
})), r = v(() => ({
"text-align": e.textAlign
}));
function i(o) {
o.stopPropagation();
}
function h() {
var o, C;
e.selectOnCreated && ((o = f.value) == null || o.select()), e.focusOnCreated && ((C = f.value) == null || C.focus({
preventScroll: !0
}));
}
async function N(o) {
y(o), await A, h();
}
return U(async () => {
await A, h();
}), () => B("input", {
ref: f,
class: t.value,
style: r.value,
type: "text",
value: n.value,
disabled: e.disabled,
readonly: e.readonly || !e.editable,
placeholder: w.value,
onBlur: m,
onChange: i,
onFocus: N,
onInput: u,
onKeydown: d,
title: n.value
}, null);
}
const ie = /* @__PURE__ */ X({
name: "FNumberSpinner",
props: $,
emits: ["update:modelValue", "valueChange", "change", "blur", "focus", "click", "input"],
setup(e, s) {
const b = ne(e, s), g = te(e, s, b), f = ee(e, s, g, b), m = ae(e, s, g, b, f), y = ue(e, s, f), {
displayValue: u,
modelValue: d,
getRealValue: n
} = b, w = re(e, s, m), {
format: t
} = g, {
isFocus: r
} = m, i = v(() => !e.disabled && !e.readonly && e.showButton), h = v(() => ({
"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": r.value && !e.readonly && !e.disable,
"spinner-hidden": !i.value
}));
return U(() => {
const N = n(e.modelValue, !1);
u.value = t(N, !1);
}), P(() => [e.value], ([N]) => {
const o = n(N, !1);
d.value = o, u.value = t(o, !1);
}), P(() => [e.modelValue], ([N]) => {
N !== d.value && (d.value = N, !r.value && (u.value = t(n(N, !1), !1)));
}), P(() => [e.precision, e.useThousands, e.prefix, e.suffix, e.showZero], () => {
u.value = t(d.value, !1);
}), () => B("div", {
class: h.value,
id: e.id
}, [w(), i.value && y()]);
}
}), ge = W(ie);
export {
ie as FNumberSpinner,
ge as default,
re as getNumberTextBoxRender,
ue as getSpinnerRender,
$ as numberSpinnerProps,
te as useFormat,
ne as useNumber,
le as useNumberLocales,
ee as useSpinner,
ae as useTextBox
};