laif-ds
Version:
Design System di Laif con componenti React basati su principi di Atomic Design
351 lines (350 loc) • 14.1 kB
JavaScript
"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
};