laif-ds 1.1.3 → 1.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,452 +1,651 @@
1
1
  "use client";
2
- import { jsxs as c, jsx as r } from "react/jsx-runtime";
3
- import { useState as x, useRef as U, useId as je, useCallback as C, useMemo as w, useEffect as ae, useLayoutEffect as Ee } from "react";
4
- import { designTokens as p } from "../design-tokens.js";
5
- import { Badge as Fe } from "./badge.js";
6
- import { Command as Be, CommandInput as $e, CommandList as Ge, CommandEmpty as We, CommandGroup as ne, CommandItem as se } from "./command.js";
7
- import { Label as Xe } from "./label.js";
8
- import { cn as S } from "../../lib/utils.js";
9
- import { Button as He } from "./button.js";
10
- import { Checkbox as Ke } from "./checkbox.js";
11
- import { Icon as O } from "./icon.js";
12
- import { Popover as Ue, PopoverTrigger as _e, PopoverContent as Je } from "./popover.js";
13
- import Qe from "../../node_modules/lucide-react/dist/esm/icons/chevron-down.js";
14
- const Ye = {
15
- sm: p.sizes.sm,
16
- default: p.sizes.default,
17
- lg: p.sizes.lg
2
+ import { jsxs as h, jsx as n } from "react/jsx-runtime";
3
+ import { useState as I, useRef as O, useId as tt, useCallback as T, useMemo as R, useLayoutEffect as re } from "react";
4
+ import rt from "../../node_modules/react-remove-scroll/dist/es2015/Combination.js";
5
+ import { designTokens as c } from "../design-tokens.js";
6
+ import { Badge as at } from "./badge.js";
7
+ import { Command as nt, CommandInput as lt, CommandList as it, CommandEmpty as ot, CommandGroup as ge, CommandItem as be } from "./command.js";
8
+ import { Label as st } from "./label.js";
9
+ import { cn as g } from "../../lib/utils.js";
10
+ import { Button as dt } from "./button.js";
11
+ import { Checkbox as ct } from "./checkbox.js";
12
+ import { Icon as E } from "./icon.js";
13
+ import { Popover as ut, PopoverTrigger as ft, PopoverContent as mt } from "./popover.js";
14
+ import pt from "../../node_modules/lucide-react/dist/esm/icons/chevron-down.js";
15
+ const ve = {
16
+ sm: c.sizes.sm,
17
+ default: c.sizes.default,
18
+ lg: c.sizes.lg
19
+ }, ht = 24, xe = g(
20
+ c.motion.duration,
21
+ "-mx-1 flex shrink-0 cursor-pointer items-center rounded-sm p-1 opacity-50 outline-none transition-opacity enabled:hover:opacity-100 focus-visible:opacity-100 focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-d-ring disabled:cursor-not-allowed"
22
+ ), gt = {
23
+ width: 0,
24
+ height: 0,
25
+ innerHeight: 0,
26
+ paddingLeft: 0,
27
+ paddingRight: 0
28
+ }, ye = (u) => typeof u.label == "string" ? u.label : u.keywords?.[0] ?? String(u.value), we = (u) => {
29
+ const z = typeof u.label == "string" ? [u.label] : [];
30
+ return u.keywords && z.push(...u.keywords), z.length > 0 ? z : [String(u.value)];
18
31
  };
19
- function ut(A) {
20
- const {
32
+ function Lt(u) {
33
+ const z = u, {
21
34
  multiple: a = !1,
22
- options: d,
23
- value: oe,
24
- defaultValue: ie,
25
- renderValue: D,
26
- onValueChange: M,
27
- onClear: R,
28
- placeholder: q = "Seleziona...",
29
- emptyPlaceholder: ce = "Nessun risultato",
30
- searchPlaceholder: de = "Cerca...",
31
- addItemPlaceholder: ue = "Aggiungi",
32
- itemCountMessage: me = (e) => `${e} elementi selezionati`,
33
- maxSelectedMessage: fe = (e) => `Puoi selezionare fino a ${e} elementi`,
35
+ options: f,
36
+ value: Ce,
37
+ defaultValue: Ne,
38
+ renderValue: B,
39
+ onValueChange: $,
40
+ onClear: j,
41
+ placeholder: D = "Seleziona...",
42
+ emptyPlaceholder: Se = "Nessun risultato",
43
+ searchPlaceholder: Ie = "Cerca...",
44
+ addItemPlaceholder: ke = "Aggiungi",
45
+ itemCountMessage: Re = (e) => e === 1 ? "1 elemento selezionato" : `${e} elementi selezionati`,
46
+ maxSelectedMessage: ze = (e) => `Puoi selezionare fino a ${e} elementi`,
34
47
  label: b,
35
- className: he = "",
36
- labelClassName: pe = "",
37
- wrpClassName: be = "",
38
- searchable: T = !1,
39
- creatable: ge = !1,
40
- noGroupLabel: _ = "Nessun gruppo",
41
- maxSelected: i,
42
- showChipsInsteadOfCount: ve = !1,
43
- disabled: N,
44
- size: ye = "default",
45
- isSingleSelectClearable: xe = !1,
46
- id: Ce,
47
- "data-testid": we,
48
- "aria-label": J,
49
- "aria-labelledby": j,
50
- portalContainer: Ne
51
- } = A, L = A.multiple ? A.selectableAll ?? !0 : !1, [u, I] = x(!1), [g, E] = x(""), F = U(null), B = U(null), [Q, ke] = x(0), Y = je(), $ = `${Y}-label`, z = `${Y}-value`, [Z, Ie] = x(void 0), P = U(null), [Se, G] = x(void 0), W = C(
52
- () => P.current?.querySelector(
53
- '[cmdk-item][aria-selected="true"]'
54
- ) ?? void 0,
55
- []
56
- ), Ae = C((e) => {
57
- P.current = e, Ie(e?.querySelector("[cmdk-list]")?.id);
58
- }, []), X = Object.prototype.hasOwnProperty.call(A, "value"), [De, Le] = x(ie), v = X ? oe : De, m = C(
48
+ className: De = "",
49
+ labelClassName: Le = "",
50
+ wrpClassName: Ae = "",
51
+ searchable: H = !1,
52
+ creatable: Pe = !1,
53
+ noGroupLabel: ae = "Nessun gruppo",
54
+ maxSelected: m,
55
+ showChipsInsteadOfCount: K = !1,
56
+ disabled: d,
57
+ size: ne = "default",
58
+ isSingleSelectClearable: Oe = !1,
59
+ required: le = !1,
60
+ "aria-invalid": M = !1,
61
+ id: Te,
62
+ "data-testid": Be,
63
+ selectableAll: He,
64
+ "aria-label": G,
65
+ "aria-labelledby": L,
66
+ portalContainer: Me,
67
+ // Caller attributes that are merged with the trigger's own, not replaced.
68
+ "aria-describedby": _e,
69
+ onKeyDown: Ve,
70
+ // Every remaining prop is an HTML attribute for the trigger.
71
+ ...Fe
72
+ } = z, _ = a ? He ?? !0 : !1, [C, V] = I(!1), qe = C && document.body.hasAttribute("data-scroll-locked"), [N, W] = I(""), X = O(null), Y = O(null), F = O(null), ie = O(null), Z = O(!1), [y, Ee] = I(
73
+ gt
74
+ ), [$e, je] = I(0), [Ke, oe] = I(!1), [Ge, se] = I(
75
+ Number.POSITIVE_INFINITY
76
+ ), J = tt(), A = `${J}-label`, q = `${J}-value`, de = `${J}-summary`, Q = Object.prototype.hasOwnProperty.call(u, "value"), [We, Xe] = I(Ne), k = Q ? Ce : We, v = T(
59
77
  (e) => {
60
- X || Le(e), M?.(
78
+ Q || Xe(e), $?.(
61
79
  a ? Array.isArray(e) ? e : [] : Array.isArray(e) ? e[0] : e
62
80
  );
63
81
  },
64
- [X, a, M]
65
- ), n = w(() => a ? Array.isArray(v) ? v : [] : v != null ? [v] : [], [v, a]), f = w(() => {
66
- const e = d.filter((l) => n.includes(l.value));
82
+ [Q, a, $]
83
+ ), i = R(() => {
84
+ const e = a ? Array.isArray(k) ? k : [] : k != null ? [k] : [];
85
+ return f.some((t) => t.value === "") ? e : e.filter((t) => t !== "");
86
+ }, [k, a, f]), s = R(() => {
87
+ const e = f.filter((t) => i.includes(t.value));
67
88
  if (a) {
68
- const l = n.filter((t) => !e.find((s) => s.value === t)).map((t) => ({ value: t, label: t }));
69
- return [...e, ...l];
70
- } else if (n.length && !e.length)
71
- return [{ value: n[0], label: n[0] }];
89
+ const t = i.filter((r) => !e.find((l) => l.value === r)).map((r) => ({ value: r, label: r }));
90
+ return [...e, ...t];
91
+ } else if (i.length && !e.length)
92
+ return [{ value: i[0], label: i[0] }];
72
93
  return e;
73
- }, [d, n, a]), H = w(() => {
74
- const e = f[0];
75
- if (e)
76
- return String(e.value).trim();
77
- }, [f]), [ze, V] = x(void 0), ee = C(() => {
78
- V(H), I(!0);
79
- }, [H]), te = (e) => {
80
- if (!e.disabled)
94
+ }, [f, i, a]), ce = (e) => {
95
+ if (!(d || e.disabled))
81
96
  if (a) {
82
- const l = n.includes(e.value);
83
- if (!l && i !== void 0 && n.length >= i)
97
+ const t = i.includes(e.value);
98
+ if (t && e.fixed || !t && m !== void 0 && i.length >= m)
84
99
  return;
85
- m(
86
- l ? n.filter((t) => t !== e.value) : [...n, e.value]
100
+ v(
101
+ t ? i.filter((r) => r !== e.value) : [...i, e.value]
87
102
  );
88
103
  } else
89
- m(e.value), I(!1);
90
- }, le = C(() => {
91
- m(a ? [] : void 0), E(""), R && R();
92
- }, [m, R, a]), Pe = () => Array.from(
93
- P.current?.querySelectorAll(
94
- '[cmdk-item]:not([aria-disabled="true"])'
95
- ) ?? []
96
- ), Ve = (e) => {
97
- const l = Pe();
98
- if (l.length === 0) return;
99
- const t = l.findIndex(
100
- (Te) => Te.getAttribute("aria-selected") === "true"
101
- ), s = l.length - 1, k = e === "Home" ? 0 : e === "End" ? s : e === "ArrowDown" ? t < 0 ? 0 : Math.min(t + 1, s) : t <= 0 ? 0 : t - 1, o = l[k];
102
- V(o.getAttribute("data-value") ?? void 0), G(o.id), o.scrollIntoView({ block: "nearest" });
103
- }, Oe = () => {
104
- W()?.click();
105
- }, Me = (e) => {
106
- if (!N && e.target === e.currentTarget) {
107
- if (e.key === "Enter" || e.key === " ") {
108
- if (e.preventDefault(), !u) {
109
- ee();
110
- return;
111
- }
112
- if (e.key === "Enter") {
113
- Oe();
114
- return;
115
- }
116
- I(!1);
104
+ v(e.value), V(!1);
105
+ }, ue = T(() => {
106
+ if (!d) {
107
+ if (a) {
108
+ const e = new Set(
109
+ f.filter((t) => t.fixed).map((t) => t.value)
110
+ );
111
+ v(i.filter((t) => e.has(t)));
112
+ } else
113
+ v(void 0);
114
+ W(""), j && j();
115
+ }
116
+ }, [d, a, f, i, v, j]), Ye = s.some((e) => !e.fixed), U = () => {
117
+ (F.current?.querySelector("input") ?? F.current)?.focus();
118
+ }, Ze = (e) => {
119
+ if (!(d || e.target !== e.currentTarget) && ["Enter", " ", "ArrowDown"].includes(e.key)) {
120
+ if (e.preventDefault(), C) {
121
+ U();
117
122
  return;
118
123
  }
119
- if (e.key === "ArrowDown" || e.key === "ArrowUp" || e.key === "Home" || e.key === "End") {
120
- if (e.preventDefault(), !u) {
121
- ee();
122
- return;
123
- }
124
- Ve(e.key);
125
- }
124
+ Z.current = !0, V(!0);
126
125
  }
127
- }, re = C(
126
+ }, fe = T(
128
127
  (e) => {
129
- const l = g.toLocaleLowerCase();
130
- return l ? (typeof e.label == "string" ? e.label : String(e.value)).toLocaleLowerCase().includes(l) : !0;
128
+ const t = N.toLocaleLowerCase();
129
+ return t ? we(e).some(
130
+ (r) => r.toLocaleLowerCase().includes(t)
131
+ ) : !0;
131
132
  },
132
- [g]
133
- ), h = w(
134
- () => d.filter((e) => !e.disabled && re(e)),
135
- [d, re]
136
- ), K = w(
137
- () => h.filter((e) => n.includes(e.value)).length,
138
- [h, n]
139
- ), y = w(() => {
140
- if (K === 0) return "none";
141
- const e = i !== void 0 && n.length >= i;
142
- return K >= h.length || e ? "all" : "some";
133
+ [N]
134
+ ), w = R(
135
+ () => f.filter((e) => !e.disabled && fe(e)),
136
+ [f, fe]
137
+ ), ee = R(
138
+ () => w.filter((e) => i.includes(e.value)).length,
139
+ [w, i]
140
+ ), S = R(() => {
141
+ if (ee === 0) return "none";
142
+ const e = m !== void 0 && i.length >= m;
143
+ return ee >= w.length || e ? "all" : "some";
143
144
  }, [
144
- K,
145
- h.length,
146
- n.length,
147
- i
148
- ]), Re = C(() => {
145
+ ee,
146
+ w.length,
147
+ i.length,
148
+ m
149
+ ]), Je = T(() => {
149
150
  if (!a) return;
150
- if (y === "all") {
151
- const t = new Set(h.map((o) => o.value)), s = new Set(
152
- d.filter((o) => o.fixed).map((o) => o.value)
153
- ), k = n.filter(
154
- (o) => !t.has(o) || s.has(o)
151
+ if (S === "all") {
152
+ const r = new Set(w.map((o) => o.value)), l = new Set(
153
+ f.filter((o) => o.fixed).map((o) => o.value)
154
+ ), p = i.filter(
155
+ (o) => !r.has(o) || l.has(o)
155
156
  );
156
- m(k);
157
+ v(p);
157
158
  return;
158
159
  }
159
- const e = new Set(n), l = [...n];
160
- for (const t of h)
161
- if (!e.has(t.value)) {
162
- if (i !== void 0 && l.length >= i) break;
163
- l.push(t.value), e.add(t.value);
160
+ const e = new Set(i), t = [...i];
161
+ for (const r of w)
162
+ if (!e.has(r.value)) {
163
+ if (m !== void 0 && t.length >= m) break;
164
+ t.push(r.value), e.add(r.value);
164
165
  }
165
- m(l);
166
+ v(t);
166
167
  }, [
167
168
  a,
168
- y,
169
- d,
170
- n,
171
- h,
169
+ S,
170
+ f,
172
171
  i,
173
- m
174
- ]), qe = w(() => {
175
- const e = d.some((l) => l.group);
176
- return d.reduce((l, t) => {
177
- const s = e ? t.group || _ : "";
178
- return l[s] = l[s] || [], l[s].push(t), l;
172
+ w,
173
+ m,
174
+ v
175
+ ]), Qe = R(() => {
176
+ const e = f.some((t) => t.group);
177
+ return f.reduce((t, r) => {
178
+ const l = e ? r.group || ae : "";
179
+ return t[l] = t[l] || [], t[l].push(r), t;
179
180
  }, {});
180
- }, [d, _]);
181
- return ae(() => {
182
- F.current && ke(F.current.getBoundingClientRect().width);
183
- }, [u, n, d]), Ee(() => {
184
- if (!u) return;
181
+ }, [f, ae]);
182
+ re(() => {
183
+ const e = X.current;
184
+ if (!e) return;
185
+ const t = () => {
186
+ const l = e.getBoundingClientRect(), p = window.getComputedStyle(e);
187
+ Ee({
188
+ width: l.width,
189
+ height: l.height,
190
+ innerHeight: e.clientHeight,
191
+ paddingLeft: parseFloat(p.paddingLeft),
192
+ paddingRight: parseFloat(p.paddingRight)
193
+ });
194
+ };
195
+ if (t(), typeof ResizeObserver > "u") return;
196
+ const r = new ResizeObserver(t);
197
+ return r.observe(e), () => r.disconnect();
198
+ }, [C]);
199
+ const me = s.length > 0, Ue = s.some(
200
+ (e) => !e.fixed && !e.disabled
201
+ ), et = T((e) => {
202
+ const t = e?.querySelector('[data-slot="badge"]');
203
+ t && je(t.offsetHeight);
204
+ }, []);
205
+ re(() => {
206
+ if (!C || a) return;
185
207
  const e = requestAnimationFrame(() => {
186
- B.current && B.current?.scrollIntoView({
208
+ Y.current && Y.current?.scrollIntoView({
187
209
  behavior: "instant",
188
210
  block: "center"
189
211
  });
190
212
  });
191
213
  return () => cancelAnimationFrame(e);
192
- }, [u]), ae(() => {
193
- const e = P.current;
194
- if (!u || !e) {
195
- G(void 0);
214
+ }, [C, a]), re(() => {
215
+ const e = ie.current;
216
+ if (!e || !K) {
217
+ oe(!1), se(Number.POSITIVE_INFINITY);
196
218
  return;
197
219
  }
198
- const l = () => G(W()?.id);
199
- l();
200
- const t = new MutationObserver(l);
201
- return t.observe(e, {
202
- subtree: !0,
203
- childList: !0,
204
- attributes: !0,
205
- attributeFilter: ["aria-selected"]
206
- }), () => t.disconnect();
207
- }, [u, Z, W]), /* @__PURE__ */ c("div", { className: S("flex flex-col gap-1.5", be), children: [
208
- b && /* @__PURE__ */ r(Xe, { id: $, className: pe, children: b }),
209
- /* @__PURE__ */ c(
210
- Ue,
220
+ const t = () => {
221
+ const l = e.scrollWidth > e.clientWidth, p = Array.from(e.children).filter(
222
+ (x) => x instanceof HTMLElement
223
+ );
224
+ let o = p.length;
225
+ if (l) {
226
+ const x = e.clientWidth - ht, P = p.findIndex(
227
+ (he) => he.offsetLeft + he.offsetWidth > x
228
+ );
229
+ P !== -1 && (o = Math.max(1, P));
230
+ }
231
+ oe(l), se(o);
232
+ };
233
+ if (t(), typeof ResizeObserver > "u") return;
234
+ const r = new ResizeObserver(t);
235
+ r.observe(e);
236
+ for (const l of Array.from(e.children))
237
+ r.observe(l);
238
+ return () => r.disconnect();
239
+ }, [s, K]);
240
+ const pe = (e, t) => /* @__PURE__ */ h(
241
+ at,
242
+ {
243
+ variant: "secondary",
244
+ className: "bg-d-secondary/50 border-d-border flex max-w-full items-center gap-1 border",
245
+ children: [
246
+ /* @__PURE__ */ n("span", { className: "min-w-0 truncate", children: e.label }),
247
+ !e.fixed && !e.disabled && /* @__PURE__ */ n(
248
+ "button",
249
+ {
250
+ type: "button",
251
+ tabIndex: t ? void 0 : -1,
252
+ disabled: d,
253
+ "aria-label": `Rimuovi ${ye(e)}`,
254
+ className: "hover:bg-d-secondary focus-visible:ring-d-ring -my-0.5 -mr-1.5 flex shrink-0 cursor-pointer items-center rounded-sm p-0.5 outline-none focus-visible:ring-2 focus-visible:ring-inset",
255
+ onMouseDown: (r) => r.preventDefault(),
256
+ onClick: (r) => {
257
+ r.stopPropagation(), r.preventDefault();
258
+ const l = r.currentTarget, p = t && document.activeElement === l, o = p ? Array.from(
259
+ l.closest('[role="list"]')?.querySelectorAll("button") ?? []
260
+ ) : [], x = o.indexOf(l);
261
+ if (ce(e), !p) return;
262
+ const P = o[x + 1] ?? o[x - 1];
263
+ requestAnimationFrame(() => {
264
+ P?.isConnected ? P.focus() : U();
265
+ });
266
+ },
267
+ children: /* @__PURE__ */ n(E, { name: "X", size: "xs" })
268
+ }
269
+ )
270
+ ]
271
+ }
272
+ ), te = a && s.length > 0 ? `${s.length} ${s.length === 1 ? "selezionato" : "selezionati"}: ${s.map(ye).join(", ")}` : void 0;
273
+ return /* @__PURE__ */ h("div", { className: g("flex flex-col gap-1.5", Ae), children: [
274
+ b && // The trigger is a div, so `htmlFor` cannot bind to it: it is named via
275
+ // aria-labelledby and a click here focuses it, like a native <select>.
276
+ /* @__PURE__ */ h(
277
+ st,
211
278
  {
212
- open: N ? !1 : u,
213
- onOpenChange: (e) => {
214
- N || (e && V(H), I(e));
279
+ id: A,
280
+ className: g(
281
+ "gap-0.5",
282
+ !d && "cursor-pointer",
283
+ Le
284
+ ),
285
+ onClick: () => {
286
+ d || X.current?.focus();
215
287
  },
288
+ children: [
289
+ b,
290
+ le && !M && /* @__PURE__ */ n("span", { "aria-hidden": !0, children: "*" }),
291
+ M && /* @__PURE__ */ n("span", { "aria-hidden": !0, className: "text-d-destructive", children: "*" })
292
+ ]
293
+ }
294
+ ),
295
+ /* @__PURE__ */ h(
296
+ ut,
297
+ {
298
+ open: d ? !1 : C,
299
+ onOpenChange: (e) => !d && V(e),
216
300
  modal: !1,
217
301
  children: [
218
- /* @__PURE__ */ r(_e, { asChild: !0, children: /* @__PURE__ */ c(
302
+ /* @__PURE__ */ n(ft, { asChild: !0, children: /* @__PURE__ */ h(
219
303
  "div",
220
304
  {
221
- ref: F,
222
- id: Ce,
223
- "data-testid": we,
305
+ ...Fe,
306
+ ref: X,
307
+ id: Te,
308
+ "data-testid": Be,
224
309
  role: "combobox",
225
- tabIndex: N ? -1 : 0,
226
- "aria-haspopup": "listbox",
227
- "aria-controls": Z,
228
- "aria-activedescendant": u ? Se : void 0,
229
- "aria-labelledby": b ? `${$} ${z}` : j || void 0,
230
- "aria-label": b || j ? void 0 : J ?? q,
231
- "aria-disabled": N || void 0,
232
- onKeyDown: Me,
233
- className: S(
234
- p.input.base,
235
- p.radius.default,
236
- p.focusRingWithin,
310
+ "aria-expanded": C,
311
+ "aria-haspopup": "dialog",
312
+ "aria-disabled": d || void 0,
313
+ "aria-required": le || void 0,
314
+ "aria-invalid": M || void 0,
315
+ "aria-labelledby": b ? a ? A : `${A} ${q}` : L || void 0,
316
+ "aria-label": b || L ? void 0 : G ?? D,
317
+ "aria-describedby": [_e, te && de].filter(Boolean).join(" ") || void 0,
318
+ tabIndex: d ? -1 : 0,
319
+ onKeyDown: (e) => {
320
+ Ve?.(e), e.defaultPrevented || Ze(e);
321
+ },
322
+ className: g(
323
+ c.input.base,
324
+ c.radius.default,
325
+ // focus-visible, not focus-within: the trigger is the focusable
326
+ // element, and focus-within would keep the ring after a mouse
327
+ // pick and light it when an inner clear button is focused.
328
+ c.focusRing,
237
329
  "flex w-full min-w-[100px] cursor-pointer items-center justify-between gap-2",
238
- u && p.activeRing,
239
- Ye[ye],
240
- N && "cursor-not-allowed opacity-50",
241
- he
330
+ // Multiple: the open popover covers the trigger, and its ring
331
+ // would only show as a halo around the popover's edge.
332
+ C && !a && c.activeRing,
333
+ // aria-invalid: out-specifies activeRing and sorts after
334
+ // focus-visible, so the error wins while open or focused.
335
+ c.input.invalid,
336
+ ve[ne],
337
+ d && "cursor-not-allowed opacity-50",
338
+ De
242
339
  ),
243
340
  children: [
244
- f.length === 0 ? /* @__PURE__ */ r("span", { id: z, className: "text-d-muted-foreground", children: q }) : a ? /* @__PURE__ */ c("div", { className: "flex h-full w-full min-w-0 items-center justify-between gap-2", children: [
245
- /* @__PURE__ */ r(
341
+ s.length === 0 ? /* @__PURE__ */ n("span", { id: q, className: "text-d-muted-foreground", children: D }) : a ? /* @__PURE__ */ h("div", { className: "flex h-full w-full min-w-0 items-center justify-between gap-2", children: [
342
+ /* @__PURE__ */ n(
246
343
  "div",
247
344
  {
248
- id: z,
249
- className: "flex min-w-0 flex-nowrap gap-1 overflow-auto",
250
- children: ve ? f.map(
251
- (e) => D ? D(e) : /* @__PURE__ */ c(
252
- Fe,
253
- {
254
- variant: "secondary",
255
- className: "hover:bg-d-secondary/100 bg-d-secondary/50 border-d-border flex cursor-pointer items-center gap-1 border",
256
- onClick: (l) => {
257
- l.stopPropagation(), te(e);
258
- },
259
- children: [
260
- e.label,
261
- !e.fixed && /* @__PURE__ */ r(O, { name: "X", size: "xs" })
262
- ]
263
- },
264
- e.value
265
- )
266
- ) : /* @__PURE__ */ r("div", { children: me(f.length) })
345
+ ref: ie,
346
+ id: q,
347
+ "aria-hidden": !0,
348
+ className: g(
349
+ "relative flex min-w-0 flex-1 flex-nowrap items-center gap-1 overflow-hidden",
350
+ // mask-image instead of a colored gradient: the trigger
351
+ // background can be overridden via className and turns
352
+ // translucent when disabled.
353
+ Ke && "[mask-image:linear-gradient(to_right,#000_calc(100%-1.5rem),transparent)]"
354
+ ),
355
+ children: K ? s.map((e, t) => /* @__PURE__ */ n(
356
+ "span",
357
+ {
358
+ inert: t >= Ge,
359
+ className: "flex max-w-full min-w-0 shrink-0",
360
+ children: B ? B(e) : pe(e, !1)
361
+ },
362
+ e.value
363
+ )) : /* @__PURE__ */ n("div", { className: "truncate", children: Re(s.length) })
267
364
  }
268
365
  ),
269
- a && /* @__PURE__ */ r(
270
- "div",
366
+ Ye && /* @__PURE__ */ n(
367
+ "button",
271
368
  {
272
- className: "border-d-input bg-d-accent cursor-pointer rounded-full p-1",
369
+ type: "button",
370
+ disabled: d,
371
+ className: xe,
273
372
  onClick: (e) => {
274
- e.stopPropagation(), e.preventDefault(), le();
373
+ e.stopPropagation(), e.preventDefault(), ue();
275
374
  },
276
375
  onMouseDown: (e) => e.preventDefault(),
277
- "aria-label": "Clear selection",
278
- children: /* @__PURE__ */ r(
279
- O,
280
- {
281
- name: "X",
282
- size: "xs",
283
- className: "!text-d-foreground opacity-50"
284
- }
285
- )
376
+ "aria-label": "Rimuovi tutte le selezioni",
377
+ children: /* @__PURE__ */ n(E, { name: "X", size: "xs", className: "!text-d-foreground" })
286
378
  }
287
379
  )
288
- ] }) : /* @__PURE__ */ c("div", { className: "flex h-full w-full min-w-0 items-center justify-between gap-2", children: [
289
- /* @__PURE__ */ r("div", { id: z, className: "min-w-0 flex-1 truncate", children: D ? D(f[0]) : typeof f[0]?.label == "string" ? /* @__PURE__ */ r("span", { children: f[0]?.label }) : f[0]?.label }),
290
- xe && v !== void 0 && v !== null && /* @__PURE__ */ r(
291
- "div",
380
+ ] }) : /* @__PURE__ */ h("div", { className: "flex h-full w-full min-w-0 items-center justify-between gap-2", children: [
381
+ /* @__PURE__ */ n("div", { id: q, className: "min-w-0 flex-1 truncate", children: B ? B(s[0]) : typeof s[0]?.label == "string" ? /* @__PURE__ */ n("span", { children: s[0]?.label }) : s[0]?.label }),
382
+ Oe && s.length > 0 && /* @__PURE__ */ n(
383
+ "button",
292
384
  {
293
- role: "button",
294
- className: "border-d-input bg-d-accent cursor-pointer rounded-full p-1",
385
+ type: "button",
386
+ disabled: d,
387
+ className: xe,
295
388
  onClick: (e) => {
296
- e.stopPropagation(), e.preventDefault(), le();
389
+ e.stopPropagation(), e.preventDefault(), ue();
297
390
  },
298
391
  onMouseDown: (e) => e.preventDefault(),
299
- "aria-label": "Clear selection",
300
- children: /* @__PURE__ */ r(
301
- O,
302
- {
303
- name: "X",
304
- size: "xs",
305
- className: "!text-d-foreground opacity-50"
306
- }
307
- )
392
+ "aria-label": "Rimuovi selezione",
393
+ children: /* @__PURE__ */ n(E, { name: "X", size: "xs", className: "!text-d-foreground" })
308
394
  }
309
395
  )
310
396
  ] }),
311
- /* @__PURE__ */ r(Qe, { className: "h-4 w-4 opacity-50" })
397
+ /* @__PURE__ */ n(pt, { className: "h-4 w-4 opacity-50" })
312
398
  ]
313
399
  }
314
400
  ) }),
315
- /* @__PURE__ */ r(
316
- Je,
401
+ /* @__PURE__ */ n(
402
+ mt,
317
403
  {
318
- container: Ne,
319
- className: "p-0",
320
- style: { width: Q > 0 ? Q : "auto" },
404
+ container: Me,
405
+ "aria-labelledby": b ? A : L || void 0,
406
+ "aria-label": b || L ? void 0 : G ?? D,
407
+ className: g(
408
+ "p-0",
409
+ // Multiple: the popover covers the trigger (see sideOffset), so it
410
+ // only fades — sliding or zooming would move the chips it lands
411
+ // on. The overrides beat tw-animate-css's zoom/slide variables.
412
+ // The height cap keeps it inside the viewport: the list shrinks.
413
+ // Flipped above the trigger (data-side=top, set by Radix after
414
+ // measuring), the order is reversed so that the top row still lands
415
+ // on the trigger, now at the bottom. Variants rather than React
416
+ // state: the side is known only once positioned, so no wrong frame.
417
+ a && "group/select-popover flex max-h-[var(--radix-popover-content-available-height)] flex-col ![--tw-enter-scale:1] ![--tw-enter-translate-x:0] ![--tw-enter-translate-y:0] ![--tw-exit-scale:1] data-[side=top]:flex-col-reverse",
418
+ a && M && "border-d-destructive"
419
+ ),
420
+ style: {
421
+ width: y.width > 0 ? y.width : "auto"
422
+ },
321
423
  align: "start",
322
- sideOffset: 4,
424
+ sideOffset: a ? -y.height : 4,
323
425
  avoidCollisions: !0,
324
426
  collisionPadding: 8,
325
- onOpenAutoFocus: (e) => e.preventDefault(),
326
- children: /* @__PURE__ */ c(
327
- Be,
427
+ onOpenAutoFocus: (e) => {
428
+ e.preventDefault();
429
+ const t = Z.current;
430
+ Z.current = !1, H || t ? U() : a && F.current?.focus();
431
+ },
432
+ children: /* @__PURE__ */ h(
433
+ rt,
328
434
  {
329
- ref: Ae,
330
- value: ze,
331
- onValueChange: V,
332
- shouldFilter: T,
333
- filter: (e, l, t) => {
334
- const s = l.toLocaleLowerCase();
335
- return s ? [e, ...t ?? []].some(
336
- (o) => o.toLocaleLowerCase().includes(s)
337
- ) ? 1 : 0 : 1;
338
- },
339
- className: "w-full",
435
+ allowPinchZoom: !0,
436
+ noIsolation: !qe,
437
+ removeScrollBar: !1,
438
+ className: "contents",
340
439
  children: [
341
- (T || a && L) && /* @__PURE__ */ c(
440
+ a && // The top row lines up with the covered trigger: same horizontal
441
+ // padding and a trigger-high first row. The popover border is 1px
442
+ // like the trigger's, so the content starts at the same point.
443
+ // bg-d-input and the corner radius on the trigger's side: some
444
+ // themes give the input a different surface than the popover.
445
+ /* @__PURE__ */ n(
342
446
  "div",
343
447
  {
344
- className: S(
345
- "relative",
346
- a && L && "[&_[data-slot=command-d-input-wrapper]>svg]:hidden"
448
+ className: g(
449
+ ve[ne],
450
+ c.radius.default,
451
+ // box-content: the one-row min-height below excludes the 1px
452
+ // separator, so the row can shrink down to exactly the trigger.
453
+ "border-d-border bg-d-input box-content flex h-auto flex-col border-b py-0",
454
+ "rounded-b-none group-data-[side=top]/select-popover:rounded-t-none group-data-[side=top]/select-popover:rounded-b-md group-data-[side=top]/select-popover:border-t group-data-[side=top]/select-popover:border-b-0"
347
455
  ),
348
- children: [
349
- T ? /* @__PURE__ */ r(
350
- $e,
351
- {
352
- placeholder: de,
353
- className: S(
354
- "placeholder:text-d-muted-foreground",
355
- a && L && "pl-7"
356
- ),
357
- value: g,
358
- onValueChange: E
359
- }
360
- ) : /* @__PURE__ */ r("div", { className: "border-d-border h-9 border-b" }),
361
- a && L && /* @__PURE__ */ r(
362
- He,
363
- {
364
- type: "button",
365
- variant: "ghost",
366
- size: "sm",
367
- disabled: h.length === 0,
368
- "aria-label": y === "all" ? "Deselect all" : "Select all",
369
- "aria-checked": y === "all" ? !0 : y === "some" ? "mixed" : !1,
370
- role: "checkbox",
371
- className: "text-d-muted-foreground hover:text-d-foreground absolute top-1/2 left-2 size-6 -translate-y-1/2 px-0",
372
- onMouseDown: (e) => {
373
- e.stopPropagation(), e.preventDefault();
374
- },
375
- onClick: (e) => {
376
- e.stopPropagation(), e.preventDefault(), Re();
377
- },
378
- children: /* @__PURE__ */ r(
379
- O,
380
- {
381
- name: h.length === 0 ? "SquareDot" : y === "all" ? "SquareCheck" : y === "some" ? "SquareMinus" : "Square",
382
- size: "xs"
383
- }
456
+ style: {
457
+ paddingLeft: y.paddingLeft,
458
+ // With badges the right padding moves into the scrolling list,
459
+ // so its scrollbar sits against the popover edge.
460
+ paddingRight: me ? 0 : y.paddingRight,
461
+ // One row: on a short viewport the badge area shrinks down to
462
+ // its first row (and scrolls) instead of squeezing the list.
463
+ minHeight: y.innerHeight
464
+ },
465
+ children: me ? /* @__PURE__ */ n(
466
+ "div",
467
+ {
468
+ ref: et,
469
+ role: "list",
470
+ "aria-label": "Selezionati",
471
+ tabIndex: Ue ? void 0 : 0,
472
+ className: g(
473
+ c.focusRing,
474
+ c.radius.sm,
475
+ // Flipped: the first row goes at the bottom, on the trigger.
476
+ "flex max-h-24 flex-wrap gap-1 overflow-y-auto overscroll-contain group-data-[side=top]/select-popover:flex-wrap-reverse"
477
+ ),
478
+ style: {
479
+ paddingRight: y.paddingRight,
480
+ paddingBlock: Math.max(
481
+ 0,
482
+ (y.innerHeight - $e) / 2
384
483
  )
385
- }
386
- )
387
- ]
484
+ },
485
+ children: s.map((e) => /* @__PURE__ */ n(
486
+ "span",
487
+ {
488
+ role: "listitem",
489
+ className: "flex max-w-full min-w-0",
490
+ children: pe(e, !0)
491
+ },
492
+ e.value
493
+ ))
494
+ }
495
+ ) : /* @__PURE__ */ n(
496
+ "div",
497
+ {
498
+ "aria-hidden": !0,
499
+ className: "text-d-muted-foreground flex items-center",
500
+ style: { minHeight: y.innerHeight },
501
+ children: D
502
+ }
503
+ )
388
504
  }
389
505
  ),
390
- /* @__PURE__ */ c(
391
- Ge,
506
+ /* @__PURE__ */ h(
507
+ nt,
392
508
  {
393
- "aria-labelledby": b ? $ : j || void 0,
394
- label: typeof b == "string" && b ? b : J ?? q,
395
- className: "max-h-60 overflow-auto overscroll-contain",
509
+ ref: F,
510
+ defaultValue: "__none__",
511
+ shouldFilter: H,
512
+ filter: (e, t, r) => {
513
+ const l = t.toLocaleLowerCase();
514
+ return (r?.length ? r : [e]).some(
515
+ (o) => o.toLocaleLowerCase().includes(l)
516
+ ) ? 1 : 0;
517
+ },
518
+ className: g(
519
+ "w-full",
520
+ // Flipped: search next to the top row (now at the bottom), list
521
+ // above it; separators move to the other side.
522
+ a && "min-h-0 group-data-[side=top]/select-popover:flex-col-reverse"
523
+ ),
396
524
  children: [
397
- /* @__PURE__ */ r(We, { children: ce }),
398
- ge && g && /* @__PURE__ */ r(ne, { children: /* @__PURE__ */ r(
399
- se,
525
+ (H || a && _) && /* @__PURE__ */ h(
526
+ "div",
400
527
  {
401
- className: "cursor-pointer",
402
- onSelect: () => {
403
- g && (m(a ? [...n, g] : g), E(""), a || I(!1));
404
- },
405
- children: /* @__PURE__ */ c("div", { className: "text-d-foreground text-xs", children: [
406
- ue,
407
- " “",
408
- g,
409
- "”"
410
- ] })
528
+ className: g(
529
+ "relative",
530
+ a && _ && "[&_[data-slot=command-d-input-wrapper]>svg]:hidden",
531
+ a && "group-data-[side=top]/select-popover:[&>[data-slot=command-d-input-wrapper]]:border-t group-data-[side=top]/select-popover:[&>[data-slot=command-d-input-wrapper]]:border-b-0"
532
+ ),
533
+ children: [
534
+ H ? /* @__PURE__ */ n(
535
+ lt,
536
+ {
537
+ placeholder: Ie,
538
+ className: g(
539
+ "placeholder:text-d-muted-foreground",
540
+ a && _ && "pl-7"
541
+ ),
542
+ value: N,
543
+ onValueChange: W
544
+ }
545
+ ) : /* @__PURE__ */ n("div", { className: "border-d-border h-9 border-b group-data-[side=top]/select-popover:border-t group-data-[side=top]/select-popover:border-b-0" }),
546
+ a && _ && /* @__PURE__ */ n(
547
+ dt,
548
+ {
549
+ type: "button",
550
+ variant: "ghost",
551
+ size: "sm",
552
+ disabled: w.length === 0,
553
+ "aria-label": S === "all" ? "Deseleziona tutto" : "Seleziona tutto",
554
+ "aria-checked": S === "all" ? !0 : S === "some" ? "mixed" : !1,
555
+ role: "checkbox",
556
+ className: g(
557
+ "text-d-muted-foreground hover:text-d-foreground absolute inset-y-0 left-2 my-auto size-6 px-0",
558
+ S === "all" && "text-d-primary hover:text-d-primary interactive:hover:text-d-primary"
559
+ ),
560
+ onMouseDown: (e) => {
561
+ e.stopPropagation(), e.preventDefault();
562
+ },
563
+ onClick: (e) => {
564
+ e.stopPropagation(), e.preventDefault(), Je();
565
+ },
566
+ children: /* @__PURE__ */ n(
567
+ E,
568
+ {
569
+ name: w.length === 0 ? "SquareDot" : S === "all" ? "SquareCheck" : S === "some" ? "SquareMinus" : "Square",
570
+ size: "xs"
571
+ }
572
+ )
573
+ }
574
+ )
575
+ ]
411
576
  }
412
- ) }),
413
- Object.entries(qe).map(([e, l]) => /* @__PURE__ */ r(ne, { heading: e || void 0, children: l.map((t) => {
414
- const s = n.includes(t.value), k = a && i !== void 0 && !s && n.length >= i, o = t.disabled || k;
415
- return /* @__PURE__ */ c(
416
- se,
417
- {
418
- ref: s ? B : null,
419
- value: String(t.value).trim(),
420
- keywords: typeof t.label == "string" ? [t.label] : void 0,
421
- disabled: o || void 0,
422
- "aria-checked": a ? s : void 0,
423
- onSelect: () => !o && te(t),
424
- className: S(
425
- "cursor-pointer",
426
- p.dropdownItem.hover,
427
- o && "cursor-not-allowed opacity-50",
428
- !a && s && p.dropdownItem.selected
429
- ),
430
- children: [
431
- a && /* @__PURE__ */ r(
432
- Ke,
433
- {
434
- checked: s,
435
- "aria-hidden": "true",
436
- tabIndex: -1,
437
- className: "mr-1"
438
- }
439
- ),
440
- typeof t.label == "string" ? /* @__PURE__ */ r("span", { children: t.label }) : t.label
441
- ]
442
- },
443
- t.value
444
- );
445
- }) }, e))
577
+ ),
578
+ /* @__PURE__ */ h(
579
+ it,
580
+ {
581
+ "aria-labelledby": b ? A : L || void 0,
582
+ label: typeof b == "string" && b ? b : G ?? D,
583
+ className: "max-h-60 overflow-auto overscroll-contain",
584
+ children: [
585
+ /* @__PURE__ */ n(ot, { children: Se }),
586
+ Pe && N && /* @__PURE__ */ n(ge, { children: /* @__PURE__ */ n(
587
+ be,
588
+ {
589
+ className: "cursor-pointer",
590
+ onSelect: () => {
591
+ N && (v(a ? [...i, N] : N), W(""), a || V(!1));
592
+ },
593
+ children: /* @__PURE__ */ h("div", { className: "text-d-foreground text-xs", children: [
594
+ ke,
595
+ " “",
596
+ N,
597
+ "”"
598
+ ] })
599
+ }
600
+ ) }),
601
+ Object.entries(Qe).map(([e, t]) => /* @__PURE__ */ n(
602
+ ge,
603
+ {
604
+ heading: e || void 0,
605
+ className: "[&_[cmdk-group-heading]]:bg-d-muted [&_[cmdk-group-heading]]:rounded-sm",
606
+ children: t.map((r) => {
607
+ const l = i.includes(r.value), p = a && m !== void 0 && !l && i.length >= m, o = a && l && r.fixed, x = r.disabled || p || o;
608
+ return /* @__PURE__ */ h(
609
+ be,
610
+ {
611
+ ref: !a && l ? Y : null,
612
+ value: String(r.value).trim(),
613
+ keywords: we(r),
614
+ disabled: x || void 0,
615
+ "aria-checked": a ? l : void 0,
616
+ onSelect: () => !x && ce(r),
617
+ className: g(
618
+ "cursor-pointer",
619
+ c.dropdownItem.hover,
620
+ x && "cursor-not-allowed opacity-50",
621
+ !a && l && c.dropdownItem.selected
622
+ ),
623
+ children: [
624
+ a && /* @__PURE__ */ n(
625
+ ct,
626
+ {
627
+ checked: l,
628
+ "aria-hidden": "true",
629
+ tabIndex: -1,
630
+ className: "mr-1"
631
+ }
632
+ ),
633
+ typeof r.label == "string" ? /* @__PURE__ */ n("span", { children: r.label }) : r.label
634
+ ]
635
+ },
636
+ r.value
637
+ );
638
+ })
639
+ },
640
+ e
641
+ ))
642
+ ]
643
+ }
644
+ ),
645
+ a && m !== void 0 && i.length >= m && /* @__PURE__ */ n("div", { className: "border-d-border text-d-muted-foreground border-t px-2 py-1 text-xs group-data-[side=top]/select-popover:border-t-0 group-data-[side=top]/select-popover:border-b", children: ze(m) })
446
646
  ]
447
647
  }
448
- ),
449
- a && i !== void 0 && n.length >= i && /* @__PURE__ */ r("div", { className: "border-d-border text-d-muted-foreground border-t px-2 py-1 text-xs", children: fe(i) })
648
+ )
450
649
  ]
451
650
  }
452
651
  )
@@ -454,9 +653,10 @@ function ut(A) {
454
653
  )
455
654
  ]
456
655
  }
457
- )
656
+ ),
657
+ te && /* @__PURE__ */ n("span", { id: de, className: "sr-only", children: te })
458
658
  ] });
459
659
  }
460
660
  export {
461
- ut as AppSelect
661
+ Lt as AppSelect
462
662
  };