laif-ds
Version:
Design System di Laif con componenti React basati su principi di Atomic Design
381 lines (380 loc) • 13.7 kB
JavaScript
"use client";
import { jsx as r, jsxs as L, Fragment as G } from "react/jsx-runtime";
import { Command as ue, useCommandState as ce } from "../../node_modules/cmdk/dist/index.js";
import * as o from "react";
import { useEffect as C, forwardRef as fe } from "react";
import { Popover as me, PopoverTrigger as ge, PopoverContent as he } from "./popover.js";
import { Badge as pe } from "./badge.js";
import { CommandItem as I, Command as q, CommandList as ve, CommandGroup as be } from "./command.js";
import { cn as p } from "../../lib/utils.js";
import { Label as we } from "./label.js";
import { Icon as xe } from "./icon.js";
import Ne from "../../node_modules/lucide-react/dist/esm/icons/x.js";
function ye(s, l) {
const [i, u] = o.useState(s);
return C(() => {
const a = setTimeout(() => u(s), l);
return () => {
clearTimeout(a);
};
}, [s, l]), i;
}
function T(s, l) {
if (s.length === 0)
return {};
if (!l)
return {
"": s
};
const i = {};
return s.forEach((u) => {
const a = u[l] || "";
i[a] || (i[a] = []), i[a].push(u);
}), i;
}
function Ce(s, l) {
const i = JSON.parse(JSON.stringify(s));
for (const [u, a] of Object.entries(i))
i[u] = a.filter(
(V) => !l.find((c) => c.value === V.value)
);
return i;
}
function Ee(s, l) {
for (const [, i] of Object.entries(s))
if (i.some((u) => l.find((a) => a.value === u.value)))
return !0;
return !1;
}
const Q = fe(({ className: s, ...l }, i) => ce((a) => a.filtered.count === 0) ? /* @__PURE__ */ r(
"div",
{
ref: i,
className: p("py-6 text-center text-sm", s),
"cmdk-empty": "",
role: "presentation",
...l
}
) : null);
Q.displayName = "CommandEmpty";
const Oe = o.forwardRef(
({
value: s,
onChange: l,
placeholder: i = "Cerca...",
defaultOptions: u = [],
options: a,
delay: V,
onSearch: c,
onSearchSync: X,
loadingIndicator: Y,
emptyIndicator: D,
maxSelected: _ = Number.MAX_SAFE_INTEGER,
onMaxSelected: A,
hidePlaceholderWhenSelected: U = !0,
disabled: N,
groupBy: v,
className: Z,
badgeClassName: B,
selectFirstItem: P = !0,
creatable: E = !1,
triggerSearchOnFocus: R = !1,
commandProps: m,
inputProps: O,
hideClearAllButton: ee = !1,
label: W
}, te) => {
const g = o.useRef(null), [f, S] = o.useState(!1), [ne, z] = o.useState(!1), [H, $] = o.useState(!1), [re, oe] = o.useState(
void 0
), j = o.useRef(null), F = o.useRef(null), [t, y] = o.useState(s || []), [b, J] = o.useState(
T(u, v)
), [h, K] = o.useState(""), w = ye(h, V || 500);
o.useImperativeHandle(
te,
() => ({
selectedValue: [...t],
input: g.current,
focus: () => g?.current?.focus(),
reset: () => y([])
}),
[t]
);
const x = (e) => {
j.current && !j.current.contains(e.target) && g.current && !g.current.contains(e.target) && (S(!1), g.current.blur());
}, M = o.useCallback(
(e) => {
const n = t.filter((d) => d.value !== e.value);
y(n), l?.(n);
},
[l, t]
), se = o.useCallback(
(e) => {
const n = g.current;
n && ((e.key === "Delete" || e.key === "Backspace") && n.value === "" && t.length > 0 && (t[t.length - 1].fixed || M(t[t.length - 1])), e.key === "Escape" && n.blur());
},
[M, t]
);
C(() => {
if (typeof document < "u")
return f ? (document.addEventListener("mousedown", x), document.addEventListener("touchend", x)) : (document.removeEventListener("mousedown", x), document.removeEventListener("touchend", x)), () => {
document.removeEventListener("mousedown", x), document.removeEventListener("touchend", x);
};
}, [f, x]), C(() => {
s && y(s);
}, [s]), C(() => {
if (!a || c)
return;
const e = T(a || [], v);
JSON.stringify(e) !== JSON.stringify(b) && J(e);
}, [u, a, v, c, b]), C(() => {
const e = () => {
const d = X?.(w);
J(T(d || [], v));
};
(async () => {
!X || !f || (R && e(), w && e());
})();
}, [w, v, f, R]), C(() => {
const e = async () => {
$(!0);
const d = await c?.(w);
J(T(d || [], v)), $(!1);
};
(async () => {
!c || !f || (R && await e(), w && await e());
})();
}, [w, v, f, R]), o.useEffect(() => {
if (f && F.current) {
const e = F.current.getBoundingClientRect();
oe(e.width);
}
}, [f]);
const le = () => {
if (!E || Ee(b, [{ value: h, label: h }]) || t.find((n) => n.value === h))
return;
const e = /* @__PURE__ */ r(
I,
{
value: h,
className: "cursor-pointer",
onMouseDown: (n) => {
n.preventDefault(), n.stopPropagation();
},
onSelect: (n) => {
if (t.length >= _) {
A?.(t.length);
return;
}
K("");
const d = [...t, { value: n, label: n }];
y(d), l?.(d);
},
children: `Create "${h}"`
}
);
if (!c && h.length > 0 || c && w.length > 0 && !H)
return e;
}, ie = o.useCallback(() => {
if (D)
return c && !E && Object.keys(b).length === 0 ? /* @__PURE__ */ r(I, { value: "-", disabled: !0, children: D }) : /* @__PURE__ */ r(Q, { children: D });
}, [E, D, c, b]), de = o.useMemo(
() => Ce(b, t),
[b, t]
), ae = o.useCallback(() => {
if (m?.filter)
return m.filter;
if (E)
return (e, n) => e.toLowerCase().includes(n.toLowerCase()) ? 1 : -1;
}, [E, m?.filter]);
return /* @__PURE__ */ L("div", { className: "flex flex-col space-y-1.5", children: [
W && /* @__PURE__ */ r(we, { className: "w-fit", children: W }),
/* @__PURE__ */ r(
q,
{
ref: j,
...m,
onKeyDown: (e) => {
se(e), m?.onKeyDown?.(e);
},
className: p(
"bg-d-input border-d-border h-auto overflow-visible",
m?.className
),
shouldFilter: m?.shouldFilter !== void 0 ? m.shouldFilter : !c,
filter: ae(),
children: /* @__PURE__ */ L(me, { open: f, onOpenChange: S, children: [
/* @__PURE__ */ r(ge, { asChild: !0, children: /* @__PURE__ */ r(
"div",
{
ref: F,
className: p(
"border-d-border/50 ring-offset-d-background min-h-10 rounded-md border text-base md:text-sm",
"focus-within:outline-none",
"focus-visible-within:ring-d-ring focus-visible-within:ring-1",
f && "ring-d-ring ring-1",
{
"px-3 py-2": t.length !== 0,
"cursor-text": !N && t.length !== 0,
"disabled:cursor-not-allowed disabled:opacity-50": N
},
Z
),
children: /* @__PURE__ */ L("div", { className: "relative flex flex-wrap gap-1", children: [
t.map((e) => /* @__PURE__ */ L(
pe,
{
className: p(
"data-[disabled]:bg-d-secondary-foreground data-[disabled]:text-d-secondary data-[disabled]:hover:bg-d-secondary-foreground",
"data-[fixed]:bg-d-secondary-foreground data-[fixed]:text-d-secondary data-[fixed]:hover:bg-d-secondary-foreground",
B
),
"data-fixed": e.fixed,
"data-disabled": N || void 0,
children: [
e.label,
/* @__PURE__ */ r(
"button",
{
type: "button",
className: p(
"text-d-secondary-foreground ring-offset-d-background focus:ring-d-ring ml-1 rounded-full outline-none focus:ring-1 focus:ring-offset-2",
(N || e.fixed) && "hidden"
),
onKeyDown: (n) => {
n.key === "Enter" && M(e);
},
onMouseDown: (n) => {
n.preventDefault(), n.stopPropagation();
},
onClick: () => M(e),
children: /* @__PURE__ */ r(Ne, { className: "text-d-secondary-foreground hover:text-d-foreground h-3 w-3 cursor-pointer" })
}
)
]
},
e.value
)),
/* @__PURE__ */ r(
ue.Input,
{
...O,
ref: g,
value: h,
disabled: N,
onValueChange: (e) => {
K(e), O?.onValueChange?.(e);
},
onBlur: (e) => {
ne || S(!1), O?.onBlur?.(e);
},
onFocus: (e) => {
S(!0), O?.onFocus?.(e);
},
placeholder: U && t.length !== 0 ? "" : i,
className: p(
"placeholder:text-d-muted-foreground flex-1 bg-transparent outline-none",
{
"w-full": U,
"px-3 py-2": t.length === 0,
"ml-1": t.length !== 0
},
O?.className
)
}
),
/* @__PURE__ */ r(
"div",
{
className: p(
"border-d-input bg-d-accent cursor-pointer rounded-full p-1",
(ee || N || t.length < 1 || t.filter((e) => e.fixed).length === t.length) && "hidden"
),
onClick: () => {
y(t.filter((e) => e.fixed)), l?.(t.filter((e) => e.fixed));
},
"aria-label": "Clear selection",
children: /* @__PURE__ */ r(
xe,
{
name: "X",
size: "xs",
className: "!text-d-foreground opacity-50"
}
)
}
)
] })
}
) }),
/* @__PURE__ */ r(
he,
{
className: "border-none p-0 shadow-sm",
style: { width: re },
onWheel: (e) => e.stopPropagation(),
children: /* @__PURE__ */ r(q, { shouldFilter: !1, className: "w-full", children: /* @__PURE__ */ r(
ve,
{
className: "bg-d-popover text-d-popover-foreground animate-in border-d-border w-full rounded-md border shadow-md outline-none",
onMouseLeave: () => {
z(!1);
},
onMouseEnter: () => {
z(!0);
},
onMouseUp: () => {
g?.current?.focus();
},
children: H ? /* @__PURE__ */ r(G, { children: Y }) : /* @__PURE__ */ L(G, { children: [
ie(),
le(),
!P && /* @__PURE__ */ r(I, { value: "-", className: "hidden" }),
Object.entries(de).map(([e, n]) => /* @__PURE__ */ r(
be,
{
heading: e,
className: "h-full overflow-auto",
children: /* @__PURE__ */ r(G, { children: n.map((d) => /* @__PURE__ */ r(
I,
{
value: d.label,
disabled: d.disable,
onMouseDown: (k) => {
k.preventDefault(), k.stopPropagation();
},
onSelect: () => {
if (t.length >= _) {
A?.(t.length);
return;
}
K("");
const k = [...t, d];
y(k), l?.(k);
},
className: p(
"cursor-pointer",
d.disable && "text-d-secondary-foreground cursor-default"
),
children: d.label
},
d.value
)) })
},
e
))
] })
}
) })
}
)
] })
}
)
] });
}
);
Oe.displayName = "MultipleSelector";
export {
Oe as MultipleSelector,
ye as useDebounce
};