bj-web-components 0.2.27 → 0.2.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +51 -1
- package/dist/index.mjs +49 -49
- package/dist/style.css +3744 -1
- package/dist/web/BasicInput/BInput.js +208 -1
- package/dist/web/BasicInput/BInput.mjs +164 -132
- package/dist/web/BasicInput/utils.js +47 -1
- package/dist/web/BasicInput/utils.mjs +38 -28
- package/dist/web/CategoryDropdown/CategoryDropdown.js +307 -1
- package/dist/web/CategoryDropdown/CategoryDropdown.mjs +218 -170
- package/dist/web/CheckBox/BCheckBox.js +116 -1
- package/dist/web/CheckBox/BCheckBox.mjs +86 -70
- package/dist/web/CheckBox/Group.js +73 -1
- package/dist/web/CheckBox/Group.mjs +63 -56
- package/dist/web/CheckBox/context.js +5 -1
- package/dist/web/CheckBox/context.mjs +3 -3
- package/dist/web/CheckBox/index.js +8 -1
- package/dist/web/CheckBox/index.mjs +6 -6
- package/dist/web/Dropdown/BDropdown.js +186 -1
- package/dist/web/Dropdown/BDropdown.mjs +132 -106
- package/dist/web/EmptyInputBox/EmptyInputBox.js +77 -1
- package/dist/web/EmptyInputBox/EmptyInputBox.mjs +52 -48
- package/dist/web/FileCard/FileCard.js +157 -1
- package/dist/web/FileCard/FileCard.mjs +112 -82
- package/dist/web/Icon/Icon.js +9 -1
- package/dist/web/Icon/Icon.mjs +6 -6
- package/dist/web/Input/Input.js +181 -1
- package/dist/web/Input/Input.mjs +122 -113
- package/dist/web/InputNumber/BInputNumber.js +311 -1
- package/dist/web/InputNumber/BInputNumber.mjs +275 -167
- package/dist/web/InputNumber/StepHandler.js +69 -1
- package/dist/web/InputNumber/StepHandler.mjs +38 -32
- package/dist/web/InputNumber/hooks/useCursor.js +40 -1
- package/dist/web/InputNumber/hooks/useCursor.mjs +35 -33
- package/dist/web/InputNumber/hooks/useFrame.js +12 -1
- package/dist/web/InputNumber/hooks/useFrame.mjs +9 -6
- package/dist/web/InputNumber/utils/decimal.js +147 -1
- package/dist/web/InputNumber/utils/decimal.mjs +109 -81
- package/dist/web/Modal/Modal.js +84 -1
- package/dist/web/Modal/Modal.mjs +52 -49
- package/dist/web/OverlayScrollbar/BOverlayScrollbar.js +232 -1
- package/dist/web/OverlayScrollbar/BOverlayScrollbar.mjs +206 -125
- package/dist/web/Pagination/Pagination.js +328 -1
- package/dist/web/Pagination/Pagination.mjs +254 -178
- package/dist/web/ProductField/ProductField.js +272 -1
- package/dist/web/ProductField/ProductField.mjs +190 -143
- package/dist/web/ProductField/arrow-up.svg.js +3 -1
- package/dist/web/ProductField/arrow-up.svg.mjs +2 -2
- package/dist/web/ProductField/checkbox-no.svg.js +3 -1
- package/dist/web/ProductField/checkbox-no.svg.mjs +2 -2
- package/dist/web/ProductField/checkbox-ok.svg.js +3 -1
- package/dist/web/ProductField/checkbox-ok.svg.mjs +2 -2
- package/dist/web/ProductField/no_data_light.svg.js +3 -1
- package/dist/web/ProductField/no_data_light.svg.mjs +2 -2
- package/dist/web/ProductField/search.svg.js +3 -1
- package/dist/web/ProductField/search.svg.mjs +2 -2
- package/dist/web/ProductField/sort.svg.js +3 -1
- package/dist/web/ProductField/sort.svg.mjs +2 -2
- package/dist/web/SkuInputCard/SkuInputCard.js +276 -1
- package/dist/web/SkuInputCard/SkuInputCard.mjs +188 -149
- package/dist/web/SkuInputCard/spin_loading_red.gif.js +3 -1
- package/dist/web/SkuInputCard/spin_loading_red.gif.mjs +2 -2
- package/dist/web/Switch/Switch.js +70 -1
- package/dist/web/Switch/Switch.mjs +47 -37
- package/dist/web/Table/BTable.js +950 -1
- package/dist/web/Table/BTable.mjs +771 -519
- package/dist/web/Table/Column.js +5 -1
- package/dist/web/Table/Column.mjs +2 -2
- package/dist/web/Table/ColumnGroup.js +5 -1
- package/dist/web/Table/ColumnGroup.mjs +2 -2
- package/dist/web/Table/utils/columns.js +48 -1
- package/dist/web/Table/utils/columns.mjs +35 -30
- package/dist/web/Table/utils/sortFilter.js +84 -1
- package/dist/web/Table/utils/sortFilter.mjs +73 -52
- package/dist/web/Tabs/BTabs.js +150 -1
- package/dist/web/Tabs/BTabs.mjs +118 -98
- package/dist/web/Tabs/TabPane.js +8 -1
- package/dist/web/Tabs/TabPane.mjs +4 -4
- package/dist/web/Tooltip/ConfirmTooltip.js +26 -1
- package/dist/web/Tooltip/ConfirmTooltip.mjs +20 -19
- package/dist/web/Tooltip/ContentTooltip.js +94 -1
- package/dist/web/Tooltip/ContentTooltip.mjs +72 -62
- package/dist/web/Tooltip/ProgressTooltip.js +36 -1
- package/dist/web/Tooltip/ProgressTooltip.mjs +22 -20
- package/dist/web/Tooltip/TooltipWrapper.js +12 -1
- package/dist/web/Tooltip/TooltipWrapper.mjs +8 -8
- package/dist/web/Tooltip/useAutoPlacement.js +41 -1
- package/dist/web/Tooltip/useAutoPlacement.mjs +34 -25
- package/dist/web.js +51 -1
- package/dist/web.mjs +49 -49
- package/package.json +1 -1
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { jsxs
|
|
2
|
-
import { useRef
|
|
3
|
-
const
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
import { jsxs, jsx, Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useRef, useEffect } from "react";
|
|
3
|
+
const STEP_DELAY = 600;
|
|
4
|
+
const STEP_INTERVAL = 200;
|
|
5
|
+
function SpinnerIcon({ className }) {
|
|
6
|
+
return /* @__PURE__ */ jsx("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", className, children: /* @__PURE__ */ jsx(
|
|
6
7
|
"path",
|
|
7
8
|
{
|
|
8
9
|
d: "M15.4573 13.6501C15.9047 13.6504 16.129 14.192 15.8128 14.5085L12.3352 17.9851C12.139 18.1811 11.8214 18.1811 11.6253 17.9851L8.14772 14.5085C7.83144 14.192 8.0558 13.6504 8.50319 13.6501H15.4573ZM11.6643 5.98311C11.8606 5.78688 12.179 5.78688 12.3753 5.98311L15.8518 9.45967C16.1683 9.77623 15.944 10.3171 15.4964 10.3171H8.54323C8.09567 10.3171 7.87154 9.77625 8.18776 9.45967L11.6643 5.98311Z",
|
|
@@ -10,55 +11,60 @@ function m({ className: t }) {
|
|
|
10
11
|
}
|
|
11
12
|
) });
|
|
12
13
|
}
|
|
13
|
-
function
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
14
|
+
function StepHandler({ icon, upDisabled, downDisabled, onStep }) {
|
|
15
|
+
const stepTimeoutRef = useRef(void 0);
|
|
16
|
+
const onStepRef = useRef(onStep);
|
|
17
|
+
onStepRef.current = onStep;
|
|
18
|
+
const onStopStep = () => clearTimeout(stepTimeoutRef.current);
|
|
19
|
+
const onStepMouseDown = (e, up) => {
|
|
20
|
+
e.preventDefault();
|
|
21
|
+
onStopStep();
|
|
22
|
+
onStepRef.current(up);
|
|
23
|
+
function loopStep() {
|
|
24
|
+
onStepRef.current(up);
|
|
25
|
+
stepTimeoutRef.current = setTimeout(loopStep, STEP_INTERVAL);
|
|
20
26
|
}
|
|
21
|
-
|
|
27
|
+
stepTimeoutRef.current = setTimeout(loopStep, STEP_DELAY);
|
|
22
28
|
};
|
|
23
|
-
|
|
24
|
-
const
|
|
29
|
+
useEffect(() => onStopStep, []);
|
|
30
|
+
const sharedProps = {
|
|
25
31
|
unselectable: "on",
|
|
26
32
|
role: "button",
|
|
27
|
-
onMouseUp:
|
|
28
|
-
onMouseLeave:
|
|
33
|
+
onMouseUp: onStopStep,
|
|
34
|
+
onMouseLeave: onStopStep
|
|
29
35
|
};
|
|
30
36
|
return (
|
|
31
37
|
// Click zones come before the icon(s) in DOM order so the icon halves
|
|
32
38
|
// can be dimmed via a `:hover ~`/`:active ~` sibling selector in CSS —
|
|
33
39
|
// the icon itself stays `pointer-events: none` and purely visual.
|
|
34
|
-
/* @__PURE__ */
|
|
35
|
-
/* @__PURE__ */
|
|
40
|
+
/* @__PURE__ */ jsxs("div", { className: "bj-input-number__handler-wrap", children: [
|
|
41
|
+
/* @__PURE__ */ jsx(
|
|
36
42
|
"span",
|
|
37
43
|
{
|
|
38
|
-
...
|
|
44
|
+
...sharedProps,
|
|
39
45
|
"aria-label": "Increase Value",
|
|
40
|
-
"aria-disabled":
|
|
41
|
-
className:
|
|
42
|
-
onMouseDown: (
|
|
46
|
+
"aria-disabled": upDisabled,
|
|
47
|
+
className: upDisabled ? "bj-input-number__handler bj-input-number__handler--up bj-input-number__handler--disabled" : "bj-input-number__handler bj-input-number__handler--up",
|
|
48
|
+
onMouseDown: (e) => onStepMouseDown(e, true)
|
|
43
49
|
}
|
|
44
50
|
),
|
|
45
|
-
/* @__PURE__ */
|
|
51
|
+
/* @__PURE__ */ jsx(
|
|
46
52
|
"span",
|
|
47
53
|
{
|
|
48
|
-
...
|
|
54
|
+
...sharedProps,
|
|
49
55
|
"aria-label": "Decrease Value",
|
|
50
|
-
"aria-disabled":
|
|
51
|
-
className:
|
|
52
|
-
onMouseDown: (
|
|
56
|
+
"aria-disabled": downDisabled,
|
|
57
|
+
className: downDisabled ? "bj-input-number__handler bj-input-number__handler--down bj-input-number__handler--disabled" : "bj-input-number__handler bj-input-number__handler--down",
|
|
58
|
+
onMouseDown: (e) => onStepMouseDown(e, false)
|
|
53
59
|
}
|
|
54
60
|
),
|
|
55
|
-
|
|
56
|
-
/* @__PURE__ */
|
|
57
|
-
/* @__PURE__ */
|
|
61
|
+
icon || /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
62
|
+
/* @__PURE__ */ jsx(SpinnerIcon, { className: "bj-input-number__handler-icon bj-input-number__handler-icon--up" }),
|
|
63
|
+
/* @__PURE__ */ jsx(SpinnerIcon, { className: "bj-input-number__handler-icon bj-input-number__handler-icon--down" })
|
|
58
64
|
] })
|
|
59
65
|
] })
|
|
60
66
|
);
|
|
61
67
|
}
|
|
62
68
|
export {
|
|
63
|
-
|
|
69
|
+
StepHandler as default
|
|
64
70
|
};
|
|
@@ -1 +1,40 @@
|
|
|
1
|
-
"use strict";
|
|
1
|
+
"use strict";
|
|
2
|
+
const react = require("react");
|
|
3
|
+
function useCursor(input, focused) {
|
|
4
|
+
const selectionRef = react.useRef(null);
|
|
5
|
+
function recordCursor() {
|
|
6
|
+
if (!input) return;
|
|
7
|
+
try {
|
|
8
|
+
const { selectionStart: start, selectionEnd: end, value } = input;
|
|
9
|
+
selectionRef.current = {
|
|
10
|
+
start: start ?? 0,
|
|
11
|
+
end: end ?? 0,
|
|
12
|
+
value,
|
|
13
|
+
beforeTxt: value.substring(0, start ?? 0),
|
|
14
|
+
afterTxt: value.substring(end ?? 0)
|
|
15
|
+
};
|
|
16
|
+
} catch {
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
function restoreCursor() {
|
|
20
|
+
if (!input || !selectionRef.current || !focused) return;
|
|
21
|
+
try {
|
|
22
|
+
const { value } = input;
|
|
23
|
+
const { beforeTxt, afterTxt, start } = selectionRef.current;
|
|
24
|
+
let startPos = value.length;
|
|
25
|
+
if (value.startsWith(beforeTxt)) {
|
|
26
|
+
startPos = beforeTxt.length;
|
|
27
|
+
} else if (value.endsWith(afterTxt)) {
|
|
28
|
+
startPos = value.length - afterTxt.length;
|
|
29
|
+
} else {
|
|
30
|
+
const beforeLastChar = beforeTxt[start - 1];
|
|
31
|
+
const newIndex = value.indexOf(beforeLastChar, start - 1);
|
|
32
|
+
if (newIndex !== -1) startPos = newIndex + 1;
|
|
33
|
+
}
|
|
34
|
+
input.setSelectionRange(startPos, startPos);
|
|
35
|
+
} catch {
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return [recordCursor, restoreCursor];
|
|
39
|
+
}
|
|
40
|
+
module.exports = useCursor;
|
|
@@ -1,39 +1,41 @@
|
|
|
1
|
-
import { useRef
|
|
2
|
-
function
|
|
3
|
-
const
|
|
4
|
-
function
|
|
5
|
-
if (
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
1
|
+
import { useRef } from "react";
|
|
2
|
+
function useCursor(input, focused) {
|
|
3
|
+
const selectionRef = useRef(null);
|
|
4
|
+
function recordCursor() {
|
|
5
|
+
if (!input) return;
|
|
6
|
+
try {
|
|
7
|
+
const { selectionStart: start, selectionEnd: end, value } = input;
|
|
8
|
+
selectionRef.current = {
|
|
9
|
+
start: start ?? 0,
|
|
10
|
+
end: end ?? 0,
|
|
11
|
+
value,
|
|
12
|
+
beforeTxt: value.substring(0, start ?? 0),
|
|
13
|
+
afterTxt: value.substring(end ?? 0)
|
|
14
|
+
};
|
|
15
|
+
} catch {
|
|
16
|
+
}
|
|
17
17
|
}
|
|
18
|
-
function
|
|
19
|
-
if (!
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
} catch {
|
|
18
|
+
function restoreCursor() {
|
|
19
|
+
if (!input || !selectionRef.current || !focused) return;
|
|
20
|
+
try {
|
|
21
|
+
const { value } = input;
|
|
22
|
+
const { beforeTxt, afterTxt, start } = selectionRef.current;
|
|
23
|
+
let startPos = value.length;
|
|
24
|
+
if (value.startsWith(beforeTxt)) {
|
|
25
|
+
startPos = beforeTxt.length;
|
|
26
|
+
} else if (value.endsWith(afterTxt)) {
|
|
27
|
+
startPos = value.length - afterTxt.length;
|
|
28
|
+
} else {
|
|
29
|
+
const beforeLastChar = beforeTxt[start - 1];
|
|
30
|
+
const newIndex = value.indexOf(beforeLastChar, start - 1);
|
|
31
|
+
if (newIndex !== -1) startPos = newIndex + 1;
|
|
33
32
|
}
|
|
33
|
+
input.setSelectionRange(startPos, startPos);
|
|
34
|
+
} catch {
|
|
35
|
+
}
|
|
34
36
|
}
|
|
35
|
-
return [
|
|
37
|
+
return [recordCursor, restoreCursor];
|
|
36
38
|
}
|
|
37
39
|
export {
|
|
38
|
-
|
|
40
|
+
useCursor as default
|
|
39
41
|
};
|
|
@@ -1 +1,12 @@
|
|
|
1
|
-
"use strict";
|
|
1
|
+
"use strict";
|
|
2
|
+
const react = require("react");
|
|
3
|
+
function useFrame() {
|
|
4
|
+
const idRef = react.useRef(0);
|
|
5
|
+
const cleanUp = () => cancelAnimationFrame(idRef.current);
|
|
6
|
+
react.useEffect(() => cleanUp, []);
|
|
7
|
+
return (callback) => {
|
|
8
|
+
cleanUp();
|
|
9
|
+
idRef.current = requestAnimationFrame(callback);
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
module.exports = useFrame;
|
|
@@ -1,10 +1,13 @@
|
|
|
1
|
-
import { useRef
|
|
2
|
-
function
|
|
3
|
-
const
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
import { useRef, useEffect } from "react";
|
|
2
|
+
function useFrame() {
|
|
3
|
+
const idRef = useRef(0);
|
|
4
|
+
const cleanUp = () => cancelAnimationFrame(idRef.current);
|
|
5
|
+
useEffect(() => cleanUp, []);
|
|
6
|
+
return (callback) => {
|
|
7
|
+
cleanUp();
|
|
8
|
+
idRef.current = requestAnimationFrame(callback);
|
|
6
9
|
};
|
|
7
10
|
}
|
|
8
11
|
export {
|
|
9
|
-
|
|
12
|
+
useFrame as default
|
|
10
13
|
};
|
|
@@ -1 +1,147 @@
|
|
|
1
|
-
"use strict";
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
function isEmptyValue(value) {
|
|
4
|
+
return !value && value !== 0 && !Number.isNaN(value) || !String(value).trim();
|
|
5
|
+
}
|
|
6
|
+
function trimNumber(numStr) {
|
|
7
|
+
let str = numStr.trim();
|
|
8
|
+
let negative = str.startsWith("-");
|
|
9
|
+
if (negative) {
|
|
10
|
+
str = str.slice(1);
|
|
11
|
+
}
|
|
12
|
+
str = str.replace(/(\.\d*[^0])0*$/, "$1").replace(/\.0*$/, "").replace(/^0+/, "");
|
|
13
|
+
if (str.startsWith(".")) {
|
|
14
|
+
str = `0${str}`;
|
|
15
|
+
}
|
|
16
|
+
const trimStr = str || "0";
|
|
17
|
+
const splitNumber = trimStr.split(".");
|
|
18
|
+
const integerStr = splitNumber[0] || "0";
|
|
19
|
+
const decimalStr = splitNumber[1] || "0";
|
|
20
|
+
if (integerStr === "0" && decimalStr === "0") {
|
|
21
|
+
negative = false;
|
|
22
|
+
}
|
|
23
|
+
const negativeStr = negative ? "-" : "";
|
|
24
|
+
return {
|
|
25
|
+
negative,
|
|
26
|
+
negativeStr,
|
|
27
|
+
trimStr,
|
|
28
|
+
integerStr,
|
|
29
|
+
decimalStr,
|
|
30
|
+
fullStr: `${negativeStr}${trimStr}`
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
function isScientificNotation(number) {
|
|
34
|
+
const str = String(number);
|
|
35
|
+
return !Number.isNaN(Number(str)) && str.includes("e");
|
|
36
|
+
}
|
|
37
|
+
function getNumberPrecision(number) {
|
|
38
|
+
const numStr = String(number);
|
|
39
|
+
if (isScientificNotation(number)) {
|
|
40
|
+
const [, exp = "0"] = numStr.toLowerCase().split("e");
|
|
41
|
+
return Math.max(0, -Number(exp));
|
|
42
|
+
}
|
|
43
|
+
return numStr.includes(".") && validateNumber(numStr) ? numStr.length - numStr.indexOf(".") - 1 : 0;
|
|
44
|
+
}
|
|
45
|
+
function num2str(number) {
|
|
46
|
+
const numStr = String(number);
|
|
47
|
+
if (isScientificNotation(number)) {
|
|
48
|
+
if (number > Number.MAX_SAFE_INTEGER) return String(Number.MAX_SAFE_INTEGER);
|
|
49
|
+
if (number < Number.MIN_SAFE_INTEGER) return String(Number.MIN_SAFE_INTEGER);
|
|
50
|
+
return trimNumber(number.toFixed(getNumberPrecision(number))).fullStr;
|
|
51
|
+
}
|
|
52
|
+
return trimNumber(numStr).fullStr;
|
|
53
|
+
}
|
|
54
|
+
function validateNumber(num) {
|
|
55
|
+
if (typeof num === "number") {
|
|
56
|
+
return !Number.isNaN(num);
|
|
57
|
+
}
|
|
58
|
+
if (!num) return false;
|
|
59
|
+
const str = String(num);
|
|
60
|
+
return /^\s*-?\d+(\.\d+)?\s*$/.test(str) || // 11.28
|
|
61
|
+
/^\s*-?\d+\.\s*$/.test(str) || // 1.
|
|
62
|
+
/^\s*-?\.\d+\s*$/.test(str);
|
|
63
|
+
}
|
|
64
|
+
class Decimal {
|
|
65
|
+
constructor(value) {
|
|
66
|
+
this.origin = "";
|
|
67
|
+
if (isEmptyValue(value)) {
|
|
68
|
+
this.empty = true;
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
this.origin = String(value);
|
|
72
|
+
this.number = Number(value);
|
|
73
|
+
}
|
|
74
|
+
negate() {
|
|
75
|
+
return new Decimal(-this.toNumber());
|
|
76
|
+
}
|
|
77
|
+
add(value) {
|
|
78
|
+
if (this.isInvalidate()) return new Decimal(value);
|
|
79
|
+
const target = Number(value);
|
|
80
|
+
if (Number.isNaN(target)) return this;
|
|
81
|
+
const number = this.number + target;
|
|
82
|
+
if (number > Number.MAX_SAFE_INTEGER) return new Decimal(Number.MAX_SAFE_INTEGER);
|
|
83
|
+
if (number < Number.MIN_SAFE_INTEGER) return new Decimal(Number.MIN_SAFE_INTEGER);
|
|
84
|
+
const maxPrecision = Math.max(getNumberPrecision(this.number), getNumberPrecision(target));
|
|
85
|
+
return new Decimal(number.toFixed(maxPrecision));
|
|
86
|
+
}
|
|
87
|
+
isEmpty() {
|
|
88
|
+
return !!this.empty;
|
|
89
|
+
}
|
|
90
|
+
isNaN() {
|
|
91
|
+
return Number.isNaN(this.number);
|
|
92
|
+
}
|
|
93
|
+
isInvalidate() {
|
|
94
|
+
return this.isEmpty() || this.isNaN();
|
|
95
|
+
}
|
|
96
|
+
equals(target) {
|
|
97
|
+
return this.toNumber() === (target == null ? void 0 : target.toNumber());
|
|
98
|
+
}
|
|
99
|
+
lessEquals(target) {
|
|
100
|
+
return this.add(target.negate().toString()).toNumber() <= 0;
|
|
101
|
+
}
|
|
102
|
+
toNumber() {
|
|
103
|
+
return this.number;
|
|
104
|
+
}
|
|
105
|
+
toString(safe = true) {
|
|
106
|
+
if (!safe) return this.origin;
|
|
107
|
+
if (this.isInvalidate()) return "";
|
|
108
|
+
return num2str(this.number);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
function getDecimal(value) {
|
|
112
|
+
return new Decimal(value);
|
|
113
|
+
}
|
|
114
|
+
function toFixed(numStr, separatorStr, precision, cutOnly = false) {
|
|
115
|
+
if (numStr === "") return "";
|
|
116
|
+
const { negativeStr, integerStr, decimalStr } = trimNumber(numStr);
|
|
117
|
+
const precisionDecimalStr = `${separatorStr}${decimalStr}`;
|
|
118
|
+
const numberWithoutDecimal = `${negativeStr}${integerStr}`;
|
|
119
|
+
if (precision !== void 0 && precision >= 0) {
|
|
120
|
+
const advancedNum = Number(decimalStr[precision]);
|
|
121
|
+
if (advancedNum >= 5 && !cutOnly) {
|
|
122
|
+
const advancedDecimal = getDecimal(numStr).add(
|
|
123
|
+
`${negativeStr}0.${"0".repeat(precision)}${10 - advancedNum}`
|
|
124
|
+
);
|
|
125
|
+
return toFixed(advancedDecimal.toString(), separatorStr, precision, cutOnly);
|
|
126
|
+
}
|
|
127
|
+
if (precision === 0) return numberWithoutDecimal;
|
|
128
|
+
return `${numberWithoutDecimal}${separatorStr}${decimalStr.padEnd(precision, "0").slice(0, precision)}`;
|
|
129
|
+
}
|
|
130
|
+
if (precisionDecimalStr === ".0") return numberWithoutDecimal;
|
|
131
|
+
return `${numberWithoutDecimal}${precisionDecimalStr}`;
|
|
132
|
+
}
|
|
133
|
+
function getDecupleSteps(step) {
|
|
134
|
+
const stepStr = typeof step === "number" ? num2str(step) : trimNumber(String(step)).fullStr;
|
|
135
|
+
const hasPoint = stepStr.includes(".");
|
|
136
|
+
if (!hasPoint) return `${step}0`;
|
|
137
|
+
return trimNumber(stepStr.replace(/(\d)\.(\d)/g, "$1$2.")).fullStr;
|
|
138
|
+
}
|
|
139
|
+
exports.Decimal = Decimal;
|
|
140
|
+
exports.getDecimal = getDecimal;
|
|
141
|
+
exports.getDecupleSteps = getDecupleSteps;
|
|
142
|
+
exports.getNumberPrecision = getNumberPrecision;
|
|
143
|
+
exports.isEmptyValue = isEmptyValue;
|
|
144
|
+
exports.num2str = num2str;
|
|
145
|
+
exports.toFixed = toFixed;
|
|
146
|
+
exports.trimNumber = trimNumber;
|
|
147
|
+
exports.validateNumber = validateNumber;
|
|
@@ -1,66 +1,86 @@
|
|
|
1
|
-
function
|
|
2
|
-
return !
|
|
1
|
+
function isEmptyValue(value) {
|
|
2
|
+
return !value && value !== 0 && !Number.isNaN(value) || !String(value).trim();
|
|
3
3
|
}
|
|
4
|
-
function
|
|
5
|
-
let
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
4
|
+
function trimNumber(numStr) {
|
|
5
|
+
let str = numStr.trim();
|
|
6
|
+
let negative = str.startsWith("-");
|
|
7
|
+
if (negative) {
|
|
8
|
+
str = str.slice(1);
|
|
9
|
+
}
|
|
10
|
+
str = str.replace(/(\.\d*[^0])0*$/, "$1").replace(/\.0*$/, "").replace(/^0+/, "");
|
|
11
|
+
if (str.startsWith(".")) {
|
|
12
|
+
str = `0${str}`;
|
|
13
|
+
}
|
|
14
|
+
const trimStr = str || "0";
|
|
15
|
+
const splitNumber = trimStr.split(".");
|
|
16
|
+
const integerStr = splitNumber[0] || "0";
|
|
17
|
+
const decimalStr = splitNumber[1] || "0";
|
|
18
|
+
if (integerStr === "0" && decimalStr === "0") {
|
|
19
|
+
negative = false;
|
|
20
|
+
}
|
|
21
|
+
const negativeStr = negative ? "-" : "";
|
|
10
22
|
return {
|
|
11
|
-
negative
|
|
12
|
-
negativeStr
|
|
13
|
-
trimStr
|
|
14
|
-
integerStr
|
|
15
|
-
decimalStr
|
|
16
|
-
fullStr: `${
|
|
23
|
+
negative,
|
|
24
|
+
negativeStr,
|
|
25
|
+
trimStr,
|
|
26
|
+
integerStr,
|
|
27
|
+
decimalStr,
|
|
28
|
+
fullStr: `${negativeStr}${trimStr}`
|
|
17
29
|
};
|
|
18
30
|
}
|
|
19
|
-
function
|
|
20
|
-
const
|
|
21
|
-
return !Number.isNaN(Number(
|
|
31
|
+
function isScientificNotation(number) {
|
|
32
|
+
const str = String(number);
|
|
33
|
+
return !Number.isNaN(Number(str)) && str.includes("e");
|
|
22
34
|
}
|
|
23
|
-
function
|
|
24
|
-
const
|
|
25
|
-
if (
|
|
26
|
-
const [,
|
|
27
|
-
return Math.max(0, -Number(
|
|
35
|
+
function getNumberPrecision(number) {
|
|
36
|
+
const numStr = String(number);
|
|
37
|
+
if (isScientificNotation(number)) {
|
|
38
|
+
const [, exp = "0"] = numStr.toLowerCase().split("e");
|
|
39
|
+
return Math.max(0, -Number(exp));
|
|
28
40
|
}
|
|
29
|
-
return
|
|
41
|
+
return numStr.includes(".") && validateNumber(numStr) ? numStr.length - numStr.indexOf(".") - 1 : 0;
|
|
30
42
|
}
|
|
31
|
-
function
|
|
32
|
-
const
|
|
33
|
-
|
|
43
|
+
function num2str(number) {
|
|
44
|
+
const numStr = String(number);
|
|
45
|
+
if (isScientificNotation(number)) {
|
|
46
|
+
if (number > Number.MAX_SAFE_INTEGER) return String(Number.MAX_SAFE_INTEGER);
|
|
47
|
+
if (number < Number.MIN_SAFE_INTEGER) return String(Number.MIN_SAFE_INTEGER);
|
|
48
|
+
return trimNumber(number.toFixed(getNumberPrecision(number))).fullStr;
|
|
49
|
+
}
|
|
50
|
+
return trimNumber(numStr).fullStr;
|
|
34
51
|
}
|
|
35
|
-
function
|
|
36
|
-
if (typeof
|
|
37
|
-
return !Number.isNaN(
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
/^\s*-?\d
|
|
42
|
-
/^\s
|
|
52
|
+
function validateNumber(num) {
|
|
53
|
+
if (typeof num === "number") {
|
|
54
|
+
return !Number.isNaN(num);
|
|
55
|
+
}
|
|
56
|
+
if (!num) return false;
|
|
57
|
+
const str = String(num);
|
|
58
|
+
return /^\s*-?\d+(\.\d+)?\s*$/.test(str) || // 11.28
|
|
59
|
+
/^\s*-?\d+\.\s*$/.test(str) || // 1.
|
|
60
|
+
/^\s*-?\.\d+\s*$/.test(str);
|
|
43
61
|
}
|
|
44
|
-
class
|
|
45
|
-
constructor(
|
|
46
|
-
|
|
47
|
-
|
|
62
|
+
class Decimal {
|
|
63
|
+
constructor(value) {
|
|
64
|
+
this.origin = "";
|
|
65
|
+
if (isEmptyValue(value)) {
|
|
66
|
+
this.empty = true;
|
|
48
67
|
return;
|
|
49
68
|
}
|
|
50
|
-
this.origin = String(
|
|
69
|
+
this.origin = String(value);
|
|
70
|
+
this.number = Number(value);
|
|
51
71
|
}
|
|
52
72
|
negate() {
|
|
53
|
-
return new
|
|
54
|
-
}
|
|
55
|
-
add(
|
|
56
|
-
if (this.isInvalidate()) return new
|
|
57
|
-
const
|
|
58
|
-
if (Number.isNaN(
|
|
59
|
-
const
|
|
60
|
-
if (
|
|
61
|
-
if (
|
|
62
|
-
const
|
|
63
|
-
return new
|
|
73
|
+
return new Decimal(-this.toNumber());
|
|
74
|
+
}
|
|
75
|
+
add(value) {
|
|
76
|
+
if (this.isInvalidate()) return new Decimal(value);
|
|
77
|
+
const target = Number(value);
|
|
78
|
+
if (Number.isNaN(target)) return this;
|
|
79
|
+
const number = this.number + target;
|
|
80
|
+
if (number > Number.MAX_SAFE_INTEGER) return new Decimal(Number.MAX_SAFE_INTEGER);
|
|
81
|
+
if (number < Number.MIN_SAFE_INTEGER) return new Decimal(Number.MIN_SAFE_INTEGER);
|
|
82
|
+
const maxPrecision = Math.max(getNumberPrecision(this.number), getNumberPrecision(target));
|
|
83
|
+
return new Decimal(number.toFixed(maxPrecision));
|
|
64
84
|
}
|
|
65
85
|
isEmpty() {
|
|
66
86
|
return !!this.empty;
|
|
@@ -71,49 +91,57 @@ class u {
|
|
|
71
91
|
isInvalidate() {
|
|
72
92
|
return this.isEmpty() || this.isNaN();
|
|
73
93
|
}
|
|
74
|
-
equals(
|
|
75
|
-
return this.toNumber() === (
|
|
94
|
+
equals(target) {
|
|
95
|
+
return this.toNumber() === (target == null ? void 0 : target.toNumber());
|
|
76
96
|
}
|
|
77
|
-
lessEquals(
|
|
78
|
-
return this.add(
|
|
97
|
+
lessEquals(target) {
|
|
98
|
+
return this.add(target.negate().toString()).toNumber() <= 0;
|
|
79
99
|
}
|
|
80
100
|
toNumber() {
|
|
81
101
|
return this.number;
|
|
82
102
|
}
|
|
83
|
-
toString(
|
|
84
|
-
|
|
103
|
+
toString(safe = true) {
|
|
104
|
+
if (!safe) return this.origin;
|
|
105
|
+
if (this.isInvalidate()) return "";
|
|
106
|
+
return num2str(this.number);
|
|
85
107
|
}
|
|
86
108
|
}
|
|
87
|
-
function
|
|
88
|
-
return new
|
|
109
|
+
function getDecimal(value) {
|
|
110
|
+
return new Decimal(value);
|
|
89
111
|
}
|
|
90
|
-
function
|
|
91
|
-
if (
|
|
92
|
-
const { negativeStr
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
112
|
+
function toFixed(numStr, separatorStr, precision, cutOnly = false) {
|
|
113
|
+
if (numStr === "") return "";
|
|
114
|
+
const { negativeStr, integerStr, decimalStr } = trimNumber(numStr);
|
|
115
|
+
const precisionDecimalStr = `${separatorStr}${decimalStr}`;
|
|
116
|
+
const numberWithoutDecimal = `${negativeStr}${integerStr}`;
|
|
117
|
+
if (precision !== void 0 && precision >= 0) {
|
|
118
|
+
const advancedNum = Number(decimalStr[precision]);
|
|
119
|
+
if (advancedNum >= 5 && !cutOnly) {
|
|
120
|
+
const advancedDecimal = getDecimal(numStr).add(
|
|
121
|
+
`${negativeStr}0.${"0".repeat(precision)}${10 - advancedNum}`
|
|
98
122
|
);
|
|
99
|
-
return
|
|
123
|
+
return toFixed(advancedDecimal.toString(), separatorStr, precision, cutOnly);
|
|
100
124
|
}
|
|
101
|
-
|
|
125
|
+
if (precision === 0) return numberWithoutDecimal;
|
|
126
|
+
return `${numberWithoutDecimal}${separatorStr}${decimalStr.padEnd(precision, "0").slice(0, precision)}`;
|
|
102
127
|
}
|
|
103
|
-
|
|
128
|
+
if (precisionDecimalStr === ".0") return numberWithoutDecimal;
|
|
129
|
+
return `${numberWithoutDecimal}${precisionDecimalStr}`;
|
|
104
130
|
}
|
|
105
|
-
function
|
|
106
|
-
const
|
|
107
|
-
|
|
131
|
+
function getDecupleSteps(step) {
|
|
132
|
+
const stepStr = typeof step === "number" ? num2str(step) : trimNumber(String(step)).fullStr;
|
|
133
|
+
const hasPoint = stepStr.includes(".");
|
|
134
|
+
if (!hasPoint) return `${step}0`;
|
|
135
|
+
return trimNumber(stepStr.replace(/(\d)\.(\d)/g, "$1$2.")).fullStr;
|
|
108
136
|
}
|
|
109
137
|
export {
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
138
|
+
Decimal,
|
|
139
|
+
getDecimal,
|
|
140
|
+
getDecupleSteps,
|
|
141
|
+
getNumberPrecision,
|
|
142
|
+
isEmptyValue,
|
|
143
|
+
num2str,
|
|
144
|
+
toFixed,
|
|
145
|
+
trimNumber,
|
|
146
|
+
validateNumber
|
|
119
147
|
};
|