UNPKG

laif-ds

Version:

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

381 lines (380 loc) 13.7 kB
"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 };