deepsea-components 5.18.2 → 5.18.4
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/README.md +23 -23
- package/dist/components/InputFile.cjs +29 -18
- package/dist/components/InputFile.js +29 -18
- package/dist/components/InputFileButton.cjs +9 -5
- package/dist/components/InputFileButton.js +9 -5
- package/package.json +1 -1
- package/src/components/CircleText.tsx +81 -81
- package/src/components/InputFile.tsx +31 -19
- package/src/components/InputFileButton.tsx +9 -5
- package/src/components/ReadExcel.tsx +13 -13
- package/src/components/ScrollMask.module.css +87 -87
- package/src/components/WriteExcel.tsx +13 -13
- package/src/utils/getReactVersion.ts +7 -7
- package/src/utils/index.ts +33 -33
package/README.md
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
# deepsea-components
|
|
2
|
-
|
|
3
|
-
[](https://npmjs.org/package/deepsea-components)
|
|
4
|
-
[](https://npmjs.org/package/deepsea-components)
|
|
5
|
-
|
|
6
|
-
## Install
|
|
7
|
-
|
|
8
|
-
```bash
|
|
9
|
-
$ yarn install
|
|
10
|
-
```
|
|
11
|
-
|
|
12
|
-
```bash
|
|
13
|
-
$ npm run dev
|
|
14
|
-
$ npm run build
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
## Options
|
|
18
|
-
|
|
19
|
-
TODO
|
|
20
|
-
|
|
21
|
-
## LICENSE
|
|
22
|
-
|
|
23
|
-
MIT
|
|
1
|
+
# deepsea-components
|
|
2
|
+
|
|
3
|
+
[](https://npmjs.org/package/deepsea-components)
|
|
4
|
+
[](https://npmjs.org/package/deepsea-components)
|
|
5
|
+
|
|
6
|
+
## Install
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
$ yarn install
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
$ npm run dev
|
|
14
|
+
$ npm run build
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Options
|
|
18
|
+
|
|
19
|
+
TODO
|
|
20
|
+
|
|
21
|
+
## LICENSE
|
|
22
|
+
|
|
23
|
+
MIT
|
|
@@ -30,28 +30,39 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
30
30
|
});
|
|
31
31
|
const jsx_runtime_namespaceObject = require("react/jsx-runtime");
|
|
32
32
|
const external_react_namespaceObject = require("react");
|
|
33
|
-
|
|
33
|
+
function getFileData(file, type) {
|
|
34
|
+
if ("file" === type) return Promise.resolve(file);
|
|
34
35
|
const fileReader = new FileReader();
|
|
35
|
-
|
|
36
|
-
case "arrayBuffer":
|
|
37
|
-
fileReader.readAsArrayBuffer(file);
|
|
38
|
-
break;
|
|
39
|
-
case "binary":
|
|
40
|
-
fileReader.readAsBinaryString(file);
|
|
41
|
-
break;
|
|
42
|
-
case "base64":
|
|
43
|
-
fileReader.readAsDataURL(file);
|
|
44
|
-
break;
|
|
45
|
-
case "text":
|
|
46
|
-
fileReader.readAsText(file);
|
|
47
|
-
break;
|
|
48
|
-
default:
|
|
49
|
-
return file;
|
|
50
|
-
}
|
|
51
|
-
return new Promise((resolve)=>{
|
|
36
|
+
return new Promise((resolve, reject)=>{
|
|
52
37
|
fileReader.addEventListener("load", ()=>{
|
|
53
38
|
resolve(fileReader.result);
|
|
54
39
|
});
|
|
40
|
+
fileReader.addEventListener("error", ()=>{
|
|
41
|
+
reject(fileReader.error ?? new Error("Failed to read file"));
|
|
42
|
+
});
|
|
43
|
+
fileReader.addEventListener("abort", ()=>{
|
|
44
|
+
reject(fileReader.error ?? new Error("File reading was aborted"));
|
|
45
|
+
});
|
|
46
|
+
try {
|
|
47
|
+
switch(type){
|
|
48
|
+
case "arrayBuffer":
|
|
49
|
+
fileReader.readAsArrayBuffer(file);
|
|
50
|
+
break;
|
|
51
|
+
case "binary":
|
|
52
|
+
fileReader.readAsBinaryString(file);
|
|
53
|
+
break;
|
|
54
|
+
case "base64":
|
|
55
|
+
fileReader.readAsDataURL(file);
|
|
56
|
+
break;
|
|
57
|
+
case "text":
|
|
58
|
+
fileReader.readAsText(file);
|
|
59
|
+
break;
|
|
60
|
+
default:
|
|
61
|
+
resolve(file);
|
|
62
|
+
}
|
|
63
|
+
} catch (error) {
|
|
64
|
+
reject(error);
|
|
65
|
+
}
|
|
55
66
|
});
|
|
56
67
|
}
|
|
57
68
|
function InputFile(props) {
|
|
@@ -1,28 +1,39 @@
|
|
|
1
1
|
"use client"
|
|
2
2
|
import { jsx } from "react/jsx-runtime";
|
|
3
3
|
import { useState } from "react";
|
|
4
|
-
|
|
4
|
+
function getFileData(file, type) {
|
|
5
|
+
if ("file" === type) return Promise.resolve(file);
|
|
5
6
|
const fileReader = new FileReader();
|
|
6
|
-
|
|
7
|
-
case "arrayBuffer":
|
|
8
|
-
fileReader.readAsArrayBuffer(file);
|
|
9
|
-
break;
|
|
10
|
-
case "binary":
|
|
11
|
-
fileReader.readAsBinaryString(file);
|
|
12
|
-
break;
|
|
13
|
-
case "base64":
|
|
14
|
-
fileReader.readAsDataURL(file);
|
|
15
|
-
break;
|
|
16
|
-
case "text":
|
|
17
|
-
fileReader.readAsText(file);
|
|
18
|
-
break;
|
|
19
|
-
default:
|
|
20
|
-
return file;
|
|
21
|
-
}
|
|
22
|
-
return new Promise((resolve)=>{
|
|
7
|
+
return new Promise((resolve, reject)=>{
|
|
23
8
|
fileReader.addEventListener("load", ()=>{
|
|
24
9
|
resolve(fileReader.result);
|
|
25
10
|
});
|
|
11
|
+
fileReader.addEventListener("error", ()=>{
|
|
12
|
+
reject(fileReader.error ?? new Error("Failed to read file"));
|
|
13
|
+
});
|
|
14
|
+
fileReader.addEventListener("abort", ()=>{
|
|
15
|
+
reject(fileReader.error ?? new Error("File reading was aborted"));
|
|
16
|
+
});
|
|
17
|
+
try {
|
|
18
|
+
switch(type){
|
|
19
|
+
case "arrayBuffer":
|
|
20
|
+
fileReader.readAsArrayBuffer(file);
|
|
21
|
+
break;
|
|
22
|
+
case "binary":
|
|
23
|
+
fileReader.readAsBinaryString(file);
|
|
24
|
+
break;
|
|
25
|
+
case "base64":
|
|
26
|
+
fileReader.readAsDataURL(file);
|
|
27
|
+
break;
|
|
28
|
+
case "text":
|
|
29
|
+
fileReader.readAsText(file);
|
|
30
|
+
break;
|
|
31
|
+
default:
|
|
32
|
+
resolve(file);
|
|
33
|
+
}
|
|
34
|
+
} catch (error) {
|
|
35
|
+
reject(error);
|
|
36
|
+
}
|
|
26
37
|
});
|
|
27
38
|
}
|
|
28
39
|
function InputFile(props) {
|
|
@@ -35,17 +35,19 @@ function InputFileButton(props) {
|
|
|
35
35
|
const { ref, style, disabled: __disabled, ...restInputProps } = inputProps;
|
|
36
36
|
const [disabled, setDisabled] = (0, external_react_namespaceObject.useState)(false);
|
|
37
37
|
const input = (0, external_react_namespaceObject.useRef)(null);
|
|
38
|
+
const isDisabled = disabled || _disabled || __disabled;
|
|
38
39
|
(0, external_react_namespaceObject.useImperativeHandle)(ref, ()=>input.current, [
|
|
39
40
|
input.current
|
|
40
41
|
]);
|
|
41
42
|
function onClick(e) {
|
|
42
43
|
var _input_current;
|
|
43
|
-
null == (_input_current = input.current) || _input_current.click();
|
|
44
44
|
null == _onClick || _onClick(e);
|
|
45
|
+
if (isDisabled || e.defaultPrevented) return;
|
|
46
|
+
null == (_input_current = input.current) || _input_current.click();
|
|
45
47
|
}
|
|
46
48
|
async function onDrop(e) {
|
|
47
49
|
null == _onDrop || _onDrop(e);
|
|
48
|
-
if (
|
|
50
|
+
if (isDisabled || !dragFile) return;
|
|
49
51
|
e.preventDefault();
|
|
50
52
|
const { files } = e.dataTransfer;
|
|
51
53
|
if (!files || 0 === files.length) return;
|
|
@@ -80,14 +82,14 @@ function InputFileButton(props) {
|
|
|
80
82
|
}
|
|
81
83
|
function onDragOver(e) {
|
|
82
84
|
null == _onDragOver || _onDragOver(e);
|
|
83
|
-
if (
|
|
85
|
+
if (isDisabled || !dragFile) return;
|
|
84
86
|
e.preventDefault();
|
|
85
87
|
}
|
|
86
88
|
return /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsxs)(external_react_namespaceObject.Fragment, {
|
|
87
89
|
children: [
|
|
88
90
|
/*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_InputFile_cjs_namespaceObject.InputFile, {
|
|
89
91
|
ref: input,
|
|
90
|
-
disabled:
|
|
92
|
+
disabled: isDisabled,
|
|
91
93
|
style: {
|
|
92
94
|
display: "none",
|
|
93
95
|
...style
|
|
@@ -97,11 +99,13 @@ function InputFileButton(props) {
|
|
|
97
99
|
type: type,
|
|
98
100
|
onValueChange: onValueChange,
|
|
99
101
|
onFileChange: onFileChange,
|
|
102
|
+
onDataChange: onDataChange,
|
|
100
103
|
clearAfterChange: clearAfterChange,
|
|
101
104
|
...restInputProps
|
|
102
105
|
}),
|
|
103
106
|
/*#__PURE__*/ (0, external_react_namespaceObject.createElement)(as, {
|
|
104
|
-
disabled:
|
|
107
|
+
disabled: isDisabled,
|
|
108
|
+
type: "button",
|
|
105
109
|
onClick,
|
|
106
110
|
onDrop,
|
|
107
111
|
onDragOver,
|
|
@@ -7,17 +7,19 @@ function InputFileButton(props) {
|
|
|
7
7
|
const { ref, style, disabled: __disabled, ...restInputProps } = inputProps;
|
|
8
8
|
const [disabled, setDisabled] = useState(false);
|
|
9
9
|
const input = useRef(null);
|
|
10
|
+
const isDisabled = disabled || _disabled || __disabled;
|
|
10
11
|
useImperativeHandle(ref, ()=>input.current, [
|
|
11
12
|
input.current
|
|
12
13
|
]);
|
|
13
14
|
function onClick(e) {
|
|
14
15
|
var _input_current;
|
|
15
|
-
null == (_input_current = input.current) || _input_current.click();
|
|
16
16
|
null == _onClick || _onClick(e);
|
|
17
|
+
if (isDisabled || e.defaultPrevented) return;
|
|
18
|
+
null == (_input_current = input.current) || _input_current.click();
|
|
17
19
|
}
|
|
18
20
|
async function onDrop(e) {
|
|
19
21
|
null == _onDrop || _onDrop(e);
|
|
20
|
-
if (
|
|
22
|
+
if (isDisabled || !dragFile) return;
|
|
21
23
|
e.preventDefault();
|
|
22
24
|
const { files } = e.dataTransfer;
|
|
23
25
|
if (!files || 0 === files.length) return;
|
|
@@ -52,14 +54,14 @@ function InputFileButton(props) {
|
|
|
52
54
|
}
|
|
53
55
|
function onDragOver(e) {
|
|
54
56
|
null == _onDragOver || _onDragOver(e);
|
|
55
|
-
if (
|
|
57
|
+
if (isDisabled || !dragFile) return;
|
|
56
58
|
e.preventDefault();
|
|
57
59
|
}
|
|
58
60
|
return /*#__PURE__*/ jsxs(Fragment, {
|
|
59
61
|
children: [
|
|
60
62
|
/*#__PURE__*/ jsx(InputFile, {
|
|
61
63
|
ref: input,
|
|
62
|
-
disabled:
|
|
64
|
+
disabled: isDisabled,
|
|
63
65
|
style: {
|
|
64
66
|
display: "none",
|
|
65
67
|
...style
|
|
@@ -69,11 +71,13 @@ function InputFileButton(props) {
|
|
|
69
71
|
type: type,
|
|
70
72
|
onValueChange: onValueChange,
|
|
71
73
|
onFileChange: onFileChange,
|
|
74
|
+
onDataChange: onDataChange,
|
|
72
75
|
clearAfterChange: clearAfterChange,
|
|
73
76
|
...restInputProps
|
|
74
77
|
}),
|
|
75
78
|
/*#__PURE__*/ createElement(as, {
|
|
76
|
-
disabled:
|
|
79
|
+
disabled: isDisabled,
|
|
80
|
+
type: "button",
|
|
77
81
|
onClick,
|
|
78
82
|
onDrop,
|
|
79
83
|
onDragOver,
|
package/package.json
CHANGED
|
@@ -1,81 +1,81 @@
|
|
|
1
|
-
"use client"
|
|
2
|
-
|
|
3
|
-
import { FC, Fragment, HTMLAttributes } from "react"
|
|
4
|
-
|
|
5
|
-
export interface CircleTextProps extends Omit<HTMLAttributes<HTMLSpanElement>, "children"> {
|
|
6
|
-
/** 每一个方块的宽度 */
|
|
7
|
-
width: number
|
|
8
|
-
/** 每一个方块的高度 */
|
|
9
|
-
height: number
|
|
10
|
-
/** 圆弧的半径,不包含方块的高度 */
|
|
11
|
-
radius: number
|
|
12
|
-
/** 开始旋转的弧度,逆时针增加,0 为 x 轴方向 */
|
|
13
|
-
startAngel?: number
|
|
14
|
-
/** 每一个方块之间间隔的弧度 */
|
|
15
|
-
gapAngel?: number
|
|
16
|
-
/** 文字对齐的方式,默认居中 */
|
|
17
|
-
align?: "left" | "center" | "right"
|
|
18
|
-
/** 文字朝向圆心还是外侧,默认外侧 */
|
|
19
|
-
direction?: "inner" | "outer"
|
|
20
|
-
/** 是否反转文字顺序 */
|
|
21
|
-
reverse?: boolean
|
|
22
|
-
/** 分割文字的方法 */
|
|
23
|
-
separator?: string | RegExp | ((text: string) => string[])
|
|
24
|
-
/** 显示的文字 */
|
|
25
|
-
children: string
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/** 环形文字 */
|
|
29
|
-
export const CircleText: FC<CircleTextProps> = props => {
|
|
30
|
-
const {
|
|
31
|
-
width,
|
|
32
|
-
height,
|
|
33
|
-
radius,
|
|
34
|
-
startAngel = 0,
|
|
35
|
-
gapAngel = 0,
|
|
36
|
-
align = "center",
|
|
37
|
-
style,
|
|
38
|
-
direction = "outer",
|
|
39
|
-
reverse = false,
|
|
40
|
-
separator,
|
|
41
|
-
children,
|
|
42
|
-
...rest
|
|
43
|
-
} = props
|
|
44
|
-
const unitAngle = Math.atan(width / 2 / radius) * 2
|
|
45
|
-
const totalAngle = (unitAngle + gapAngel) * children.length - gapAngel
|
|
46
|
-
const offsetAngle = align === "left" ? 0 : align === "right" ? totalAngle : totalAngle / 2
|
|
47
|
-
|
|
48
|
-
function getTransform(idx: number) {
|
|
49
|
-
const angle = startAngel - idx * (unitAngle + gapAngel) + offsetAngle - unitAngle / 2
|
|
50
|
-
const x = (radius + height / 2) * Math.cos(angle) - width / 2
|
|
51
|
-
const y = (radius + height / 2) * Math.sin(angle) * -1 - height / 2
|
|
52
|
-
const z = Math.PI / 2 - angle + (direction === "inner" ? Math.PI : 0)
|
|
53
|
-
return `translateX(${x}px) translateY(${y}px) rotateZ(${(z / Math.PI) * 180}deg)`
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
const words = typeof separator === "function" ? separator(children) : children.split(separator ?? "")
|
|
57
|
-
|
|
58
|
-
if (reverse) words.reverse()
|
|
59
|
-
|
|
60
|
-
return (
|
|
61
|
-
<Fragment>
|
|
62
|
-
{words.map((w, idx) => (
|
|
63
|
-
<span
|
|
64
|
-
key={idx}
|
|
65
|
-
style={{
|
|
66
|
-
position: "absolute",
|
|
67
|
-
...style,
|
|
68
|
-
transform: getTransform(idx),
|
|
69
|
-
textAlign: "center",
|
|
70
|
-
width,
|
|
71
|
-
lineHeight: `${height}px`,
|
|
72
|
-
height: height,
|
|
73
|
-
}}
|
|
74
|
-
{...rest}
|
|
75
|
-
>
|
|
76
|
-
{w}
|
|
77
|
-
</span>
|
|
78
|
-
))}
|
|
79
|
-
</Fragment>
|
|
80
|
-
)
|
|
81
|
-
}
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import { FC, Fragment, HTMLAttributes } from "react"
|
|
4
|
+
|
|
5
|
+
export interface CircleTextProps extends Omit<HTMLAttributes<HTMLSpanElement>, "children"> {
|
|
6
|
+
/** 每一个方块的宽度 */
|
|
7
|
+
width: number
|
|
8
|
+
/** 每一个方块的高度 */
|
|
9
|
+
height: number
|
|
10
|
+
/** 圆弧的半径,不包含方块的高度 */
|
|
11
|
+
radius: number
|
|
12
|
+
/** 开始旋转的弧度,逆时针增加,0 为 x 轴方向 */
|
|
13
|
+
startAngel?: number
|
|
14
|
+
/** 每一个方块之间间隔的弧度 */
|
|
15
|
+
gapAngel?: number
|
|
16
|
+
/** 文字对齐的方式,默认居中 */
|
|
17
|
+
align?: "left" | "center" | "right"
|
|
18
|
+
/** 文字朝向圆心还是外侧,默认外侧 */
|
|
19
|
+
direction?: "inner" | "outer"
|
|
20
|
+
/** 是否反转文字顺序 */
|
|
21
|
+
reverse?: boolean
|
|
22
|
+
/** 分割文字的方法 */
|
|
23
|
+
separator?: string | RegExp | ((text: string) => string[])
|
|
24
|
+
/** 显示的文字 */
|
|
25
|
+
children: string
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** 环形文字 */
|
|
29
|
+
export const CircleText: FC<CircleTextProps> = props => {
|
|
30
|
+
const {
|
|
31
|
+
width,
|
|
32
|
+
height,
|
|
33
|
+
radius,
|
|
34
|
+
startAngel = 0,
|
|
35
|
+
gapAngel = 0,
|
|
36
|
+
align = "center",
|
|
37
|
+
style,
|
|
38
|
+
direction = "outer",
|
|
39
|
+
reverse = false,
|
|
40
|
+
separator,
|
|
41
|
+
children,
|
|
42
|
+
...rest
|
|
43
|
+
} = props
|
|
44
|
+
const unitAngle = Math.atan(width / 2 / radius) * 2
|
|
45
|
+
const totalAngle = (unitAngle + gapAngel) * children.length - gapAngel
|
|
46
|
+
const offsetAngle = align === "left" ? 0 : align === "right" ? totalAngle : totalAngle / 2
|
|
47
|
+
|
|
48
|
+
function getTransform(idx: number) {
|
|
49
|
+
const angle = startAngel - idx * (unitAngle + gapAngel) + offsetAngle - unitAngle / 2
|
|
50
|
+
const x = (radius + height / 2) * Math.cos(angle) - width / 2
|
|
51
|
+
const y = (radius + height / 2) * Math.sin(angle) * -1 - height / 2
|
|
52
|
+
const z = Math.PI / 2 - angle + (direction === "inner" ? Math.PI : 0)
|
|
53
|
+
return `translateX(${x}px) translateY(${y}px) rotateZ(${(z / Math.PI) * 180}deg)`
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const words = typeof separator === "function" ? separator(children) : children.split(separator ?? "")
|
|
57
|
+
|
|
58
|
+
if (reverse) words.reverse()
|
|
59
|
+
|
|
60
|
+
return (
|
|
61
|
+
<Fragment>
|
|
62
|
+
{words.map((w, idx) => (
|
|
63
|
+
<span
|
|
64
|
+
key={idx}
|
|
65
|
+
style={{
|
|
66
|
+
position: "absolute",
|
|
67
|
+
...style,
|
|
68
|
+
transform: getTransform(idx),
|
|
69
|
+
textAlign: "center",
|
|
70
|
+
width,
|
|
71
|
+
lineHeight: `${height}px`,
|
|
72
|
+
height: height,
|
|
73
|
+
}}
|
|
74
|
+
{...rest}
|
|
75
|
+
>
|
|
76
|
+
{w}
|
|
77
|
+
</span>
|
|
78
|
+
))}
|
|
79
|
+
</Fragment>
|
|
80
|
+
)
|
|
81
|
+
}
|
|
@@ -12,30 +12,42 @@ export interface InputFileDataTypeMap {
|
|
|
12
12
|
|
|
13
13
|
export type InputFileDataType = keyof InputFileDataTypeMap
|
|
14
14
|
|
|
15
|
-
export
|
|
16
|
-
|
|
15
|
+
export function getFileData<T extends InputFileDataType>(file: File, type: T): Promise<InputFileDataTypeMap[T]> {
|
|
16
|
+
if (type === "file") return Promise.resolve(file as InputFileDataTypeMap[T])
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
case "arrayBuffer":
|
|
20
|
-
fileReader.readAsArrayBuffer(file)
|
|
21
|
-
break
|
|
22
|
-
case "binary":
|
|
23
|
-
fileReader.readAsBinaryString(file)
|
|
24
|
-
break
|
|
25
|
-
case "base64":
|
|
26
|
-
fileReader.readAsDataURL(file)
|
|
27
|
-
break
|
|
28
|
-
case "text":
|
|
29
|
-
fileReader.readAsText(file)
|
|
30
|
-
break
|
|
31
|
-
default:
|
|
32
|
-
return file as any
|
|
33
|
-
}
|
|
18
|
+
const fileReader = new FileReader()
|
|
34
19
|
|
|
35
|
-
return new Promise(resolve => {
|
|
20
|
+
return new Promise((resolve, reject) => {
|
|
36
21
|
fileReader.addEventListener("load", () => {
|
|
37
22
|
resolve(fileReader.result as any)
|
|
38
23
|
})
|
|
24
|
+
fileReader.addEventListener("error", () => {
|
|
25
|
+
reject(fileReader.error ?? new Error("Failed to read file"))
|
|
26
|
+
})
|
|
27
|
+
fileReader.addEventListener("abort", () => {
|
|
28
|
+
reject(fileReader.error ?? new Error("File reading was aborted"))
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
try {
|
|
32
|
+
switch (type) {
|
|
33
|
+
case "arrayBuffer":
|
|
34
|
+
fileReader.readAsArrayBuffer(file)
|
|
35
|
+
break
|
|
36
|
+
case "binary":
|
|
37
|
+
fileReader.readAsBinaryString(file)
|
|
38
|
+
break
|
|
39
|
+
case "base64":
|
|
40
|
+
fileReader.readAsDataURL(file)
|
|
41
|
+
break
|
|
42
|
+
case "text":
|
|
43
|
+
fileReader.readAsText(file)
|
|
44
|
+
break
|
|
45
|
+
default:
|
|
46
|
+
resolve(file as any)
|
|
47
|
+
}
|
|
48
|
+
} catch (error) {
|
|
49
|
+
reject(error)
|
|
50
|
+
}
|
|
39
51
|
})
|
|
40
52
|
}
|
|
41
53
|
|
|
@@ -66,17 +66,19 @@ export function InputFileButton<
|
|
|
66
66
|
const { ref, style, disabled: __disabled, ...restInputProps } = inputProps
|
|
67
67
|
const [disabled, setDisabled] = useState(false)
|
|
68
68
|
const input = useRef<HTMLInputElement>(null)
|
|
69
|
+
const isDisabled = disabled || _disabled || __disabled
|
|
69
70
|
|
|
70
71
|
useImperativeHandle(ref, () => input.current!, [input.current])
|
|
71
72
|
|
|
72
73
|
function onClick(e: ReactMouseEvent<ComponentRef<AS>, MouseEvent>) {
|
|
73
|
-
input.current?.click()
|
|
74
74
|
_onClick?.(e as any)
|
|
75
|
+
if (isDisabled || e.defaultPrevented) return
|
|
76
|
+
input.current?.click()
|
|
75
77
|
}
|
|
76
78
|
|
|
77
79
|
async function onDrop(e: DragEvent<ComponentRef<AS>>) {
|
|
78
80
|
_onDrop?.(e as any)
|
|
79
|
-
if (
|
|
81
|
+
if (isDisabled || !dragFile) return
|
|
80
82
|
e.preventDefault()
|
|
81
83
|
const { files } = e.dataTransfer
|
|
82
84
|
if (!files || files.length === 0) return
|
|
@@ -110,7 +112,7 @@ export function InputFileButton<
|
|
|
110
112
|
|
|
111
113
|
function onDragOver(e: DragEvent<ComponentRef<AS>>) {
|
|
112
114
|
_onDragOver?.(e as any)
|
|
113
|
-
if (
|
|
115
|
+
if (isDisabled || !dragFile) return
|
|
114
116
|
e.preventDefault()
|
|
115
117
|
}
|
|
116
118
|
|
|
@@ -118,18 +120,20 @@ export function InputFileButton<
|
|
|
118
120
|
<Fragment>
|
|
119
121
|
<InputFile<Multiple, Type>
|
|
120
122
|
ref={input}
|
|
121
|
-
disabled={
|
|
123
|
+
disabled={isDisabled}
|
|
122
124
|
style={{ display: "none", ...style }}
|
|
123
125
|
multiple={multiple}
|
|
124
126
|
accept={accept}
|
|
125
127
|
type={type as Type}
|
|
126
128
|
onValueChange={onValueChange}
|
|
127
129
|
onFileChange={onFileChange}
|
|
130
|
+
onDataChange={onDataChange}
|
|
128
131
|
clearAfterChange={clearAfterChange}
|
|
129
132
|
{...restInputProps}
|
|
130
133
|
/>
|
|
131
134
|
{createElement(as, {
|
|
132
|
-
disabled:
|
|
135
|
+
disabled: isDisabled,
|
|
136
|
+
type: "button",
|
|
133
137
|
onClick,
|
|
134
138
|
onDrop,
|
|
135
139
|
onDragOver,
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
"use client"
|
|
2
|
-
|
|
3
|
-
import { ReadSheet, ReadSheetProps } from "./ReadSheet"
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* @deprecated 请使用 ReadSheetProps 代替
|
|
7
|
-
*/
|
|
8
|
-
export type ReadExcelProps = ReadSheetProps
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* @deprecated 请使用 ReadSheet 代替
|
|
12
|
-
*/
|
|
13
|
-
export const ReadExcel = ReadSheet
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import { ReadSheet, ReadSheetProps } from "./ReadSheet"
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @deprecated 请使用 ReadSheetProps 代替
|
|
7
|
+
*/
|
|
8
|
+
export type ReadExcelProps = ReadSheetProps
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* @deprecated 请使用 ReadSheet 代替
|
|
12
|
+
*/
|
|
13
|
+
export const ReadExcel = ReadSheet
|
|
@@ -1,87 +1,87 @@
|
|
|
1
|
-
.scroll-mask {
|
|
2
|
-
position: sticky;
|
|
3
|
-
z-index: 10;
|
|
4
|
-
pointer-events: none;
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
.top-scroll-mask {
|
|
8
|
-
width: 100%;
|
|
9
|
-
height: 0;
|
|
10
|
-
top: 0;
|
|
11
|
-
right: 0;
|
|
12
|
-
bottom: 100%;
|
|
13
|
-
left: 0;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
.scroll-mask-content {
|
|
17
|
-
position: absolute;
|
|
18
|
-
background-image: linear-gradient(
|
|
19
|
-
to var(--scroll-mask-direction),
|
|
20
|
-
var(--scroll-mask-color-from, rgba(0, 0, 0, 0.1)),
|
|
21
|
-
var(--scroll-mask-color-to, rgba(0, 0, 0, 0))
|
|
22
|
-
);
|
|
23
|
-
clip-path: var(--scroll-mask-clip-path, none);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
.top-scroll-mask-content {
|
|
27
|
-
width: 100%;
|
|
28
|
-
height: var(--scroll-mask-size, 8px);
|
|
29
|
-
top: 0;
|
|
30
|
-
right: 50%;
|
|
31
|
-
transform: translateX(50%);
|
|
32
|
-
--scroll-mask-direction: bottom;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
.bottom-scroll-mask {
|
|
36
|
-
width: 100%;
|
|
37
|
-
height: 0;
|
|
38
|
-
top: 100%;
|
|
39
|
-
right: 0;
|
|
40
|
-
bottom: 0;
|
|
41
|
-
left: 0;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
.bottom-scroll-mask-content {
|
|
45
|
-
width: 100%;
|
|
46
|
-
height: var(--scroll-mask-size, 8px);
|
|
47
|
-
bottom: 0;
|
|
48
|
-
left: 50%;
|
|
49
|
-
transform: translateX(-50%);
|
|
50
|
-
--scroll-mask-direction: top;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
.left-scroll-mask {
|
|
54
|
-
width: 0;
|
|
55
|
-
height: 100%;
|
|
56
|
-
top: 0;
|
|
57
|
-
right: 100%;
|
|
58
|
-
bottom: 0;
|
|
59
|
-
left: 0;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
.left-scroll-mask-content {
|
|
63
|
-
width: var(--scroll-mask-size, 8px);
|
|
64
|
-
height: 100%;
|
|
65
|
-
left: 0;
|
|
66
|
-
top: 50%;
|
|
67
|
-
transform: translateY(-50%);
|
|
68
|
-
--scroll-mask-direction: right;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
.right-scroll-mask {
|
|
72
|
-
width: 0;
|
|
73
|
-
height: 100%;
|
|
74
|
-
top: 0;
|
|
75
|
-
right: 0;
|
|
76
|
-
bottom: 0;
|
|
77
|
-
left: 100%;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
.right-scroll-mask-content {
|
|
81
|
-
width: var(--scroll-mask-size, 8px);
|
|
82
|
-
height: 100%;
|
|
83
|
-
right: 0;
|
|
84
|
-
bottom: 50%;
|
|
85
|
-
transform: translateY(50%);
|
|
86
|
-
--scroll-mask-direction: left;
|
|
87
|
-
}
|
|
1
|
+
.scroll-mask {
|
|
2
|
+
position: sticky;
|
|
3
|
+
z-index: 10;
|
|
4
|
+
pointer-events: none;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
.top-scroll-mask {
|
|
8
|
+
width: 100%;
|
|
9
|
+
height: 0;
|
|
10
|
+
top: 0;
|
|
11
|
+
right: 0;
|
|
12
|
+
bottom: 100%;
|
|
13
|
+
left: 0;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.scroll-mask-content {
|
|
17
|
+
position: absolute;
|
|
18
|
+
background-image: linear-gradient(
|
|
19
|
+
to var(--scroll-mask-direction),
|
|
20
|
+
var(--scroll-mask-color-from, rgba(0, 0, 0, 0.1)),
|
|
21
|
+
var(--scroll-mask-color-to, rgba(0, 0, 0, 0))
|
|
22
|
+
);
|
|
23
|
+
clip-path: var(--scroll-mask-clip-path, none);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.top-scroll-mask-content {
|
|
27
|
+
width: 100%;
|
|
28
|
+
height: var(--scroll-mask-size, 8px);
|
|
29
|
+
top: 0;
|
|
30
|
+
right: 50%;
|
|
31
|
+
transform: translateX(50%);
|
|
32
|
+
--scroll-mask-direction: bottom;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.bottom-scroll-mask {
|
|
36
|
+
width: 100%;
|
|
37
|
+
height: 0;
|
|
38
|
+
top: 100%;
|
|
39
|
+
right: 0;
|
|
40
|
+
bottom: 0;
|
|
41
|
+
left: 0;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.bottom-scroll-mask-content {
|
|
45
|
+
width: 100%;
|
|
46
|
+
height: var(--scroll-mask-size, 8px);
|
|
47
|
+
bottom: 0;
|
|
48
|
+
left: 50%;
|
|
49
|
+
transform: translateX(-50%);
|
|
50
|
+
--scroll-mask-direction: top;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.left-scroll-mask {
|
|
54
|
+
width: 0;
|
|
55
|
+
height: 100%;
|
|
56
|
+
top: 0;
|
|
57
|
+
right: 100%;
|
|
58
|
+
bottom: 0;
|
|
59
|
+
left: 0;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.left-scroll-mask-content {
|
|
63
|
+
width: var(--scroll-mask-size, 8px);
|
|
64
|
+
height: 100%;
|
|
65
|
+
left: 0;
|
|
66
|
+
top: 50%;
|
|
67
|
+
transform: translateY(-50%);
|
|
68
|
+
--scroll-mask-direction: right;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.right-scroll-mask {
|
|
72
|
+
width: 0;
|
|
73
|
+
height: 100%;
|
|
74
|
+
top: 0;
|
|
75
|
+
right: 0;
|
|
76
|
+
bottom: 0;
|
|
77
|
+
left: 100%;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
.right-scroll-mask-content {
|
|
81
|
+
width: var(--scroll-mask-size, 8px);
|
|
82
|
+
height: 100%;
|
|
83
|
+
right: 0;
|
|
84
|
+
bottom: 50%;
|
|
85
|
+
transform: translateY(50%);
|
|
86
|
+
--scroll-mask-direction: left;
|
|
87
|
+
}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
"use client"
|
|
2
|
-
|
|
3
|
-
import { WriteSheet, WriteSheetProps } from "./WriteSheet"
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* @deprecated 请使用 WriteSheetProps 代替
|
|
7
|
-
*/
|
|
8
|
-
export type WriteExcelProps = WriteSheetProps
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* @deprecated 请使用 WriteSheet 代替
|
|
12
|
-
*/
|
|
13
|
-
export const WriteExcel = WriteSheet
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import { WriteSheet, WriteSheetProps } from "./WriteSheet"
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @deprecated 请使用 WriteSheetProps 代替
|
|
7
|
+
*/
|
|
8
|
+
export type WriteExcelProps = WriteSheetProps
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* @deprecated 请使用 WriteSheet 代替
|
|
12
|
+
*/
|
|
13
|
+
export const WriteExcel = WriteSheet
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { version } from "react"
|
|
2
|
-
|
|
3
|
-
const reg = /(\d+)\.(\d+)\.(\d+)/
|
|
4
|
-
|
|
5
|
-
export function getReactVersion() {
|
|
6
|
-
return version.match(reg)!.slice(1).map(Number)
|
|
7
|
-
}
|
|
1
|
+
import { version } from "react"
|
|
2
|
+
|
|
3
|
+
const reg = /(\d+)\.(\d+)\.(\d+)/
|
|
4
|
+
|
|
5
|
+
export function getReactVersion() {
|
|
6
|
+
return version.match(reg)!.slice(1).map(Number)
|
|
7
|
+
}
|
package/src/utils/index.ts
CHANGED
|
@@ -1,33 +1,33 @@
|
|
|
1
|
-
import { CSSProperties } from "react"
|
|
2
|
-
|
|
3
|
-
export type CSSVariableName = `--${string}`
|
|
4
|
-
|
|
5
|
-
export type CSSVariableValue = string | number | undefined
|
|
6
|
-
|
|
7
|
-
export interface StyleWithCSSVariable extends CSSProperties {
|
|
8
|
-
[X: CSSVariableName]: CSSVariableValue
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
const cssVariableReg = /[A-Z]/
|
|
12
|
-
|
|
13
|
-
function addCSSVariableLine(match: string): string {
|
|
14
|
-
return `-${match}`
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export function transformCSSVariableName(name: string): CSSVariableName {
|
|
18
|
-
return `--${name.replace(cssVariableReg, addCSSVariableLine).toLowerCase()}`
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export function transformCSSVariable(style: Partial<Record<string, CSSVariableValue>>, style2?: CSSProperties): CSSProperties {
|
|
22
|
-
return Object.assign(
|
|
23
|
-
Object.entries(style).reduce((acc: StyleWithCSSVariable, [key, value]) => {
|
|
24
|
-
acc[transformCSSVariableName(key)] = value
|
|
25
|
-
return acc
|
|
26
|
-
}, {}),
|
|
27
|
-
style2,
|
|
28
|
-
)
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export function px(value: string | number | undefined): string | undefined {
|
|
32
|
-
return typeof value === "number" ? `${value}px` : value
|
|
33
|
-
}
|
|
1
|
+
import { CSSProperties } from "react"
|
|
2
|
+
|
|
3
|
+
export type CSSVariableName = `--${string}`
|
|
4
|
+
|
|
5
|
+
export type CSSVariableValue = string | number | undefined
|
|
6
|
+
|
|
7
|
+
export interface StyleWithCSSVariable extends CSSProperties {
|
|
8
|
+
[X: CSSVariableName]: CSSVariableValue
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const cssVariableReg = /[A-Z]/
|
|
12
|
+
|
|
13
|
+
function addCSSVariableLine(match: string): string {
|
|
14
|
+
return `-${match}`
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function transformCSSVariableName(name: string): CSSVariableName {
|
|
18
|
+
return `--${name.replace(cssVariableReg, addCSSVariableLine).toLowerCase()}`
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function transformCSSVariable(style: Partial<Record<string, CSSVariableValue>>, style2?: CSSProperties): CSSProperties {
|
|
22
|
+
return Object.assign(
|
|
23
|
+
Object.entries(style).reduce((acc: StyleWithCSSVariable, [key, value]) => {
|
|
24
|
+
acc[transformCSSVariableName(key)] = value
|
|
25
|
+
return acc
|
|
26
|
+
}, {}),
|
|
27
|
+
style2,
|
|
28
|
+
)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function px(value: string | number | undefined): string | undefined {
|
|
32
|
+
return typeof value === "number" ? `${value}px` : value
|
|
33
|
+
}
|