laif-ds
Version:
Design System di Laif con componenti React basati su principi di Atomic Design
264 lines (263 loc) • 9.22 kB
JavaScript
"use client";
import { jsx as i, jsxs as a, Fragment as g } from "react/jsx-runtime";
import { getExt as h, imageExts as P } from "../../lib/file-preview.js";
import { motion as k } from "framer-motion";
import c, { useEffect as j } from "react";
import { AppTextTooltip as z } from "./app-tooltip.js";
import { Button as L } from "./button.js";
import { Command as A, CommandGroup as T, CommandItem as B } from "./command.js";
import { Icon as p } from "./icon.js";
import { Popover as I, PopoverTrigger as U, PopoverContent as E } from "./popover.js";
import { cn as b } from "../../lib/utils.js";
import l from "../../node_modules/lucide-react/dist/esm/icons/file-text.js";
import F from "../../node_modules/lucide-react/dist/esm/icons/file-audio.js";
import N from "../../node_modules/lucide-react/dist/esm/icons/file-video.js";
import S from "../../node_modules/lucide-react/dist/esm/icons/file.js";
import O from "../../node_modules/lucide-react/dist/esm/icons/file-spreadsheet.js";
import R from "../../node_modules/lucide-react/dist/esm/icons/file-archive.js";
import $ from "../../node_modules/lucide-react/dist/esm/icons/file-code.js";
const u = (e) => "type" in e && typeof e.type == "string" && e instanceof File, d = (e) => e.name || "url" in e && e.url || "", v = (e) => {
if (u(e)) return e.type || "";
const t = e.type;
return typeof t == "string" ? t : "";
}, W = (e, t) => {
const o = {
pdf: { icon: l, colorClass: "text-red-600" },
doc: { icon: l, colorClass: "text-blue-600" },
docx: { icon: l, colorClass: "text-blue-600" },
ppt: { icon: l, colorClass: "text-orange-600" },
pptx: { icon: l, colorClass: "text-orange-600" },
txt: { icon: l, colorClass: "text-gray-600" },
md: { icon: l, colorClass: "text-gray-600" }
}, r = (s, n) => s.forEach((m) => o[m] = n);
return r(["xls", "xlsx", "csv"], {
icon: O,
colorClass: "text-green-600"
}), r(["zip", "rar", "7z", "tar", "gz", "tgz"], {
icon: R,
colorClass: "text-amber-600"
}), r(["mp3", "wav", "ogg", "flac", "m4a"], {
icon: F,
colorClass: "text-violet-600"
}), r(["mp4", "mov", "avi", "mkv", "webm"], {
icon: N,
colorClass: "text-rose-600"
}), r(
[
"js",
"ts",
"jsx",
"tsx",
"json",
"xml",
"yml",
"yaml",
"html",
"css",
"scss"
],
{
icon: $,
colorClass: "text-indigo-600"
}
), e && o[e] ? o[e] : t?.startsWith("audio/") ? { icon: F, colorClass: "text-violet-600" } : t?.startsWith("video/") ? { icon: N, colorClass: "text-rose-600" } : t?.startsWith("text/") ? { icon: l, colorClass: "text-gray-600" } : { icon: S, colorClass: "text-d-secondary-foreground" };
}, _ = (e) => {
if (!Number.isFinite(e) || e < 0) return "";
if (e === 0) return "0B";
const t = ["B", "KB", "MB", "GB", "TB"], o = Math.min(
Math.floor(Math.log(e) / Math.log(1024)),
t.length - 1
), r = e / 1024 ** o, s = o > 0 && r < 100 ? 2 : 0;
return `${r.toFixed(s)}${t[o]}`;
}, G = (e) => {
const t = u(e) ? _(e.size) : "", o = V(e);
return { sizeLabel: t, formatLabel: o };
}, D = (e, t) => e && t ? `${e} · ${t}` : e || t || null, K = {
layout: !0,
initial: { opacity: 0, y: "100%" },
animate: { opacity: 1, y: 0 },
exit: { opacity: 0, y: "100%" }
}, y = ({
sizeLabel: e,
formatLabel: t
}) => {
const o = D(e, t);
return o ? /* @__PURE__ */ i("div", { className: "text-d-secondary-foreground/70 text-xs", children: o }) : null;
}, V = (e) => {
const t = h(d(e));
if (t) return t.toUpperCase();
const o = v(e);
if (!o) return "";
if (o === "application/pdf") return "PDF";
const [r, s] = o.split("/");
return r === "image" ? s?.toUpperCase() || "IMAGE" : r === "audio" || r === "video" || r === "text" ? r.toUpperCase() : /(officedocument|msword|ms-excel|ms-powerpoint)/.test(o) ? "OFFICE" : "";
}, X = ({
url: e,
onPreview: t,
onDownload: o,
onRemove: r
}) => /* @__PURE__ */ a(I, { children: [
/* @__PURE__ */ i(U, { asChild: !0, children: /* @__PURE__ */ i(L, { variant: "ghost", size: "icon", children: /* @__PURE__ */ i(p, { name: "Menu", size: "sm" }) }) }),
/* @__PURE__ */ i(E, { className: "w-42 p-0", align: "end", children: /* @__PURE__ */ i(A, { children: /* @__PURE__ */ i(T, { children: [
{
key: "preview",
cond: !!t,
icon: "Presentation",
label: "Anteprima",
onSelect: t
},
{
key: "download",
cond: !!o,
icon: "Download",
label: "Download",
onSelect: o
},
{
key: "remove",
cond: !!r,
icon: "Trash",
label: "Elimina",
onSelect: r,
danger: !0
}
].map(
(n) => n.cond && /* @__PURE__ */ a(
B,
{
onSelect: () => n.onSelect?.(e),
className: n.danger ? "text-d-destructive" : void 0,
children: [
/* @__PURE__ */ i(
p,
{
name: n.icon,
size: "sm",
className: n.danger ? "text-d-destructive" : void 0
}
),
/* @__PURE__ */ i("span", { children: n.label })
]
},
n.key
)
) }) }) })
] }), xe = c.forwardRef(
(e, t) => {
const o = d(e.file), r = h(o), s = v(e.file), n = r === "csv" || s === "text/csv";
return s && s.startsWith("image/") || r && P.has(r) ? /* @__PURE__ */ i(q, { ...e, ref: t }) : !n && (r === "txt" || r === "md" || s && s.startsWith("text/")) ? /* @__PURE__ */ i(H, { ...e, ref: t }) : /* @__PURE__ */ i(J, { ...e, ref: t });
}
), C = c.forwardRef(
({
file: e,
onRemove: t,
onPreview: o,
onDownload: r,
showActionMenu: s = !1,
className: n,
defaultClassName: m,
children: w
}, f) => {
const x = u(e) ? URL.createObjectURL(e) : e.url, M = G(e);
return /* @__PURE__ */ a(
k.div,
{
ref: f,
className: b(
"border-d-border relative flex items-center rounded-md border text-xs",
m,
n
),
...K,
children: [
/* @__PURE__ */ a("div", { className: "flex w-full min-w-0 items-center gap-2", children: [
w(x, M),
s && /* @__PURE__ */ i(
X,
{
url: x,
onPreview: o,
onDownload: r,
onRemove: t
}
)
] }),
!s && t ? /* @__PURE__ */ i(
L,
{
className: "bg-d-background hover:bg-d-background absolute -top-2 -right-2 flex !size-3.5 rounded-full text-xs",
variant: "outline",
size: "icon",
onClick: () => t(x),
children: /* @__PURE__ */ i(p, { name: "X", className: "h-2.5 max-w-2.5" })
}
) : null
]
}
);
}
), q = c.forwardRef((e, t) => /* @__PURE__ */ i(C, { ...e, ref: t, defaultClassName: "gap-2 p-1.5 pr-2", children: (o, r) => /* @__PURE__ */ a(g, { children: [
/* @__PURE__ */ i(
"img",
{
alt: `Attachment ${d(e.file)}`,
className: b(
"bg-d-secondary border-d-border h-10 w-10 shrink-0 rounded-sm border object-cover"
),
src: o
}
),
/* @__PURE__ */ a("div", { className: "flex min-w-0 flex-1 flex-col gap-1", children: [
/* @__PURE__ */ i(z, { text: d(e.file) }),
/* @__PURE__ */ i(
y,
{
sizeLabel: r.sizeLabel,
formatLabel: r.formatLabel
}
)
] })
] }) })), H = c.forwardRef((e, t) => {
const [o, r] = c.useState("");
return j(() => {
if (u(e.file)) {
const s = new FileReader();
s.onload = (n) => {
n.target?.result && r(
typeof n.target.result == "string" ? n.target.result.slice(0, 100) : ""
);
}, s.readAsText(e.file);
} else
r("Anteprima non disponibile");
}, [e.file]), /* @__PURE__ */ i(C, { ...e, ref: t, defaultClassName: "gap-2 p-1.5 pr-2", children: (s, n) => /* @__PURE__ */ a(g, { children: [
/* @__PURE__ */ i("div", { className: "bg-d-secondary border-d-border flex h-10 w-10 shrink-0 items-center justify-center rounded-sm border p-1 text-[8px]", children: o }),
/* @__PURE__ */ i("div", { className: "min-w-0 flex-1", children: /* @__PURE__ */ i(
y,
{
sizeLabel: n.sizeLabel,
formatLabel: n.formatLabel
}
) })
] }) });
}), J = c.forwardRef((e, t) => {
const o = d(e.file), r = h(o), s = v(e.file), { icon: n, colorClass: m } = W(r, s);
return /* @__PURE__ */ i(C, { ...e, ref: t, defaultClassName: "gap-2 p-1.5 pr-2", children: (w, f) => /* @__PURE__ */ a(g, { children: [
/* @__PURE__ */ i("div", { className: "bg-d-secondary flex h-10 w-10 shrink-0 items-center justify-center rounded-sm", children: /* @__PURE__ */ i(n, { className: b("h-5 w-5", m) }) }),
/* @__PURE__ */ a("div", { className: "flex min-w-0 flex-1 flex-col gap-1", children: [
/* @__PURE__ */ i(z, { text: o }),
/* @__PURE__ */ i(
y,
{
sizeLabel: f.sizeLabel,
formatLabel: f.formatLabel
}
)
] })
] }) });
});
export {
xe as FilePreview,
J as GenericFilePreview,
q as ImageFilePreview,
H as TextFilePreview
};