@fctc/sme-widget-ui 1.6.5 → 1.6.6
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/hooks.d.mts +34 -1
- package/dist/hooks.d.ts +34 -1
- package/dist/hooks.js +218 -2
- package/dist/hooks.mjs +216 -1
- package/dist/icons.d.mts +3 -1
- package/dist/icons.d.ts +3 -1
- package/dist/icons.js +34 -26
- package/dist/icons.mjs +87 -80
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1347 -1068
- package/dist/index.mjs +1102 -825
- package/dist/widgets.d.mts +1 -0
- package/dist/widgets.d.ts +1 -0
- package/dist/widgets.js +1306 -1031
- package/dist/widgets.mjs +1070 -795
- package/package.json +1 -1
package/dist/hooks.d.mts
CHANGED
|
@@ -10,4 +10,37 @@ interface UseClickOutsideOptions {
|
|
|
10
10
|
}
|
|
11
11
|
declare const useClickOutside: ({ handler, events, nodes, refs, }: UseClickOutsideOptions) => RefObject<HTMLDivElement | null>;
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
/** Kiểu trả về của hook */
|
|
14
|
+
type FileInfo = {
|
|
15
|
+
name?: string;
|
|
16
|
+
size?: number;
|
|
17
|
+
type?: string;
|
|
18
|
+
extension?: string | null;
|
|
19
|
+
dataUrl?: string | null;
|
|
20
|
+
text?: string | null;
|
|
21
|
+
arrayBuffer?: ArrayBuffer | null;
|
|
22
|
+
image?: {
|
|
23
|
+
width: number;
|
|
24
|
+
height: number;
|
|
25
|
+
} | null;
|
|
26
|
+
video?: {
|
|
27
|
+
width?: number;
|
|
28
|
+
height?: number;
|
|
29
|
+
duration?: number;
|
|
30
|
+
} | null;
|
|
31
|
+
audio?: {
|
|
32
|
+
duration?: number;
|
|
33
|
+
} | null;
|
|
34
|
+
rawBlob?: Blob | null;
|
|
35
|
+
};
|
|
36
|
+
type InputSource = string | File | Blob | null;
|
|
37
|
+
declare function useFileInfo(source: InputSource, options?: {
|
|
38
|
+
readAs?: 'dataUrl' | 'text' | 'arrayBuffer' | 'all';
|
|
39
|
+
}): {
|
|
40
|
+
info: FileInfo | null;
|
|
41
|
+
loading: boolean;
|
|
42
|
+
error: string | null;
|
|
43
|
+
reload: () => void;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
export { useClickOutside, useFileInfo };
|
package/dist/hooks.d.ts
CHANGED
|
@@ -10,4 +10,37 @@ interface UseClickOutsideOptions {
|
|
|
10
10
|
}
|
|
11
11
|
declare const useClickOutside: ({ handler, events, nodes, refs, }: UseClickOutsideOptions) => RefObject<HTMLDivElement | null>;
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
/** Kiểu trả về của hook */
|
|
14
|
+
type FileInfo = {
|
|
15
|
+
name?: string;
|
|
16
|
+
size?: number;
|
|
17
|
+
type?: string;
|
|
18
|
+
extension?: string | null;
|
|
19
|
+
dataUrl?: string | null;
|
|
20
|
+
text?: string | null;
|
|
21
|
+
arrayBuffer?: ArrayBuffer | null;
|
|
22
|
+
image?: {
|
|
23
|
+
width: number;
|
|
24
|
+
height: number;
|
|
25
|
+
} | null;
|
|
26
|
+
video?: {
|
|
27
|
+
width?: number;
|
|
28
|
+
height?: number;
|
|
29
|
+
duration?: number;
|
|
30
|
+
} | null;
|
|
31
|
+
audio?: {
|
|
32
|
+
duration?: number;
|
|
33
|
+
} | null;
|
|
34
|
+
rawBlob?: Blob | null;
|
|
35
|
+
};
|
|
36
|
+
type InputSource = string | File | Blob | null;
|
|
37
|
+
declare function useFileInfo(source: InputSource, options?: {
|
|
38
|
+
readAs?: 'dataUrl' | 'text' | 'arrayBuffer' | 'all';
|
|
39
|
+
}): {
|
|
40
|
+
info: FileInfo | null;
|
|
41
|
+
loading: boolean;
|
|
42
|
+
error: string | null;
|
|
43
|
+
reload: () => void;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
export { useClickOutside, useFileInfo };
|
package/dist/hooks.js
CHANGED
|
@@ -20,7 +20,8 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/hooks.ts
|
|
21
21
|
var hooks_exports = {};
|
|
22
22
|
__export(hooks_exports, {
|
|
23
|
-
useClickOutside: () => useClickOutside
|
|
23
|
+
useClickOutside: () => useClickOutside,
|
|
24
|
+
useFileInfo: () => useFileInfo
|
|
24
25
|
});
|
|
25
26
|
module.exports = __toCommonJS(hooks_exports);
|
|
26
27
|
|
|
@@ -55,7 +56,222 @@ var useClickOutside = ({
|
|
|
55
56
|
}, [handler, nodes, events]);
|
|
56
57
|
return ref;
|
|
57
58
|
};
|
|
59
|
+
|
|
60
|
+
// src/hooks/use-get-file-infor.ts
|
|
61
|
+
var import_react2 = require("react");
|
|
62
|
+
function getFileName(source, mime) {
|
|
63
|
+
if (source instanceof File) return source.name;
|
|
64
|
+
if (typeof source === "string") {
|
|
65
|
+
if (source.startsWith("data:")) {
|
|
66
|
+
const ext2 = mime?.split("/")[1] || "bin";
|
|
67
|
+
return `file.${ext2}`;
|
|
68
|
+
}
|
|
69
|
+
try {
|
|
70
|
+
const pathname = new URL(source).pathname;
|
|
71
|
+
const filename = decodeURIComponent(pathname.split("/").pop() || "");
|
|
72
|
+
if (filename) return filename;
|
|
73
|
+
} catch {
|
|
74
|
+
}
|
|
75
|
+
return "file.bin";
|
|
76
|
+
}
|
|
77
|
+
const ext = mime?.split("/")[1] || "bin";
|
|
78
|
+
return `file.${ext}`;
|
|
79
|
+
}
|
|
80
|
+
function useFileInfo(source, options) {
|
|
81
|
+
const { readAs = "all" } = options ?? {};
|
|
82
|
+
const [info, setInfo] = (0, import_react2.useState)(null);
|
|
83
|
+
const [loading, setLoading] = (0, import_react2.useState)(false);
|
|
84
|
+
const [error, setError] = (0, import_react2.useState)(null);
|
|
85
|
+
const abortRef = (0, import_react2.useRef)({ aborted: false });
|
|
86
|
+
(0, import_react2.useEffect)(() => {
|
|
87
|
+
abortRef.current.aborted = false;
|
|
88
|
+
if (!source) {
|
|
89
|
+
setInfo(null);
|
|
90
|
+
setLoading(false);
|
|
91
|
+
setError(null);
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
let localUrl = null;
|
|
95
|
+
let fr = null;
|
|
96
|
+
let mediaEl = null;
|
|
97
|
+
const makeExtension = (name, type) => {
|
|
98
|
+
if (name) {
|
|
99
|
+
const idx = name.lastIndexOf(".");
|
|
100
|
+
if (idx > -1) return name.slice(idx + 1).toLowerCase();
|
|
101
|
+
}
|
|
102
|
+
if (type) {
|
|
103
|
+
const match = /\/([a-z0-9.+-]+)$/.exec(type);
|
|
104
|
+
return match ? match[1] : null;
|
|
105
|
+
}
|
|
106
|
+
return null;
|
|
107
|
+
};
|
|
108
|
+
const toBlobFromSource = async (src) => {
|
|
109
|
+
if (src instanceof Blob) return src;
|
|
110
|
+
if (typeof src === "string") {
|
|
111
|
+
const s = src.trim();
|
|
112
|
+
if (s.startsWith("data:")) {
|
|
113
|
+
const parts = s.split(",");
|
|
114
|
+
const meta = parts[0];
|
|
115
|
+
const isBase64 = meta.includes(";base64");
|
|
116
|
+
const mimeMatch = meta.match(/data:([^;]+)/);
|
|
117
|
+
const mime = mimeMatch ? mimeMatch[1] : "application/octet-stream";
|
|
118
|
+
const dataPart = parts.slice(1).join(",");
|
|
119
|
+
if (isBase64) {
|
|
120
|
+
const binary = atob(dataPart);
|
|
121
|
+
const len = binary.length;
|
|
122
|
+
const arr = new Uint8Array(len);
|
|
123
|
+
for (let i = 0; i < len; i++) arr[i] = binary.charCodeAt(i);
|
|
124
|
+
return new Blob([arr], { type: mime });
|
|
125
|
+
} else {
|
|
126
|
+
const decoded = decodeURIComponent(dataPart);
|
|
127
|
+
return new Blob([decoded], { type: mime });
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
const resp = await fetch(s);
|
|
131
|
+
if (!resp.ok) throw new Error(`Fetch failed with status ${resp.status}`);
|
|
132
|
+
const blob = await resp.blob();
|
|
133
|
+
return blob;
|
|
134
|
+
}
|
|
135
|
+
throw new Error("Unsupported source type");
|
|
136
|
+
};
|
|
137
|
+
const run = async () => {
|
|
138
|
+
setLoading(true);
|
|
139
|
+
setError(null);
|
|
140
|
+
setInfo(null);
|
|
141
|
+
try {
|
|
142
|
+
const blob = await toBlobFromSource(source);
|
|
143
|
+
if (abortRef.current.aborted) return;
|
|
144
|
+
const fileInfo = {
|
|
145
|
+
rawBlob: blob,
|
|
146
|
+
size: blob.size,
|
|
147
|
+
type: blob.type || "application/octet-stream",
|
|
148
|
+
dataUrl: null,
|
|
149
|
+
text: null,
|
|
150
|
+
arrayBuffer: null,
|
|
151
|
+
image: null,
|
|
152
|
+
video: null,
|
|
153
|
+
audio: null
|
|
154
|
+
};
|
|
155
|
+
if (source instanceof File || source instanceof Blob || typeof source === "string" && !source.startsWith("data:")) {
|
|
156
|
+
fileInfo.name = getFileName(source, fileInfo.type);
|
|
157
|
+
}
|
|
158
|
+
fileInfo.extension = makeExtension(fileInfo.name, fileInfo.type);
|
|
159
|
+
localUrl = URL.createObjectURL(blob);
|
|
160
|
+
const readPromises = [];
|
|
161
|
+
if (readAs === "dataUrl" || readAs === "all") {
|
|
162
|
+
fr = new FileReader();
|
|
163
|
+
const p = new Promise((resolve, reject) => {
|
|
164
|
+
fr.onload = () => {
|
|
165
|
+
if (abortRef.current.aborted) return resolve();
|
|
166
|
+
fileInfo.dataUrl = fr.result;
|
|
167
|
+
resolve();
|
|
168
|
+
};
|
|
169
|
+
fr.onerror = () => reject(fr.error);
|
|
170
|
+
fr.readAsDataURL(blob);
|
|
171
|
+
});
|
|
172
|
+
readPromises.push(p);
|
|
173
|
+
}
|
|
174
|
+
if (readAs === "text" || readAs === "all") {
|
|
175
|
+
const frText = new FileReader();
|
|
176
|
+
const p = new Promise((resolve, reject) => {
|
|
177
|
+
frText.onload = () => {
|
|
178
|
+
if (abortRef.current.aborted) return resolve();
|
|
179
|
+
fileInfo.text = frText.result;
|
|
180
|
+
resolve();
|
|
181
|
+
};
|
|
182
|
+
frText.onerror = () => reject(frText.error);
|
|
183
|
+
frText.readAsText(blob);
|
|
184
|
+
});
|
|
185
|
+
readPromises.push(p);
|
|
186
|
+
}
|
|
187
|
+
if (readAs === "arrayBuffer" || readAs === "all") {
|
|
188
|
+
const frBuf = new FileReader();
|
|
189
|
+
const p = new Promise((resolve, reject) => {
|
|
190
|
+
frBuf.onload = () => {
|
|
191
|
+
if (abortRef.current.aborted) return resolve();
|
|
192
|
+
fileInfo.arrayBuffer = frBuf.result;
|
|
193
|
+
resolve();
|
|
194
|
+
};
|
|
195
|
+
frBuf.onerror = () => reject(frBuf.error);
|
|
196
|
+
frBuf.readAsArrayBuffer(blob);
|
|
197
|
+
});
|
|
198
|
+
readPromises.push(p);
|
|
199
|
+
}
|
|
200
|
+
if (fileInfo?.type?.startsWith("image/")) {
|
|
201
|
+
const p = new Promise((resolve, reject) => {
|
|
202
|
+
const img = new Image();
|
|
203
|
+
img.onload = () => {
|
|
204
|
+
if (abortRef.current.aborted) return resolve();
|
|
205
|
+
fileInfo.image = {
|
|
206
|
+
width: img.naturalWidth,
|
|
207
|
+
height: img.naturalHeight
|
|
208
|
+
};
|
|
209
|
+
resolve();
|
|
210
|
+
};
|
|
211
|
+
img.onerror = () => resolve();
|
|
212
|
+
img.src = localUrl;
|
|
213
|
+
});
|
|
214
|
+
readPromises.push(p);
|
|
215
|
+
}
|
|
216
|
+
if (fileInfo && fileInfo?.type?.startsWith("video/") || fileInfo?.type?.startsWith("audio/")) {
|
|
217
|
+
const p = new Promise((resolve) => {
|
|
218
|
+
const el = document.createElement(
|
|
219
|
+
fileInfo?.type?.startsWith("video/") ? "video" : "audio"
|
|
220
|
+
);
|
|
221
|
+
mediaEl = el;
|
|
222
|
+
mediaEl.preload = "metadata";
|
|
223
|
+
mediaEl.onloadedmetadata = () => {
|
|
224
|
+
if (abortRef.current.aborted) return resolve();
|
|
225
|
+
const duration = isFinite(mediaEl.duration) ? mediaEl.duration : void 0;
|
|
226
|
+
if (fileInfo?.type?.startsWith("video/")) {
|
|
227
|
+
fileInfo.video = {
|
|
228
|
+
width: mediaEl.videoWidth || void 0,
|
|
229
|
+
height: mediaEl.videoHeight || void 0,
|
|
230
|
+
duration
|
|
231
|
+
};
|
|
232
|
+
} else {
|
|
233
|
+
fileInfo.audio = { duration };
|
|
234
|
+
}
|
|
235
|
+
resolve();
|
|
236
|
+
};
|
|
237
|
+
mediaEl.onerror = () => resolve();
|
|
238
|
+
mediaEl.src = localUrl;
|
|
239
|
+
});
|
|
240
|
+
readPromises.push(p);
|
|
241
|
+
}
|
|
242
|
+
await Promise.all(readPromises);
|
|
243
|
+
if (abortRef.current.aborted) return;
|
|
244
|
+
setInfo(fileInfo);
|
|
245
|
+
} catch (err) {
|
|
246
|
+
if (!abortRef.current.aborted) setError(err?.message ?? String(err));
|
|
247
|
+
} finally {
|
|
248
|
+
if (!abortRef.current.aborted) setLoading(false);
|
|
249
|
+
}
|
|
250
|
+
};
|
|
251
|
+
run();
|
|
252
|
+
return () => {
|
|
253
|
+
abortRef.current.aborted = true;
|
|
254
|
+
if (fr && fr.readyState === 1) {
|
|
255
|
+
try {
|
|
256
|
+
fr.abort();
|
|
257
|
+
} catch {
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
if (mediaEl) {
|
|
261
|
+
try {
|
|
262
|
+
mediaEl.src = "";
|
|
263
|
+
mediaEl.load();
|
|
264
|
+
} catch {
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
if (localUrl) URL.revokeObjectURL(localUrl);
|
|
268
|
+
};
|
|
269
|
+
}, [source, readAs]);
|
|
270
|
+
return { info, loading, error, reload: () => {
|
|
271
|
+
} };
|
|
272
|
+
}
|
|
58
273
|
// Annotate the CommonJS export names for ESM import in node:
|
|
59
274
|
0 && (module.exports = {
|
|
60
|
-
useClickOutside
|
|
275
|
+
useClickOutside,
|
|
276
|
+
useFileInfo
|
|
61
277
|
});
|
package/dist/hooks.mjs
CHANGED
|
@@ -29,6 +29,221 @@ var useClickOutside = ({
|
|
|
29
29
|
}, [handler, nodes, events]);
|
|
30
30
|
return ref;
|
|
31
31
|
};
|
|
32
|
+
|
|
33
|
+
// src/hooks/use-get-file-infor.ts
|
|
34
|
+
import { useEffect as useEffect2, useRef as useRef2, useState } from "react";
|
|
35
|
+
function getFileName(source, mime) {
|
|
36
|
+
if (source instanceof File) return source.name;
|
|
37
|
+
if (typeof source === "string") {
|
|
38
|
+
if (source.startsWith("data:")) {
|
|
39
|
+
const ext2 = mime?.split("/")[1] || "bin";
|
|
40
|
+
return `file.${ext2}`;
|
|
41
|
+
}
|
|
42
|
+
try {
|
|
43
|
+
const pathname = new URL(source).pathname;
|
|
44
|
+
const filename = decodeURIComponent(pathname.split("/").pop() || "");
|
|
45
|
+
if (filename) return filename;
|
|
46
|
+
} catch {
|
|
47
|
+
}
|
|
48
|
+
return "file.bin";
|
|
49
|
+
}
|
|
50
|
+
const ext = mime?.split("/")[1] || "bin";
|
|
51
|
+
return `file.${ext}`;
|
|
52
|
+
}
|
|
53
|
+
function useFileInfo(source, options) {
|
|
54
|
+
const { readAs = "all" } = options ?? {};
|
|
55
|
+
const [info, setInfo] = useState(null);
|
|
56
|
+
const [loading, setLoading] = useState(false);
|
|
57
|
+
const [error, setError] = useState(null);
|
|
58
|
+
const abortRef = useRef2({ aborted: false });
|
|
59
|
+
useEffect2(() => {
|
|
60
|
+
abortRef.current.aborted = false;
|
|
61
|
+
if (!source) {
|
|
62
|
+
setInfo(null);
|
|
63
|
+
setLoading(false);
|
|
64
|
+
setError(null);
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
let localUrl = null;
|
|
68
|
+
let fr = null;
|
|
69
|
+
let mediaEl = null;
|
|
70
|
+
const makeExtension = (name, type) => {
|
|
71
|
+
if (name) {
|
|
72
|
+
const idx = name.lastIndexOf(".");
|
|
73
|
+
if (idx > -1) return name.slice(idx + 1).toLowerCase();
|
|
74
|
+
}
|
|
75
|
+
if (type) {
|
|
76
|
+
const match = /\/([a-z0-9.+-]+)$/.exec(type);
|
|
77
|
+
return match ? match[1] : null;
|
|
78
|
+
}
|
|
79
|
+
return null;
|
|
80
|
+
};
|
|
81
|
+
const toBlobFromSource = async (src) => {
|
|
82
|
+
if (src instanceof Blob) return src;
|
|
83
|
+
if (typeof src === "string") {
|
|
84
|
+
const s = src.trim();
|
|
85
|
+
if (s.startsWith("data:")) {
|
|
86
|
+
const parts = s.split(",");
|
|
87
|
+
const meta = parts[0];
|
|
88
|
+
const isBase64 = meta.includes(";base64");
|
|
89
|
+
const mimeMatch = meta.match(/data:([^;]+)/);
|
|
90
|
+
const mime = mimeMatch ? mimeMatch[1] : "application/octet-stream";
|
|
91
|
+
const dataPart = parts.slice(1).join(",");
|
|
92
|
+
if (isBase64) {
|
|
93
|
+
const binary = atob(dataPart);
|
|
94
|
+
const len = binary.length;
|
|
95
|
+
const arr = new Uint8Array(len);
|
|
96
|
+
for (let i = 0; i < len; i++) arr[i] = binary.charCodeAt(i);
|
|
97
|
+
return new Blob([arr], { type: mime });
|
|
98
|
+
} else {
|
|
99
|
+
const decoded = decodeURIComponent(dataPart);
|
|
100
|
+
return new Blob([decoded], { type: mime });
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
const resp = await fetch(s);
|
|
104
|
+
if (!resp.ok) throw new Error(`Fetch failed with status ${resp.status}`);
|
|
105
|
+
const blob = await resp.blob();
|
|
106
|
+
return blob;
|
|
107
|
+
}
|
|
108
|
+
throw new Error("Unsupported source type");
|
|
109
|
+
};
|
|
110
|
+
const run = async () => {
|
|
111
|
+
setLoading(true);
|
|
112
|
+
setError(null);
|
|
113
|
+
setInfo(null);
|
|
114
|
+
try {
|
|
115
|
+
const blob = await toBlobFromSource(source);
|
|
116
|
+
if (abortRef.current.aborted) return;
|
|
117
|
+
const fileInfo = {
|
|
118
|
+
rawBlob: blob,
|
|
119
|
+
size: blob.size,
|
|
120
|
+
type: blob.type || "application/octet-stream",
|
|
121
|
+
dataUrl: null,
|
|
122
|
+
text: null,
|
|
123
|
+
arrayBuffer: null,
|
|
124
|
+
image: null,
|
|
125
|
+
video: null,
|
|
126
|
+
audio: null
|
|
127
|
+
};
|
|
128
|
+
if (source instanceof File || source instanceof Blob || typeof source === "string" && !source.startsWith("data:")) {
|
|
129
|
+
fileInfo.name = getFileName(source, fileInfo.type);
|
|
130
|
+
}
|
|
131
|
+
fileInfo.extension = makeExtension(fileInfo.name, fileInfo.type);
|
|
132
|
+
localUrl = URL.createObjectURL(blob);
|
|
133
|
+
const readPromises = [];
|
|
134
|
+
if (readAs === "dataUrl" || readAs === "all") {
|
|
135
|
+
fr = new FileReader();
|
|
136
|
+
const p = new Promise((resolve, reject) => {
|
|
137
|
+
fr.onload = () => {
|
|
138
|
+
if (abortRef.current.aborted) return resolve();
|
|
139
|
+
fileInfo.dataUrl = fr.result;
|
|
140
|
+
resolve();
|
|
141
|
+
};
|
|
142
|
+
fr.onerror = () => reject(fr.error);
|
|
143
|
+
fr.readAsDataURL(blob);
|
|
144
|
+
});
|
|
145
|
+
readPromises.push(p);
|
|
146
|
+
}
|
|
147
|
+
if (readAs === "text" || readAs === "all") {
|
|
148
|
+
const frText = new FileReader();
|
|
149
|
+
const p = new Promise((resolve, reject) => {
|
|
150
|
+
frText.onload = () => {
|
|
151
|
+
if (abortRef.current.aborted) return resolve();
|
|
152
|
+
fileInfo.text = frText.result;
|
|
153
|
+
resolve();
|
|
154
|
+
};
|
|
155
|
+
frText.onerror = () => reject(frText.error);
|
|
156
|
+
frText.readAsText(blob);
|
|
157
|
+
});
|
|
158
|
+
readPromises.push(p);
|
|
159
|
+
}
|
|
160
|
+
if (readAs === "arrayBuffer" || readAs === "all") {
|
|
161
|
+
const frBuf = new FileReader();
|
|
162
|
+
const p = new Promise((resolve, reject) => {
|
|
163
|
+
frBuf.onload = () => {
|
|
164
|
+
if (abortRef.current.aborted) return resolve();
|
|
165
|
+
fileInfo.arrayBuffer = frBuf.result;
|
|
166
|
+
resolve();
|
|
167
|
+
};
|
|
168
|
+
frBuf.onerror = () => reject(frBuf.error);
|
|
169
|
+
frBuf.readAsArrayBuffer(blob);
|
|
170
|
+
});
|
|
171
|
+
readPromises.push(p);
|
|
172
|
+
}
|
|
173
|
+
if (fileInfo?.type?.startsWith("image/")) {
|
|
174
|
+
const p = new Promise((resolve, reject) => {
|
|
175
|
+
const img = new Image();
|
|
176
|
+
img.onload = () => {
|
|
177
|
+
if (abortRef.current.aborted) return resolve();
|
|
178
|
+
fileInfo.image = {
|
|
179
|
+
width: img.naturalWidth,
|
|
180
|
+
height: img.naturalHeight
|
|
181
|
+
};
|
|
182
|
+
resolve();
|
|
183
|
+
};
|
|
184
|
+
img.onerror = () => resolve();
|
|
185
|
+
img.src = localUrl;
|
|
186
|
+
});
|
|
187
|
+
readPromises.push(p);
|
|
188
|
+
}
|
|
189
|
+
if (fileInfo && fileInfo?.type?.startsWith("video/") || fileInfo?.type?.startsWith("audio/")) {
|
|
190
|
+
const p = new Promise((resolve) => {
|
|
191
|
+
const el = document.createElement(
|
|
192
|
+
fileInfo?.type?.startsWith("video/") ? "video" : "audio"
|
|
193
|
+
);
|
|
194
|
+
mediaEl = el;
|
|
195
|
+
mediaEl.preload = "metadata";
|
|
196
|
+
mediaEl.onloadedmetadata = () => {
|
|
197
|
+
if (abortRef.current.aborted) return resolve();
|
|
198
|
+
const duration = isFinite(mediaEl.duration) ? mediaEl.duration : void 0;
|
|
199
|
+
if (fileInfo?.type?.startsWith("video/")) {
|
|
200
|
+
fileInfo.video = {
|
|
201
|
+
width: mediaEl.videoWidth || void 0,
|
|
202
|
+
height: mediaEl.videoHeight || void 0,
|
|
203
|
+
duration
|
|
204
|
+
};
|
|
205
|
+
} else {
|
|
206
|
+
fileInfo.audio = { duration };
|
|
207
|
+
}
|
|
208
|
+
resolve();
|
|
209
|
+
};
|
|
210
|
+
mediaEl.onerror = () => resolve();
|
|
211
|
+
mediaEl.src = localUrl;
|
|
212
|
+
});
|
|
213
|
+
readPromises.push(p);
|
|
214
|
+
}
|
|
215
|
+
await Promise.all(readPromises);
|
|
216
|
+
if (abortRef.current.aborted) return;
|
|
217
|
+
setInfo(fileInfo);
|
|
218
|
+
} catch (err) {
|
|
219
|
+
if (!abortRef.current.aborted) setError(err?.message ?? String(err));
|
|
220
|
+
} finally {
|
|
221
|
+
if (!abortRef.current.aborted) setLoading(false);
|
|
222
|
+
}
|
|
223
|
+
};
|
|
224
|
+
run();
|
|
225
|
+
return () => {
|
|
226
|
+
abortRef.current.aborted = true;
|
|
227
|
+
if (fr && fr.readyState === 1) {
|
|
228
|
+
try {
|
|
229
|
+
fr.abort();
|
|
230
|
+
} catch {
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
if (mediaEl) {
|
|
234
|
+
try {
|
|
235
|
+
mediaEl.src = "";
|
|
236
|
+
mediaEl.load();
|
|
237
|
+
} catch {
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
if (localUrl) URL.revokeObjectURL(localUrl);
|
|
241
|
+
};
|
|
242
|
+
}, [source, readAs]);
|
|
243
|
+
return { info, loading, error, reload: () => {
|
|
244
|
+
} };
|
|
245
|
+
}
|
|
32
246
|
export {
|
|
33
|
-
useClickOutside
|
|
247
|
+
useClickOutside,
|
|
248
|
+
useFileInfo
|
|
34
249
|
};
|
package/dist/icons.d.mts
CHANGED
|
@@ -85,4 +85,6 @@ declare const GoogleIcon: ({ width, height, ...props }: React.SVGProps<SVGSVGEle
|
|
|
85
85
|
|
|
86
86
|
declare const EyeClosedIcon: () => JSX.Element;
|
|
87
87
|
|
|
88
|
-
|
|
88
|
+
declare const DeleteIconDanger: () => JSX.Element;
|
|
89
|
+
|
|
90
|
+
export { AddIcon, ArchiveIcon, ArrowDownIcon, ArrowRightIcon, AttachIcon, BackIcon, CalendarIcon, CheckIcon, ChevronBottomIcon, CloseIcon, CopyIcon, DeleteIcon, DeleteIconDanger, DownloadIcon, ExcelIcon, ExportIcon, EyeClosedIcon, EyeIcon, FilterIcon, GoogleIcon, GroupByIcon, KanbanIcon, ListIcon, LoadingIcon, MoreIcon, PaidIcon, PdfIcon, PlaceHolderIcon, PlayIcon, ResetIcon, SearchIcon, SettingIcon, StarIcon, TriangleIcon, UnArchiveIcon, VectorIcon, ZipIcon };
|
package/dist/icons.d.ts
CHANGED
|
@@ -85,4 +85,6 @@ declare const GoogleIcon: ({ width, height, ...props }: React.SVGProps<SVGSVGEle
|
|
|
85
85
|
|
|
86
86
|
declare const EyeClosedIcon: () => JSX.Element;
|
|
87
87
|
|
|
88
|
-
|
|
88
|
+
declare const DeleteIconDanger: () => JSX.Element;
|
|
89
|
+
|
|
90
|
+
export { AddIcon, ArchiveIcon, ArrowDownIcon, ArrowRightIcon, AttachIcon, BackIcon, CalendarIcon, CheckIcon, ChevronBottomIcon, CloseIcon, CopyIcon, DeleteIcon, DeleteIconDanger, DownloadIcon, ExcelIcon, ExportIcon, EyeClosedIcon, EyeIcon, FilterIcon, GoogleIcon, GroupByIcon, KanbanIcon, ListIcon, LoadingIcon, MoreIcon, PaidIcon, PdfIcon, PlaceHolderIcon, PlayIcon, ResetIcon, SearchIcon, SettingIcon, StarIcon, TriangleIcon, UnArchiveIcon, VectorIcon, ZipIcon };
|
package/dist/icons.js
CHANGED
|
@@ -32,6 +32,7 @@ __export(icons_exports, {
|
|
|
32
32
|
CloseIcon: () => CloseIcon,
|
|
33
33
|
CopyIcon: () => CopyIcon,
|
|
34
34
|
DeleteIcon: () => DeleteIcon,
|
|
35
|
+
DeleteIconDanger: () => DeleteIconDanger,
|
|
35
36
|
DownloadIcon: () => DownloadIcon,
|
|
36
37
|
ExcelIcon: () => ExcelIcon,
|
|
37
38
|
ExportIcon: () => ExportIcon,
|
|
@@ -385,37 +386,21 @@ var DeleteIcon = () => {
|
|
|
385
386
|
// src/icons/download-icon.tsx
|
|
386
387
|
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
387
388
|
var DownloadIcon = () => {
|
|
388
|
-
return /* @__PURE__ */ (0, import_jsx_runtime13.
|
|
389
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
389
390
|
"svg",
|
|
390
391
|
{
|
|
391
392
|
xmlns: "http://www.w3.org/2000/svg",
|
|
392
|
-
width: "
|
|
393
|
+
width: "20",
|
|
393
394
|
height: "20",
|
|
394
|
-
viewBox: "0 0
|
|
395
|
+
viewBox: "0 0 20 20",
|
|
395
396
|
fill: "none",
|
|
396
|
-
children:
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
),
|
|
404
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
405
|
-
"path",
|
|
406
|
-
{
|
|
407
|
-
d: "M10.5 13.025C10.1583 13.025 9.875 12.7417 9.875 12.4V1.66667C9.875 1.32501 10.1583 1.04167 10.5 1.04167C10.8417 1.04167 11.125 1.32501 11.125 1.66667V12.4C11.125 12.75 10.8417 13.025 10.5 13.025Z",
|
|
408
|
-
fill: "currentColor"
|
|
409
|
-
}
|
|
410
|
-
),
|
|
411
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
412
|
-
"path",
|
|
413
|
-
{
|
|
414
|
-
d: "M10.5 13.9583C10.3417 13.9583 10.1834 13.9 10.0584 13.775L7.2667 10.9833C7.02503 10.7417 7.02503 10.3417 7.2667 10.1C7.50837 9.85833 7.90837 9.85833 8.15003 10.1L10.5 12.45L12.85 10.1C13.0917 9.85833 13.4917 9.85833 13.7334 10.1C13.975 10.3417 13.975 10.7417 13.7334 10.9833L10.9417 13.775C10.8167 13.9 10.6584 13.9583 10.5 13.9583Z",
|
|
415
|
-
fill: "currentColor"
|
|
416
|
-
}
|
|
417
|
-
)
|
|
418
|
-
]
|
|
397
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
398
|
+
"path",
|
|
399
|
+
{
|
|
400
|
+
d: "M10.75 8.5H14.5L10 13L5.5 8.5H9.25V3.25H10.75V8.5ZM4 15.25H16V10H17.5V16C17.5 16.1989 17.421 16.3897 17.2803 16.5303C17.1397 16.671 16.9489 16.75 16.75 16.75H3.25C3.05109 16.75 2.86032 16.671 2.71967 16.5303C2.57902 16.3897 2.5 16.1989 2.5 16V10H4V15.25Z",
|
|
401
|
+
fill: "#060606"
|
|
402
|
+
}
|
|
403
|
+
)
|
|
419
404
|
}
|
|
420
405
|
);
|
|
421
406
|
};
|
|
@@ -1802,6 +1787,28 @@ var EyeClosedIcon = () => {
|
|
|
1802
1787
|
}
|
|
1803
1788
|
);
|
|
1804
1789
|
};
|
|
1790
|
+
|
|
1791
|
+
// src/icons/delete-icon-danger.tsx
|
|
1792
|
+
var import_jsx_runtime37 = require("react/jsx-runtime");
|
|
1793
|
+
var DeleteIconDanger = () => {
|
|
1794
|
+
return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
1795
|
+
"svg",
|
|
1796
|
+
{
|
|
1797
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
1798
|
+
width: "20",
|
|
1799
|
+
height: "20",
|
|
1800
|
+
viewBox: "0 0 20 20",
|
|
1801
|
+
fill: "none",
|
|
1802
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
1803
|
+
"path",
|
|
1804
|
+
{
|
|
1805
|
+
d: "M13.75 5.5H17.5V7H16V16.75C16 16.9489 15.921 17.1397 15.7803 17.2803C15.6397 17.421 15.4489 17.5 15.25 17.5H4.75C4.55109 17.5 4.36032 17.421 4.21967 17.2803C4.07902 17.1397 4 16.9489 4 16.75V7H2.5V5.5H6.25V3.25C6.25 3.05109 6.32902 2.86032 6.46967 2.71967C6.61032 2.57902 6.80109 2.5 7 2.5H13C13.1989 2.5 13.3897 2.57902 13.5303 2.71967C13.671 2.86032 13.75 3.05109 13.75 3.25V5.5ZM14.5 7H5.5V16H14.5V7ZM7.75 9.25H9.25V13.75H7.75V9.25ZM10.75 9.25H12.25V13.75H10.75V9.25ZM7.75 4V5.5H12.25V4H7.75Z",
|
|
1806
|
+
fill: "#FB2B3D"
|
|
1807
|
+
}
|
|
1808
|
+
)
|
|
1809
|
+
}
|
|
1810
|
+
);
|
|
1811
|
+
};
|
|
1805
1812
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1806
1813
|
0 && (module.exports = {
|
|
1807
1814
|
AddIcon,
|
|
@@ -1816,6 +1823,7 @@ var EyeClosedIcon = () => {
|
|
|
1816
1823
|
CloseIcon,
|
|
1817
1824
|
CopyIcon,
|
|
1818
1825
|
DeleteIcon,
|
|
1826
|
+
DeleteIconDanger,
|
|
1819
1827
|
DownloadIcon,
|
|
1820
1828
|
ExcelIcon,
|
|
1821
1829
|
ExportIcon,
|