@roy-ui/ui 0.0.14 → 0.0.16
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/{UploadFiles-VBIEAV7L.css → UploadFiles-QEAOV3R6.css} +288 -56
- package/dist/chunk-E2VDIA6U.js +621 -0
- package/dist/chunk-E2VDIA6U.js.map +1 -0
- package/dist/{chunk-LV4JMUGV.js → chunk-PDUQROG2.js} +3 -3
- package/dist/{chunk-LV4JMUGV.js.map → chunk-PDUQROG2.js.map} +1 -1
- package/dist/components/data-table/index.js +2 -2
- package/dist/components/upload-files/index.d.ts +22 -1
- package/dist/components/upload-files/index.js +1 -1
- package/dist/index.js +4 -4
- package/package.json +1 -1
- package/dist/chunk-6JYEHTQR.js +0 -364
- package/dist/chunk-6JYEHTQR.js.map +0 -1
package/dist/chunk-6JYEHTQR.js
DELETED
|
@@ -1,364 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { TextMorph } from './chunk-MO7UPMW7.js';
|
|
3
|
-
import { Button } from './chunk-B6LXWGX5.js';
|
|
4
|
-
import { forwardRef, useRef, useState, useMemo, useEffect } from 'react';
|
|
5
|
-
import './UploadFiles-VBIEAV7L.css';
|
|
6
|
-
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
7
|
-
|
|
8
|
-
var DEFAULT_STATUS_WORDS = [
|
|
9
|
-
"Uploading\u2026",
|
|
10
|
-
"Transferring\u2026",
|
|
11
|
-
"Beaming bytes\u2026",
|
|
12
|
-
"Encrypting\u2026",
|
|
13
|
-
"Securing\u2026",
|
|
14
|
-
"Packing bits\u2026",
|
|
15
|
-
"Syncing\u2026",
|
|
16
|
-
"Crunching data\u2026",
|
|
17
|
-
"Pushing pixels\u2026",
|
|
18
|
-
"Almost there\u2026",
|
|
19
|
-
"Hang tight\u2026",
|
|
20
|
-
"Wrangling chunks\u2026",
|
|
21
|
-
"Verifying\u2026",
|
|
22
|
-
"Finalizing\u2026",
|
|
23
|
-
"Just a sec\u2026"
|
|
24
|
-
];
|
|
25
|
-
var EXT_META = {
|
|
26
|
-
pdf: { label: "PDF", color: "#f0524b" },
|
|
27
|
-
doc: { label: "DOC", color: "#3b82f6" },
|
|
28
|
-
docx: { label: "DOCX", color: "#3b82f6" },
|
|
29
|
-
fig: { label: "FIG", color: "#a259ff" },
|
|
30
|
-
png: { label: "PNG", color: "#10b981" },
|
|
31
|
-
jpg: { label: "JPG", color: "#10b981" },
|
|
32
|
-
jpeg: { label: "JPG", color: "#10b981" },
|
|
33
|
-
gif: { label: "GIF", color: "#10b981" },
|
|
34
|
-
svg: { label: "SVG", color: "#f59e0b" },
|
|
35
|
-
zip: { label: "ZIP", color: "#f59e0b" },
|
|
36
|
-
mp4: { label: "MP4", color: "#ec4899" },
|
|
37
|
-
csv: { label: "CSV", color: "#22c55e" },
|
|
38
|
-
json: { label: "JSON", color: "#eab308" },
|
|
39
|
-
default: { label: "FILE", color: "#8b8b94" }
|
|
40
|
-
};
|
|
41
|
-
function extMeta(name) {
|
|
42
|
-
const ext = name.split(".").pop()?.toLowerCase() ?? "";
|
|
43
|
-
return EXT_META[ext] ?? EXT_META.default;
|
|
44
|
-
}
|
|
45
|
-
function trimNum(n) {
|
|
46
|
-
return (Math.round(n * 10) / 10).toString();
|
|
47
|
-
}
|
|
48
|
-
function formatBytes(bytes) {
|
|
49
|
-
if (!Number.isFinite(bytes) || bytes < 0) return "0 B";
|
|
50
|
-
if (bytes < 1024) return `${Math.round(bytes)} B`;
|
|
51
|
-
const kb = bytes / 1024;
|
|
52
|
-
if (kb < 1024) return `${trimNum(kb)} KB`;
|
|
53
|
-
const mb = kb / 1024;
|
|
54
|
-
if (mb < 1024) return `${trimNum(mb)} MB`;
|
|
55
|
-
return `${trimNum(mb / 1024)} GB`;
|
|
56
|
-
}
|
|
57
|
-
function shuffle(input) {
|
|
58
|
-
const a = input.slice();
|
|
59
|
-
for (let i = a.length - 1; i > 0; i--) {
|
|
60
|
-
const j = Math.floor(Math.random() * (i + 1));
|
|
61
|
-
[a[i], a[j]] = [a[j], a[i]];
|
|
62
|
-
}
|
|
63
|
-
return a;
|
|
64
|
-
}
|
|
65
|
-
var cn = (...classes) => classes.filter(Boolean).join(" ");
|
|
66
|
-
var UploadGlyph = () => /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 24 24", width: "22", height: "22", fill: "none", "aria-hidden": "true", children: [
|
|
67
|
-
/* @__PURE__ */ jsx(
|
|
68
|
-
"path",
|
|
69
|
-
{
|
|
70
|
-
d: "M12 15V4m0 0L7.5 8.5M12 4l4.5 4.5",
|
|
71
|
-
stroke: "currentColor",
|
|
72
|
-
strokeWidth: "1.6",
|
|
73
|
-
strokeLinecap: "round",
|
|
74
|
-
strokeLinejoin: "round"
|
|
75
|
-
}
|
|
76
|
-
),
|
|
77
|
-
/* @__PURE__ */ jsx(
|
|
78
|
-
"path",
|
|
79
|
-
{
|
|
80
|
-
d: "M4 14v3.5A2.5 2.5 0 0 0 6.5 20h11a2.5 2.5 0 0 0 2.5-2.5V14",
|
|
81
|
-
stroke: "currentColor",
|
|
82
|
-
strokeWidth: "1.6",
|
|
83
|
-
strokeLinecap: "round"
|
|
84
|
-
}
|
|
85
|
-
)
|
|
86
|
-
] });
|
|
87
|
-
var CloseGlyph = () => /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", width: "16", height: "16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx(
|
|
88
|
-
"path",
|
|
89
|
-
{
|
|
90
|
-
d: "M6 6l12 12M18 6L6 18",
|
|
91
|
-
stroke: "currentColor",
|
|
92
|
-
strokeWidth: "1.6",
|
|
93
|
-
strokeLinecap: "round"
|
|
94
|
-
}
|
|
95
|
-
) });
|
|
96
|
-
var TrashGlyph = () => /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", width: "17", height: "17", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx(
|
|
97
|
-
"path",
|
|
98
|
-
{
|
|
99
|
-
d: "M4 7h16M9 7V5.5A1.5 1.5 0 0 1 10.5 4h3A1.5 1.5 0 0 1 15 5.5V7m2 0v11.5A1.5 1.5 0 0 1 15.5 20h-7A1.5 1.5 0 0 1 7 18.5V7m3 3.5v6m4-6v6",
|
|
100
|
-
stroke: "currentColor",
|
|
101
|
-
strokeWidth: "1.5",
|
|
102
|
-
strokeLinecap: "round",
|
|
103
|
-
strokeLinejoin: "round"
|
|
104
|
-
}
|
|
105
|
-
) });
|
|
106
|
-
var CheckGlyph = () => /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", width: "13", height: "13", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx(
|
|
107
|
-
"path",
|
|
108
|
-
{
|
|
109
|
-
d: "M4 12.5l5 5 11-12",
|
|
110
|
-
stroke: "currentColor",
|
|
111
|
-
strokeWidth: "2.2",
|
|
112
|
-
strokeLinecap: "round",
|
|
113
|
-
strokeLinejoin: "round"
|
|
114
|
-
}
|
|
115
|
-
) });
|
|
116
|
-
var KebabGlyph = () => /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 24 24", width: "16", height: "16", fill: "currentColor", "aria-hidden": "true", children: [
|
|
117
|
-
/* @__PURE__ */ jsx("circle", { cx: "12", cy: "5", r: "1.7" }),
|
|
118
|
-
/* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "1.7" }),
|
|
119
|
-
/* @__PURE__ */ jsx("circle", { cx: "12", cy: "19", r: "1.7" })
|
|
120
|
-
] });
|
|
121
|
-
function FileRow({
|
|
122
|
-
file,
|
|
123
|
-
word,
|
|
124
|
-
onRemove
|
|
125
|
-
}) {
|
|
126
|
-
const meta = extMeta(file.name);
|
|
127
|
-
const pct = file.progress != null ? Math.max(0, Math.min(100, Math.round(file.progress))) : file.size > 0 ? Math.max(0, Math.min(100, Math.round((file.uploaded ?? 0) / file.size * 100))) : 0;
|
|
128
|
-
const isUploading = file.status === "uploading";
|
|
129
|
-
const isError = file.status === "error";
|
|
130
|
-
return /* @__PURE__ */ jsxs("div", { className: "royui-upload__row", "data-status": file.status, children: [
|
|
131
|
-
/* @__PURE__ */ jsx(
|
|
132
|
-
"span",
|
|
133
|
-
{
|
|
134
|
-
className: "royui-upload__badge",
|
|
135
|
-
style: { ["--royui-upload-badge"]: file.icon ? "transparent" : meta.color },
|
|
136
|
-
"aria-hidden": "true",
|
|
137
|
-
children: file.icon ?? /* @__PURE__ */ jsx("span", { className: "royui-upload__badge-label", children: meta.label })
|
|
138
|
-
}
|
|
139
|
-
),
|
|
140
|
-
/* @__PURE__ */ jsxs("div", { className: "royui-upload__row-main", children: [
|
|
141
|
-
/* @__PURE__ */ jsxs("div", { className: "royui-upload__row-top", children: [
|
|
142
|
-
/* @__PURE__ */ jsx("span", { className: "royui-upload__name", title: file.name, children: file.name }),
|
|
143
|
-
/* @__PURE__ */ jsx(
|
|
144
|
-
"button",
|
|
145
|
-
{
|
|
146
|
-
type: "button",
|
|
147
|
-
className: "royui-upload__row-action",
|
|
148
|
-
"aria-label": isUploading ? `Cancel ${file.name}` : `Remove ${file.name}`,
|
|
149
|
-
onClick: () => onRemove?.(file.id),
|
|
150
|
-
children: isUploading ? /* @__PURE__ */ jsx(CloseGlyph, {}) : /* @__PURE__ */ jsx(TrashGlyph, {})
|
|
151
|
-
}
|
|
152
|
-
)
|
|
153
|
-
] }),
|
|
154
|
-
/* @__PURE__ */ jsxs("div", { className: "royui-upload__meta", children: [
|
|
155
|
-
file.status === "complete" && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
156
|
-
/* @__PURE__ */ jsx("span", { children: formatBytes(file.size) }),
|
|
157
|
-
/* @__PURE__ */ jsx("span", { className: "royui-upload__meta-sep", children: "/" }),
|
|
158
|
-
/* @__PURE__ */ jsxs("span", { className: "royui-upload__complete", children: [
|
|
159
|
-
/* @__PURE__ */ jsx(CheckGlyph, {}),
|
|
160
|
-
"Complete"
|
|
161
|
-
] })
|
|
162
|
-
] }),
|
|
163
|
-
isUploading && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
164
|
-
/* @__PURE__ */ jsxs("span", { children: [
|
|
165
|
-
/* @__PURE__ */ jsx(TextMorph, { value: formatBytes(file.uploaded ?? 0) }),
|
|
166
|
-
" of",
|
|
167
|
-
" ",
|
|
168
|
-
formatBytes(file.size)
|
|
169
|
-
] }),
|
|
170
|
-
/* @__PURE__ */ jsx("span", { className: "royui-upload__meta-sep", children: "/" }),
|
|
171
|
-
/* @__PURE__ */ jsx(
|
|
172
|
-
TextMorph,
|
|
173
|
-
{
|
|
174
|
-
className: "royui-upload__status",
|
|
175
|
-
value: word,
|
|
176
|
-
renderText: (t) => /* @__PURE__ */ jsx("span", { className: "royui-upload__shimmer", children: t })
|
|
177
|
-
}
|
|
178
|
-
)
|
|
179
|
-
] }),
|
|
180
|
-
isError && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
181
|
-
/* @__PURE__ */ jsx("span", { children: formatBytes(file.size) }),
|
|
182
|
-
/* @__PURE__ */ jsx("span", { className: "royui-upload__meta-sep", children: "/" }),
|
|
183
|
-
/* @__PURE__ */ jsx("span", { className: "royui-upload__error", children: "Failed" })
|
|
184
|
-
] })
|
|
185
|
-
] }),
|
|
186
|
-
isUploading && /* @__PURE__ */ jsxs("div", { className: "royui-upload__progress", children: [
|
|
187
|
-
/* @__PURE__ */ jsx(
|
|
188
|
-
"div",
|
|
189
|
-
{
|
|
190
|
-
className: "royui-upload__bar",
|
|
191
|
-
role: "progressbar",
|
|
192
|
-
"aria-valuenow": pct,
|
|
193
|
-
"aria-valuemin": 0,
|
|
194
|
-
"aria-valuemax": 100,
|
|
195
|
-
children: /* @__PURE__ */ jsx("div", { className: "royui-upload__bar-fill", style: { width: `${pct}%` } })
|
|
196
|
-
}
|
|
197
|
-
),
|
|
198
|
-
/* @__PURE__ */ jsxs("span", { className: "royui-upload__pct", children: [
|
|
199
|
-
pct,
|
|
200
|
-
"%"
|
|
201
|
-
] })
|
|
202
|
-
] })
|
|
203
|
-
] })
|
|
204
|
-
] });
|
|
205
|
-
}
|
|
206
|
-
var UploadFiles = forwardRef(
|
|
207
|
-
function UploadFiles2({
|
|
208
|
-
files,
|
|
209
|
-
title = "Upload files",
|
|
210
|
-
maxSizeLabel = "MAX FILE SIZE: 20 MB",
|
|
211
|
-
accept,
|
|
212
|
-
multiple = true,
|
|
213
|
-
theme = "dark",
|
|
214
|
-
statusWords = DEFAULT_STATUS_WORDS,
|
|
215
|
-
actionLabel,
|
|
216
|
-
onFilesSelected,
|
|
217
|
-
onRemove,
|
|
218
|
-
onRemoveAll,
|
|
219
|
-
onClose,
|
|
220
|
-
onAction,
|
|
221
|
-
className = "",
|
|
222
|
-
...rest
|
|
223
|
-
}, ref) {
|
|
224
|
-
const inputRef = useRef(null);
|
|
225
|
-
const [isDragging, setDragging] = useState(false);
|
|
226
|
-
const [tick, setTick] = useState(0);
|
|
227
|
-
const anyUploading = files.some((f) => f.status === "uploading");
|
|
228
|
-
const words = useMemo(
|
|
229
|
-
() => statusWords.length ? shuffle(statusWords) : DEFAULT_STATUS_WORDS,
|
|
230
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
231
|
-
[]
|
|
232
|
-
);
|
|
233
|
-
useEffect(() => {
|
|
234
|
-
if (!anyUploading) return;
|
|
235
|
-
const id = setInterval(() => setTick((t) => t + 1), 1900);
|
|
236
|
-
return () => clearInterval(id);
|
|
237
|
-
}, [anyUploading]);
|
|
238
|
-
const emit = (list) => {
|
|
239
|
-
if (!list || list.length === 0) return;
|
|
240
|
-
onFilesSelected?.(Array.from(list));
|
|
241
|
-
};
|
|
242
|
-
const classes = cn(
|
|
243
|
-
"royui-upload",
|
|
244
|
-
theme === "dark" && "royui-upload--dark",
|
|
245
|
-
theme === "light" && "royui-upload--light",
|
|
246
|
-
theme === "auto" && "royui-upload--auto",
|
|
247
|
-
className
|
|
248
|
-
);
|
|
249
|
-
return /* @__PURE__ */ jsxs("div", { ref, className: classes, ...rest, children: [
|
|
250
|
-
/* @__PURE__ */ jsxs("header", { className: "royui-upload__header", children: [
|
|
251
|
-
/* @__PURE__ */ jsx("h2", { className: "royui-upload__title", children: title }),
|
|
252
|
-
onClose && /* @__PURE__ */ jsx(
|
|
253
|
-
"button",
|
|
254
|
-
{
|
|
255
|
-
type: "button",
|
|
256
|
-
className: "royui-upload__close",
|
|
257
|
-
"aria-label": "Close",
|
|
258
|
-
onClick: onClose,
|
|
259
|
-
children: /* @__PURE__ */ jsx(CloseGlyph, {})
|
|
260
|
-
}
|
|
261
|
-
)
|
|
262
|
-
] }),
|
|
263
|
-
/* @__PURE__ */ jsxs(
|
|
264
|
-
"div",
|
|
265
|
-
{
|
|
266
|
-
className: cn("royui-upload__dropzone", isDragging && "is-dragging"),
|
|
267
|
-
onDragOver: (e) => {
|
|
268
|
-
e.preventDefault();
|
|
269
|
-
setDragging(true);
|
|
270
|
-
},
|
|
271
|
-
onDragLeave: (e) => {
|
|
272
|
-
e.preventDefault();
|
|
273
|
-
setDragging(false);
|
|
274
|
-
},
|
|
275
|
-
onDrop: (e) => {
|
|
276
|
-
e.preventDefault();
|
|
277
|
-
setDragging(false);
|
|
278
|
-
emit(e.dataTransfer.files);
|
|
279
|
-
},
|
|
280
|
-
children: [
|
|
281
|
-
/* @__PURE__ */ jsx("span", { className: "royui-upload__drop-icon", "aria-hidden": "true", children: /* @__PURE__ */ jsx(UploadGlyph, {}) }),
|
|
282
|
-
/* @__PURE__ */ jsxs("p", { className: "royui-upload__drop-text", children: [
|
|
283
|
-
"Drag and drop or",
|
|
284
|
-
" ",
|
|
285
|
-
/* @__PURE__ */ jsx(
|
|
286
|
-
"button",
|
|
287
|
-
{
|
|
288
|
-
type: "button",
|
|
289
|
-
className: "royui-upload__browse",
|
|
290
|
-
onClick: () => inputRef.current?.click(),
|
|
291
|
-
children: "browse files"
|
|
292
|
-
}
|
|
293
|
-
)
|
|
294
|
-
] }),
|
|
295
|
-
/* @__PURE__ */ jsx("p", { className: "royui-upload__drop-hint", children: maxSizeLabel }),
|
|
296
|
-
/* @__PURE__ */ jsx(
|
|
297
|
-
"input",
|
|
298
|
-
{
|
|
299
|
-
ref: inputRef,
|
|
300
|
-
type: "file",
|
|
301
|
-
accept,
|
|
302
|
-
multiple,
|
|
303
|
-
className: "royui-upload__input",
|
|
304
|
-
onChange: (e) => {
|
|
305
|
-
emit(e.target.files);
|
|
306
|
-
e.target.value = "";
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
)
|
|
310
|
-
]
|
|
311
|
-
}
|
|
312
|
-
),
|
|
313
|
-
files.length > 0 && /* @__PURE__ */ jsx("div", { className: "royui-upload__list", children: files.map((file, i) => /* @__PURE__ */ jsx(
|
|
314
|
-
FileRow,
|
|
315
|
-
{
|
|
316
|
-
file,
|
|
317
|
-
word: words[(tick + i) % words.length],
|
|
318
|
-
onRemove
|
|
319
|
-
},
|
|
320
|
-
file.id
|
|
321
|
-
)) }),
|
|
322
|
-
files.length > 0 && /* @__PURE__ */ jsxs("footer", { className: "royui-upload__footer", children: [
|
|
323
|
-
/* @__PURE__ */ jsx(
|
|
324
|
-
"button",
|
|
325
|
-
{
|
|
326
|
-
type: "button",
|
|
327
|
-
className: "royui-upload__icon-btn",
|
|
328
|
-
"aria-label": "More options",
|
|
329
|
-
children: /* @__PURE__ */ jsx(KebabGlyph, {})
|
|
330
|
-
}
|
|
331
|
-
),
|
|
332
|
-
/* @__PURE__ */ jsxs(
|
|
333
|
-
"button",
|
|
334
|
-
{
|
|
335
|
-
type: "button",
|
|
336
|
-
className: "royui-upload__remove-all",
|
|
337
|
-
onClick: onRemoveAll,
|
|
338
|
-
children: [
|
|
339
|
-
/* @__PURE__ */ jsx(TrashGlyph, {}),
|
|
340
|
-
"Remove all"
|
|
341
|
-
]
|
|
342
|
-
}
|
|
343
|
-
),
|
|
344
|
-
/* @__PURE__ */ jsx("span", { className: "royui-upload__footer-spacer" }),
|
|
345
|
-
/* @__PURE__ */ jsx(
|
|
346
|
-
Button,
|
|
347
|
-
{
|
|
348
|
-
size: "sm",
|
|
349
|
-
variant: "secondary",
|
|
350
|
-
className: "royui-upload__action",
|
|
351
|
-
disabled: anyUploading,
|
|
352
|
-
onClick: onAction,
|
|
353
|
-
children: actionLabel ?? (anyUploading ? /* @__PURE__ */ jsx(TextMorph, { value: "Uploading\u2026" }) : "Done")
|
|
354
|
-
}
|
|
355
|
-
)
|
|
356
|
-
] })
|
|
357
|
-
] });
|
|
358
|
-
}
|
|
359
|
-
);
|
|
360
|
-
UploadFiles.displayName = "UploadFiles";
|
|
361
|
-
|
|
362
|
-
export { UploadFiles };
|
|
363
|
-
//# sourceMappingURL=chunk-6JYEHTQR.js.map
|
|
364
|
-
//# sourceMappingURL=chunk-6JYEHTQR.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/upload-files/UploadFiles.tsx"],"names":["UploadFiles"],"mappings":"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","file":"chunk-6JYEHTQR.js","sourcesContent":["'use client';\n\nimport {\n forwardRef,\n useEffect,\n useMemo,\n useRef,\n useState,\n type HTMLAttributes,\n type ReactNode,\n} from 'react';\nimport { TextMorph } from '../text-morph/TextMorph';\nimport { Button } from '../button/Button';\nimport './UploadFiles.css';\n\nexport type UploadStatus = 'uploading' | 'complete' | 'error';\n\nexport interface UploadFile {\n /** Stable id — used as the React key and passed back to onRemove. */\n id: string;\n /** File name including extension; drives the type badge. */\n name: string;\n /** Total size in bytes. */\n size: number;\n /** Bytes transferred so far. Drives the \"X OF Y\" label and, when\n * `progress` is omitted, the percentage. */\n uploaded?: number;\n /** Progress 0–100. Falls back to uploaded / size when omitted. */\n progress?: number;\n /** Lifecycle state. */\n status: UploadStatus;\n /** Optional override for the file-type badge. */\n icon?: ReactNode;\n}\n\nexport type UploadTheme = 'auto' | 'light' | 'dark';\n\nexport interface UploadFilesProps\n extends Omit<HTMLAttributes<HTMLDivElement>, 'title'> {\n /** The files to render. The component is controlled — it draws this\n * list and emits events; the consumer owns the upload + progress. */\n files: UploadFile[];\n /** Panel heading. Defaults to \"Upload files\". */\n title?: ReactNode;\n /** Caption under the dropzone. Defaults to \"MAX FILE SIZE: 20 MB\". */\n maxSizeLabel?: string;\n /** Forwarded to the hidden file input's `accept`. */\n accept?: string;\n /** Allow selecting multiple files. Defaults to true. */\n multiple?: boolean;\n /** Color scheme. Dark by default; \"auto\" follows the OS. */\n theme?: UploadTheme;\n /** Words cycled (and morphed) in the per-file status while uploading.\n * Defaults to a long, varied upload vocabulary so the wait stays lively. */\n statusWords?: string[];\n /** Footer action button content. Defaults to a state-derived label\n * (\"Uploading…\" while in flight, \"Done\" otherwise). */\n actionLabel?: ReactNode;\n /** Fired with the dropped / browsed File objects. */\n onFilesSelected?: (files: File[]) => void;\n /** Fired when a single row's trash / cancel control is pressed. */\n onRemove?: (id: string) => void;\n /** Fired by the \"Remove all\" footer control. */\n onRemoveAll?: () => void;\n /** When provided, renders the header close (×) button. */\n onClose?: () => void;\n /** Fired by the footer action button. */\n onAction?: () => void;\n}\n\nconst DEFAULT_STATUS_WORDS = [\n 'Uploading…',\n 'Transferring…',\n 'Beaming bytes…',\n 'Encrypting…',\n 'Securing…',\n 'Packing bits…',\n 'Syncing…',\n 'Crunching data…',\n 'Pushing pixels…',\n 'Almost there…',\n 'Hang tight…',\n 'Wrangling chunks…',\n 'Verifying…',\n 'Finalizing…',\n 'Just a sec…',\n];\n\nconst EXT_META: Record<string, { label: string; color: string }> = {\n pdf: { label: 'PDF', color: '#f0524b' },\n doc: { label: 'DOC', color: '#3b82f6' },\n docx: { label: 'DOCX', color: '#3b82f6' },\n fig: { label: 'FIG', color: '#a259ff' },\n png: { label: 'PNG', color: '#10b981' },\n jpg: { label: 'JPG', color: '#10b981' },\n jpeg: { label: 'JPG', color: '#10b981' },\n gif: { label: 'GIF', color: '#10b981' },\n svg: { label: 'SVG', color: '#f59e0b' },\n zip: { label: 'ZIP', color: '#f59e0b' },\n mp4: { label: 'MP4', color: '#ec4899' },\n csv: { label: 'CSV', color: '#22c55e' },\n json: { label: 'JSON', color: '#eab308' },\n default: { label: 'FILE', color: '#8b8b94' },\n};\n\nfunction extMeta(name: string) {\n const ext = name.split('.').pop()?.toLowerCase() ?? '';\n return EXT_META[ext] ?? EXT_META.default!;\n}\n\nfunction trimNum(n: number): string {\n return (Math.round(n * 10) / 10).toString();\n}\n\n/** Human-readable byte size, e.g. 2.7 MB / 14 MB. */\nfunction formatBytes(bytes: number): string {\n if (!Number.isFinite(bytes) || bytes < 0) return '0 B';\n if (bytes < 1024) return `${Math.round(bytes)} B`;\n const kb = bytes / 1024;\n if (kb < 1024) return `${trimNum(kb)} KB`;\n const mb = kb / 1024;\n if (mb < 1024) return `${trimNum(mb)} MB`;\n return `${trimNum(mb / 1024)} GB`;\n}\n\n/** Deterministic-ish shuffle (Fisher–Yates) so the word order varies per\n * session without two adjacent entries being the same word. */\nfunction shuffle<T>(input: T[]): T[] {\n const a = input.slice();\n for (let i = a.length - 1; i > 0; i--) {\n const j = Math.floor(Math.random() * (i + 1));\n [a[i], a[j]] = [a[j]!, a[i]!];\n }\n return a;\n}\n\nconst cn = (...classes: (string | false | undefined)[]) =>\n classes.filter(Boolean).join(' ');\n\n/* ── Icons ──────────────────────────────────────────────────────────────── */\n\nconst UploadGlyph = () => (\n <svg viewBox=\"0 0 24 24\" width=\"22\" height=\"22\" fill=\"none\" aria-hidden=\"true\">\n <path\n d=\"M12 15V4m0 0L7.5 8.5M12 4l4.5 4.5\"\n stroke=\"currentColor\"\n strokeWidth=\"1.6\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n <path\n d=\"M4 14v3.5A2.5 2.5 0 0 0 6.5 20h11a2.5 2.5 0 0 0 2.5-2.5V14\"\n stroke=\"currentColor\"\n strokeWidth=\"1.6\"\n strokeLinecap=\"round\"\n />\n </svg>\n);\n\nconst CloseGlyph = () => (\n <svg viewBox=\"0 0 24 24\" width=\"16\" height=\"16\" fill=\"none\" aria-hidden=\"true\">\n <path\n d=\"M6 6l12 12M18 6L6 18\"\n stroke=\"currentColor\"\n strokeWidth=\"1.6\"\n strokeLinecap=\"round\"\n />\n </svg>\n);\n\nconst TrashGlyph = () => (\n <svg viewBox=\"0 0 24 24\" width=\"17\" height=\"17\" fill=\"none\" aria-hidden=\"true\">\n <path\n d=\"M4 7h16M9 7V5.5A1.5 1.5 0 0 1 10.5 4h3A1.5 1.5 0 0 1 15 5.5V7m2 0v11.5A1.5 1.5 0 0 1 15.5 20h-7A1.5 1.5 0 0 1 7 18.5V7m3 3.5v6m4-6v6\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n);\n\nconst CheckGlyph = () => (\n <svg viewBox=\"0 0 24 24\" width=\"13\" height=\"13\" fill=\"none\" aria-hidden=\"true\">\n <path\n d=\"M4 12.5l5 5 11-12\"\n stroke=\"currentColor\"\n strokeWidth=\"2.2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n);\n\nconst KebabGlyph = () => (\n <svg viewBox=\"0 0 24 24\" width=\"16\" height=\"16\" fill=\"currentColor\" aria-hidden=\"true\">\n <circle cx=\"12\" cy=\"5\" r=\"1.7\" />\n <circle cx=\"12\" cy=\"12\" r=\"1.7\" />\n <circle cx=\"12\" cy=\"19\" r=\"1.7\" />\n </svg>\n);\n\n/* ── File row ───────────────────────────────────────────────────────────── */\n\nfunction FileRow({\n file,\n word,\n onRemove,\n}: {\n file: UploadFile;\n word: string;\n onRemove?: (id: string) => void;\n}) {\n const meta = extMeta(file.name);\n const pct =\n file.progress != null\n ? Math.max(0, Math.min(100, Math.round(file.progress)))\n : file.size > 0\n ? Math.max(0, Math.min(100, Math.round(((file.uploaded ?? 0) / file.size) * 100)))\n : 0;\n\n const isUploading = file.status === 'uploading';\n const isError = file.status === 'error';\n\n return (\n <div className=\"royui-upload__row\" data-status={file.status}>\n <span\n className=\"royui-upload__badge\"\n style={{ ['--royui-upload-badge' as string]: file.icon ? 'transparent' : meta.color }}\n aria-hidden=\"true\"\n >\n {file.icon ?? <span className=\"royui-upload__badge-label\">{meta.label}</span>}\n </span>\n\n <div className=\"royui-upload__row-main\">\n <div className=\"royui-upload__row-top\">\n <span className=\"royui-upload__name\" title={file.name}>\n {file.name}\n </span>\n <button\n type=\"button\"\n className=\"royui-upload__row-action\"\n aria-label={isUploading ? `Cancel ${file.name}` : `Remove ${file.name}`}\n onClick={() => onRemove?.(file.id)}\n >\n {isUploading ? <CloseGlyph /> : <TrashGlyph />}\n </button>\n </div>\n\n <div className=\"royui-upload__meta\">\n {file.status === 'complete' && (\n <>\n <span>{formatBytes(file.size)}</span>\n <span className=\"royui-upload__meta-sep\">/</span>\n <span className=\"royui-upload__complete\">\n <CheckGlyph />\n Complete\n </span>\n </>\n )}\n {isUploading && (\n <>\n <span>\n <TextMorph value={formatBytes(file.uploaded ?? 0)} /> of{' '}\n {formatBytes(file.size)}\n </span>\n <span className=\"royui-upload__meta-sep\">/</span>\n <TextMorph\n className=\"royui-upload__status\"\n value={word}\n renderText={(t) => (\n <span className=\"royui-upload__shimmer\">{t}</span>\n )}\n />\n </>\n )}\n {isError && (\n <>\n <span>{formatBytes(file.size)}</span>\n <span className=\"royui-upload__meta-sep\">/</span>\n <span className=\"royui-upload__error\">Failed</span>\n </>\n )}\n </div>\n\n {isUploading && (\n <div className=\"royui-upload__progress\">\n <div\n className=\"royui-upload__bar\"\n role=\"progressbar\"\n aria-valuenow={pct}\n aria-valuemin={0}\n aria-valuemax={100}\n >\n <div className=\"royui-upload__bar-fill\" style={{ width: `${pct}%` }} />\n </div>\n <span className=\"royui-upload__pct\">{pct}%</span>\n </div>\n )}\n </div>\n </div>\n );\n}\n\n/* ── Component ──────────────────────────────────────────────────────────── */\n\nexport const UploadFiles = forwardRef<HTMLDivElement, UploadFilesProps>(\n function UploadFiles(\n {\n files,\n title = 'Upload files',\n maxSizeLabel = 'MAX FILE SIZE: 20 MB',\n accept,\n multiple = true,\n theme = 'dark',\n statusWords = DEFAULT_STATUS_WORDS,\n actionLabel,\n onFilesSelected,\n onRemove,\n onRemoveAll,\n onClose,\n onAction,\n className = '',\n ...rest\n },\n ref,\n ) {\n const inputRef = useRef<HTMLInputElement>(null);\n const [isDragging, setDragging] = useState(false);\n const [tick, setTick] = useState(0);\n\n const anyUploading = files.some((f) => f.status === 'uploading');\n\n // Shuffle once per mount so the word order varies between sessions.\n const words = useMemo(\n () => (statusWords.length ? shuffle(statusWords) : DEFAULT_STATUS_WORDS),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [],\n );\n\n // Advance the shared cycle only while something is in flight.\n useEffect(() => {\n if (!anyUploading) return;\n const id = setInterval(() => setTick((t) => t + 1), 1900);\n return () => clearInterval(id);\n }, [anyUploading]);\n\n const emit = (list: FileList | null) => {\n if (!list || list.length === 0) return;\n onFilesSelected?.(Array.from(list));\n };\n\n const classes = cn(\n 'royui-upload',\n theme === 'dark' && 'royui-upload--dark',\n theme === 'light' && 'royui-upload--light',\n theme === 'auto' && 'royui-upload--auto',\n className,\n );\n\n return (\n <div ref={ref} className={classes} {...rest}>\n <header className=\"royui-upload__header\">\n <h2 className=\"royui-upload__title\">{title}</h2>\n {onClose && (\n <button\n type=\"button\"\n className=\"royui-upload__close\"\n aria-label=\"Close\"\n onClick={onClose}\n >\n <CloseGlyph />\n </button>\n )}\n </header>\n\n <div\n className={cn('royui-upload__dropzone', isDragging && 'is-dragging')}\n onDragOver={(e) => {\n e.preventDefault();\n setDragging(true);\n }}\n onDragLeave={(e) => {\n e.preventDefault();\n setDragging(false);\n }}\n onDrop={(e) => {\n e.preventDefault();\n setDragging(false);\n emit(e.dataTransfer.files);\n }}\n >\n <span className=\"royui-upload__drop-icon\" aria-hidden=\"true\">\n <UploadGlyph />\n </span>\n <p className=\"royui-upload__drop-text\">\n Drag and drop or{' '}\n <button\n type=\"button\"\n className=\"royui-upload__browse\"\n onClick={() => inputRef.current?.click()}\n >\n browse files\n </button>\n </p>\n <p className=\"royui-upload__drop-hint\">{maxSizeLabel}</p>\n <input\n ref={inputRef}\n type=\"file\"\n accept={accept}\n multiple={multiple}\n className=\"royui-upload__input\"\n onChange={(e) => {\n emit(e.target.files);\n e.target.value = '';\n }}\n />\n </div>\n\n {files.length > 0 && (\n <div className=\"royui-upload__list\">\n {files.map((file, i) => (\n <FileRow\n key={file.id}\n file={file}\n word={words[(tick + i) % words.length]!}\n onRemove={onRemove}\n />\n ))}\n </div>\n )}\n\n {files.length > 0 && (\n <footer className=\"royui-upload__footer\">\n <button\n type=\"button\"\n className=\"royui-upload__icon-btn\"\n aria-label=\"More options\"\n >\n <KebabGlyph />\n </button>\n <button\n type=\"button\"\n className=\"royui-upload__remove-all\"\n onClick={onRemoveAll}\n >\n <TrashGlyph />\n Remove all\n </button>\n <span className=\"royui-upload__footer-spacer\" />\n <Button\n size=\"sm\"\n variant=\"secondary\"\n className=\"royui-upload__action\"\n disabled={anyUploading}\n onClick={onAction}\n >\n {actionLabel ??\n (anyUploading ? (\n <TextMorph value=\"Uploading…\" />\n ) : (\n 'Done'\n ))}\n </Button>\n </footer>\n )}\n </div>\n );\n },\n);\n\nUploadFiles.displayName = 'UploadFiles';\n"]}
|