laif-ds
Version:
Design System di Laif con componenti React basati su principi di Atomic Design
546 lines (545 loc) • 14.3 kB
JavaScript
"use client";
import { jsx as d, jsxs as D, Fragment as A } from "react/jsx-runtime";
import { useId as E, useRef as R, useCallback as b, useMemo as M, createContext as $, useState as y, useEffect as O, useContext as S } from "react";
import { createPortal as I } from "react-dom";
import { Button as P } from "./button.js";
import { Popover as z, PopoverTrigger as L, PopoverContent as _ } from "./popover.js";
import { TooltipProvider as j } from "./tooltip.js";
import { Typo as k } from "./typo.js";
import { cn as m } from "../../lib/utils.js";
import F from "../../node_modules/lucide-react/dist/esm/icons/pencil.js";
import H from "../../node_modules/lucide-react/dist/esm/icons/ellipsis-vertical.js";
const T = $(void 0);
function J(e) {
const r = S(T);
if (!r)
throw new Error("useDndMonitor must be used within a DndMonitorProvider");
const { registerMonitor: i, unregisterMonitor: t } = r;
O(() => (i(e), () => {
t(e);
}), [e, i, t]);
}
function B() {
const e = S(T);
if (!e)
throw new Error("useDndEvents must be used within a DndMonitorProvider");
const { activeIdRef: r, draggableDescribedById: i, triggerEvent: t } = e, s = b(
(a) => {
r.current = a, t("onDragStart", a);
},
[t, r]
), c = b(
(a, o) => {
t("onDragMove", a, o);
},
[t]
), l = b(
(a, o) => {
const g = a || r.current;
t("onDragOver", g, o);
},
[t, r]
), p = b(
(a, o) => {
t("onDragEnd", a, o);
},
[t]
), u = b(
(a) => {
t("onDragCancel", a);
},
[t]
);
return {
draggableDescribedById: i,
onDragStart: s,
onDragMove: c,
onDragOver: l,
onDragEnd: p,
onDragCancel: u
};
}
const V = `
To pick up a draggable item, press the space bar.
While dragging, use the arrow keys to move the item.
Press space again to drop the item in its new position, or press escape to cancel.
`, Y = {
onDragStart(e) {
return `Picked up draggable item ${e}.`;
},
onDragOver(e, r) {
return r ? `Draggable item ${e} was moved over droppable area ${r}.` : `Draggable item ${e} is no longer over a droppable area.`;
},
onDragEnd(e, r) {
return r ? `Draggable item ${e} was dropped over droppable area ${r}` : `Draggable item ${e} was dropped.`;
},
onDragCancel(e) {
return `Dragging was cancelled. Draggable item ${e} was dropped.`;
}
};
function W({
announcement: e,
ariaLiveType: r = "assertive",
className: i,
id: t,
ref: s,
...c
}) {
return /* @__PURE__ */ d(
"div",
{
"aria-live": r,
"aria-atomic": !0,
className: m(
"clip-[rect(0_0_0_0)] clip-path-[inset(100%)] fixed top-0 left-0 -m-px h-px w-px overflow-hidden border-0 p-0 whitespace-nowrap",
i
),
id: t,
ref: s,
role: "status",
...c,
children: e
}
);
}
function q({
id: e,
value: r,
className: i,
ref: t,
...s
}) {
return /* @__PURE__ */ d("div", { id: e, className: m("hidden", i), ref: t, ...s, children: r });
}
function G() {
const [e, r] = y("");
return { announce: b((t) => {
t != null && r(t);
}, []), announcement: e };
}
const Q = ({
announcements: e = Y,
container: r,
hiddenTextDescribedById: i,
screenReaderInstructions: t = V
}) => {
const { announce: s, announcement: c } = G(), l = E(), [p, u] = y(!1);
if (O(() => {
u(!0);
}, []), J(
M(
() => ({
onDragStart(o) {
s(e.onDragStart(o));
},
onDragMove(o, g) {
e.onDragMove && s(e.onDragMove(o, g));
},
onDragOver(o, g) {
s(e.onDragOver(o, g));
},
onDragEnd(o, g) {
s(e.onDragEnd(o, g));
},
onDragCancel(o) {
s(e.onDragCancel(o));
}
}),
[s, e]
)
), !p)
return null;
const a = /* @__PURE__ */ D(A, { children: [
/* @__PURE__ */ d(
q,
{
id: i,
value: t
}
),
/* @__PURE__ */ d(W, { id: l, announcement: c })
] });
return r ? I(a, r) : a;
}, ce = ({
announcements: e,
screenReaderInstructions: r,
container: i,
children: t
}) => {
const s = E(), c = R([]), l = R(""), p = b(
(g) => {
c.current.push(g);
},
[]
), u = b(
(g) => {
c.current = c.current.filter(
(v) => v !== g
);
},
[]
), a = b(
(g, v, C) => {
for (const N of c.current) {
const w = N[g];
w && w(v, C);
}
},
[]
), o = M(
() => ({
activeIdRef: l,
draggableDescribedById: s,
registerMonitor: p,
unregisterMonitor: u,
triggerEvent: a
}),
[
l,
s,
p,
u,
a
]
);
return /* @__PURE__ */ d(j, { children: /* @__PURE__ */ D(T.Provider, { value: o, children: [
t,
/* @__PURE__ */ d(
Q,
{
announcements: e,
screenReaderInstructions: r,
container: i,
hiddenTextDescribedById: s
}
)
] }) });
}, x = {
CARD: "kanban-board-card"
};
function ge({
className: e,
ref: r,
...i
}) {
return /* @__PURE__ */ d(
"div",
{
className: m(
"flex h-full flex-grow items-start gap-x-2 overflow-x-auto py-1 select-none",
e
),
draggable: !1,
onDragStart: (t) => {
t.preventDefault(), t.stopPropagation();
},
ref: r,
...i
}
);
}
const U = "w-80 flex-shrink-0 rounded-lg border flex flex-col border-d-border bg-d-sidebar py-1.5";
function pe({
className: e,
columnId: r,
onDropOverColumn: i,
ref: t,
...s
}) {
const [c, l] = y(!1), { onDragEnd: p, onDragOver: u } = B();
return /* @__PURE__ */ d(
"section",
{
"aria-labelledby": `column-${r}-title`,
className: m(
U,
c && "border-d-primary border-2 bg-d-primary/5",
e
),
draggable: !1,
onDragStart: (a) => {
a.preventDefault(), a.stopPropagation();
},
onDragLeave: () => {
l(!1);
},
onDragOver: (a) => {
a.dataTransfer.types.includes(x.CARD) && (a.preventDefault(), l(!0), u("", r));
},
onDrop: (a) => {
if (a.dataTransfer.types.includes(x.CARD)) {
a.preventDefault(), l(!1);
const o = a.dataTransfer.getData(x.CARD);
i?.(o), p("", r);
}
},
ref: t,
...s
}
);
}
function ue({
className: e,
ref: r,
...i
}) {
return /* @__PURE__ */ d(
"div",
{
className: m("flex items-center justify-between px-2 py-1", e),
ref: r,
...i
}
);
}
function fe({
className: e,
ref: r,
...i
}) {
return /* @__PURE__ */ d(
"ul",
{
className: m("min-h-0.5 flex-grow overflow-y-auto", e),
ref: r,
...i
}
);
}
const X = "-mb-[2px] border-b-2 border-t-2 border-b-transparent border-t-transparent px-2 py-1 last:mb-0";
function me({
cardId: e,
className: r,
onDropOverListItem: i,
ref: t,
...s
}) {
const [c, l] = y("none"), { onDragOver: p, onDragEnd: u } = B();
return /* @__PURE__ */ d(
"li",
{
className: m(
X,
c === "top" && "border-t-d-primary !border-t-[3px]",
c === "bottom" && "border-b-d-primary !border-b-[3px]",
r
),
onDragLeave: () => {
l("none");
},
onDragOver: (a) => {
if (a.dataTransfer.types.includes(x.CARD)) {
a.preventDefault(), a.stopPropagation();
const o = a.currentTarget.getBoundingClientRect(), g = (o.top + o.bottom) / 2;
l(a.clientY <= g ? "top" : "bottom"), p("", e);
}
},
onDrop: (a) => {
a.stopPropagation();
const o = a.dataTransfer.getData(x.CARD);
i?.(o, c), u(JSON.parse(o).id, e), l("none");
},
ref: t,
...s
}
);
}
const Z = "p-2.5 text-start";
function be({
className: e,
data: r,
isActive: i = !1,
onEdit: t,
actions: s,
meta: c,
backgroundColor: l,
ref: p,
children: u,
...a
}) {
const [o, g] = y(!1), [v, C] = y(!1), { draggableDescribedById: N, onDragStart: w } = B(), K = t || s && s.length > 0;
return /* @__PURE__ */ D(
"div",
{
role: "button",
tabIndex: 0,
"aria-describedby": N,
"aria-roledescription": "draggable",
draggable: !0,
onDragStart: (n) => {
n.stopPropagation(), g(!0), n.dataTransfer.effectAllowed = "move", n.dataTransfer.setData(
x.CARD,
JSON.stringify(r)
);
const f = n.currentTarget.cloneNode(!0), h = n.currentTarget.getBoundingClientRect();
f.style.position = "absolute", f.style.top = "-9999px", f.style.width = `${h.width}px`, f.style.opacity = "0.8", document.body.appendChild(f), n.dataTransfer.setDragImage(
f,
h.width / 2,
h.height / 2
), setTimeout(() => document.body.removeChild(f), 0), n.currentTarget.blur(), w(r.id);
},
onDragEnd: () => {
g(!1);
},
onClick: (n) => {
o && (n.preventDefault(), n.stopPropagation());
},
onKeyDown: (n) => {
(n.key === "Enter" || n.key === " ") && n.preventDefault();
},
className: m(
"border-d-border text-d-card-foreground rounded-lg border shadow-sm",
!l && "bg-d-card",
Z,
"focus-visible:ring-d-ring inline-flex w-full cursor-grab touch-manipulation flex-col gap-2 focus-visible:ring-1 focus-visible:outline-none",
o ? "cursor-grabbing active:cursor-grabbing opacity-40" : "group/card relative",
i && "rotate-1 transform shadow-lg",
e
),
style: {
backgroundColor: l ? `${l}18` : void 0,
borderColor: l ? `${l}35` : void 0,
...a.style
},
ref: p,
...a,
children: [
u,
c && c.length > 0 && /* @__PURE__ */ d("div", { className: "mt-1.5 flex flex-wrap gap-1.5", children: c.map((n, f) => /* @__PURE__ */ D(
"div",
{
className: "inline-flex items-center gap-1 rounded-full border px-2 py-0.5 text-[11px]",
style: {
backgroundColor: void 0,
color: void 0,
borderColor: l ? `${l}40` : void 0
},
children: [
/* @__PURE__ */ d("span", { className: "truncate font-medium", children: n.name }),
n.value && /* @__PURE__ */ D(A, { children: [
/* @__PURE__ */ d("span", { className: "opacity-60", children: "•" }),
/* @__PURE__ */ d("span", { className: "truncate opacity-80", children: n.value })
] })
]
},
f
)) }),
K && !o && /* @__PURE__ */ D(
"div",
{
className: m(
"bg-d-card border-d-border absolute top-2 right-2 items-center gap-1 rounded-md border p-0.5 shadow-sm",
v ? "flex" : "hidden group-focus-within/card:flex group-hover/card:flex"
),
children: [
t && /* @__PURE__ */ d(
P,
{
variant: "ghost",
size: "icon",
className: "hover:bg-d-accent size-6",
onClick: (n) => {
n.stopPropagation(), n.preventDefault(), o || t();
},
children: /* @__PURE__ */ d(F, { className: "size-3.5" })
}
),
s && s.length > 0 && /* @__PURE__ */ D(z, { open: v, onOpenChange: C, children: [
/* @__PURE__ */ d(L, { asChild: !0, children: /* @__PURE__ */ d(
P,
{
variant: "ghost",
size: "icon",
className: "hover:bg-d-accent size-6",
onClick: (n) => {
n.stopPropagation();
},
children: /* @__PURE__ */ d(H, { className: "size-3.5" })
}
) }),
/* @__PURE__ */ d(
_,
{
className: "w-48 p-1",
align: "end",
side: "bottom",
sideOffset: 8,
onClick: (n) => n.stopPropagation(),
children: /* @__PURE__ */ d("div", { className: "flex flex-col gap-0.5", children: s.map((n, f) => /* @__PURE__ */ D(
P,
{
variant: n.variant === "destructive" ? "ghost-destructive" : "ghost",
size: "sm",
className: "w-full justify-start gap-2",
onClick: (h) => {
h.stopPropagation(), h.preventDefault(), n.onClick(), C(!1);
},
children: [
n.icon && /* @__PURE__ */ d("span", { className: "size-4", children: n.icon }),
n.label
]
},
f
)) })
}
)
] })
]
}
)
]
}
);
}
function De({
className: e,
...r
}) {
return /* @__PURE__ */ d(
k,
{
variant: "small",
as: "h3",
className: m("text-sm font-semibold", e),
...r
}
);
}
function ve({
className: e,
...r
}) {
return /* @__PURE__ */ d(
k,
{
variant: "caption",
as: "p",
className: m(
"text-d-muted-foreground leading-relaxed whitespace-pre-wrap",
e
),
...r
}
);
}
export {
ge as KanbanBoard,
Q as KanbanBoardAccessibility,
be as KanbanBoardCard,
ve as KanbanBoardCardDescription,
De as KanbanBoardCardTitle,
pe as KanbanBoardColumn,
ue as KanbanBoardColumnHeader,
fe as KanbanBoardColumnList,
me as KanbanBoardColumnListItem,
T as KanbanBoardContext,
q as KanbanBoardHiddenText,
W as KanbanBoardLiveRegion,
ce as KanbanBoardProvider,
Y as defaultAnnouncements,
V as defaultScreenReaderInstructions,
U as kanbanBoardColumnClassNames,
X as kanbanBoardColumnListItemClassNames,
G as useAnnouncement,
B as useDndEvents
};