@better-s3/ui 3.1045.2 → 3.1046.0
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/components/delete/delete-button.d.ts +2 -1
- package/dist/components/download/download-button.d.ts +2 -1
- package/dist/components/download/progress-download-button.d.ts +2 -1
- package/dist/components/upload/upload-button.d.ts +2 -2
- package/dist/components/upload/upload-dropzone.d.ts +2 -2
- package/dist/components/upload/upload-status-block.d.ts +20 -0
- package/dist/hooks/use-upload-toast.d.ts +15 -2
- package/dist/index.js +179 -94
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { S3Api, DeleteHooks } from "@better-s3/react";
|
|
2
2
|
type DeleteButtonProps = DeleteHooks & {
|
|
3
|
-
|
|
3
|
+
/** S3Api client. Optional when an `<S3Provider>` is present in the tree. */
|
|
4
|
+
api?: S3Api;
|
|
4
5
|
objectKey: string;
|
|
5
6
|
fileName?: string;
|
|
6
7
|
fileSize?: number;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { S3Api, FetchDownloadHooks } from "@better-s3/react";
|
|
2
2
|
type ProgressDownloadButtonProps = FetchDownloadHooks & {
|
|
3
|
-
|
|
3
|
+
/** S3Api client. Optional when an `<S3Provider>` is present in the tree. */
|
|
4
|
+
api?: S3Api;
|
|
4
5
|
objectKey: string;
|
|
5
6
|
fileName?: string;
|
|
6
7
|
fileSize?: number;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type
|
|
2
|
-
export type UploadButtonProps = UseUploadControlsOptions & {
|
|
1
|
+
import { type UseUploadControlsOptions, type UseMultiUploadControlsOptions } from "@better-s3/react";
|
|
2
|
+
export type UploadButtonProps = (UseUploadControlsOptions | UseMultiUploadControlsOptions) & {
|
|
3
3
|
className?: string;
|
|
4
4
|
label?: string;
|
|
5
5
|
disabled?: boolean;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type
|
|
2
|
-
export type UploadDropzoneProps = UseUploadControlsOptions & {
|
|
1
|
+
import { type UseUploadControlsOptions, type UseMultiUploadControlsOptions } from "@better-s3/react";
|
|
2
|
+
export type UploadDropzoneProps = (UseUploadControlsOptions | UseMultiUploadControlsOptions) & {
|
|
3
3
|
className?: string;
|
|
4
4
|
label?: string;
|
|
5
5
|
disabled?: boolean;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { UploadPhase, UploadProgress, MultiUploadFileState, MultiUploadPhase } from "@better-s3/react";
|
|
2
|
+
export type UploadStatusBlockProps = {
|
|
3
|
+
mode: "single";
|
|
4
|
+
phase: UploadPhase;
|
|
5
|
+
progress: UploadProgress;
|
|
6
|
+
error: string | null;
|
|
7
|
+
fileInfo: {
|
|
8
|
+
name: string;
|
|
9
|
+
size: number;
|
|
10
|
+
} | null;
|
|
11
|
+
onCancel?: () => void;
|
|
12
|
+
} | {
|
|
13
|
+
mode: "multi";
|
|
14
|
+
phase: MultiUploadPhase;
|
|
15
|
+
files: MultiUploadFileState[];
|
|
16
|
+
totalProgress: UploadProgress;
|
|
17
|
+
error: string | null;
|
|
18
|
+
onCancel?: () => void;
|
|
19
|
+
};
|
|
20
|
+
export declare function UploadStatusBlock(props: UploadStatusBlockProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,6 +1,19 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { UploadProgress, MultiUploadFileState } from "@better-s3/react";
|
|
2
|
+
export type UploadToastCtrl = {
|
|
3
|
+
mode: "single" | "multi";
|
|
4
|
+
phase: string;
|
|
5
|
+
fileInfo?: {
|
|
6
|
+
name: string;
|
|
7
|
+
size: number;
|
|
8
|
+
} | null;
|
|
9
|
+
progress?: UploadProgress;
|
|
10
|
+
files?: MultiUploadFileState[];
|
|
11
|
+
totalProgress?: UploadProgress;
|
|
12
|
+
error: string | null;
|
|
13
|
+
cancel: () => void;
|
|
14
|
+
};
|
|
2
15
|
/**
|
|
3
16
|
* Drives sonner toasts for upload progress/success/error.
|
|
4
17
|
* Shared between UploadButton and UploadDropzone.
|
|
5
18
|
*/
|
|
6
|
-
export declare function useUploadToast(ctrl:
|
|
19
|
+
export declare function useUploadToast(ctrl: UploadToastCtrl, enabled: boolean): void;
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { XIcon, CheckCircleIcon, AlertCircleIcon, UploadIcon, LoaderIcon, DownloadIcon, Trash2Icon, CheckCircle2Icon } from 'lucide-react';
|
|
2
|
-
import { formatFileSize, useUploadControls, useDownload, useFetchDownload, useDelete } from '@better-s3/react';
|
|
2
|
+
import { formatEta, formatFileSize, formatSpeed, truncateFilename, useUploadControls, useMultiUploadControls, useDownload, useFetchDownload, useDelete } from '@better-s3/react';
|
|
3
3
|
import { clsx } from 'clsx';
|
|
4
4
|
import { twMerge } from 'tailwind-merge';
|
|
5
5
|
import { Button as Button$1 } from '@base-ui/react/button';
|
|
@@ -159,23 +159,24 @@ function UploadStatus({
|
|
|
159
159
|
}) {
|
|
160
160
|
if (phase === "idle") return null;
|
|
161
161
|
if (phase === "uploading" && fileInfo) {
|
|
162
|
-
|
|
162
|
+
const eta = progress.speed && progress.total ? formatEta(progress.total - progress.loaded, progress.speed) : null;
|
|
163
|
+
const meta = [
|
|
164
|
+
`${formatFileSize(progress.loaded)} / ${formatFileSize(fileInfo.size)}`,
|
|
165
|
+
progress.speed ? formatSpeed(progress.speed) : null,
|
|
166
|
+
eta ? `${eta} left` : null
|
|
167
|
+
].filter(Boolean).join(" \xB7 ");
|
|
168
|
+
const compactMeta = `${Math.round(progress.percent)}%`;
|
|
169
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex w-full items-center gap-2 text-xs", children: [
|
|
163
170
|
/* @__PURE__ */ jsx(CircleProgress, { percent: progress.percent, size: 14, strokeWidth: 2 }),
|
|
164
|
-
/* @__PURE__ */ jsx("span", { className: "
|
|
165
|
-
/* @__PURE__ */
|
|
166
|
-
|
|
167
|
-
" / ",
|
|
168
|
-
formatFileSize(fileInfo.size),
|
|
169
|
-
" (",
|
|
170
|
-
progress.percent,
|
|
171
|
-
"%)"
|
|
172
|
-
] }),
|
|
171
|
+
/* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate max-w-[30ch]", children: truncateFilename(fileInfo.name) }),
|
|
172
|
+
/* @__PURE__ */ jsx("span", { className: "ml-auto shrink-0 whitespace-nowrap tabular-nums text-muted-foreground sm:hidden", children: compactMeta }),
|
|
173
|
+
/* @__PURE__ */ jsx("span", { className: "ml-auto hidden shrink-0 whitespace-nowrap tabular-nums text-muted-foreground sm:inline", children: meta }),
|
|
173
174
|
/* @__PURE__ */ jsx(
|
|
174
175
|
Button,
|
|
175
176
|
{
|
|
176
177
|
variant: "ghost",
|
|
177
178
|
size: "icon",
|
|
178
|
-
className: "
|
|
179
|
+
className: "size-6 shrink-0",
|
|
179
180
|
onClick: (e) => {
|
|
180
181
|
e.stopPropagation();
|
|
181
182
|
onCancel?.();
|
|
@@ -186,10 +187,10 @@ function UploadStatus({
|
|
|
186
187
|
] });
|
|
187
188
|
}
|
|
188
189
|
if (phase === "success" && fileInfo) {
|
|
189
|
-
return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 text-xs", children: [
|
|
190
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex w-full items-center gap-1.5 text-xs", children: [
|
|
190
191
|
/* @__PURE__ */ jsx(CheckCircleIcon, { className: "size-3.5 shrink-0 text-green-600" }),
|
|
191
|
-
/* @__PURE__ */ jsx("span", { className: "
|
|
192
|
-
/* @__PURE__ */ jsx("span", { className: "shrink-0 text-muted-foreground", children: formatFileSize(fileInfo.size) })
|
|
192
|
+
/* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate max-w-[30ch]", children: truncateFilename(fileInfo.name) }),
|
|
193
|
+
/* @__PURE__ */ jsx("span", { className: "ml-auto shrink-0 text-muted-foreground", children: formatFileSize(fileInfo.size) })
|
|
193
194
|
] });
|
|
194
195
|
}
|
|
195
196
|
if (phase === "error") {
|
|
@@ -343,7 +344,7 @@ function FileList({ files }) {
|
|
|
343
344
|
strokeWidth: 2
|
|
344
345
|
}
|
|
345
346
|
),
|
|
346
|
-
/* @__PURE__ */ jsx("span", { className: "
|
|
347
|
+
/* @__PURE__ */ jsx("span", { className: "min-w-0 shrink", children: truncateFilename(f.fileName) }),
|
|
347
348
|
f.status === "uploading" ? /* @__PURE__ */ jsxs("span", { className: "shrink-0 text-muted-foreground", children: [
|
|
348
349
|
formatFileSize(f.progress.loaded),
|
|
349
350
|
" /",
|
|
@@ -357,9 +358,40 @@ function FileList({ files }) {
|
|
|
357
358
|
f.status === "error" && f.error && /* @__PURE__ */ jsx("span", { className: "truncate [overflow-wrap:anywhere] pl-5 text-destructive", children: f.error })
|
|
358
359
|
] }, f.id)) });
|
|
359
360
|
}
|
|
361
|
+
function UploadStatusBlock(props) {
|
|
362
|
+
if (props.mode === "multi") {
|
|
363
|
+
return /* @__PURE__ */ jsx(
|
|
364
|
+
MultiUploadStatus,
|
|
365
|
+
{
|
|
366
|
+
phase: props.phase,
|
|
367
|
+
files: props.files,
|
|
368
|
+
totalProgress: props.totalProgress,
|
|
369
|
+
error: props.error,
|
|
370
|
+
onCancel: props.onCancel
|
|
371
|
+
}
|
|
372
|
+
);
|
|
373
|
+
}
|
|
374
|
+
return /* @__PURE__ */ jsx(
|
|
375
|
+
UploadStatus,
|
|
376
|
+
{
|
|
377
|
+
phase: props.phase,
|
|
378
|
+
progress: props.progress,
|
|
379
|
+
error: props.error,
|
|
380
|
+
fileInfo: props.fileInfo,
|
|
381
|
+
onCancel: props.onCancel
|
|
382
|
+
}
|
|
383
|
+
);
|
|
384
|
+
}
|
|
360
385
|
function useUploadToast(ctrl, enabled) {
|
|
361
386
|
const toastIdRef = useRef(null);
|
|
362
387
|
const isMulti = ctrl.mode === "multi";
|
|
388
|
+
const files = ctrl.files ?? [];
|
|
389
|
+
const totalProgress = ctrl.totalProgress ?? {
|
|
390
|
+
loaded: 0,
|
|
391
|
+
total: 0,
|
|
392
|
+
percent: 0
|
|
393
|
+
};
|
|
394
|
+
const progress = ctrl.progress ?? { loaded: 0, percent: 0 };
|
|
363
395
|
const prevPhaseRef = useRef(ctrl.phase);
|
|
364
396
|
if (prevPhaseRef.current !== ctrl.phase) {
|
|
365
397
|
prevPhaseRef.current = ctrl.phase;
|
|
@@ -371,8 +403,8 @@ function useUploadToast(ctrl, enabled) {
|
|
|
371
403
|
if (ctrl.phase === "success") {
|
|
372
404
|
if (toastIdRef.current) toast.dismiss(toastIdRef.current);
|
|
373
405
|
if (isMulti) {
|
|
374
|
-
toast.success(`${
|
|
375
|
-
description: formatFileSize(
|
|
406
|
+
toast.success(`${files.length} file(s) uploaded`, {
|
|
407
|
+
description: formatFileSize(totalProgress.total)
|
|
376
408
|
});
|
|
377
409
|
} else if (ctrl.fileInfo) {
|
|
378
410
|
toast.success("Upload complete", {
|
|
@@ -383,11 +415,9 @@ function useUploadToast(ctrl, enabled) {
|
|
|
383
415
|
}
|
|
384
416
|
if (ctrl.phase === "error") {
|
|
385
417
|
if (toastIdRef.current) toast.dismiss(toastIdRef.current);
|
|
386
|
-
if (isMulti &&
|
|
387
|
-
const succeeded =
|
|
388
|
-
|
|
389
|
-
).length;
|
|
390
|
-
const failed = ctrl.files.filter((f) => f.status === "error").length;
|
|
418
|
+
if (isMulti && files.length > 0) {
|
|
419
|
+
const succeeded = files.filter((f) => f.status === "success").length;
|
|
420
|
+
const failed = files.filter((f) => f.status === "error").length;
|
|
391
421
|
toast.error("Upload finished with errors", {
|
|
392
422
|
description: `${succeeded} succeeded, ${failed} failed`
|
|
393
423
|
});
|
|
@@ -405,16 +435,16 @@ function useUploadToast(ctrl, enabled) {
|
|
|
405
435
|
const id = toastIdRef.current ?? `upload-${Date.now()}`;
|
|
406
436
|
toastIdRef.current = id;
|
|
407
437
|
if (isMulti) {
|
|
408
|
-
const done =
|
|
409
|
-
toast.loading(`Uploading... ${done}/${
|
|
438
|
+
const done = files.filter((f) => f.status === "success").length;
|
|
439
|
+
toast.loading(`Uploading... ${done}/${files.length}`, {
|
|
410
440
|
id,
|
|
411
|
-
description: `${formatFileSize(
|
|
441
|
+
description: `${formatFileSize(totalProgress.loaded)} / ${formatFileSize(totalProgress.total)} (${totalProgress.percent}%)`,
|
|
412
442
|
cancel: { label: "Cancel", onClick: () => ctrl.cancel() }
|
|
413
443
|
});
|
|
414
444
|
} else if (ctrl.fileInfo) {
|
|
415
445
|
toast.loading("Uploading...", {
|
|
416
446
|
id,
|
|
417
|
-
description: `${formatFileSize(
|
|
447
|
+
description: `${formatFileSize(progress.loaded)} / ${formatFileSize(ctrl.fileInfo.size)} (${progress.percent}%)`,
|
|
418
448
|
cancel: { label: "Cancel", onClick: () => ctrl.cancel() }
|
|
419
449
|
});
|
|
420
450
|
}
|
|
@@ -422,16 +452,18 @@ function useUploadToast(ctrl, enabled) {
|
|
|
422
452
|
enabled,
|
|
423
453
|
ctrl.phase,
|
|
424
454
|
isMulti,
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
455
|
+
progress.loaded,
|
|
456
|
+
progress.percent,
|
|
457
|
+
totalProgress.loaded,
|
|
458
|
+
totalProgress.total,
|
|
459
|
+
totalProgress.percent,
|
|
430
460
|
ctrl.fileInfo,
|
|
431
|
-
|
|
461
|
+
files,
|
|
432
462
|
ctrl.cancel
|
|
433
463
|
]);
|
|
434
464
|
}
|
|
465
|
+
var EMPTY_PROGRESS = { loaded: 0, total: 0, percent: 0 };
|
|
466
|
+
var EMPTY_FILES = [];
|
|
435
467
|
function UploadButton({
|
|
436
468
|
className,
|
|
437
469
|
label,
|
|
@@ -441,56 +473,69 @@ function UploadButton({
|
|
|
441
473
|
showStatus = true,
|
|
442
474
|
...options
|
|
443
475
|
}) {
|
|
444
|
-
const
|
|
445
|
-
const
|
|
446
|
-
const
|
|
476
|
+
const isMulti = (options.maxFiles ?? 1) > 1;
|
|
477
|
+
const single = useUploadControls(options);
|
|
478
|
+
const multi = useMultiUploadControls(
|
|
479
|
+
options
|
|
480
|
+
);
|
|
481
|
+
const ctrl = isMulti ? {
|
|
482
|
+
mode: "multi",
|
|
483
|
+
phase: multi.phase,
|
|
484
|
+
files: multi.files,
|
|
485
|
+
totalProgress: multi.totalProgress,
|
|
486
|
+
error: multi.error,
|
|
487
|
+
cancel: multi.cancel
|
|
488
|
+
} : {
|
|
489
|
+
mode: "single",
|
|
490
|
+
phase: single.phase,
|
|
491
|
+
fileInfo: single.fileInfo,
|
|
492
|
+
progress: single.progress,
|
|
493
|
+
error: single.error,
|
|
494
|
+
cancel: single.cancel
|
|
495
|
+
};
|
|
496
|
+
const isDisabled = disabled || (isMulti ? multi.isUploading : single.isUploading);
|
|
447
497
|
useUploadToast(ctrl, enableToast);
|
|
448
498
|
const status = showStatus ? isMulti ? /* @__PURE__ */ jsx(
|
|
449
|
-
|
|
499
|
+
UploadStatusBlock,
|
|
450
500
|
{
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
501
|
+
mode: "multi",
|
|
502
|
+
phase: multi.phase,
|
|
503
|
+
files: multi.files ?? EMPTY_FILES,
|
|
504
|
+
totalProgress: multi.totalProgress ?? EMPTY_PROGRESS,
|
|
505
|
+
error: multi.error,
|
|
506
|
+
onCancel: multi.cancel
|
|
456
507
|
}
|
|
457
508
|
) : /* @__PURE__ */ jsx(
|
|
458
|
-
|
|
509
|
+
UploadStatusBlock,
|
|
459
510
|
{
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
511
|
+
mode: "single",
|
|
512
|
+
phase: single.phase,
|
|
513
|
+
progress: single.progress,
|
|
514
|
+
error: single.error,
|
|
515
|
+
fileInfo: single.fileInfo,
|
|
516
|
+
onCancel: single.cancel
|
|
465
517
|
}
|
|
466
518
|
) : null;
|
|
519
|
+
const openFilePicker = isMulti ? multi.openFilePicker : single.openFilePicker;
|
|
520
|
+
const inputProps = isMulti ? multi.inputProps : single.inputProps;
|
|
521
|
+
const buttonLabel = label ?? (isMulti ? "Upload files" : "Upload file");
|
|
522
|
+
const button = /* @__PURE__ */ jsxs(Button, { size: "default", disabled: isDisabled, onClick: openFilePicker, children: [
|
|
523
|
+
/* @__PURE__ */ jsx(UploadIcon, { "data-icon": "inline-start" }),
|
|
524
|
+
buttonLabel
|
|
525
|
+
] });
|
|
467
526
|
return /* @__PURE__ */ jsxs("div", { className: cn("inline-flex flex-col gap-2", className), children: [
|
|
468
527
|
/* @__PURE__ */ jsxs("div", { className: "inline-flex items-center gap-2", children: [
|
|
469
|
-
/* @__PURE__ */ jsx("input", { ...
|
|
470
|
-
/* @__PURE__ */ jsx(TooltipProvider, { children: /* @__PURE__ */ jsxs(Tooltip, { children: [
|
|
471
|
-
/* @__PURE__ */
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
render: /* @__PURE__ */ jsx(
|
|
475
|
-
Button,
|
|
476
|
-
{
|
|
477
|
-
size: "default",
|
|
478
|
-
disabled: isDisabled,
|
|
479
|
-
onClick: ctrl.openFilePicker
|
|
480
|
-
}
|
|
481
|
-
),
|
|
482
|
-
children: [
|
|
483
|
-
/* @__PURE__ */ jsx(UploadIcon, { "data-icon": "inline-start" }),
|
|
484
|
-
label ?? (isMulti ? "Upload files" : "Upload file")
|
|
485
|
-
]
|
|
486
|
-
}
|
|
487
|
-
),
|
|
488
|
-
/* @__PURE__ */ jsx(TooltipContent, { children: tooltipText ?? (isMulti ? "Upload files" : "Upload file") })
|
|
489
|
-
] }) })
|
|
528
|
+
/* @__PURE__ */ jsx("input", { ...inputProps }),
|
|
529
|
+
tooltipText ? /* @__PURE__ */ jsx(TooltipProvider, { children: /* @__PURE__ */ jsxs(Tooltip, { children: [
|
|
530
|
+
/* @__PURE__ */ jsx(TooltipTrigger, { render: button }),
|
|
531
|
+
/* @__PURE__ */ jsx(TooltipContent, { children: tooltipText })
|
|
532
|
+
] }) }) : button
|
|
490
533
|
] }),
|
|
491
534
|
status
|
|
492
535
|
] });
|
|
493
536
|
}
|
|
537
|
+
var EMPTY_PROGRESS2 = { loaded: 0, total: 0, percent: 0 };
|
|
538
|
+
var EMPTY_FILES2 = [];
|
|
494
539
|
function UploadDropzone({
|
|
495
540
|
className,
|
|
496
541
|
label,
|
|
@@ -499,27 +544,50 @@ function UploadDropzone({
|
|
|
499
544
|
showStatus = true,
|
|
500
545
|
...options
|
|
501
546
|
}) {
|
|
502
|
-
const
|
|
503
|
-
const
|
|
504
|
-
const
|
|
547
|
+
const isMulti = (options.maxFiles ?? 1) > 1;
|
|
548
|
+
const single = useUploadControls(options);
|
|
549
|
+
const multi = useMultiUploadControls(
|
|
550
|
+
options
|
|
551
|
+
);
|
|
552
|
+
const ctrl = isMulti ? {
|
|
553
|
+
mode: "multi",
|
|
554
|
+
phase: multi.phase,
|
|
555
|
+
files: multi.files,
|
|
556
|
+
totalProgress: multi.totalProgress,
|
|
557
|
+
error: multi.error,
|
|
558
|
+
cancel: multi.cancel
|
|
559
|
+
} : {
|
|
560
|
+
mode: "single",
|
|
561
|
+
phase: single.phase,
|
|
562
|
+
fileInfo: single.fileInfo,
|
|
563
|
+
progress: single.progress,
|
|
564
|
+
error: single.error,
|
|
565
|
+
cancel: single.cancel
|
|
566
|
+
};
|
|
567
|
+
const isDisabled = disabled || (isMulti ? multi.isUploading : single.isUploading);
|
|
568
|
+
const openFilePicker = isMulti ? multi.openFilePicker : single.openFilePicker;
|
|
569
|
+
const dropHandlers = isMulti ? multi.dropHandlers : single.dropHandlers;
|
|
570
|
+
const inputProps = isMulti ? multi.inputProps : single.inputProps;
|
|
505
571
|
useUploadToast(ctrl, enableToast);
|
|
506
572
|
const status = showStatus ? isMulti ? /* @__PURE__ */ jsx(
|
|
507
|
-
|
|
573
|
+
UploadStatusBlock,
|
|
508
574
|
{
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
575
|
+
mode: "multi",
|
|
576
|
+
phase: multi.phase,
|
|
577
|
+
files: multi.files ?? EMPTY_FILES2,
|
|
578
|
+
totalProgress: multi.totalProgress ?? EMPTY_PROGRESS2,
|
|
579
|
+
error: multi.error,
|
|
580
|
+
onCancel: multi.cancel
|
|
514
581
|
}
|
|
515
582
|
) : /* @__PURE__ */ jsx(
|
|
516
|
-
|
|
583
|
+
UploadStatusBlock,
|
|
517
584
|
{
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
585
|
+
mode: "single",
|
|
586
|
+
phase: single.phase,
|
|
587
|
+
progress: single.progress,
|
|
588
|
+
error: single.error,
|
|
589
|
+
fileInfo: single.fileInfo,
|
|
590
|
+
onCancel: single.cancel
|
|
523
591
|
}
|
|
524
592
|
) : null;
|
|
525
593
|
return /* @__PURE__ */ jsxs(
|
|
@@ -530,10 +598,10 @@ function UploadDropzone({
|
|
|
530
598
|
isDisabled ? "cursor-not-allowed border-muted-foreground/25" : "cursor-pointer border-muted-foreground/25 hover:border-primary/50",
|
|
531
599
|
className
|
|
532
600
|
),
|
|
533
|
-
onClick: isDisabled ? void 0 :
|
|
534
|
-
...isDisabled ? {} :
|
|
601
|
+
onClick: isDisabled ? void 0 : openFilePicker,
|
|
602
|
+
...isDisabled ? {} : dropHandlers,
|
|
535
603
|
children: [
|
|
536
|
-
/* @__PURE__ */ jsx("input", { ...
|
|
604
|
+
/* @__PURE__ */ jsx("input", { ...inputProps }),
|
|
537
605
|
/* @__PURE__ */ jsx(
|
|
538
606
|
UploadIcon,
|
|
539
607
|
{
|
|
@@ -573,8 +641,8 @@ function useDownloadToast({
|
|
|
573
641
|
if (!enabled) return;
|
|
574
642
|
toast.dismiss(`dl-${objectKey}`);
|
|
575
643
|
toast.success("Download complete", {
|
|
576
|
-
description: /* @__PURE__ */ jsxs("span", { className: "block
|
|
577
|
-
actualFileName,
|
|
644
|
+
description: /* @__PURE__ */ jsxs("span", { className: "block", children: [
|
|
645
|
+
truncateFilename(actualFileName),
|
|
578
646
|
fileSize != null ? ` \xB7 ${formatFileSize(fileSize)}` : ""
|
|
579
647
|
] })
|
|
580
648
|
});
|
|
@@ -593,7 +661,7 @@ function useDownloadToast({
|
|
|
593
661
|
if (!enabled) return;
|
|
594
662
|
toast.dismiss(`dl-${objectKey}`);
|
|
595
663
|
toast.info("Download cancelled", {
|
|
596
|
-
description: /* @__PURE__ */ jsx("span", {
|
|
664
|
+
description: /* @__PURE__ */ jsx("span", { children: truncateFilename(displayName) })
|
|
597
665
|
});
|
|
598
666
|
};
|
|
599
667
|
return { onInitiated, onSuccess, onError, onErrorWithPhase, onCancel };
|
|
@@ -689,6 +757,7 @@ function ProgressDownloadButton({
|
|
|
689
757
|
}
|
|
690
758
|
});
|
|
691
759
|
const isDownloading = dl.phase === "downloading" || dl.phase === "presigning";
|
|
760
|
+
const eta = dl.phase === "downloading" && dl.progress.speed && dl.progress.total ? formatEta(dl.progress.total - dl.progress.loaded, dl.progress.speed) : null;
|
|
692
761
|
const handleClick = () => {
|
|
693
762
|
if (isDownloading) {
|
|
694
763
|
dl.cancel();
|
|
@@ -731,6 +800,22 @@ function ProgressDownloadButton({
|
|
|
731
800
|
),
|
|
732
801
|
/* @__PURE__ */ jsx(TooltipContent, { children: isDownloading ? "Cancel download" : tooltipText })
|
|
733
802
|
] }) }),
|
|
803
|
+
showStatus && dl.phase === "downloading" && dl.progress.loaded > 0 && /* @__PURE__ */ jsxs("p", { className: "text-xs tabular-nums text-muted-foreground", children: [
|
|
804
|
+
formatFileSize(dl.progress.loaded),
|
|
805
|
+
dl.progress.total > 0 && /* @__PURE__ */ jsxs("span", { className: "text-muted-foreground/50", children: [
|
|
806
|
+
" ",
|
|
807
|
+
"/ ",
|
|
808
|
+
formatFileSize(dl.progress.total)
|
|
809
|
+
] }),
|
|
810
|
+
dl.progress.speed ? /* @__PURE__ */ jsxs("span", { children: [
|
|
811
|
+
" \xB7 ",
|
|
812
|
+
formatSpeed(dl.progress.speed)
|
|
813
|
+
] }) : null,
|
|
814
|
+
eta ? /* @__PURE__ */ jsxs("span", { className: "text-muted-foreground/50", children: [
|
|
815
|
+
" \xB7 in ",
|
|
816
|
+
eta
|
|
817
|
+
] }) : null
|
|
818
|
+
] }),
|
|
734
819
|
showStatus && dl.phase === "error" && /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 items-start gap-1.5 text-xs", children: [
|
|
735
820
|
/* @__PURE__ */ jsx(AlertCircleIcon, { className: "mt-0.5 size-3.5 shrink-0 text-destructive" }),
|
|
736
821
|
/* @__PURE__ */ jsx("p", { className: "min-w-0 [overflow-wrap:anywhere] text-destructive", children: dl.error ?? "Download failed" })
|
|
@@ -899,7 +984,7 @@ function useDeleteToast({
|
|
|
899
984
|
const onSuccess = (_key) => {
|
|
900
985
|
if (!enabled) return;
|
|
901
986
|
toast.success("File deleted", {
|
|
902
|
-
description: /* @__PURE__ */ jsx("span", {
|
|
987
|
+
description: /* @__PURE__ */ jsx("span", { children: truncateFilename(displayName) })
|
|
903
988
|
});
|
|
904
989
|
};
|
|
905
990
|
const onError = (_key, error) => {
|
|
@@ -952,9 +1037,9 @@ function DeleteButton({
|
|
|
952
1037
|
const isDisabled = disabled || isDeleting;
|
|
953
1038
|
const description = confirmDescription ?? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
954
1039
|
"Are you sure you want to delete ",
|
|
955
|
-
/* @__PURE__ */ jsxs("span", { className: "inline-block
|
|
1040
|
+
/* @__PURE__ */ jsxs("span", { className: "font-medium inline-block align-bottom", children: [
|
|
956
1041
|
"\u201C",
|
|
957
|
-
displayName,
|
|
1042
|
+
truncateFilename(displayName),
|
|
958
1043
|
"\u201D"
|
|
959
1044
|
] }),
|
|
960
1045
|
fileSize != null ? ` (${formatFileSize(fileSize)})` : "",
|
|
@@ -1027,7 +1112,7 @@ function DeleteButton({
|
|
|
1027
1112
|
/* @__PURE__ */ jsx(CheckCircle2Icon, { className: "size-3.5 shrink-0 text-green-600" }),
|
|
1028
1113
|
/* @__PURE__ */ jsxs("p", { className: "min-w-0 [overflow-wrap:anywhere] text-green-600", children: [
|
|
1029
1114
|
"\u201C",
|
|
1030
|
-
|
|
1115
|
+
truncateFilename(displayName),
|
|
1031
1116
|
"\u201D deleted"
|
|
1032
1117
|
] })
|
|
1033
1118
|
] }),
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/lib/utils.ts","../src/components/ui/button.tsx","../src/components/ui/tooltip.tsx","../src/components/ui/circle-progress.tsx","../src/components/upload/upload-status.tsx","../src/components/ui/progress.tsx","../src/components/upload/multi-upload-status.tsx","../src/hooks/use-upload-toast.tsx","../src/components/upload/upload-button.tsx","../src/components/upload/upload-dropzone.tsx","../src/hooks/use-download-toast.tsx","../src/components/download/download-button.tsx","../src/components/download/progress-download-button.tsx","../src/components/ui/alert-dialog.tsx","../src/hooks/use-delete-toast.tsx","../src/components/delete/delete-button.tsx"],"names":["ButtonPrimitive","jsx","TooltipPrimitive","jsxs","ProgressPrimitive","XIcon","CheckCircleIcon","AlertCircleIcon","formatFileSize","useUploadControls","UploadIcon","toast","DownloadIcon","AlertDialogPrimitive","LoaderIcon"],"mappings":"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","file":"index.js","sourcesContent":["import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs))\n}\n","\"use client\";\n\nimport { Button as ButtonPrimitive } from \"@base-ui/react/button\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\n\nimport { cn } from \"@/lib/utils\";\n\nconst buttonVariants = cva(\n \"group/button cursor-pointer inline-flex shrink-0 items-center justify-center rounded-md border border-transparent bg-clip-padding text-xs/relaxed font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-2 focus-visible:ring-ring/30 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-2 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n {\n variants: {\n variant: {\n default: \"bg-primary text-primary-foreground hover:bg-primary/80\",\n outline:\n \"border-border hover:bg-input/50 hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:bg-input/30\",\n secondary:\n \"bg-secondary text-secondary-foreground hover:bg-secondary/80 aria-expanded:bg-secondary aria-expanded:text-secondary-foreground\",\n ghost:\n \"hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:hover:bg-muted/50\",\n destructive:\n \"bg-destructive/10 text-destructive hover:bg-destructive/20 focus-visible:border-destructive/40 focus-visible:ring-destructive/20 dark:bg-destructive/20 dark:hover:bg-destructive/30 dark:focus-visible:ring-destructive/40\",\n link: \"text-primary underline-offset-4 hover:underline\",\n },\n size: {\n default:\n \"h-7 gap-1 px-2 text-xs/relaxed has-data-[icon=inline-end]:pe-1.5 has-data-[icon=inline-start]:ps-1.5 [&_svg:not([class*='size-'])]:size-3.5\",\n xs: \"h-5 gap-1 rounded-sm px-2 text-[0.625rem] has-data-[icon=inline-end]:pe-1.5 has-data-[icon=inline-start]:ps-1.5 [&_svg:not([class*='size-'])]:size-2.5\",\n sm: \"h-6 gap-1 px-2 text-xs/relaxed has-data-[icon=inline-end]:pe-1.5 has-data-[icon=inline-start]:ps-1.5 [&_svg:not([class*='size-'])]:size-3\",\n lg: \"h-8 gap-1 px-2.5 text-xs/relaxed has-data-[icon=inline-end]:pe-2 has-data-[icon=inline-start]:ps-2 [&_svg:not([class*='size-'])]:size-4\",\n icon: \"size-7 [&_svg:not([class*='size-'])]:size-3.5\",\n \"icon-xs\": \"size-5 rounded-sm [&_svg:not([class*='size-'])]:size-2.5\",\n \"icon-sm\": \"size-6 [&_svg:not([class*='size-'])]:size-3\",\n \"icon-lg\": \"size-8 [&_svg:not([class*='size-'])]:size-4\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n },\n);\n\nfunction Button({\n className,\n variant = \"default\",\n size = \"default\",\n ...props\n}: ButtonPrimitive.Props & VariantProps<typeof buttonVariants>) {\n return (\n <ButtonPrimitive\n data-slot=\"button\"\n className={cn(buttonVariants({ variant, size, className }))}\n {...props}\n />\n );\n}\n\nexport { Button, buttonVariants };\n","\"use client\";\n\nimport { Tooltip as TooltipPrimitive } from \"@base-ui/react/tooltip\";\n\nimport { cn } from \"@/lib/utils\";\n\nfunction TooltipProvider({\n delay = 0,\n ...props\n}: TooltipPrimitive.Provider.Props) {\n return (\n <TooltipPrimitive.Provider\n data-slot=\"tooltip-provider\"\n delay={delay}\n {...props}\n />\n );\n}\n\nfunction Tooltip({ ...props }: TooltipPrimitive.Root.Props) {\n return <TooltipPrimitive.Root data-slot=\"tooltip\" {...props} />;\n}\n\nfunction TooltipTrigger({ ...props }: TooltipPrimitive.Trigger.Props) {\n return <TooltipPrimitive.Trigger data-slot=\"tooltip-trigger\" {...props} />;\n}\n\nfunction TooltipContent({\n className,\n side = \"top\",\n sideOffset = 4,\n align = \"center\",\n alignOffset = 0,\n children,\n ...props\n}: TooltipPrimitive.Popup.Props &\n Pick<\n TooltipPrimitive.Positioner.Props,\n \"align\" | \"alignOffset\" | \"side\" | \"sideOffset\"\n >) {\n return (\n <TooltipPrimitive.Portal>\n <TooltipPrimitive.Positioner\n align={align}\n alignOffset={alignOffset}\n side={side}\n sideOffset={sideOffset}\n className=\"isolate z-50\">\n <TooltipPrimitive.Popup\n data-slot=\"tooltip-content\"\n className={cn(\n \"z-50 inline-flex w-fit max-w-xs origin-(--transform-origin) items-center gap-1.5 rounded-md bg-foreground px-3 py-1.5 text-xs text-background has-data-[slot=kbd]:pe-1.5 data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-start-2 data-[side=inline-start]:slide-in-from-end-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 **:data-[slot=kbd]:relative **:data-[slot=kbd]:isolate **:data-[slot=kbd]:z-50 **:data-[slot=kbd]:rounded-sm data-[state=delayed-open]:animate-in data-[state=delayed-open]:fade-in-0 data-[state=delayed-open]:zoom-in-95 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95\",\n className,\n )}\n {...props}>\n {children}\n <TooltipPrimitive.Arrow className=\"z-50 size-2.5 translate-y-[calc(-50%-2px)] rotate-45 rounded-[2px] bg-foreground fill-foreground data-[side=bottom]:top-1 data-[side=inline-end]:top-1/2! data-[side=inline-end]:-start-1 data-[side=inline-end]:-translate-y-1/2 data-[side=inline-start]:top-1/2! data-[side=inline-start]:-end-1 data-[side=inline-start]:-translate-y-1/2 data-[side=left]:top-1/2! data-[side=left]:-right-1 data-[side=left]:-translate-y-1/2 data-[side=right]:top-1/2! data-[side=right]:-left-1 data-[side=right]:-translate-y-1/2 data-[side=top]:-bottom-2.5\" />\n </TooltipPrimitive.Popup>\n </TooltipPrimitive.Positioner>\n </TooltipPrimitive.Portal>\n );\n}\n\nexport { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider };\n","\"use client\"\n\nexport function CircleProgress({\n percent,\n size = 20,\n strokeWidth = 2.5,\n}: {\n percent: number\n size?: number\n strokeWidth?: number\n}) {\n const r = (size - strokeWidth) / 2\n const c = 2 * Math.PI * r\n const offset = c - (percent / 100) * c\n return (\n <svg width={size} height={size} className=\"shrink-0 -rotate-90\">\n <circle\n cx={size / 2}\n cy={size / 2}\n r={r}\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={strokeWidth}\n className=\"text-muted-foreground/20\"\n />\n <circle\n cx={size / 2}\n cy={size / 2}\n r={r}\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={strokeWidth}\n strokeDasharray={c}\n strokeDashoffset={offset}\n strokeLinecap=\"round\"\n className=\"text-primary transition-[stroke-dashoffset] duration-200\"\n />\n </svg>\n )\n}\n","\"use client\";\n\nimport { XIcon, CheckCircleIcon, AlertCircleIcon } from \"lucide-react\";\nimport { formatFileSize } from \"@better-s3/react\";\nimport type { UploadPhase, UploadProgress } from \"@better-s3/react\";\nimport { Button } from \"@/components/ui/button\";\nimport { CircleProgress } from \"@/components/ui/circle-progress\";\n\nexport function UploadStatus({\n phase,\n progress,\n error,\n fileInfo,\n onCancel,\n}: {\n phase: UploadPhase;\n progress: UploadProgress;\n error: string | null;\n fileInfo: { name: string; size: number } | null;\n onCancel?: () => void;\n}) {\n if (phase === \"idle\") return null;\n\n if (phase === \"uploading\" && fileInfo) {\n return (\n <div className=\"flex w-full items-center gap-1.5 text-xs\">\n <CircleProgress percent={progress.percent} size={14} strokeWidth={2} />\n <span className=\"max-w-32 min-w-16 truncate sm:max-w-48\">\n {fileInfo.name}\n </span>\n <span className=\"shrink-0 text-muted-foreground\">\n {formatFileSize(progress.loaded)} / {formatFileSize(fileInfo.size)} (\n {progress.percent}%)\n </span>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"ml-auto size-6 shrink-0\"\n onClick={(e) => {\n e.stopPropagation();\n onCancel?.();\n }}>\n <XIcon className=\"size-3.5\" />\n </Button>\n </div>\n );\n }\n\n if (phase === \"success\" && fileInfo) {\n return (\n <div className=\"flex items-center gap-1.5 text-xs\">\n <CheckCircleIcon className=\"size-3.5 shrink-0 text-green-600\" />\n <span className=\"[overflow-wrap:anywhere] max-w-32 min-w-16 truncate sm:max-w-48\">\n {fileInfo.name}\n </span>\n <span className=\"shrink-0 text-muted-foreground\">\n {formatFileSize(fileInfo.size)}\n </span>\n </div>\n );\n }\n\n if (phase === \"error\") {\n return (\n <div className=\"flex min-w-0 items-start gap-1.5 text-xs\">\n <AlertCircleIcon className=\"mt-0.5 size-3.5 shrink-0 text-destructive\" />\n <p className=\"min-w-0 [overflow-wrap:anywhere] text-destructive\">\n {error ?? \"Upload failed\"}\n </p>\n </div>\n );\n }\n\n if (phase === \"validating\" || phase === \"presigning\") {\n return <span className=\"text-xs text-muted-foreground\">Preparing…</span>;\n }\n\n return null;\n}\n","\"use client\";\n\nimport { Progress as ProgressPrimitive } from \"@base-ui/react/progress\";\n\nimport { cn } from \"@/lib/utils\";\n\nfunction Progress({\n className,\n children,\n value,\n ...props\n}: ProgressPrimitive.Root.Props) {\n return (\n <ProgressPrimitive.Root\n value={value}\n data-slot=\"progress\"\n className={cn(\"flex flex-wrap gap-3\", className)}\n {...props}>\n {children}\n <ProgressTrack>\n <ProgressIndicator />\n </ProgressTrack>\n </ProgressPrimitive.Root>\n );\n}\n\nfunction ProgressTrack({ className, ...props }: ProgressPrimitive.Track.Props) {\n return (\n <ProgressPrimitive.Track\n className={cn(\n \"relative flex h-1 w-full items-center overflow-x-hidden rounded-md bg-muted\",\n className,\n )}\n data-slot=\"progress-track\"\n {...props}\n />\n );\n}\n\nfunction ProgressIndicator({\n className,\n ...props\n}: ProgressPrimitive.Indicator.Props) {\n return (\n <ProgressPrimitive.Indicator\n data-slot=\"progress-indicator\"\n className={cn(\"h-full bg-primary transition-all\", className)}\n {...props}\n />\n );\n}\n\nfunction ProgressLabel({ className, ...props }: ProgressPrimitive.Label.Props) {\n return (\n <ProgressPrimitive.Label\n className={cn(\"text-xs/relaxed font-medium\", className)}\n data-slot=\"progress-label\"\n {...props}\n />\n );\n}\n\nfunction ProgressValue({ className, ...props }: ProgressPrimitive.Value.Props) {\n return (\n <ProgressPrimitive.Value\n className={cn(\n \"ms-auto text-xs/relaxed text-muted-foreground tabular-nums\",\n className,\n )}\n data-slot=\"progress-value\"\n {...props}\n />\n );\n}\n\nexport {\n Progress,\n ProgressTrack,\n ProgressIndicator,\n ProgressLabel,\n ProgressValue,\n};\n","\"use client\";\n\nimport { XIcon, CheckCircleIcon, AlertCircleIcon } from \"lucide-react\";\nimport { formatFileSize } from \"@better-s3/react\";\nimport type { UploadProgress, MultiUploadFileState } from \"@better-s3/react\";\nimport { Button } from \"@/components/ui/button\";\nimport {\n Progress,\n ProgressLabel,\n ProgressValue,\n} from \"@/components/ui/progress\";\nimport { CircleProgress } from \"@/components/ui/circle-progress\";\n\nexport function MultiUploadStatus({\n phase,\n files,\n totalProgress,\n error,\n onCancel,\n}: {\n phase: string;\n files: MultiUploadFileState[];\n totalProgress: UploadProgress;\n error: string | null;\n onCancel?: () => void;\n}) {\n if (phase === \"idle\") return null;\n\n if (phase === \"uploading\") {\n return (\n <div className=\"flex w-full flex-col gap-2\">\n <div className=\"flex w-full items-center gap-1.5\">\n <Progress value={totalProgress.percent} className=\"flex-1\">\n <ProgressLabel>\n {files.filter((f) => f.status === \"success\").length}/\n {files.length} files\n </ProgressLabel>\n <ProgressValue />\n </Progress>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"size-7 shrink-0\"\n onClick={(e) => {\n e.stopPropagation();\n onCancel?.();\n }}>\n <XIcon className=\"size-4\" />\n </Button>\n </div>\n <FileList files={files} />\n </div>\n );\n }\n\n if (phase === \"success\") {\n return (\n <div className=\"flex w-full flex-col gap-1\">\n <span className=\"text-xs text-green-600\">\n All {files.length} file(s) uploaded\n </span>\n <FileList files={files} />\n </div>\n );\n }\n\n if (phase === \"error\") {\n return (\n <div className=\"flex w-full flex-col gap-1\">\n <span className=\"text-xs text-destructive\">\n {error ?? \"Upload failed\"}\n </span>\n {files.length > 0 && <FileList files={files} />}\n </div>\n );\n }\n\n if (phase === \"validating\") {\n return <span className=\"text-xs text-muted-foreground\">Validating…</span>;\n }\n\n return null;\n}\n\n// ─── File List ──────────────────────────────────────────────────────────\n\nfunction FileList({ files }: { files: MultiUploadFileState[] }) {\n return (\n <ul className=\"flex flex-col gap-1\">\n {files.map((f) => (\n <li key={f.id} className=\"flex flex-col gap-0.5 text-xs\">\n <div className=\"flex items-center gap-1.5\">\n {f.status === \"success\" && (\n <CheckCircleIcon className=\"size-3.5 shrink-0 text-green-600\" />\n )}\n {f.status === \"error\" && (\n <AlertCircleIcon className=\"size-3.5 shrink-0 text-destructive\" />\n )}\n {(f.status === \"pending\" || f.status === \"uploading\") && (\n <CircleProgress\n percent={f.status === \"uploading\" ? f.progress.percent : 0}\n size={14}\n strokeWidth={2}\n />\n )}\n <span className=\"[overflow-wrap:anywhere] max-w-32 min-w-16 truncate sm:max-w-48\">\n {f.fileName}\n </span>\n {f.status === \"uploading\" ? (\n <span className=\"shrink-0 text-muted-foreground\">\n {formatFileSize(f.progress.loaded)} /{\" \"}\n {formatFileSize(f.fileSize)} ({f.progress.percent}%)\n </span>\n ) : (\n <span className=\"shrink-0 text-muted-foreground\">\n {formatFileSize(f.fileSize)}\n </span>\n )}\n </div>\n {f.status === \"error\" && f.error && (\n <span className=\"truncate [overflow-wrap:anywhere] pl-5 text-destructive\">\n {f.error}\n </span>\n )}\n </li>\n ))}\n </ul>\n );\n}\n","\"use client\";\n\nimport { useEffect, useRef } from \"react\";\nimport { toast } from \"sonner\";\nimport { formatFileSize } from \"@better-s3/react\";\nimport type { UseUploadControlsReturn } from \"@better-s3/react\";\n\n/**\n * Drives sonner toasts for upload progress/success/error.\n * Shared between UploadButton and UploadDropzone.\n */\nexport function useUploadToast(\n ctrl: Pick<\n UseUploadControlsReturn,\n | \"mode\"\n | \"phase\"\n | \"fileInfo\"\n | \"progress\"\n | \"files\"\n | \"totalProgress\"\n | \"error\"\n | \"cancel\"\n >,\n enabled: boolean,\n) {\n const toastIdRef = useRef<string | null>(null);\n const isMulti = ctrl.mode === \"multi\";\n\n // Phase-transition toasts (runs synchronously during render to fire exactly once)\n const prevPhaseRef = useRef(ctrl.phase);\n if (prevPhaseRef.current !== ctrl.phase) {\n prevPhaseRef.current = ctrl.phase;\n if (enabled) {\n if (ctrl.phase === \"idle\" && toastIdRef.current) {\n toast.dismiss(toastIdRef.current);\n toastIdRef.current = null;\n }\n if (ctrl.phase === \"success\") {\n if (toastIdRef.current) toast.dismiss(toastIdRef.current);\n if (isMulti) {\n toast.success(`${ctrl.files.length} file(s) uploaded`, {\n description: formatFileSize(ctrl.totalProgress.total),\n });\n } else if (ctrl.fileInfo) {\n toast.success(\"Upload complete\", {\n description: formatFileSize(ctrl.fileInfo.size),\n });\n }\n toastIdRef.current = null;\n }\n if (ctrl.phase === \"error\") {\n if (toastIdRef.current) toast.dismiss(toastIdRef.current);\n if (isMulti && ctrl.files.length > 0) {\n const succeeded = ctrl.files.filter(\n (f) => f.status === \"success\",\n ).length;\n const failed = ctrl.files.filter((f) => f.status === \"error\").length;\n toast.error(\"Upload finished with errors\", {\n description: `${succeeded} succeeded, ${failed} failed`,\n });\n } else {\n toast.error(\"Upload failed\", {\n description: (\n <span className=\"block [overflow-wrap:anywhere]\">\n {ctrl.error ?? \"Unknown error\"}\n </span>\n ),\n });\n }\n toastIdRef.current = null;\n }\n }\n }\n\n // Progress toast (updated on each progress tick)\n useEffect(() => {\n if (!enabled || ctrl.phase !== \"uploading\") return;\n const id = toastIdRef.current ?? `upload-${Date.now()}`;\n toastIdRef.current = id;\n if (isMulti) {\n const done = ctrl.files.filter((f) => f.status === \"success\").length;\n toast.loading(`Uploading... ${done}/${ctrl.files.length}`, {\n id,\n description: `${formatFileSize(ctrl.totalProgress.loaded)} / ${formatFileSize(ctrl.totalProgress.total)} (${ctrl.totalProgress.percent}%)`,\n cancel: { label: \"Cancel\", onClick: () => ctrl.cancel() },\n });\n } else if (ctrl.fileInfo) {\n toast.loading(\"Uploading...\", {\n id,\n description: `${formatFileSize(ctrl.progress.loaded)} / ${formatFileSize(ctrl.fileInfo.size)} (${ctrl.progress.percent}%)`,\n cancel: { label: \"Cancel\", onClick: () => ctrl.cancel() },\n });\n }\n }, [\n enabled,\n ctrl.phase,\n isMulti,\n ctrl.progress.loaded,\n ctrl.progress.percent,\n ctrl.totalProgress.loaded,\n ctrl.totalProgress.total,\n ctrl.totalProgress.percent,\n ctrl.fileInfo,\n ctrl.files,\n ctrl.cancel,\n ]);\n}\n","\"use client\";\n\nimport { UploadIcon } from \"lucide-react\";\nimport type { UseUploadControlsOptions } from \"@better-s3/react\";\nimport { useUploadControls } from \"@better-s3/react\";\nimport { cn } from \"@/lib/utils\";\nimport { Button } from \"@/components/ui/button\";\nimport {\n Tooltip,\n TooltipContent,\n TooltipProvider,\n TooltipTrigger,\n} from \"@/components/ui/tooltip\";\nimport { UploadStatus } from \"@/components/upload/upload-status\";\nimport { MultiUploadStatus } from \"@/components/upload/multi-upload-status\";\nimport { useUploadToast } from \"@/hooks/use-upload-toast\";\n\nexport type UploadButtonProps = UseUploadControlsOptions & {\n className?: string;\n label?: string;\n disabled?: boolean;\n tooltipText?: string;\n /** Enable sonner toasts (default: `true`) */\n toast?: boolean;\n /** Show inline status below the button (default: `true`) */\n showStatus?: boolean;\n};\n\nexport function UploadButton({\n className,\n label,\n disabled,\n tooltipText,\n toast: enableToast = true,\n showStatus = true,\n ...options\n}: UploadButtonProps) {\n const ctrl = useUploadControls(options);\n const isMulti = ctrl.mode === \"multi\";\n const isDisabled = disabled || ctrl.isUploading;\n\n useUploadToast(ctrl, enableToast);\n\n const status = showStatus ? (\n isMulti ? (\n <MultiUploadStatus\n phase={ctrl.phase}\n files={ctrl.files}\n totalProgress={ctrl.totalProgress}\n error={ctrl.error}\n onCancel={ctrl.cancel}\n />\n ) : (\n <UploadStatus\n phase={ctrl.phase}\n progress={ctrl.progress}\n error={ctrl.error}\n fileInfo={ctrl.fileInfo}\n onCancel={ctrl.cancel}\n />\n )\n ) : null;\n\n return (\n <div className={cn(\"inline-flex flex-col gap-2\", className)}>\n <div className=\"inline-flex items-center gap-2\">\n <input {...ctrl.inputProps} />\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger\n render={\n <Button\n size=\"default\"\n disabled={isDisabled}\n onClick={ctrl.openFilePicker}\n />\n }>\n <UploadIcon data-icon=\"inline-start\" />\n {label ?? (isMulti ? \"Upload files\" : \"Upload file\")}\n </TooltipTrigger>\n <TooltipContent>\n {tooltipText ?? (isMulti ? \"Upload files\" : \"Upload file\")}\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n </div>\n {status}\n </div>\n );\n}\n","\"use client\";\n\nimport { UploadIcon } from \"lucide-react\";\nimport type { UseUploadControlsOptions } from \"@better-s3/react\";\nimport { useUploadControls } from \"@better-s3/react\";\nimport { cn } from \"@/lib/utils\";\nimport { UploadStatus } from \"@/components/upload/upload-status\";\nimport { MultiUploadStatus } from \"@/components/upload/multi-upload-status\";\nimport { useUploadToast } from \"@/hooks/use-upload-toast\";\n\nexport type UploadDropzoneProps = UseUploadControlsOptions & {\n className?: string;\n label?: string;\n disabled?: boolean;\n /** Enable sonner toasts (default: `true`) */\n toast?: boolean;\n /** Show inline status inside the dropzone (default: `true`) */\n showStatus?: boolean;\n};\n\nexport function UploadDropzone({\n className,\n label,\n disabled,\n toast: enableToast = true,\n showStatus = true,\n ...options\n}: UploadDropzoneProps) {\n const ctrl = useUploadControls(options);\n const isMulti = ctrl.mode === \"multi\";\n const isDisabled = disabled || ctrl.isUploading;\n\n useUploadToast(ctrl, enableToast);\n\n const status = showStatus ? (\n isMulti ? (\n <MultiUploadStatus\n phase={ctrl.phase}\n files={ctrl.files}\n totalProgress={ctrl.totalProgress}\n error={ctrl.error}\n onCancel={ctrl.cancel}\n />\n ) : (\n <UploadStatus\n phase={ctrl.phase}\n progress={ctrl.progress}\n error={ctrl.error}\n fileInfo={ctrl.fileInfo}\n onCancel={ctrl.cancel}\n />\n )\n ) : null;\n\n return (\n <div\n className={cn(\n \"flex flex-col items-center justify-center gap-3 rounded-lg border-2 border-dashed p-6 text-center transition-colors\",\n isDisabled\n ? \"cursor-not-allowed border-muted-foreground/25\"\n : \"cursor-pointer border-muted-foreground/25 hover:border-primary/50\",\n className,\n )}\n onClick={isDisabled ? undefined : ctrl.openFilePicker}\n {...(isDisabled ? {} : ctrl.dropHandlers)}>\n <input {...ctrl.inputProps} />\n <UploadIcon\n className={cn(\n \"size-6 text-muted-foreground\",\n isDisabled && \"opacity-50\",\n )}\n />\n <p\n className={cn(\n \"text-sm text-muted-foreground\",\n isDisabled && \"opacity-50\",\n )}>\n {label ??\n (isMulti\n ? \"Click or drag & drop files to upload\"\n : \"Click or drag & drop to upload\")}\n </p>\n {status && <div className=\"w-full text-left\">{status}</div>}\n </div>\n );\n}\n","\"use client\";\n\nimport { toast } from \"sonner\";\nimport { formatFileSize } from \"@better-s3/react\";\n\nexport type DownloadToastOptions = {\n enabled?: boolean;\n objectKey: string;\n fileName?: string;\n fileSize?: number;\n};\n\nexport function useDownloadToast({\n enabled = true,\n objectKey,\n fileName,\n fileSize,\n}: DownloadToastOptions) {\n const displayName = fileName ?? objectKey.split(\"/\").pop() ?? objectKey;\n\n const errorNode = (error: unknown) => (\n <span className=\"block [overflow-wrap:anywhere]\">\n {error instanceof Error ? error.message : \"Unknown error\"}\n </span>\n );\n\n const onInitiated = () => {\n if (enabled) toast.success(\"Download started\");\n };\n\n const onSuccess = (_key: string, actualFileName: string) => {\n if (!enabled) return;\n toast.dismiss(`dl-${objectKey}`);\n toast.success(\"Download complete\", {\n description: (\n <span className=\"block max-w-[50ch] truncate\">\n {actualFileName}\n {fileSize != null ? ` · ${formatFileSize(fileSize)}` : \"\"}\n </span>\n ),\n });\n };\n\n const onError = (_key: string, error: unknown) => {\n if (!enabled) return;\n toast.dismiss(`dl-${objectKey}`);\n toast.error(\"Download failed\", { description: errorNode(error) });\n };\n\n const onErrorWithPhase = (_key: string, error: unknown, _phase: string) => {\n if (!enabled) return;\n toast.dismiss(`dl-${objectKey}`);\n toast.error(\"Download failed\", { description: errorNode(error) });\n };\n\n const onCancel = (_key: string) => {\n if (!enabled) return;\n toast.dismiss(`dl-${objectKey}`);\n toast.info(\"Download cancelled\", {\n description: (\n <span className=\"block max-w-[50ch] truncate\">{displayName}</span>\n ),\n });\n };\n\n return { onInitiated, onSuccess, onError, onErrorWithPhase, onCancel };\n}\n","\"use client\";\n\nimport { AlertCircleIcon, DownloadIcon, LoaderIcon } from \"lucide-react\";\nimport { cn } from \"@/lib/utils\";\nimport type { S3Api } from \"@better-s3/react\";\nimport { useDownload } from \"@better-s3/react\";\nimport { Button } from \"@/components/ui/button\";\nimport { useDownloadToast } from \"@/hooks/use-download-toast\";\n\ntype DownloadButtonProps = {\n api: S3Api;\n objectKey: string;\n fileName?: string;\n label?: string;\n className?: string;\n disabled?: boolean;\n /** Enable sonner toasts (default: `true`) */\n toast?: boolean;\n /** Show inline error status below the button (default: `true`) */\n showStatus?: boolean;\n};\n\nexport function DownloadButton({\n api,\n objectKey,\n fileName,\n label,\n className,\n disabled,\n toast: enableToast = true,\n showStatus = true,\n}: DownloadButtonProps) {\n const toastHandlers = useDownloadToast({\n enabled: enableToast,\n objectKey,\n fileName,\n });\n\n const dl = useDownload({\n api,\n onInitiated: () => {\n toastHandlers.onInitiated();\n },\n onError: (key, error) => {\n toastHandlers.onError(key, error);\n },\n });\n\n const isPending = dl.phase === \"presigning\";\n\n return (\n <div className={cn(\"inline-flex flex-col gap-1.5\", className)}>\n <Button\n size=\"default\"\n variant=\"outline\"\n disabled={disabled || isPending}\n onClick={() => dl.download(objectKey, fileName)}>\n <span className=\"inline-flex items-center gap-1\">\n {isPending ? (\n <LoaderIcon className=\"animate-spin\" data-icon=\"inline-start\" />\n ) : (\n <DownloadIcon data-icon=\"inline-start\" />\n )}\n {label ?? \"Download\"}\n </span>\n </Button>\n\n {showStatus && dl.phase === \"error\" && (\n <div className=\"flex min-w-0 items-start gap-1.5 text-xs\">\n <AlertCircleIcon className=\"mt-0.5 size-3.5 shrink-0 text-destructive\" />\n <p className=\"min-w-0 [overflow-wrap:anywhere] text-destructive\">\n {dl.error ?? \"Download failed\"}\n </p>\n </div>\n )}\n </div>\n );\n}\n","\"use client\";\n\nimport { DownloadIcon, AlertCircleIcon } from \"lucide-react\";\nimport { cn } from \"@/lib/utils\";\nimport { formatFileSize } from \"@better-s3/react\";\nimport type { S3Api, FetchDownloadHooks } from \"@better-s3/react\";\nimport { useFetchDownload } from \"@better-s3/react\";\nimport { Button } from \"@/components/ui/button\";\nimport {\n Tooltip,\n TooltipContent,\n TooltipProvider,\n TooltipTrigger,\n} from \"@/components/ui/tooltip\";\nimport { useDownloadToast } from \"@/hooks/use-download-toast\";\n\ntype ProgressDownloadButtonProps = FetchDownloadHooks & {\n api: S3Api;\n objectKey: string;\n fileName?: string;\n fileSize?: number;\n /** Target bucket (overrides server default) */\n bucket?: string;\n label?: string;\n className?: string;\n fillClassName?: string;\n disabled?: boolean;\n tooltipText?: string;\n /** Enable sonner toasts (default: `true`) */\n toast?: boolean;\n /** Show inline error status below the button (default: `true`) */\n showStatus?: boolean;\n};\n\nexport function ProgressDownloadButton({\n api,\n objectKey,\n fileName,\n fileSize,\n bucket,\n label,\n className,\n fillClassName,\n disabled,\n tooltipText = \"Download file\",\n toast: enableToast = true,\n showStatus = true,\n beforeDownload,\n onDownloadStart,\n onProgress,\n onSuccess,\n onError,\n onCancel,\n}: ProgressDownloadButtonProps) {\n const toastHandlers = useDownloadToast({\n enabled: enableToast,\n objectKey,\n fileName,\n fileSize,\n });\n\n const dl = useFetchDownload({\n api,\n bucket,\n beforeDownload,\n onDownloadStart,\n onProgress,\n onSuccess: (key, actualFileName) => {\n toastHandlers.onSuccess(key, actualFileName);\n onSuccess?.(key, actualFileName);\n },\n onError: (key, error, phase) => {\n toastHandlers.onErrorWithPhase(key, error, phase);\n onError?.(key, error, phase);\n },\n onCancel: (key) => {\n toastHandlers.onCancel(key);\n onCancel?.(key);\n },\n });\n\n const isDownloading = dl.phase === \"downloading\" || dl.phase === \"presigning\";\n\n const handleClick = () => {\n if (isDownloading) {\n dl.cancel();\n return;\n }\n dl.download(objectKey, fileName);\n };\n\n return (\n <div className={cn(\"inline-flex flex-col gap-1.5\", className)}>\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger\n render={\n <Button\n size=\"default\"\n variant=\"outline\"\n disabled={disabled}\n className={cn(\"relative min-w-24 overflow-hidden\")}\n onClick={handleClick}\n />\n }>\n {isDownloading && (\n <span\n className={cn(\n \"absolute inset-0 bg-primary/15 transition-[width] duration-200\",\n fillClassName,\n )}\n style={{ width: `${dl.progress.percent}%` }}\n />\n )}\n <span className=\"relative z-10 inline-flex items-center gap-1\">\n <DownloadIcon data-icon=\"inline-start\" />\n {isDownloading\n ? formatFileSize(dl.progress.loaded)\n : (label ?? \"Download\")}\n </span>\n </TooltipTrigger>\n <TooltipContent>\n {isDownloading ? \"Cancel download\" : tooltipText}\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n\n {showStatus && dl.phase === \"error\" && (\n <div className=\"flex min-w-0 items-start gap-1.5 text-xs\">\n <AlertCircleIcon className=\"mt-0.5 size-3.5 shrink-0 text-destructive\" />\n <p className=\"min-w-0 [overflow-wrap:anywhere] text-destructive\">\n {dl.error ?? \"Download failed\"}\n </p>\n </div>\n )}\n </div>\n );\n}\n","\"use client\";\n\nimport * as React from \"react\";\nimport { AlertDialog as AlertDialogPrimitive } from \"@base-ui/react/alert-dialog\";\n\nimport { cn } from \"@/lib/utils\";\nimport { Button } from \"@/components/ui/button\";\n\nfunction AlertDialog({ ...props }: AlertDialogPrimitive.Root.Props) {\n return <AlertDialogPrimitive.Root data-slot=\"alert-dialog\" {...props} />;\n}\n\nfunction AlertDialogTrigger({ ...props }: AlertDialogPrimitive.Trigger.Props) {\n return (\n <AlertDialogPrimitive.Trigger data-slot=\"alert-dialog-trigger\" {...props} />\n );\n}\n\nfunction AlertDialogPortal({ ...props }: AlertDialogPrimitive.Portal.Props) {\n return (\n <AlertDialogPrimitive.Portal data-slot=\"alert-dialog-portal\" {...props} />\n );\n}\n\nfunction AlertDialogOverlay({\n className,\n ...props\n}: AlertDialogPrimitive.Backdrop.Props) {\n return (\n <AlertDialogPrimitive.Backdrop\n data-slot=\"alert-dialog-overlay\"\n className={cn(\n \"fixed inset-0 isolate z-50 bg-black/80 duration-100 supports-backdrop-filter:backdrop-blur-xs data-open:animate-in data-open:fade-in-0 data-closed:animate-out data-closed:fade-out-0\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction AlertDialogContent({\n className,\n size = \"default\",\n ...props\n}: AlertDialogPrimitive.Popup.Props & {\n size?: \"default\" | \"sm\";\n}) {\n return (\n <AlertDialogPortal>\n <AlertDialogOverlay />\n <AlertDialogPrimitive.Popup\n data-slot=\"alert-dialog-content\"\n data-size={size}\n className={cn(\n \"group/alert-dialog-content fixed top-1/2 start-1/2 z-50 grid w-full -translate-x-1/2 rtl:translate-x-1/2 -translate-y-1/2 gap-3 rounded-xl bg-popover p-4 text-popover-foreground ring-1 ring-foreground/10 duration-100 outline-none data-[size=default]:max-w-xs data-[size=sm]:max-w-64 data-[size=default]:sm:max-w-sm data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95\",\n className,\n )}\n {...props}\n />\n </AlertDialogPortal>\n );\n}\n\nfunction AlertDialogHeader({\n className,\n ...props\n}: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"alert-dialog-header\"\n className={cn(\n \"grid grid-rows-[auto_1fr] place-items-center gap-1 text-center has-data-[slot=alert-dialog-media]:grid-rows-[auto_auto_1fr] has-data-[slot=alert-dialog-media]:gap-x-4 sm:group-data-[size=default]/alert-dialog-content:place-items-start sm:group-data-[size=default]/alert-dialog-content:text-start sm:group-data-[size=default]/alert-dialog-content:has-data-[slot=alert-dialog-media]:grid-rows-[auto_1fr]\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction AlertDialogFooter({\n className,\n ...props\n}: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"alert-dialog-footer\"\n className={cn(\n \"flex flex-col-reverse gap-2 group-data-[size=sm]/alert-dialog-content:grid group-data-[size=sm]/alert-dialog-content:grid-cols-2 sm:flex-row sm:justify-end\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction AlertDialogMedia({\n className,\n ...props\n}: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"alert-dialog-media\"\n className={cn(\n \"mb-2 inline-flex size-8 items-center justify-center rounded-md bg-muted sm:group-data-[size=default]/alert-dialog-content:row-span-2 *:[svg:not([class*='size-'])]:size-4\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction AlertDialogTitle({\n className,\n ...props\n}: React.ComponentProps<typeof AlertDialogPrimitive.Title>) {\n return (\n <AlertDialogPrimitive.Title\n data-slot=\"alert-dialog-title\"\n className={cn(\n \"font-heading text-sm font-medium sm:group-data-[size=default]/alert-dialog-content:group-has-data-[slot=alert-dialog-media]/alert-dialog-content:col-start-2\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction AlertDialogDescription({\n className,\n ...props\n}: React.ComponentProps<typeof AlertDialogPrimitive.Description>) {\n return (\n <AlertDialogPrimitive.Description\n data-slot=\"alert-dialog-description\"\n className={cn(\n \"text-xs/relaxed text-balance text-muted-foreground md:text-pretty *:[a]:underline *:[a]:underline-offset-3 *:[a]:hover:text-foreground\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction AlertDialogAction({\n className,\n ...props\n}: React.ComponentProps<typeof Button>) {\n return (\n <Button\n data-slot=\"alert-dialog-action\"\n className={cn(className)}\n {...props}\n />\n );\n}\n\nfunction AlertDialogCancel({\n className,\n variant = \"outline\",\n size = \"default\",\n ...props\n}: AlertDialogPrimitive.Close.Props &\n Pick<React.ComponentProps<typeof Button>, \"variant\" | \"size\">) {\n return (\n <AlertDialogPrimitive.Close\n data-slot=\"alert-dialog-cancel\"\n className={cn(className)}\n render={<Button variant={variant} size={size} />}\n {...props}\n />\n );\n}\n\nexport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogMedia,\n AlertDialogOverlay,\n AlertDialogPortal,\n AlertDialogTitle,\n AlertDialogTrigger,\n};\n","\"use client\";\n\nimport { toast } from \"sonner\";\n\nexport type DeleteToastOptions = {\n enabled?: boolean;\n displayName: string;\n};\n\nexport function useDeleteToast({\n enabled = true,\n displayName,\n}: DeleteToastOptions) {\n const onSuccess = (_key: string) => {\n if (!enabled) return;\n toast.success(\"File deleted\", {\n description: (\n <span className=\"block max-w-[50ch] truncate\">{displayName}</span>\n ),\n });\n };\n\n const onError = (_key: string, error: unknown) => {\n if (!enabled) return;\n toast.error(\"Delete failed\", {\n description: (\n <span className=\"block [overflow-wrap:anywhere]\">\n {error instanceof Error ? error.message : \"Unknown error\"}\n </span>\n ),\n });\n };\n\n return { onSuccess, onError };\n}\n","\"use client\";\n\nimport {\n Trash2Icon,\n LoaderIcon,\n AlertCircleIcon,\n CheckCircle2Icon,\n} from \"lucide-react\";\nimport { cn } from \"@/lib/utils\";\nimport { formatFileSize } from \"@better-s3/react\";\nimport type { S3Api, DeleteHooks } from \"@better-s3/react\";\nimport { useDelete } from \"@better-s3/react\";\nimport { Button } from \"@/components/ui/button\";\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogMedia,\n AlertDialogTitle,\n AlertDialogTrigger,\n} from \"@/components/ui/alert-dialog\";\nimport {\n Tooltip,\n TooltipContent,\n TooltipProvider,\n TooltipTrigger,\n} from \"@/components/ui/tooltip\";\nimport { useDeleteToast } from \"@/hooks/use-delete-toast\";\n\ntype DeleteButtonProps = DeleteHooks & {\n api: S3Api;\n objectKey: string;\n fileName?: string;\n fileSize?: number;\n /** Target bucket (overrides server default) */\n bucket?: string;\n label?: string;\n className?: string;\n disabled?: boolean;\n tooltipText?: string;\n /** Enable sonner toasts (default: `true`) */\n toast?: boolean;\n /** Show inline error status below the button (default: `true`) */\n showStatus?: boolean;\n confirmTitle?: string;\n confirmDescription?: string;\n};\n\nexport function DeleteButton({\n api,\n objectKey,\n fileName,\n fileSize,\n bucket,\n label,\n className,\n disabled,\n tooltipText = \"Delete file\",\n toast: enableToast = true,\n showStatus = true,\n confirmTitle = \"Delete file?\",\n confirmDescription,\n beforeDelete,\n onDeleteStart,\n onSuccess,\n onError,\n}: DeleteButtonProps) {\n const displayName = fileName ?? objectKey.split(\"/\").pop() ?? objectKey;\n const toastHandlers = useDeleteToast({\n enabled: enableToast,\n displayName,\n });\n\n const del = useDelete({\n api,\n bucket,\n beforeDelete,\n onDeleteStart,\n onSuccess: (key) => {\n toastHandlers.onSuccess(key);\n onSuccess?.(key);\n },\n onError: (key, error, phase) => {\n toastHandlers.onError(key, error);\n onError?.(key, error, phase);\n },\n });\n\n const isDeleting = del.phase === \"deleting\";\n const isDisabled = disabled || isDeleting;\n\n const description = confirmDescription ?? (\n <>\n {\"Are you sure you want to delete \"}\n <span className=\"inline-block max-w-[30ch] truncate align-bottom\">\n “{displayName}”\n </span>\n {fileSize != null ? ` (${formatFileSize(fileSize)})` : \"\"}\n {\"? This action cannot be undone.\"}\n </>\n );\n\n return (\n <div className={cn(\"inline-flex flex-col gap-1.5\", className)}>\n <div className=\"inline-flex items-center gap-2\">\n <AlertDialog\n open={del.phase === \"confirming\"}\n onOpenChange={(open) => {\n if (!open) del.cancelDelete();\n }}>\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger\n render={\n <AlertDialogTrigger\n disabled={isDisabled}\n onClick={() => del.requestDelete(objectKey)}\n render={\n <Button\n size=\"default\"\n variant=\"destructive\"\n disabled={isDisabled}\n />\n }\n />\n }>\n {isDeleting ? (\n <LoaderIcon\n className=\"animate-spin\"\n data-icon=\"inline-start\"\n />\n ) : (\n <Trash2Icon data-icon=\"inline-start\" />\n )}\n {label ?? \"Delete\"}\n </TooltipTrigger>\n <TooltipContent>{tooltipText}</TooltipContent>\n </Tooltip>\n </TooltipProvider>\n\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogMedia>\n <Trash2Icon />\n </AlertDialogMedia>\n <AlertDialogTitle>{confirmTitle}</AlertDialogTitle>\n <AlertDialogDescription className=\"[overflow-wrap:anywhere]\">\n {description}\n </AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel>Cancel</AlertDialogCancel>\n <AlertDialogAction\n variant=\"destructive\"\n onClick={() => del.confirmDelete()}>\n Delete\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n </div>\n\n {showStatus && del.phase === \"success\" && (\n <div className=\"flex min-w-0 items-center gap-1.5 text-xs\">\n <CheckCircle2Icon className=\"size-3.5 shrink-0 text-green-600\" />\n <p className=\"min-w-0 [overflow-wrap:anywhere] text-green-600\">\n “\n <span className=\"inline-block max-w-[30ch] truncate align-bottom\">\n {displayName}\n </span>\n ” deleted\n </p>\n </div>\n )}\n\n {showStatus && del.phase === \"error\" && (\n <div className=\"flex min-w-0 items-start gap-1.5 text-xs\">\n <AlertCircleIcon className=\"mt-0.5 size-3.5 shrink-0 text-destructive\" />\n <p className=\"min-w-0 [overflow-wrap:anywhere] text-destructive\">\n {del.error ?? \"Delete failed\"}\n </p>\n </div>\n )}\n </div>\n );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/lib/utils.ts","../src/components/ui/button.tsx","../src/components/ui/tooltip.tsx","../src/components/ui/circle-progress.tsx","../src/components/upload/upload-status.tsx","../src/components/ui/progress.tsx","../src/components/upload/multi-upload-status.tsx","../src/components/upload/upload-status-block.tsx","../src/hooks/use-upload-toast.tsx","../src/components/upload/upload-button.tsx","../src/components/upload/upload-dropzone.tsx","../src/hooks/use-download-toast.tsx","../src/components/download/download-button.tsx","../src/components/download/progress-download-button.tsx","../src/components/ui/alert-dialog.tsx","../src/hooks/use-delete-toast.tsx","../src/components/delete/delete-button.tsx"],"names":["ButtonPrimitive","jsx","TooltipPrimitive","jsxs","ProgressPrimitive","XIcon","CheckCircleIcon","AlertCircleIcon","truncateFilename","formatFileSize","EMPTY_PROGRESS","EMPTY_FILES","useUploadControls","useMultiUploadControls","UploadIcon","toast","formatEta","DownloadIcon","formatSpeed","AlertDialogPrimitive","LoaderIcon"],"mappings":"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","file":"index.js","sourcesContent":["import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs))\n}\n","import { Button as ButtonPrimitive } from \"@base-ui/react/button\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\n\nimport { cn } from \"@/lib/utils\";\n\nconst buttonVariants = cva(\n \"group/button cursor-pointer inline-flex shrink-0 items-center justify-center rounded-md border border-transparent bg-clip-padding text-xs/relaxed font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-2 focus-visible:ring-ring/30 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-2 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n {\n variants: {\n variant: {\n default: \"bg-primary text-primary-foreground hover:bg-primary/80\",\n outline:\n \"border-border hover:bg-input/50 hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:bg-input/30\",\n secondary:\n \"bg-secondary text-secondary-foreground hover:bg-secondary/80 aria-expanded:bg-secondary aria-expanded:text-secondary-foreground\",\n ghost:\n \"hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:hover:bg-muted/50\",\n destructive:\n \"bg-destructive/10 text-destructive hover:bg-destructive/20 focus-visible:border-destructive/40 focus-visible:ring-destructive/20 dark:bg-destructive/20 dark:hover:bg-destructive/30 dark:focus-visible:ring-destructive/40\",\n link: \"text-primary underline-offset-4 hover:underline\",\n },\n size: {\n default:\n \"h-7 gap-1 px-2 text-xs/relaxed has-data-[icon=inline-end]:pe-1.5 has-data-[icon=inline-start]:ps-1.5 [&_svg:not([class*='size-'])]:size-3.5\",\n xs: \"h-5 gap-1 rounded-sm px-2 text-[0.625rem] has-data-[icon=inline-end]:pe-1.5 has-data-[icon=inline-start]:ps-1.5 [&_svg:not([class*='size-'])]:size-2.5\",\n sm: \"h-6 gap-1 px-2 text-xs/relaxed has-data-[icon=inline-end]:pe-1.5 has-data-[icon=inline-start]:ps-1.5 [&_svg:not([class*='size-'])]:size-3\",\n lg: \"h-8 gap-1 px-2.5 text-xs/relaxed has-data-[icon=inline-end]:pe-2 has-data-[icon=inline-start]:ps-2 [&_svg:not([class*='size-'])]:size-4\",\n icon: \"size-7 [&_svg:not([class*='size-'])]:size-3.5\",\n \"icon-xs\": \"size-5 rounded-sm [&_svg:not([class*='size-'])]:size-2.5\",\n \"icon-sm\": \"size-6 [&_svg:not([class*='size-'])]:size-3\",\n \"icon-lg\": \"size-8 [&_svg:not([class*='size-'])]:size-4\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n },\n);\n\nfunction Button({\n className,\n variant = \"default\",\n size = \"default\",\n ...props\n}: ButtonPrimitive.Props & VariantProps<typeof buttonVariants>) {\n return (\n <ButtonPrimitive\n data-slot=\"button\"\n className={cn(buttonVariants({ variant, size, className }))}\n {...props}\n />\n );\n}\n\nexport { Button, buttonVariants };\n","\"use client\";\n\nimport { Tooltip as TooltipPrimitive } from \"@base-ui/react/tooltip\";\n\nimport { cn } from \"@/lib/utils\";\n\nfunction TooltipProvider({\n delay = 0,\n ...props\n}: TooltipPrimitive.Provider.Props) {\n return (\n <TooltipPrimitive.Provider\n data-slot=\"tooltip-provider\"\n delay={delay}\n {...props}\n />\n );\n}\n\nfunction Tooltip({ ...props }: TooltipPrimitive.Root.Props) {\n return <TooltipPrimitive.Root data-slot=\"tooltip\" {...props} />;\n}\n\nfunction TooltipTrigger({ ...props }: TooltipPrimitive.Trigger.Props) {\n return <TooltipPrimitive.Trigger data-slot=\"tooltip-trigger\" {...props} />;\n}\n\nfunction TooltipContent({\n className,\n side = \"top\",\n sideOffset = 4,\n align = \"center\",\n alignOffset = 0,\n children,\n ...props\n}: TooltipPrimitive.Popup.Props &\n Pick<\n TooltipPrimitive.Positioner.Props,\n \"align\" | \"alignOffset\" | \"side\" | \"sideOffset\"\n >) {\n return (\n <TooltipPrimitive.Portal>\n <TooltipPrimitive.Positioner\n align={align}\n alignOffset={alignOffset}\n side={side}\n sideOffset={sideOffset}\n className=\"isolate z-50\">\n <TooltipPrimitive.Popup\n data-slot=\"tooltip-content\"\n className={cn(\n \"z-50 inline-flex w-fit max-w-xs origin-(--transform-origin) items-center gap-1.5 rounded-md bg-foreground px-3 py-1.5 text-xs text-background has-data-[slot=kbd]:pe-1.5 data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-start-2 data-[side=inline-start]:slide-in-from-end-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 **:data-[slot=kbd]:relative **:data-[slot=kbd]:isolate **:data-[slot=kbd]:z-50 **:data-[slot=kbd]:rounded-sm data-[state=delayed-open]:animate-in data-[state=delayed-open]:fade-in-0 data-[state=delayed-open]:zoom-in-95 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95\",\n className,\n )}\n {...props}>\n {children}\n <TooltipPrimitive.Arrow className=\"z-50 size-2.5 translate-y-[calc(-50%-2px)] rotate-45 rounded-[2px] bg-foreground fill-foreground data-[side=bottom]:top-1 data-[side=inline-end]:top-1/2! data-[side=inline-end]:-start-1 data-[side=inline-end]:-translate-y-1/2 data-[side=inline-start]:top-1/2! data-[side=inline-start]:-end-1 data-[side=inline-start]:-translate-y-1/2 data-[side=left]:top-1/2! data-[side=left]:-right-1 data-[side=left]:-translate-y-1/2 data-[side=right]:top-1/2! data-[side=right]:-left-1 data-[side=right]:-translate-y-1/2 data-[side=top]:-bottom-2.5\" />\n </TooltipPrimitive.Popup>\n </TooltipPrimitive.Positioner>\n </TooltipPrimitive.Portal>\n );\n}\n\nexport { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider };\n","\"use client\"\n\nexport function CircleProgress({\n percent,\n size = 20,\n strokeWidth = 2.5,\n}: {\n percent: number\n size?: number\n strokeWidth?: number\n}) {\n const r = (size - strokeWidth) / 2\n const c = 2 * Math.PI * r\n const offset = c - (percent / 100) * c\n return (\n <svg width={size} height={size} className=\"shrink-0 -rotate-90\">\n <circle\n cx={size / 2}\n cy={size / 2}\n r={r}\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={strokeWidth}\n className=\"text-muted-foreground/20\"\n />\n <circle\n cx={size / 2}\n cy={size / 2}\n r={r}\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={strokeWidth}\n strokeDasharray={c}\n strokeDashoffset={offset}\n strokeLinecap=\"round\"\n className=\"text-primary transition-[stroke-dashoffset] duration-200\"\n />\n </svg>\n )\n}\n","\"use client\";\n\nimport { XIcon, CheckCircleIcon, AlertCircleIcon } from \"lucide-react\";\nimport {\n formatFileSize,\n formatSpeed,\n formatEta,\n truncateFilename,\n} from \"@better-s3/react\";\nimport type { UploadPhase, UploadProgress } from \"@better-s3/react\";\nimport { Button } from \"@/components/ui/button\";\nimport { CircleProgress } from \"@/components/ui/circle-progress\";\n\nexport function UploadStatus({\n phase,\n progress,\n error,\n fileInfo,\n onCancel,\n}: {\n phase: UploadPhase;\n progress: UploadProgress;\n error: string | null;\n fileInfo: { name: string; size: number } | null;\n onCancel?: () => void;\n}) {\n if (phase === \"idle\") return null;\n\n if (phase === \"uploading\" && fileInfo) {\n const eta =\n progress.speed && progress.total\n ? formatEta(progress.total - progress.loaded, progress.speed)\n : null;\n\n const meta = [\n `${formatFileSize(progress.loaded)} / ${formatFileSize(fileInfo.size)}`,\n progress.speed ? formatSpeed(progress.speed) : null,\n eta ? `${eta} left` : null,\n ]\n .filter(Boolean)\n .join(\" · \");\n\n const compactMeta = `${Math.round(progress.percent)}%`;\n\n return (\n <div className=\"flex w-full items-center gap-2 text-xs\">\n <CircleProgress percent={progress.percent} size={14} strokeWidth={2} />\n <span className=\"min-w-0 flex-1 truncate max-w-[30ch]\">\n {truncateFilename(fileInfo.name)}\n </span>\n <span className=\"ml-auto shrink-0 whitespace-nowrap tabular-nums text-muted-foreground sm:hidden\">\n {compactMeta}\n </span>\n <span className=\"ml-auto hidden shrink-0 whitespace-nowrap tabular-nums text-muted-foreground sm:inline\">\n {meta}\n </span>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"size-6 shrink-0\"\n onClick={(e) => {\n e.stopPropagation();\n onCancel?.();\n }}>\n <XIcon className=\"size-3.5\" />\n </Button>\n </div>\n );\n }\n\n if (phase === \"success\" && fileInfo) {\n return (\n <div className=\"flex w-full items-center gap-1.5 text-xs\">\n <CheckCircleIcon className=\"size-3.5 shrink-0 text-green-600\" />\n <span className=\"min-w-0 flex-1 truncate max-w-[30ch]\">\n {truncateFilename(fileInfo.name)}\n </span>\n <span className=\"ml-auto shrink-0 text-muted-foreground\">\n {formatFileSize(fileInfo.size)}\n </span>\n </div>\n );\n }\n\n if (phase === \"error\") {\n return (\n <div className=\"flex min-w-0 items-start gap-1.5 text-xs\">\n <AlertCircleIcon className=\"mt-0.5 size-3.5 shrink-0 text-destructive\" />\n <p className=\"min-w-0 [overflow-wrap:anywhere] text-destructive\">\n {error ?? \"Upload failed\"}\n </p>\n </div>\n );\n }\n\n if (phase === \"validating\" || phase === \"presigning\") {\n return <span className=\"text-xs text-muted-foreground\">Preparing…</span>;\n }\n\n return null;\n}\n","\"use client\";\n\nimport { Progress as ProgressPrimitive } from \"@base-ui/react/progress\";\n\nimport { cn } from \"@/lib/utils\";\n\nfunction Progress({\n className,\n children,\n value,\n ...props\n}: ProgressPrimitive.Root.Props) {\n return (\n <ProgressPrimitive.Root\n value={value}\n data-slot=\"progress\"\n className={cn(\"flex flex-wrap gap-3\", className)}\n {...props}>\n {children}\n <ProgressTrack>\n <ProgressIndicator />\n </ProgressTrack>\n </ProgressPrimitive.Root>\n );\n}\n\nfunction ProgressTrack({ className, ...props }: ProgressPrimitive.Track.Props) {\n return (\n <ProgressPrimitive.Track\n className={cn(\n \"relative flex h-1 w-full items-center overflow-x-hidden rounded-md bg-muted\",\n className,\n )}\n data-slot=\"progress-track\"\n {...props}\n />\n );\n}\n\nfunction ProgressIndicator({\n className,\n ...props\n}: ProgressPrimitive.Indicator.Props) {\n return (\n <ProgressPrimitive.Indicator\n data-slot=\"progress-indicator\"\n className={cn(\"h-full bg-primary transition-all\", className)}\n {...props}\n />\n );\n}\n\nfunction ProgressLabel({ className, ...props }: ProgressPrimitive.Label.Props) {\n return (\n <ProgressPrimitive.Label\n className={cn(\"text-xs/relaxed font-medium\", className)}\n data-slot=\"progress-label\"\n {...props}\n />\n );\n}\n\nfunction ProgressValue({ className, ...props }: ProgressPrimitive.Value.Props) {\n return (\n <ProgressPrimitive.Value\n className={cn(\n \"ms-auto text-xs/relaxed text-muted-foreground tabular-nums\",\n className,\n )}\n data-slot=\"progress-value\"\n {...props}\n />\n );\n}\n\nexport {\n Progress,\n ProgressTrack,\n ProgressIndicator,\n ProgressLabel,\n ProgressValue,\n};\n","\"use client\";\n\nimport { XIcon, CheckCircleIcon, AlertCircleIcon } from \"lucide-react\";\nimport { formatFileSize, truncateFilename } from \"@better-s3/react\";\nimport type { UploadProgress, MultiUploadFileState } from \"@better-s3/react\";\nimport { Button } from \"@/components/ui/button\";\nimport {\n Progress,\n ProgressLabel,\n ProgressValue,\n} from \"@/components/ui/progress\";\nimport { CircleProgress } from \"@/components/ui/circle-progress\";\n\nexport function MultiUploadStatus({\n phase,\n files,\n totalProgress,\n error,\n onCancel,\n}: {\n phase: string;\n files: MultiUploadFileState[];\n totalProgress: UploadProgress;\n error: string | null;\n onCancel?: () => void;\n}) {\n if (phase === \"idle\") return null;\n\n if (phase === \"uploading\") {\n return (\n <div className=\"flex w-full flex-col gap-2\">\n <div className=\"flex w-full items-center gap-1.5\">\n <Progress value={totalProgress.percent} className=\"flex-1\">\n <ProgressLabel>\n {files.filter((f) => f.status === \"success\").length}/\n {files.length} files\n </ProgressLabel>\n <ProgressValue />\n </Progress>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"size-7 shrink-0\"\n onClick={(e) => {\n e.stopPropagation();\n onCancel?.();\n }}>\n <XIcon className=\"size-4\" />\n </Button>\n </div>\n <FileList files={files} />\n </div>\n );\n }\n\n if (phase === \"success\") {\n return (\n <div className=\"flex w-full flex-col gap-1\">\n <span className=\"text-xs text-green-600\">\n All {files.length} file(s) uploaded\n </span>\n <FileList files={files} />\n </div>\n );\n }\n\n if (phase === \"error\") {\n return (\n <div className=\"flex w-full flex-col gap-1\">\n <span className=\"text-xs text-destructive\">\n {error ?? \"Upload failed\"}\n </span>\n {files.length > 0 && <FileList files={files} />}\n </div>\n );\n }\n\n if (phase === \"validating\") {\n return <span className=\"text-xs text-muted-foreground\">Validating…</span>;\n }\n\n return null;\n}\n\n// ─── File List ──────────────────────────────────────────────────────────\n\nfunction FileList({ files }: { files: MultiUploadFileState[] }) {\n return (\n <ul className=\"flex flex-col gap-1\">\n {files.map((f) => (\n <li key={f.id} className=\"flex flex-col gap-0.5 text-xs\">\n <div className=\"flex items-center gap-1.5\">\n {f.status === \"success\" && (\n <CheckCircleIcon className=\"size-3.5 shrink-0 text-green-600\" />\n )}\n {f.status === \"error\" && (\n <AlertCircleIcon className=\"size-3.5 shrink-0 text-destructive\" />\n )}\n {(f.status === \"pending\" || f.status === \"uploading\") && (\n <CircleProgress\n percent={f.status === \"uploading\" ? f.progress.percent : 0}\n size={14}\n strokeWidth={2}\n />\n )}\n <span className=\"min-w-0 shrink\">\n {truncateFilename(f.fileName)}\n </span>\n {f.status === \"uploading\" ? (\n <span className=\"shrink-0 text-muted-foreground\">\n {formatFileSize(f.progress.loaded)} /{\" \"}\n {formatFileSize(f.fileSize)} ({f.progress.percent}%)\n </span>\n ) : (\n <span className=\"shrink-0 text-muted-foreground\">\n {formatFileSize(f.fileSize)}\n </span>\n )}\n </div>\n {f.status === \"error\" && f.error && (\n <span className=\"truncate [overflow-wrap:anywhere] pl-5 text-destructive\">\n {f.error}\n </span>\n )}\n </li>\n ))}\n </ul>\n );\n}\n","\"use client\";\n\nimport type {\n UploadPhase,\n UploadProgress,\n MultiUploadFileState,\n MultiUploadPhase,\n} from \"@better-s3/react\";\nimport { UploadStatus } from \"@/components/upload/upload-status\";\nimport { MultiUploadStatus } from \"@/components/upload/multi-upload-status\";\n\nexport type UploadStatusBlockProps =\n | {\n mode: \"single\";\n phase: UploadPhase;\n progress: UploadProgress;\n error: string | null;\n fileInfo: { name: string; size: number } | null;\n onCancel?: () => void;\n }\n | {\n mode: \"multi\";\n phase: MultiUploadPhase;\n files: MultiUploadFileState[];\n totalProgress: UploadProgress;\n error: string | null;\n onCancel?: () => void;\n };\n\nexport function UploadStatusBlock(props: UploadStatusBlockProps) {\n if (props.mode === \"multi\") {\n return (\n <MultiUploadStatus\n phase={props.phase}\n files={props.files}\n totalProgress={props.totalProgress}\n error={props.error}\n onCancel={props.onCancel}\n />\n );\n }\n return (\n <UploadStatus\n phase={props.phase}\n progress={props.progress}\n error={props.error}\n fileInfo={props.fileInfo}\n onCancel={props.onCancel}\n />\n );\n}\n","\"use client\";\n\nimport { useEffect, useRef } from \"react\";\nimport { toast } from \"sonner\";\nimport { formatFileSize } from \"@better-s3/react\";\nimport type { UploadProgress, MultiUploadFileState } from \"@better-s3/react\";\n\nexport type UploadToastCtrl = {\n mode: \"single\" | \"multi\";\n phase: string;\n fileInfo?: { name: string; size: number } | null;\n progress?: UploadProgress;\n files?: MultiUploadFileState[];\n totalProgress?: UploadProgress;\n error: string | null;\n cancel: () => void;\n};\n\n/**\n * Drives sonner toasts for upload progress/success/error.\n * Shared between UploadButton and UploadDropzone.\n */\nexport function useUploadToast(ctrl: UploadToastCtrl, enabled: boolean) {\n const toastIdRef = useRef<string | null>(null);\n const isMulti = ctrl.mode === \"multi\";\n const files = ctrl.files ?? [];\n const totalProgress = ctrl.totalProgress ?? {\n loaded: 0,\n total: 0,\n percent: 0,\n };\n const progress = ctrl.progress ?? { loaded: 0, total: 0, percent: 0 };\n\n // Phase-transition toasts (runs synchronously during render to fire exactly once)\n const prevPhaseRef = useRef(ctrl.phase);\n if (prevPhaseRef.current !== ctrl.phase) {\n prevPhaseRef.current = ctrl.phase;\n if (enabled) {\n if (ctrl.phase === \"idle\" && toastIdRef.current) {\n toast.dismiss(toastIdRef.current);\n toastIdRef.current = null;\n }\n if (ctrl.phase === \"success\") {\n if (toastIdRef.current) toast.dismiss(toastIdRef.current);\n if (isMulti) {\n toast.success(`${files.length} file(s) uploaded`, {\n description: formatFileSize(totalProgress.total),\n });\n } else if (ctrl.fileInfo) {\n toast.success(\"Upload complete\", {\n description: formatFileSize(ctrl.fileInfo.size),\n });\n }\n toastIdRef.current = null;\n }\n if (ctrl.phase === \"error\") {\n if (toastIdRef.current) toast.dismiss(toastIdRef.current);\n if (isMulti && files.length > 0) {\n const succeeded = files.filter((f) => f.status === \"success\").length;\n const failed = files.filter((f) => f.status === \"error\").length;\n toast.error(\"Upload finished with errors\", {\n description: `${succeeded} succeeded, ${failed} failed`,\n });\n } else {\n toast.error(\"Upload failed\", {\n description: (\n <span className=\"block [overflow-wrap:anywhere]\">\n {ctrl.error ?? \"Unknown error\"}\n </span>\n ),\n });\n }\n toastIdRef.current = null;\n }\n }\n }\n\n // Progress toast (updated on each progress tick)\n useEffect(() => {\n if (!enabled || ctrl.phase !== \"uploading\") return;\n const id = toastIdRef.current ?? `upload-${Date.now()}`;\n toastIdRef.current = id;\n if (isMulti) {\n const done = files.filter((f) => f.status === \"success\").length;\n toast.loading(`Uploading... ${done}/${files.length}`, {\n id,\n description: `${formatFileSize(totalProgress.loaded)} / ${formatFileSize(totalProgress.total)} (${totalProgress.percent}%)`,\n cancel: { label: \"Cancel\", onClick: () => ctrl.cancel() },\n });\n } else if (ctrl.fileInfo) {\n toast.loading(\"Uploading...\", {\n id,\n description: `${formatFileSize(progress.loaded)} / ${formatFileSize(ctrl.fileInfo.size)} (${progress.percent}%)`,\n cancel: { label: \"Cancel\", onClick: () => ctrl.cancel() },\n });\n }\n }, [\n enabled,\n ctrl.phase,\n isMulti,\n progress.loaded,\n progress.percent,\n totalProgress.loaded,\n totalProgress.total,\n totalProgress.percent,\n ctrl.fileInfo,\n files,\n ctrl.cancel,\n ]);\n}\n","\"use client\";\n\nimport { useRef, useState } from \"react\";\nimport { UploadIcon } from \"lucide-react\";\nimport {\n useUploadControls,\n useMultiUploadControls,\n type UseUploadControlsOptions,\n type UseMultiUploadControlsOptions,\n type UploadProgress,\n type MultiUploadFileState,\n} from \"@better-s3/react\";\nimport { cn } from \"@/lib/utils\";\nimport { Button } from \"@/components/ui/button\";\nimport {\n Tooltip,\n TooltipContent,\n TooltipProvider,\n TooltipTrigger,\n} from \"@/components/ui/tooltip\";\nimport { UploadStatusBlock } from \"@/components/upload/upload-status-block\";\nimport { useUploadToast, type UploadToastCtrl } from \"@/hooks/use-upload-toast\";\n\nconst EMPTY_PROGRESS: UploadProgress = { loaded: 0, total: 0, percent: 0 };\nconst EMPTY_FILES: MultiUploadFileState[] = [];\n\nexport type UploadButtonProps = (\n | UseUploadControlsOptions\n | UseMultiUploadControlsOptions\n) & {\n className?: string;\n label?: string;\n disabled?: boolean;\n tooltipText?: string;\n /** Enable sonner toasts (default: `true`) */\n toast?: boolean;\n /** Show inline status below the button (default: `true`) */\n showStatus?: boolean;\n};\n\nexport function UploadButton({\n className,\n label,\n disabled,\n tooltipText,\n toast: enableToast = true,\n showStatus = true,\n ...options\n}: UploadButtonProps) {\n const isMulti =\n ((options as UseMultiUploadControlsOptions).maxFiles ?? 1) > 1;\n\n // Both hooks must be called unconditionally (React rules of hooks).\n // Only the active mode's output is used.\n const single = useUploadControls(options as UseUploadControlsOptions);\n const multi = useMultiUploadControls(\n options as UseMultiUploadControlsOptions,\n );\n\n const ctrl: UploadToastCtrl = isMulti\n ? {\n mode: \"multi\",\n phase: multi.phase,\n files: multi.files,\n totalProgress: multi.totalProgress,\n error: multi.error,\n cancel: multi.cancel,\n }\n : {\n mode: \"single\",\n phase: single.phase,\n fileInfo: single.fileInfo,\n progress: single.progress,\n error: single.error,\n cancel: single.cancel,\n };\n\n const isDisabled =\n disabled || (isMulti ? multi.isUploading : single.isUploading);\n\n useUploadToast(ctrl, enableToast);\n\n const status = showStatus ? (\n isMulti ? (\n <UploadStatusBlock\n mode=\"multi\"\n phase={multi.phase}\n files={multi.files ?? EMPTY_FILES}\n totalProgress={multi.totalProgress ?? EMPTY_PROGRESS}\n error={multi.error}\n onCancel={multi.cancel}\n />\n ) : (\n <UploadStatusBlock\n mode=\"single\"\n phase={single.phase}\n progress={single.progress}\n error={single.error}\n fileInfo={single.fileInfo}\n onCancel={single.cancel}\n />\n )\n ) : null;\n\n const openFilePicker = isMulti ? multi.openFilePicker : single.openFilePicker;\n const inputProps = isMulti ? multi.inputProps : single.inputProps;\n\n const buttonLabel = label ?? (isMulti ? \"Upload files\" : \"Upload file\");\n\n const button = (\n <Button size=\"default\" disabled={isDisabled} onClick={openFilePicker}>\n <UploadIcon data-icon=\"inline-start\" />\n {buttonLabel}\n </Button>\n );\n\n return (\n <div className={cn(\"inline-flex flex-col gap-2\", className)}>\n <div className=\"inline-flex items-center gap-2\">\n <input {...inputProps} />\n {tooltipText ? (\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger render={button} />\n <TooltipContent>{tooltipText}</TooltipContent>\n </Tooltip>\n </TooltipProvider>\n ) : (\n button\n )}\n </div>\n {status}\n </div>\n );\n}\n","\"use client\";\n\nimport { UploadIcon } from \"lucide-react\";\nimport {\n useUploadControls,\n useMultiUploadControls,\n type UseUploadControlsOptions,\n type UseMultiUploadControlsOptions,\n type UploadProgress,\n type MultiUploadFileState,\n} from \"@better-s3/react\";\nimport { cn } from \"@/lib/utils\";\nimport { UploadStatusBlock } from \"@/components/upload/upload-status-block\";\nimport { useUploadToast, type UploadToastCtrl } from \"@/hooks/use-upload-toast\";\n\nconst EMPTY_PROGRESS: UploadProgress = { loaded: 0, total: 0, percent: 0 };\nconst EMPTY_FILES: MultiUploadFileState[] = [];\n\nexport type UploadDropzoneProps = (\n | UseUploadControlsOptions\n | UseMultiUploadControlsOptions\n) & {\n className?: string;\n label?: string;\n disabled?: boolean;\n /** Enable sonner toasts (default: `true`) */\n toast?: boolean;\n /** Show inline status inside the dropzone (default: `true`) */\n showStatus?: boolean;\n};\n\nexport function UploadDropzone({\n className,\n label,\n disabled,\n toast: enableToast = true,\n showStatus = true,\n ...options\n}: UploadDropzoneProps) {\n const isMulti =\n ((options as UseMultiUploadControlsOptions).maxFiles ?? 1) > 1;\n\n // Both hooks must be called unconditionally (React rules of hooks).\n const single = useUploadControls(options as UseUploadControlsOptions);\n const multi = useMultiUploadControls(\n options as UseMultiUploadControlsOptions,\n );\n\n const ctrl: UploadToastCtrl = isMulti\n ? {\n mode: \"multi\",\n phase: multi.phase,\n files: multi.files,\n totalProgress: multi.totalProgress,\n error: multi.error,\n cancel: multi.cancel,\n }\n : {\n mode: \"single\",\n phase: single.phase,\n fileInfo: single.fileInfo,\n progress: single.progress,\n error: single.error,\n cancel: single.cancel,\n };\n\n const isDisabled =\n disabled || (isMulti ? multi.isUploading : single.isUploading);\n const openFilePicker = isMulti ? multi.openFilePicker : single.openFilePicker;\n const dropHandlers = isMulti ? multi.dropHandlers : single.dropHandlers;\n const inputProps = isMulti ? multi.inputProps : single.inputProps;\n\n useUploadToast(ctrl, enableToast);\n\n const status = showStatus ? (\n isMulti ? (\n <UploadStatusBlock\n mode=\"multi\"\n phase={multi.phase}\n files={multi.files ?? EMPTY_FILES}\n totalProgress={multi.totalProgress ?? EMPTY_PROGRESS}\n error={multi.error}\n onCancel={multi.cancel}\n />\n ) : (\n <UploadStatusBlock\n mode=\"single\"\n phase={single.phase}\n progress={single.progress}\n error={single.error}\n fileInfo={single.fileInfo}\n onCancel={single.cancel}\n />\n )\n ) : null;\n\n return (\n <div\n className={cn(\n \"flex flex-col items-center justify-center gap-3 rounded-lg border-2 border-dashed p-6 text-center transition-colors\",\n isDisabled\n ? \"cursor-not-allowed border-muted-foreground/25\"\n : \"cursor-pointer border-muted-foreground/25 hover:border-primary/50\",\n className,\n )}\n onClick={isDisabled ? undefined : openFilePicker}\n {...(isDisabled ? {} : dropHandlers)}>\n <input {...inputProps} />\n <UploadIcon\n className={cn(\n \"size-6 text-muted-foreground\",\n isDisabled && \"opacity-50\",\n )}\n />\n <p\n className={cn(\n \"text-sm text-muted-foreground\",\n isDisabled && \"opacity-50\",\n )}>\n {label ??\n (isMulti\n ? \"Click or drag & drop files to upload\"\n : \"Click or drag & drop to upload\")}\n </p>\n {status && <div className=\"w-full text-left\">{status}</div>}\n </div>\n );\n}\n\n\n","\"use client\";\n\nimport { toast } from \"sonner\";\nimport { formatFileSize, truncateFilename } from \"@better-s3/react\";\n\nexport type DownloadToastOptions = {\n enabled?: boolean;\n objectKey: string;\n fileName?: string;\n fileSize?: number;\n};\n\nexport function useDownloadToast({\n enabled = true,\n objectKey,\n fileName,\n fileSize,\n}: DownloadToastOptions) {\n const displayName = fileName ?? objectKey.split(\"/\").pop() ?? objectKey;\n\n const errorNode = (error: unknown) => (\n <span className=\"block [overflow-wrap:anywhere]\">\n {error instanceof Error ? error.message : \"Unknown error\"}\n </span>\n );\n\n const onInitiated = () => {\n if (enabled) toast.success(\"Download started\");\n };\n\n const onSuccess = (_key: string, actualFileName: string) => {\n if (!enabled) return;\n toast.dismiss(`dl-${objectKey}`);\n toast.success(\"Download complete\", {\n description: (\n <span className=\"block\">\n {truncateFilename(actualFileName)}\n {fileSize != null ? ` · ${formatFileSize(fileSize)}` : \"\"}\n </span>\n ),\n });\n };\n\n const onError = (_key: string, error: unknown) => {\n if (!enabled) return;\n toast.dismiss(`dl-${objectKey}`);\n toast.error(\"Download failed\", { description: errorNode(error) });\n };\n\n const onErrorWithPhase = (_key: string, error: unknown, _phase: string) => {\n if (!enabled) return;\n toast.dismiss(`dl-${objectKey}`);\n toast.error(\"Download failed\", { description: errorNode(error) });\n };\n\n const onCancel = (_key: string) => {\n if (!enabled) return;\n toast.dismiss(`dl-${objectKey}`);\n toast.info(\"Download cancelled\", {\n description: <span>{truncateFilename(displayName)}</span>,\n });\n };\n\n return { onInitiated, onSuccess, onError, onErrorWithPhase, onCancel };\n}\n","\"use client\";\n\nimport { AlertCircleIcon, DownloadIcon, LoaderIcon } from \"lucide-react\";\nimport { cn } from \"@/lib/utils\";\nimport type { S3Api } from \"@better-s3/react\";\nimport { useDownload } from \"@better-s3/react\";\nimport { Button } from \"@/components/ui/button\";\nimport { useDownloadToast } from \"@/hooks/use-download-toast\";\n\ntype DownloadButtonProps = {\n /** S3Api client. Optional when an `<S3Provider>` is present in the tree. */\n api?: S3Api;\n objectKey: string;\n fileName?: string;\n label?: string;\n className?: string;\n disabled?: boolean;\n /** Enable sonner toasts (default: `true`) */\n toast?: boolean;\n /** Show inline error status below the button (default: `true`) */\n showStatus?: boolean;\n};\n\nexport function DownloadButton({\n api,\n objectKey,\n fileName,\n label,\n className,\n disabled,\n toast: enableToast = true,\n showStatus = true,\n}: DownloadButtonProps) {\n const toastHandlers = useDownloadToast({\n enabled: enableToast,\n objectKey,\n fileName,\n });\n\n const dl = useDownload({\n api,\n onInitiated: () => {\n toastHandlers.onInitiated();\n },\n onError: (key, error) => {\n toastHandlers.onError(key, error);\n },\n });\n\n const isPending = dl.phase === \"presigning\";\n\n return (\n <div className={cn(\"inline-flex flex-col gap-1.5\", className)}>\n <Button\n size=\"default\"\n variant=\"outline\"\n disabled={disabled || isPending}\n onClick={() => dl.download(objectKey, fileName)}>\n <span className=\"inline-flex items-center gap-1\">\n {isPending ? (\n <LoaderIcon className=\"animate-spin\" data-icon=\"inline-start\" />\n ) : (\n <DownloadIcon data-icon=\"inline-start\" />\n )}\n {label ?? \"Download\"}\n </span>\n </Button>\n\n {showStatus && dl.phase === \"error\" && (\n <div className=\"flex min-w-0 items-start gap-1.5 text-xs\">\n <AlertCircleIcon className=\"mt-0.5 size-3.5 shrink-0 text-destructive\" />\n <p className=\"min-w-0 [overflow-wrap:anywhere] text-destructive\">\n {dl.error ?? \"Download failed\"}\n </p>\n </div>\n )}\n </div>\n );\n}\n","\"use client\";\n\nimport { DownloadIcon, AlertCircleIcon } from \"lucide-react\";\nimport { cn } from \"@/lib/utils\";\nimport { formatFileSize, formatSpeed, formatEta } from \"@better-s3/react\";\nimport type { S3Api, FetchDownloadHooks } from \"@better-s3/react\";\nimport { useFetchDownload } from \"@better-s3/react\";\nimport { Button } from \"@/components/ui/button\";\nimport {\n Tooltip,\n TooltipContent,\n TooltipProvider,\n TooltipTrigger,\n} from \"@/components/ui/tooltip\";\nimport { useDownloadToast } from \"@/hooks/use-download-toast\";\n\ntype ProgressDownloadButtonProps = FetchDownloadHooks & {\n /** S3Api client. Optional when an `<S3Provider>` is present in the tree. */\n api?: S3Api;\n objectKey: string;\n fileName?: string;\n fileSize?: number;\n /** Target bucket (overrides server default) */\n bucket?: string;\n label?: string;\n className?: string;\n fillClassName?: string;\n disabled?: boolean;\n tooltipText?: string;\n /** Enable sonner toasts (default: `true`) */\n toast?: boolean;\n /** Show inline error status below the button (default: `true`) */\n showStatus?: boolean;\n};\n\nexport function ProgressDownloadButton({\n api,\n objectKey,\n fileName,\n fileSize,\n bucket,\n label,\n className,\n fillClassName,\n disabled,\n tooltipText = \"Download file\",\n toast: enableToast = true,\n showStatus = true,\n beforeDownload,\n onDownloadStart,\n onProgress,\n onSuccess,\n onError,\n onCancel,\n}: ProgressDownloadButtonProps) {\n const toastHandlers = useDownloadToast({\n enabled: enableToast,\n objectKey,\n fileName,\n fileSize,\n });\n\n const dl = useFetchDownload({\n api,\n bucket,\n beforeDownload,\n onDownloadStart,\n onProgress,\n onSuccess: (key, actualFileName) => {\n toastHandlers.onSuccess(key, actualFileName);\n onSuccess?.(key, actualFileName);\n },\n onError: (key, error, phase) => {\n toastHandlers.onErrorWithPhase(key, error, phase);\n onError?.(key, error, phase);\n },\n onCancel: (key) => {\n toastHandlers.onCancel(key);\n onCancel?.(key);\n },\n });\n\n const isDownloading = dl.phase === \"downloading\" || dl.phase === \"presigning\";\n\n const eta =\n dl.phase === \"downloading\" && dl.progress.speed && dl.progress.total\n ? formatEta(dl.progress.total - dl.progress.loaded, dl.progress.speed)\n : null;\n\n const handleClick = () => {\n if (isDownloading) {\n dl.cancel();\n return;\n }\n dl.download(objectKey, fileName);\n };\n\n return (\n <div className={cn(\"inline-flex flex-col gap-1.5\", className)}>\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger\n render={\n <Button\n size=\"default\"\n variant=\"outline\"\n disabled={disabled}\n className={cn(\"relative min-w-24 overflow-hidden\")}\n onClick={handleClick}\n />\n }>\n {isDownloading && (\n <span\n className={cn(\n \"absolute inset-0 bg-primary/15 transition-[width] duration-200\",\n fillClassName,\n )}\n style={{ width: `${dl.progress.percent}%` }}\n />\n )}\n <span className=\"relative z-10 inline-flex items-center gap-1\">\n <DownloadIcon data-icon=\"inline-start\" />\n {isDownloading\n ? formatFileSize(dl.progress.loaded)\n : (label ?? \"Download\")}\n </span>\n </TooltipTrigger>\n <TooltipContent>\n {isDownloading ? \"Cancel download\" : tooltipText}\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n\n {showStatus && dl.phase === \"downloading\" && dl.progress.loaded > 0 && (\n <p className=\"text-xs tabular-nums text-muted-foreground\">\n {formatFileSize(dl.progress.loaded)}\n {dl.progress.total > 0 && (\n <span className=\"text-muted-foreground/50\">\n {\" \"}\n / {formatFileSize(dl.progress.total)}\n </span>\n )}\n {dl.progress.speed ? (\n <span> · {formatSpeed(dl.progress.speed)}</span>\n ) : null}\n {eta ? (\n <span className=\"text-muted-foreground/50\"> · in {eta}</span>\n ) : null}\n </p>\n )}\n\n {showStatus && dl.phase === \"error\" && (\n <div className=\"flex min-w-0 items-start gap-1.5 text-xs\">\n <AlertCircleIcon className=\"mt-0.5 size-3.5 shrink-0 text-destructive\" />\n <p className=\"min-w-0 [overflow-wrap:anywhere] text-destructive\">\n {dl.error ?? \"Download failed\"}\n </p>\n </div>\n )}\n </div>\n );\n}\n","\"use client\";\n\nimport * as React from \"react\";\nimport { AlertDialog as AlertDialogPrimitive } from \"@base-ui/react/alert-dialog\";\n\nimport { cn } from \"@/lib/utils\";\nimport { Button } from \"@/components/ui/button\";\n\nfunction AlertDialog({ ...props }: AlertDialogPrimitive.Root.Props) {\n return <AlertDialogPrimitive.Root data-slot=\"alert-dialog\" {...props} />;\n}\n\nfunction AlertDialogTrigger({ ...props }: AlertDialogPrimitive.Trigger.Props) {\n return (\n <AlertDialogPrimitive.Trigger data-slot=\"alert-dialog-trigger\" {...props} />\n );\n}\n\nfunction AlertDialogPortal({ ...props }: AlertDialogPrimitive.Portal.Props) {\n return (\n <AlertDialogPrimitive.Portal data-slot=\"alert-dialog-portal\" {...props} />\n );\n}\n\nfunction AlertDialogOverlay({\n className,\n ...props\n}: AlertDialogPrimitive.Backdrop.Props) {\n return (\n <AlertDialogPrimitive.Backdrop\n data-slot=\"alert-dialog-overlay\"\n className={cn(\n \"fixed inset-0 isolate z-50 bg-black/80 duration-100 supports-backdrop-filter:backdrop-blur-xs data-open:animate-in data-open:fade-in-0 data-closed:animate-out data-closed:fade-out-0\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction AlertDialogContent({\n className,\n size = \"default\",\n ...props\n}: AlertDialogPrimitive.Popup.Props & {\n size?: \"default\" | \"sm\";\n}) {\n return (\n <AlertDialogPortal>\n <AlertDialogOverlay />\n <AlertDialogPrimitive.Popup\n data-slot=\"alert-dialog-content\"\n data-size={size}\n className={cn(\n \"group/alert-dialog-content fixed top-1/2 start-1/2 z-50 grid w-full -translate-x-1/2 rtl:translate-x-1/2 -translate-y-1/2 gap-3 rounded-xl bg-popover p-4 text-popover-foreground ring-1 ring-foreground/10 duration-100 outline-none data-[size=default]:max-w-xs data-[size=sm]:max-w-64 data-[size=default]:sm:max-w-sm data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95\",\n className,\n )}\n {...props}\n />\n </AlertDialogPortal>\n );\n}\n\nfunction AlertDialogHeader({\n className,\n ...props\n}: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"alert-dialog-header\"\n className={cn(\n \"grid grid-rows-[auto_1fr] place-items-center gap-1 text-center has-data-[slot=alert-dialog-media]:grid-rows-[auto_auto_1fr] has-data-[slot=alert-dialog-media]:gap-x-4 sm:group-data-[size=default]/alert-dialog-content:place-items-start sm:group-data-[size=default]/alert-dialog-content:text-start sm:group-data-[size=default]/alert-dialog-content:has-data-[slot=alert-dialog-media]:grid-rows-[auto_1fr]\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction AlertDialogFooter({\n className,\n ...props\n}: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"alert-dialog-footer\"\n className={cn(\n \"flex flex-col-reverse gap-2 group-data-[size=sm]/alert-dialog-content:grid group-data-[size=sm]/alert-dialog-content:grid-cols-2 sm:flex-row sm:justify-end\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction AlertDialogMedia({\n className,\n ...props\n}: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"alert-dialog-media\"\n className={cn(\n \"mb-2 inline-flex size-8 items-center justify-center rounded-md bg-muted sm:group-data-[size=default]/alert-dialog-content:row-span-2 *:[svg:not([class*='size-'])]:size-4\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction AlertDialogTitle({\n className,\n ...props\n}: React.ComponentProps<typeof AlertDialogPrimitive.Title>) {\n return (\n <AlertDialogPrimitive.Title\n data-slot=\"alert-dialog-title\"\n className={cn(\n \"font-heading text-sm font-medium sm:group-data-[size=default]/alert-dialog-content:group-has-data-[slot=alert-dialog-media]/alert-dialog-content:col-start-2\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction AlertDialogDescription({\n className,\n ...props\n}: React.ComponentProps<typeof AlertDialogPrimitive.Description>) {\n return (\n <AlertDialogPrimitive.Description\n data-slot=\"alert-dialog-description\"\n className={cn(\n \"text-xs/relaxed text-balance text-muted-foreground md:text-pretty *:[a]:underline *:[a]:underline-offset-3 *:[a]:hover:text-foreground\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction AlertDialogAction({\n className,\n ...props\n}: React.ComponentProps<typeof Button>) {\n return (\n <Button\n data-slot=\"alert-dialog-action\"\n className={cn(className)}\n {...props}\n />\n );\n}\n\nfunction AlertDialogCancel({\n className,\n variant = \"outline\",\n size = \"default\",\n ...props\n}: AlertDialogPrimitive.Close.Props &\n Pick<React.ComponentProps<typeof Button>, \"variant\" | \"size\">) {\n return (\n <AlertDialogPrimitive.Close\n data-slot=\"alert-dialog-cancel\"\n className={cn(className)}\n render={<Button variant={variant} size={size} />}\n {...props}\n />\n );\n}\n\nexport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogMedia,\n AlertDialogOverlay,\n AlertDialogPortal,\n AlertDialogTitle,\n AlertDialogTrigger,\n};\n","\"use client\";\n\nimport { toast } from \"sonner\";\nimport { truncateFilename } from \"@better-s3/react\";\n\nexport type DeleteToastOptions = {\n enabled?: boolean;\n displayName: string;\n};\n\nexport function useDeleteToast({\n enabled = true,\n displayName,\n}: DeleteToastOptions) {\n const onSuccess = (_key: string) => {\n if (!enabled) return;\n toast.success(\"File deleted\", {\n description: <span>{truncateFilename(displayName)}</span>,\n });\n };\n\n const onError = (_key: string, error: unknown) => {\n if (!enabled) return;\n toast.error(\"Delete failed\", {\n description: (\n <span className=\"block [overflow-wrap:anywhere]\">\n {error instanceof Error ? error.message : \"Unknown error\"}\n </span>\n ),\n });\n };\n\n return { onSuccess, onError };\n}\n","\"use client\";\n\nimport {\n Trash2Icon,\n LoaderIcon,\n AlertCircleIcon,\n CheckCircle2Icon,\n} from \"lucide-react\";\nimport { cn } from \"@/lib/utils\";\nimport { formatFileSize, truncateFilename } from \"@better-s3/react\";\nimport type { S3Api, DeleteHooks } from \"@better-s3/react\";\nimport { useDelete } from \"@better-s3/react\";\nimport { Button } from \"@/components/ui/button\";\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogMedia,\n AlertDialogTitle,\n AlertDialogTrigger,\n} from \"@/components/ui/alert-dialog\";\nimport {\n Tooltip,\n TooltipContent,\n TooltipProvider,\n TooltipTrigger,\n} from \"@/components/ui/tooltip\";\nimport { useDeleteToast } from \"@/hooks/use-delete-toast\";\n\ntype DeleteButtonProps = DeleteHooks & {\n /** S3Api client. Optional when an `<S3Provider>` is present in the tree. */\n api?: S3Api;\n objectKey: string;\n fileName?: string;\n fileSize?: number;\n /** Target bucket (overrides server default) */\n bucket?: string;\n label?: string;\n className?: string;\n disabled?: boolean;\n tooltipText?: string;\n /** Enable sonner toasts (default: `true`) */\n toast?: boolean;\n /** Show inline error status below the button (default: `true`) */\n showStatus?: boolean;\n confirmTitle?: string;\n confirmDescription?: string;\n};\n\nexport function DeleteButton({\n api,\n objectKey,\n fileName,\n fileSize,\n bucket,\n label,\n className,\n disabled,\n tooltipText = \"Delete file\",\n toast: enableToast = true,\n showStatus = true,\n confirmTitle = \"Delete file?\",\n confirmDescription,\n beforeDelete,\n onDeleteStart,\n onSuccess,\n onError,\n}: DeleteButtonProps) {\n const displayName = fileName ?? objectKey.split(\"/\").pop() ?? objectKey;\n const toastHandlers = useDeleteToast({\n enabled: enableToast,\n displayName,\n });\n\n const del = useDelete({\n api,\n bucket,\n beforeDelete,\n onDeleteStart,\n onSuccess: (key) => {\n toastHandlers.onSuccess(key);\n onSuccess?.(key);\n },\n onError: (key, error, phase) => {\n toastHandlers.onError(key, error);\n onError?.(key, error, phase);\n },\n });\n\n const isDeleting = del.phase === \"deleting\";\n const isDisabled = disabled || isDeleting;\n\n const description = confirmDescription ?? (\n <>\n {\"Are you sure you want to delete \"}\n <span className=\"font-medium inline-block align-bottom\">\n “{truncateFilename(displayName)}”\n </span>\n {fileSize != null ? ` (${formatFileSize(fileSize)})` : \"\"}\n {\"? This action cannot be undone.\"}\n </>\n );\n\n return (\n <div className={cn(\"inline-flex flex-col gap-1.5\", className)}>\n <div className=\"inline-flex items-center gap-2\">\n <AlertDialog\n open={del.phase === \"confirming\"}\n onOpenChange={(open) => {\n if (!open) del.cancelDelete();\n }}>\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger\n render={\n <AlertDialogTrigger\n disabled={isDisabled}\n onClick={() => del.requestDelete(objectKey)}\n render={\n <Button\n size=\"default\"\n variant=\"destructive\"\n disabled={isDisabled}\n />\n }\n />\n }>\n {isDeleting ? (\n <LoaderIcon\n className=\"animate-spin\"\n data-icon=\"inline-start\"\n />\n ) : (\n <Trash2Icon data-icon=\"inline-start\" />\n )}\n {label ?? \"Delete\"}\n </TooltipTrigger>\n <TooltipContent>{tooltipText}</TooltipContent>\n </Tooltip>\n </TooltipProvider>\n\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogMedia>\n <Trash2Icon />\n </AlertDialogMedia>\n <AlertDialogTitle>{confirmTitle}</AlertDialogTitle>\n <AlertDialogDescription className=\"[overflow-wrap:anywhere]\">\n {description}\n </AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel>Cancel</AlertDialogCancel>\n <AlertDialogAction\n variant=\"destructive\"\n onClick={() => del.confirmDelete()}>\n Delete\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n </div>\n\n {showStatus && del.phase === \"success\" && (\n <div className=\"flex min-w-0 items-center gap-1.5 text-xs\">\n <CheckCircle2Icon className=\"size-3.5 shrink-0 text-green-600\" />\n <p className=\"min-w-0 [overflow-wrap:anywhere] text-green-600\">\n “{truncateFilename(displayName)}” deleted\n </p>\n </div>\n )}\n\n {showStatus && del.phase === \"error\" && (\n <div className=\"flex min-w-0 items-start gap-1.5 text-xs\">\n <AlertCircleIcon className=\"mt-0.5 size-3.5 shrink-0 text-destructive\" />\n <p className=\"min-w-0 [overflow-wrap:anywhere] text-destructive\">\n {del.error ?? \"Delete failed\"}\n </p>\n </div>\n )}\n </div>\n );\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@better-s3/ui",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.1046.0",
|
|
4
4
|
"description": "Pre-built React UI components for S3 file upload, download, and delete",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"s3",
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"styles.css"
|
|
37
37
|
],
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@better-s3/react": "3.
|
|
39
|
+
"@better-s3/react": "3.1046.0"
|
|
40
40
|
},
|
|
41
41
|
"peerDependencies": {
|
|
42
42
|
"@base-ui/react": ">=1.0.0",
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
"lucide-react": "^1.14.0",
|
|
57
57
|
"react": "^19.2.6",
|
|
58
58
|
"sonner": "^2.0.7",
|
|
59
|
-
"tailwind-merge": "^3.
|
|
59
|
+
"tailwind-merge": "^3.6.0",
|
|
60
60
|
"tsc-alias": "^1.8.17",
|
|
61
61
|
"tsup": "^8.5.1",
|
|
62
62
|
"typescript": "^6.0.3"
|