laif-ds
Version:
Design System di Laif con componenti React basati su principi di Atomic Design
190 lines (189 loc) • 5.78 kB
JavaScript
"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.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/*"
}, R = (g) => Math.ceil(g / (1024 * 1024)), ee = ({
extensions: g = ["pdf", "image", "video", "audio"],
multiple: f = !1,
onUpload: b,
description: y = "Trascina un file o clicca per selezionare",
formatDescription: w = "Formato accettato: PDF, Immagini, Video, Audio",
selectedLabel: N = "File selezionati",
maxTotalSize: d,
removeAllLabel: j = "rimuovi tutto",
maxFiles: x,
id: i,
"data-testid": z
}) => {
const u = g.map((e) => U[e]).join(","), [s, p] = l.useState([]), [D, I] = l.useState(""), a = (e) => {
const o = Array.from(e).filter(
(n) => u.split(",").some((t) => (t = t.trim(), n.type.startsWith(t.replace("/*", "")) || n.name.toLowerCase().endsWith(t.replace("*", ""))))
);
let c = [];
const m = [];
if (f) {
let n = o;
if (typeof x == "number") {
const t = Math.max(x - s.length, 0);
t < o.length && (n = o.slice(0, t), m.push(`Max ${x} file`));
}
if (typeof d == "number") {
const t = d;
let F = s.reduce((h, A) => h + (A.size || 0), 0);
const M = [];
let $ = !1;
for (const h of n)
F + (h.size || 0) <= t ? (M.push(h), F += h.size || 0) : $ || (m.push(`Max ${R(t)} MB`), $ = !0);
n = M;
}
c = [...s, ...n];
} else {
const n = o[0] ? [o[0]] : [];
if (typeof d == "number" && n[0]) {
const t = d;
(n[0].size || 0) > t ? (m.push(`Max ${R(t)} MB`), c = s) : c = n;
} else
c = n;
}
p(c), I(m.join(" • ")), b?.(c);
}, E = (e) => {
e.target.files && a(e.target.files), e.target.value = "";
}, L = (e) => {
e.preventDefault(), a(e.dataTransfer.files);
}, C = (e) => {
const o = s.filter((c, m) => m !== e);
p(o), I(""), b?.(o);
};
return /* @__PURE__ */ v("div", { className: "mx-auto w-full space-y-4", children: [
(f || s.length === 0) && /* @__PURE__ */ r(
V,
{
accept: u,
multiple: f,
onDrop: L,
onChange: E,
description: y,
formatDescription: w,
errorCaption: D,
id: i,
"data-testid": z
}
),
s.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: N }),
/* @__PURE__ */ r(
S,
{
size: "sm",
variant: "ghost",
className: "text-xs",
onClick: () => p([]),
children: j
}
)
] }),
/* @__PURE__ */ r(H, { children: f ? /* @__PURE__ */ r("div", { className: "flex flex-nowrap gap-2 overflow-x-auto py-2", children: s.map((e, o) => /* @__PURE__ */ r(
k,
{
file: e,
onRemove: () => C(o)
},
e.name + o
)) }) : /* @__PURE__ */ r(k, { file: s[0], onRemove: () => C(0) }) })
] }) })
] });
}, V = ({
accept: g,
multiple: f,
onDrop: b,
onChange: y,
description: w,
formatDescription: N,
errorCaption: d,
id: j,
"data-testid": x
}) => {
const i = l.useRef(null), [z, u] = l.useState(!1), s = l.useId(), p = l.useId(), D = l.useId(), I = l.useId();
return /* @__PURE__ */ v(
"div",
{
id: j,
"data-testid": x,
role: "button",
tabIndex: 0,
"aria-label": w || "Seleziona file",
"aria-describedby": `${s} ${p}${d ? ` ${D}` : ""}`,
onKeyDown: (a) => {
(a.key === "Enter" || a.key === " ") && (a.preventDefault(), i.current && (i.current.value = "", i.current.click()));
},
onClick: () => {
i.current && (i.current.value = "", i.current.click());
},
onDragEnter: () => u(!0),
onDragOver: (a) => a.preventDefault(),
onDragLeave: () => u(!1),
onDrop: (a) => {
u(!1), b(a);
},
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 ${z ? "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: s, className: "text-d-muted-foreground text-sm font-medium", children: w }),
/* @__PURE__ */ r(
"p",
{
id: p,
className: "text-d-muted-foreground text-muted-foreground mt-1 text-xs",
children: N
}
),
d ? /* @__PURE__ */ r("p", { id: D, className: "mt-2 text-xs font-medium text-red-600", children: d }) : null
] }),
/* @__PURE__ */ r(
O,
{
ref: i,
id: I,
type: "file",
className: "hidden",
accept: g,
multiple: f,
onChange: y
}
)
]
}
);
};
export {
ee as FileUploader
};