UNPKG

laif-ds

Version:

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

351 lines (350 loc) 14.1 kB
"use client"; import { jsxs as c, jsx as a } from "react/jsx-runtime"; import { useState as S, useRef as X, useCallback as k, useMemo as b, useEffect as pe, useLayoutEffect as ge } from "react"; import { designTokens as m } from "../design-tokens.js"; import { Badge as ve } from "./badge.js"; import { Command as be, CommandInput as xe, CommandList as Ce, CommandEmpty as ye, CommandGroup as $, CommandItem as _ } from "./command.js"; import { Label as we } from "./label.js"; import { cn as C } from "../../lib/utils.js"; import { Button as Ne } from "./button.js"; import { Checkbox as Se } from "./checkbox.js"; import { Icon as A } from "./icon.js"; import { Popover as ke, PopoverTrigger as Ae, PopoverContent as De } from "./popover.js"; import ze from "../../node_modules/lucide-react/dist/esm/icons/chevron-down.js"; const Pe = { sm: m.sizes.sm, default: m.sizes.default, lg: m.sizes.lg }; function Ge(y) { const { multiple: r = !1, options: d, value: H, defaultValue: J, renderValue: w, onValueChange: D, onClear: z, placeholder: K = "Seleziona...", emptyPlaceholder: Q = "Nessun risultato", searchPlaceholder: U = "Cerca...", addItemPlaceholder: Y = "Aggiungi", itemCountMessage: Z = (e) => `${e} elementi selezionati`, maxSelectedMessage: ee = (e) => `Puoi selezionare fino a ${e} elementi`, label: T, className: le = "", labelClassName: te = "", wrpClassName: ae = "", searchable: P = !1, creatable: re = !1, noGroupLabel: q = "Nessun gruppo", maxSelected: s, showChipsInsteadOfCount: ne = !1, disabled: I, size: se = "default", isSingleSelectClearable: oe = !1, id: ie, "data-testid": ce } = y, N = y.multiple ? y.selectableAll ?? !0 : !1, [x, L] = S(!1), [h, O] = S(""), V = X(null), M = X(null), [B, de] = S(0), j = Object.prototype.hasOwnProperty.call(y, "value"), [ue, fe] = S(J), p = j ? H : ue, u = k( (e) => { j || fe(e), D?.( r ? Array.isArray(e) ? e : [] : Array.isArray(e) ? e[0] : e ); }, [j, r, D] ), n = b(() => r ? Array.isArray(p) ? p : [] : p != null ? [p] : [], [p, r]), g = b(() => { const e = d.filter((t) => n.includes(t.value)); if (r) { const t = n.filter((l) => !e.find((o) => o.value === l)).map((l) => ({ value: l, label: l })); return [...e, ...t]; } else if (n.length && !e.length) return [{ value: n[0], label: n[0] }]; return e; }, [d, n, r]), E = (e) => { if (!e.disabled) if (r) { const t = n.includes(e.value); if (!t && s !== void 0 && n.length >= s) return; u( t ? n.filter((l) => l !== e.value) : [...n, e.value] ); } else u(e.value), L(!1); }, G = k(() => { u(r ? [] : void 0), O(""), z && z(); }, [u, z, r]), W = k( (e) => { const t = h.toLocaleLowerCase(); return t ? (typeof e.label == "string" ? e.label : String(e.value)).toLocaleLowerCase().includes(t) : !0; }, [h] ), f = b( () => d.filter((e) => !e.disabled && W(e)), [d, W] ), R = b( () => f.filter((e) => n.includes(e.value)).length, [f, n] ), v = b(() => { if (R === 0) return "none"; const e = s !== void 0 && n.length >= s; return R >= f.length || e ? "all" : "some"; }, [ R, f.length, n.length, s ]), me = k(() => { if (!r) return; if (v === "all") { const l = new Set(f.map((i) => i.value)), o = new Set( d.filter((i) => i.fixed).map((i) => i.value) ), F = n.filter( (i) => !l.has(i) || o.has(i) ); u(F); return; } const e = new Set(n), t = [...n]; for (const l of f) if (!e.has(l.value)) { if (s !== void 0 && t.length >= s) break; t.push(l.value), e.add(l.value); } u(t); }, [ r, v, d, n, f, s, u ]), he = b(() => { const e = d.some((t) => t.group); return d.reduce((t, l) => { const o = e ? l.group || q : ""; return t[o] = t[o] || [], t[o].push(l), t; }, {}); }, [d, q]); return pe(() => { V.current && de(V.current.getBoundingClientRect().width); }, [x, n, d]), ge(() => { if (!x) return; const e = requestAnimationFrame(() => { M.current && M.current?.scrollIntoView({ behavior: "instant", block: "center" }); }); return () => cancelAnimationFrame(e); }, [x]), /* @__PURE__ */ c("div", { className: C("flex flex-col gap-1.5", ae), children: [ T && /* @__PURE__ */ a(we, { className: te, children: T }), /* @__PURE__ */ c( ke, { open: I ? !1 : x, onOpenChange: (e) => !I && L(e), modal: !0, children: [ /* @__PURE__ */ a(Ae, { asChild: !0, children: /* @__PURE__ */ c( "div", { ref: V, id: ie, "data-testid": ce, className: C( m.input.base, m.radius.default, m.focusRingWithin, "flex w-full min-w-[100px] cursor-pointer items-center justify-between gap-2", x && m.activeRing, Pe[se], I && "cursor-not-allowed opacity-50", le ), children: [ g.length === 0 ? /* @__PURE__ */ a("span", { className: "text-d-muted-foreground", children: K }) : r ? /* @__PURE__ */ c("div", { className: "flex h-full w-full min-w-0 items-center justify-between gap-2", children: [ /* @__PURE__ */ a("div", { className: "flex min-w-0 flex-nowrap gap-1 overflow-auto", children: ne ? g.map( (e) => w ? w(e) : /* @__PURE__ */ c( ve, { variant: "secondary", className: "hover:bg-d-secondary/100 bg-d-secondary/50 border-d-border flex cursor-pointer items-center gap-1 border", onClick: (t) => { t.stopPropagation(), E(e); }, children: [ e.label, !e.fixed && /* @__PURE__ */ a(A, { name: "X", size: "xs" }) ] }, e.value ) ) : /* @__PURE__ */ a("div", { children: Z(g.length) }) }), r && /* @__PURE__ */ a( "div", { className: "border-d-input bg-d-accent cursor-pointer rounded-full p-1", onClick: (e) => { e.stopPropagation(), e.preventDefault(), G(); }, onMouseDown: (e) => e.preventDefault(), "aria-label": "Clear selection", children: /* @__PURE__ */ a( A, { name: "X", size: "xs", className: "!text-d-foreground opacity-50" } ) } ) ] }) : /* @__PURE__ */ c("div", { className: "flex h-full w-full min-w-0 items-center justify-between gap-2", children: [ /* @__PURE__ */ a("div", { className: "min-w-0 flex-1 truncate", children: w ? w(g[0]) : typeof g[0]?.label == "string" ? /* @__PURE__ */ a("span", { children: g[0]?.label }) : g[0]?.label }), oe && p !== void 0 && p !== null && /* @__PURE__ */ a( "div", { role: "button", className: "border-d-input bg-d-accent cursor-pointer rounded-full p-1", onClick: (e) => { e.stopPropagation(), e.preventDefault(), G(); }, onMouseDown: (e) => e.preventDefault(), "aria-label": "Clear selection", children: /* @__PURE__ */ a( A, { name: "X", size: "xs", className: "!text-d-foreground opacity-50" } ) } ) ] }), /* @__PURE__ */ a(ze, { className: "h-4 w-4 opacity-50" }) ] } ) }), /* @__PURE__ */ a( De, { className: "p-0", style: { width: B > 0 ? B : "auto" }, align: "start", sideOffset: 4, avoidCollisions: !0, collisionPadding: 8, onOpenAutoFocus: (e) => e.preventDefault(), children: /* @__PURE__ */ c( be, { shouldFilter: P, filter: (e, t) => e.toLocaleLowerCase().includes(t.toLocaleLowerCase()) ? 1 : 0, className: "w-full", children: [ (P || r && N) && /* @__PURE__ */ c( "div", { className: C( "relative", r && N && "[&_[data-slot=command-d-input-wrapper]>svg]:hidden" ), children: [ P ? /* @__PURE__ */ a( xe, { placeholder: U, className: C( "placeholder:text-d-muted-foreground", r && N && "pl-7" ), value: h, onValueChange: O } ) : /* @__PURE__ */ a("div", { className: "border-d-border h-9 border-b" }), r && N && /* @__PURE__ */ a( Ne, { type: "button", variant: "ghost", size: "sm", disabled: f.length === 0, "aria-label": v === "all" ? "Deselect all" : "Select all", "aria-checked": v === "all" ? !0 : v === "some" ? "mixed" : !1, role: "checkbox", className: "text-d-muted-foreground hover:text-d-foreground absolute top-1/2 left-2 size-6 -translate-y-1/2 px-0", onMouseDown: (e) => { e.stopPropagation(), e.preventDefault(); }, onClick: (e) => { e.stopPropagation(), e.preventDefault(), me(); }, children: /* @__PURE__ */ a( A, { name: f.length === 0 ? "SquareDot" : v === "all" ? "SquareCheck" : v === "some" ? "SquareMinus" : "Square", size: "xs" } ) } ) ] } ), /* @__PURE__ */ c(Ce, { className: "max-h-60 overflow-auto overscroll-contain", children: [ /* @__PURE__ */ a(ye, { children: Q }), re && h && /* @__PURE__ */ a($, { children: /* @__PURE__ */ a( _, { className: "cursor-pointer", onSelect: () => { h && (u(r ? [...n, h] : h), O(""), r || L(!1)); }, children: /* @__PURE__ */ c("div", { className: "text-d-foreground text-xs", children: [ Y, " “", h, "”" ] }) } ) }), Object.entries(he).map(([e, t]) => /* @__PURE__ */ a($, { heading: e || void 0, children: t.map((l) => { const o = n.includes(l.value), F = r && s !== void 0 && !o && n.length >= s, i = l.disabled || F; return /* @__PURE__ */ c( _, { ref: o ? M : null, value: typeof l.label == "string" ? l.label : String(l.value), onSelect: () => !i && E(l), className: C( "cursor-pointer", m.dropdownItem.hover, i && "cursor-not-allowed opacity-50", !r && o && m.dropdownItem.selected ), children: [ r && /* @__PURE__ */ a(Se, { checked: o, className: "mr-1" }), typeof l.label == "string" ? /* @__PURE__ */ a("span", { children: l.label }) : l.label ] }, l.value ); }) }, e)) ] }), r && s !== void 0 && n.length >= s && /* @__PURE__ */ a("div", { className: "border-d-border text-d-muted-foreground border-t px-2 py-1 text-xs", children: ee(s) }) ] } ) } ) ] } ) ] }); } export { Ge as AppSelect };