@better-s3/ui 3.1045.1 → 3.1045.2
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 +21 -0
- package/dist/components/download/download-button.d.ts +15 -0
- package/dist/components/download/progress-download-button.d.ts +20 -0
- package/dist/components/ui/alert-dialog.d.ts +18 -0
- package/dist/components/ui/button.d.ts +8 -0
- package/dist/components/ui/circle-progress.d.ts +5 -0
- package/dist/components/ui/progress.d.ts +7 -0
- package/dist/components/ui/tooltip.d.ts +6 -0
- package/dist/components/upload/multi-upload-status.d.ts +8 -0
- package/dist/components/upload/upload-button.d.ts +12 -0
- package/dist/components/upload/upload-dropzone.d.ts +11 -0
- package/dist/components/upload/upload-status.d.ts +11 -0
- package/dist/hooks/use-delete-toast.d.ts +8 -0
- package/dist/hooks/use-download-toast.d.ts +13 -0
- package/dist/hooks/use-upload-toast.d.ts +6 -0
- package/dist/index.d.ts +7 -7
- package/dist/index.js +32 -31
- package/dist/index.js.map +1 -1
- package/dist/lib/utils.d.ts +2 -0
- package/package.json +6 -3
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { S3Api, DeleteHooks } from "@better-s3/react";
|
|
2
|
+
type DeleteButtonProps = DeleteHooks & {
|
|
3
|
+
api: S3Api;
|
|
4
|
+
objectKey: string;
|
|
5
|
+
fileName?: string;
|
|
6
|
+
fileSize?: number;
|
|
7
|
+
/** Target bucket (overrides server default) */
|
|
8
|
+
bucket?: string;
|
|
9
|
+
label?: string;
|
|
10
|
+
className?: string;
|
|
11
|
+
disabled?: boolean;
|
|
12
|
+
tooltipText?: string;
|
|
13
|
+
/** Enable sonner toasts (default: `true`) */
|
|
14
|
+
toast?: boolean;
|
|
15
|
+
/** Show inline error status below the button (default: `true`) */
|
|
16
|
+
showStatus?: boolean;
|
|
17
|
+
confirmTitle?: string;
|
|
18
|
+
confirmDescription?: string;
|
|
19
|
+
};
|
|
20
|
+
export declare function DeleteButton({ api, objectKey, fileName, fileSize, bucket, label, className, disabled, tooltipText, toast: enableToast, showStatus, confirmTitle, confirmDescription, beforeDelete, onDeleteStart, onSuccess, onError, }: DeleteButtonProps): import("react/jsx-runtime").JSX.Element;
|
|
21
|
+
export {};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { S3Api } from "@better-s3/react";
|
|
2
|
+
type DownloadButtonProps = {
|
|
3
|
+
api: S3Api;
|
|
4
|
+
objectKey: string;
|
|
5
|
+
fileName?: string;
|
|
6
|
+
label?: string;
|
|
7
|
+
className?: string;
|
|
8
|
+
disabled?: boolean;
|
|
9
|
+
/** Enable sonner toasts (default: `true`) */
|
|
10
|
+
toast?: boolean;
|
|
11
|
+
/** Show inline error status below the button (default: `true`) */
|
|
12
|
+
showStatus?: boolean;
|
|
13
|
+
};
|
|
14
|
+
export declare function DownloadButton({ api, objectKey, fileName, label, className, disabled, toast: enableToast, showStatus, }: DownloadButtonProps): import("react/jsx-runtime").JSX.Element;
|
|
15
|
+
export {};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { S3Api, FetchDownloadHooks } from "@better-s3/react";
|
|
2
|
+
type ProgressDownloadButtonProps = FetchDownloadHooks & {
|
|
3
|
+
api: S3Api;
|
|
4
|
+
objectKey: string;
|
|
5
|
+
fileName?: string;
|
|
6
|
+
fileSize?: number;
|
|
7
|
+
/** Target bucket (overrides server default) */
|
|
8
|
+
bucket?: string;
|
|
9
|
+
label?: string;
|
|
10
|
+
className?: string;
|
|
11
|
+
fillClassName?: string;
|
|
12
|
+
disabled?: boolean;
|
|
13
|
+
tooltipText?: string;
|
|
14
|
+
/** Enable sonner toasts (default: `true`) */
|
|
15
|
+
toast?: boolean;
|
|
16
|
+
/** Show inline error status below the button (default: `true`) */
|
|
17
|
+
showStatus?: boolean;
|
|
18
|
+
};
|
|
19
|
+
export declare function ProgressDownloadButton({ api, objectKey, fileName, fileSize, bucket, label, className, fillClassName, disabled, tooltipText, toast: enableToast, showStatus, beforeDownload, onDownloadStart, onProgress, onSuccess, onError, onCancel, }: ProgressDownloadButtonProps): import("react/jsx-runtime").JSX.Element;
|
|
20
|
+
export {};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { AlertDialog as AlertDialogPrimitive } from "@base-ui/react/alert-dialog";
|
|
3
|
+
import { Button } from "../../components/ui/button";
|
|
4
|
+
declare function AlertDialog({ ...props }: AlertDialogPrimitive.Root.Props): import("react/jsx-runtime").JSX.Element;
|
|
5
|
+
declare function AlertDialogTrigger({ ...props }: AlertDialogPrimitive.Trigger.Props): import("react/jsx-runtime").JSX.Element;
|
|
6
|
+
declare function AlertDialogPortal({ ...props }: AlertDialogPrimitive.Portal.Props): import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
declare function AlertDialogOverlay({ className, ...props }: AlertDialogPrimitive.Backdrop.Props): import("react/jsx-runtime").JSX.Element;
|
|
8
|
+
declare function AlertDialogContent({ className, size, ...props }: AlertDialogPrimitive.Popup.Props & {
|
|
9
|
+
size?: "default" | "sm";
|
|
10
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
11
|
+
declare function AlertDialogHeader({ className, ...props }: React.ComponentProps<"div">): import("react/jsx-runtime").JSX.Element;
|
|
12
|
+
declare function AlertDialogFooter({ className, ...props }: React.ComponentProps<"div">): import("react/jsx-runtime").JSX.Element;
|
|
13
|
+
declare function AlertDialogMedia({ className, ...props }: React.ComponentProps<"div">): import("react/jsx-runtime").JSX.Element;
|
|
14
|
+
declare function AlertDialogTitle({ className, ...props }: React.ComponentProps<typeof AlertDialogPrimitive.Title>): import("react/jsx-runtime").JSX.Element;
|
|
15
|
+
declare function AlertDialogDescription({ className, ...props }: React.ComponentProps<typeof AlertDialogPrimitive.Description>): import("react/jsx-runtime").JSX.Element;
|
|
16
|
+
declare function AlertDialogAction({ className, ...props }: React.ComponentProps<typeof Button>): import("react/jsx-runtime").JSX.Element;
|
|
17
|
+
declare function AlertDialogCancel({ className, variant, size, ...props }: AlertDialogPrimitive.Close.Props & Pick<React.ComponentProps<typeof Button>, "variant" | "size">): import("react/jsx-runtime").JSX.Element;
|
|
18
|
+
export { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogMedia, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Button as ButtonPrimitive } from "@base-ui/react/button";
|
|
2
|
+
import { type VariantProps } from "class-variance-authority";
|
|
3
|
+
declare const buttonVariants: (props?: ({
|
|
4
|
+
variant?: "default" | "outline" | "secondary" | "ghost" | "destructive" | "link" | null | undefined;
|
|
5
|
+
size?: "default" | "xs" | "sm" | "lg" | "icon" | "icon-xs" | "icon-sm" | "icon-lg" | null | undefined;
|
|
6
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
7
|
+
declare function Button({ className, variant, size, ...props }: ButtonPrimitive.Props & VariantProps<typeof buttonVariants>): import("react/jsx-runtime").JSX.Element;
|
|
8
|
+
export { Button, buttonVariants };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Progress as ProgressPrimitive } from "@base-ui/react/progress";
|
|
2
|
+
declare function Progress({ className, children, value, ...props }: ProgressPrimitive.Root.Props): import("react/jsx-runtime").JSX.Element;
|
|
3
|
+
declare function ProgressTrack({ className, ...props }: ProgressPrimitive.Track.Props): import("react/jsx-runtime").JSX.Element;
|
|
4
|
+
declare function ProgressIndicator({ className, ...props }: ProgressPrimitive.Indicator.Props): import("react/jsx-runtime").JSX.Element;
|
|
5
|
+
declare function ProgressLabel({ className, ...props }: ProgressPrimitive.Label.Props): import("react/jsx-runtime").JSX.Element;
|
|
6
|
+
declare function ProgressValue({ className, ...props }: ProgressPrimitive.Value.Props): import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export { Progress, ProgressTrack, ProgressIndicator, ProgressLabel, ProgressValue, };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { Tooltip as TooltipPrimitive } from "@base-ui/react/tooltip";
|
|
2
|
+
declare function TooltipProvider({ delay, ...props }: TooltipPrimitive.Provider.Props): import("react/jsx-runtime").JSX.Element;
|
|
3
|
+
declare function Tooltip({ ...props }: TooltipPrimitive.Root.Props): import("react/jsx-runtime").JSX.Element;
|
|
4
|
+
declare function TooltipTrigger({ ...props }: TooltipPrimitive.Trigger.Props): import("react/jsx-runtime").JSX.Element;
|
|
5
|
+
declare function TooltipContent({ className, side, sideOffset, align, alignOffset, children, ...props }: TooltipPrimitive.Popup.Props & Pick<TooltipPrimitive.Positioner.Props, "align" | "alignOffset" | "side" | "sideOffset">): import("react/jsx-runtime").JSX.Element;
|
|
6
|
+
export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { UploadProgress, MultiUploadFileState } from "@better-s3/react";
|
|
2
|
+
export declare function MultiUploadStatus({ phase, files, totalProgress, error, onCancel, }: {
|
|
3
|
+
phase: string;
|
|
4
|
+
files: MultiUploadFileState[];
|
|
5
|
+
totalProgress: UploadProgress;
|
|
6
|
+
error: string | null;
|
|
7
|
+
onCancel?: () => void;
|
|
8
|
+
}): import("react/jsx-runtime").JSX.Element | null;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { UseUploadControlsOptions } from "@better-s3/react";
|
|
2
|
+
export type UploadButtonProps = UseUploadControlsOptions & {
|
|
3
|
+
className?: string;
|
|
4
|
+
label?: string;
|
|
5
|
+
disabled?: boolean;
|
|
6
|
+
tooltipText?: string;
|
|
7
|
+
/** Enable sonner toasts (default: `true`) */
|
|
8
|
+
toast?: boolean;
|
|
9
|
+
/** Show inline status below the button (default: `true`) */
|
|
10
|
+
showStatus?: boolean;
|
|
11
|
+
};
|
|
12
|
+
export declare function UploadButton({ className, label, disabled, tooltipText, toast: enableToast, showStatus, ...options }: UploadButtonProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { UseUploadControlsOptions } from "@better-s3/react";
|
|
2
|
+
export type UploadDropzoneProps = UseUploadControlsOptions & {
|
|
3
|
+
className?: string;
|
|
4
|
+
label?: string;
|
|
5
|
+
disabled?: boolean;
|
|
6
|
+
/** Enable sonner toasts (default: `true`) */
|
|
7
|
+
toast?: boolean;
|
|
8
|
+
/** Show inline status inside the dropzone (default: `true`) */
|
|
9
|
+
showStatus?: boolean;
|
|
10
|
+
};
|
|
11
|
+
export declare function UploadDropzone({ className, label, disabled, toast: enableToast, showStatus, ...options }: UploadDropzoneProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { UploadPhase, UploadProgress } from "@better-s3/react";
|
|
2
|
+
export declare function UploadStatus({ phase, progress, error, fileInfo, onCancel, }: {
|
|
3
|
+
phase: UploadPhase;
|
|
4
|
+
progress: UploadProgress;
|
|
5
|
+
error: string | null;
|
|
6
|
+
fileInfo: {
|
|
7
|
+
name: string;
|
|
8
|
+
size: number;
|
|
9
|
+
} | null;
|
|
10
|
+
onCancel?: () => void;
|
|
11
|
+
}): import("react/jsx-runtime").JSX.Element | null;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export type DeleteToastOptions = {
|
|
2
|
+
enabled?: boolean;
|
|
3
|
+
displayName: string;
|
|
4
|
+
};
|
|
5
|
+
export declare function useDeleteToast({ enabled, displayName, }: DeleteToastOptions): {
|
|
6
|
+
onSuccess: (_key: string) => void;
|
|
7
|
+
onError: (_key: string, error: unknown) => void;
|
|
8
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export type DownloadToastOptions = {
|
|
2
|
+
enabled?: boolean;
|
|
3
|
+
objectKey: string;
|
|
4
|
+
fileName?: string;
|
|
5
|
+
fileSize?: number;
|
|
6
|
+
};
|
|
7
|
+
export declare function useDownloadToast({ enabled, objectKey, fileName, fileSize, }: DownloadToastOptions): {
|
|
8
|
+
onInitiated: () => void;
|
|
9
|
+
onSuccess: (_key: string, actualFileName: string) => void;
|
|
10
|
+
onError: (_key: string, error: unknown) => void;
|
|
11
|
+
onErrorWithPhase: (_key: string, error: unknown, _phase: string) => void;
|
|
12
|
+
onCancel: (_key: string) => void;
|
|
13
|
+
};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { UseUploadControlsReturn } from "@better-s3/react";
|
|
2
|
+
/**
|
|
3
|
+
* Drives sonner toasts for upload progress/success/error.
|
|
4
|
+
* Shared between UploadButton and UploadDropzone.
|
|
5
|
+
*/
|
|
6
|
+
export declare function useUploadToast(ctrl: Pick<UseUploadControlsReturn, "mode" | "phase" | "fileInfo" | "progress" | "files" | "totalProgress" | "error" | "cancel">, enabled: boolean): void;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export { UploadButton, UploadButtonProps } from
|
|
2
|
-
export { UploadDropzone, UploadDropzoneProps } from
|
|
3
|
-
export { UploadStatus } from
|
|
4
|
-
export { MultiUploadStatus } from
|
|
5
|
-
export { DownloadButton } from
|
|
6
|
-
export { ProgressDownloadButton } from
|
|
7
|
-
export { DeleteButton } from
|
|
1
|
+
export { UploadButton, type UploadButtonProps, } from "./components/upload/upload-button";
|
|
2
|
+
export { UploadDropzone, type UploadDropzoneProps, } from "./components/upload/upload-dropzone";
|
|
3
|
+
export { UploadStatus } from "./components/upload/upload-status";
|
|
4
|
+
export { MultiUploadStatus } from "./components/upload/multi-upload-status";
|
|
5
|
+
export { DownloadButton } from "./components/download/download-button";
|
|
6
|
+
export { ProgressDownloadButton } from "./components/download/progress-download-button";
|
|
7
|
+
export { DeleteButton } from "./components/delete/delete-button";
|
package/dist/index.js
CHANGED
|
@@ -4,7 +4,7 @@ import { clsx } from 'clsx';
|
|
|
4
4
|
import { twMerge } from 'tailwind-merge';
|
|
5
5
|
import { Button as Button$1 } from '@base-ui/react/button';
|
|
6
6
|
import { cva } from 'class-variance-authority';
|
|
7
|
-
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
7
|
+
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
8
8
|
import { Tooltip as Tooltip$1 } from '@base-ui/react/tooltip';
|
|
9
9
|
import { Progress as Progress$1 } from '@base-ui/react/progress';
|
|
10
10
|
import { useRef, useEffect } from 'react';
|
|
@@ -357,13 +357,6 @@ function FileList({ files }) {
|
|
|
357
357
|
f.status === "error" && f.error && /* @__PURE__ */ jsx("span", { className: "truncate [overflow-wrap:anywhere] pl-5 text-destructive", children: f.error })
|
|
358
358
|
] }, f.id)) });
|
|
359
359
|
}
|
|
360
|
-
|
|
361
|
-
// ../../registry/registry/better-s3-ui/lib/truncate-msg.ts
|
|
362
|
-
function truncateMsg(msg, max = 100) {
|
|
363
|
-
return msg.length > max ? msg.slice(0, max) + "..." : msg;
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
// ../../registry/registry/better-s3-ui/hooks/use-upload-toast.ts
|
|
367
360
|
function useUploadToast(ctrl, enabled) {
|
|
368
361
|
const toastIdRef = useRef(null);
|
|
369
362
|
const isMulti = ctrl.mode === "multi";
|
|
@@ -400,7 +393,7 @@ function useUploadToast(ctrl, enabled) {
|
|
|
400
393
|
});
|
|
401
394
|
} else {
|
|
402
395
|
toast.error("Upload failed", {
|
|
403
|
-
description:
|
|
396
|
+
description: /* @__PURE__ */ jsx("span", { className: "block [overflow-wrap:anywhere]", children: ctrl.error ?? "Unknown error" })
|
|
404
397
|
});
|
|
405
398
|
}
|
|
406
399
|
toastIdRef.current = null;
|
|
@@ -571,40 +564,37 @@ function useDownloadToast({
|
|
|
571
564
|
fileName,
|
|
572
565
|
fileSize
|
|
573
566
|
}) {
|
|
574
|
-
const
|
|
575
|
-
const
|
|
576
|
-
fileName ?? objectKey.split("/").pop() ?? objectKey,
|
|
577
|
-
60
|
|
578
|
-
);
|
|
567
|
+
const displayName = fileName ?? objectKey.split("/").pop() ?? objectKey;
|
|
568
|
+
const errorNode = (error) => /* @__PURE__ */ jsx("span", { className: "block [overflow-wrap:anywhere]", children: error instanceof Error ? error.message : "Unknown error" });
|
|
579
569
|
const onInitiated = () => {
|
|
580
570
|
if (enabled) toast.success("Download started");
|
|
581
571
|
};
|
|
582
572
|
const onSuccess = (_key, actualFileName) => {
|
|
583
573
|
if (!enabled) return;
|
|
584
574
|
toast.dismiss(`dl-${objectKey}`);
|
|
585
|
-
const safeFileName = truncateMsg(actualFileName, 60);
|
|
586
575
|
toast.success("Download complete", {
|
|
587
|
-
description:
|
|
576
|
+
description: /* @__PURE__ */ jsxs("span", { className: "block max-w-[50ch] truncate", children: [
|
|
577
|
+
actualFileName,
|
|
578
|
+
fileSize != null ? ` \xB7 ${formatFileSize(fileSize)}` : ""
|
|
579
|
+
] })
|
|
588
580
|
});
|
|
589
581
|
};
|
|
590
582
|
const onError = (_key, error) => {
|
|
591
583
|
if (!enabled) return;
|
|
592
584
|
toast.dismiss(`dl-${objectKey}`);
|
|
593
|
-
toast.error("Download failed", {
|
|
594
|
-
description: buildErrorDescription(error)
|
|
595
|
-
});
|
|
585
|
+
toast.error("Download failed", { description: errorNode(error) });
|
|
596
586
|
};
|
|
597
587
|
const onErrorWithPhase = (_key, error, _phase) => {
|
|
598
588
|
if (!enabled) return;
|
|
599
589
|
toast.dismiss(`dl-${objectKey}`);
|
|
600
|
-
toast.error("Download failed", {
|
|
601
|
-
description: buildErrorDescription(error)
|
|
602
|
-
});
|
|
590
|
+
toast.error("Download failed", { description: errorNode(error) });
|
|
603
591
|
};
|
|
604
592
|
const onCancel = (_key) => {
|
|
605
593
|
if (!enabled) return;
|
|
606
594
|
toast.dismiss(`dl-${objectKey}`);
|
|
607
|
-
toast.info("Download cancelled", {
|
|
595
|
+
toast.info("Download cancelled", {
|
|
596
|
+
description: /* @__PURE__ */ jsx("span", { className: "block max-w-[50ch] truncate", children: displayName })
|
|
597
|
+
});
|
|
608
598
|
};
|
|
609
599
|
return { onInitiated, onSuccess, onError, onErrorWithPhase, onCancel };
|
|
610
600
|
}
|
|
@@ -902,18 +892,20 @@ function AlertDialogCancel({
|
|
|
902
892
|
}
|
|
903
893
|
);
|
|
904
894
|
}
|
|
905
|
-
function useDeleteToast({
|
|
906
|
-
|
|
895
|
+
function useDeleteToast({
|
|
896
|
+
enabled = true,
|
|
897
|
+
displayName
|
|
898
|
+
}) {
|
|
907
899
|
const onSuccess = (_key) => {
|
|
908
900
|
if (!enabled) return;
|
|
909
|
-
toast.success("File deleted", {
|
|
901
|
+
toast.success("File deleted", {
|
|
902
|
+
description: /* @__PURE__ */ jsx("span", { className: "block max-w-[50ch] truncate", children: displayName })
|
|
903
|
+
});
|
|
910
904
|
};
|
|
911
905
|
const onError = (_key, error) => {
|
|
912
906
|
if (!enabled) return;
|
|
913
907
|
toast.error("Delete failed", {
|
|
914
|
-
description:
|
|
915
|
-
error instanceof Error ? error.message : "Unknown error"
|
|
916
|
-
)
|
|
908
|
+
description: /* @__PURE__ */ jsx("span", { className: "block [overflow-wrap:anywhere]", children: error instanceof Error ? error.message : "Unknown error" })
|
|
917
909
|
});
|
|
918
910
|
};
|
|
919
911
|
return { onSuccess, onError };
|
|
@@ -958,7 +950,16 @@ function DeleteButton({
|
|
|
958
950
|
});
|
|
959
951
|
const isDeleting = del.phase === "deleting";
|
|
960
952
|
const isDisabled = disabled || isDeleting;
|
|
961
|
-
const description = confirmDescription ??
|
|
953
|
+
const description = confirmDescription ?? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
954
|
+
"Are you sure you want to delete ",
|
|
955
|
+
/* @__PURE__ */ jsxs("span", { className: "inline-block max-w-[30ch] truncate align-bottom", children: [
|
|
956
|
+
"\u201C",
|
|
957
|
+
displayName,
|
|
958
|
+
"\u201D"
|
|
959
|
+
] }),
|
|
960
|
+
fileSize != null ? ` (${formatFileSize(fileSize)})` : "",
|
|
961
|
+
"? This action cannot be undone."
|
|
962
|
+
] });
|
|
962
963
|
return /* @__PURE__ */ jsxs("div", { className: cn("inline-flex flex-col gap-1.5", className), children: [
|
|
963
964
|
/* @__PURE__ */ jsx("div", { className: "inline-flex items-center gap-2", children: /* @__PURE__ */ jsxs(
|
|
964
965
|
AlertDialog,
|
|
@@ -1026,7 +1027,7 @@ function DeleteButton({
|
|
|
1026
1027
|
/* @__PURE__ */ jsx(CheckCircle2Icon, { className: "size-3.5 shrink-0 text-green-600" }),
|
|
1027
1028
|
/* @__PURE__ */ jsxs("p", { className: "min-w-0 [overflow-wrap:anywhere] text-green-600", children: [
|
|
1028
1029
|
"\u201C",
|
|
1029
|
-
/* @__PURE__ */ jsx("span", { className: "inline-block max-w-[
|
|
1030
|
+
/* @__PURE__ */ jsx("span", { className: "inline-block max-w-[30ch] truncate align-bottom", children: displayName }),
|
|
1030
1031
|
"\u201D deleted"
|
|
1031
1032
|
] })
|
|
1032
1033
|
] }),
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../registry/registry/better-s3-ui/lib/utils.ts","../../../registry/registry/better-s3-ui/components/ui/button.tsx","../../../registry/registry/better-s3-ui/components/ui/tooltip.tsx","../../../registry/registry/better-s3-ui/components/ui/circle-progress.tsx","../../../registry/registry/better-s3-ui/components/upload/upload-status.tsx","../../../registry/registry/better-s3-ui/components/ui/progress.tsx","../../../registry/registry/better-s3-ui/components/upload/multi-upload-status.tsx","../../../registry/registry/better-s3-ui/lib/truncate-msg.ts","../../../registry/registry/better-s3-ui/hooks/use-upload-toast.ts","../../../registry/registry/better-s3-ui/components/upload/upload-button.tsx","../../../registry/registry/better-s3-ui/components/upload/upload-dropzone.tsx","../../../registry/registry/better-s3-ui/hooks/use-download-toast.ts","../../../registry/registry/better-s3-ui/components/download/download-button.tsx","../../../registry/registry/better-s3-ui/components/download/progress-download-button.tsx","../../../registry/registry/better-s3-ui/components/ui/alert-dialog.tsx","../../../registry/registry/better-s3-ui/hooks/use-delete-toast.ts","../../../registry/registry/better-s3-ui/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 \"@/registry/better-s3-ui/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 \"@/registry/better-s3-ui/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 \"@/registry/better-s3-ui/components/ui/button\";\nimport { CircleProgress } from \"@/registry/better-s3-ui/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 \"@/registry/better-s3-ui/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 \"@/registry/better-s3-ui/components/ui/button\";\nimport {\n Progress,\n ProgressLabel,\n ProgressValue,\n} from \"@/registry/better-s3-ui/components/ui/progress\";\nimport { CircleProgress } from \"@/registry/better-s3-ui/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","export function truncateMsg(msg: string, max = 100) {\n return msg.length > max ? msg.slice(0, max) + \"...\" : msg;\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\";\nimport { truncateMsg } from \"@/registry/better-s3-ui/lib/truncate-msg\";\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: truncateMsg(ctrl.error ?? \"Unknown error\"),\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 \"@/registry/better-s3-ui/lib/utils\";\nimport { Button } from \"@/registry/better-s3-ui/components/ui/button\";\nimport {\n Tooltip,\n TooltipContent,\n TooltipProvider,\n TooltipTrigger,\n} from \"@/registry/better-s3-ui/components/ui/tooltip\";\nimport { UploadStatus } from \"@/registry/better-s3-ui/components/upload/upload-status\";\nimport { MultiUploadStatus } from \"@/registry/better-s3-ui/components/upload/multi-upload-status\";\nimport { useUploadToast } from \"@/registry/better-s3-ui/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 \"@/registry/better-s3-ui/lib/utils\";\nimport { UploadStatus } from \"@/registry/better-s3-ui/components/upload/upload-status\";\nimport { MultiUploadStatus } from \"@/registry/better-s3-ui/components/upload/multi-upload-status\";\nimport { useUploadToast } from \"@/registry/better-s3-ui/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\";\nimport { truncateMsg } from \"@/registry/better-s3-ui/lib/truncate-msg\";\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 buildErrorDescription = (error: unknown) =>\n truncateMsg(error instanceof Error ? error.message : \"Unknown error\");\n\n const displayName = truncateMsg(\n fileName ?? objectKey.split(\"/\").pop() ?? objectKey,\n 60,\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 const safeFileName = truncateMsg(actualFileName, 60);\n toast.success(\"Download complete\", {\n description: `${safeFileName}${fileSize != null ? ` · ${formatFileSize(fileSize)}` : \"\"}`,\n });\n };\n\n const onError = (_key: string, error: unknown) => {\n if (!enabled) return;\n toast.dismiss(`dl-${objectKey}`);\n toast.error(\"Download failed\", {\n description: buildErrorDescription(error),\n });\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\", {\n description: buildErrorDescription(error),\n });\n };\n\n const onCancel = (_key: string) => {\n if (!enabled) return;\n toast.dismiss(`dl-${objectKey}`);\n toast.info(\"Download cancelled\", { description: displayName });\n };\n\n return { onInitiated, onSuccess, onError, onErrorWithPhase, onCancel };\n}\n","\"use client\";\n\nimport { AlertCircleIcon, DownloadIcon, LoaderIcon } from \"lucide-react\";\nimport { cn } from \"@/registry/better-s3-ui/lib/utils\";\nimport type { S3Api } from \"@better-s3/react\";\nimport { useDownload } from \"@better-s3/react\";\nimport { Button } from \"@/registry/better-s3-ui/components/ui/button\";\nimport { useDownloadToast } from \"@/registry/better-s3-ui/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 \"@/registry/better-s3-ui/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 \"@/registry/better-s3-ui/components/ui/button\";\nimport {\n Tooltip,\n TooltipContent,\n TooltipProvider,\n TooltipTrigger,\n} from \"@/registry/better-s3-ui/components/ui/tooltip\";\nimport { useDownloadToast } from \"@/registry/better-s3-ui/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 \"@/registry/better-s3-ui/lib/utils\";\nimport { Button } from \"@/registry/better-s3-ui/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 { truncateMsg } from \"@/registry/better-s3-ui/lib/truncate-msg\";\n\nexport type DeleteToastOptions = {\n enabled?: boolean;\n displayName: string;\n};\n\nexport function useDeleteToast({ enabled = true, displayName }: DeleteToastOptions) {\n const safeDisplayName = truncateMsg(displayName, 60);\n\n const onSuccess = (_key: string) => {\n if (!enabled) return;\n toast.success(\"File deleted\", { description: safeDisplayName });\n };\n\n const onError = (_key: string, error: unknown) => {\n if (!enabled) return;\n toast.error(\"Delete failed\", {\n description: truncateMsg(\n error instanceof Error ? error.message : \"Unknown error\",\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 \"@/registry/better-s3-ui/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 \"@/registry/better-s3-ui/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 \"@/registry/better-s3-ui/components/ui/alert-dialog\";\nimport {\n Tooltip,\n TooltipContent,\n TooltipProvider,\n TooltipTrigger,\n} from \"@/registry/better-s3-ui/components/ui/tooltip\";\nimport { useDeleteToast } from \"@/registry/better-s3-ui/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 =\n confirmDescription ??\n `Are you sure you want to delete \"${displayName}\"${fileSize != null ? ` (${formatFileSize(fileSize)})` : \"\"}? This action cannot be undone.`;\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-[14ch] 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/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":";;;;;;;;;;;;;AAGO,SAAS,MAAM,MAAA,EAAsB;AAC1C,EAAA,OAAO,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAC,CAAA;AAC7B;ACEA,IAAM,cAAA,GAAiB,GAAA;AAAA,EACrB,mnBAAA;AAAA,EACA;AAAA,IACE,QAAA,EAAU;AAAA,MACR,OAAA,EAAS;AAAA,QACP,OAAA,EAAS,wDAAA;AAAA,QACT,OAAA,EACE,6HAAA;AAAA,QACF,SAAA,EACE,iIAAA;AAAA,QACF,KAAA,EACE,kHAAA;AAAA,QACF,WAAA,EACE,6NAAA;AAAA,QACF,IAAA,EAAM;AAAA,OACR;AAAA,MACA,IAAA,EAAM;AAAA,QACJ,OAAA,EACE,6IAAA;AAAA,QACF,EAAA,EAAI,wJAAA;AAAA,QACJ,EAAA,EAAI,2IAAA;AAAA,QACJ,EAAA,EAAI,yIAAA;AAAA,QACJ,IAAA,EAAM,+CAAA;AAAA,QACN,SAAA,EAAW,0DAAA;AAAA,QACX,SAAA,EAAW,6CAAA;AAAA,QACX,SAAA,EAAW;AAAA;AACb,KACF;AAAA,IACA,eAAA,EAAiB;AAAA,MACf,OAAA,EAAS,SAAA;AAAA,MACT,IAAA,EAAM;AAAA;AACR;AAEJ,CAAA;AAEA,SAAS,MAAA,CAAO;AAAA,EACd,SAAA;AAAA,EACA,OAAA,GAAU,SAAA;AAAA,EACV,IAAA,GAAO,SAAA;AAAA,EACP,GAAG;AACL,CAAA,EAAgE;AAC9D,EAAA,uBACE,GAAA;AAAA,IAACA,QAAA;AAAA,IAAA;AAAA,MACC,WAAA,EAAU,QAAA;AAAA,MACV,SAAA,EAAW,GAAG,cAAA,CAAe,EAAE,SAAS,IAAA,EAAM,SAAA,EAAW,CAAC,CAAA;AAAA,MACzD,GAAG;AAAA;AAAA,GACN;AAEJ;ACjDA,SAAS,eAAA,CAAgB;AAAA,EACvB,KAAA,GAAQ,CAAA;AAAA,EACR,GAAG;AACL,CAAA,EAAoC;AAClC,EAAA,uBACEC,GAAAA;AAAA,IAACC,SAAA,CAAiB,QAAA;AAAA,IAAjB;AAAA,MACC,WAAA,EAAU,kBAAA;AAAA,MACV,KAAA;AAAA,MACC,GAAG;AAAA;AAAA,GACN;AAEJ;AAEA,SAAS,OAAA,CAAQ,EAAE,GAAG,KAAA,EAAM,EAAgC;AAC1D,EAAA,uBAAOD,IAACC,SAAA,CAAiB,IAAA,EAAjB,EAAsB,WAAA,EAAU,SAAA,EAAW,GAAG,KAAA,EAAO,CAAA;AAC/D;AAEA,SAAS,cAAA,CAAe,EAAE,GAAG,KAAA,EAAM,EAAmC;AACpE,EAAA,uBAAOD,IAACC,SAAA,CAAiB,OAAA,EAAjB,EAAyB,WAAA,EAAU,iBAAA,EAAmB,GAAG,KAAA,EAAO,CAAA;AAC1E;AAEA,SAAS,cAAA,CAAe;AAAA,EACtB,SAAA;AAAA,EACA,IAAA,GAAO,KAAA;AAAA,EACP,UAAA,GAAa,CAAA;AAAA,EACb,KAAA,GAAQ,QAAA;AAAA,EACR,WAAA,GAAc,CAAA;AAAA,EACd,QAAA;AAAA,EACA,GAAG;AACL,CAAA,EAIK;AACH,EAAA,uBACED,GAAAA,CAACC,SAAA,CAAiB,MAAA,EAAjB,EACC,QAAA,kBAAAD,GAAAA;AAAA,IAACC,SAAA,CAAiB,UAAA;AAAA,IAAjB;AAAA,MACC,KAAA;AAAA,MACA,WAAA;AAAA,MACA,IAAA;AAAA,MACA,UAAA;AAAA,MACA,SAAA,EAAU,cAAA;AAAA,MACV,QAAA,kBAAA,IAAA;AAAA,QAACA,SAAA,CAAiB,KAAA;AAAA,QAAjB;AAAA,UACC,WAAA,EAAU,iBAAA;AAAA,UACV,SAAA,EAAW,EAAA;AAAA,YACT,gwBAAA;AAAA,YACA;AAAA,WACF;AAAA,UACC,GAAG,KAAA;AAAA,UACH,QAAA,EAAA;AAAA,YAAA,QAAA;AAAA,4BACDD,GAAAA,CAACC,SAAA,CAAiB,KAAA,EAAjB,EAAuB,WAAU,yhBAAA,EAA0hB;AAAA;AAAA;AAAA;AAC9jB;AAAA,GACF,EACF,CAAA;AAEJ;AC3DO,SAAS,cAAA,CAAe;AAAA,EAC7B,OAAA;AAAA,EACA,IAAA,GAAO,EAAA;AAAA,EACP,WAAA,GAAc;AAChB,CAAA,EAIG;AACD,EAAA,MAAM,CAAA,GAAA,CAAK,OAAO,WAAA,IAAe,CAAA;AACjC,EAAA,MAAM,CAAA,GAAI,CAAA,GAAI,IAAA,CAAK,EAAA,GAAK,CAAA;AACxB,EAAA,MAAM,MAAA,GAAS,CAAA,GAAK,OAAA,GAAU,GAAA,GAAO,CAAA;AACrC,EAAA,uBACEC,KAAC,KAAA,EAAA,EAAI,KAAA,EAAO,MAAM,MAAA,EAAQ,IAAA,EAAM,WAAU,qBAAA,EACxC,QAAA,EAAA;AAAA,oBAAAF,GAAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACC,IAAI,IAAA,GAAO,CAAA;AAAA,QACX,IAAI,IAAA,GAAO,CAAA;AAAA,QACX,CAAA;AAAA,QACA,IAAA,EAAK,MAAA;AAAA,QACL,MAAA,EAAO,cAAA;AAAA,QACP,WAAA;AAAA,QACA,SAAA,EAAU;AAAA;AAAA,KACZ;AAAA,oBACAA,GAAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACC,IAAI,IAAA,GAAO,CAAA;AAAA,QACX,IAAI,IAAA,GAAO,CAAA;AAAA,QACX,CAAA;AAAA,QACA,IAAA,EAAK,MAAA;AAAA,QACL,MAAA,EAAO,cAAA;AAAA,QACP,WAAA;AAAA,QACA,eAAA,EAAiB,CAAA;AAAA,QACjB,gBAAA,EAAkB,MAAA;AAAA,QAClB,aAAA,EAAc,OAAA;AAAA,QACd,SAAA,EAAU;AAAA;AAAA;AACZ,GAAA,EACF,CAAA;AAEJ;AC/BO,SAAS,YAAA,CAAa;AAAA,EAC3B,KAAA;AAAA,EACA,QAAA;AAAA,EACA,KAAA;AAAA,EACA,QAAA;AAAA,EACA;AACF,CAAA,EAMG;AACD,EAAA,IAAI,KAAA,KAAU,QAAQ,OAAO,IAAA;AAE7B,EAAA,IAAI,KAAA,KAAU,eAAe,QAAA,EAAU;AACrC,IAAA,uBACEE,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,0CAAA,EACb,QAAA,EAAA;AAAA,sBAAAF,GAAAA,CAAC,kBAAe,OAAA,EAAS,QAAA,CAAS,SAAS,IAAA,EAAM,EAAA,EAAI,aAAa,CAAA,EAAG,CAAA;AAAA,sBACrEA,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,wCAAA,EACb,mBAAS,IAAA,EACZ,CAAA;AAAA,sBACAE,IAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,gCAAA,EACb,QAAA,EAAA;AAAA,QAAA,cAAA,CAAe,SAAS,MAAM,CAAA;AAAA,QAAE,KAAA;AAAA,QAAI,cAAA,CAAe,SAAS,IAAI,CAAA;AAAA,QAAE,IAAA;AAAA,QAClE,QAAA,CAAS,OAAA;AAAA,QAAQ;AAAA,OAAA,EACpB,CAAA;AAAA,sBACAF,GAAAA;AAAA,QAAC,MAAA;AAAA,QAAA;AAAA,UACC,OAAA,EAAQ,OAAA;AAAA,UACR,IAAA,EAAK,MAAA;AAAA,UACL,SAAA,EAAU,yBAAA;AAAA,UACV,OAAA,EAAS,CAAC,CAAA,KAAM;AACd,YAAA,CAAA,CAAE,eAAA,EAAgB;AAClB,YAAA,QAAA,IAAW;AAAA,UACb,CAAA;AAAA,UACA,QAAA,kBAAAA,GAAAA,CAAC,KAAA,EAAA,EAAM,SAAA,EAAU,UAAA,EAAW;AAAA;AAAA;AAC9B,KAAA,EACF,CAAA;AAAA,EAEJ;AAEA,EAAA,IAAI,KAAA,KAAU,aAAa,QAAA,EAAU;AACnC,IAAA,uBACEE,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,mCAAA,EACb,QAAA,EAAA;AAAA,sBAAAF,GAAAA,CAAC,eAAA,EAAA,EAAgB,SAAA,EAAU,kCAAA,EAAmC,CAAA;AAAA,sBAC9DA,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,iEAAA,EACb,mBAAS,IAAA,EACZ,CAAA;AAAA,sBACAA,IAAC,MAAA,EAAA,EAAK,SAAA,EAAU,kCACb,QAAA,EAAA,cAAA,CAAe,QAAA,CAAS,IAAI,CAAA,EAC/B;AAAA,KAAA,EACF,CAAA;AAAA,EAEJ;AAEA,EAAA,IAAI,UAAU,OAAA,EAAS;AACrB,IAAA,uBACEE,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,0CAAA,EACb,QAAA,EAAA;AAAA,sBAAAF,GAAAA,CAAC,eAAA,EAAA,EAAgB,SAAA,EAAU,2CAAA,EAA4C,CAAA;AAAA,sBACvEA,GAAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,mDAAA,EACV,mBAAS,eAAA,EACZ;AAAA,KAAA,EACF,CAAA;AAAA,EAEJ;AAEA,EAAA,IAAI,KAAA,KAAU,YAAA,IAAgB,KAAA,KAAU,YAAA,EAAc;AACpD,IAAA,uBAAOA,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,iCAAgC,QAAA,EAAA,iBAAA,EAAU,CAAA;AAAA,EACnE;AAEA,EAAA,OAAO,IAAA;AACT;ACxEA,SAAS,QAAA,CAAS;AAAA,EAChB,SAAA;AAAA,EACA,QAAA;AAAA,EACA,KAAA;AAAA,EACA,GAAG;AACL,CAAA,EAAiC;AAC/B,EAAA,uBACEE,IAAAA;AAAA,IAACC,UAAA,CAAkB,IAAA;AAAA,IAAlB;AAAA,MACC,KAAA;AAAA,MACA,WAAA,EAAU,UAAA;AAAA,MACV,SAAA,EAAW,EAAA,CAAG,sBAAA,EAAwB,SAAS,CAAA;AAAA,MAC9C,GAAG,KAAA;AAAA,MACH,QAAA,EAAA;AAAA,QAAA,QAAA;AAAA,wBACDH,GAAAA,CAAC,aAAA,EAAA,EACC,QAAA,kBAAAA,GAAAA,CAAC,qBAAkB,CAAA,EACrB;AAAA;AAAA;AAAA,GACF;AAEJ;AAEA,SAAS,aAAA,CAAc,EAAE,SAAA,EAAW,GAAG,OAAM,EAAkC;AAC7E,EAAA,uBACEA,GAAAA;AAAA,IAACG,UAAA,CAAkB,KAAA;AAAA,IAAlB;AAAA,MACC,SAAA,EAAW,EAAA;AAAA,QACT,6EAAA;AAAA,QACA;AAAA,OACF;AAAA,MACA,WAAA,EAAU,gBAAA;AAAA,MACT,GAAG;AAAA;AAAA,GACN;AAEJ;AAEA,SAAS,iBAAA,CAAkB;AAAA,EACzB,SAAA;AAAA,EACA,GAAG;AACL,CAAA,EAAsC;AACpC,EAAA,uBACEH,GAAAA;AAAA,IAACG,UAAA,CAAkB,SAAA;AAAA,IAAlB;AAAA,MACC,WAAA,EAAU,oBAAA;AAAA,MACV,SAAA,EAAW,EAAA,CAAG,kCAAA,EAAoC,SAAS,CAAA;AAAA,MAC1D,GAAG;AAAA;AAAA,GACN;AAEJ;AAEA,SAAS,aAAA,CAAc,EAAE,SAAA,EAAW,GAAG,OAAM,EAAkC;AAC7E,EAAA,uBACEH,GAAAA;AAAA,IAACG,UAAA,CAAkB,KAAA;AAAA,IAAlB;AAAA,MACC,SAAA,EAAW,EAAA,CAAG,6BAAA,EAA+B,SAAS,CAAA;AAAA,MACtD,WAAA,EAAU,gBAAA;AAAA,MACT,GAAG;AAAA;AAAA,GACN;AAEJ;AAEA,SAAS,aAAA,CAAc,EAAE,SAAA,EAAW,GAAG,OAAM,EAAkC;AAC7E,EAAA,uBACEH,GAAAA;AAAA,IAACG,UAAA,CAAkB,KAAA;AAAA,IAAlB;AAAA,MACC,SAAA,EAAW,EAAA;AAAA,QACT,4DAAA;AAAA,QACA;AAAA,OACF;AAAA,MACA,WAAA,EAAU,gBAAA;AAAA,MACT,GAAG;AAAA;AAAA,GACN;AAEJ;AC5DO,SAAS,iBAAA,CAAkB;AAAA,EAChC,KAAA;AAAA,EACA,KAAA;AAAA,EACA,aAAA;AAAA,EACA,KAAA;AAAA,EACA;AACF,CAAA,EAMG;AACD,EAAA,IAAI,KAAA,KAAU,QAAQ,OAAO,IAAA;AAE7B,EAAA,IAAI,UAAU,WAAA,EAAa;AACzB,IAAA,uBACED,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,4BAAA,EACb,QAAA,EAAA;AAAA,sBAAAA,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,kCAAA,EACb,QAAA,EAAA;AAAA,wBAAAA,KAAC,QAAA,EAAA,EAAS,KAAA,EAAO,aAAA,CAAc,OAAA,EAAS,WAAU,QAAA,EAChD,QAAA,EAAA;AAAA,0BAAAA,KAAC,aAAA,EAAA,EACE,QAAA,EAAA;AAAA,YAAA,KAAA,CAAM,OAAO,CAAC,CAAA,KAAM,CAAA,CAAE,MAAA,KAAW,SAAS,CAAA,CAAE,MAAA;AAAA,YAAO,GAAA;AAAA,YACnD,KAAA,CAAM,MAAA;AAAA,YAAO;AAAA,WAAA,EAChB,CAAA;AAAA,0BACAF,IAAC,aAAA,EAAA,EAAc;AAAA,SAAA,EACjB,CAAA;AAAA,wBACAA,GAAAA;AAAA,UAAC,MAAA;AAAA,UAAA;AAAA,YACC,OAAA,EAAQ,OAAA;AAAA,YACR,IAAA,EAAK,MAAA;AAAA,YACL,SAAA,EAAU,iBAAA;AAAA,YACV,OAAA,EAAS,CAAC,CAAA,KAAM;AACd,cAAA,CAAA,CAAE,eAAA,EAAgB;AAClB,cAAA,QAAA,IAAW;AAAA,YACb,CAAA;AAAA,YACA,QAAA,kBAAAA,GAAAA,CAACI,KAAAA,EAAA,EAAM,WAAU,QAAA,EAAS;AAAA;AAAA;AAC5B,OAAA,EACF,CAAA;AAAA,sBACAJ,GAAAA,CAAC,QAAA,EAAA,EAAS,KAAA,EAAc;AAAA,KAAA,EAC1B,CAAA;AAAA,EAEJ;AAEA,EAAA,IAAI,UAAU,SAAA,EAAW;AACvB,IAAA,uBACEE,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,4BAAA,EACb,QAAA,EAAA;AAAA,sBAAAA,IAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,wBAAA,EAAyB,QAAA,EAAA;AAAA,QAAA,MAAA;AAAA,QAClC,KAAA,CAAM,MAAA;AAAA,QAAO;AAAA,OAAA,EACpB,CAAA;AAAA,sBACAF,GAAAA,CAAC,QAAA,EAAA,EAAS,KAAA,EAAc;AAAA,KAAA,EAC1B,CAAA;AAAA,EAEJ;AAEA,EAAA,IAAI,UAAU,OAAA,EAAS;AACrB,IAAA,uBACEE,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,4BAAA,EACb,QAAA,EAAA;AAAA,sBAAAF,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,0BAAA,EACb,mBAAS,eAAA,EACZ,CAAA;AAAA,MACC,MAAM,MAAA,GAAS,CAAA,oBAAKA,GAAAA,CAAC,YAAS,KAAA,EAAc;AAAA,KAAA,EAC/C,CAAA;AAAA,EAEJ;AAEA,EAAA,IAAI,UAAU,YAAA,EAAc;AAC1B,IAAA,uBAAOA,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,iCAAgC,QAAA,EAAA,kBAAA,EAAW,CAAA;AAAA,EACpE;AAEA,EAAA,OAAO,IAAA;AACT;AAIA,SAAS,QAAA,CAAS,EAAE,KAAA,EAAM,EAAsC;AAC9D,EAAA,uBACEA,GAAAA,CAAC,IAAA,EAAA,EAAG,SAAA,EAAU,qBAAA,EACX,QAAA,EAAA,KAAA,CAAM,GAAA,CAAI,CAAC,CAAA,qBACVE,IAAAA,CAAC,IAAA,EAAA,EAAc,WAAU,+BAAA,EACvB,QAAA,EAAA;AAAA,oBAAAA,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,2BAAA,EACZ,QAAA,EAAA;AAAA,MAAA,CAAA,CAAE,WAAW,SAAA,oBACZF,IAACK,eAAAA,EAAA,EAAgB,WAAU,kCAAA,EAAmC,CAAA;AAAA,MAE/D,CAAA,CAAE,WAAW,OAAA,oBACZL,IAACM,eAAAA,EAAA,EAAgB,WAAU,oCAAA,EAAqC,CAAA;AAAA,MAAA,CAEhE,EAAE,MAAA,KAAW,SAAA,IAAa,CAAA,CAAE,MAAA,KAAW,gCACvCN,GAAAA;AAAA,QAAC,cAAA;AAAA,QAAA;AAAA,UACC,SAAS,CAAA,CAAE,MAAA,KAAW,WAAA,GAAc,CAAA,CAAE,SAAS,OAAA,GAAU,CAAA;AAAA,UACzD,IAAA,EAAM,EAAA;AAAA,UACN,WAAA,EAAa;AAAA;AAAA,OACf;AAAA,sBAEFA,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,iEAAA,EACb,YAAE,QAAA,EACL,CAAA;AAAA,MACC,EAAE,MAAA,KAAW,WAAA,mBACZE,IAAAA,CAAC,MAAA,EAAA,EAAK,WAAU,gCAAA,EACb,QAAA,EAAA;AAAA,QAAAK,cAAAA,CAAe,CAAA,CAAE,QAAA,CAAS,MAAM,CAAA;AAAA,QAAE,IAAA;AAAA,QAAG,GAAA;AAAA,QACrCA,cAAAA,CAAe,EAAE,QAAQ,CAAA;AAAA,QAAE,IAAA;AAAA,QAAG,EAAE,QAAA,CAAS,OAAA;AAAA,QAAQ;AAAA,OAAA,EACpD,CAAA,mBAEAP,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,kCACb,QAAA,EAAAO,cAAAA,CAAe,CAAA,CAAE,QAAQ,CAAA,EAC5B;AAAA,KAAA,EAEJ,CAAA;AAAA,IACC,CAAA,CAAE,MAAA,KAAW,OAAA,IAAW,CAAA,CAAE,KAAA,oBACzBP,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,yDAAA,EACb,QAAA,EAAA,CAAA,CAAE,KAAA,EACL;AAAA,GAAA,EAAA,EAhCK,CAAA,CAAE,EAkCX,CACD,CAAA,EACH,CAAA;AAEJ;ACrHO,SAAS,cAAA,CACd,MAWA,OAAA,EACA;AACA,EAAA,MAAM,UAAA,GAAa,OAAsB,IAAI,CAAA;AAC7C,EAAA,MAAM,OAAA,GAAU,KAAK,IAAA,KAAS,OAAA;AAG9B,EAAA,MAAM,YAAA,GAAe,MAAA,CAAO,IAAA,CAAK,KAAK,CAAA;AACtC,EAAA,IAAI,YAAA,CAAa,OAAA,KAAY,IAAA,CAAK,KAAA,EAAO;AACvC,IAAA,YAAA,CAAa,UAAU,IAAA,CAAK,KAAA;AAC5B,IAAA,IAAI,OAAA,EAAS;AACX,MAAA,IAAI,IAAA,CAAK,KAAA,KAAU,MAAA,IAAU,UAAA,CAAW,OAAA,EAAS;AAC/C,QAAA,KAAA,CAAM,OAAA,CAAQ,WAAW,OAAO,CAAA;AAChC,QAAA,UAAA,CAAW,OAAA,GAAU,IAAA;AAAA,MACvB;AACA,MAAA,IAAI,IAAA,CAAK,UAAU,SAAA,EAAW;AAC5B,QAAA,IAAI,UAAA,CAAW,OAAA,EAAS,KAAA,CAAM,OAAA,CAAQ,WAAW,OAAO,CAAA;AACxD,QAAA,IAAI,OAAA,EAAS;AACX,UAAA,KAAA,CAAM,OAAA,CAAQ,CAAA,EAAG,IAAA,CAAK,KAAA,CAAM,MAAM,CAAA,iBAAA,CAAA,EAAqB;AAAA,YACrD,WAAA,EAAaO,cAAAA,CAAe,IAAA,CAAK,aAAA,CAAc,KAAK;AAAA,WACrD,CAAA;AAAA,QACH,CAAA,MAAA,IAAW,KAAK,QAAA,EAAU;AACxB,UAAA,KAAA,CAAM,QAAQ,iBAAA,EAAmB;AAAA,YAC/B,WAAA,EAAaA,cAAAA,CAAe,IAAA,CAAK,QAAA,CAAS,IAAI;AAAA,WAC/C,CAAA;AAAA,QACH;AACA,QAAA,UAAA,CAAW,OAAA,GAAU,IAAA;AAAA,MACvB;AACA,MAAA,IAAI,IAAA,CAAK,UAAU,OAAA,EAAS;AAC1B,QAAA,IAAI,UAAA,CAAW,OAAA,EAAS,KAAA,CAAM,OAAA,CAAQ,WAAW,OAAO,CAAA;AACxD,QAAA,IAAI,OAAA,IAAW,IAAA,CAAK,KAAA,CAAM,MAAA,GAAS,CAAA,EAAG;AACpC,UAAA,MAAM,SAAA,GAAY,KAAK,KAAA,CAAM,MAAA;AAAA,YAC3B,CAAC,CAAA,KAAM,CAAA,CAAE,MAAA,KAAW;AAAA,WACtB,CAAE,MAAA;AACF,UAAA,MAAM,MAAA,GAAS,KAAK,KAAA,CAAM,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,MAAA,KAAW,OAAO,CAAA,CAAE,MAAA;AAC9D,UAAA,KAAA,CAAM,MAAM,6BAAA,EAA+B;AAAA,YACzC,WAAA,EAAa,CAAA,EAAG,SAAS,CAAA,YAAA,EAAe,MAAM,CAAA,OAAA;AAAA,WAC/C,CAAA;AAAA,QACH,CAAA,MAAO;AACL,UAAA,KAAA,CAAM,MAAM,eAAA,EAAiB;AAAA,YAC3B,WAAA,kBACEP,GAAAA,CAAC,MAAA,EAAA,EAAK,WAAU,gCAAA,EACb,QAAA,EAAA,IAAA,CAAK,SAAS,eAAA,EACjB;AAAA,WAEH,CAAA;AAAA,QACH;AACA,QAAA,UAAA,CAAW,OAAA,GAAU,IAAA;AAAA,MACvB;AAAA,IACF;AAAA,EACF;AAGA,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,CAAC,OAAA,IAAW,IAAA,CAAK,KAAA,KAAU,WAAA,EAAa;AAC5C,IAAA,MAAM,KAAK,UAAA,CAAW,OAAA,IAAW,CAAA,OAAA,EAAU,IAAA,CAAK,KAAK,CAAA,CAAA;AACrD,IAAA,UAAA,CAAW,OAAA,GAAU,EAAA;AACrB,IAAA,IAAI,OAAA,EAAS;AACX,MAAA,MAAM,IAAA,GAAO,KAAK,KAAA,CAAM,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,MAAA,KAAW,SAAS,CAAA,CAAE,MAAA;AAC9D,MAAA,KAAA,CAAM,QAAQ,CAAA,aAAA,EAAgB,IAAI,IAAI,IAAA,CAAK,KAAA,CAAM,MAAM,CAAA,CAAA,EAAI;AAAA,QACzD,EAAA;AAAA,QACA,aAAa,CAAA,EAAGO,cAAAA,CAAe,IAAA,CAAK,aAAA,CAAc,MAAM,CAAC,CAAA,GAAA,EAAMA,cAAAA,CAAe,IAAA,CAAK,cAAc,KAAK,CAAC,CAAA,EAAA,EAAK,IAAA,CAAK,cAAc,OAAO,CAAA,EAAA,CAAA;AAAA,QACtI,MAAA,EAAQ,EAAE,KAAA,EAAO,QAAA,EAAU,SAAS,MAAM,IAAA,CAAK,QAAO;AAAE,OACzD,CAAA;AAAA,IACH,CAAA,MAAA,IAAW,KAAK,QAAA,EAAU;AACxB,MAAA,KAAA,CAAM,QAAQ,cAAA,EAAgB;AAAA,QAC5B,EAAA;AAAA,QACA,aAAa,CAAA,EAAGA,cAAAA,CAAe,IAAA,CAAK,QAAA,CAAS,MAAM,CAAC,CAAA,GAAA,EAAMA,cAAAA,CAAe,IAAA,CAAK,SAAS,IAAI,CAAC,CAAA,EAAA,EAAK,IAAA,CAAK,SAAS,OAAO,CAAA,EAAA,CAAA;AAAA,QACtH,MAAA,EAAQ,EAAE,KAAA,EAAO,QAAA,EAAU,SAAS,MAAM,IAAA,CAAK,QAAO;AAAE,OACzD,CAAA;AAAA,IACH;AAAA,EACF,CAAA,EAAG;AAAA,IACD,OAAA;AAAA,IACA,IAAA,CAAK,KAAA;AAAA,IACL,OAAA;AAAA,IACA,KAAK,QAAA,CAAS,MAAA;AAAA,IACd,KAAK,QAAA,CAAS,OAAA;AAAA,IACd,KAAK,aAAA,CAAc,MAAA;AAAA,IACnB,KAAK,aAAA,CAAc,KAAA;AAAA,IACnB,KAAK,aAAA,CAAc,OAAA;AAAA,IACnB,IAAA,CAAK,QAAA;AAAA,IACL,IAAA,CAAK,KAAA;AAAA,IACL,IAAA,CAAK;AAAA,GACN,CAAA;AACH;AC9EO,SAAS,YAAA,CAAa;AAAA,EAC3B,SAAA;AAAA,EACA,KAAA;AAAA,EACA,QAAA;AAAA,EACA,WAAA;AAAA,EACA,OAAO,WAAA,GAAc,IAAA;AAAA,EACrB,UAAA,GAAa,IAAA;AAAA,EACb,GAAG;AACL,CAAA,EAAsB;AACpB,EAAA,MAAM,IAAA,GAAO,kBAAkB,OAAO,CAAA;AACtC,EAAA,MAAM,OAAA,GAAU,KAAK,IAAA,KAAS,OAAA;AAC9B,EAAA,MAAM,UAAA,GAAa,YAAY,IAAA,CAAK,WAAA;AAEpC,EAAA,cAAA,CAAe,MAAM,WAAW,CAAA;AAEhC,EAAA,MAAM,MAAA,GAAS,UAAA,GACb,OAAA,mBACEP,GAAAA;AAAA,IAAC,iBAAA;AAAA,IAAA;AAAA,MACC,OAAO,IAAA,CAAK,KAAA;AAAA,MACZ,OAAO,IAAA,CAAK,KAAA;AAAA,MACZ,eAAe,IAAA,CAAK,aAAA;AAAA,MACpB,OAAO,IAAA,CAAK,KAAA;AAAA,MACZ,UAAU,IAAA,CAAK;AAAA;AAAA,sBAGjBA,GAAAA;AAAA,IAAC,YAAA;AAAA,IAAA;AAAA,MACC,OAAO,IAAA,CAAK,KAAA;AAAA,MACZ,UAAU,IAAA,CAAK,QAAA;AAAA,MACf,OAAO,IAAA,CAAK,KAAA;AAAA,MACZ,UAAU,IAAA,CAAK,QAAA;AAAA,MACf,UAAU,IAAA,CAAK;AAAA;AAAA,GACjB,GAEA,IAAA;AAEJ,EAAA,uBACEE,IAAAA,CAAC,KAAA,EAAA,EAAI,WAAW,EAAA,CAAG,4BAAA,EAA8B,SAAS,CAAA,EACxD,QAAA,EAAA;AAAA,oBAAAA,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,gCAAA,EACb,QAAA,EAAA;AAAA,sBAAAF,GAAAA,CAAC,OAAA,EAAA,EAAO,GAAG,IAAA,CAAK,UAAA,EAAY,CAAA;AAAA,sBAC5BA,GAAAA,CAAC,eAAA,EAAA,EACC,QAAA,kBAAAE,KAAC,OAAA,EAAA,EACC,QAAA,EAAA;AAAA,wBAAAA,IAAAA;AAAA,UAAC,cAAA;AAAA,UAAA;AAAA,YACC,wBACEF,GAAAA;AAAA,cAAC,MAAA;AAAA,cAAA;AAAA,gBACC,IAAA,EAAK,SAAA;AAAA,gBACL,QAAA,EAAU,UAAA;AAAA,gBACV,SAAS,IAAA,CAAK;AAAA;AAAA,aAChB;AAAA,YAEF,QAAA,EAAA;AAAA,8BAAAA,GAAAA,CAAC,UAAA,EAAA,EAAW,WAAA,EAAU,cAAA,EAAe,CAAA;AAAA,cACpC,KAAA,KAAU,UAAU,cAAA,GAAiB,aAAA;AAAA;AAAA;AAAA,SACxC;AAAA,wBACAA,GAAAA,CAAC,cAAA,EAAA,EACE,QAAA,EAAA,WAAA,KAAgB,OAAA,GAAU,iBAAiB,aAAA,CAAA,EAC9C;AAAA,OAAA,EACF,CAAA,EACF;AAAA,KAAA,EACF,CAAA;AAAA,IACC;AAAA,GAAA,EACH,CAAA;AAEJ;ACrEO,SAAS,cAAA,CAAe;AAAA,EAC7B,SAAA;AAAA,EACA,KAAA;AAAA,EACA,QAAA;AAAA,EACA,OAAO,WAAA,GAAc,IAAA;AAAA,EACrB,UAAA,GAAa,IAAA;AAAA,EACb,GAAG;AACL,CAAA,EAAwB;AACtB,EAAA,MAAM,IAAA,GAAOQ,kBAAkB,OAAO,CAAA;AACtC,EAAA,MAAM,OAAA,GAAU,KAAK,IAAA,KAAS,OAAA;AAC9B,EAAA,MAAM,UAAA,GAAa,YAAY,IAAA,CAAK,WAAA;AAEpC,EAAA,cAAA,CAAe,MAAM,WAAW,CAAA;AAEhC,EAAA,MAAM,MAAA,GAAS,UAAA,GACb,OAAA,mBACER,GAAAA;AAAA,IAAC,iBAAA;AAAA,IAAA;AAAA,MACC,OAAO,IAAA,CAAK,KAAA;AAAA,MACZ,OAAO,IAAA,CAAK,KAAA;AAAA,MACZ,eAAe,IAAA,CAAK,aAAA;AAAA,MACpB,OAAO,IAAA,CAAK,KAAA;AAAA,MACZ,UAAU,IAAA,CAAK;AAAA;AAAA,sBAGjBA,GAAAA;AAAA,IAAC,YAAA;AAAA,IAAA;AAAA,MACC,OAAO,IAAA,CAAK,KAAA;AAAA,MACZ,UAAU,IAAA,CAAK,QAAA;AAAA,MACf,OAAO,IAAA,CAAK,KAAA;AAAA,MACZ,UAAU,IAAA,CAAK,QAAA;AAAA,MACf,UAAU,IAAA,CAAK;AAAA;AAAA,GACjB,GAEA,IAAA;AAEJ,EAAA,uBACEE,IAAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAW,EAAA;AAAA,QACT,qHAAA;AAAA,QACA,aACI,+CAAA,GACA,mEAAA;AAAA,QACJ;AAAA,OACF;AAAA,MACA,OAAA,EAAS,UAAA,GAAa,MAAA,GAAY,IAAA,CAAK,cAAA;AAAA,MACtC,GAAI,UAAA,GAAa,EAAC,GAAI,IAAA,CAAK,YAAA;AAAA,MAC5B,QAAA,EAAA;AAAA,wBAAAF,GAAAA,CAAC,OAAA,EAAA,EAAO,GAAG,IAAA,CAAK,UAAA,EAAY,CAAA;AAAA,wBAC5BA,GAAAA;AAAA,UAACS,UAAAA;AAAA,UAAA;AAAA,YACC,SAAA,EAAW,EAAA;AAAA,cACT,8BAAA;AAAA,cACA,UAAA,IAAc;AAAA;AAChB;AAAA,SACF;AAAA,wBACAT,GAAAA;AAAA,UAAC,GAAA;AAAA,UAAA;AAAA,YACC,SAAA,EAAW,EAAA;AAAA,cACT,+BAAA;AAAA,cACA,UAAA,IAAc;AAAA,aAChB;AAAA,YACC,QAAA,EAAA,KAAA,KACE,UACG,sCAAA,GACA,gCAAA;AAAA;AAAA,SACR;AAAA,QACC,0BAAUA,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,oBAAoB,QAAA,EAAA,MAAA,EAAO;AAAA;AAAA;AAAA,GACvD;AAEJ;ACzEO,SAAS,gBAAA,CAAiB;AAAA,EAC/B,OAAA,GAAU,IAAA;AAAA,EACV,SAAA;AAAA,EACA,QAAA;AAAA,EACA;AACF,CAAA,EAAyB;AACvB,EAAA,MAAM,cAAc,QAAA,IAAY,SAAA,CAAU,MAAM,GAAG,CAAA,CAAE,KAAI,IAAK,SAAA;AAE9D,EAAA,MAAM,SAAA,GAAY,CAAC,KAAA,qBACjBA,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,gCAAA,EACb,QAAA,EAAA,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,eAAA,EAC5C,CAAA;AAGF,EAAA,MAAM,cAAc,MAAM;AACxB,IAAA,IAAI,OAAA,EAASU,KAAAA,CAAM,OAAA,CAAQ,kBAAkB,CAAA;AAAA,EAC/C,CAAA;AAEA,EAAA,MAAM,SAAA,GAAY,CAAC,IAAA,EAAc,cAAA,KAA2B;AAC1D,IAAA,IAAI,CAAC,OAAA,EAAS;AACd,IAAAA,KAAAA,CAAM,OAAA,CAAQ,CAAA,GAAA,EAAM,SAAS,CAAA,CAAE,CAAA;AAC/B,IAAAA,KAAAA,CAAM,QAAQ,mBAAA,EAAqB;AAAA,MACjC,WAAA,kBACER,IAAAA,CAAC,MAAA,EAAA,EAAK,WAAU,6BAAA,EACb,QAAA,EAAA;AAAA,QAAA,cAAA;AAAA,QACA,YAAY,IAAA,GAAO,CAAA,MAAA,EAAMK,cAAAA,CAAe,QAAQ,CAAC,CAAA,CAAA,GAAK;AAAA,OAAA,EACzD;AAAA,KAEH,CAAA;AAAA,EACH,CAAA;AAEA,EAAA,MAAM,OAAA,GAAU,CAAC,IAAA,EAAc,KAAA,KAAmB;AAChD,IAAA,IAAI,CAAC,OAAA,EAAS;AACd,IAAAG,KAAAA,CAAM,OAAA,CAAQ,CAAA,GAAA,EAAM,SAAS,CAAA,CAAE,CAAA;AAC/B,IAAAA,KAAAA,CAAM,MAAM,iBAAA,EAAmB,EAAE,aAAa,SAAA,CAAU,KAAK,GAAG,CAAA;AAAA,EAClE,CAAA;AAEA,EAAA,MAAM,gBAAA,GAAmB,CAAC,IAAA,EAAc,KAAA,EAAgB,MAAA,KAAmB;AACzE,IAAA,IAAI,CAAC,OAAA,EAAS;AACd,IAAAA,KAAAA,CAAM,OAAA,CAAQ,CAAA,GAAA,EAAM,SAAS,CAAA,CAAE,CAAA;AAC/B,IAAAA,KAAAA,CAAM,MAAM,iBAAA,EAAmB,EAAE,aAAa,SAAA,CAAU,KAAK,GAAG,CAAA;AAAA,EAClE,CAAA;AAEA,EAAA,MAAM,QAAA,GAAW,CAAC,IAAA,KAAiB;AACjC,IAAA,IAAI,CAAC,OAAA,EAAS;AACd,IAAAA,KAAAA,CAAM,OAAA,CAAQ,CAAA,GAAA,EAAM,SAAS,CAAA,CAAE,CAAA;AAC/B,IAAAA,KAAAA,CAAM,KAAK,oBAAA,EAAsB;AAAA,MAC/B,6BACEV,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,+BAA+B,QAAA,EAAA,WAAA,EAAY;AAAA,KAE9D,CAAA;AAAA,EACH,CAAA;AAEA,EAAA,OAAO,EAAE,WAAA,EAAa,SAAA,EAAW,OAAA,EAAS,kBAAkB,QAAA,EAAS;AACvE;AC5CO,SAAS,cAAA,CAAe;AAAA,EAC7B,GAAA;AAAA,EACA,SAAA;AAAA,EACA,QAAA;AAAA,EACA,KAAA;AAAA,EACA,SAAA;AAAA,EACA,QAAA;AAAA,EACA,OAAO,WAAA,GAAc,IAAA;AAAA,EACrB,UAAA,GAAa;AACf,CAAA,EAAwB;AACtB,EAAA,MAAM,gBAAgB,gBAAA,CAAiB;AAAA,IACrC,OAAA,EAAS,WAAA;AAAA,IACT,SAAA;AAAA,IACA;AAAA,GACD,CAAA;AAED,EAAA,MAAM,KAAK,WAAA,CAAY;AAAA,IACrB,GAAA;AAAA,IACA,aAAa,MAAM;AACjB,MAAA,aAAA,CAAc,WAAA,EAAY;AAAA,IAC5B,CAAA;AAAA,IACA,OAAA,EAAS,CAAC,GAAA,EAAK,KAAA,KAAU;AACvB,MAAA,aAAA,CAAc,OAAA,CAAQ,KAAK,KAAK,CAAA;AAAA,IAClC;AAAA,GACD,CAAA;AAED,EAAA,MAAM,SAAA,GAAY,GAAG,KAAA,KAAU,YAAA;AAE/B,EAAA,uBACEE,IAAAA,CAAC,KAAA,EAAA,EAAI,WAAW,EAAA,CAAG,8BAAA,EAAgC,SAAS,CAAA,EAC1D,QAAA,EAAA;AAAA,oBAAAF,GAAAA;AAAA,MAAC,MAAA;AAAA,MAAA;AAAA,QACC,IAAA,EAAK,SAAA;AAAA,QACL,OAAA,EAAQ,SAAA;AAAA,QACR,UAAU,QAAA,IAAY,SAAA;AAAA,QACtB,OAAA,EAAS,MAAM,EAAA,CAAG,QAAA,CAAS,WAAW,QAAQ,CAAA;AAAA,QAC9C,QAAA,kBAAAE,IAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,gCAAA,EACb,QAAA,EAAA;AAAA,UAAA,SAAA,mBACCF,GAAAA,CAAC,UAAA,EAAA,EAAW,SAAA,EAAU,cAAA,EAAe,WAAA,EAAU,cAAA,EAAe,CAAA,mBAE9DA,GAAAA,CAAC,YAAA,EAAA,EAAa,WAAA,EAAU,cAAA,EAAe,CAAA;AAAA,UAExC,KAAA,IAAS;AAAA,SAAA,EACZ;AAAA;AAAA,KACF;AAAA,IAEC,UAAA,IAAc,GAAG,KAAA,KAAU,OAAA,oBAC1BE,IAAAA,CAAC,KAAA,EAAA,EAAI,WAAU,0CAAA,EACb,QAAA,EAAA;AAAA,sBAAAF,GAAAA,CAACM,eAAAA,EAAA,EAAgB,SAAA,EAAU,2CAAA,EAA4C,CAAA;AAAA,sBACvEN,GAAAA,CAAC,GAAA,EAAA,EAAE,WAAU,mDAAA,EACV,QAAA,EAAA,EAAA,CAAG,SAAS,iBAAA,EACf;AAAA,KAAA,EACF;AAAA,GAAA,EAEJ,CAAA;AAEJ;AC3CO,SAAS,sBAAA,CAAuB;AAAA,EACrC,GAAA;AAAA,EACA,SAAA;AAAA,EACA,QAAA;AAAA,EACA,QAAA;AAAA,EACA,MAAA;AAAA,EACA,KAAA;AAAA,EACA,SAAA;AAAA,EACA,aAAA;AAAA,EACA,QAAA;AAAA,EACA,WAAA,GAAc,eAAA;AAAA,EACd,OAAO,WAAA,GAAc,IAAA;AAAA,EACrB,UAAA,GAAa,IAAA;AAAA,EACb,cAAA;AAAA,EACA,eAAA;AAAA,EACA,UAAA;AAAA,EACA,SAAA;AAAA,EACA,OAAA;AAAA,EACA;AACF,CAAA,EAAgC;AAC9B,EAAA,MAAM,gBAAgB,gBAAA,CAAiB;AAAA,IACrC,OAAA,EAAS,WAAA;AAAA,IACT,SAAA;AAAA,IACA,QAAA;AAAA,IACA;AAAA,GACD,CAAA;AAED,EAAA,MAAM,KAAK,gBAAA,CAAiB;AAAA,IAC1B,GAAA;AAAA,IACA,MAAA;AAAA,IACA,cAAA;AAAA,IACA,eAAA;AAAA,IACA,UAAA;AAAA,IACA,SAAA,EAAW,CAAC,GAAA,EAAK,cAAA,KAAmB;AAClC,MAAA,aAAA,CAAc,SAAA,CAAU,KAAK,cAAc,CAAA;AAC3C,MAAA,SAAA,GAAY,KAAK,cAAc,CAAA;AAAA,IACjC,CAAA;AAAA,IACA,OAAA,EAAS,CAAC,GAAA,EAAK,KAAA,EAAO,KAAA,KAAU;AAC9B,MAAA,aAAA,CAAc,gBAAA,CAAiB,GAAA,EAAK,KAAA,EAAO,KAAK,CAAA;AAChD,MAAA,OAAA,GAAU,GAAA,EAAK,OAAO,KAAK,CAAA;AAAA,IAC7B,CAAA;AAAA,IACA,QAAA,EAAU,CAAC,GAAA,KAAQ;AACjB,MAAA,aAAA,CAAc,SAAS,GAAG,CAAA;AAC1B,MAAA,QAAA,GAAW,GAAG,CAAA;AAAA,IAChB;AAAA,GACD,CAAA;AAED,EAAA,MAAM,aAAA,GAAgB,EAAA,CAAG,KAAA,KAAU,aAAA,IAAiB,GAAG,KAAA,KAAU,YAAA;AAEjE,EAAA,MAAM,cAAc,MAAM;AACxB,IAAA,IAAI,aAAA,EAAe;AACjB,MAAA,EAAA,CAAG,MAAA,EAAO;AACV,MAAA;AAAA,IACF;AACA,IAAA,EAAA,CAAG,QAAA,CAAS,WAAW,QAAQ,CAAA;AAAA,EACjC,CAAA;AAEA,EAAA,uBACEE,IAAAA,CAAC,KAAA,EAAA,EAAI,WAAW,EAAA,CAAG,8BAAA,EAAgC,SAAS,CAAA,EAC1D,QAAA,EAAA;AAAA,oBAAAF,GAAAA,CAAC,eAAA,EAAA,EACC,QAAA,kBAAAE,IAAAA,CAAC,OAAA,EAAA,EACC,QAAA,EAAA;AAAA,sBAAAA,IAAAA;AAAA,QAAC,cAAA;AAAA,QAAA;AAAA,UACC,wBACEF,GAAAA;AAAA,YAAC,MAAA;AAAA,YAAA;AAAA,cACC,IAAA,EAAK,SAAA;AAAA,cACL,OAAA,EAAQ,SAAA;AAAA,cACR,QAAA;AAAA,cACA,SAAA,EAAW,GAAG,mCAAmC,CAAA;AAAA,cACjD,OAAA,EAAS;AAAA;AAAA,WACX;AAAA,UAED,QAAA,EAAA;AAAA,YAAA,aAAA,oBACCA,GAAAA;AAAA,cAAC,MAAA;AAAA,cAAA;AAAA,gBACC,SAAA,EAAW,EAAA;AAAA,kBACT,gEAAA;AAAA,kBACA;AAAA,iBACF;AAAA,gBACA,OAAO,EAAE,KAAA,EAAO,GAAG,EAAA,CAAG,QAAA,CAAS,OAAO,CAAA,CAAA,CAAA;AAAI;AAAA,aAC5C;AAAA,4BAEFE,IAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,8CAAA,EACd,QAAA,EAAA;AAAA,8BAAAF,GAAAA,CAACW,YAAAA,EAAA,EAAa,WAAA,EAAU,cAAA,EAAe,CAAA;AAAA,cACtC,gBACGJ,cAAAA,CAAe,EAAA,CAAG,QAAA,CAAS,MAAM,IAChC,KAAA,IAAS;AAAA,aAAA,EAChB;AAAA;AAAA;AAAA,OACF;AAAA,sBACAP,GAAAA,CAAC,cAAA,EAAA,EACE,QAAA,EAAA,aAAA,GAAgB,oBAAoB,WAAA,EACvC;AAAA,KAAA,EACF,CAAA,EACF,CAAA;AAAA,IAEC,UAAA,IAAc,GAAG,KAAA,KAAU,OAAA,oBAC1BE,IAAAA,CAAC,KAAA,EAAA,EAAI,WAAU,0CAAA,EACb,QAAA,EAAA;AAAA,sBAAAF,GAAAA,CAACM,eAAAA,EAAA,EAAgB,SAAA,EAAU,2CAAA,EAA4C,CAAA;AAAA,sBACvEN,GAAAA,CAAC,GAAA,EAAA,EAAE,WAAU,mDAAA,EACV,QAAA,EAAA,EAAA,CAAG,SAAS,iBAAA,EACf;AAAA,KAAA,EACF;AAAA,GAAA,EAEJ,CAAA;AAEJ;ACjIA,SAAS,WAAA,CAAY,EAAE,GAAG,KAAA,EAAM,EAAoC;AAClE,EAAA,uBAAOA,IAACY,aAAA,CAAqB,IAAA,EAArB,EAA0B,WAAA,EAAU,cAAA,EAAgB,GAAG,KAAA,EAAO,CAAA;AACxE;AAEA,SAAS,kBAAA,CAAmB,EAAE,GAAG,KAAA,EAAM,EAAuC;AAC5E,EAAA,uBACEZ,IAACY,aAAA,CAAqB,OAAA,EAArB,EAA6B,WAAA,EAAU,sBAAA,EAAwB,GAAG,KAAA,EAAO,CAAA;AAE9E;AAEA,SAAS,iBAAA,CAAkB,EAAE,GAAG,KAAA,EAAM,EAAsC;AAC1E,EAAA,uBACEZ,IAACY,aAAA,CAAqB,MAAA,EAArB,EAA4B,WAAA,EAAU,qBAAA,EAAuB,GAAG,KAAA,EAAO,CAAA;AAE5E;AAEA,SAAS,kBAAA,CAAmB;AAAA,EAC1B,SAAA;AAAA,EACA,GAAG;AACL,CAAA,EAAwC;AACtC,EAAA,uBACEZ,GAAAA;AAAA,IAACY,aAAA,CAAqB,QAAA;AAAA,IAArB;AAAA,MACC,WAAA,EAAU,sBAAA;AAAA,MACV,SAAA,EAAW,EAAA;AAAA,QACT,uLAAA;AAAA,QACA;AAAA,OACF;AAAA,MACC,GAAG;AAAA;AAAA,GACN;AAEJ;AAEA,SAAS,kBAAA,CAAmB;AAAA,EAC1B,SAAA;AAAA,EACA,IAAA,GAAO,SAAA;AAAA,EACP,GAAG;AACL,CAAA,EAEG;AACD,EAAA,uBACEV,KAAC,iBAAA,EAAA,EACC,QAAA,EAAA;AAAA,oBAAAF,IAAC,kBAAA,EAAA,EAAmB,CAAA;AAAA,oBACpBA,GAAAA;AAAA,MAACY,aAAA,CAAqB,KAAA;AAAA,MAArB;AAAA,QACC,WAAA,EAAU,sBAAA;AAAA,QACV,WAAA,EAAW,IAAA;AAAA,QACX,SAAA,EAAW,EAAA;AAAA,UACT,icAAA;AAAA,UACA;AAAA,SACF;AAAA,QACC,GAAG;AAAA;AAAA;AACN,GAAA,EACF,CAAA;AAEJ;AAEA,SAAS,iBAAA,CAAkB;AAAA,EACzB,SAAA;AAAA,EACA,GAAG;AACL,CAAA,EAAgC;AAC9B,EAAA,uBACEZ,GAAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,WAAA,EAAU,qBAAA;AAAA,MACV,SAAA,EAAW,EAAA;AAAA,QACT,mZAAA;AAAA,QACA;AAAA,OACF;AAAA,MACC,GAAG;AAAA;AAAA,GACN;AAEJ;AAEA,SAAS,iBAAA,CAAkB;AAAA,EACzB,SAAA;AAAA,EACA,GAAG;AACL,CAAA,EAAgC;AAC9B,EAAA,uBACEA,GAAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,WAAA,EAAU,qBAAA;AAAA,MACV,SAAA,EAAW,EAAA;AAAA,QACT,6JAAA;AAAA,QACA;AAAA,OACF;AAAA,MACC,GAAG;AAAA;AAAA,GACN;AAEJ;AAEA,SAAS,gBAAA,CAAiB;AAAA,EACxB,SAAA;AAAA,EACA,GAAG;AACL,CAAA,EAAgC;AAC9B,EAAA,uBACEA,GAAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,WAAA,EAAU,oBAAA;AAAA,MACV,SAAA,EAAW,EAAA;AAAA,QACT,2KAAA;AAAA,QACA;AAAA,OACF;AAAA,MACC,GAAG;AAAA;AAAA,GACN;AAEJ;AAEA,SAAS,gBAAA,CAAiB;AAAA,EACxB,SAAA;AAAA,EACA,GAAG;AACL,CAAA,EAA4D;AAC1D,EAAA,uBACEA,GAAAA;AAAA,IAACY,aAAA,CAAqB,KAAA;AAAA,IAArB;AAAA,MACC,WAAA,EAAU,oBAAA;AAAA,MACV,SAAA,EAAW,EAAA;AAAA,QACT,8JAAA;AAAA,QACA;AAAA,OACF;AAAA,MACC,GAAG;AAAA;AAAA,GACN;AAEJ;AAEA,SAAS,sBAAA,CAAuB;AAAA,EAC9B,SAAA;AAAA,EACA,GAAG;AACL,CAAA,EAAkE;AAChE,EAAA,uBACEZ,GAAAA;AAAA,IAACY,aAAA,CAAqB,WAAA;AAAA,IAArB;AAAA,MACC,WAAA,EAAU,0BAAA;AAAA,MACV,SAAA,EAAW,EAAA;AAAA,QACT,wIAAA;AAAA,QACA;AAAA,OACF;AAAA,MACC,GAAG;AAAA;AAAA,GACN;AAEJ;AAEA,SAAS,iBAAA,CAAkB;AAAA,EACzB,SAAA;AAAA,EACA,GAAG;AACL,CAAA,EAAwC;AACtC,EAAA,uBACEZ,GAAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACC,WAAA,EAAU,qBAAA;AAAA,MACV,SAAA,EAAW,GAAG,SAAS,CAAA;AAAA,MACtB,GAAG;AAAA;AAAA,GACN;AAEJ;AAEA,SAAS,iBAAA,CAAkB;AAAA,EACzB,SAAA;AAAA,EACA,OAAA,GAAU,SAAA;AAAA,EACV,IAAA,GAAO,SAAA;AAAA,EACP,GAAG;AACL,CAAA,EACiE;AAC/D,EAAA,uBACEA,GAAAA;AAAA,IAACY,aAAA,CAAqB,KAAA;AAAA,IAArB;AAAA,MACC,WAAA,EAAU,qBAAA;AAAA,MACV,SAAA,EAAW,GAAG,SAAS,CAAA;AAAA,MACvB,MAAA,kBAAQZ,GAAAA,CAAC,MAAA,EAAA,EAAO,SAAkB,IAAA,EAAY,CAAA;AAAA,MAC7C,GAAG;AAAA;AAAA,GACN;AAEJ;AClKO,SAAS,cAAA,CAAe;AAAA,EAC7B,OAAA,GAAU,IAAA;AAAA,EACV;AACF,CAAA,EAAuB;AACrB,EAAA,MAAM,SAAA,GAAY,CAAC,IAAA,KAAiB;AAClC,IAAA,IAAI,CAAC,OAAA,EAAS;AACd,IAAAU,KAAAA,CAAM,QAAQ,cAAA,EAAgB;AAAA,MAC5B,6BACEV,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,+BAA+B,QAAA,EAAA,WAAA,EAAY;AAAA,KAE9D,CAAA;AAAA,EACH,CAAA;AAEA,EAAA,MAAM,OAAA,GAAU,CAAC,IAAA,EAAc,KAAA,KAAmB;AAChD,IAAA,IAAI,CAAC,OAAA,EAAS;AACd,IAAAU,KAAAA,CAAM,MAAM,eAAA,EAAiB;AAAA,MAC3B,WAAA,kBACEV,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,kCACb,QAAA,EAAA,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,eAAA,EAC5C;AAAA,KAEH,CAAA;AAAA,EACH,CAAA;AAEA,EAAA,OAAO,EAAE,WAAW,OAAA,EAAQ;AAC9B;ACkBO,SAAS,YAAA,CAAa;AAAA,EAC3B,GAAA;AAAA,EACA,SAAA;AAAA,EACA,QAAA;AAAA,EACA,QAAA;AAAA,EACA,MAAA;AAAA,EACA,KAAA;AAAA,EACA,SAAA;AAAA,EACA,QAAA;AAAA,EACA,WAAA,GAAc,aAAA;AAAA,EACd,OAAO,WAAA,GAAc,IAAA;AAAA,EACrB,UAAA,GAAa,IAAA;AAAA,EACb,YAAA,GAAe,cAAA;AAAA,EACf,kBAAA;AAAA,EACA,YAAA;AAAA,EACA,aAAA;AAAA,EACA,SAAA;AAAA,EACA;AACF,CAAA,EAAsB;AACpB,EAAA,MAAM,cAAc,QAAA,IAAY,SAAA,CAAU,MAAM,GAAG,CAAA,CAAE,KAAI,IAAK,SAAA;AAC9D,EAAA,MAAM,gBAAgB,cAAA,CAAe;AAAA,IACnC,OAAA,EAAS,WAAA;AAAA,IACT;AAAA,GACD,CAAA;AAED,EAAA,MAAM,MAAM,SAAA,CAAU;AAAA,IACpB,GAAA;AAAA,IACA,MAAA;AAAA,IACA,YAAA;AAAA,IACA,aAAA;AAAA,IACA,SAAA,EAAW,CAAC,GAAA,KAAQ;AAClB,MAAA,aAAA,CAAc,UAAU,GAAG,CAAA;AAC3B,MAAA,SAAA,GAAY,GAAG,CAAA;AAAA,IACjB,CAAA;AAAA,IACA,OAAA,EAAS,CAAC,GAAA,EAAK,KAAA,EAAO,KAAA,KAAU;AAC9B,MAAA,aAAA,CAAc,OAAA,CAAQ,KAAK,KAAK,CAAA;AAChC,MAAA,OAAA,GAAU,GAAA,EAAK,OAAO,KAAK,CAAA;AAAA,IAC7B;AAAA,GACD,CAAA;AAED,EAAA,MAAM,UAAA,GAAa,IAAI,KAAA,KAAU,UAAA;AACjC,EAAA,MAAM,aAAa,QAAA,IAAY,UAAA;AAE/B,EAAA,MAAM,WAAA,GAAc,kBAAA,oBAClBE,IAAAA,CAAA,QAAA,EAAA,EACG,QAAA,EAAA;AAAA,IAAA,kCAAA;AAAA,oBACDA,IAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,iDAAA,EAAkD,QAAA,EAAA;AAAA,MAAA,QAAA;AAAA,MACxD,WAAA;AAAA,MAAY;AAAA,KAAA,EACtB,CAAA;AAAA,IACC,YAAY,IAAA,GAAO,CAAA,EAAA,EAAKK,cAAAA,CAAe,QAAQ,CAAC,CAAA,CAAA,CAAA,GAAM,EAAA;AAAA,IACtD;AAAA,GAAA,EACH,CAAA;AAGF,EAAA,uBACEL,IAAAA,CAAC,KAAA,EAAA,EAAI,WAAW,EAAA,CAAG,8BAAA,EAAgC,SAAS,CAAA,EAC1D,QAAA,EAAA;AAAA,oBAAAF,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,gCAAA,EACb,QAAA,kBAAAE,IAAAA;AAAA,MAAC,WAAA;AAAA,MAAA;AAAA,QACC,IAAA,EAAM,IAAI,KAAA,KAAU,YAAA;AAAA,QACpB,YAAA,EAAc,CAAC,IAAA,KAAS;AACtB,UAAA,IAAI,CAAC,IAAA,EAAM,GAAA,CAAI,YAAA,EAAa;AAAA,QAC9B,CAAA;AAAA,QACA,QAAA,EAAA;AAAA,0BAAAF,GAAAA,CAAC,eAAA,EAAA,EACC,QAAA,kBAAAE,IAAAA,CAAC,OAAA,EAAA,EACC,QAAA,EAAA;AAAA,4BAAAA,IAAAA;AAAA,cAAC,cAAA;AAAA,cAAA;AAAA,gBACC,wBACEF,GAAAA;AAAA,kBAAC,kBAAA;AAAA,kBAAA;AAAA,oBACC,QAAA,EAAU,UAAA;AAAA,oBACV,OAAA,EAAS,MAAM,GAAA,CAAI,aAAA,CAAc,SAAS,CAAA;AAAA,oBAC1C,wBACEA,GAAAA;AAAA,sBAAC,MAAA;AAAA,sBAAA;AAAA,wBACC,IAAA,EAAK,SAAA;AAAA,wBACL,OAAA,EAAQ,aAAA;AAAA,wBACR,QAAA,EAAU;AAAA;AAAA;AACZ;AAAA,iBAEJ;AAAA,gBAED,QAAA,EAAA;AAAA,kBAAA,UAAA,mBACCA,GAAAA;AAAA,oBAACa,UAAAA;AAAA,oBAAA;AAAA,sBACC,SAAA,EAAU,cAAA;AAAA,sBACV,WAAA,EAAU;AAAA;AAAA,mBACZ,mBAEAb,GAAAA,CAAC,UAAA,EAAA,EAAW,aAAU,cAAA,EAAe,CAAA;AAAA,kBAEtC,KAAA,IAAS;AAAA;AAAA;AAAA,aACZ;AAAA,4BACAA,GAAAA,CAAC,cAAA,EAAA,EAAgB,QAAA,EAAA,WAAA,EAAY;AAAA,WAAA,EAC/B,CAAA,EACF,CAAA;AAAA,0BAEAE,KAAC,kBAAA,EAAA,EACC,QAAA,EAAA;AAAA,4BAAAA,KAAC,iBAAA,EAAA,EACC,QAAA,EAAA;AAAA,8BAAAF,GAAAA,CAAC,gBAAA,EAAA,EACC,QAAA,kBAAAA,GAAAA,CAAC,cAAW,CAAA,EACd,CAAA;AAAA,8BACAA,GAAAA,CAAC,gBAAA,EAAA,EAAkB,QAAA,EAAA,YAAA,EAAa,CAAA;AAAA,8BAChCA,GAAAA,CAAC,sBAAA,EAAA,EAAuB,SAAA,EAAU,4BAC/B,QAAA,EAAA,WAAA,EACH;AAAA,aAAA,EACF,CAAA;AAAA,4BACAE,KAAC,iBAAA,EAAA,EACC,QAAA,EAAA;AAAA,8BAAAF,GAAAA,CAAC,qBAAkB,QAAA,EAAA,QAAA,EAAM,CAAA;AAAA,8BACzBA,GAAAA;AAAA,gBAAC,iBAAA;AAAA,gBAAA;AAAA,kBACC,OAAA,EAAQ,aAAA;AAAA,kBACR,OAAA,EAAS,MAAM,GAAA,CAAI,aAAA,EAAc;AAAA,kBAAG,QAAA,EAAA;AAAA;AAAA;AAEtC,aAAA,EACF;AAAA,WAAA,EACF;AAAA;AAAA;AAAA,KACF,EACF,CAAA;AAAA,IAEC,UAAA,IAAc,IAAI,KAAA,KAAU,SAAA,oBAC3BE,IAAAA,CAAC,KAAA,EAAA,EAAI,WAAU,2CAAA,EACb,QAAA,EAAA;AAAA,sBAAAF,GAAAA,CAAC,gBAAA,EAAA,EAAiB,SAAA,EAAU,kCAAA,EAAmC,CAAA;AAAA,sBAC/DE,IAAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,iDAAA,EAAkD,QAAA,EAAA;AAAA,QAAA,QAAA;AAAA,wBAE7DF,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,mDACb,QAAA,EAAA,WAAA,EACH,CAAA;AAAA,QAAO;AAAA,OAAA,EAET;AAAA,KAAA,EACF,CAAA;AAAA,IAGD,UAAA,IAAc,IAAI,KAAA,KAAU,OAAA,oBAC3BE,IAAAA,CAAC,KAAA,EAAA,EAAI,WAAU,0CAAA,EACb,QAAA,EAAA;AAAA,sBAAAF,GAAAA,CAACM,eAAAA,EAAA,EAAgB,SAAA,EAAU,2CAAA,EAA4C,CAAA;AAAA,sBACvEN,GAAAA,CAAC,GAAA,EAAA,EAAE,WAAU,mDAAA,EACV,QAAA,EAAA,GAAA,CAAI,SAAS,eAAA,EAChB;AAAA,KAAA,EACF;AAAA,GAAA,EAEJ,CAAA;AAEJ","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"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@better-s3/ui",
|
|
3
|
-
"version": "3.1045.
|
|
3
|
+
"version": "3.1045.2",
|
|
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.1045.
|
|
39
|
+
"@better-s3/react": "3.1045.2"
|
|
40
40
|
},
|
|
41
41
|
"peerDependencies": {
|
|
42
42
|
"@base-ui/react": ">=1.0.0",
|
|
@@ -57,6 +57,7 @@
|
|
|
57
57
|
"react": "^19.2.6",
|
|
58
58
|
"sonner": "^2.0.7",
|
|
59
59
|
"tailwind-merge": "^3.5.0",
|
|
60
|
+
"tsc-alias": "^1.8.17",
|
|
60
61
|
"tsup": "^8.5.1",
|
|
61
62
|
"typescript": "^6.0.3"
|
|
62
63
|
},
|
|
@@ -64,7 +65,9 @@
|
|
|
64
65
|
"access": "public"
|
|
65
66
|
},
|
|
66
67
|
"scripts": {
|
|
67
|
-
"build": "tsup --config tsup.config.ts &&
|
|
68
|
+
"build": "pnpm run sync-registry && tsup --config tsup.config.ts && tsc --emitDeclarationOnly && tsc-alias",
|
|
69
|
+
"sync-registry": "node ./scripts/enforce-src-alias-imports.mjs && node ./scripts/sync-registry.mjs",
|
|
70
|
+
"normalize-imports": "node ./scripts/enforce-src-alias-imports.mjs",
|
|
68
71
|
"check-types": "tsc --noEmit"
|
|
69
72
|
}
|
|
70
73
|
}
|