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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "forstok-ui-lib",
3
- "version": "8.6.3",
3
+ "version": "8.7.1",
4
4
  "description": "Forstok UI Components Library",
5
5
  "path": "dist",
6
6
  "main": "dist/index.js",
@@ -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 'styled-components'
1
+ import { css } from "styled-components";
2
2
 
3
- import IconEditWhite from '../../assets/images/icons/edit-white.svg'
4
- import IconLoadingRed from '../../assets/images/icons/loading-red.svg'
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: 0rem -.0625rem 0rem 0rem #b5b5b5 inset, 0rem 0rem 0rem .0625rem rgba(0, 0, 0, .1) inset, 0rem .03125rem 0rem .09375rem #FFF inset;
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: -.0625rem 0rem .0625rem 0rem rgba(26, 26, 26, .122) inset, .0625rem 0rem .0625rem 0rem rgba(26, 26, 26, .122) inset, 0rem .125rem .0625rem 0rem rgba(26, 26, 26, .2) inset;
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: -.0625rem 0rem .0625rem 0rem rgba(26, 26, 26, .122) inset, .0625rem 0rem .0625rem 0rem rgba(26, 26, 26, .122) inset, 0rem .125rem .0625rem 0rem rgba(26, 26, 26, .2) inset;
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, &.add, &.loading {
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 { type InputHTMLAttributes, type ReactNode, useState } from 'react';
2
- import { generateMessage } from '../../assets/javascripts/function';
3
- import { UploadDragDropContainer, UploadDragDropFileHelper, UploadDragDropFileContainer, UploadInput, UploadDragDropLabel, UploadDragDropFileName, UploadDragDropFileNamePlaceholder, UploadDragDropIcon } from './styles';
4
- import type { TChangeEvent, TDragEvent } from '../../typeds/base.typed';
5
- import type { TMessageFunction } from '../message/typed';
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
- const UploadDragDropComponent = ({ children, id, name, evChange, evCreateMessage, label, ...props }: TUpload) => {
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 ? accept.split(',').map(_accept => _accept.trim().replace('.', '')) : null;
36
- for (let x= 0; x < e.dataTransfer.files.length; x++) {
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('.').pop();
92
+ const curFormat = curFile.name.split(".").pop();
39
93
  if (acceptedFormat?.length && curFormat) {
40
94
  if (!acceptedFormat.includes(curFormat)) {
41
- const _failed_props = generateMessage('failed', 'File type is not allowed. Please check again');
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 onDragEnter={handleDrag} className={dragActive ? "drag-active" : "" }>
61
- <UploadInput id={id} name={name} onChange={handleChange} {...props} />
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
- children ? (
66
- <UploadDragDropFileName>
67
- <UploadDragDropIcon />
68
- <span>
69
- {children}
70
- </span>
71
- </UploadDragDropFileName>
72
- ) :
73
- (
74
- <UploadDragDropFileNamePlaceholder>
75
- {label ?? 'Drag & Drop file here to upload, or '}<span>browse</span>.
76
- </UploadDragDropFileNamePlaceholder>
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
- { dragActive && <UploadDragDropFileHelper onDragEnter={handleDrag} onDragLeave={handleDrag} onDragOver={handleDrag} onDrop={handleDrop} /> }
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;