@tetrascience-npm/tetrascience-react-ui 1.0.0-beta.146.1 → 1.0.0-beta.147.1

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.
package/dist/ui/tree.js CHANGED
@@ -1,244 +1,359 @@
1
- import { jsx as a, jsxs as A } from "react/jsx-runtime";
2
- import { useControllableState as j } from "@radix-ui/react-use-controllable-state";
3
- import { cva as W } from "class-variance-authority";
4
- import { ChevronRightIcon as Y } from "lucide-react";
5
- import * as n from "react";
6
- import { TooltipProvider as J, Tooltip as Q, TooltipTrigger as X, TooltipContent as Z } from "./tooltip.js";
7
- import { cn as E } from "../lib/utils.js";
8
- const O = n.createContext(null);
9
- function G(e) {
10
- const r = n.useContext(O);
1
+ import { jsx as i, jsxs as q, Fragment as se } from "react/jsx-runtime";
2
+ import { useControllableState as J } from "@radix-ui/react-use-controllable-state";
3
+ import { cva as le } from "class-variance-authority";
4
+ import { ChevronRightIcon as ie } from "lucide-react";
5
+ import * as o from "react";
6
+ import { TooltipProvider as ce, Tooltip as ue, TooltipTrigger as de, TooltipContent as fe } from "./tooltip.js";
7
+ import { cn as N } from "../lib/utils.js";
8
+ const ee = o.createContext(null), te = o.createContext(null);
9
+ function re(e) {
10
+ const r = o.useContext(ee);
11
11
  if (!r)
12
12
  throw new Error(`\`${e}\` must be rendered inside a \`Tree\`.`);
13
13
  return r;
14
14
  }
15
- const B = n.createContext(1), H = n.createContext({
15
+ const U = o.createContext(1), ne = o.createContext({
16
16
  posinset: 1,
17
17
  setsize: 1,
18
18
  lastBranchPos: 0
19
- }), K = n.createContext(null), ee = [];
20
- function M(e) {
21
- const r = n.useContext(K);
19
+ }), W = o.createContext(null), me = [];
20
+ function Y(e) {
21
+ const r = o.useContext(W);
22
22
  if (!r)
23
23
  throw new Error(`\`${e}\` must be rendered inside a \`TreeItem\`.`);
24
24
  return r;
25
25
  }
26
- function ue() {
27
- return M("useTreeItem");
26
+ function Se() {
27
+ return Y("useTreeItem");
28
28
  }
29
- function te(e) {
30
- return n.useMemo(() => {
31
- const r = n.Children.toArray(e), t = r.filter(n.isValidElement), o = t.length, l = (c) => c.props?.hasChildren === !0, u = t.reduce((c, p, v) => l(p) ? v + 1 : c, 0);
32
- let x = 0;
33
- return r.map((c, p) => n.isValidElement(c) ? (x += 1, /* @__PURE__ */ a(H.Provider, { value: { posinset: x, setsize: o, lastBranchPos: u }, children: c }, c.key ?? p)) : c);
29
+ function pe(e) {
30
+ return o.useMemo(() => {
31
+ const r = o.Children.toArray(e), t = r.filter(o.isValidElement), s = t.length, a = (l) => l.props?.hasChildren === !0, c = t.reduce((l, m, p) => a(m) ? p + 1 : l, 0);
32
+ let u = 0;
33
+ return r.map((l, m) => o.isValidElement(l) ? (u += 1, /* @__PURE__ */ i(ne.Provider, { value: { posinset: u, setsize: s, lastBranchPos: c }, children: l }, l.key ?? m)) : l);
34
34
  }, [e]);
35
35
  }
36
- const R = '[role="treeitem"]';
37
- function $(e) {
38
- return e ? [...e.querySelectorAll(R)] : [];
36
+ const M = '[role="treeitem"]';
37
+ function D(e) {
38
+ return e ? [...e.querySelectorAll(M)] : [];
39
39
  }
40
- function re(e, r) {
40
+ const he = '[role="group"], [role="tree"]';
41
+ function G(e, r) {
42
+ return D(e).find((t) => t.dataset.treeItemId === r);
43
+ }
44
+ function Q(e) {
45
+ return e.parentElement?.closest(he) ?? null;
46
+ }
47
+ function ge(e) {
48
+ const r = [];
49
+ for (let t = e.parentElement?.closest(M); t; )
50
+ t.dataset.treeItemId && r.unshift(t.dataset.treeItemId), t = t.parentElement?.closest(M);
51
+ return r;
52
+ }
53
+ function oe(e) {
54
+ if (e.nodeType === Node.TEXT_NODE) return e.textContent ?? "";
55
+ if (!(e instanceof HTMLElement) || e.getAttribute("aria-hidden") === "true") return "";
56
+ let r = "";
57
+ for (const t of e.childNodes) r += oe(t);
58
+ return r;
59
+ }
60
+ function xe(e) {
61
+ const r = e.getAttribute("aria-labelledby"), t = r ? e.ownerDocument.getElementById(r) : null;
62
+ return (t ? oe(t) : "").trim().toLowerCase();
63
+ }
64
+ function be(e, r, t) {
65
+ const s = G(e, r);
66
+ if (s) return s;
67
+ for (let a = t.length - 1; a >= 0; a -= 1) {
68
+ const c = G(e, t[a]);
69
+ if (c) return c;
70
+ }
71
+ return D(e)[0];
72
+ }
73
+ function Ie(e, r) {
41
74
  const t = e?.dataset.treeItemId;
42
75
  !e || !t || (r(t), e.focus());
43
76
  }
44
- function L({ event: e, setFocusedId: r }, t) {
45
- e.preventDefault(), re(t, r);
77
+ const Te = 600, ve = 800;
78
+ function K({ event: e, setFocusedId: r }, t) {
79
+ e.preventDefault(), Ie(t, r);
46
80
  }
47
- function F(e, r) {
48
- const t = $(e.root);
49
- L(e, t[t.indexOf(e.current) + r]);
81
+ function Z(e, r) {
82
+ const t = D(e.root);
83
+ K(e, t[t.indexOf(e.current) + r]);
50
84
  }
51
- const ne = {
52
- ArrowDown: (e) => F(e, 1),
53
- ArrowUp: (e) => F(e, -1),
85
+ const ye = {
86
+ ArrowDown: (e) => Z(e, 1),
87
+ ArrowUp: (e) => Z(e, -1),
54
88
  ArrowRight: (e) => {
55
- const { event: r, current: t, id: o, hasChildren: l, expanded: u, setExpanded: x } = e;
56
- if (l && !u) {
57
- r.preventDefault(), x(o, !0);
89
+ const { event: r, current: t, id: s, hasChildren: a, expanded: c, setExpanded: u } = e;
90
+ if (a && !c) {
91
+ r.preventDefault(), u(s, !0);
58
92
  return;
59
93
  }
60
- u && L(e, t.querySelector(R));
94
+ c && K(e, t.querySelector(M));
61
95
  },
62
96
  ArrowLeft: (e) => {
63
- const { event: r, current: t, id: o, expanded: l, setExpanded: u } = e;
64
- if (l) {
65
- r.preventDefault(), u(o, !1);
97
+ const { event: r, current: t, id: s, expanded: a, setExpanded: c } = e;
98
+ if (a) {
99
+ r.preventDefault(), c(s, !1);
66
100
  return;
67
101
  }
68
- L(e, t.parentElement?.closest(R));
102
+ K(e, t.parentElement?.closest(M));
69
103
  },
70
- Home: (e) => L(e, $(e.root)[0]),
104
+ Home: (e) => K(e, D(e.root)[0]),
71
105
  End: (e) => {
72
- const r = $(e.root);
73
- L(e, r[r.length - 1]);
106
+ const r = D(e.root);
107
+ K(e, r[r.length - 1]);
74
108
  },
75
109
  Enter: (e) => {
76
110
  e.disabled || (e.event.preventDefault(), e.activate(e.id, e.hasChildren, e.expanded));
111
+ },
112
+ /** Expands every collapsed branch among the focused node's siblings, the node itself included. */
113
+ "*": (e) => {
114
+ const { event: r, root: t, current: s, expandIds: a } = e;
115
+ r.preventDefault();
116
+ const c = Q(s) ?? t, u = D(c).filter((l) => Q(l) === c).filter((l) => l.dataset.treeHasChildren === "true" && l.getAttribute("aria-expanded") !== "true").map((l) => l.dataset.treeItemId).filter((l) => !!l);
117
+ u.length && a(u);
77
118
  }
78
119
  };
79
- function me({
120
+ function Ce(e) {
121
+ return e.key.length === 1 && e.key !== " ";
122
+ }
123
+ function Ee(e) {
124
+ const { event: r, root: t, current: s, typeahead: a, setTypeaheadMatch: c } = e;
125
+ r.preventDefault(), clearTimeout(a.timer), clearTimeout(a.fadeTimer), a.buffer += r.key.toLowerCase();
126
+ const { buffer: u } = a, m = u.length > 1 && [...u].every((x) => x === u[0]) ? u[0] : u;
127
+ c({ query: m, fading: !1 }), a.timer = setTimeout(() => {
128
+ a.buffer = "", c({ query: m, fading: !0 }), a.fadeTimer = setTimeout(() => c(null), ve);
129
+ }, Te);
130
+ const p = D(t), T = p.indexOf(s);
131
+ for (let x = 1; x <= p.length; x += 1) {
132
+ const v = p[(T + x) % p.length];
133
+ if (xe(v).startsWith(m)) {
134
+ K(e, v);
135
+ return;
136
+ }
137
+ }
138
+ }
139
+ function _e({
80
140
  className: e,
81
141
  children: r,
82
142
  expandedIds: t,
83
- defaultExpandedIds: o,
84
- onExpandedChange: l,
85
- selectedId: u,
86
- defaultSelectedId: x = null,
87
- onSelectedChange: c,
88
- onActivate: p,
89
- expandOnSelect: v = !0,
90
- guides: C = "hover",
91
- ...N
143
+ defaultExpandedIds: s,
144
+ onExpandedChange: a,
145
+ selectedId: c,
146
+ defaultSelectedId: u = null,
147
+ onSelectedChange: l,
148
+ onActivate: m,
149
+ expandOnSelect: p = !0,
150
+ guides: T = "hover",
151
+ onFocus: x,
152
+ onBlur: v,
153
+ ...P
92
154
  }) {
93
- const D = n.useRef(null), [w, P] = j({
155
+ const R = o.useRef(null), [y, E] = J({
94
156
  prop: t,
95
- defaultProp: o ?? /* @__PURE__ */ new Set(),
96
- onChange: l
97
- }), [b, z] = j({
98
- prop: u,
99
- defaultProp: x,
100
- onChange: (s) => {
101
- s != null && c?.(s);
157
+ defaultProp: s ?? /* @__PURE__ */ new Set(),
158
+ onChange: a
159
+ }), [C, b] = J({
160
+ prop: c,
161
+ defaultProp: u,
162
+ onChange: (n) => {
163
+ n != null && l?.(n);
102
164
  }
103
- }), [m, g] = n.useState(null), h = n.useCallback(
104
- (s, I) => {
105
- P((d) => {
106
- const k = new Set(d);
107
- return I ? k.add(s) : k.delete(s), k;
165
+ }), [h, L] = o.useState(null), [w, S] = o.useState(null), [f, k] = o.useState(null), O = o.useRef([]), _ = o.useRef(!1), B = o.useRef({ buffer: "", timer: void 0, fadeTimer: void 0 });
166
+ o.useEffect(
167
+ () => () => {
168
+ clearTimeout(B.current.timer), clearTimeout(B.current.fadeTimer);
169
+ },
170
+ []
171
+ );
172
+ const A = o.useCallback(
173
+ (n, g) => {
174
+ E((d) => {
175
+ const I = new Set(d);
176
+ return g ? I.add(n) : I.delete(n), I;
177
+ });
178
+ },
179
+ [E]
180
+ ), z = o.useCallback(
181
+ (n) => {
182
+ E((g) => {
183
+ const d = new Set(g);
184
+ for (const I of n) d.add(I);
185
+ return d;
108
186
  });
109
187
  },
110
- [P]
111
- ), T = n.useCallback(
112
- (s, I, d) => {
113
- z(s), v && I && h(s, !d), p?.(s);
188
+ [E]
189
+ ), H = o.useCallback(
190
+ (n, g, d) => {
191
+ b(n), p && g && A(n, !d), m?.(n);
114
192
  },
115
- [z, v, h, p]
116
- ), y = n.useCallback(
117
- (s) => {
118
- const I = D.current, d = s.target?.closest(R), k = d?.dataset.treeItemId;
119
- if (!I || !d || !k || !I.contains(d)) return;
120
- const S = ne[s.key];
121
- S && S({
122
- event: s,
123
- root: I,
193
+ [b, p, A, m]
194
+ ), F = o.useCallback(
195
+ (n) => {
196
+ const g = R.current, d = n.target?.closest(M), I = d?.dataset.treeItemId;
197
+ if (!g || !d || !I || !g.contains(d) || d !== n.currentTarget || n.ctrlKey || n.metaKey || n.altKey) return;
198
+ const j = ye[n.key] ?? (Ce(n) ? Ee : void 0);
199
+ j && j({
200
+ event: n,
201
+ root: g,
124
202
  current: d,
125
- id: k,
203
+ id: I,
126
204
  hasChildren: d.dataset.treeHasChildren === "true",
127
205
  expanded: d.getAttribute("aria-expanded") === "true",
128
206
  disabled: d.getAttribute("aria-disabled") === "true",
129
- setExpanded: h,
130
- setFocusedId: g,
131
- activate: T
207
+ setExpanded: A,
208
+ expandIds: z,
209
+ setFocusedId: L,
210
+ activate: H,
211
+ typeahead: B.current,
212
+ setTypeaheadMatch: k
132
213
  });
133
214
  },
134
- [h, T]
135
- ), i = n.useMemo(
215
+ [A, z, H]
216
+ ), $ = o.useCallback(() => {
217
+ const n = R.current;
218
+ if (!n) return;
219
+ if (h == null) {
220
+ const X = C != null && !G(n, C) ? D(n)[0]?.dataset.treeItemId ?? null : null;
221
+ X !== w && S(X);
222
+ return;
223
+ }
224
+ const g = be(n, h, O.current), d = g?.dataset.treeItemId;
225
+ if (!g || !d) return;
226
+ d === h ? O.current = ge(g) : L(d);
227
+ const I = n.ownerDocument.activeElement;
228
+ _.current && (!n.contains(I) || I === n) && g.focus();
229
+ }, [h, C, w]);
230
+ o.useLayoutEffect($);
231
+ const V = o.useMemo(
136
232
  () => ({
137
- expandedIds: w ?? /* @__PURE__ */ new Set(),
138
- setExpanded: h,
139
- selectedId: b ?? null,
140
- activateItem: T,
141
- focusedId: m,
142
- setFocusedId: g,
143
- expandOnSelect: v,
144
- guides: C,
145
- onItemKeyDown: y
233
+ expandedIds: y ?? /* @__PURE__ */ new Set(),
234
+ setExpanded: A,
235
+ expandIds: z,
236
+ selectedId: C ?? null,
237
+ activateItem: H,
238
+ focusedId: h,
239
+ setFocusedId: L,
240
+ entryId: w,
241
+ expandOnSelect: p,
242
+ guides: T,
243
+ onItemKeyDown: F
146
244
  }),
147
- [w, h, b, T, m, v, C, y]
245
+ [
246
+ y,
247
+ A,
248
+ z,
249
+ C,
250
+ H,
251
+ h,
252
+ w,
253
+ p,
254
+ T,
255
+ F
256
+ ]
148
257
  );
149
- return /* @__PURE__ */ a(O.Provider, { value: i, children: /* @__PURE__ */ a(B.Provider, { value: 1, children: /* @__PURE__ */ a(
258
+ return /* @__PURE__ */ i(ee.Provider, { value: V, children: /* @__PURE__ */ i(te.Provider, { value: f, children: /* @__PURE__ */ i(U.Provider, { value: 1, children: /* @__PURE__ */ i(
150
259
  "div",
151
260
  {
152
- ref: D,
261
+ ref: R,
153
262
  "data-slot": "tree",
154
- "data-guides": C,
263
+ "data-guides": T,
155
264
  role: "tree",
156
265
  tabIndex: -1,
157
- className: E(
266
+ onFocus: (n) => {
267
+ x?.(n), _.current = !0;
268
+ },
269
+ onBlur: (n) => {
270
+ v?.(n), n.currentTarget.contains(n.relatedTarget) || (_.current = !1);
271
+ },
272
+ className: N(
158
273
  "group/tree text-foreground flex w-full flex-col text-sm",
159
274
  "[--tree-indent:1.25rem] [--tree-guide-color:color-mix(in_oklch,var(--muted-foreground)_40%,var(--background))]",
160
275
  e
161
276
  ),
162
- ...N,
163
- children: /* @__PURE__ */ a(J, { delayDuration: 500, children: /* @__PURE__ */ a(q, { children: r }) })
277
+ ...P,
278
+ children: /* @__PURE__ */ i(ce, { delayDuration: 500, children: /* @__PURE__ */ i(ae, { children: r }) })
164
279
  }
165
- ) }) });
280
+ ) }) }) });
166
281
  }
167
- function q({ children: e }) {
168
- return te(e);
282
+ function ae({ children: e }) {
283
+ return pe(e);
169
284
  }
170
- function fe({
285
+ function Me({
171
286
  className: e,
172
287
  children: r,
173
288
  id: t,
174
- hasChildren: o = !1,
175
- disabled: l = !1,
176
- onClick: u,
177
- onFocus: x,
178
- onKeyDown: c,
179
- style: p,
180
- ...v
289
+ hasChildren: s = !1,
290
+ disabled: a = !1,
291
+ onClick: c,
292
+ onFocus: u,
293
+ onKeyDown: l,
294
+ style: m,
295
+ ...p
181
296
  }) {
182
- const { expandedIds: C, setExpanded: N, selectedId: D, activateItem: w, focusedId: P, setFocusedId: b, onItemKeyDown: z } = G("TreeItem"), m = n.useContext(B), { posinset: g, setsize: h, lastBranchPos: T } = n.useContext(H), y = `${n.useId()}-label`, i = o && C.has(t), s = D === t, I = n.useCallback(() => {
183
- o && N(t, !i);
184
- }, [o, N, t, i]), d = n.useCallback(() => {
185
- l || (b(t), w(t, o, i));
186
- }, [l, b, t, w, o, i]), k = P ? P === t : m === 1 && g === 1, _ = n.useContext(K)?.trunkLevels ?? ee, V = n.useMemo(
187
- () => m > 1 && g < T ? [..._, m - 1] : _,
188
- [_, m, g, T]
189
- ), U = n.useMemo(
297
+ const { expandedIds: T, setExpanded: x, selectedId: v, activateItem: P, focusedId: R, setFocusedId: y, entryId: E, onItemKeyDown: C } = re("TreeItem"), b = o.useContext(U), { posinset: h, setsize: L, lastBranchPos: w } = o.useContext(ne), S = `${o.useId()}-label`, f = s && T.has(t), k = v === t, O = o.useCallback(() => {
298
+ s && x(t, !f);
299
+ }, [s, x, t, f]), _ = o.useCallback(() => {
300
+ a || (y(t), P(t, s, f));
301
+ }, [a, y, t, P, s, f]), B = b === 1 && h === 1, A = v == null ? B : v === t, z = R ? R === t : E ? E === t : A, F = o.useContext(W)?.trunkLevels ?? me, $ = o.useMemo(
302
+ () => b > 1 && h < w ? [...F, b - 1] : F,
303
+ [F, b, h, w]
304
+ ), V = o.useMemo(
190
305
  () => ({
191
306
  id: t,
192
- labelId: y,
193
- level: m,
194
- expanded: i,
195
- hasChildren: o,
196
- selected: s,
197
- disabled: l,
198
- trunkLevels: V,
199
- toggle: I,
200
- select: d
307
+ labelId: S,
308
+ level: b,
309
+ expanded: f,
310
+ hasChildren: s,
311
+ selected: k,
312
+ disabled: a,
313
+ trunkLevels: $,
314
+ toggle: O,
315
+ select: _
201
316
  }),
202
- [t, y, m, i, o, s, l, V, I, d]
317
+ [t, S, b, f, s, k, a, $, O, _]
203
318
  );
204
- return /* @__PURE__ */ a(K.Provider, { value: U, children: /* @__PURE__ */ a(
319
+ return /* @__PURE__ */ i(W.Provider, { value: V, children: /* @__PURE__ */ i(
205
320
  "div",
206
321
  {
207
- ...v,
322
+ ...p,
208
323
  "data-slot": "tree-item",
209
324
  "data-tree-item-id": t,
210
- "data-tree-has-children": o,
211
- "data-state": i ? "expanded" : "collapsed",
325
+ "data-tree-has-children": s,
326
+ "data-state": f ? "expanded" : "collapsed",
212
327
  role: "treeitem",
213
- "aria-labelledby": y,
214
- "aria-expanded": o ? i : void 0,
215
- "aria-level": m,
216
- "aria-posinset": g,
217
- "aria-setsize": h,
218
- "aria-selected": s,
219
- "aria-disabled": l || void 0,
220
- tabIndex: k ? 0 : -1,
221
- onKeyDown: (f) => {
222
- c?.(f), !f.defaultPrevented && z(f);
328
+ "aria-labelledby": S,
329
+ "aria-expanded": s ? f : void 0,
330
+ "aria-level": b,
331
+ "aria-posinset": h,
332
+ "aria-setsize": L,
333
+ "aria-selected": k,
334
+ "aria-disabled": a || void 0,
335
+ tabIndex: z ? 0 : -1,
336
+ onKeyDown: (n) => {
337
+ l?.(n), !n.defaultPrevented && C(n);
223
338
  },
224
- onClick: (f) => {
225
- u?.(f), !f.defaultPrevented && f.target.closest(R) === f.currentTarget && d();
339
+ onClick: (n) => {
340
+ c?.(n), !n.defaultPrevented && n.target.closest(M) === n.currentTarget && _();
226
341
  },
227
- onFocus: (f) => {
228
- x?.(f), f.target === f.currentTarget && b(t);
342
+ onFocus: (n) => {
343
+ u?.(n), n.target === n.currentTarget && y(t);
229
344
  },
230
345
  style: {
231
346
  // Inherited by the label, which draws the elbow from the same two values.
232
- "--tree-guide-left": `calc(var(--tree-indent) * ${m - 2} + 0.6875rem)`,
347
+ "--tree-guide-left": `calc(var(--tree-indent) * ${b - 2} + 0.6875rem)`,
233
348
  // Stops 0.25rem short of the row's chevron rather than touching it, so the connector
234
349
  // reads as pointing at the row instead of welded to the glyph.
235
350
  "--tree-elbow-run": "calc(var(--tree-indent) - 0.6875rem)",
236
351
  // Shared by the elbow's corner and by where the same-column trunk picks up, so the two
237
352
  // meet exactly instead of overlapping or leaving a gap.
238
353
  "--tree-elbow-radius": "0.5rem",
239
- ...p
354
+ ...m
240
355
  },
241
- className: E(
356
+ className: N(
242
357
  "relative outline-none",
243
358
  // Direct-child selectors, deliberately not `group-*/tree-item`: tree items nest, and a
244
359
  // group variant matches *any* ancestor, so a focused or selected parent painted its focus
@@ -251,7 +366,7 @@ function fe({
251
366
  }
252
367
  ) });
253
368
  }
254
- const oe = W(
369
+ const we = le(
255
370
  "flex w-full min-w-0 cursor-default items-center gap-1.5 rounded-md pr-2 text-left transition-colors select-none",
256
371
  {
257
372
  variants: {
@@ -266,31 +381,31 @@ const oe = W(
266
381
  }
267
382
  }
268
383
  );
269
- function pe({ className: e, children: r, size: t, style: o, icon: l, trailing: u, ...x }) {
270
- const { labelId: c, level: p, expanded: v, hasChildren: C, selected: N, disabled: D, trunkLevels: w, toggle: P } = M("TreeItemLabel"), { guides: b } = G("TreeItemLabel"), z = b !== "none" && p > 1 && C, m = b !== "none" && (z || w.length > 0), g = n.useRef(null), [h, T] = n.useState(!1), y = (i) => {
271
- const s = g.current;
272
- T(i && !!s && s.scrollWidth > s.clientWidth);
384
+ function ze({ className: e, children: r, size: t, style: s, icon: a, trailing: c, ...u }) {
385
+ const { labelId: l, level: m, expanded: p, hasChildren: T, selected: x, disabled: v, trunkLevels: P, toggle: R } = Y("TreeItemLabel"), { guides: y } = re("TreeItemLabel"), E = o.useContext(te), C = y !== "none" && m > 1 && T, b = y !== "none" && (C || P.length > 0), h = o.useRef(null), [L, w] = o.useState(!1), S = (f) => {
386
+ const k = h.current;
387
+ w(f && !!k && k.scrollWidth > k.clientWidth);
273
388
  };
274
- return /* @__PURE__ */ A(
389
+ return /* @__PURE__ */ q(
275
390
  "div",
276
391
  {
277
- ...x,
278
- id: c,
392
+ ...u,
393
+ id: l,
279
394
  "data-slot": "tree-item-label",
280
- style: { paddingInlineStart: `calc(var(--tree-indent) * ${p - 1} + 0.25rem)`, ...o },
281
- className: E(
282
- oe({ size: t }),
395
+ style: { paddingInlineStart: `calc(var(--tree-indent) * ${m - 1} + 0.25rem)`, ...s },
396
+ className: N(
397
+ we({ size: t }),
283
398
  "relative border border-transparent",
284
399
  // Only selection paints a background — an open folder is already marked by its rotated
285
400
  // chevron, open-folder icon and the connectors running down from it.
286
- N ? "bg-accent text-accent-foreground font-medium" : "hover:bg-muted",
401
+ x ? "bg-accent text-accent-foreground font-medium" : "hover:bg-muted",
287
402
  // From this node's own state, not an ancestor selector: `aria-disabled` is per-node, so a
288
403
  // disabled folder must not dim the contents underneath it.
289
- D && "pointer-events-none opacity-50",
404
+ v && "pointer-events-none opacity-50",
290
405
  e
291
406
  ),
292
407
  children: [
293
- m ? (
408
+ b ? (
294
409
  // One absolutely-positioned layer owns every guide on this row, fixing two bugs at once.
295
410
  //
296
411
  // Paint order: the trunk used to be drawn by the `TreeItem`, an *ancestor* of every
@@ -303,37 +418,37 @@ function pe({ className: e, children: r, size: t, style: o, icon: l, trailing: u
303
418
  // *padding* box. The label carries `border border-transparent` for its focus ring while the
304
419
  // `TreeItem` carries none, so one `--tree-guide-left` landed 1px apart on the two elements
305
420
  // and the elbow/trunk overlap read as a 2px line. Both now share this container.
306
- /* @__PURE__ */ A(
421
+ /* @__PURE__ */ q(
307
422
  "span",
308
423
  {
309
424
  "data-slot": "tree-item-guides",
310
425
  "aria-hidden": "true",
311
- className: E(
426
+ className: N(
312
427
  "pointer-events-none absolute inset-0",
313
428
  // The fade lives on the container, not on each line. Opacity on the parent renders the
314
429
  // whole layer into one buffer and composites it once, so a seam between two segments
315
430
  // can never double-expose mid-transition.
316
- b === "hover" && "opacity-0 transition-opacity group-hover/tree:opacity-100 motion-reduce:transition-none"
431
+ y === "hover" && "opacity-0 transition-opacity group-hover/tree:opacity-100 motion-reduce:transition-none"
317
432
  ),
318
433
  children: [
319
- w.map((i) => /* @__PURE__ */ a(
434
+ P.map((f) => /* @__PURE__ */ i(
320
435
  "span",
321
436
  {
322
437
  "data-slot": "tree-item-guide-trunk",
323
- style: { left: `calc(var(--tree-indent) * ${i - 1} + 0.6875rem)` },
438
+ style: { left: `calc(var(--tree-indent) * ${f - 1} + 0.6875rem)` },
324
439
  className: "absolute top-[-0.4375rem] bottom-0 w-0 border-l border-[var(--tree-guide-color)]"
325
440
  },
326
- i
441
+ f
327
442
  )),
328
- z ? (
443
+ C ? (
329
444
  // Down the guide line, then a rounded turn right, stopping just short of this row's
330
445
  // chevron. Starts half a chevron above the row so the line emerges from under the
331
446
  // parent's chevron instead of leaving a half-row gap.
332
- /* @__PURE__ */ a(
447
+ /* @__PURE__ */ i(
333
448
  "span",
334
449
  {
335
450
  "data-slot": "tree-item-guide-elbow",
336
- className: E(
451
+ className: N(
337
452
  "absolute top-[-0.4375rem] left-[var(--tree-guide-left)] border-[var(--tree-guide-color)]",
338
453
  "h-[calc(50%+0.4375rem)] w-[var(--tree-elbow-run)] border-b border-l",
339
454
  "rounded-bl-[var(--tree-elbow-radius)]"
@@ -345,62 +460,92 @@ function pe({ className: e, children: r, size: t, style: o, icon: l, trailing: u
345
460
  }
346
461
  )
347
462
  ) : null,
348
- C ? (
463
+ T ? (
349
464
  // A pointer-only affordance, deliberately not a `<button>`: expansion is reachable from the
350
465
  // keyboard through the parent treeitem's arrow keys, so this stays non-focusable. A focusable
351
466
  // element hidden from assistive tech is a contradiction, and inside a single-tab-stop widget
352
467
  // it would also be a second focus stop reachable by pointer.
353
- /* @__PURE__ */ a(
468
+ /* @__PURE__ */ i(
354
469
  "span",
355
470
  {
356
471
  "data-slot": "tree-item-indicator",
357
472
  "aria-hidden": "true",
358
- onClick: (i) => {
359
- i.stopPropagation(), P();
473
+ onClick: (f) => {
474
+ f.stopPropagation(), R();
360
475
  },
361
476
  className: "flex size-3.5 shrink-0 items-center justify-center text-muted-foreground",
362
- children: /* @__PURE__ */ a(Y, { className: E("size-3.5 transition-transform", v && "rotate-90") })
477
+ children: /* @__PURE__ */ i(ie, { className: N("size-3.5 transition-transform", p && "rotate-90") })
363
478
  }
364
479
  )
365
- ) : /* @__PURE__ */ a("span", { "data-slot": "tree-item-indicator-spacer", "aria-hidden": "true", className: "size-3.5 shrink-0" }),
366
- l ? /* @__PURE__ */ a(
480
+ ) : /* @__PURE__ */ i("span", { "data-slot": "tree-item-indicator-spacer", "aria-hidden": "true", className: "size-3.5 shrink-0" }),
481
+ a ? /* @__PURE__ */ i(
367
482
  "span",
368
483
  {
369
484
  "data-slot": "tree-item-icon",
370
485
  "aria-hidden": "true",
371
- className: E(
486
+ className: N(
372
487
  "flex size-4 shrink-0 items-center justify-center [&_svg]:size-4 [&_svg]:shrink-0",
373
- N ? "text-accent-foreground" : "text-muted-foreground"
488
+ x ? "text-accent-foreground" : "text-muted-foreground"
374
489
  ),
375
- children: l
490
+ children: a
376
491
  }
377
492
  ) : null,
378
- /* @__PURE__ */ A(Q, { open: h, onOpenChange: y, children: [
379
- /* @__PURE__ */ a(X, { asChild: !0, children: /* @__PURE__ */ a("span", { ref: g, className: "min-w-0 flex-1 truncate", children: r }) }),
380
- /* @__PURE__ */ a(Z, { children: r })
493
+ /* @__PURE__ */ q(ue, { open: L, onOpenChange: S, children: [
494
+ /* @__PURE__ */ i(de, { asChild: !0, children: /* @__PURE__ */ i(
495
+ "span",
496
+ {
497
+ ref: h,
498
+ "data-slot": "tree-item-text",
499
+ className: "-mx-1 min-w-0 flex-1 truncate px-1",
500
+ children: /* @__PURE__ */ i(ke, { match: E, children: r })
501
+ }
502
+ ) }),
503
+ /* @__PURE__ */ i(fe, { children: r })
381
504
  ] }),
382
- u ? /* @__PURE__ */ a(
383
- "span",
384
- {
385
- "data-slot": "tree-item-trailing",
386
- className: "ml-auto flex shrink-0 items-center gap-1 [&_svg]:size-3.5",
387
- children: u
388
- }
389
- ) : null
505
+ c ? /* @__PURE__ */ i("span", { "data-slot": "tree-item-trailing", className: "ml-auto flex shrink-0 items-center gap-1 [&_svg]:size-3.5", children: c }) : null
390
506
  ]
391
507
  }
392
508
  );
393
509
  }
394
- function xe({ className: e, children: r, ...t }) {
395
- const { expanded: o, level: l } = M("TreeItemGroup");
396
- return o ? /* @__PURE__ */ a(B.Provider, { value: l + 1, children: /* @__PURE__ */ a("div", { ...t, "data-slot": "tree-item-group", role: "group", className: E("flex flex-col", e), children: /* @__PURE__ */ a(q, { children: r }) }) }) : null;
510
+ function ke({ match: e, children: r }) {
511
+ if (!e || typeof r != "string" || !r.toLowerCase().startsWith(e.query))
512
+ return r;
513
+ const { query: t, fading: s } = e;
514
+ return /* @__PURE__ */ q(se, { children: [
515
+ /* @__PURE__ */ i(
516
+ "span",
517
+ {
518
+ "data-slot": "tree-item-typeahead-match",
519
+ "data-state": s ? "fading" : "active",
520
+ className: N(
521
+ // The SW-2445 selected-state tokens: a primary tint that reads as "this is the match" on
522
+ // a resting, hovered or selected row, in both themes. Plain spans, not `<mark>`, so the
523
+ // label's accessible name is unchanged.
524
+ "rounded-sm ring-1",
525
+ // Padding either side so the ring does not hug the glyphs, with a matching negative
526
+ // margin so the rest of the label stays put while the highlight comes and goes.
527
+ "-mx-0.5 px-0.5",
528
+ // Eased out over the fade window rather than snapped off; the span itself is removed
529
+ // only once the transition has finished.
530
+ "transition-[color,background-color,box-shadow] duration-700 ease-out motion-reduce:transition-none",
531
+ s ? "bg-transparent text-inherit ring-transparent" : "bg-selected text-selected-foreground ring-selected-border"
532
+ ),
533
+ children: r.slice(0, t.length)
534
+ }
535
+ ),
536
+ r.slice(t.length)
537
+ ] });
538
+ }
539
+ function Fe({ className: e, children: r, ...t }) {
540
+ const { expanded: s, level: a } = Y("TreeItemGroup");
541
+ return s ? /* @__PURE__ */ i(U.Provider, { value: a + 1, children: /* @__PURE__ */ i("div", { ...t, "data-slot": "tree-item-group", role: "group", className: N("flex flex-col", e), children: /* @__PURE__ */ i(ae, { children: r }) }) }) : null;
397
542
  }
398
543
  export {
399
- me as Tree,
400
- fe as TreeItem,
401
- xe as TreeItemGroup,
402
- pe as TreeItemLabel,
403
- oe as treeItemLabelVariants,
404
- ue as useTreeItem
544
+ _e as Tree,
545
+ Me as TreeItem,
546
+ Fe as TreeItemGroup,
547
+ ze as TreeItemLabel,
548
+ we as treeItemLabelVariants,
549
+ Se as useTreeItem
405
550
  };
406
551
  //# sourceMappingURL=tree.js.map