@tomo-inc/tomo-ui 0.0.10 → 0.0.11
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/package.json +3 -1
- package/project.json +7 -0
- package/src/components/drawer/index.tsx +9 -0
- package/src/components/formatted-number/index.tsx +134 -0
- package/src/components/formatted-number/type.ts +5 -0
- package/src/components/index.ts +6 -0
- package/src/components/info-item/index.tsx +23 -0
- package/src/components/listbox/index.tsx +2 -0
- package/src/components/radio/index.tsx +2 -0
- package/src/components/switch/index.tsx +2 -0
- package/src/tailwind/plugin.ts +1 -4
- package/src/utils/amount.ts +58 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tomo-inc/tomo-ui",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.11",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./src/index.ts",
|
|
6
6
|
"module": "./src/index.ts",
|
|
@@ -19,6 +19,8 @@
|
|
|
19
19
|
"@heroui/react": "2.8.5",
|
|
20
20
|
"@heroui/system": "^2.4.23",
|
|
21
21
|
"@heroui/theme": "^2.4.23",
|
|
22
|
+
"bignumber.js": "^9.1.2",
|
|
23
|
+
"classnames": "^2.5.1",
|
|
22
24
|
"color": "^5.0.3",
|
|
23
25
|
"flat": "^6.0.1",
|
|
24
26
|
"framer-motion": "^11.5.6",
|
package/project.json
CHANGED
|
@@ -5,6 +5,13 @@
|
|
|
5
5
|
"projectType": "library",
|
|
6
6
|
"tags": ["scope:uikit", "type:tomo-uikit"],
|
|
7
7
|
"targets": {
|
|
8
|
+
"version:up": {
|
|
9
|
+
"executor": "nx:run-commands",
|
|
10
|
+
"options": {
|
|
11
|
+
"cwd": "uikits/tomo-ui",
|
|
12
|
+
"command": "npm version patch --no-git-tag-version"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
8
15
|
"build": {
|
|
9
16
|
"executor": "nx:run-commands",
|
|
10
17
|
"outputs": ["{projectRoot}/dist"],
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { BigNumber } from "bignumber.js";
|
|
2
|
+
import classNames from "classnames";
|
|
3
|
+
import { useMemo } from "react";
|
|
4
|
+
import { effectiveBalance, isEmpty } from "../../utils/amount";
|
|
5
|
+
import { NumberType } from "./type";
|
|
6
|
+
|
|
7
|
+
export const AdaptiveFormatted = (
|
|
8
|
+
value: string | number | undefined,
|
|
9
|
+
type: NumberType,
|
|
10
|
+
balanceIsSub?: boolean,
|
|
11
|
+
decimalSubLen?: number,
|
|
12
|
+
decimalFlag?: boolean,
|
|
13
|
+
) => {
|
|
14
|
+
BigNumber.config({
|
|
15
|
+
FORMAT: {
|
|
16
|
+
prefix: "",
|
|
17
|
+
decimalSeparator: ".",
|
|
18
|
+
groupSeparator: ",",
|
|
19
|
+
groupSize: 3,
|
|
20
|
+
secondaryGroupSize: 0,
|
|
21
|
+
fractionGroupSeparator: " ",
|
|
22
|
+
fractionGroupSize: 0,
|
|
23
|
+
suffix: "",
|
|
24
|
+
},
|
|
25
|
+
EXPONENTIAL_AT: [-18, 30],
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
const valueStr = value?.toString() || "";
|
|
29
|
+
if (isEmpty(valueStr) || !value) {
|
|
30
|
+
return {
|
|
31
|
+
formatted: "-",
|
|
32
|
+
ext: undefined,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
if (valueStr === "0") {
|
|
36
|
+
return {
|
|
37
|
+
formatted: type === NumberType.USD ? "0.00" : "0",
|
|
38
|
+
ext: undefined,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const bigValue = new BigNumber(value);
|
|
43
|
+
if (type === NumberType.USD) {
|
|
44
|
+
if (bigValue.lt(0.00001)) {
|
|
45
|
+
return {
|
|
46
|
+
formatted: "0.00001",
|
|
47
|
+
ext: undefined,
|
|
48
|
+
pre: "<",
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
if (bigValue.lt(0.000001)) {
|
|
53
|
+
return {
|
|
54
|
+
formatted: "0.000001",
|
|
55
|
+
ext: undefined,
|
|
56
|
+
pre: "<",
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const normalBalance = new BigNumber(valueStr).toString();
|
|
61
|
+
const [intPart, decimalPart] = normalBalance.split(".");
|
|
62
|
+
if (decimalPart && decimalPart.length > 1 && Number(decimalPart) > 0) {
|
|
63
|
+
const leadingZeros = decimalPart.match(/^0+/);
|
|
64
|
+
|
|
65
|
+
if (leadingZeros && leadingZeros[0].length > 4 && (type === NumberType.PRICE || balanceIsSub)) {
|
|
66
|
+
const exponent = parseInt(decimalPart).toString().substring(0, 4);
|
|
67
|
+
return {
|
|
68
|
+
formatted: `${intPart}.0{${leadingZeros[0].length}}${exponent}`,
|
|
69
|
+
ext: [intPart, leadingZeros[0].length, exponent],
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
const formatted = effectiveBalance(normalBalance, type === NumberType.USD ? 2 : 4, decimalSubLen, decimalFlag);
|
|
74
|
+
|
|
75
|
+
return {
|
|
76
|
+
formatted,
|
|
77
|
+
ext: undefined,
|
|
78
|
+
};
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
export interface FormattedNumberProps {
|
|
82
|
+
value: string | number;
|
|
83
|
+
type: NumberType;
|
|
84
|
+
className?: string;
|
|
85
|
+
subClassName?: string;
|
|
86
|
+
formatClassName?: string;
|
|
87
|
+
balanceIsSub?: boolean;
|
|
88
|
+
decimalSubLen?: number;
|
|
89
|
+
decimalFlag?: boolean;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export const FormattedNumber = ({
|
|
93
|
+
value,
|
|
94
|
+
type,
|
|
95
|
+
className,
|
|
96
|
+
subClassName,
|
|
97
|
+
formatClassName,
|
|
98
|
+
balanceIsSub,
|
|
99
|
+
decimalSubLen,
|
|
100
|
+
decimalFlag,
|
|
101
|
+
}: FormattedNumberProps) => {
|
|
102
|
+
const node = useMemo(() => {
|
|
103
|
+
const adapt = AdaptiveFormatted(value, type, balanceIsSub, decimalSubLen, decimalFlag);
|
|
104
|
+
if (adapt.ext) {
|
|
105
|
+
const ext = adapt.ext as string[];
|
|
106
|
+
return {
|
|
107
|
+
render: (
|
|
108
|
+
<span>
|
|
109
|
+
{ext[0]}.
|
|
110
|
+
<span>
|
|
111
|
+
0<sub className={subClassName}>{ext[1]}</sub>
|
|
112
|
+
{ext[2]}
|
|
113
|
+
</span>
|
|
114
|
+
</span>
|
|
115
|
+
),
|
|
116
|
+
pre: adapt.pre,
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
return {
|
|
120
|
+
render: <span className={formatClassName}>{adapt.formatted}</span>,
|
|
121
|
+
pre: adapt.pre,
|
|
122
|
+
};
|
|
123
|
+
}, [value, type, balanceIsSub, decimalSubLen, decimalFlag, formatClassName, subClassName]);
|
|
124
|
+
|
|
125
|
+
return (
|
|
126
|
+
<span className={classNames(className)}>
|
|
127
|
+
{node.pre}
|
|
128
|
+
{(type === NumberType.USD || type === NumberType.PRICE) && "$"}
|
|
129
|
+
{node.render}
|
|
130
|
+
</span>
|
|
131
|
+
);
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
export { FormattedNumber as AdaptiveNumber, NumberType };
|
package/src/components/index.ts
CHANGED
|
@@ -1,15 +1,21 @@
|
|
|
1
1
|
export * from "./button";
|
|
2
2
|
export * from "./card";
|
|
3
3
|
export * from "./chip";
|
|
4
|
+
export * from "./drawer";
|
|
5
|
+
export * from "./formatted-number";
|
|
4
6
|
export * from "./image";
|
|
7
|
+
export * from "./info-item";
|
|
5
8
|
export * from "./input";
|
|
6
9
|
export * from "./link";
|
|
10
|
+
export * from "./listbox";
|
|
7
11
|
export * from "./mfaTypeChoose";
|
|
8
12
|
export * from "./modal";
|
|
9
13
|
export * from "./passcodeInput";
|
|
10
14
|
export * from "./qr";
|
|
15
|
+
export * from "./radio";
|
|
11
16
|
export * from "./select";
|
|
12
17
|
export * from "./skeleton";
|
|
13
18
|
export * from "./spinner";
|
|
19
|
+
export * from "./switch";
|
|
14
20
|
export * from "./tabs";
|
|
15
21
|
export * from "./toast";
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export interface InfoItemProps {
|
|
2
|
+
label?: string | React.ReactNode;
|
|
3
|
+
context?: string | React.ReactNode;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
export const InfoItem = ({ label, context }: InfoItemProps) => {
|
|
7
|
+
return (
|
|
8
|
+
<div className="flex w-full items-center justify-between gap-1">
|
|
9
|
+
<div className="truncate text-xs font-normal text-default-500 ">
|
|
10
|
+
<span className="w-full opacity-100 h-auto will-change-transform transform-none">{label}</span>
|
|
11
|
+
</div>
|
|
12
|
+
<div className="text-xs font-normal text-foreground flex-1 overflow-hidden">
|
|
13
|
+
<div className="w-full flex justify-end">
|
|
14
|
+
<div className="w-fit max-w-full">
|
|
15
|
+
<span className="w-full opacity-100 h-auto will-change-transform transform-none">{context}</span>
|
|
16
|
+
</div>
|
|
17
|
+
</div>
|
|
18
|
+
</div>
|
|
19
|
+
</div>
|
|
20
|
+
);
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export { InfoItem as BaseItem };
|
package/src/tailwind/plugin.ts
CHANGED
|
@@ -46,12 +46,9 @@ export const baseConfig: HeroUIPluginConfig = {
|
|
|
46
46
|
t5: "#EEC41F",
|
|
47
47
|
} as any,
|
|
48
48
|
},
|
|
49
|
-
dark: {},
|
|
50
49
|
},
|
|
51
50
|
};
|
|
52
|
-
|
|
53
|
-
export const ThemePlugin = heroui(baseConfig) as any;
|
|
54
|
-
export default ThemePlugin;
|
|
51
|
+
export default heroui(baseConfig) as any;
|
|
55
52
|
|
|
56
53
|
// export const ThemePlugin: any = heroui({
|
|
57
54
|
// layout: {},
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { BigNumber } from "bignumber.js";
|
|
2
|
+
|
|
3
|
+
export function effectiveBalance(
|
|
4
|
+
balance: any,
|
|
5
|
+
length: number = 4,
|
|
6
|
+
decimalSubLen: number = 2,
|
|
7
|
+
decimalFlag: boolean = false,
|
|
8
|
+
) {
|
|
9
|
+
if (isNaN(parseFloat(balance))) {
|
|
10
|
+
return "0.00";
|
|
11
|
+
}
|
|
12
|
+
if (!balance || balance === "0") {
|
|
13
|
+
return 0;
|
|
14
|
+
}
|
|
15
|
+
if (balance < 1 / Math.pow(10, 6)) {
|
|
16
|
+
if (decimalFlag) {
|
|
17
|
+
return BigNumber(balance.toString()).toFixed();
|
|
18
|
+
}
|
|
19
|
+
return "0.00";
|
|
20
|
+
}
|
|
21
|
+
balance = new BigNumber(balance.toString()).toFixed();
|
|
22
|
+
if (balance.split(".").length === 1) {
|
|
23
|
+
return balance > 1000 ? `${Number(balance).toLocaleString()}.00` : `${balance}.00`;
|
|
24
|
+
}
|
|
25
|
+
const integer = balance.split(".")[0];
|
|
26
|
+
const decimal = balance.split(".")[1];
|
|
27
|
+
if (integer > 0) {
|
|
28
|
+
const str = decimal.length === 1 ? `${decimal}0` : decimal.substr(0, decimalSubLen);
|
|
29
|
+
const res = `${integer}.${str}`;
|
|
30
|
+
return Number(res) > 1000 ? `${Number(integer).toLocaleString()}.${str}` : res;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const temp: any = [];
|
|
34
|
+
let tempNum = 0;
|
|
35
|
+
let isNotZero = false;
|
|
36
|
+
for (let i = 0; i < decimal.length; i++) {
|
|
37
|
+
if (decimal[i] != "0" && !isNotZero) {
|
|
38
|
+
isNotZero = true;
|
|
39
|
+
}
|
|
40
|
+
if (isNotZero) {
|
|
41
|
+
tempNum++;
|
|
42
|
+
}
|
|
43
|
+
if (tempNum <= length) {
|
|
44
|
+
temp.push(decimal[i]);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
const res = parseFloat(`${integer}.${temp.join("")}`);
|
|
48
|
+
return res > 1000 ? `${Number(integer).toLocaleString()}.${temp.join("")}` : res;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export const isEmpty = (data: string | object) => {
|
|
52
|
+
if (data instanceof Array) {
|
|
53
|
+
return !data.length;
|
|
54
|
+
} else if (data instanceof Object) {
|
|
55
|
+
return !Object.keys(data).length;
|
|
56
|
+
}
|
|
57
|
+
return !data;
|
|
58
|
+
};
|