gbs-add-block 0.0.5 → 0.0.7
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
CHANGED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Grampro Business Services and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import React from "react";
|
|
9
|
+
|
|
10
|
+
const AestheticProcessingAnimation = () => {
|
|
11
|
+
return (
|
|
12
|
+
<div className="w-full max-w-md mx-auto p-2">
|
|
13
|
+
<div className="w-full h-1 bg-gray-200 rounded-full overflow-hidden">
|
|
14
|
+
<div className="h-full w-1/3 bg-black rounded-full animate-processing"></div>
|
|
15
|
+
</div>
|
|
16
|
+
<p className="text-xs mt-2 text-center">
|
|
17
|
+
Uploading in Progress, Please Wait...
|
|
18
|
+
</p>
|
|
19
|
+
</div>
|
|
20
|
+
);
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const AestheticProcessingAnimationWithStyles = () => (
|
|
24
|
+
<>
|
|
25
|
+
<style jsx global>{`
|
|
26
|
+
@keyframes processing {
|
|
27
|
+
0% {
|
|
28
|
+
transform: translateX(-100%);
|
|
29
|
+
}
|
|
30
|
+
100% {
|
|
31
|
+
transform: translateX(300%);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
.animate-processing {
|
|
35
|
+
animation: processing 2s ease-in-out infinite;
|
|
36
|
+
}
|
|
37
|
+
`}</style>
|
|
38
|
+
<AestheticProcessingAnimation />
|
|
39
|
+
</>
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
export default AestheticProcessingAnimationWithStyles;
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Grampro Business Services and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import React, { useState, useRef, useEffect } from "react";
|
|
9
|
+
import { upload, x } from "../../icon/iconPaths";
|
|
10
|
+
import Icon from "../../icon/Icon";
|
|
11
|
+
import { GetFileIcon } from "./uploaderIcon";
|
|
12
|
+
import AestheticProcessingAnimationWithStyles from "./ProgressAnimation";
|
|
13
|
+
|
|
14
|
+
export const FileUploader = ({
|
|
15
|
+
showImagePreview = false,
|
|
16
|
+
multiple = true,
|
|
17
|
+
onChange,
|
|
18
|
+
startsUpload = false,
|
|
19
|
+
selectedFiles = [],
|
|
20
|
+
}: any) => {
|
|
21
|
+
const [files, setFiles] = useState<any[]>([]);
|
|
22
|
+
const [previewUrls, setPreviewUrls] = useState<{ [key: string]: string }>({});
|
|
23
|
+
const fileInputRef = useRef<any>(null);
|
|
24
|
+
|
|
25
|
+
useEffect(() => {
|
|
26
|
+
if (selectedFiles && selectedFiles.length > 0) {
|
|
27
|
+
setFiles(selectedFiles);
|
|
28
|
+
}
|
|
29
|
+
}, [selectedFiles]);
|
|
30
|
+
|
|
31
|
+
// adds files to file array
|
|
32
|
+
const handleFileChange = (e: any) => {
|
|
33
|
+
const selectedFiles = Array.from(e.target.files);
|
|
34
|
+
const newPreviewUrls = { ...previewUrls };
|
|
35
|
+
|
|
36
|
+
selectedFiles.forEach((file: any) => {
|
|
37
|
+
if (showImagePreview && file.type.startsWith("image/")) {
|
|
38
|
+
const reader = new FileReader();
|
|
39
|
+
reader.onload = () => {
|
|
40
|
+
newPreviewUrls[file.name] = reader.result as string;
|
|
41
|
+
setPreviewUrls(newPreviewUrls);
|
|
42
|
+
};
|
|
43
|
+
reader.readAsDataURL(file);
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
const updatedFiles = [...files, ...selectedFiles];
|
|
48
|
+
setFiles(updatedFiles);
|
|
49
|
+
|
|
50
|
+
if (onChange) onChange(updatedFiles);
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
// remove file from the file array
|
|
54
|
+
const removeFile = (index: any) => {
|
|
55
|
+
const fileToRemove = files[index];
|
|
56
|
+
const updatedFiles = files.filter((_, i) => i !== index);
|
|
57
|
+
|
|
58
|
+
setFiles(updatedFiles);
|
|
59
|
+
setPreviewUrls((prevPreviews) => {
|
|
60
|
+
const { [fileToRemove.name]: _, ...rest } = prevPreviews;
|
|
61
|
+
return rest;
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
if (onChange) onChange(updatedFiles);
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
return (
|
|
68
|
+
<div className="w-full max-w-md mx-auto">
|
|
69
|
+
<div
|
|
70
|
+
className="flex flex-col items-center border-2 border-dashed border-gray-300 rounded-lg p-4 text-center cursor-pointer hover:border-gray-400 transition-colors"
|
|
71
|
+
onClick={() => fileInputRef.current.click()}
|
|
72
|
+
>
|
|
73
|
+
<Icon
|
|
74
|
+
dimensions={{ width: "36", height: "36" }}
|
|
75
|
+
elements={upload}
|
|
76
|
+
svgClass={"stroke-gray-400 fill-none dark:stroke-white"}
|
|
77
|
+
/>
|
|
78
|
+
<p className="mt-2 text-sm text-gray-500">
|
|
79
|
+
Click to upload or drag and drop
|
|
80
|
+
</p>
|
|
81
|
+
{multiple && (
|
|
82
|
+
<p className="text-xs text-gray-400">
|
|
83
|
+
Supports multiple file uploads
|
|
84
|
+
</p>
|
|
85
|
+
)}
|
|
86
|
+
</div>
|
|
87
|
+
<input
|
|
88
|
+
type="file"
|
|
89
|
+
ref={fileInputRef}
|
|
90
|
+
className="hidden"
|
|
91
|
+
onChange={handleFileChange}
|
|
92
|
+
multiple={multiple}
|
|
93
|
+
/>
|
|
94
|
+
|
|
95
|
+
{startsUpload && <AestheticProcessingAnimationWithStyles />}
|
|
96
|
+
|
|
97
|
+
{files.length > 0 && (
|
|
98
|
+
<div className="mt-4 space-y-2">
|
|
99
|
+
{files.map((file: any, index) => (
|
|
100
|
+
<div
|
|
101
|
+
key={index}
|
|
102
|
+
className="flex items-center justify-between bg-gray-50 p-2 rounded-md"
|
|
103
|
+
>
|
|
104
|
+
<div className="flex items-center space-x-2">
|
|
105
|
+
<GetFileIcon
|
|
106
|
+
file={file}
|
|
107
|
+
showImagePreview={showImagePreview}
|
|
108
|
+
previewUrls={previewUrls}
|
|
109
|
+
/>
|
|
110
|
+
<div>
|
|
111
|
+
<p className="text-sm font-medium text-gray-700">
|
|
112
|
+
{file.name}
|
|
113
|
+
</p>
|
|
114
|
+
<p className="text-xs text-gray-500">
|
|
115
|
+
{(file.size / 1024 / 1024).toFixed(2)} MB
|
|
116
|
+
</p>
|
|
117
|
+
</div>
|
|
118
|
+
</div>
|
|
119
|
+
<button
|
|
120
|
+
type="button"
|
|
121
|
+
onClick={() => removeFile(index)}
|
|
122
|
+
className="text-red-500 hover:text-red-700 transition-colors"
|
|
123
|
+
>
|
|
124
|
+
<Icon
|
|
125
|
+
dimensions={{ width: "16", height: "16" }}
|
|
126
|
+
elements={x}
|
|
127
|
+
svgClass={"stroke-red-500 fill-none dark:stroke-white"}
|
|
128
|
+
/>
|
|
129
|
+
</button>
|
|
130
|
+
</div>
|
|
131
|
+
))}
|
|
132
|
+
</div>
|
|
133
|
+
)}
|
|
134
|
+
</div>
|
|
135
|
+
);
|
|
136
|
+
};
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Grampro Business Services and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import {
|
|
9
|
+
fileimage,
|
|
10
|
+
filespreadsheet,
|
|
11
|
+
filetext,
|
|
12
|
+
film,
|
|
13
|
+
music,
|
|
14
|
+
} from "../../icon/iconPaths";
|
|
15
|
+
import Icon from "../../icon/Icon";
|
|
16
|
+
|
|
17
|
+
// returns an icon based on the selected file type
|
|
18
|
+
export const GetFileIcon = ({ file, showImagePreview, previewUrls }: any) => {
|
|
19
|
+
if (file.type.startsWith("image/"))
|
|
20
|
+
return showImagePreview ? (
|
|
21
|
+
<img
|
|
22
|
+
src={previewUrls[file.name]}
|
|
23
|
+
alt={file.name}
|
|
24
|
+
className="mt-2 w-8 h-8 object-cover rounded-lg"
|
|
25
|
+
/>
|
|
26
|
+
) : (
|
|
27
|
+
<Icon
|
|
28
|
+
dimensions={{ width: "26", height: "26" }}
|
|
29
|
+
elements={fileimage}
|
|
30
|
+
svgClass={"stroke-blue-500 fill-none dark:stroke-white"}
|
|
31
|
+
/>
|
|
32
|
+
);
|
|
33
|
+
if (file.type === "application/pdf")
|
|
34
|
+
return (
|
|
35
|
+
<Icon
|
|
36
|
+
dimensions={{ width: "26", height: "26" }}
|
|
37
|
+
elements={filetext}
|
|
38
|
+
svgClass={"stroke-red-500 fill-none dark:stroke-white"}
|
|
39
|
+
/>
|
|
40
|
+
);
|
|
41
|
+
if (file.type.includes("spreadsheet") || file.type.includes("excel"))
|
|
42
|
+
return (
|
|
43
|
+
<Icon
|
|
44
|
+
dimensions={{ width: "26", height: "26" }}
|
|
45
|
+
elements={filespreadsheet}
|
|
46
|
+
svgClass={"stroke-green-500 fill-none dark:stroke-white"}
|
|
47
|
+
/>
|
|
48
|
+
);
|
|
49
|
+
if (file.type.startsWith("video/"))
|
|
50
|
+
return (
|
|
51
|
+
<Icon
|
|
52
|
+
dimensions={{ width: "26", height: "26" }}
|
|
53
|
+
elements={film}
|
|
54
|
+
svgClass={"stroke-purple-500 fill-none dark:stroke-white"}
|
|
55
|
+
/>
|
|
56
|
+
);
|
|
57
|
+
if (file.type.startsWith("audio/"))
|
|
58
|
+
return (
|
|
59
|
+
<Icon
|
|
60
|
+
dimensions={{ width: "26", height: "26" }}
|
|
61
|
+
elements={music}
|
|
62
|
+
svgClass={"stroke-yellow-500 fill-none dark:stroke-white"}
|
|
63
|
+
/>
|
|
64
|
+
);
|
|
65
|
+
return (
|
|
66
|
+
<Icon
|
|
67
|
+
dimensions={{ width: "16", height: "16" }}
|
|
68
|
+
elements={filetext}
|
|
69
|
+
svgClass={"stroke-red-500 fill-none dark:stroke-white"}
|
|
70
|
+
/>
|
|
71
|
+
);
|
|
72
|
+
};
|
package/source/icon/iconPaths.ts
CHANGED
|
@@ -90,3 +90,79 @@ export let sun: any = [
|
|
|
90
90
|
export let moon: any = [
|
|
91
91
|
{ type: "path", d: "M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z", key: "a7tn18" },
|
|
92
92
|
];
|
|
93
|
+
|
|
94
|
+
export const upload: any = [
|
|
95
|
+
{
|
|
96
|
+
type: "path",
|
|
97
|
+
d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4",
|
|
98
|
+
key: "ih7n3h",
|
|
99
|
+
},
|
|
100
|
+
{ type: "polyline", points: "17 8 12 3 7 8", key: "t8dd8p" },
|
|
101
|
+
{ type: "line", x1: "12", x2: "12", y1: "3", y2: "15", key: "widbto" },
|
|
102
|
+
];
|
|
103
|
+
|
|
104
|
+
export const filetext: any = [
|
|
105
|
+
{
|
|
106
|
+
type: "path",
|
|
107
|
+
d: "M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z",
|
|
108
|
+
key: "1rqfz7",
|
|
109
|
+
},
|
|
110
|
+
{ type: "path", d: "M14 2v4a2 2 0 0 0 2 2h4", key: "tnqrlb" },
|
|
111
|
+
{ type: "path", d: "M10 9H8", key: "b1mrlr" },
|
|
112
|
+
{ type: "path", d: "M16 13H8", key: "t4e002" },
|
|
113
|
+
{ type: "path", d: "M16 17H8", key: "z1uh3a" },
|
|
114
|
+
];
|
|
115
|
+
|
|
116
|
+
export const fileimage: any = [
|
|
117
|
+
{
|
|
118
|
+
type: "path",
|
|
119
|
+
d: "M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z",
|
|
120
|
+
key: "1rqfz7",
|
|
121
|
+
},
|
|
122
|
+
{ type: "path", d: "M14 2v4a2 2 0 0 0 2 2h4", key: "tnqrlb" },
|
|
123
|
+
{ type: "circle", cx: "10", cy: "12", r: "2", key: "737tya" },
|
|
124
|
+
{
|
|
125
|
+
type: "path",
|
|
126
|
+
d: "m20 17-1.296-1.296a2.41 2.41 0 0 0-3.408 0L9 22",
|
|
127
|
+
key: "wt3hpn",
|
|
128
|
+
},
|
|
129
|
+
];
|
|
130
|
+
|
|
131
|
+
export const music: any = [
|
|
132
|
+
{ type: "path", d: "M9 18V5l12-2v13", key: "1jmyc2" },
|
|
133
|
+
{ type: "circle", cx: "6", cy: "18", r: "3", key: "fqmcym" },
|
|
134
|
+
{ type: "circle", cx: "18", cy: "16", r: "3", key: "1hluhg" },
|
|
135
|
+
];
|
|
136
|
+
|
|
137
|
+
export const film: any = [
|
|
138
|
+
{
|
|
139
|
+
type: "rect",
|
|
140
|
+
width: "18",
|
|
141
|
+
height: "18",
|
|
142
|
+
x: "3",
|
|
143
|
+
y: "3",
|
|
144
|
+
rx: "2",
|
|
145
|
+
key: "afitv7",
|
|
146
|
+
},
|
|
147
|
+
{ type: "path", d: "M7 3v18", key: "bbkbws" },
|
|
148
|
+
{ type: "path", d: "M3 7.5h4", key: "zfgn84" },
|
|
149
|
+
{ type: "path", d: "M3 12h18", key: "1i2n21" },
|
|
150
|
+
{ type: "path", d: "M3 16.5h4", key: "1230mu" },
|
|
151
|
+
{ type: "path", d: "M17 3v18", key: "in4fa5" },
|
|
152
|
+
{ type: "path", d: "M17 7.5h4", key: "myr1c1" },
|
|
153
|
+
{ type: "path", d: "M17 16.5h4", key: "go4c1d" },
|
|
154
|
+
];
|
|
155
|
+
|
|
156
|
+
export const filespreadsheet: any = [
|
|
157
|
+
{
|
|
158
|
+
type: "path",
|
|
159
|
+
d: "M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z",
|
|
160
|
+
key: "1rqfz7",
|
|
161
|
+
},
|
|
162
|
+
,
|
|
163
|
+
{ type: "path", d: "M14 2v4a2 2 0 0 0 2 2h4", key: "tnqrlb" },
|
|
164
|
+
{ type: "path", d: "M8 13h2", key: "yr2amv" },
|
|
165
|
+
{ type: "path", d: "M14 13h2", key: "un5t4a" },
|
|
166
|
+
{ type: "path", d: "M8 17h2", key: "2yhykz" },
|
|
167
|
+
{ type: "path", d: "M14 17h2", key: "10kma7" },
|
|
168
|
+
];
|