@wipco/sdui 1.8.2 → 1.8.3
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.
|
@@ -6,6 +6,98 @@ import { useState, useRef, useEffect, useCallback } from 'react';
|
|
|
6
6
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
7
7
|
|
|
8
8
|
var THUMB_SIZE = 72;
|
|
9
|
+
var FILE_TILE_WIDTH = 168;
|
|
10
|
+
var IMAGE_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
11
|
+
"jpg",
|
|
12
|
+
"jpeg",
|
|
13
|
+
"jpe",
|
|
14
|
+
"jfif",
|
|
15
|
+
"pjpeg",
|
|
16
|
+
"pjp",
|
|
17
|
+
"png",
|
|
18
|
+
"apng",
|
|
19
|
+
"gif",
|
|
20
|
+
"webp",
|
|
21
|
+
"avif",
|
|
22
|
+
"bmp",
|
|
23
|
+
"svg",
|
|
24
|
+
"ico",
|
|
25
|
+
"heic",
|
|
26
|
+
"heif",
|
|
27
|
+
"tif",
|
|
28
|
+
"tiff"
|
|
29
|
+
]);
|
|
30
|
+
var MIME_SHAPE = /^[a-z0-9][\w.+-]*\/[\w.+-]+/i;
|
|
31
|
+
function urlOf(item) {
|
|
32
|
+
return typeof item.url === "string" ? item.url : "";
|
|
33
|
+
}
|
|
34
|
+
function itemMime(item) {
|
|
35
|
+
const record = item;
|
|
36
|
+
for (const key of ["mimeType", "mime_type", "type"]) {
|
|
37
|
+
const value = record[key];
|
|
38
|
+
if (typeof value === "string" && MIME_SHAPE.test(value.trim())) return value.trim().toLowerCase();
|
|
39
|
+
}
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
function extensionOfPath(path) {
|
|
43
|
+
const segment = path.slice(Math.max(path.lastIndexOf("/"), path.lastIndexOf("\\")) + 1);
|
|
44
|
+
const dot = segment.lastIndexOf(".");
|
|
45
|
+
if (dot <= 0) return null;
|
|
46
|
+
const ext = segment.slice(dot + 1).toLowerCase();
|
|
47
|
+
return /^[a-z0-9]{1,10}$/.test(ext) ? ext : null;
|
|
48
|
+
}
|
|
49
|
+
function extensionOfUrl(url) {
|
|
50
|
+
if (/^(blob|data):/i.test(url.trim())) return null;
|
|
51
|
+
return extensionOfPath(url.split(/[?#]/, 1)[0]);
|
|
52
|
+
}
|
|
53
|
+
function dataUrlMime(url) {
|
|
54
|
+
const match = /^data:([^;,]+)/i.exec(url.trim());
|
|
55
|
+
return match && MIME_SHAPE.test(match[1]) ? match[1].toLowerCase() : null;
|
|
56
|
+
}
|
|
57
|
+
function itemLooksLikeImage(item, fileType) {
|
|
58
|
+
const mime = itemMime(item) ?? (fileType && MIME_SHAPE.test(fileType) ? fileType.toLowerCase() : null) ?? dataUrlMime(urlOf(item));
|
|
59
|
+
if (mime) return mime.startsWith("image/");
|
|
60
|
+
const ext = extensionOfUrl(urlOf(item)) ?? (item.name ? extensionOfPath(item.name) : null);
|
|
61
|
+
if (ext) return IMAGE_EXTENSIONS.has(ext);
|
|
62
|
+
return true;
|
|
63
|
+
}
|
|
64
|
+
function fileBadgeOf(item, fileType) {
|
|
65
|
+
const ext = (item.name ? extensionOfPath(item.name) : null) ?? extensionOfUrl(urlOf(item));
|
|
66
|
+
if (ext) return ext.toUpperCase();
|
|
67
|
+
const mime = itemMime(item) ?? (fileType && MIME_SHAPE.test(fileType) ? fileType.toLowerCase() : null);
|
|
68
|
+
const subtype = mime?.split("/")[1]?.split(/[;+]/)[0];
|
|
69
|
+
return subtype && /^[a-z0-9]{1,5}$/.test(subtype) ? subtype.toUpperCase() : null;
|
|
70
|
+
}
|
|
71
|
+
function displayNameOf(item) {
|
|
72
|
+
if (item.name && item.name.trim() !== "") return item.name;
|
|
73
|
+
const url = urlOf(item);
|
|
74
|
+
if (!/^(blob|data):/i.test(url.trim())) {
|
|
75
|
+
const path = url.split(/[?#]/, 1)[0];
|
|
76
|
+
const segment = path.slice(path.lastIndexOf("/") + 1);
|
|
77
|
+
if (segment !== "") {
|
|
78
|
+
try {
|
|
79
|
+
return decodeURIComponent(segment);
|
|
80
|
+
} catch {
|
|
81
|
+
return segment;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return "\uCCA8\uBD80 \uD30C\uC77C";
|
|
86
|
+
}
|
|
87
|
+
function safeFileHref(url) {
|
|
88
|
+
const value = url.replace(/[\u0000-\u0020]/g, "");
|
|
89
|
+
if (value === "") return null;
|
|
90
|
+
const scheme = /^([a-z][a-z0-9+.-]*):/i.exec(value);
|
|
91
|
+
if (!scheme) return url;
|
|
92
|
+
return /^(https?|blob)$/i.test(scheme[1]) ? url : null;
|
|
93
|
+
}
|
|
94
|
+
function acceptIsImageOnly(accept) {
|
|
95
|
+
const rules = accept.split(",").map((rule) => rule.trim().toLowerCase()).filter(Boolean);
|
|
96
|
+
if (rules.length === 0) return false;
|
|
97
|
+
return rules.every(
|
|
98
|
+
(rule) => rule.startsWith(".") ? IMAGE_EXTENSIONS.has(rule.slice(1)) : rule.startsWith("image/")
|
|
99
|
+
);
|
|
100
|
+
}
|
|
9
101
|
function matchesAccept(file, accept) {
|
|
10
102
|
const rules = accept.split(",").map((rule) => rule.trim().toLowerCase()).filter(Boolean);
|
|
11
103
|
if (rules.length === 0) return true;
|
|
@@ -65,6 +157,10 @@ function FileDropzoneImpl({
|
|
|
65
157
|
const inputRef = useRef(null);
|
|
66
158
|
const dragDepthRef = useRef(0);
|
|
67
159
|
const createdUrlsRef = useRef(/* @__PURE__ */ new Set());
|
|
160
|
+
const fileTypesRef = useRef(/* @__PURE__ */ new Map());
|
|
161
|
+
const rememberFileType = (id, file) => {
|
|
162
|
+
if (file.type) fileTypesRef.current.set(id, file.type);
|
|
163
|
+
};
|
|
68
164
|
useEffect(() => {
|
|
69
165
|
const created = createdUrlsRef.current;
|
|
70
166
|
return () => created.forEach((url) => URL.revokeObjectURL(url));
|
|
@@ -93,6 +189,7 @@ function FileDropzoneImpl({
|
|
|
93
189
|
try {
|
|
94
190
|
const item = await upload(file);
|
|
95
191
|
if (item && typeof item.id === "string" && typeof item.url === "string") {
|
|
192
|
+
rememberFileType(item.id, file);
|
|
96
193
|
commit([...itemsRef.current, { name: file.name, ...item }]);
|
|
97
194
|
} else {
|
|
98
195
|
failures.push(`${file.name} (\uC5C5\uB85C\uB354\uAC00 \uD56D\uBAA9\uC744 \uC8FC\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4)`);
|
|
@@ -116,10 +213,11 @@ function FileDropzoneImpl({
|
|
|
116
213
|
} else {
|
|
117
214
|
const json = await res.json().catch(() => null);
|
|
118
215
|
const body = unwrapUploaded(json);
|
|
119
|
-
const
|
|
216
|
+
const id2 = body?.id;
|
|
120
217
|
const url2 = body?.url;
|
|
121
|
-
if ((typeof
|
|
122
|
-
|
|
218
|
+
if ((typeof id2 === "string" || typeof id2 === "number") && typeof url2 === "string") {
|
|
219
|
+
rememberFileType(String(id2), file);
|
|
220
|
+
commit([...itemsRef.current, { id: String(id2), url: url2, name: file.name }]);
|
|
123
221
|
} else {
|
|
124
222
|
failures.push(`${file.name} (\uC751\uB2F5 \uD615\uC2DD \uC624\uB958)`);
|
|
125
223
|
}
|
|
@@ -132,7 +230,9 @@ function FileDropzoneImpl({
|
|
|
132
230
|
}
|
|
133
231
|
const url = URL.createObjectURL(file);
|
|
134
232
|
createdUrlsRef.current.add(url);
|
|
135
|
-
|
|
233
|
+
const id = localId();
|
|
234
|
+
rememberFileType(id, file);
|
|
235
|
+
commit([...itemsRef.current, { id, url, name: file.name }]);
|
|
136
236
|
}
|
|
137
237
|
} finally {
|
|
138
238
|
setProgress(null);
|
|
@@ -177,6 +277,7 @@ function FileDropzoneImpl({
|
|
|
177
277
|
(item) => {
|
|
178
278
|
const forget = () => {
|
|
179
279
|
commit(itemsRef.current.filter((current) => current.id !== item.id));
|
|
280
|
+
fileTypesRef.current.delete(item.id);
|
|
180
281
|
if (createdUrlsRef.current.has(item.url)) {
|
|
181
282
|
URL.revokeObjectURL(item.url);
|
|
182
283
|
createdUrlsRef.current.delete(item.url);
|
|
@@ -208,6 +309,7 @@ function FileDropzoneImpl({
|
|
|
208
309
|
};
|
|
209
310
|
const showLocalCaption = localMode || items.some((item) => item.id.startsWith("local-"));
|
|
210
311
|
const dropTinted = canAdd && (dragOver || hovering);
|
|
312
|
+
const imageOnly = acceptIsImageOnly(accept);
|
|
211
313
|
return /* @__PURE__ */ jsxs("div", { className: "wp-col", style: { gap: "var(--wp-space-2)" }, children: [
|
|
212
314
|
/* @__PURE__ */ jsx(
|
|
213
315
|
"input",
|
|
@@ -231,7 +333,7 @@ function FileDropzoneImpl({
|
|
|
231
333
|
role: "button",
|
|
232
334
|
tabIndex: canAdd ? 0 : -1,
|
|
233
335
|
"aria-disabled": !canAdd,
|
|
234
|
-
"aria-label": "\uC774\uBBF8\uC9C0 \uCCA8\uBD80",
|
|
336
|
+
"aria-label": imageOnly ? "\uC774\uBBF8\uC9C0 \uCCA8\uBD80" : "\uD30C\uC77C \uCCA8\uBD80",
|
|
235
337
|
onClick: openPicker,
|
|
236
338
|
onKeyDown: (event) => {
|
|
237
339
|
if (canAdd && (event.key === "Enter" || event.key === " ")) {
|
|
@@ -284,7 +386,7 @@ function FileDropzoneImpl({
|
|
|
284
386
|
style: { color: dropTinted ? "var(--wp-text-brand)" : "var(--wp-text-muted)" }
|
|
285
387
|
}
|
|
286
388
|
),
|
|
287
|
-
/* @__PURE__ */ jsx("span", { className: "wp-body-sm", style: { color: "var(--wp-text-default)" }, children: atCapacity ? `\uCD5C\uB300 ${maxCount}\uAC1C\uAE4C\uC9C0 \uCCA8\uBD80\uD588\uC2B5\uB2C8\uB2E4` :
|
|
389
|
+
/* @__PURE__ */ jsx("span", { className: "wp-body-sm", style: { color: "var(--wp-text-default)" }, children: atCapacity ? `\uCD5C\uB300 ${maxCount}\uAC1C\uAE4C\uC9C0 \uCCA8\uBD80\uD588\uC2B5\uB2C8\uB2E4` : `\uD074\uB9AD\uD558\uAC70\uB098 ${imageOnly ? "\uC774\uBBF8\uC9C0\uB97C" : "\uD30C\uC77C\uC744"} \uB04C\uC5B4\uB2E4 \uB193\uC73C\uC138\uC694` }),
|
|
288
390
|
hint ? /* @__PURE__ */ jsx("span", { className: "wp-caption", children: hint }) : null
|
|
289
391
|
] })
|
|
290
392
|
}
|
|
@@ -318,47 +420,128 @@ function FileDropzoneImpl({
|
|
|
318
420
|
}
|
|
319
421
|
) : null,
|
|
320
422
|
items.length > 0 ? /* @__PURE__ */ jsx("div", { style: { display: "flex", flexWrap: "wrap", gap: "var(--wp-space-2)" }, children: items.map((item) => {
|
|
321
|
-
const
|
|
423
|
+
const fileType = fileTypesRef.current.get(item.id);
|
|
424
|
+
const asImage = itemLooksLikeImage(item, fileType);
|
|
425
|
+
const resolved = resolveAsset(item.url, {
|
|
322
426
|
component: "FileDropzone",
|
|
323
|
-
prop: "src",
|
|
427
|
+
prop: asImage ? "src" : "href",
|
|
324
428
|
kind: "attribute"
|
|
325
429
|
});
|
|
430
|
+
const hovered = hoverItemId === item.id;
|
|
431
|
+
let preview;
|
|
432
|
+
if (asImage) {
|
|
433
|
+
preview = resolved === null ? /* @__PURE__ */ jsx(
|
|
434
|
+
"span",
|
|
435
|
+
{
|
|
436
|
+
"aria-label": item.name ?? "\uCCA8\uBD80 \uBBF8\uB9AC\uBCF4\uAE30 \uC5C6\uC74C",
|
|
437
|
+
role: "img",
|
|
438
|
+
style: {
|
|
439
|
+
display: "block",
|
|
440
|
+
width: THUMB_SIZE,
|
|
441
|
+
height: THUMB_SIZE,
|
|
442
|
+
borderRadius: "var(--wp-radius-md)",
|
|
443
|
+
border: "var(--wp-border-w) solid var(--wp-border-subtle)",
|
|
444
|
+
background: "var(--wp-surface-sunken)"
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
) : /* @__PURE__ */ jsx(
|
|
448
|
+
ImageLightbox,
|
|
449
|
+
{
|
|
450
|
+
src: resolved,
|
|
451
|
+
alt: item.name,
|
|
452
|
+
thumbStyle: {
|
|
453
|
+
width: THUMB_SIZE,
|
|
454
|
+
height: THUMB_SIZE,
|
|
455
|
+
objectFit: "cover",
|
|
456
|
+
display: "block",
|
|
457
|
+
borderRadius: "var(--wp-radius-md)",
|
|
458
|
+
border: "var(--wp-border-w) solid var(--wp-border-subtle)"
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
);
|
|
462
|
+
} else {
|
|
463
|
+
const href = sandbox || resolved === null ? null : safeFileHref(resolved);
|
|
464
|
+
const displayName = displayNameOf(item);
|
|
465
|
+
const badge = fileBadgeOf(item, fileType);
|
|
466
|
+
const tileStyle = {
|
|
467
|
+
display: "flex",
|
|
468
|
+
alignItems: "center",
|
|
469
|
+
gap: "var(--wp-space-2)",
|
|
470
|
+
boxSizing: "border-box",
|
|
471
|
+
width: FILE_TILE_WIDTH,
|
|
472
|
+
height: THUMB_SIZE,
|
|
473
|
+
padding: "0 var(--wp-space-2)",
|
|
474
|
+
borderRadius: "var(--wp-radius-md)",
|
|
475
|
+
border: `var(--wp-border-w) solid ${hovered && href ? "var(--wp-border-strong)" : "var(--wp-border-subtle)"}`,
|
|
476
|
+
background: "var(--wp-surface-sunken)",
|
|
477
|
+
color: "var(--wp-text-default)",
|
|
478
|
+
textDecoration: "none",
|
|
479
|
+
transition: "var(--wp-transition-surface)"
|
|
480
|
+
};
|
|
481
|
+
const tileBody = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
482
|
+
/* @__PURE__ */ jsxs(
|
|
483
|
+
"span",
|
|
484
|
+
{
|
|
485
|
+
style: {
|
|
486
|
+
display: "flex",
|
|
487
|
+
flexDirection: "column",
|
|
488
|
+
alignItems: "center",
|
|
489
|
+
gap: 2,
|
|
490
|
+
flex: "none",
|
|
491
|
+
minWidth: 28,
|
|
492
|
+
color: "var(--wp-text-muted)"
|
|
493
|
+
},
|
|
494
|
+
children: [
|
|
495
|
+
/* @__PURE__ */ jsx(Icon, { name: "file-text", size: 24 }),
|
|
496
|
+
badge ? /* @__PURE__ */ jsx("span", { className: "wp-overline", style: { lineHeight: 1 }, children: badge }) : null
|
|
497
|
+
]
|
|
498
|
+
}
|
|
499
|
+
),
|
|
500
|
+
/* @__PURE__ */ jsx(
|
|
501
|
+
"span",
|
|
502
|
+
{
|
|
503
|
+
className: "wp-caption",
|
|
504
|
+
style: {
|
|
505
|
+
flex: 1,
|
|
506
|
+
minWidth: 0,
|
|
507
|
+
color: "var(--wp-text-default)",
|
|
508
|
+
display: "-webkit-box",
|
|
509
|
+
WebkitLineClamp: 2,
|
|
510
|
+
WebkitBoxOrient: "vertical",
|
|
511
|
+
overflow: "hidden",
|
|
512
|
+
wordBreak: "break-all"
|
|
513
|
+
},
|
|
514
|
+
children: displayName
|
|
515
|
+
}
|
|
516
|
+
)
|
|
517
|
+
] });
|
|
518
|
+
preview = href ? /* @__PURE__ */ jsx(
|
|
519
|
+
"a",
|
|
520
|
+
{
|
|
521
|
+
href,
|
|
522
|
+
target: "_blank",
|
|
523
|
+
rel: "noopener",
|
|
524
|
+
title: displayName,
|
|
525
|
+
"aria-label": `${displayName}${badge ? ` (${badge})` : ""} \u2014 \uC0C8 \uD0ED\uC5D0\uC11C \uC5F4\uAE30`,
|
|
526
|
+
"data-file-tile": "",
|
|
527
|
+
style: tileStyle,
|
|
528
|
+
onClick: (event) => event.stopPropagation(),
|
|
529
|
+
children: tileBody
|
|
530
|
+
}
|
|
531
|
+
) : /* @__PURE__ */ jsx("span", { title: displayName, "data-file-tile": "", style: tileStyle, children: tileBody });
|
|
532
|
+
}
|
|
326
533
|
return /* @__PURE__ */ jsxs(
|
|
327
534
|
"div",
|
|
328
535
|
{
|
|
329
|
-
style: {
|
|
536
|
+
style: {
|
|
537
|
+
position: "relative",
|
|
538
|
+
width: asImage ? THUMB_SIZE : FILE_TILE_WIDTH,
|
|
539
|
+
height: THUMB_SIZE
|
|
540
|
+
},
|
|
330
541
|
onMouseEnter: () => setHoverItemId(item.id),
|
|
331
542
|
onMouseLeave: () => setHoverItemId((current) => current === item.id ? null : current),
|
|
332
543
|
children: [
|
|
333
|
-
|
|
334
|
-
"span",
|
|
335
|
-
{
|
|
336
|
-
"aria-label": item.name ?? "\uCCA8\uBD80 \uBBF8\uB9AC\uBCF4\uAE30 \uC5C6\uC74C",
|
|
337
|
-
role: "img",
|
|
338
|
-
style: {
|
|
339
|
-
display: "block",
|
|
340
|
-
width: THUMB_SIZE,
|
|
341
|
-
height: THUMB_SIZE,
|
|
342
|
-
borderRadius: "var(--wp-radius-md)",
|
|
343
|
-
border: "var(--wp-border-w) solid var(--wp-border-subtle)",
|
|
344
|
-
background: "var(--wp-surface-sunken)"
|
|
345
|
-
}
|
|
346
|
-
}
|
|
347
|
-
) : /* @__PURE__ */ jsx(
|
|
348
|
-
ImageLightbox,
|
|
349
|
-
{
|
|
350
|
-
src: thumbSrc,
|
|
351
|
-
alt: item.name,
|
|
352
|
-
thumbStyle: {
|
|
353
|
-
width: THUMB_SIZE,
|
|
354
|
-
height: THUMB_SIZE,
|
|
355
|
-
objectFit: "cover",
|
|
356
|
-
display: "block",
|
|
357
|
-
borderRadius: "var(--wp-radius-md)",
|
|
358
|
-
border: "var(--wp-border-w) solid var(--wp-border-subtle)"
|
|
359
|
-
}
|
|
360
|
-
}
|
|
361
|
-
),
|
|
544
|
+
preview,
|
|
362
545
|
/* @__PURE__ */ jsx(
|
|
363
546
|
"span",
|
|
364
547
|
{
|
|
@@ -369,7 +552,7 @@ function FileDropzoneImpl({
|
|
|
369
552
|
background: "var(--wp-surface-card)",
|
|
370
553
|
borderRadius: "var(--wp-radius-sm)",
|
|
371
554
|
boxShadow: "var(--wp-shadow-sm)",
|
|
372
|
-
opacity:
|
|
555
|
+
opacity: hovered ? 1 : 0,
|
|
373
556
|
transition: "opacity var(--wp-duration-fast) var(--wp-ease-out)"
|
|
374
557
|
},
|
|
375
558
|
children: /* @__PURE__ */ jsx(
|
package/dist/meta.js
CHANGED
|
@@ -4376,7 +4376,7 @@ var FileDropzoneMeta = {
|
|
|
4376
4376
|
label: "\uD30C\uC77C \uCCA8\uBD80",
|
|
4377
4377
|
category: "input",
|
|
4378
4378
|
icon: "paperclip",
|
|
4379
|
-
description: "\uB4DC\uB798\uADF8 \uC564 \uB4DC\uB86D \uB2E4\uC911 \uCCA8\uBD80. \uC5C5\uB85C\uB4DC \uACBD\uB85C\uAC00 \uC5C6\uAC70\uB098 \uBC31\uC5D4\uB4DC\uAC00 503\uC774\uBA74 object URL \uB85C\uCEEC \uBBF8\uB9AC\uBCF4\uAE30\uB85C \uB5A8\uC5B4\uC9C4\uB2E4.",
|
|
4379
|
+
description: "\uB4DC\uB798\uADF8 \uC564 \uB4DC\uB86D \uB2E4\uC911 \uCCA8\uBD80. \uC774\uBBF8\uC9C0\uB294 \uC378\uB124\uC77C, PDF \uB4F1 \uADF8 \uBC16\uC758 \uD30C\uC77C\uC740 \uC0C8 \uD0ED\uC73C\uB85C \uC5EC\uB294 \uD30C\uC77C \uD0C0\uC77C\uB85C \uBCF4\uC778\uB2E4. \uC5C5\uB85C\uB4DC \uACBD\uB85C\uAC00 \uC5C6\uAC70\uB098 \uBC31\uC5D4\uB4DC\uAC00 503\uC774\uBA74 object URL \uB85C\uCEEC \uBBF8\uB9AC\uBCF4\uAE30\uB85C \uB5A8\uC5B4\uC9C4\uB2E4.",
|
|
4380
4380
|
props: [
|
|
4381
4381
|
{
|
|
4382
4382
|
name: "value",
|
|
@@ -4389,7 +4389,13 @@ var FileDropzoneMeta = {
|
|
|
4389
4389
|
item: [
|
|
4390
4390
|
{ name: "id", kind: "string", label: "\uC2DD\uBCC4\uC790", required: true },
|
|
4391
4391
|
{ name: "url", kind: "string", label: "URL", required: true },
|
|
4392
|
-
{ name: "name", kind: "string", label: "\uD30C\uC77C\uBA85" }
|
|
4392
|
+
{ name: "name", kind: "string", label: "\uD30C\uC77C\uBA85" },
|
|
4393
|
+
{
|
|
4394
|
+
name: "mimeType",
|
|
4395
|
+
kind: "string",
|
|
4396
|
+
label: "MIME \uD615\uC2DD",
|
|
4397
|
+
description: "image/\u2026 \uC774\uBA74 \uC378\uB124\uC77C, \uC544\uB2C8\uBA74 \uD30C\uC77C \uD0C0\uC77C(\uBB38\uC11C \uC544\uC774\uCF58\xB7\uD655\uC7A5\uC790\xB7\uD30C\uC77C\uBA85, \uB204\uB974\uBA74 \uC0C8 \uD0ED). mime_type\xB7type \uB3C4 \uC77D\uACE0, \uC5C6\uC73C\uBA74 URL\xB7\uD30C\uC77C\uBA85 \uD655\uC7A5\uC790\uB85C \uD310\uC815\uD55C\uB2E4."
|
|
4398
|
+
}
|
|
4393
4399
|
]
|
|
4394
4400
|
},
|
|
4395
4401
|
{
|
|
@@ -5,6 +5,14 @@ type FileDropzoneItem = {
|
|
|
5
5
|
id: string;
|
|
6
6
|
url: string;
|
|
7
7
|
name?: string;
|
|
8
|
+
/**
|
|
9
|
+
* MIME 형식(예: `application/pdf`) — 있으면 이미지/파일 타일 판정의 1순위다.
|
|
10
|
+
* 서버 행을 그대로 채우는 앱은 snake_case(`mime_type`)로 주고, File 같은 객체는
|
|
11
|
+
* `type`으로 준다 — 셋 다 읽는다(`type`은 `x/y` 모양일 때만 MIME 으로 본다).
|
|
12
|
+
*/
|
|
13
|
+
mimeType?: string;
|
|
14
|
+
mime_type?: string;
|
|
15
|
+
type?: string;
|
|
8
16
|
};
|
|
9
17
|
interface FileDropzoneProps {
|
|
10
18
|
/** 백엔드 업로드 경로 (예: "/attachments"). 없으면 로컬 미리보기 모드 */
|
package/dist/widgets/index.js
CHANGED
|
@@ -59,7 +59,7 @@ import { Disclosure } from '../chunk-LONXOEZY.js';
|
|
|
59
59
|
export { Disclosure } from '../chunk-LONXOEZY.js';
|
|
60
60
|
import { EventCalendar } from '../chunk-KVQXQLAP.js';
|
|
61
61
|
export { EventCalendar, statusToneOf } from '../chunk-KVQXQLAP.js';
|
|
62
|
-
export { FileDropzone, unwrapUploaded } from '../chunk-
|
|
62
|
+
export { FileDropzone, unwrapUploaded } from '../chunk-CFFSCGDV.js';
|
|
63
63
|
import { ImageLightbox } from '../chunk-JDTVNS3H.js';
|
|
64
64
|
export { ImageLightbox } from '../chunk-JDTVNS3H.js';
|
|
65
65
|
import { InlineEdit } from '../chunk-FXEKHHEA.js';
|