UNPKG

laif-ds

Version:

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

347 lines (346 loc) 11 kB
"use client"; import { jsxs as x, jsx as r } from "react/jsx-runtime"; import { useDebounce as me } from "../../hooks/use-debounce.js"; import { cva as ue } from "../../node_modules/class-variance-authority/dist/index.js"; import * as k from "react"; import { useState as y, useEffect as A, useCallback as j } from "react"; import { designTokens as u } from "../design-tokens.js"; import { cn as z } from "../../lib/utils.js"; import { Checkbox as he } from "./checkbox.js"; import { Command as ge, CommandInput as pe, CommandList as we, CommandEmpty as xe, CommandGroup as _, CommandItem as O } from "./command.js"; import { Icon as Z } from "./icon.js"; import { Label as ye } from "./label.js"; import { Popover as Ne, PopoverTrigger as be, PopoverContent as Ce } from "./popover.js"; import Ae from "../../node_modules/lucide-react/dist/esm/icons/loader-circle.js"; const Se = ue( z( u.input.base, u.radius.default, u.interaction.disabled, "flex items-center justify-between whitespace-nowrap transition-all [&>span]:line-clamp-1", "data-[placeholder]:text-d-muted-foreground", "focus:outline-none" ), { variants: { size: { default: u.sizes.default, sm: u.sizes.sm, lg: u.sizes.lg } }, defaultVariants: { size: "default" } } ); function $e({ fetcher: i, initialOptions: n, debounce: N = 300, renderOptionItem: S, resolveOptionValue: s, renderSelectedValue: c, notFound: h, label: C, placeholder: f = "Select...", value: t, onChange: g, disabled: M = !1, className: v, wrpClassName: E, noResultsMessage: I, clearable: R = !0, multiple: o = !1, size: V, id: ee, "data-testid": re }) { const [m, P] = y(!1), L = k.useRef(null), F = k.useRef(null), te = k.useRef(null), [ne, W] = y({ loading: !1, error: null }), [X, se] = y(""), B = me(X, N), [$, ce] = y(/* @__PURE__ */ new Map()), [G, K] = y([]), [q, ae] = y(0), [H, J] = y(() => n?.length ? new Map( n.map((e) => [s(e), e]) ) : /* @__PURE__ */ new Map()); A(() => { n?.length && (K((e) => e.length ? e : n), J((e) => { const p = new Map(e); return n.forEach((a) => p.set(s(a), a)), p; })); }, [n, s]); const [D, Q] = y([]), T = j( (e) => { if (!e) { Q([]); return; } const a = (Array.isArray(e) ? e : [e]).map((l) => { const d = H.get(l); if (d) return d; if (n?.length) { const b = n.find( (fe) => s(fe) === l ); if (b) return b; } return G.find( (b) => s(b) === l ) ?? null; }).filter(Boolean); Q(a); }, [H, s, n, G] ); A(() => { T(t); }, [t, T]); const U = k.useMemo(() => o ? null : D[0] ?? null, [o, D]); A(() => { if (!m) return; const e = B || ""; if ($.has(e)) { K($.get(e)); return; } (async () => { try { W({ loading: !0, error: null }); const a = await i(B), l = (() => { if (!n?.length) return a; const d = /* @__PURE__ */ new Map(); return n.forEach((w) => { d.set(s(w), w); }), a.forEach((w) => { d.set(s(w), w); }), Array.from(d.values()); })(); ce((d) => new Map(d).set(e, l)), K(l), J((d) => { const w = new Map(d); return l.forEach((b) => w.set(s(b), b)), w; }); } catch (a) { W({ loading: !1, error: a instanceof Error ? a.message : "Failed to fetch options" }); } finally { W((a) => ({ ...a, loading: !1 })); } })(); }, [ m, B, $, i, s, n ]), A(() => { m && T(t); }, [m, T, t]), A(() => { m && L.current && L.current.focus(); }, [m]), A(() => { if (!m || !F.current) return; const e = F.current.getBoundingClientRect(); ae(e.width); }, [m]); const oe = j( (e) => { g?.(R && e === t ? "" : e), P(!1); }, [t, g, R] ), de = j( (e) => { if (!o) return; const p = Array.isArray(t) ? t : [], a = p.includes(e); let l; a ? l = p.filter((d) => d !== e) : l = [...p, e], g?.(l); }, [t, g, o] ), le = j( (e) => { e.stopPropagation(), e.preventDefault(), g?.(o ? [] : ""), P(!1); }, [g] ), ie = k.useId(), Y = ee ?? ie; return /* @__PURE__ */ x("div", { className: z("flex flex-col gap-1.5", E), children: [ C && /* @__PURE__ */ r(ye, { htmlFor: Y, children: C }), /* @__PURE__ */ x(Ne, { open: m, onOpenChange: P, children: [ /* @__PURE__ */ r(be, { asChild: !0, children: /* @__PURE__ */ r( "button", { id: Y, "data-testid": re, ref: F, type: "button", disabled: M, className: z( Se({ size: V }), "!border-d-border/50 border !shadow-none", M && "cursor-not-allowed opacity-50", "font-normal", "w-full", "w-full", u.focusRing, m && u.activeRing, v ), children: /* @__PURE__ */ x("div", { className: "flex w-full flex-1 items-center justify-between overflow-hidden", children: [ o ? Array.isArray(t) && t.length > 0 ? /* @__PURE__ */ r("div", { className: "min-w-0 flex-1 truncate text-left", children: t.length === 1 ? D[0] && c(D[0]) : `${t.length} elementi selezionati` }) : /* @__PURE__ */ r("span", { className: "text-d-muted-foreground truncate text-left", children: f }) : U ? /* @__PURE__ */ r("div", { className: "min-w-0 flex-1 truncate text-left", children: c(U) }) : /* @__PURE__ */ r("span", { className: "text-d-muted-foreground truncate text-left", children: f }), /* @__PURE__ */ x("div", { className: "flex flex-shrink-0 items-center justify-end gap-1", children: [ R && (o && Array.isArray(t) && t.length > 0 || !o && U) && /* @__PURE__ */ r( "div", { className: "border-d-input bg-d-accent cursor-pointer rounded-full p-1", onClick: le, onMouseDown: (e) => e.preventDefault(), "aria-label": "Clear selection", children: /* @__PURE__ */ r( Z, { name: "X", size: "xs", className: "!text-d-foreground opacity-50" } ) } ), /* @__PURE__ */ r( Z, { name: "ChevronsUpDown", size: "xs", className: "!text-d-foreground opacity-50" } ) ] }) ] }) } ) }), /* @__PURE__ */ r( Ce, { className: z("p-0"), style: { width: q ? `${q}px` : void 0 }, align: "start", side: "bottom", sideOffset: 4, onWheel: (e) => e.stopPropagation(), avoidCollisions: !0, collisionPadding: 8, children: /* @__PURE__ */ r( Re, { inputRef: L, commandListRef: te, placeholder: f, searchTerm: X, onSearchTermChange: se, fetchState: ne, options: G, notFound: h, noResultsMessage: I, multiple: o, value: t, resolveOptionValue: s, renderSelectedValue: c, renderOptionItem: S, onSelect: oe, onSelectMultiple: de } ) } ) ] }) ] }); } function Me({ option: i, multiple: n, value: N, resolveOptionValue: S, renderSelectedValue: s, renderOptionItem: c, onSelect: h, onSelectMultiple: C }) { const f = S(i); let t = !1; return n ? t = Array.isArray(N) && N.includes(f) : t = N === f, /* @__PURE__ */ r( O, { value: f, onSelect: n ? C : h, className: z( "cursor-pointer", u.dropdownItem.hover, t && u.dropdownItem.selected ), children: /* @__PURE__ */ r("div", { className: "flex w-full items-center justify-between overflow-hidden", children: /* @__PURE__ */ x("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: [ n && /* @__PURE__ */ r(he, { checked: t }), c ? /* @__PURE__ */ r("div", { className: "truncate", children: c(i) }) : /* @__PURE__ */ r("span", { className: "truncate", children: s(i) }) ] }) }) }, f ); } function Re({ inputRef: i, commandListRef: n, placeholder: N, searchTerm: S, onSearchTermChange: s, fetchState: c, options: h, notFound: C, noResultsMessage: f, multiple: t, value: g, resolveOptionValue: M, renderSelectedValue: v, renderOptionItem: E, onSelect: I, onSelectMultiple: R }) { return /* @__PURE__ */ x(ge, { shouldFilter: !1, className: "w-full border-none shadow-sm", children: [ /* @__PURE__ */ r( pe, { ref: i, placeholder: N, className: "placeholder:text-d-muted-foreground", value: S, onValueChange: s } ), c.loading && h.length > 0 && /* @__PURE__ */ r("div", { className: "flex items-center justify-center p-2", children: /* @__PURE__ */ r(Ae, { className: "h-4 w-4 animate-spin" }) }), /* @__PURE__ */ x(we, { ref: n, children: [ c.error && /* @__PURE__ */ r("div", { className: "text-d-destructive p-3 text-center", children: c.error }), c.loading && h.length === 0 && /* @__PURE__ */ r(ke, {}), !c.loading && !c.error && h.length === 0 && (C || /* @__PURE__ */ r(xe, { children: f || "No results found." })), !c.loading && !c.error && h.length > 0 && /* @__PURE__ */ r(_, { children: h.map((o) => /* @__PURE__ */ r( Me, { option: o, multiple: t, value: g, resolveOptionValue: M, renderSelectedValue: v, renderOptionItem: E, onSelect: I, onSelectMultiple: R }, M(o) )) }) ] }) ] }); } function ke() { return /* @__PURE__ */ r(_, { children: [1, 2, 3].map((i) => /* @__PURE__ */ r(O, { disabled: !0, children: /* @__PURE__ */ x("div", { className: "flex w-full items-center gap-2", children: [ /* @__PURE__ */ r("div", { className: "bg-d-secondary h-6 w-6 animate-pulse rounded-full" }), /* @__PURE__ */ x("div", { className: "flex flex-1 flex-col gap-1", children: [ /* @__PURE__ */ r("div", { className: "bg-d-secondary h-4 w-24 animate-pulse rounded" }), /* @__PURE__ */ r("div", { className: "bg-d-secondary h-3 w-16 animate-pulse rounded" }) ] }) ] }) }, i)) }); } export { $e as AsyncSelect, Se as selectTriggerVariants };