forstok-ui-lib 8.6.3 → 8.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +8 -2
- package/dist/index.js +479 -427
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +480 -428
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/assets/javascripts/function.ts +139 -0
- package/src/assets/stylesheets/bases.styles.ts +40 -41
- package/src/components/upload/drag.drop.tsx +279 -44
- package/src/components/upload/styles.tsx +114 -45
package/package.json
CHANGED
|
@@ -1130,3 +1130,142 @@ export const evCheckAllValidationByHeaderWithVariant = (
|
|
|
1130
1130
|
}
|
|
1131
1131
|
return { error: isError, data: _newData };
|
|
1132
1132
|
};
|
|
1133
|
+
|
|
1134
|
+
export const getFileType = (file?: File | null): string => {
|
|
1135
|
+
if (!file) return "";
|
|
1136
|
+
|
|
1137
|
+
const mimeType = (file.type || "").toLowerCase();
|
|
1138
|
+
const fileName = file.name.toLowerCase();
|
|
1139
|
+
const extension = fileName.includes(".")
|
|
1140
|
+
? fileName.split(".").pop() || ""
|
|
1141
|
+
: "";
|
|
1142
|
+
|
|
1143
|
+
if (mimeType.includes("image/")) return "image";
|
|
1144
|
+
if (mimeType.includes("video/")) return "video";
|
|
1145
|
+
if (mimeType.includes("audio/")) return "audio";
|
|
1146
|
+
if (mimeType.includes("application/pdf")) return "pdf";
|
|
1147
|
+
if (mimeType.includes("text/csv")) return "csv";
|
|
1148
|
+
if (mimeType.includes("text/plain")) return "text";
|
|
1149
|
+
if (mimeType.includes("text/html")) return "html";
|
|
1150
|
+
if (mimeType.includes("text/xml") || mimeType.includes("application/xml"))
|
|
1151
|
+
return "xml";
|
|
1152
|
+
if (mimeType.includes("application/json") || mimeType.includes("text/json"))
|
|
1153
|
+
return "json";
|
|
1154
|
+
if (
|
|
1155
|
+
mimeType.includes("application/zip") ||
|
|
1156
|
+
mimeType.includes("application/x-zip-compressed")
|
|
1157
|
+
)
|
|
1158
|
+
return "zip";
|
|
1159
|
+
if (
|
|
1160
|
+
mimeType.includes("application/x-rar") ||
|
|
1161
|
+
mimeType.includes("application/vnd.rar")
|
|
1162
|
+
)
|
|
1163
|
+
return "rar";
|
|
1164
|
+
if (mimeType.includes("application/x-7z-compressed")) return "7z";
|
|
1165
|
+
if (mimeType.includes("application/x-tar")) return "tar";
|
|
1166
|
+
if (
|
|
1167
|
+
mimeType.includes("application/gzip") ||
|
|
1168
|
+
mimeType.includes("application/x-gzip")
|
|
1169
|
+
)
|
|
1170
|
+
return "gzip";
|
|
1171
|
+
|
|
1172
|
+
if (
|
|
1173
|
+
mimeType.includes("application/vnd.ms-excel") ||
|
|
1174
|
+
mimeType.includes(
|
|
1175
|
+
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
|
1176
|
+
) ||
|
|
1177
|
+
mimeType.includes("application/vnd.oasis.opendocument.spreadsheet")
|
|
1178
|
+
) {
|
|
1179
|
+
return "sheet";
|
|
1180
|
+
}
|
|
1181
|
+
|
|
1182
|
+
if (
|
|
1183
|
+
mimeType.includes("application/msword") ||
|
|
1184
|
+
mimeType.includes(
|
|
1185
|
+
"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
|
1186
|
+
) ||
|
|
1187
|
+
mimeType.includes("application/vnd.oasis.opendocument.text") ||
|
|
1188
|
+
mimeType.includes("application/rtf")
|
|
1189
|
+
) {
|
|
1190
|
+
return "word";
|
|
1191
|
+
}
|
|
1192
|
+
|
|
1193
|
+
if (
|
|
1194
|
+
mimeType.includes("application/vnd.ms-powerpoint") ||
|
|
1195
|
+
mimeType.includes(
|
|
1196
|
+
"application/vnd.openxmlformats-officedocument.presentationml.presentation",
|
|
1197
|
+
) ||
|
|
1198
|
+
mimeType.includes("application/vnd.oasis.opendocument.presentation")
|
|
1199
|
+
) {
|
|
1200
|
+
return "powerpoint";
|
|
1201
|
+
}
|
|
1202
|
+
|
|
1203
|
+
if (mimeType.includes("application/epub+zip")) return "epub";
|
|
1204
|
+
|
|
1205
|
+
switch (extension) {
|
|
1206
|
+
case "jpg":
|
|
1207
|
+
case "jpeg":
|
|
1208
|
+
case "png":
|
|
1209
|
+
case "gif":
|
|
1210
|
+
case "webp":
|
|
1211
|
+
case "bmp":
|
|
1212
|
+
case "svg":
|
|
1213
|
+
case "heic":
|
|
1214
|
+
case "heif":
|
|
1215
|
+
return "image";
|
|
1216
|
+
case "mp4":
|
|
1217
|
+
case "mov":
|
|
1218
|
+
case "avi":
|
|
1219
|
+
case "mkv":
|
|
1220
|
+
case "webm":
|
|
1221
|
+
case "m4v":
|
|
1222
|
+
return "video";
|
|
1223
|
+
case "mp3":
|
|
1224
|
+
case "wav":
|
|
1225
|
+
case "ogg":
|
|
1226
|
+
case "m4a":
|
|
1227
|
+
case "aac":
|
|
1228
|
+
case "flac":
|
|
1229
|
+
return "audio";
|
|
1230
|
+
case "pdf":
|
|
1231
|
+
return "pdf";
|
|
1232
|
+
case "csv":
|
|
1233
|
+
return "csv";
|
|
1234
|
+
case "txt":
|
|
1235
|
+
return "text";
|
|
1236
|
+
case "html":
|
|
1237
|
+
case "htm":
|
|
1238
|
+
return "html";
|
|
1239
|
+
case "xml":
|
|
1240
|
+
return "xml";
|
|
1241
|
+
case "json":
|
|
1242
|
+
return "json";
|
|
1243
|
+
case "xls":
|
|
1244
|
+
case "xlsx":
|
|
1245
|
+
case "ods":
|
|
1246
|
+
return "sheet";
|
|
1247
|
+
case "doc":
|
|
1248
|
+
case "docx":
|
|
1249
|
+
case "odt":
|
|
1250
|
+
case "rtf":
|
|
1251
|
+
return "word";
|
|
1252
|
+
case "ppt":
|
|
1253
|
+
case "pptx":
|
|
1254
|
+
case "odp":
|
|
1255
|
+
return "powerpoint";
|
|
1256
|
+
case "zip":
|
|
1257
|
+
return "zip";
|
|
1258
|
+
case "rar":
|
|
1259
|
+
return "rar";
|
|
1260
|
+
case "7z":
|
|
1261
|
+
return "7z";
|
|
1262
|
+
case "tar":
|
|
1263
|
+
return "tar";
|
|
1264
|
+
case "gz":
|
|
1265
|
+
return "gzip";
|
|
1266
|
+
case "epub":
|
|
1267
|
+
return "epub";
|
|
1268
|
+
default:
|
|
1269
|
+
return mimeType.includes("application/") ? "document" : "";
|
|
1270
|
+
}
|
|
1271
|
+
};
|
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
import { css } from
|
|
1
|
+
import { css } from "styled-components";
|
|
2
2
|
|
|
3
|
-
import IconEditWhite from
|
|
4
|
-
import IconLoadingRed from
|
|
3
|
+
import IconEditWhite from "../../assets/images/icons/edit-white.svg";
|
|
4
|
+
import IconLoadingRed from "../../assets/images/icons/loading-red.svg";
|
|
5
5
|
|
|
6
6
|
export const clearList = css`
|
|
7
7
|
list-style: none;
|
|
8
8
|
padding: 0;
|
|
9
9
|
margin: 0;
|
|
10
|
-
|
|
11
|
-
export const responseWidth = css
|
|
10
|
+
`;
|
|
11
|
+
export const responseWidth = css`
|
|
12
12
|
width: 100%;
|
|
13
|
-
|
|
14
|
-
export const elipsis = css
|
|
13
|
+
`;
|
|
14
|
+
export const elipsis = css`
|
|
15
15
|
overflow: hidden;
|
|
16
16
|
text-overflow: ellipsis;
|
|
17
17
|
white-space: nowrap;
|
|
18
18
|
display: block;
|
|
19
19
|
max-width: 100%;
|
|
20
20
|
width: auto;
|
|
21
|
-
|
|
21
|
+
`;
|
|
22
22
|
export const multiElipsis = css`
|
|
23
23
|
display: -webkit-box !important;
|
|
24
24
|
-webkit-line-clamp: 2;
|
|
@@ -28,7 +28,7 @@ export const multiElipsis = css`
|
|
|
28
28
|
overflow-wrap: anywhere;
|
|
29
29
|
word-break: break-all;
|
|
30
30
|
line-height: 16px;
|
|
31
|
-
|
|
31
|
+
`;
|
|
32
32
|
export const thirdElipsis = css`
|
|
33
33
|
display: -webkit-box !important;
|
|
34
34
|
-webkit-line-clamp: 3 !important;
|
|
@@ -38,46 +38,55 @@ export const thirdElipsis = css`
|
|
|
38
38
|
overflow-wrap: anywhere !important;
|
|
39
39
|
word-break: break-word !important;
|
|
40
40
|
line-height: 16px;
|
|
41
|
-
|
|
41
|
+
`;
|
|
42
42
|
export const dropBase = css`
|
|
43
43
|
background-color: var(--sec-clr-bg);
|
|
44
44
|
border: 1px solid var(--sec-clr-ln);
|
|
45
45
|
box-shadow: var(--sec-shd-bx);
|
|
46
46
|
border-radius: var(--sec-rd);
|
|
47
|
-
|
|
47
|
+
`;
|
|
48
48
|
export const headTable = css`
|
|
49
49
|
font-size: 12px;
|
|
50
50
|
font-weight: 600;
|
|
51
51
|
text-transform: capitalize;
|
|
52
|
-
|
|
52
|
+
`;
|
|
53
53
|
export const formLabel = css`
|
|
54
54
|
color: var(--hd-clr);
|
|
55
55
|
font-weight: 600;
|
|
56
56
|
font-size: 13px;
|
|
57
57
|
text-transform: capitalize;
|
|
58
|
-
|
|
58
|
+
`;
|
|
59
59
|
export const buttonStyle = css`
|
|
60
60
|
border: none;
|
|
61
|
-
border-radius: .5rem;
|
|
62
|
-
box-shadow:
|
|
61
|
+
border-radius: 0.5rem;
|
|
62
|
+
box-shadow:
|
|
63
|
+
0rem -0.0625rem 0rem 0rem #b5b5b5 inset,
|
|
64
|
+
0rem 0rem 0rem 0.0625rem rgba(0, 0, 0, 0.1) inset,
|
|
65
|
+
0rem 0.03125rem 0rem 0.09375rem #fff inset;
|
|
63
66
|
color: rgba(74, 74, 74, 1);
|
|
64
67
|
cursor: pointer;
|
|
65
68
|
user-select: none;
|
|
66
69
|
touch-action: manipulation;
|
|
67
|
-
background-color: #ffffff;
|
|
68
|
-
|
|
70
|
+
background-color: #ffffff;
|
|
71
|
+
`;
|
|
69
72
|
export const buttonHoverStyle = css`
|
|
70
73
|
color: rgba(48, 48, 48, 1);
|
|
71
74
|
background-color: rgba(250, 250, 250, 1);
|
|
72
|
-
|
|
75
|
+
`;
|
|
73
76
|
export const buttonActiveStyle = css`
|
|
74
77
|
color: rgba(48, 48, 48, 1);
|
|
75
78
|
background: rgba(247, 247, 247, 1);
|
|
76
|
-
box-shadow:
|
|
77
|
-
|
|
79
|
+
box-shadow:
|
|
80
|
+
-0.0625rem 0rem 0.0625rem 0rem rgba(26, 26, 26, 0.122) inset,
|
|
81
|
+
0.0625rem 0rem 0.0625rem 0rem rgba(26, 26, 26, 0.122) inset,
|
|
82
|
+
0rem 0.125rem 0.0625rem 0rem rgba(26, 26, 26, 0.2) inset;
|
|
83
|
+
`;
|
|
78
84
|
export const buttonActiveShadowStyle = css`
|
|
79
|
-
box-shadow:
|
|
80
|
-
|
|
85
|
+
box-shadow:
|
|
86
|
+
-0.0625rem 0rem 0.0625rem 0rem rgba(26, 26, 26, 0.122) inset,
|
|
87
|
+
0.0625rem 0rem 0.0625rem 0rem rgba(26, 26, 26, 0.122) inset,
|
|
88
|
+
0rem 0.125rem 0.0625rem 0rem rgba(26, 26, 26, 0.2) inset;
|
|
89
|
+
`;
|
|
81
90
|
export const commonCSSLists = css`
|
|
82
91
|
.table-image-figure {
|
|
83
92
|
display: block;
|
|
@@ -89,7 +98,9 @@ export const commonCSSLists = css`
|
|
|
89
98
|
border: 1px solid var(--pri-clr-ln);
|
|
90
99
|
background-color: var(--pri-clr-bg);
|
|
91
100
|
border-radius: var(--ter-rd);
|
|
92
|
-
&.edit,
|
|
101
|
+
&.edit,
|
|
102
|
+
&.add,
|
|
103
|
+
&.loading {
|
|
93
104
|
width: 70px;
|
|
94
105
|
height: 70px;
|
|
95
106
|
cursor: pointer;
|
|
@@ -113,10 +124,10 @@ export const commonCSSLists = css`
|
|
|
113
124
|
}
|
|
114
125
|
}
|
|
115
126
|
&.edit {
|
|
116
|
-
border: 1px solid rgba(0, 0, 0, .04);
|
|
127
|
+
border: 1px solid rgba(0, 0, 0, 0.04);
|
|
117
128
|
&:hover {
|
|
118
129
|
position: relative;
|
|
119
|
-
span {
|
|
130
|
+
span {
|
|
120
131
|
width: 100%;
|
|
121
132
|
height: 100%;
|
|
122
133
|
position: absolute;
|
|
@@ -125,7 +136,7 @@ export const commonCSSLists = css`
|
|
|
125
136
|
z-index: 1;
|
|
126
137
|
background-color: var(--ov-clr-bg);
|
|
127
138
|
}
|
|
128
|
-
&::after {
|
|
139
|
+
&::after {
|
|
129
140
|
content: url(${IconEditWhite});
|
|
130
141
|
height: 14px;
|
|
131
142
|
width: 14px;
|
|
@@ -140,9 +151,9 @@ export const commonCSSLists = css`
|
|
|
140
151
|
}
|
|
141
152
|
}
|
|
142
153
|
&.loading {
|
|
143
|
-
border: 1px solid rgba(0, 0, 0, .04);
|
|
154
|
+
border: 1px solid rgba(0, 0, 0, 0.04);
|
|
144
155
|
cursor: default;
|
|
145
|
-
&::after {
|
|
156
|
+
&::after {
|
|
146
157
|
content: url(${IconLoadingRed});
|
|
147
158
|
height: 14px;
|
|
148
159
|
width: 14px;
|
|
@@ -163,19 +174,7 @@ export const commonCSSLists = css`
|
|
|
163
174
|
}
|
|
164
175
|
}
|
|
165
176
|
.remove {
|
|
166
|
-
font-style: normal;
|
|
167
|
-
position: absolute;
|
|
168
177
|
top: -6px;
|
|
169
178
|
right: -6px;
|
|
170
|
-
background: #000;
|
|
171
|
-
color: var(--sec-clr);
|
|
172
|
-
border-radius: 50%;
|
|
173
|
-
width: 14px;
|
|
174
|
-
height: 14px;
|
|
175
|
-
padding: 3px 5px;
|
|
176
|
-
font-weight: 600;
|
|
177
|
-
font-size: 7px;
|
|
178
|
-
z-index: 1;
|
|
179
|
-
cursor: pointer;
|
|
180
179
|
}
|
|
181
|
-
|
|
180
|
+
`;
|
|
@@ -1,44 +1,101 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
import {
|
|
2
|
+
type InputHTMLAttributes,
|
|
3
|
+
type ReactNode,
|
|
4
|
+
useEffect,
|
|
5
|
+
useRef,
|
|
6
|
+
useState,
|
|
7
|
+
} from "react";
|
|
8
|
+
import {
|
|
9
|
+
UploadDragDropContainer,
|
|
10
|
+
UploadDragDropFileHelper,
|
|
11
|
+
UploadDragDropFileContainer,
|
|
12
|
+
UploadDragDropFilePreviewCard,
|
|
13
|
+
UploadDragDropImagePreview,
|
|
14
|
+
UploadInput,
|
|
15
|
+
UploadDragDropLabel,
|
|
16
|
+
UploadDragDropFileName,
|
|
17
|
+
UploadDragDropFileNamePlaceholder,
|
|
18
|
+
UploadDragDropIcon,
|
|
19
|
+
} from "./styles";
|
|
20
|
+
import {
|
|
21
|
+
generateMessage,
|
|
22
|
+
getFileType,
|
|
23
|
+
} from "../../assets/javascripts/function";
|
|
24
|
+
import type { TMessageFunction } from "../message/typed";
|
|
25
|
+
import type { TChangeEvent, TDragEvent, TMouseEvent } from "../../typeds";
|
|
6
26
|
|
|
7
27
|
type TUpload = InputHTMLAttributes<HTMLInputElement> & {
|
|
8
|
-
children?: ReactNode
|
|
9
|
-
evChange?: (arg0: FileList) => void
|
|
10
|
-
evCreateMessage?: TMessageFunction
|
|
11
|
-
label?: string
|
|
12
|
-
|
|
28
|
+
children?: ReactNode;
|
|
29
|
+
evChange?: (arg0: FileList) => void;
|
|
30
|
+
evCreateMessage?: TMessageFunction;
|
|
31
|
+
label?: string;
|
|
32
|
+
subLabel?: string;
|
|
33
|
+
defaultValue?: string;
|
|
34
|
+
isValidFile?: boolean;
|
|
35
|
+
type?: string;
|
|
36
|
+
evRemove?: TMouseEvent;
|
|
37
|
+
};
|
|
13
38
|
|
|
14
|
-
|
|
39
|
+
type TFilePreview = {
|
|
40
|
+
fileSrc: string;
|
|
41
|
+
fileType: string;
|
|
42
|
+
previewKind: "image" | "file";
|
|
43
|
+
fileLabel: string;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
const UploadDragDropComponent = ({
|
|
47
|
+
children,
|
|
48
|
+
id,
|
|
49
|
+
name,
|
|
50
|
+
evChange,
|
|
51
|
+
evCreateMessage,
|
|
52
|
+
label,
|
|
53
|
+
subLabel,
|
|
54
|
+
type,
|
|
55
|
+
defaultValue,
|
|
56
|
+
isValidFile = true,
|
|
57
|
+
evRemove,
|
|
58
|
+
...props
|
|
59
|
+
}: TUpload) => {
|
|
15
60
|
const { accept } = props;
|
|
16
61
|
|
|
62
|
+
const inputRef = useRef<HTMLInputElement>(null);
|
|
63
|
+
const [valueFile, setValueFile] = useState<FileList>();
|
|
17
64
|
const [dragActive, setDragActive] = useState<boolean>(false);
|
|
65
|
+
const [filePreview, setFilePreview] = useState<TFilePreview>({
|
|
66
|
+
fileSrc: "",
|
|
67
|
+
fileType: "",
|
|
68
|
+
previewKind: "file",
|
|
69
|
+
fileLabel: "",
|
|
70
|
+
});
|
|
18
71
|
|
|
19
|
-
const handleDrag: TDragEvent = e => {
|
|
72
|
+
const handleDrag: TDragEvent = (e) => {
|
|
20
73
|
e.preventDefault();
|
|
21
74
|
e.stopPropagation();
|
|
22
75
|
if (e.type === "dragenter" || e.type === "dragover") {
|
|
23
76
|
setDragActive(true);
|
|
24
|
-
}
|
|
25
|
-
else if (e.type === "dragleave") {
|
|
77
|
+
} else if (e.type === "dragleave") {
|
|
26
78
|
setDragActive(false);
|
|
27
79
|
}
|
|
28
|
-
}
|
|
80
|
+
};
|
|
29
81
|
|
|
30
|
-
const handleDrop: TDragEvent = e => {
|
|
82
|
+
const handleDrop: TDragEvent = (e) => {
|
|
31
83
|
e.preventDefault();
|
|
32
84
|
e.stopPropagation();
|
|
33
85
|
setDragActive(false);
|
|
34
86
|
if (e.dataTransfer.files[0]) {
|
|
35
|
-
const acceptedFormat = accept
|
|
36
|
-
|
|
87
|
+
const acceptedFormat = accept
|
|
88
|
+
? accept.split(",").map((_accept) => _accept.trim().replace(".", ""))
|
|
89
|
+
: null;
|
|
90
|
+
for (let x = 0; x < e.dataTransfer.files.length; x++) {
|
|
37
91
|
const curFile = e.dataTransfer.files[x];
|
|
38
|
-
const curFormat = curFile.name.split(
|
|
92
|
+
const curFormat = curFile.name.split(".").pop();
|
|
39
93
|
if (acceptedFormat?.length && curFormat) {
|
|
40
94
|
if (!acceptedFormat.includes(curFormat)) {
|
|
41
|
-
const _failed_props = generateMessage(
|
|
95
|
+
const _failed_props = generateMessage(
|
|
96
|
+
"failed",
|
|
97
|
+
"File type is not allowed. Please check again",
|
|
98
|
+
);
|
|
42
99
|
evCreateMessage && evCreateMessage(_failed_props);
|
|
43
100
|
return false;
|
|
44
101
|
}
|
|
@@ -46,41 +103,219 @@ const UploadDragDropComponent = ({ children, id, name, evChange, evCreateMessage
|
|
|
46
103
|
}
|
|
47
104
|
evChange && evChange(e.dataTransfer.files);
|
|
48
105
|
}
|
|
49
|
-
}
|
|
106
|
+
};
|
|
50
107
|
|
|
51
|
-
const handleChange: TChangeEvent = e => {
|
|
108
|
+
const handleChange: TChangeEvent = (e) => {
|
|
52
109
|
e.preventDefault();
|
|
53
110
|
const target = e.target as HTMLInputElement;
|
|
54
111
|
if (target.files && target.files[0]) {
|
|
55
112
|
evChange && evChange(target.files);
|
|
113
|
+
setValueFile(target.files);
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
const handleRemove: TMouseEvent = (e) => {
|
|
118
|
+
e.preventDefault();
|
|
119
|
+
setValueFile(undefined);
|
|
120
|
+
setFilePreview({
|
|
121
|
+
fileSrc: "",
|
|
122
|
+
fileType: "",
|
|
123
|
+
previewKind: "file",
|
|
124
|
+
fileLabel: "",
|
|
125
|
+
});
|
|
126
|
+
if (inputRef.current) {
|
|
127
|
+
inputRef.current.value = "";
|
|
56
128
|
}
|
|
57
|
-
|
|
129
|
+
evRemove?.(e);
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
useEffect(() => {
|
|
133
|
+
let activeObjectUrl = "";
|
|
134
|
+
let isMounted = true;
|
|
135
|
+
|
|
136
|
+
const evGenerateThumbVideo = (videoFile: File): Promise<string> => {
|
|
137
|
+
return new Promise((resolve, reject) => {
|
|
138
|
+
const video = document.createElement("video");
|
|
139
|
+
const source = document.createElement("source");
|
|
140
|
+
const objectUrl = URL.createObjectURL(videoFile);
|
|
141
|
+
|
|
142
|
+
source.src = objectUrl;
|
|
143
|
+
source.type = videoFile.type;
|
|
144
|
+
activeObjectUrl = objectUrl;
|
|
145
|
+
|
|
146
|
+
video.appendChild(source);
|
|
147
|
+
video.muted = true;
|
|
148
|
+
video.playsInline = true;
|
|
149
|
+
video.preload = "metadata";
|
|
150
|
+
|
|
151
|
+
video.onloadedmetadata = () => {
|
|
152
|
+
const canvas = document.createElement("canvas");
|
|
153
|
+
canvas.width = video.videoWidth || 720;
|
|
154
|
+
canvas.height = video.videoHeight || 122;
|
|
155
|
+
|
|
156
|
+
video.currentTime = Math.min(0.1, video.duration || 0);
|
|
157
|
+
|
|
158
|
+
video.onseeked = () => {
|
|
159
|
+
const ctx = canvas.getContext("2d");
|
|
160
|
+
if (!ctx) {
|
|
161
|
+
reject(new Error("Canvas context is not available"));
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
|
|
166
|
+
resolve(canvas.toDataURL("image/jpeg"));
|
|
167
|
+
};
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
video.onerror = () => {
|
|
171
|
+
reject(new Error("Failed to load video"));
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
video.load();
|
|
175
|
+
});
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
const evProcessFile = async () => {
|
|
179
|
+
let nextPreview: TFilePreview = {
|
|
180
|
+
fileSrc: "",
|
|
181
|
+
fileType: "",
|
|
182
|
+
previewKind: "file",
|
|
183
|
+
fileLabel: "",
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
if (!isValidFile) {
|
|
187
|
+
if (isMounted) {
|
|
188
|
+
setFilePreview(nextPreview);
|
|
189
|
+
}
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
if (valueFile && valueFile.length) {
|
|
194
|
+
const currentFile = valueFile[0];
|
|
195
|
+
const currentFileType = getFileType(currentFile) || "document";
|
|
196
|
+
|
|
197
|
+
nextPreview = {
|
|
198
|
+
fileSrc: currentFile.name,
|
|
199
|
+
fileType: currentFileType,
|
|
200
|
+
previewKind: "file",
|
|
201
|
+
fileLabel: currentFile.name,
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
if (currentFileType === "image") {
|
|
205
|
+
activeObjectUrl = URL.createObjectURL(currentFile);
|
|
206
|
+
nextPreview = {
|
|
207
|
+
fileSrc: activeObjectUrl,
|
|
208
|
+
fileType: currentFileType,
|
|
209
|
+
previewKind: "image",
|
|
210
|
+
fileLabel: currentFile.name,
|
|
211
|
+
};
|
|
212
|
+
} else if (currentFileType === "video") {
|
|
213
|
+
try {
|
|
214
|
+
const thumbSrc = await evGenerateThumbVideo(currentFile);
|
|
215
|
+
nextPreview = {
|
|
216
|
+
fileSrc: thumbSrc,
|
|
217
|
+
fileType: currentFileType,
|
|
218
|
+
previewKind: "image",
|
|
219
|
+
fileLabel: currentFile.name,
|
|
220
|
+
};
|
|
221
|
+
} catch {
|
|
222
|
+
nextPreview = {
|
|
223
|
+
fileSrc: currentFile.name,
|
|
224
|
+
fileType: currentFileType,
|
|
225
|
+
previewKind: "file",
|
|
226
|
+
fileLabel: currentFile.name,
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
} else if (defaultValue) {
|
|
231
|
+
nextPreview = {
|
|
232
|
+
fileSrc: defaultValue,
|
|
233
|
+
fileType: type ?? "image",
|
|
234
|
+
previewKind: (type ?? "image") === "image" ? "image" : "file",
|
|
235
|
+
fileLabel: defaultValue.split("/").pop() || defaultValue,
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
if (isMounted) {
|
|
240
|
+
setFilePreview(nextPreview);
|
|
241
|
+
}
|
|
242
|
+
};
|
|
243
|
+
|
|
244
|
+
void evProcessFile();
|
|
245
|
+
|
|
246
|
+
return () => {
|
|
247
|
+
isMounted = false;
|
|
248
|
+
if (activeObjectUrl) {
|
|
249
|
+
URL.revokeObjectURL(activeObjectUrl);
|
|
250
|
+
}
|
|
251
|
+
};
|
|
252
|
+
}, [defaultValue, isValidFile, type, valueFile]);
|
|
253
|
+
|
|
254
|
+
const { fileSrc, fileType, previewKind, fileLabel } = filePreview;
|
|
58
255
|
|
|
59
256
|
return (
|
|
60
|
-
<UploadDragDropContainer
|
|
61
|
-
|
|
257
|
+
<UploadDragDropContainer
|
|
258
|
+
onDragEnter={handleDrag}
|
|
259
|
+
className={dragActive ? "drag-active" : ""}
|
|
260
|
+
>
|
|
261
|
+
<UploadInput
|
|
262
|
+
ref={inputRef}
|
|
263
|
+
id={id}
|
|
264
|
+
name={name}
|
|
265
|
+
onChange={handleChange}
|
|
266
|
+
{...props}
|
|
267
|
+
/>
|
|
62
268
|
<UploadDragDropLabel id="label-file-dragdrop-upload" htmlFor={id}>
|
|
63
269
|
<UploadDragDropFileContainer>
|
|
64
|
-
{
|
|
65
|
-
|
|
66
|
-
<
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
</span>
|
|
71
|
-
</
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
270
|
+
{fileSrc ? (
|
|
271
|
+
<UploadDragDropImagePreview>
|
|
272
|
+
<UploadDragDropFilePreviewCard
|
|
273
|
+
$backgroundSrc={previewKind === "image" ? fileSrc : undefined}
|
|
274
|
+
>
|
|
275
|
+
<span className="file-type">{fileType || "document"}</span>
|
|
276
|
+
<span className="file-name">{fileLabel}</span>
|
|
277
|
+
</UploadDragDropFilePreviewCard>
|
|
278
|
+
{evRemove !== undefined && (
|
|
279
|
+
<i
|
|
280
|
+
className="remove-button remove"
|
|
281
|
+
onClick={handleRemove}
|
|
282
|
+
title="Remove File"
|
|
283
|
+
>
|
|
284
|
+
X
|
|
285
|
+
</i>
|
|
286
|
+
)}
|
|
287
|
+
</UploadDragDropImagePreview>
|
|
288
|
+
) : children ? (
|
|
289
|
+
<UploadDragDropFileName>
|
|
290
|
+
<UploadDragDropIcon />
|
|
291
|
+
<span>{children}</span>
|
|
292
|
+
</UploadDragDropFileName>
|
|
293
|
+
) : (
|
|
294
|
+
<UploadDragDropFileNamePlaceholder>
|
|
295
|
+
<span>
|
|
296
|
+
{label ?? "Drag & Drop file here to upload, or "}
|
|
297
|
+
<aside>browse</aside>
|
|
298
|
+
</span>
|
|
299
|
+
{subLabel && (
|
|
300
|
+
<>
|
|
301
|
+
<br />
|
|
302
|
+
<span className="_refSubLabel">{subLabel}</span>
|
|
303
|
+
</>
|
|
304
|
+
)}
|
|
305
|
+
</UploadDragDropFileNamePlaceholder>
|
|
306
|
+
)}
|
|
79
307
|
</UploadDragDropFileContainer>
|
|
80
308
|
</UploadDragDropLabel>
|
|
81
|
-
{
|
|
309
|
+
{dragActive && (
|
|
310
|
+
<UploadDragDropFileHelper
|
|
311
|
+
onDragEnter={handleDrag}
|
|
312
|
+
onDragLeave={handleDrag}
|
|
313
|
+
onDragOver={handleDrag}
|
|
314
|
+
onDrop={handleDrop}
|
|
315
|
+
/>
|
|
316
|
+
)}
|
|
82
317
|
</UploadDragDropContainer>
|
|
83
|
-
)
|
|
84
|
-
}
|
|
318
|
+
);
|
|
319
|
+
};
|
|
85
320
|
|
|
86
|
-
export default UploadDragDropComponent
|
|
321
|
+
export default UploadDragDropComponent;
|