@uniai-fe/util-react 0.1.0
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/LICENSE +27 -0
- package/README.md +26 -0
- package/dist/chart/index.cjs +164 -0
- package/dist/chart/index.cjs.map +1 -0
- package/dist/chart/index.d.cts +46 -0
- package/dist/chart/index.d.ts +46 -0
- package/dist/chart/index.mjs +159 -0
- package/dist/chart/index.mjs.map +1 -0
- package/dist/convert/index.cjs +65 -0
- package/dist/convert/index.cjs.map +1 -0
- package/dist/convert/index.d.cts +19 -0
- package/dist/convert/index.d.ts +19 -0
- package/dist/convert/index.mjs +55 -0
- package/dist/convert/index.mjs.map +1 -0
- package/dist/file/index.cjs +47 -0
- package/dist/file/index.cjs.map +1 -0
- package/dist/file/index.d.cts +9 -0
- package/dist/file/index.d.ts +9 -0
- package/dist/file/index.mjs +40 -0
- package/dist/file/index.mjs.map +1 -0
- package/dist/index.cjs +280 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +6 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.mjs +262 -0
- package/dist/index.mjs.map +1 -0
- package/dist/match/index.cjs +33 -0
- package/dist/match/index.cjs.map +1 -0
- package/dist/match/index.d.cts +10 -0
- package/dist/match/index.d.ts +10 -0
- package/dist/match/index.mjs +27 -0
- package/dist/match/index.mjs.map +1 -0
- package/package.json +95 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 UNIAI
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
This project includes third-party software governed by additional licenses,
|
|
26
|
+
including Apache License 2.0. Refer to `THIRD_PARTY_NOTICES.md` for the full
|
|
27
|
+
text of those notices and any required attributions.
|
package/README.md
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# util / react
|
|
2
|
+
|
|
3
|
+
React 전용 텍스트/파일 유틸 모음입니다.
|
|
4
|
+
|
|
5
|
+
- `convertTextToJsx`, `convertArrayToJsx`, `convertTextToHTML` 등 텍스트를 JSX로 변환하는 헬퍼를 제공합니다.
|
|
6
|
+
- `getChartYTicks`, `getXAxisTextAttr`처럼 Recharts 기반 컴포넌트에서 재사용하는 차트 유틸(내부적으로 `recharts@^3.3.0` 타입을 참조합니다)을 포함합니다.
|
|
7
|
+
- `fileDownload`, `fileSize`와 같이 브라우저 전용 파일 유틸을 함께 제공합니다.
|
|
8
|
+
- `@uniai-fe/util-functions`와 의존성을 분리해 React 앱에서만 설치하면 되도록 구성했습니다.
|
|
9
|
+
|
|
10
|
+
## 설치
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
pnpm add @uniai-fe/util-react recharts@^3.3.0
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
> 차트 유틸을 사용하지 않는다면 `recharts` 설치는 생략해도 됩니다.
|
|
17
|
+
|
|
18
|
+
## 사용 예시
|
|
19
|
+
|
|
20
|
+
```tsx
|
|
21
|
+
import { convertTextToJsx } from "@uniai-fe/util-react";
|
|
22
|
+
|
|
23
|
+
function Content({ text }: { text: string }) {
|
|
24
|
+
return <div>{convertTextToJsx({ text, key: "article/body" })}</div>;
|
|
25
|
+
}
|
|
26
|
+
```
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var d3Array = require('d3-array');
|
|
4
|
+
|
|
5
|
+
// src/chart/index.tsx
|
|
6
|
+
var getChartYTicks = ({
|
|
7
|
+
data,
|
|
8
|
+
length,
|
|
9
|
+
pad = 0.5,
|
|
10
|
+
limitMin,
|
|
11
|
+
limitMax,
|
|
12
|
+
digit = 2,
|
|
13
|
+
outliers = false,
|
|
14
|
+
log
|
|
15
|
+
}) => {
|
|
16
|
+
if (data.length === 0 || length <= 1) return void 0;
|
|
17
|
+
if (typeof limitMin === "number" && typeof limitMax === "number")
|
|
18
|
+
return Array.from({ length: length + 1 }).map(
|
|
19
|
+
(_, index) => Math.round((limitMax - limitMin) / length * index + limitMin)
|
|
20
|
+
);
|
|
21
|
+
const dataSet = [];
|
|
22
|
+
data.forEach((d) => {
|
|
23
|
+
if (typeof d !== "number" && typeof d !== "string" && !(typeof d === "object" && d !== null && "value" in d))
|
|
24
|
+
return;
|
|
25
|
+
if (typeof d === "number") dataSet.push(d);
|
|
26
|
+
else if (typeof d === "string" && !isNaN(Number(d)))
|
|
27
|
+
dataSet.push(Number(d));
|
|
28
|
+
else if (typeof d === "object" && d !== null && "value" in d && typeof d.value === "number")
|
|
29
|
+
dataSet.push(d.value);
|
|
30
|
+
});
|
|
31
|
+
if (dataSet.length === 0) return void 0;
|
|
32
|
+
let domain = d3Array.extent(dataSet);
|
|
33
|
+
if (typeof limitMin === "number") domain = [limitMin, domain[1]];
|
|
34
|
+
if (typeof limitMax === "number") domain = [domain[0], limitMax];
|
|
35
|
+
if (typeof domain[0] === "undefined" || typeof domain[1] === "undefined")
|
|
36
|
+
return void 0;
|
|
37
|
+
const isAllDecimal = dataSet.every(
|
|
38
|
+
(v) => typeof digit === "number" && digit > 0 || String(v).split(".").filter((_, index) => index === 1).filter(Boolean).filter((f) => f.split("").some((s) => s !== "0")).length > 0
|
|
39
|
+
);
|
|
40
|
+
const DECIMAL_LIMIT = typeof digit === "number" ? digit : 2;
|
|
41
|
+
const floor = (domain[0] + 1e-3 * domain[0]) * Math.pow(10, DECIMAL_LIMIT);
|
|
42
|
+
const ceil = (domain[1] + 1e-3 * domain[1]) * Math.pow(10, DECIMAL_LIMIT);
|
|
43
|
+
const interval = (ceil - floor) / length;
|
|
44
|
+
const ticks = [];
|
|
45
|
+
for (let i = 0; i < length + 1; i++)
|
|
46
|
+
ticks.push((floor + i * interval) / Math.pow(10, DECIMAL_LIMIT));
|
|
47
|
+
const [firstTick] = ticks;
|
|
48
|
+
const lastTick = ticks[ticks.length - 1];
|
|
49
|
+
if (typeof firstTick === "undefined" || typeof lastTick === "undefined")
|
|
50
|
+
return void 0;
|
|
51
|
+
const gap = Math.abs(lastTick - firstTick);
|
|
52
|
+
const precision = typeof digit === "number" ? digit : gap < 1 ? 3 : gap < 10 && isAllDecimal ? 2 : gap < 25 ? 1 : 0;
|
|
53
|
+
const ticksArr = ticks.map(
|
|
54
|
+
(tick) => Number((tick + Number.EPSILON).toFixed(precision))
|
|
55
|
+
);
|
|
56
|
+
if (log) {
|
|
57
|
+
const MAX_LENGTH = 8;
|
|
58
|
+
const top = ticksArr[ticksArr.length - 1];
|
|
59
|
+
const bottom = ticksArr[0];
|
|
60
|
+
const domainRange = typeof top === "number" && typeof bottom === "number" ? top - bottom : 0;
|
|
61
|
+
const logScale = domainRange > 0 ? Math.round(Math.log2(domainRange)) : 0;
|
|
62
|
+
if (ticksArr.length > MAX_LENGTH) {
|
|
63
|
+
const step = Math.ceil(ticksArr.length / MAX_LENGTH);
|
|
64
|
+
return ticksArr.filter((_, index) => index % step === 0);
|
|
65
|
+
}
|
|
66
|
+
if (logScale > 0) {
|
|
67
|
+
const step = Math.max(1, Math.floor(MAX_LENGTH / logScale));
|
|
68
|
+
return ticksArr.filter((_, index) => index % step === 0);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
if (pad === 0) return ticksArr;
|
|
72
|
+
const isPowTen = ticksArr.every((t) => {
|
|
73
|
+
const v = Math.abs(t);
|
|
74
|
+
return v === 0 || Number.isInteger(Math.log10(v));
|
|
75
|
+
});
|
|
76
|
+
const [tickMin] = ticksArr;
|
|
77
|
+
const tickMax = ticksArr[ticksArr.length - 1];
|
|
78
|
+
const quantiles = d3Array.extent(dataSet);
|
|
79
|
+
let [min, max] = quantiles;
|
|
80
|
+
if (typeof min === "undefined" || typeof max === "undefined")
|
|
81
|
+
return ticksArr;
|
|
82
|
+
if (outliers)
|
|
83
|
+
[min, max] = [
|
|
84
|
+
d3Array.quantile(dataSet, 0.4) ?? min,
|
|
85
|
+
d3Array.quantile(dataSet, 0.6) ?? max
|
|
86
|
+
];
|
|
87
|
+
if (pad > 0) {
|
|
88
|
+
const SCALE = typeof max === "number" && typeof min === "number" ? Math.max(Math.abs(max), Math.abs(min)) : 0;
|
|
89
|
+
const OFFSET = SCALE < 10 && isPowTen ? 0.5 : SCALE < 100 && isPowTen ? 5 : SCALE < 1e3 && isPowTen ? 50 : Math.round((max - min) / ticksArr.length);
|
|
90
|
+
if (typeof tickMax === "number")
|
|
91
|
+
ticksArr[ticksArr.length - 1] = Math.round(
|
|
92
|
+
tickMax + OFFSET * pad + Number.EPSILON
|
|
93
|
+
);
|
|
94
|
+
if (typeof tickMin === "number")
|
|
95
|
+
ticksArr[0] = Math.round(tickMin - OFFSET * pad - Number.EPSILON);
|
|
96
|
+
}
|
|
97
|
+
const bad = ticksArr.some((tick, index) => {
|
|
98
|
+
if (index === 0) return false;
|
|
99
|
+
const prev = ticksArr[index - 1];
|
|
100
|
+
const d = Math.abs(tick - prev);
|
|
101
|
+
if (typeof digit === "number" && digit < 1 && String(d).includes("."))
|
|
102
|
+
return false;
|
|
103
|
+
return d !== 1 && d !== 5 && d !== 0;
|
|
104
|
+
});
|
|
105
|
+
if (bad && pad !== 0) {
|
|
106
|
+
return getChartYTicks({
|
|
107
|
+
data,
|
|
108
|
+
length,
|
|
109
|
+
pad: 0,
|
|
110
|
+
limitMin,
|
|
111
|
+
limitMax,
|
|
112
|
+
digit,
|
|
113
|
+
outliers,
|
|
114
|
+
log
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
return ticksArr;
|
|
118
|
+
};
|
|
119
|
+
var getDecimalIndex = (v) => !isNaN(Number(v)) && String(v).includes(".") ? String(v).split(".")[1].split("").findIndex((d) => Number(d) !== 0) + 1 : 0;
|
|
120
|
+
var getDomainLimit = ({
|
|
121
|
+
value,
|
|
122
|
+
gap,
|
|
123
|
+
min,
|
|
124
|
+
max
|
|
125
|
+
}) => {
|
|
126
|
+
if (typeof value === "number" && !isNaN(value)) {
|
|
127
|
+
const limit = value + gap;
|
|
128
|
+
if (typeof min === "number" && limit < min) return min;
|
|
129
|
+
if (typeof max === "number" && limit > max) return max;
|
|
130
|
+
return limit;
|
|
131
|
+
}
|
|
132
|
+
return value ?? "";
|
|
133
|
+
};
|
|
134
|
+
var getXAxisTextAttr = (props) => {
|
|
135
|
+
const {
|
|
136
|
+
width,
|
|
137
|
+
height,
|
|
138
|
+
x,
|
|
139
|
+
y,
|
|
140
|
+
stroke,
|
|
141
|
+
fill,
|
|
142
|
+
orientation,
|
|
143
|
+
textAnchor,
|
|
144
|
+
transform
|
|
145
|
+
} = props;
|
|
146
|
+
return {
|
|
147
|
+
width,
|
|
148
|
+
height,
|
|
149
|
+
x,
|
|
150
|
+
y,
|
|
151
|
+
stroke,
|
|
152
|
+
fill,
|
|
153
|
+
textAnchor,
|
|
154
|
+
orientation,
|
|
155
|
+
transform
|
|
156
|
+
};
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
exports.getChartYTicks = getChartYTicks;
|
|
160
|
+
exports.getDecimalIndex = getDecimalIndex;
|
|
161
|
+
exports.getDomainLimit = getDomainLimit;
|
|
162
|
+
exports.getXAxisTextAttr = getXAxisTextAttr;
|
|
163
|
+
//# sourceMappingURL=index.cjs.map
|
|
164
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/chart/index.tsx"],"names":["extent","quantile"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { SVGAttributes } from \"react\";\nimport { extent, quantile } from \"d3-array\";\nimport type {\n GetChartYTicksProps,\n RechartsXAxisTickPayload,\n RechartsXAxisTickProps,\n} from \"./types\";\n\nexport const getChartYTicks = ({\n data,\n length,\n pad = 0.5,\n limitMin,\n limitMax,\n digit = 2,\n outliers = false,\n log,\n}: GetChartYTicksProps): number[] | undefined => {\n if (data.length === 0 || length <= 1) return undefined;\n if (typeof limitMin === \"number\" && typeof limitMax === \"number\")\n return Array.from({ length: length + 1 }).map((_, index) =>\n Math.round(((limitMax - limitMin) / length) * index + limitMin),\n );\n\n const dataSet: number[] = [];\n\n data.forEach(d => {\n if (\n typeof d !== \"number\" &&\n typeof d !== \"string\" &&\n !(typeof d === \"object\" && d !== null && \"value\" in d)\n )\n return;\n\n if (typeof d === \"number\") dataSet.push(d);\n else if (typeof d === \"string\" && !isNaN(Number(d)))\n dataSet.push(Number(d));\n else if (\n typeof d === \"object\" &&\n d !== null &&\n \"value\" in d &&\n typeof (d as { value: unknown }).value === \"number\"\n )\n dataSet.push((d as { value: number }).value);\n });\n\n if (dataSet.length === 0) return undefined;\n\n let domain = extent(dataSet) as [number | undefined, number | undefined];\n if (typeof limitMin === \"number\") domain = [limitMin, domain[1]];\n if (typeof limitMax === \"number\") domain = [domain[0], limitMax];\n\n if (typeof domain[0] === \"undefined\" || typeof domain[1] === \"undefined\")\n return undefined;\n\n const isAllDecimal = dataSet.every(\n v =>\n (typeof digit === \"number\" && digit > 0) ||\n String(v)\n .split(\".\")\n .filter((_, index) => index === 1)\n .filter(Boolean)\n .filter(f => f.split(\"\").some(s => s !== \"0\")).length > 0,\n );\n\n const DECIMAL_LIMIT = typeof digit === \"number\" ? digit : 2;\n\n const floor = (domain[0] + 0.001 * domain[0]) * Math.pow(10, DECIMAL_LIMIT);\n const ceil = (domain[1] + 0.001 * domain[1]) * Math.pow(10, DECIMAL_LIMIT);\n const interval = (ceil - floor) / length;\n\n const ticks: number[] = [];\n for (let i = 0; i < length + 1; i++)\n ticks.push((floor + i * interval) / Math.pow(10, DECIMAL_LIMIT));\n\n const [firstTick] = ticks;\n const lastTick = ticks[ticks.length - 1];\n if (typeof firstTick === \"undefined\" || typeof lastTick === \"undefined\")\n return undefined;\n\n const gap = Math.abs(lastTick - firstTick);\n const precision =\n typeof digit === \"number\"\n ? digit\n : gap < 1\n ? 3\n : gap < 10 && isAllDecimal\n ? 2\n : gap < 25\n ? 1\n : 0;\n\n const ticksArr = ticks.map(tick =>\n Number((tick + Number.EPSILON).toFixed(precision)),\n );\n\n if (log) {\n const MAX_LENGTH = 8;\n const top = ticksArr[ticksArr.length - 1];\n const bottom = ticksArr[0];\n const domainRange =\n typeof top === \"number\" && typeof bottom === \"number\"\n ? top - bottom\n : 0;\n const logScale =\n domainRange > 0 ? Math.round(Math.log2(domainRange)) : 0;\n\n if (ticksArr.length > MAX_LENGTH) {\n const step = Math.ceil(ticksArr.length / MAX_LENGTH);\n return ticksArr.filter((_, index) => index % step === 0);\n }\n\n if (logScale > 0) {\n const step = Math.max(1, Math.floor(MAX_LENGTH / logScale));\n return ticksArr.filter((_, index) => index % step === 0);\n }\n }\n\n if (pad === 0) return ticksArr;\n\n const isPowTen = ticksArr.every(t => {\n const v = Math.abs(t);\n return v === 0 || Number.isInteger(Math.log10(v));\n });\n\n const [tickMin] = ticksArr;\n const tickMax = ticksArr[ticksArr.length - 1];\n\n const quantiles = extent(dataSet);\n let [min, max] = quantiles;\n if (typeof min === \"undefined\" || typeof max === \"undefined\")\n return ticksArr;\n\n if (outliers)\n [min, max] = [\n quantile(dataSet, 0.4) ?? min,\n quantile(dataSet, 0.6) ?? max,\n ];\n\n if (pad > 0) {\n const SCALE =\n typeof max === \"number\" && typeof min === \"number\"\n ? Math.max(Math.abs(max), Math.abs(min))\n : 0;\n const OFFSET =\n SCALE < 10 && isPowTen\n ? 0.5\n : SCALE < 100 && isPowTen\n ? 5\n : SCALE < 1000 && isPowTen\n ? 50\n : Math.round((max - min) / ticksArr.length);\n\n if (typeof tickMax === \"number\")\n ticksArr[ticksArr.length - 1] = Math.round(\n tickMax + OFFSET * pad + Number.EPSILON,\n );\n if (typeof tickMin === \"number\")\n ticksArr[0] = Math.round(tickMin - OFFSET * pad - Number.EPSILON);\n }\n\n const bad = ticksArr.some((tick, index) => {\n if (index === 0) return false;\n const prev = ticksArr[index - 1];\n const d = Math.abs(tick - prev);\n if (\n typeof digit === \"number\" &&\n digit < 1 &&\n String(d).includes(\".\")\n )\n return false;\n\n return d !== 1 && d !== 5 && d !== 0;\n });\n\n if (bad && pad !== 0) {\n return getChartYTicks({\n data,\n length,\n pad: 0,\n limitMin,\n limitMax,\n digit,\n outliers,\n log,\n });\n }\n\n return ticksArr;\n};\n\nexport const getDecimalIndex = (v: unknown): number =>\n !isNaN(Number(v)) && String(v).includes(\".\")\n ? String(v)\n .split(\".\")[1]\n .split(\"\")\n .findIndex(d => Number(d) !== 0) + 1\n : 0;\n\nexport const getDomainLimit = ({\n value,\n gap,\n min,\n max,\n}: {\n value: number | null;\n gap: number;\n min?: number;\n max?: number;\n}): number | string => {\n if (typeof value === \"number\" && !isNaN(value)) {\n const limit = value + gap;\n if (typeof min === \"number\" && limit < min) return min;\n if (typeof max === \"number\" && limit > max) return max;\n return limit;\n }\n return value ?? \"\";\n};\n\nexport const getXAxisTextAttr = (\n props: RechartsXAxisTickProps,\n): SVGAttributes<SVGTextElement> => {\n const {\n width,\n height,\n x,\n y,\n stroke,\n fill,\n orientation,\n textAnchor,\n transform,\n } = props;\n\n return {\n width,\n height,\n x,\n y,\n stroke,\n fill,\n textAnchor,\n orientation,\n transform,\n };\n};\n"]}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { SVGAttributes } from 'react';
|
|
2
|
+
import { XAxisProps } from 'recharts';
|
|
3
|
+
|
|
4
|
+
type GetChartYTicksProps = {
|
|
5
|
+
data: unknown[];
|
|
6
|
+
length: number;
|
|
7
|
+
} & Partial<{
|
|
8
|
+
pad: number;
|
|
9
|
+
limitMin: number;
|
|
10
|
+
limitMax: number;
|
|
11
|
+
log: boolean;
|
|
12
|
+
digit: number;
|
|
13
|
+
outliers: boolean;
|
|
14
|
+
yTickWidth: number;
|
|
15
|
+
}>;
|
|
16
|
+
type RechartsXAxisTickPayload = {
|
|
17
|
+
coordinate: number;
|
|
18
|
+
value: number | string | null;
|
|
19
|
+
index: number;
|
|
20
|
+
offset: number;
|
|
21
|
+
tickCoord: number;
|
|
22
|
+
isShow: boolean;
|
|
23
|
+
};
|
|
24
|
+
type TickLayoutProps = Partial<Record<"width" | "height" | "x" | "y", number | string | undefined>> & Partial<{
|
|
25
|
+
stroke: string;
|
|
26
|
+
fill: string;
|
|
27
|
+
textAnchor: "start" | "middle" | "end" | "inherit";
|
|
28
|
+
transform: string;
|
|
29
|
+
}>;
|
|
30
|
+
type RechartsXAxisTickProps = XAxisProps & TickLayoutProps & {
|
|
31
|
+
verticalAnchor: "start" | "middle" | "end";
|
|
32
|
+
index: number;
|
|
33
|
+
payload: RechartsXAxisTickPayload;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
declare const getChartYTicks: ({ data, length, pad, limitMin, limitMax, digit, outliers, log, }: GetChartYTicksProps) => number[] | undefined;
|
|
37
|
+
declare const getDecimalIndex: (v: unknown) => number;
|
|
38
|
+
declare const getDomainLimit: ({ value, gap, min, max, }: {
|
|
39
|
+
value: number | null;
|
|
40
|
+
gap: number;
|
|
41
|
+
min?: number;
|
|
42
|
+
max?: number;
|
|
43
|
+
}) => number | string;
|
|
44
|
+
declare const getXAxisTextAttr: (props: RechartsXAxisTickProps) => SVGAttributes<SVGTextElement>;
|
|
45
|
+
|
|
46
|
+
export { getChartYTicks, getDecimalIndex, getDomainLimit, getXAxisTextAttr };
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { SVGAttributes } from 'react';
|
|
2
|
+
import { XAxisProps } from 'recharts';
|
|
3
|
+
|
|
4
|
+
type GetChartYTicksProps = {
|
|
5
|
+
data: unknown[];
|
|
6
|
+
length: number;
|
|
7
|
+
} & Partial<{
|
|
8
|
+
pad: number;
|
|
9
|
+
limitMin: number;
|
|
10
|
+
limitMax: number;
|
|
11
|
+
log: boolean;
|
|
12
|
+
digit: number;
|
|
13
|
+
outliers: boolean;
|
|
14
|
+
yTickWidth: number;
|
|
15
|
+
}>;
|
|
16
|
+
type RechartsXAxisTickPayload = {
|
|
17
|
+
coordinate: number;
|
|
18
|
+
value: number | string | null;
|
|
19
|
+
index: number;
|
|
20
|
+
offset: number;
|
|
21
|
+
tickCoord: number;
|
|
22
|
+
isShow: boolean;
|
|
23
|
+
};
|
|
24
|
+
type TickLayoutProps = Partial<Record<"width" | "height" | "x" | "y", number | string | undefined>> & Partial<{
|
|
25
|
+
stroke: string;
|
|
26
|
+
fill: string;
|
|
27
|
+
textAnchor: "start" | "middle" | "end" | "inherit";
|
|
28
|
+
transform: string;
|
|
29
|
+
}>;
|
|
30
|
+
type RechartsXAxisTickProps = XAxisProps & TickLayoutProps & {
|
|
31
|
+
verticalAnchor: "start" | "middle" | "end";
|
|
32
|
+
index: number;
|
|
33
|
+
payload: RechartsXAxisTickPayload;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
declare const getChartYTicks: ({ data, length, pad, limitMin, limitMax, digit, outliers, log, }: GetChartYTicksProps) => number[] | undefined;
|
|
37
|
+
declare const getDecimalIndex: (v: unknown) => number;
|
|
38
|
+
declare const getDomainLimit: ({ value, gap, min, max, }: {
|
|
39
|
+
value: number | null;
|
|
40
|
+
gap: number;
|
|
41
|
+
min?: number;
|
|
42
|
+
max?: number;
|
|
43
|
+
}) => number | string;
|
|
44
|
+
declare const getXAxisTextAttr: (props: RechartsXAxisTickProps) => SVGAttributes<SVGTextElement>;
|
|
45
|
+
|
|
46
|
+
export { getChartYTicks, getDecimalIndex, getDomainLimit, getXAxisTextAttr };
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import { extent, quantile } from 'd3-array';
|
|
2
|
+
|
|
3
|
+
// src/chart/index.tsx
|
|
4
|
+
var getChartYTicks = ({
|
|
5
|
+
data,
|
|
6
|
+
length,
|
|
7
|
+
pad = 0.5,
|
|
8
|
+
limitMin,
|
|
9
|
+
limitMax,
|
|
10
|
+
digit = 2,
|
|
11
|
+
outliers = false,
|
|
12
|
+
log
|
|
13
|
+
}) => {
|
|
14
|
+
if (data.length === 0 || length <= 1) return void 0;
|
|
15
|
+
if (typeof limitMin === "number" && typeof limitMax === "number")
|
|
16
|
+
return Array.from({ length: length + 1 }).map(
|
|
17
|
+
(_, index) => Math.round((limitMax - limitMin) / length * index + limitMin)
|
|
18
|
+
);
|
|
19
|
+
const dataSet = [];
|
|
20
|
+
data.forEach((d) => {
|
|
21
|
+
if (typeof d !== "number" && typeof d !== "string" && !(typeof d === "object" && d !== null && "value" in d))
|
|
22
|
+
return;
|
|
23
|
+
if (typeof d === "number") dataSet.push(d);
|
|
24
|
+
else if (typeof d === "string" && !isNaN(Number(d)))
|
|
25
|
+
dataSet.push(Number(d));
|
|
26
|
+
else if (typeof d === "object" && d !== null && "value" in d && typeof d.value === "number")
|
|
27
|
+
dataSet.push(d.value);
|
|
28
|
+
});
|
|
29
|
+
if (dataSet.length === 0) return void 0;
|
|
30
|
+
let domain = extent(dataSet);
|
|
31
|
+
if (typeof limitMin === "number") domain = [limitMin, domain[1]];
|
|
32
|
+
if (typeof limitMax === "number") domain = [domain[0], limitMax];
|
|
33
|
+
if (typeof domain[0] === "undefined" || typeof domain[1] === "undefined")
|
|
34
|
+
return void 0;
|
|
35
|
+
const isAllDecimal = dataSet.every(
|
|
36
|
+
(v) => typeof digit === "number" && digit > 0 || String(v).split(".").filter((_, index) => index === 1).filter(Boolean).filter((f) => f.split("").some((s) => s !== "0")).length > 0
|
|
37
|
+
);
|
|
38
|
+
const DECIMAL_LIMIT = typeof digit === "number" ? digit : 2;
|
|
39
|
+
const floor = (domain[0] + 1e-3 * domain[0]) * Math.pow(10, DECIMAL_LIMIT);
|
|
40
|
+
const ceil = (domain[1] + 1e-3 * domain[1]) * Math.pow(10, DECIMAL_LIMIT);
|
|
41
|
+
const interval = (ceil - floor) / length;
|
|
42
|
+
const ticks = [];
|
|
43
|
+
for (let i = 0; i < length + 1; i++)
|
|
44
|
+
ticks.push((floor + i * interval) / Math.pow(10, DECIMAL_LIMIT));
|
|
45
|
+
const [firstTick] = ticks;
|
|
46
|
+
const lastTick = ticks[ticks.length - 1];
|
|
47
|
+
if (typeof firstTick === "undefined" || typeof lastTick === "undefined")
|
|
48
|
+
return void 0;
|
|
49
|
+
const gap = Math.abs(lastTick - firstTick);
|
|
50
|
+
const precision = typeof digit === "number" ? digit : gap < 1 ? 3 : gap < 10 && isAllDecimal ? 2 : gap < 25 ? 1 : 0;
|
|
51
|
+
const ticksArr = ticks.map(
|
|
52
|
+
(tick) => Number((tick + Number.EPSILON).toFixed(precision))
|
|
53
|
+
);
|
|
54
|
+
if (log) {
|
|
55
|
+
const MAX_LENGTH = 8;
|
|
56
|
+
const top = ticksArr[ticksArr.length - 1];
|
|
57
|
+
const bottom = ticksArr[0];
|
|
58
|
+
const domainRange = typeof top === "number" && typeof bottom === "number" ? top - bottom : 0;
|
|
59
|
+
const logScale = domainRange > 0 ? Math.round(Math.log2(domainRange)) : 0;
|
|
60
|
+
if (ticksArr.length > MAX_LENGTH) {
|
|
61
|
+
const step = Math.ceil(ticksArr.length / MAX_LENGTH);
|
|
62
|
+
return ticksArr.filter((_, index) => index % step === 0);
|
|
63
|
+
}
|
|
64
|
+
if (logScale > 0) {
|
|
65
|
+
const step = Math.max(1, Math.floor(MAX_LENGTH / logScale));
|
|
66
|
+
return ticksArr.filter((_, index) => index % step === 0);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
if (pad === 0) return ticksArr;
|
|
70
|
+
const isPowTen = ticksArr.every((t) => {
|
|
71
|
+
const v = Math.abs(t);
|
|
72
|
+
return v === 0 || Number.isInteger(Math.log10(v));
|
|
73
|
+
});
|
|
74
|
+
const [tickMin] = ticksArr;
|
|
75
|
+
const tickMax = ticksArr[ticksArr.length - 1];
|
|
76
|
+
const quantiles = extent(dataSet);
|
|
77
|
+
let [min, max] = quantiles;
|
|
78
|
+
if (typeof min === "undefined" || typeof max === "undefined")
|
|
79
|
+
return ticksArr;
|
|
80
|
+
if (outliers)
|
|
81
|
+
[min, max] = [
|
|
82
|
+
quantile(dataSet, 0.4) ?? min,
|
|
83
|
+
quantile(dataSet, 0.6) ?? max
|
|
84
|
+
];
|
|
85
|
+
if (pad > 0) {
|
|
86
|
+
const SCALE = typeof max === "number" && typeof min === "number" ? Math.max(Math.abs(max), Math.abs(min)) : 0;
|
|
87
|
+
const OFFSET = SCALE < 10 && isPowTen ? 0.5 : SCALE < 100 && isPowTen ? 5 : SCALE < 1e3 && isPowTen ? 50 : Math.round((max - min) / ticksArr.length);
|
|
88
|
+
if (typeof tickMax === "number")
|
|
89
|
+
ticksArr[ticksArr.length - 1] = Math.round(
|
|
90
|
+
tickMax + OFFSET * pad + Number.EPSILON
|
|
91
|
+
);
|
|
92
|
+
if (typeof tickMin === "number")
|
|
93
|
+
ticksArr[0] = Math.round(tickMin - OFFSET * pad - Number.EPSILON);
|
|
94
|
+
}
|
|
95
|
+
const bad = ticksArr.some((tick, index) => {
|
|
96
|
+
if (index === 0) return false;
|
|
97
|
+
const prev = ticksArr[index - 1];
|
|
98
|
+
const d = Math.abs(tick - prev);
|
|
99
|
+
if (typeof digit === "number" && digit < 1 && String(d).includes("."))
|
|
100
|
+
return false;
|
|
101
|
+
return d !== 1 && d !== 5 && d !== 0;
|
|
102
|
+
});
|
|
103
|
+
if (bad && pad !== 0) {
|
|
104
|
+
return getChartYTicks({
|
|
105
|
+
data,
|
|
106
|
+
length,
|
|
107
|
+
pad: 0,
|
|
108
|
+
limitMin,
|
|
109
|
+
limitMax,
|
|
110
|
+
digit,
|
|
111
|
+
outliers,
|
|
112
|
+
log
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
return ticksArr;
|
|
116
|
+
};
|
|
117
|
+
var getDecimalIndex = (v) => !isNaN(Number(v)) && String(v).includes(".") ? String(v).split(".")[1].split("").findIndex((d) => Number(d) !== 0) + 1 : 0;
|
|
118
|
+
var getDomainLimit = ({
|
|
119
|
+
value,
|
|
120
|
+
gap,
|
|
121
|
+
min,
|
|
122
|
+
max
|
|
123
|
+
}) => {
|
|
124
|
+
if (typeof value === "number" && !isNaN(value)) {
|
|
125
|
+
const limit = value + gap;
|
|
126
|
+
if (typeof min === "number" && limit < min) return min;
|
|
127
|
+
if (typeof max === "number" && limit > max) return max;
|
|
128
|
+
return limit;
|
|
129
|
+
}
|
|
130
|
+
return value ?? "";
|
|
131
|
+
};
|
|
132
|
+
var getXAxisTextAttr = (props) => {
|
|
133
|
+
const {
|
|
134
|
+
width,
|
|
135
|
+
height,
|
|
136
|
+
x,
|
|
137
|
+
y,
|
|
138
|
+
stroke,
|
|
139
|
+
fill,
|
|
140
|
+
orientation,
|
|
141
|
+
textAnchor,
|
|
142
|
+
transform
|
|
143
|
+
} = props;
|
|
144
|
+
return {
|
|
145
|
+
width,
|
|
146
|
+
height,
|
|
147
|
+
x,
|
|
148
|
+
y,
|
|
149
|
+
stroke,
|
|
150
|
+
fill,
|
|
151
|
+
textAnchor,
|
|
152
|
+
orientation,
|
|
153
|
+
transform
|
|
154
|
+
};
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
export { getChartYTicks, getDecimalIndex, getDomainLimit, getXAxisTextAttr };
|
|
158
|
+
//# sourceMappingURL=index.mjs.map
|
|
159
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/chart/index.tsx"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["import type { SVGAttributes } from \"react\";\nimport { extent, quantile } from \"d3-array\";\nimport type {\n GetChartYTicksProps,\n RechartsXAxisTickPayload,\n RechartsXAxisTickProps,\n} from \"./types\";\n\nexport const getChartYTicks = ({\n data,\n length,\n pad = 0.5,\n limitMin,\n limitMax,\n digit = 2,\n outliers = false,\n log,\n}: GetChartYTicksProps): number[] | undefined => {\n if (data.length === 0 || length <= 1) return undefined;\n if (typeof limitMin === \"number\" && typeof limitMax === \"number\")\n return Array.from({ length: length + 1 }).map((_, index) =>\n Math.round(((limitMax - limitMin) / length) * index + limitMin),\n );\n\n const dataSet: number[] = [];\n\n data.forEach(d => {\n if (\n typeof d !== \"number\" &&\n typeof d !== \"string\" &&\n !(typeof d === \"object\" && d !== null && \"value\" in d)\n )\n return;\n\n if (typeof d === \"number\") dataSet.push(d);\n else if (typeof d === \"string\" && !isNaN(Number(d)))\n dataSet.push(Number(d));\n else if (\n typeof d === \"object\" &&\n d !== null &&\n \"value\" in d &&\n typeof (d as { value: unknown }).value === \"number\"\n )\n dataSet.push((d as { value: number }).value);\n });\n\n if (dataSet.length === 0) return undefined;\n\n let domain = extent(dataSet) as [number | undefined, number | undefined];\n if (typeof limitMin === \"number\") domain = [limitMin, domain[1]];\n if (typeof limitMax === \"number\") domain = [domain[0], limitMax];\n\n if (typeof domain[0] === \"undefined\" || typeof domain[1] === \"undefined\")\n return undefined;\n\n const isAllDecimal = dataSet.every(\n v =>\n (typeof digit === \"number\" && digit > 0) ||\n String(v)\n .split(\".\")\n .filter((_, index) => index === 1)\n .filter(Boolean)\n .filter(f => f.split(\"\").some(s => s !== \"0\")).length > 0,\n );\n\n const DECIMAL_LIMIT = typeof digit === \"number\" ? digit : 2;\n\n const floor = (domain[0] + 0.001 * domain[0]) * Math.pow(10, DECIMAL_LIMIT);\n const ceil = (domain[1] + 0.001 * domain[1]) * Math.pow(10, DECIMAL_LIMIT);\n const interval = (ceil - floor) / length;\n\n const ticks: number[] = [];\n for (let i = 0; i < length + 1; i++)\n ticks.push((floor + i * interval) / Math.pow(10, DECIMAL_LIMIT));\n\n const [firstTick] = ticks;\n const lastTick = ticks[ticks.length - 1];\n if (typeof firstTick === \"undefined\" || typeof lastTick === \"undefined\")\n return undefined;\n\n const gap = Math.abs(lastTick - firstTick);\n const precision =\n typeof digit === \"number\"\n ? digit\n : gap < 1\n ? 3\n : gap < 10 && isAllDecimal\n ? 2\n : gap < 25\n ? 1\n : 0;\n\n const ticksArr = ticks.map(tick =>\n Number((tick + Number.EPSILON).toFixed(precision)),\n );\n\n if (log) {\n const MAX_LENGTH = 8;\n const top = ticksArr[ticksArr.length - 1];\n const bottom = ticksArr[0];\n const domainRange =\n typeof top === \"number\" && typeof bottom === \"number\"\n ? top - bottom\n : 0;\n const logScale =\n domainRange > 0 ? Math.round(Math.log2(domainRange)) : 0;\n\n if (ticksArr.length > MAX_LENGTH) {\n const step = Math.ceil(ticksArr.length / MAX_LENGTH);\n return ticksArr.filter((_, index) => index % step === 0);\n }\n\n if (logScale > 0) {\n const step = Math.max(1, Math.floor(MAX_LENGTH / logScale));\n return ticksArr.filter((_, index) => index % step === 0);\n }\n }\n\n if (pad === 0) return ticksArr;\n\n const isPowTen = ticksArr.every(t => {\n const v = Math.abs(t);\n return v === 0 || Number.isInteger(Math.log10(v));\n });\n\n const [tickMin] = ticksArr;\n const tickMax = ticksArr[ticksArr.length - 1];\n\n const quantiles = extent(dataSet);\n let [min, max] = quantiles;\n if (typeof min === \"undefined\" || typeof max === \"undefined\")\n return ticksArr;\n\n if (outliers)\n [min, max] = [\n quantile(dataSet, 0.4) ?? min,\n quantile(dataSet, 0.6) ?? max,\n ];\n\n if (pad > 0) {\n const SCALE =\n typeof max === \"number\" && typeof min === \"number\"\n ? Math.max(Math.abs(max), Math.abs(min))\n : 0;\n const OFFSET =\n SCALE < 10 && isPowTen\n ? 0.5\n : SCALE < 100 && isPowTen\n ? 5\n : SCALE < 1000 && isPowTen\n ? 50\n : Math.round((max - min) / ticksArr.length);\n\n if (typeof tickMax === \"number\")\n ticksArr[ticksArr.length - 1] = Math.round(\n tickMax + OFFSET * pad + Number.EPSILON,\n );\n if (typeof tickMin === \"number\")\n ticksArr[0] = Math.round(tickMin - OFFSET * pad - Number.EPSILON);\n }\n\n const bad = ticksArr.some((tick, index) => {\n if (index === 0) return false;\n const prev = ticksArr[index - 1];\n const d = Math.abs(tick - prev);\n if (\n typeof digit === \"number\" &&\n digit < 1 &&\n String(d).includes(\".\")\n )\n return false;\n\n return d !== 1 && d !== 5 && d !== 0;\n });\n\n if (bad && pad !== 0) {\n return getChartYTicks({\n data,\n length,\n pad: 0,\n limitMin,\n limitMax,\n digit,\n outliers,\n log,\n });\n }\n\n return ticksArr;\n};\n\nexport const getDecimalIndex = (v: unknown): number =>\n !isNaN(Number(v)) && String(v).includes(\".\")\n ? String(v)\n .split(\".\")[1]\n .split(\"\")\n .findIndex(d => Number(d) !== 0) + 1\n : 0;\n\nexport const getDomainLimit = ({\n value,\n gap,\n min,\n max,\n}: {\n value: number | null;\n gap: number;\n min?: number;\n max?: number;\n}): number | string => {\n if (typeof value === \"number\" && !isNaN(value)) {\n const limit = value + gap;\n if (typeof min === \"number\" && limit < min) return min;\n if (typeof max === \"number\" && limit > max) return max;\n return limit;\n }\n return value ?? \"\";\n};\n\nexport const getXAxisTextAttr = (\n props: RechartsXAxisTickProps,\n): SVGAttributes<SVGTextElement> => {\n const {\n width,\n height,\n x,\n y,\n stroke,\n fill,\n orientation,\n textAnchor,\n transform,\n } = props;\n\n return {\n width,\n height,\n x,\n y,\n stroke,\n fill,\n textAnchor,\n orientation,\n transform,\n };\n};\n"]}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var React = require('react');
|
|
4
|
+
var parse = require('html-react-parser');
|
|
5
|
+
|
|
6
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
7
|
+
|
|
8
|
+
var React__default = /*#__PURE__*/_interopDefault(React);
|
|
9
|
+
var parse__default = /*#__PURE__*/_interopDefault(parse);
|
|
10
|
+
|
|
11
|
+
// src/convert/index.tsx
|
|
12
|
+
var convertTextToHTML = (text, tagName, key) => {
|
|
13
|
+
if (!text.includes(`<${tagName}>`)) return text;
|
|
14
|
+
const HTML_KEY = key ? key : `util/convert/text-to-html/${tagName}`;
|
|
15
|
+
const parts = text.split(new RegExp(`(<${tagName}>|</${tagName}>)`, "g"));
|
|
16
|
+
let isTagContents = false;
|
|
17
|
+
return /* @__PURE__ */ React__default.default.createElement(React__default.default.Fragment, null, parts.map((part, index) => {
|
|
18
|
+
if (part === `<${tagName}>`) {
|
|
19
|
+
isTagContents = true;
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
if (part === `</${tagName}>`) {
|
|
23
|
+
isTagContents = false;
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
if (isTagContents)
|
|
27
|
+
return /* @__PURE__ */ React__default.default.createElement("span", { key: `${HTML_KEY}/${index}`, className: tagName }, part);
|
|
28
|
+
return /* @__PURE__ */ React__default.default.createElement(React.Fragment, { key: `${HTML_KEY}/${index}` }, part);
|
|
29
|
+
}));
|
|
30
|
+
};
|
|
31
|
+
var convertTextToLineArray = (text) => {
|
|
32
|
+
if (text.includes("<br")) return text.split(/<br\s*\/?>|<br>/);
|
|
33
|
+
if (text.includes("\n")) return text.split("\n");
|
|
34
|
+
return [text];
|
|
35
|
+
};
|
|
36
|
+
var convertTextToJsx = ({
|
|
37
|
+
text,
|
|
38
|
+
key,
|
|
39
|
+
callback
|
|
40
|
+
}) => {
|
|
41
|
+
if (typeof text !== "string") return text;
|
|
42
|
+
if (/<[a-z][\s\S]*>/i.test(text)) {
|
|
43
|
+
return /* @__PURE__ */ React__default.default.createElement(React__default.default.Fragment, null, parse__default.default(text));
|
|
44
|
+
}
|
|
45
|
+
const lines = convertTextToLineArray(text);
|
|
46
|
+
if (lines.length > 1) {
|
|
47
|
+
const LINE_KEY = "util/convert/text-to-jsx";
|
|
48
|
+
return lines.map((line, index) => /* @__PURE__ */ React__default.default.createElement(React.Fragment, { key: key ? `${key}/${index}` : `${LINE_KEY}/${line}/${index}` }, index !== 0 && /* @__PURE__ */ React__default.default.createElement("br", null), typeof callback === "function" ? callback(line) : line));
|
|
49
|
+
}
|
|
50
|
+
return text;
|
|
51
|
+
};
|
|
52
|
+
var convertArrayToJsx = (textArray, options) => {
|
|
53
|
+
if (typeof textArray === "string" || !Array.isArray(textArray))
|
|
54
|
+
return convertTextToJsx({ text: textArray });
|
|
55
|
+
const LINE_KEY = "util/convert/array-to-jsx";
|
|
56
|
+
const commonKey = (content, index, additionalKey) => options?.key ? `${options.key}${additionalKey ? `/${additionalKey}` : ""}/${index}` : `${LINE_KEY}/${String(content)}${additionalKey ? `/${additionalKey}` : ""}/${index}`;
|
|
57
|
+
return textArray.map((content, index) => /* @__PURE__ */ React__default.default.createElement(React.Fragment, { key: commonKey(content, index) }, index !== 0 && /* @__PURE__ */ React__default.default.createElement(React__default.default.Fragment, null, new Array(options?.phraseGap || 1).fill({}).map((_, i) => /* @__PURE__ */ React__default.default.createElement("br", { key: commonKey(content, i, "br") }))), content));
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
exports.convertArrayToJsx = convertArrayToJsx;
|
|
61
|
+
exports.convertTextToHTML = convertTextToHTML;
|
|
62
|
+
exports.convertTextToJsx = convertTextToJsx;
|
|
63
|
+
exports.convertTextToLineArray = convertTextToLineArray;
|
|
64
|
+
//# sourceMappingURL=index.cjs.map
|
|
65
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/convert/index.tsx"],"names":["React","Fragment","parse"],"mappings":";;;;;;;;;;;AAOO,IAAM,iBAAA,GAAoB,CAC/B,IAAA,EACA,OAAA,EACA,GAAA,KACoB;AACpB,EAAA,IAAI,CAAC,IAAA,CAAK,QAAA,CAAS,IAAI,OAAO,CAAA,CAAA,CAAG,GAAG,OAAO,IAAA;AAC3C,EAAA,MAAM,QAAA,GAAW,GAAA,GAAM,GAAA,GAAM,CAAA,0BAAA,EAA6B,OAAO,CAAA,CAAA;AACjE,EAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,KAAA,CAAM,IAAI,MAAA,CAAO,CAAA,EAAA,EAAK,OAAO,CAAA,IAAA,EAAO,OAAO,CAAA,EAAA,CAAA,EAAM,GAAG,CAAC,CAAA;AAExE,EAAA,IAAI,aAAA,GAAgB,KAAA;AACpB,EAAA,uBACEA,sBAAA,CAAA,aAAA,CAAAA,sBAAA,CAAA,QAAA,EAAA,IAAA,EACG,KAAA,CAAM,GAAA,CAAI,CAAC,MAAM,KAAA,KAAU;AAC1B,IAAA,IAAI,IAAA,KAAS,CAAA,CAAA,EAAI,OAAO,CAAA,CAAA,CAAA,EAAK;AAC3B,MAAA,aAAA,GAAgB,IAAA;AAChB,MAAA,OAAO,IAAA;AAAA,IACT;AACA,IAAA,IAAI,IAAA,KAAS,CAAA,EAAA,EAAK,OAAO,CAAA,CAAA,CAAA,EAAK;AAC5B,MAAA,aAAA,GAAgB,KAAA;AAChB,MAAA,OAAO,IAAA;AAAA,IACT;AAEA,IAAA,IAAI,aAAA;AACF,MAAA,uBACEA,sBAAA,CAAA,aAAA,CAAC,MAAA,EAAA,EAAK,GAAA,EAAK,CAAA,EAAG,QAAQ,IAAI,KAAK,CAAA,CAAA,EAAI,SAAA,EAAW,OAAA,EAAA,EAC3C,IACH,CAAA;AAEJ,IAAA,uBAAOA,sBAAA,CAAA,aAAA,CAACC,kBAAS,GAAA,EAAK,CAAA,EAAG,QAAQ,CAAA,CAAA,EAAI,KAAK,MAAK,IAAK,CAAA;AAAA,EACtD,CAAC,CACH,CAAA;AAEJ;AAEO,IAAM,sBAAA,GAAyB,CAAC,IAAA,KAA2B;AAChE,EAAA,IAAI,KAAK,QAAA,CAAS,KAAK,GAAG,OAAO,IAAA,CAAK,MAAM,iBAAiB,CAAA;AAC7D,EAAA,IAAI,KAAK,QAAA,CAAS,IAAI,GAAG,OAAO,IAAA,CAAK,MAAM,IAAI,CAAA;AAC/C,EAAA,OAAO,CAAC,IAAI,CAAA;AACd;AAEO,IAAM,mBAAmB,CAAC;AAAA,EAC/B,IAAA;AAAA,EACA,GAAA;AAAA,EACA;AACF,CAAA,KAAwD;AACtD,EAAA,IAAI,OAAO,IAAA,KAAS,QAAA,EAAU,OAAO,IAAA;AAErC,EAAA,IAAI,iBAAA,CAAkB,IAAA,CAAK,IAAI,CAAA,EAAG;AAChC,IAAA,uBAAOD,sBAAA,CAAA,aAAA,CAAAA,sBAAA,CAAA,QAAA,EAAA,IAAA,EAAGE,sBAAA,CAAM,IAAI,CAAE,CAAA;AAAA,EACxB;AAEA,EAAA,MAAM,KAAA,GAAQ,uBAAuB,IAAI,CAAA;AAEzC,EAAA,IAAI,KAAA,CAAM,SAAS,CAAA,EAAG;AACpB,IAAA,MAAM,QAAA,GAAW,0BAAA;AACjB,IAAA,OAAO,KAAA,CAAM,GAAA,CAAI,CAAC,IAAA,EAAM,0BACtBF,sBAAA,CAAA,aAAA,CAACC,cAAA,EAAA,EAAS,GAAA,EAAK,GAAA,GAAM,CAAA,EAAG,GAAG,CAAA,CAAA,EAAI,KAAK,KAAK,CAAA,EAAG,QAAQ,CAAA,CAAA,EAAI,IAAI,CAAA,CAAA,EAAI,KAAK,CAAA,CAAA,EAAA,EAClE,KAAA,KAAU,qBAAKD,sBAAA,CAAA,aAAA,CAAC,IAAA,EAAA,IAAG,CAAA,EACnB,OAAO,aAAa,UAAA,GAAa,QAAA,CAAS,IAAI,CAAA,GAAI,IACrD,CACD,CAAA;AAAA,EACH;AAEA,EAAA,OAAO,IAAA;AACT;AAEO,IAAM,iBAAA,GAAoB,CAC/B,SAAA,EACA,OAAA,KACoB;AACpB,EAAA,IAAI,OAAO,SAAA,KAAc,QAAA,IAAY,CAAC,KAAA,CAAM,QAAQ,SAAS,CAAA;AAC3D,IAAA,OAAO,gBAAA,CAAiB,EAAE,IAAA,EAAM,SAAA,EAAW,CAAA;AAE7C,EAAA,MAAM,QAAA,GAAW,2BAAA;AACjB,EAAA,MAAM,SAAA,GAAY,CAChB,OAAA,EACA,KAAA,EACA,kBAEA,OAAA,EAAS,GAAA,GACL,CAAA,EAAG,OAAA,CAAQ,GAAG,CAAA,EAAG,aAAA,GAAgB,CAAA,CAAA,EAAI,aAAa,CAAA,CAAA,GAAK,EAAE,CAAA,CAAA,EAAI,KAAK,CAAA,CAAA,GAClE,CAAA,EAAG,QAAQ,CAAA,CAAA,EAAI,OAAO,OAAO,CAAC,CAAA,EAAG,aAAA,GAAgB,CAAA,CAAA,EAAI,aAAa,CAAA,CAAA,GAAK,EAAE,IAAI,KAAK,CAAA,CAAA;AAExF,EAAA,OAAO,UAAU,GAAA,CAAI,CAAC,SAAS,KAAA,qBAC7BA,sBAAA,CAAA,aAAA,CAACC,kBAAS,GAAA,EAAK,SAAA,CAAU,OAAA,EAAS,KAAK,KACpC,KAAA,KAAU,CAAA,gGAEN,IAAI,KAAA,CAAM,SAAS,SAAA,IAAa,CAAC,CAAA,CAAE,IAAA,CAAK,EAAE,CAAA,CAAE,IAAI,CAAC,CAAA,EAAG,sBACnDD,sBAAA,CAAA,aAAA,CAAC,IAAA,EAAA,EAAG,KAAK,SAAA,CAAU,OAAA,EAAS,GAAG,IAAI,CAAA,EAAG,CACvC,CACH,CAAA,EAED,OACH,CACD,CAAA;AACH","file":"index.cjs","sourcesContent":["import React, { Fragment } from \"react\";\nimport parse from \"html-react-parser\";\nimport type {\n ConvertArrayToJsxOptions,\n ConvertTextToJsxParams,\n} from \"./types\";\n\nexport const convertTextToHTML = (\n text: string,\n tagName: string,\n key?: string,\n): React.ReactNode => {\n if (!text.includes(`<${tagName}>`)) return text;\n const HTML_KEY = key ? key : `util/convert/text-to-html/${tagName}`;\n const parts = text.split(new RegExp(`(<${tagName}>|</${tagName}>)`, \"g\"));\n\n let isTagContents = false;\n return (\n <>\n {parts.map((part, index) => {\n if (part === `<${tagName}>`) {\n isTagContents = true;\n return null;\n }\n if (part === `</${tagName}>`) {\n isTagContents = false;\n return null;\n }\n\n if (isTagContents)\n return (\n <span key={`${HTML_KEY}/${index}`} className={tagName}>\n {part}\n </span>\n );\n return <Fragment key={`${HTML_KEY}/${index}`}>{part}</Fragment>;\n })}\n </>\n );\n};\n\nexport const convertTextToLineArray = (text: string): string[] => {\n if (text.includes(\"<br\")) return text.split(/<br\\s*\\/?>|<br>/);\n if (text.includes(\"\\n\")) return text.split(\"\\n\");\n return [text];\n};\n\nexport const convertTextToJsx = ({\n text,\n key,\n callback,\n}: ConvertTextToJsxParams): string | React.ReactNode => {\n if (typeof text !== \"string\") return text;\n\n if (/<[a-z][\\s\\S]*>/i.test(text)) {\n return <>{parse(text)}</>;\n }\n\n const lines = convertTextToLineArray(text);\n\n if (lines.length > 1) {\n const LINE_KEY = \"util/convert/text-to-jsx\";\n return lines.map((line, index) => (\n <Fragment key={key ? `${key}/${index}` : `${LINE_KEY}/${line}/${index}`}>\n {index !== 0 && <br />}\n {typeof callback === \"function\" ? callback(line) : line}\n </Fragment>\n ));\n }\n\n return text;\n};\n\nexport const convertArrayToJsx = (\n textArray: React.ReactNode[] | string,\n options?: ConvertArrayToJsxOptions,\n): React.ReactNode => {\n if (typeof textArray === \"string\" || !Array.isArray(textArray))\n return convertTextToJsx({ text: textArray });\n\n const LINE_KEY = \"util/convert/array-to-jsx\";\n const commonKey = (\n content: React.ReactNode,\n index: number,\n additionalKey?: string,\n ) =>\n options?.key\n ? `${options.key}${additionalKey ? `/${additionalKey}` : \"\"}/${index}`\n : `${LINE_KEY}/${String(content)}${additionalKey ? `/${additionalKey}` : \"\"}/${index}`;\n\n return textArray.map((content, index) => (\n <Fragment key={commonKey(content, index)}>\n {index !== 0 && (\n <>\n {new Array(options?.phraseGap || 1).fill({}).map((_, i) => (\n <br key={commonKey(content, i, \"br\")} />\n ))}\n </>\n )}\n {content}\n </Fragment>\n ));\n};\n"]}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
type ConvertTextToJsxParams = {
|
|
4
|
+
text: string;
|
|
5
|
+
} & Partial<{
|
|
6
|
+
key: string;
|
|
7
|
+
callback: (text: string) => string | React.ReactNode;
|
|
8
|
+
}>;
|
|
9
|
+
type ConvertArrayToJsxOptions = {
|
|
10
|
+
key?: string;
|
|
11
|
+
phraseGap?: number;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
declare const convertTextToHTML: (text: string, tagName: string, key?: string) => React.ReactNode;
|
|
15
|
+
declare const convertTextToLineArray: (text: string) => string[];
|
|
16
|
+
declare const convertTextToJsx: ({ text, key, callback, }: ConvertTextToJsxParams) => string | React.ReactNode;
|
|
17
|
+
declare const convertArrayToJsx: (textArray: React.ReactNode[] | string, options?: ConvertArrayToJsxOptions) => React.ReactNode;
|
|
18
|
+
|
|
19
|
+
export { convertArrayToJsx, convertTextToHTML, convertTextToJsx, convertTextToLineArray };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
type ConvertTextToJsxParams = {
|
|
4
|
+
text: string;
|
|
5
|
+
} & Partial<{
|
|
6
|
+
key: string;
|
|
7
|
+
callback: (text: string) => string | React.ReactNode;
|
|
8
|
+
}>;
|
|
9
|
+
type ConvertArrayToJsxOptions = {
|
|
10
|
+
key?: string;
|
|
11
|
+
phraseGap?: number;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
declare const convertTextToHTML: (text: string, tagName: string, key?: string) => React.ReactNode;
|
|
15
|
+
declare const convertTextToLineArray: (text: string) => string[];
|
|
16
|
+
declare const convertTextToJsx: ({ text, key, callback, }: ConvertTextToJsxParams) => string | React.ReactNode;
|
|
17
|
+
declare const convertArrayToJsx: (textArray: React.ReactNode[] | string, options?: ConvertArrayToJsxOptions) => React.ReactNode;
|
|
18
|
+
|
|
19
|
+
export { convertArrayToJsx, convertTextToHTML, convertTextToJsx, convertTextToLineArray };
|