UNPKG

laif-ds

Version:

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

198 lines (197 loc) 6.26 kB
"use client"; import { jsxs as v, jsx as r, Fragment as B } from "react/jsx-runtime"; import l from "react"; import { Button as S } from "./button.js"; import { Card as P, CardHeader as _, CardTitle as W, CardContent as H } from "./card.js"; import { FilePreview as k } from "./file-preview/index.js"; import { Icon as K } from "./icon.js"; import { Input as O } from "./input.js"; const U = { pdf: "application/pdf", doc: ".doc", docx: ".docx", xls: ".xls", xlsx: ".xlsx", ppt: ".ppt", pptx: ".pptx", txt: ".txt", csv: ".csv", jpg: ".jpg", jpeg: ".jpeg", png: ".png", gif: ".gif", image: "image/*", video: "video/*", audio: "audio/*", // Keep both extensions and MIME aliases because archive file types are // reported inconsistently across browsers and operating systems. zip: ".zip,application/zip,application/x-zip-compressed,multipart/x-zip", rar: ".rar,application/vnd.rar,application/x-rar-compressed", "7z": ".7z,application/x-7z-compressed", tar: ".tar,application/x-tar", gz: ".gz,application/gzip,application/x-gzip", tgz: ".tgz,.tar.gz,application/gzip,application/x-compressed-tar" }, R = (g) => Math.ceil(g / (1024 * 1024)), ee = ({ extensions: g = ["pdf", "image", "video", "audio"], multiple: p = !1, onUpload: z, description: I = "Trascina un file o clicca per selezionare", formatDescription: b = "Formato accettato: PDF, Immagini, Video, Audio", selectedLabel: y = "File selezionati", maxTotalSize: c, removeAllLabel: N = "rimuovi tutto", maxFiles: x, id: s, "data-testid": j }) => { const f = g.map((e) => U[e]).join(","), [a, u] = l.useState([]), [w, D] = l.useState(""), o = (e) => { const n = Array.from(e).filter( (i) => f.split(",").some((t) => (t = t.trim(), i.type.startsWith(t.replace("/*", "")) || i.name.toLowerCase().endsWith(t.replace("*", "")))) ); let d = []; const m = []; if (p) { let i = n; if (typeof x == "number") { const t = Math.max(x - a.length, 0); t < n.length && (i = n.slice(0, t), m.push(`Max ${x} file`)); } if (typeof c == "number") { const t = c; let F = a.reduce((h, A) => h + (A.size || 0), 0); const M = []; let $ = !1; for (const h of i) F + (h.size || 0) <= t ? (M.push(h), F += h.size || 0) : $ || (m.push(`Max ${R(t)} MB`), $ = !0); i = M; } d = [...a, ...i]; } else { const i = n[0] ? [n[0]] : []; if (typeof c == "number" && i[0]) { const t = c; (i[0].size || 0) > t ? (m.push(`Max ${R(t)} MB`), d = a) : d = i; } else d = i; } u(d), D(m.join(" • ")), z?.(d); }, E = (e) => { e.target.files && o(e.target.files), e.target.value = ""; }, L = (e) => { e.preventDefault(), o(e.dataTransfer.files); }, C = (e) => { const n = a.filter((d, m) => m !== e); u(n), D(""), z?.(n); }; return /* @__PURE__ */ v("div", { className: "mx-auto w-full space-y-4", children: [ (p || a.length === 0) && /* @__PURE__ */ r( V, { accept: f, multiple: p, onDrop: L, onChange: E, description: I, formatDescription: b, errorCaption: w, id: s, "data-testid": j } ), a.length > 0 && /* @__PURE__ */ r(B, { children: /* @__PURE__ */ v(P, { size: "sm", className: "shadow-none", children: [ /* @__PURE__ */ v(_, { className: "flex justify-between", children: [ /* @__PURE__ */ r(W, { children: y }), /* @__PURE__ */ r( S, { size: "sm", variant: "ghost", className: "text-xs", onClick: () => u([]), children: N } ) ] }), /* @__PURE__ */ r(H, { children: p ? /* @__PURE__ */ r("div", { className: "flex flex-nowrap gap-2 overflow-x-auto py-2", children: a.map((e, n) => /* @__PURE__ */ r( k, { file: e, onRemove: () => C(n) }, e.name + n )) }) : /* @__PURE__ */ r(k, { file: a[0], onRemove: () => C(0) }) }) ] }) }) ] }); }, V = ({ accept: g, multiple: p, onDrop: z, onChange: I, description: b, formatDescription: y, errorCaption: c, id: N, "data-testid": x }) => { const s = l.useRef(null), [j, f] = l.useState(!1), a = l.useId(), u = l.useId(), w = l.useId(), D = l.useId(); return /* @__PURE__ */ v( "div", { id: N, "data-testid": x, role: "button", tabIndex: 0, "aria-label": b || "Seleziona file", "aria-describedby": `${a} ${u}${c ? ` ${w}` : ""}`, onKeyDown: (o) => { (o.key === "Enter" || o.key === " ") && (o.preventDefault(), s.current && (s.current.value = "", s.current.click())); }, onClick: () => { s.current && (s.current.value = "", s.current.click()); }, onDragEnter: () => f(!0), onDragOver: (o) => o.preventDefault(), onDragLeave: () => f(!1), onDrop: (o) => { f(!1), z(o); }, className: `border-d-border flex w-full cursor-pointer flex-col items-center gap-3 rounded-lg border-2 border-dashed px-4 py-8 ${j ? "bg-muted/40" : ""}`, children: [ /* @__PURE__ */ r( K, { name: "ArrowUpFromLine", className: "text-d-muted-foreground h-10 w-10" } ), /* @__PURE__ */ v("div", { className: "max-w-xs text-center", children: [ /* @__PURE__ */ r("p", { id: a, className: "text-d-muted-foreground text-sm font-medium", children: b }), /* @__PURE__ */ r( "p", { id: u, className: "text-d-muted-foreground text-muted-foreground mt-1 text-xs", children: y } ), c ? /* @__PURE__ */ r("p", { id: w, className: "mt-2 text-xs font-medium text-red-600", children: c }) : null ] }), /* @__PURE__ */ r( O, { ref: s, id: D, type: "file", className: "hidden", accept: g, multiple: p, onChange: I } ) ] } ); }; export { ee as FileUploader };