UNPKG

laif-ds

Version:

Design System di Laif con componenti React basati su principi di Atomic Design

264 lines (263 loc) 9.22 kB
"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 };