@knymbus/voxel-ui 1.0.17 → 1.0.19

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,36 +1,20 @@
1
1
  import { t as e } from "./jsx-runtime-Boo2vksn.js";
2
- import { t } from "./Button-BgQwvn3C.js";
3
- import { E as n, S as r } from "./icons-BpfDVwCQ.js";
4
- import { useEffect as i, useRef as a, useState as o } from "react";
5
- //#region src/components/search/types.ts
6
- var s = {
7
- colors: {
8
- bgInput: "var(--color-vsc-bg-input, #f6f8fa)",
9
- border: "var(--color-vsc-border, #e4e4e7)",
10
- borderAccent: "var(--color-vsc-accent, #007acc)",
11
- borderAccentHover: "var(--color-vsc-accent-hover, #0062a3)",
12
- text: "var(--color-vsc-text, #333333)",
13
- muted: "var(--color-vsc-muted, #6a737d)",
14
- sidebarBg: "var(--color-vsc-sidebar, #f3f3f3)",
15
- hoverBg: "var(--color-vsc-hover, #e8e8e8)",
16
- accentBgLight: "rgba(0, 122, 204, 0.1)"
17
- },
18
- typography: {
19
- sans: "var(--font-sans, font-sans, ui-sans-serif, system-ui, sans-serif)",
20
- mono: "var(--font-mono, font-mono, ui-monospace, SFMono-Regular, monospace)"
21
- },
22
- transitions: { smooth: "all 200ms cubic-bezier(0.34, 1.56, 0.64, 1)" }
23
- }, c = e();
24
- function l({ isOpen: e, value: t, menuResults: n, onResultClick: r, onViewMoreClick: i, onCloseMenu: a }) {
25
- let [l, u] = o(null), [d, f] = o(!1);
26
- return !e || !t ? null : /* @__PURE__ */ (0, c.jsxs)("div", {
2
+ import { t } from "./types-DmQVfNPh.js";
3
+ import { t as n } from "./Button-BgQwvn3C.js";
4
+ import { E as r, S as i } from "./icons-BpfDVwCQ.js";
5
+ import { useEffect as a, useRef as o, useState as s } from "react";
6
+ //#region src/components/search/SearchMenu.tsx
7
+ var c = e();
8
+ function l({ isOpen: e, value: n, menuResults: r, onResultClick: i, onViewMoreClick: a, onCloseMenu: o }) {
9
+ let [l, u] = s(null), [d, f] = s(!1);
10
+ return !e || !n ? null : /* @__PURE__ */ (0, c.jsxs)("div", {
27
11
  style: {
28
12
  position: "absolute",
29
13
  top: "36px",
30
14
  left: 0,
31
15
  width: "100%",
32
- backgroundColor: s.colors.sidebarBg,
33
- border: `1px solid ${s.colors.border}`,
16
+ backgroundColor: t.colors.sidebarBg,
17
+ border: `1px solid ${t.colors.border}`,
34
18
  borderRadius: "4px",
35
19
  boxShadow: "0 10px 15px -3px rgba(0, 0, 0, 0.2)",
36
20
  zIndex: 50,
@@ -44,25 +28,25 @@ function l({ isOpen: e, value: t, menuResults: n, onResultClick: r, onViewMoreCl
44
28
  overflowY: "auto",
45
29
  flex: 1
46
30
  },
47
- children: n.length === 0 ? /* @__PURE__ */ (0, c.jsx)("div", {
31
+ children: r.length === 0 ? /* @__PURE__ */ (0, c.jsx)("div", {
48
32
  style: {
49
33
  padding: "16px",
50
34
  textAlign: "center",
51
35
  fontSize: "11px",
52
- color: s.colors.muted,
36
+ color: t.colors.muted,
53
37
  fontStyle: "italic"
54
38
  },
55
39
  children: "No indexed record entities match your text query constraints."
56
- }) : n.map((e) => /* @__PURE__ */ (0, c.jsxs)("div", {
40
+ }) : r.map((e) => /* @__PURE__ */ (0, c.jsxs)("div", {
57
41
  onMouseEnter: () => u(e.id),
58
42
  onMouseLeave: () => u(null),
59
43
  onClick: () => {
60
- r && r(e), a();
44
+ i && i(e), o();
61
45
  },
62
46
  style: {
63
47
  width: "100%",
64
48
  padding: "8px",
65
- backgroundColor: l === e.id ? s.colors.hoverBg : "transparent",
49
+ backgroundColor: l === e.id ? t.colors.hoverBg : "transparent",
66
50
  borderRadius: "2px",
67
51
  cursor: "pointer",
68
52
  display: "flex",
@@ -74,7 +58,7 @@ function l({ isOpen: e, value: t, menuResults: n, onResultClick: r, onViewMoreCl
74
58
  children: [/* @__PURE__ */ (0, c.jsxs)("div", {
75
59
  style: {
76
60
  fontWeight: 600,
77
- color: s.colors.text,
61
+ color: t.colors.text,
78
62
  display: "flex",
79
63
  justifyContent: "space-between",
80
64
  alignItems: "center",
@@ -93,9 +77,9 @@ function l({ isOpen: e, value: t, menuResults: n, onResultClick: r, onViewMoreCl
93
77
  fontSize: "9px",
94
78
  fontFamily: "monospace",
95
79
  fontWeight: "bold",
96
- backgroundColor: s.colors.accentBgLight,
80
+ backgroundColor: t.colors.accentBgLight,
97
81
  border: "1px solid rgba(0, 122, 204, 0.2)",
98
- color: s.colors.borderAccent,
82
+ color: t.colors.borderAccent,
99
83
  padding: "2px 4px",
100
84
  borderRadius: "2px",
101
85
  textTransform: "uppercase",
@@ -107,7 +91,7 @@ function l({ isOpen: e, value: t, menuResults: n, onResultClick: r, onViewMoreCl
107
91
  }), e.subtitle && /* @__PURE__ */ (0, c.jsx)("div", {
108
92
  style: {
109
93
  fontSize: "10px",
110
- color: s.colors.muted,
94
+ color: t.colors.muted,
111
95
  whiteSpace: "nowrap",
112
96
  overflow: "hidden",
113
97
  textOverflow: "ellipsis"
@@ -115,22 +99,22 @@ function l({ isOpen: e, value: t, menuResults: n, onResultClick: r, onViewMoreCl
115
99
  children: e.subtitle
116
100
  })]
117
101
  }, e.id))
118
- }), n.length > 0 && i && /* @__PURE__ */ (0, c.jsx)("button", {
102
+ }), r.length > 0 && a && /* @__PURE__ */ (0, c.jsx)("button", {
119
103
  onMouseEnter: () => f(!0),
120
104
  onMouseLeave: () => f(!1),
121
105
  onClick: () => {
122
- i(), a();
106
+ a(), o();
123
107
  },
124
108
  style: {
125
109
  width: "100%",
126
110
  border: "none",
127
- borderTop: `1px solid ${s.colors.border}`,
128
- backgroundColor: d ? s.colors.hoverBg : "transparent",
111
+ borderTop: `1px solid ${t.colors.border}`,
112
+ backgroundColor: d ? t.colors.hoverBg : "transparent",
129
113
  padding: "8px",
130
114
  textAlign: "center",
131
115
  fontSize: "10px",
132
116
  fontWeight: "bold",
133
- color: s.colors.borderAccent,
117
+ color: t.colors.borderAccent,
134
118
  letterSpacing: "0.5px",
135
119
  textTransform: "uppercase",
136
120
  transition: "background-color 150ms",
@@ -144,8 +128,8 @@ function l({ isOpen: e, value: t, menuResults: n, onResultClick: r, onViewMoreCl
144
128
  //#endregion
145
129
  //#region src/components/search/SearchInput.tsx
146
130
  function u({ variant: e = "simple", value: u, onChange: d, onClear: f, placeholder: p = "Search manifests or tracking codes...", resultsCount: m = 0, menuResults: h = [], onResultClick: g, onViewMoreClick: _, className: v = "", showFloatPeek: y = !1, peekContent: b }) {
147
- let [x, S] = o(!1), [C, w] = o(!1), [T, E] = o(!1), [D, O] = o(!1), k = a(null), A = a(null);
148
- i(() => {
131
+ let [x, S] = s(!1), [C, w] = s(!1), [T, E] = s(!1), [D, O] = s(!1), k = o(null), A = o(null);
132
+ a(() => {
149
133
  let t = (t) => {
150
134
  k.current && !k.current.contains(t.target) && (w(!1), e === "float" && u === "" && S(!1));
151
135
  };
@@ -159,7 +143,7 @@ function u({ variant: e = "simple", value: u, onChange: d, onClear: f, placehold
159
143
  position: "relative",
160
144
  display: "flex",
161
145
  flexDirection: "column",
162
- fontFamily: s.typography.sans,
146
+ fontFamily: t.typography.sans,
163
147
  fontSize: "12px",
164
148
  userSelect: "none",
165
149
  boxSizing: "border-box"
@@ -167,26 +151,26 @@ function u({ variant: e = "simple", value: u, onChange: d, onClear: f, placehold
167
151
  position: "relative",
168
152
  display: "flex",
169
153
  alignItems: "center",
170
- backgroundColor: s.colors.bgInput,
171
- border: `1px solid ${D || e === "float" && x ? s.colors.borderAccent : T ? s.colors.borderAccentHover : s.colors.border}`,
154
+ backgroundColor: t.colors.bgInput,
155
+ border: `1px solid ${D || e === "float" && x ? t.colors.borderAccent : T ? t.colors.borderAccentHover : t.colors.border}`,
172
156
  borderRadius: "6px",
173
157
  height: "32px",
174
- transition: s.transitions.smooth,
158
+ transition: t.transitions.smooth,
175
159
  boxSizing: "border-box"
176
160
  }, F = {
177
161
  width: "100%",
178
162
  height: "100%",
179
163
  backgroundColor: "transparent",
180
- color: s.colors.text,
164
+ color: t.colors.text,
181
165
  border: "none",
182
166
  outline: "none",
183
167
  padding: "0 32px",
184
168
  fontSize: "12px",
185
- fontFamily: s.typography.sans,
169
+ fontFamily: t.typography.sans,
186
170
  boxSizing: "border-box"
187
171
  };
188
172
  if (e === "simple") {
189
- let e = u.length > 0, i = m > 0;
173
+ let e = u.length > 0, a = m > 0;
190
174
  return /* @__PURE__ */ (0, c.jsxs)("div", {
191
175
  style: N,
192
176
  className: v,
@@ -201,9 +185,9 @@ function u({ variant: e = "simple", value: u, onChange: d, onClear: f, placehold
201
185
  left: "10px",
202
186
  display: "flex",
203
187
  alignItems: "center",
204
- color: T ? s.colors.text : s.colors.muted
188
+ color: T ? t.colors.text : t.colors.muted
205
189
  },
206
- children: /* @__PURE__ */ (0, c.jsx)(r, { size: 14 })
190
+ children: /* @__PURE__ */ (0, c.jsx)(i, { size: 14 })
207
191
  }),
208
192
  /* @__PURE__ */ (0, c.jsx)("input", {
209
193
  ref: A,
@@ -224,8 +208,8 @@ function u({ variant: e = "simple", value: u, onChange: d, onClear: f, placehold
224
208
  display: "flex",
225
209
  alignItems: "center"
226
210
  },
227
- children: /* @__PURE__ */ (0, c.jsx)(t, {
228
- icon: n,
211
+ children: /* @__PURE__ */ (0, c.jsx)(n, {
212
+ icon: r,
229
213
  color: "ghost",
230
214
  iconOnly: !0,
231
215
  onClick: j,
@@ -240,7 +224,7 @@ function u({ variant: e = "simple", value: u, onChange: d, onClear: f, placehold
240
224
  right: 0,
241
225
  top: "32px",
242
226
  zIndex: 10,
243
- transition: s.transitions.smooth,
227
+ transition: t.transitions.smooth,
244
228
  height: e ? "auto" : "0px",
245
229
  opacity: +!!e,
246
230
  transform: e ? "translateY(4px)" : "translateY(-4px)",
@@ -248,19 +232,19 @@ function u({ variant: e = "simple", value: u, onChange: d, onClear: f, placehold
248
232
  },
249
233
  children: /* @__PURE__ */ (0, c.jsx)("div", {
250
234
  style: {
251
- backgroundColor: s.colors.sidebarBg,
252
- border: `0px solid ${s.colors.border}`,
235
+ backgroundColor: t.colors.sidebarBg,
236
+ border: `0px solid ${t.colors.border}`,
253
237
  borderTop: "none",
254
238
  padding: "4px 6px",
255
239
  borderRadius: "6px",
256
240
  boxShadow: "0 4px 6px -1px rgba(0,0,0,0.1)"
257
241
  },
258
- children: e && b ? b : e && !b && i ? /* @__PURE__ */ (0, c.jsxs)("p", {
242
+ children: e && b ? b : e && !b && a ? /* @__PURE__ */ (0, c.jsxs)("p", {
259
243
  style: {
260
244
  margin: 0,
261
245
  fontSize: "10px",
262
- fontFamily: s.typography.mono,
263
- color: s.colors.muted,
246
+ fontFamily: t.typography.mono,
247
+ color: t.colors.muted,
264
248
  whiteSpace: "nowrap",
265
249
  overflow: "hidden",
266
250
  textOverflow: "ellipsis"
@@ -269,26 +253,26 @@ function u({ variant: e = "simple", value: u, onChange: d, onClear: f, placehold
269
253
  "Showing ",
270
254
  /* @__PURE__ */ (0, c.jsx)("span", {
271
255
  style: {
272
- color: s.colors.borderAccent,
256
+ color: t.colors.borderAccent,
273
257
  fontWeight: "bold"
274
258
  },
275
259
  children: m
276
260
  }),
277
261
  " matching database metrics records"
278
262
  ]
279
- }) : e && !b && !i ? /* @__PURE__ */ (0, c.jsxs)("p", {
263
+ }) : e && !b && !a ? /* @__PURE__ */ (0, c.jsxs)("p", {
280
264
  style: {
281
265
  margin: 0,
282
266
  fontSize: "10px",
283
- fontFamily: s.typography.mono,
284
- color: s.colors.borderAccent,
267
+ fontFamily: t.typography.mono,
268
+ color: t.colors.borderAccent,
285
269
  whiteSpace: "nowrap",
286
270
  overflow: "hidden",
287
271
  textOverflow: "ellipsis"
288
272
  },
289
273
  children: ["No matching records found for your query: ", /* @__PURE__ */ (0, c.jsx)("span", {
290
274
  style: {
291
- color: s.colors.text,
275
+ color: t.colors.text,
292
276
  fontWeight: "bold"
293
277
  },
294
278
  children: u
@@ -299,12 +283,12 @@ function u({ variant: e = "simple", value: u, onChange: d, onClear: f, placehold
299
283
  });
300
284
  }
301
285
  if (e === "float") {
302
- let e = y && m > 0 && u.length > 0, i = x || u.length > 0, a = b || /* @__PURE__ */ (0, c.jsxs)("p", {
286
+ let e = y && m > 0 && u.length > 0, a = x || u.length > 0, o = b || /* @__PURE__ */ (0, c.jsxs)("p", {
303
287
  style: {
304
288
  margin: 0,
305
289
  fontSize: "9px",
306
- fontFamily: s.typography.mono,
307
- color: s.colors.borderAccent,
290
+ fontFamily: t.typography.mono,
291
+ color: t.colors.borderAccent,
308
292
  whiteSpace: "nowrap",
309
293
  overflow: "hidden",
310
294
  textOverflow: "ellipsis"
@@ -324,13 +308,13 @@ function u({ variant: e = "simple", value: u, onChange: d, onClear: f, placehold
324
308
  onMouseLeave: () => E(!1),
325
309
  style: {
326
310
  ...P,
327
- width: i ? "256px" : "32px",
328
- justifyContent: i ? "flex-start" : "center",
329
- backgroundColor: i ? s.colors.bgInput : "transparent",
330
- borderColor: i ? s.colors.borderAccent : "transparent",
331
- padding: i ? "0 8px" : "0"
311
+ width: a ? "256px" : "32px",
312
+ justifyContent: a ? "flex-start" : "center",
313
+ backgroundColor: a ? t.colors.bgInput : "transparent",
314
+ borderColor: a ? t.colors.borderAccent : "transparent",
315
+ padding: a ? "0 8px" : "0"
332
316
  },
333
- children: i ? /* @__PURE__ */ (0, c.jsxs)("div", {
317
+ children: a ? /* @__PURE__ */ (0, c.jsxs)("div", {
334
318
  style: {
335
319
  position: "relative",
336
320
  display: "flex",
@@ -339,10 +323,10 @@ function u({ variant: e = "simple", value: u, onChange: d, onClear: f, placehold
339
323
  height: "100%"
340
324
  },
341
325
  children: [
342
- /* @__PURE__ */ (0, c.jsx)(r, {
326
+ /* @__PURE__ */ (0, c.jsx)(i, {
343
327
  size: 14,
344
328
  style: {
345
- color: s.colors.text,
329
+ color: t.colors.text,
346
330
  flexShrink: 0
347
331
  }
348
332
  }),
@@ -366,22 +350,22 @@ function u({ variant: e = "simple", value: u, onChange: d, onClear: f, placehold
366
350
  display: "flex",
367
351
  alignItems: "center"
368
352
  },
369
- children: /* @__PURE__ */ (0, c.jsx)(t, {
353
+ children: /* @__PURE__ */ (0, c.jsx)(n, {
370
354
  iconOnly: !0,
371
355
  color: "ghost",
372
- icon: n,
356
+ icon: r,
373
357
  onClick: j,
374
358
  size: "xs"
375
359
  })
376
360
  })
377
361
  ]
378
- }) : /* @__PURE__ */ (0, c.jsx)(t, {
362
+ }) : /* @__PURE__ */ (0, c.jsx)(n, {
379
363
  iconOnly: !0,
380
364
  size: "sm",
381
- icon: r,
365
+ icon: i,
382
366
  onClick: M,
383
367
  color: "ghost",
384
- style: { color: s.colors.muted },
368
+ style: { color: t.colors.muted },
385
369
  title: "Open Expandable Search"
386
370
  })
387
371
  }), /* @__PURE__ */ (0, c.jsx)("div", {
@@ -391,7 +375,7 @@ function u({ variant: e = "simple", value: u, onChange: d, onClear: f, placehold
391
375
  width: "256px",
392
376
  zIndex: 10,
393
377
  overflow: "hidden",
394
- transition: s.transitions.smooth,
378
+ transition: t.transitions.smooth,
395
379
  height: e ? "24px" : "0px",
396
380
  opacity: +!!e,
397
381
  transform: e ? "translateY(0px)" : "translateY(-4px)",
@@ -399,14 +383,14 @@ function u({ variant: e = "simple", value: u, onChange: d, onClear: f, placehold
399
383
  },
400
384
  children: /* @__PURE__ */ (0, c.jsx)("div", {
401
385
  style: {
402
- backgroundColor: s.colors.sidebarBg,
403
- border: `1px solid ${s.colors.border}`,
386
+ backgroundColor: t.colors.sidebarBg,
387
+ border: `1px solid ${t.colors.border}`,
404
388
  borderTop: "none",
405
389
  padding: "4px",
406
390
  borderRadius: "0 0 2px 2px",
407
391
  boxShadow: "0 4px 6px -1px rgba(0,0,0,0.1)"
408
392
  },
409
- children: a
393
+ children: o
410
394
  })
411
395
  })]
412
396
  });
@@ -426,9 +410,9 @@ function u({ variant: e = "simple", value: u, onChange: d, onClear: f, placehold
426
410
  left: "10px",
427
411
  display: "flex",
428
412
  alignItems: "center",
429
- color: s.colors.muted
413
+ color: t.colors.muted
430
414
  },
431
- children: /* @__PURE__ */ (0, c.jsx)(r, { size: 14 })
415
+ children: /* @__PURE__ */ (0, c.jsx)(i, { size: 14 })
432
416
  }),
433
417
  /* @__PURE__ */ (0, c.jsx)("input", {
434
418
  ref: A,
@@ -450,9 +434,9 @@ function u({ variant: e = "simple", value: u, onChange: d, onClear: f, placehold
450
434
  display: "flex",
451
435
  alignItems: "center"
452
436
  },
453
- children: /* @__PURE__ */ (0, c.jsx)(t, {
437
+ children: /* @__PURE__ */ (0, c.jsx)(n, {
454
438
  iconOnly: !0,
455
- icon: n,
439
+ icon: r,
456
440
  color: "ghost",
457
441
  onClick: j,
458
442
  size: "xs"
@@ -470,4 +454,4 @@ function u({ variant: e = "simple", value: u, onChange: d, onClear: f, placehold
470
454
  });
471
455
  }
472
456
  //#endregion
473
- export { s as n, u as t };
457
+ export { u as t };
@@ -0,0 +1,182 @@
1
+ import { t as e } from "./jsx-runtime-Boo2vksn.js";
2
+ import { t } from "./types-DmQVfNPh.js";
3
+ import { createContext as n, useContext as r, useEffect as i, useState as a } from "react";
4
+ import { create as o } from "zustand";
5
+ //#region src/components/tabs/useTab.ts
6
+ var s = o((e) => ({
7
+ activeTabs: {},
8
+ setActiveTab: (t, n) => e((e) => ({ activeTabs: {
9
+ ...e.activeTabs,
10
+ [t]: n
11
+ } })),
12
+ initializeTab: (t, n) => e((e) => e.activeTabs[t] ? {} : { activeTabs: {
13
+ ...e.activeTabs,
14
+ [t]: n
15
+ } })
16
+ }));
17
+ function c(e) {
18
+ let t = s((t) => t.activeTabs[e]), n = s((e) => e.setActiveTab), r = s((e) => e.initializeTab);
19
+ return {
20
+ activeTab: t,
21
+ changeTab: (t) => n(e, t),
22
+ registerDefault: (t) => r(e, t)
23
+ };
24
+ }
25
+ //#endregion
26
+ //#region src/components/tabs/TabPanelList.tsx
27
+ var l = e(), u = n({ activeTabId: void 0 }), d = () => r(u);
28
+ function f({ children: e, targetScopeName: n, defaultValue: r }) {
29
+ let { activeTab: a, registerDefault: o } = c(n);
30
+ i(() => {
31
+ o(r);
32
+ }, [r, o]);
33
+ let s = a || r, d = {
34
+ position: "relative",
35
+ width: "100%",
36
+ height: "100%",
37
+ minHeight: 0,
38
+ flex: "1 1 0%",
39
+ overflow: "hidden",
40
+ backgroundColor: t.colors.bgInput,
41
+ fontFamily: t.typography.sans,
42
+ boxSizing: "border-box"
43
+ };
44
+ return /* @__PURE__ */ (0, l.jsx)(u.Provider, {
45
+ value: { activeTabId: s },
46
+ children: /* @__PURE__ */ (0, l.jsx)("div", {
47
+ style: d,
48
+ children: e
49
+ })
50
+ });
51
+ }
52
+ //#endregion
53
+ //#region src/components/tabs/TabPanel.tsx
54
+ function p({ children: e, id: t, persist: n = !1 }) {
55
+ let { activeTabId: r } = d(), o = r === t, [s, c] = a(!1);
56
+ return i(() => {
57
+ o && !s && c(!0);
58
+ }, [o, s]), !s || !n && !o ? null : /* @__PURE__ */ (0, l.jsx)("div", {
59
+ style: {
60
+ position: "absolute",
61
+ top: 0,
62
+ left: 0,
63
+ right: 0,
64
+ bottom: 0,
65
+ width: "100%",
66
+ height: "100%",
67
+ backgroundColor: "transparent",
68
+ transition: "opacity 250ms ease-out, transform 250ms cubic-bezier(0.34, 1.56, 0.64, 1)",
69
+ boxSizing: "border-box",
70
+ opacity: +!!o,
71
+ transform: o ? "scale(1)" : "scale(0.995)",
72
+ zIndex: o ? 10 : 0,
73
+ pointerEvents: o ? "auto" : "none",
74
+ visibility: o ? "visible" : "hidden"
75
+ },
76
+ children: /* @__PURE__ */ (0, l.jsx)("div", {
77
+ style: {
78
+ width: "100%",
79
+ height: "100%",
80
+ boxSizing: "border-box"
81
+ },
82
+ children: e
83
+ })
84
+ });
85
+ }
86
+ //#endregion
87
+ //#region src/components/tabs/TabButton.tsx
88
+ function m({ id: e, scopeName: n, children: r, variant: i = "underline", startIcon: o, endIcon: s }) {
89
+ let { activeTab: u, changeTab: d } = c(n), [f, p] = a(!1), m = u === e, h = {
90
+ display: "inline-flex",
91
+ alignItems: "center",
92
+ justifyContent: "center",
93
+ gap: "6px",
94
+ backgroundColor: "transparent",
95
+ border: "none",
96
+ outline: "none",
97
+ fontFamily: t.typography.sans,
98
+ fontSize: "12px",
99
+ userSelect: "none",
100
+ cursor: "pointer",
101
+ height: "100%",
102
+ transition: "all 150ms ease",
103
+ boxSizing: "border-box",
104
+ position: "relative",
105
+ zIndex: 10
106
+ }, g = {
107
+ underline: {
108
+ padding: "4px 12px 8px 12px",
109
+ fontWeight: m ? 600 : 500,
110
+ color: m || f ? t.colors.text : t.colors.muted,
111
+ borderBottom: `2px solid ${m ? t.colors.borderAccent : "transparent"}`
112
+ },
113
+ "sliding-underline": {
114
+ padding: "8px 16px",
115
+ fontWeight: m ? 700 : 500,
116
+ color: m || f ? t.colors.text : t.colors.muted
117
+ },
118
+ pill: {
119
+ padding: "6px 14px",
120
+ fontWeight: 700,
121
+ borderRadius: "9999px",
122
+ backgroundColor: m ? t.colors.borderAccent : f ? t.colors.hoverBg : "transparent",
123
+ color: m ? "#ffffff" : f ? t.colors.text : t.colors.muted,
124
+ transform: m ? "scale(1.02)" : "scale(1)",
125
+ boxShadow: m ? "0 1px 3px rgba(0,0,0,0.1)" : "none"
126
+ },
127
+ vscode: {
128
+ padding: "0 16px",
129
+ fontWeight: 500,
130
+ color: m || f ? t.colors.text : t.colors.muted,
131
+ backgroundColor: m ? t.colors.bgInput : f ? "rgba(0,0,0,0.02)" : t.colors.sidebarBg,
132
+ borderRight: `1px solid ${t.colors.border}`,
133
+ borderTop: m ? `2px solid ${t.colors.borderAccent}` : "2px solid transparent",
134
+ marginTop: m ? "-1px" : "0"
135
+ },
136
+ ghost: {
137
+ padding: "6px 12px",
138
+ fontWeight: m ? 700 : 500,
139
+ borderRadius: "2px",
140
+ backgroundColor: m ? t.colors.hoverBg : f ? "rgba(0,0,0,0.04)" : "transparent",
141
+ color: m || f ? t.colors.text : t.colors.muted
142
+ }
143
+ };
144
+ return /* @__PURE__ */ (0, l.jsxs)("button", {
145
+ "data-id": e,
146
+ onClick: () => d(e),
147
+ onMouseEnter: () => p(!0),
148
+ onMouseLeave: () => p(!1),
149
+ style: {
150
+ ...h,
151
+ ...g[i]
152
+ },
153
+ children: [
154
+ o && /* @__PURE__ */ (0, l.jsx)("span", {
155
+ style: {
156
+ display: "inline-flex",
157
+ flexShrink: 0,
158
+ opacity: m || f ? 1 : .7
159
+ },
160
+ children: o
161
+ }),
162
+ /* @__PURE__ */ (0, l.jsx)("span", {
163
+ style: {
164
+ overflow: "hidden",
165
+ textOverflow: "ellipsis",
166
+ whiteSpace: "nowrap"
167
+ },
168
+ children: r
169
+ }),
170
+ s && /* @__PURE__ */ (0, l.jsx)("span", {
171
+ style: {
172
+ display: "inline-flex",
173
+ flexShrink: 0,
174
+ opacity: m || f ? 1 : .6
175
+ },
176
+ children: s
177
+ })
178
+ ]
179
+ });
180
+ }
181
+ //#endregion
182
+ export { c as i, p as n, f as r, m as t };
@@ -0,0 +1,21 @@
1
+ //#region src/components/types.ts
2
+ var e = {
3
+ colors: {
4
+ bgInput: "var(--color-vsc-bg-input, #f6f8fa)",
5
+ border: "var(--color-vsc-border, #e4e4e7)",
6
+ borderAccent: "var(--color-vsc-accent, #007acc)",
7
+ borderAccentHover: "var(--color-vsc-accent-hover, #0062a3)",
8
+ text: "var(--color-vsc-text, #333333)",
9
+ muted: "var(--color-vsc-muted, #6a737d)",
10
+ sidebarBg: "var(--color-vsc-sidebar, #f3f3f3)",
11
+ hoverBg: "var(--color-vsc-hover, #e8e8e8)",
12
+ accentBgLight: "rgba(0, 122, 204, 0.1)"
13
+ },
14
+ typography: {
15
+ sans: "var(--font-sans, font-sans, ui-sans-serif, system-ui, sans-serif)",
16
+ mono: "var(--font-mono, font-mono, ui-monospace, SFMono-Regular, monospace)"
17
+ },
18
+ transitions: { smooth: "all 200ms cubic-bezier(0.34, 1.56, 0.64, 1)" }
19
+ };
20
+ //#endregion
21
+ export { e as t };
@@ -1,2 +1,2 @@
1
- import { n as e, t } from "../../chunks/search-WFmasN49.js";
2
- export { t as SearchInput, e as searchTokens };
1
+ import { t as e } from "../../chunks/search-DSDSn6PK.js";
2
+ export { e as SearchInput };
@@ -20,23 +20,3 @@ export interface SearchInputProps {
20
20
  showFloatPeek?: boolean;
21
21
  peekContent?: React.ReactNode;
22
22
  }
23
- export declare const searchTokens: {
24
- colors: {
25
- bgInput: string;
26
- border: string;
27
- borderAccent: string;
28
- borderAccentHover: string;
29
- text: string;
30
- muted: string;
31
- sidebarBg: string;
32
- hoverBg: string;
33
- accentBgLight: string;
34
- };
35
- typography: {
36
- sans: string;
37
- mono: string;
38
- };
39
- transitions: {
40
- smooth: string;
41
- };
42
- };
@@ -1,2 +1,2 @@
1
- import { i as e, n as t, r as n, t as r } from "../../chunks/tabs-MaVN00hJ.js";
1
+ import { i as e, n as t, r as n, t as r } from "../../chunks/tabs-DkmFedCI.js";
2
2
  export { r as TabButton, t as TabPanel, n as TabPanelList, e as useTab };
@@ -0,0 +1,20 @@
1
+ export declare const searchTokens: {
2
+ colors: {
3
+ bgInput: string;
4
+ border: string;
5
+ borderAccent: string;
6
+ borderAccentHover: string;
7
+ text: string;
8
+ muted: string;
9
+ sidebarBg: string;
10
+ hoverBg: string;
11
+ accentBgLight: string;
12
+ };
13
+ typography: {
14
+ sans: string;
15
+ mono: string;
16
+ };
17
+ transitions: {
18
+ smooth: string;
19
+ };
20
+ };
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { t as e } from "./chunks/resizable-ImB8dfG_.js";
2
- import { i as t, n, r, t as i } from "./chunks/tabs-MaVN00hJ.js";
2
+ import { i as t, n, r, t as i } from "./chunks/tabs-DkmFedCI.js";
3
3
  import { t as a } from "./chunks/Button-BgQwvn3C.js";
4
4
  import { n as o, t as s } from "./chunks/button-dHcpTNIG.js";
5
5
  import { C as c, E as l, S as u, T as d, _ as f, a as p, b as m, c as h, d as g, f as _, g as v, h as y, i as b, l as x, m as S, n as C, o as w, p as T, r as E, s as D, t as O, u as k, v as A, w as j, x as M, y as N } from "./chunks/icons-BpfDVwCQ.js";
6
- import { n as P, t as F } from "./chunks/search-WFmasN49.js";
7
- export { A as Add, S as BlankDoc, a as Button, o as ButtonGroup, _ as Chat, N as ChevronDown, l as Close, x as Comment, k as DeleteChat, j as Document, v as Expand, c as Folder, C as Group, y as Minimize, f as Minus, w as More, D as OpenFolder, b as Person, g as PlusChat, h as PlusComment, T as PlusDoc, O as PlusDocBadge, E as PlusPerson, M as Refresh, e as ResizablePanel, u as Search, F as SearchInput, s as SplitActionButton, i as TabButton, n as TabPanel, r as TabPanelList, d as Terminal, m as Trash, p as Truck, P as searchTokens, t as useTab };
6
+ import { t as P } from "./chunks/search-DSDSn6PK.js";
7
+ export { A as Add, S as BlankDoc, a as Button, o as ButtonGroup, _ as Chat, N as ChevronDown, l as Close, x as Comment, k as DeleteChat, j as Document, v as Expand, c as Folder, C as Group, y as Minimize, f as Minus, w as More, D as OpenFolder, b as Person, g as PlusChat, h as PlusComment, T as PlusDoc, O as PlusDocBadge, E as PlusPerson, M as Refresh, e as ResizablePanel, u as Search, P as SearchInput, s as SplitActionButton, i as TabButton, n as TabPanel, r as TabPanelList, d as Terminal, m as Trash, p as Truck, t as useTab };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@knymbus/voxel-ui",
3
- "version": "1.0.17",
3
+ "version": "1.0.19",
4
4
  "main": "./dist/index.js",
5
5
  "module": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -1,8 +1,9 @@
1
1
  import React, { useState, useRef, useEffect } from 'react';
2
- import { SearchInputProps, searchTokens } from './types';
2
+ import { SearchInputProps } from './types';
3
3
  import { Search, Close } from '../icons';
4
4
  import { Button } from '../button/Button';
5
5
  import SearchMenu from './SearchMenu';
6
+ import { searchTokens } from '../types';
6
7
 
7
8
  export default function SearchInput({
8
9
  variant = 'simple',
@@ -1,5 +1,6 @@
1
1
  import { useState } from 'react';
2
- import { SearchResultItem, searchTokens } from './types';
2
+ import { SearchResultItem } from './types';
3
+ import { searchTokens } from '../types';
3
4
 
4
5
  interface SearchMenuProps {
5
6
  isOpen: boolean;
@@ -25,24 +25,3 @@ export interface SearchInputProps {
25
25
  peekContent?: React.ReactNode;
26
26
  }
27
27
 
28
- export const searchTokens = {
29
- colors: {
30
- bgInput: 'var(--color-vsc-bg-input, #f6f8fa)',
31
- border: 'var(--color-vsc-border, #e4e4e7)',
32
- borderAccent: 'var(--color-vsc-accent, #007acc)',
33
- borderAccentHover: 'var(--color-vsc-accent-hover, #0062a3)',
34
- text: 'var(--color-vsc-text, #333333)',
35
- muted: 'var(--color-vsc-muted, #6a737d)',
36
- sidebarBg: 'var(--color-vsc-sidebar, #f3f3f3)',
37
- hoverBg: 'var(--color-vsc-hover, #e8e8e8)',
38
- accentBgLight: 'rgba(0, 122, 204, 0.1)'
39
- },
40
- typography: {
41
- /* ⚡ Pulls Tailwind's native font configuration maps from your global layout shell App context */
42
- sans: 'var(--font-sans, font-sans, ui-sans-serif, system-ui, sans-serif)',
43
- mono: 'var(--font-mono, font-mono, ui-monospace, SFMono-Regular, monospace)'
44
- },
45
- transitions: {
46
- smooth: 'all 200ms cubic-bezier(0.34, 1.56, 0.64, 1)'
47
- }
48
- };
@@ -1,6 +1,7 @@
1
- import React from 'react';
1
+ import React, { useState } from 'react';
2
2
  import { useTab } from './useTab';
3
- import { TabVariant } from './types';
3
+ import { TabVariant } from './types'; // Shares the typography/color tokens mapping schema
4
+ import { searchTokens } from '../types';
4
5
 
5
6
  interface TabButtonProps {
6
7
  id: string;
@@ -20,37 +21,78 @@ export default function TabButton({
20
21
  endIcon
21
22
  }: TabButtonProps) {
22
23
  const { activeTab, changeTab } = useTab(scopeName);
24
+ const [isHovered, setIsHovered] = useState(false);
23
25
  const isCurrent = activeTab === id;
24
26
 
25
- const baseStyles = "flex items-center justify-center gap-1.5 focus:outline-none border-none outline-none z-10 transition-colors select-none h-full";
27
+ const baseButtonStyles: React.CSSProperties = {
28
+ display: 'inline-flex',
29
+ alignItems: 'center',
30
+ justifyContent: 'center',
31
+ gap: '6px',
32
+ backgroundColor: 'transparent',
33
+ border: 'none',
34
+ outline: 'none',
35
+ fontFamily: searchTokens.typography.sans,
36
+ fontSize: '12px',
37
+ userSelect: 'none',
38
+ cursor: 'pointer',
39
+ height: '100%',
40
+ transition: 'all 150ms ease',
41
+ boxSizing: 'border-box',
42
+ position: 'relative',
43
+ zIndex: 10
44
+ };
26
45
 
27
- const variantClasses: Record<TabVariant, string> = {
28
- underline: `pb-2 pt-1 px-3 text-xs font-semibold cursor-pointer border-b-2 ${
29
- isCurrent ? 'border-vsc-accent text-vsc-text' : 'border-transparent text-vsc-muted hover:text-vsc-text'
30
- }`,
31
- 'sliding-underline': `py-2 px-4 text-xs font-semibold cursor-pointer transition-colors duration-200 ${
32
- isCurrent ? 'text-vsc-text font-bold' : 'text-vsc-muted hover:text-vsc-text'
33
- }`,
34
- pill: `px-3.5 py-1.5 text-xs font-bold rounded-full cursor-pointer scale-100 ${
35
- isCurrent ? 'bg-vsc-accent text-vsc-button-text shadow-sm' : 'bg-vsc-hover/40 text-vsc-muted hover:bg-vsc-hover'
36
- }`,
37
- vscode: `px-4 text-xs font-medium border-r border-vsc-border cursor-pointer ${
38
- isCurrent ? 'bg-vsc-bg text-vsc-text border-t-2 border-t-vsc-accent -mt-[1px]' : 'bg-vsc-sidebar text-vsc-muted hover:bg-vsc-hover/50'
39
- }`,
40
- ghost: `px-3 py-1.5 text-xs font-semibold rounded cursor-pointer ${
41
- isCurrent ? 'bg-vsc-hover text-vsc-text font-bold' : 'text-vsc-muted hover:bg-vsc-hover/30'
42
- }`
46
+ const variantStyles: Record<TabVariant, React.CSSProperties> = {
47
+ underline: {
48
+ padding: '4px 12px 8px 12px',
49
+ fontWeight: isCurrent ? 600 : 500,
50
+ color: isCurrent ? searchTokens.colors.text : (isHovered ? searchTokens.colors.text : searchTokens.colors.muted),
51
+ borderBottom: `2px solid ${isCurrent ? searchTokens.colors.borderAccent : 'transparent'}`
52
+ },
53
+ 'sliding-underline': {
54
+ padding: '8px 16px',
55
+ fontWeight: isCurrent ? 700 : 500,
56
+ color: isCurrent ? searchTokens.colors.text : (isHovered ? searchTokens.colors.text : searchTokens.colors.muted)
57
+ },
58
+ pill: {
59
+ padding: '6px 14px',
60
+ fontWeight: 700,
61
+ borderRadius: '9999px',
62
+ backgroundColor: isCurrent ? searchTokens.colors.borderAccent : (isHovered ? searchTokens.colors.hoverBg : 'transparent'),
63
+ color: isCurrent ? '#ffffff' : (isHovered ? searchTokens.colors.text : searchTokens.colors.muted),
64
+ transform: isCurrent ? 'scale(1.02)' : 'scale(1)',
65
+ boxShadow: isCurrent ? '0 1px 3px rgba(0,0,0,0.1)' : 'none'
66
+ },
67
+ vscode: {
68
+ padding: '0 16px',
69
+ fontWeight: 500,
70
+ color: isCurrent ? searchTokens.colors.text : (isHovered ? searchTokens.colors.text : searchTokens.colors.muted),
71
+ backgroundColor: isCurrent ? searchTokens.colors.bgInput : (isHovered ? 'rgba(0,0,0,0.02)' : searchTokens.colors.sidebarBg),
72
+ borderRight: `1px solid ${searchTokens.colors.border}`,
73
+ borderTop: isCurrent ? `2px solid ${searchTokens.colors.borderAccent}` : '2px solid transparent',
74
+ marginTop: isCurrent ? '-1px' : '0'
75
+ },
76
+ ghost: {
77
+ padding: '6px 12px',
78
+ fontWeight: isCurrent ? 700 : 500,
79
+ borderRadius: '2px',
80
+ backgroundColor: isCurrent ? searchTokens.colors.hoverBg : (isHovered ? 'rgba(0,0,0,0.04)' : 'transparent'),
81
+ color: isCurrent ? searchTokens.colors.text : (isHovered ? searchTokens.colors.text : searchTokens.colors.muted)
82
+ }
43
83
  };
44
84
 
45
85
  return (
46
86
  <button
47
87
  data-id={id}
48
88
  onClick={() => changeTab(id)}
49
- className={`${baseStyles} ${variantClasses[variant]}`}
89
+ onMouseEnter={() => setIsHovered(true)}
90
+ onMouseLeave={() => setIsHovered(false)}
91
+ style={{ ...baseButtonStyles, ...variantStyles[variant] }}
50
92
  >
51
- {startIcon && <span className="shrink-0 opacity-80">{startIcon}</span>}
52
- <span className="truncate">{children}</span>
53
- {endIcon && <span className="shrink-0 opacity-70">{endIcon}</span>}
93
+ {startIcon && <span style={{ display: 'inline-flex', flexShrink: 0, opacity: isCurrent || isHovered ? 1 : 0.7 }}>{startIcon}</span>}
94
+ <span style={{ overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{children}</span>
95
+ {endIcon && <span style={{ display: 'inline-flex', flexShrink: 0, opacity: isCurrent || isHovered ? 1 : 0.6 }}>{endIcon}</span>}
54
96
  </button>
55
97
  );
56
98
  }
@@ -1,7 +1,8 @@
1
1
  import React, { useState, useEffect, useRef } from 'react';
2
2
  import { useTab } from './useTab';
3
3
  import { TabVariant } from './types';
4
- import TabButton from './TabButton'; // Imported to execute type-checking audits
4
+ import TabButton from './TabButton';
5
+ import { searchTokens } from '../types';
5
6
 
6
7
  interface TabButtonGroupProps {
7
8
  children: React.ReactNode;
@@ -20,15 +21,10 @@ export default function TabButtonGroup({
20
21
  const [lineStyles, setLineStyles] = useState<React.CSSProperties>({ left: 0, width: 0, opacity: 0 });
21
22
  const [hoveredId, setHoveredId] = useState<string | null>(null);
22
23
 
23
- // --- STRICT CHILDREN SUB-COMPONENT VALIDATION ENGINE LOOP ---
24
24
  const validatedChildren = React.Children.map(children, (child) => {
25
25
  if (!React.isValidElement(child)) return null;
26
-
27
- // Verify if the child component reference maps directly to our TabButton signature
28
26
  if (child.type !== TabButton) {
29
- console.warn(
30
- `[Voxel UI Validation Warning]: TabButtonGroup scope "${scopeName}" only accepts sub-children elements of type <TabButton />. Ignored invalid component node.`
31
- );
27
+ console.warn(`[Voxel UI Warning]: TabButtonGroup only accepts children of type <TabButton />.`);
32
28
  return null;
33
29
  }
34
30
  return child;
@@ -45,18 +41,27 @@ export default function TabButtonGroup({
45
41
  left: `${targetElement.offsetLeft}px`,
46
42
  width: `${targetElement.offsetWidth}px`,
47
43
  opacity: 1,
48
- backgroundColor: hoveredId && hoveredId !== activeTab ? 'var(--color-vsc-text)' : 'var(--color-vsc-accent)'
44
+ backgroundColor: hoveredId && hoveredId !== activeTab ? searchTokens.colors.text : searchTokens.colors.borderAccent
49
45
  });
50
46
  }
51
47
  }, [activeTab, hoveredId, variant]);
52
48
 
53
- const containerClasses = {
54
- underline: 'flex items-center space-x-2 border-b border-vsc-border w-full bg-vsc-bg pb-[1px]',
55
- 'sliding-underline': 'relative flex items-center border-b border-vsc-border w-full bg-vsc-bg pb-[2px]',
56
- pill: 'flex items-center space-x-1.5 p-1 bg-vsc-sidebar rounded-full w-fit',
57
- vscode: 'flex items-center h-9 bg-vsc-sidebar border-b border-vsc-border w-full overflow-hidden',
58
- ghost: 'flex items-center space-x-1 p-1 bg-vsc-bg-input border border-vsc-border rounded'
59
- }[variant];
49
+ const baseContainerStyles: React.CSSProperties = {
50
+ display: 'flex',
51
+ alignItems: 'center',
52
+ fontFamily: searchTokens.typography.sans,
53
+ userSelect: 'none',
54
+ boxSizing: 'border-box',
55
+ position: 'relative'
56
+ };
57
+
58
+ const variantContainerStyles: Record<TabVariant, React.CSSProperties> = {
59
+ underline: { width: '100%', borderBottom: `1px solid ${searchTokens.colors.border}`, backgroundColor: searchTokens.colors.bgInput, gap: '8px', paddingBottom: '1px' },
60
+ 'sliding-underline': { width: '100%', borderBottom: `1px solid ${searchTokens.colors.border}`, backgroundColor: searchTokens.colors.bgInput, paddingBottom: '2px' },
61
+ pill: { width: 'max-content', padding: '4px', backgroundColor: searchTokens.colors.sidebarBg, borderRadius: '9999px', gap: '6px' },
62
+ vscode: { width: '100%', height: '36px', backgroundColor: searchTokens.colors.sidebarBg, borderBottom: `1px solid ${searchTokens.colors.border}`, overflowX: 'auto', overflowY: 'hidden' },
63
+ ghost: { width: '100%', padding: '4px', backgroundColor: searchTokens.colors.bgInput, border: `1px solid ${searchTokens.colors.border}`, borderRadius: '4px', gap: '4px' }
64
+ };
60
65
 
61
66
  return (
62
67
  <div
@@ -66,15 +71,22 @@ export default function TabButtonGroup({
66
71
  if (btn) setHoveredId(btn.getAttribute('data-id'));
67
72
  }}
68
73
  onMouseLeave={() => setHoveredId(null)}
69
- className={`${containerClasses} select-none`}
74
+ style={{ ...baseContainerStyles, ...variantContainerStyles[variant] }}
70
75
  >
71
- {/* Render exclusively the type-validated sub-nodes collection array */}
72
76
  {validatedChildren}
73
77
 
78
+ {/* Real-time Sliding Underline Track Line Component */}
74
79
  {variant === 'sliding-underline' && (
75
80
  <div
76
- className="absolute bottom-0 h-0.5 rounded-t transition-all duration-200 ease-out pointer-events-none z-20"
77
- style={lineStyles}
81
+ style={{
82
+ position: 'absolute',
83
+ bottom: 0,
84
+ height: '2px',
85
+ borderRadius: '2px 2px 0 0',
86
+ transition: 'all 200ms cubic-bezier(0.34, 1.56, 0.64, 1)',
87
+ zIndex: 20,
88
+ ...lineStyles
89
+ }}
78
90
  />
79
91
  )}
80
92
  </div>
@@ -10,7 +10,6 @@ interface TabPanelProps {
10
10
  export default function TabPanel({ children, id, persist = false }: TabPanelProps) {
11
11
  const { activeTabId } = useTabListContext();
12
12
  const isCurrent = activeTabId === id;
13
-
14
13
  const [hasRenderedOnce, setHasRenderedOnce] = useState<boolean>(false);
15
14
 
16
15
  useEffect(() => {
@@ -22,21 +21,40 @@ export default function TabPanel({ children, id, persist = false }: TabPanelProp
22
21
  if (!hasRenderedOnce) return null;
23
22
  if (!persist && !isCurrent) return null;
24
23
 
24
+ // Render the core layout canvas frame absolutely with zero layout shifts
25
+ const panelInlineStyles: React.CSSProperties = {
26
+ position: 'absolute',
27
+ top: 0,
28
+ left: 0,
29
+ right: 0,
30
+ bottom: 0,
31
+ width: '100%',
32
+ height: '100%',
33
+ /*
34
+ ⚡ FIXED VISIBILITY OVERRIDE:
35
+ Bypassed background color fills entirely to prevent canvas z-index clipping traps.
36
+ */
37
+ backgroundColor: 'transparent',
38
+ transition: 'opacity 250ms ease-out, transform 250ms cubic-bezier(0.34, 1.56, 0.64, 1)',
39
+ boxSizing: 'border-box',
40
+
41
+ // Smooth opacity fading animation matrices
42
+ opacity: isCurrent ? 1 : 0,
43
+ transform: isCurrent ? 'scale(1)' : 'scale(0.995)',
44
+ zIndex: isCurrent ? 10 : 0,
45
+ pointerEvents: isCurrent ? 'auto' : 'none',
46
+ visibility: isCurrent ? 'visible' : 'hidden'
47
+ };
48
+
25
49
  return (
26
- <div
27
- className={`absolute inset-0 w-full h-full bg-vsc-bg transition-all duration-300 ease-in-out ${
28
- isCurrent
29
- ? 'opacity-100 scale-100 z-10 pointer-events-auto visible'
30
- : 'opacity-0 scale-[0.99] z-0 pointer-events-none invisible delay-75'
31
- }`}
32
- >
33
- {/*
34
- Inner layout wrapper applies a micro-blur and fine opacity mask cross-fade
35
- to ensure background elements never clip through transparent gaps during transitions.
36
- */}
37
- <div className={`w-full h-full transition-opacity duration-300 ${
38
- isCurrent ? 'opacity-100' : 'opacity-0'
39
- }`}>
50
+ <div style={panelInlineStyles}>
51
+ <div
52
+ style={{
53
+ width: '100%',
54
+ height: '100%',
55
+ boxSizing: 'border-box'
56
+ }}
57
+ >
40
58
  {children}
41
59
  </div>
42
60
  </div>
@@ -1,10 +1,11 @@
1
1
  import React, { useEffect, createContext, useContext } from 'react';
2
2
  import { useTab } from './useTab';
3
+ import { searchTokens } from '../types';
3
4
 
4
5
  interface TabPanelListProps {
5
6
  children: React.ReactNode;
6
- targetScopeName: string; // Ties this structural list panel block to a named useTab hook loop
7
- defaultValue: string; // Initial focus viewport tab on render
7
+ targetScopeName: string; // Ties this list panel block to a named useTab instance
8
+ defaultValue: string; // Initial focused tab on mount
8
9
  }
9
10
 
10
11
  const TabListContext = createContext<{ activeTabId: string | undefined }>({ activeTabId: undefined });
@@ -14,16 +15,29 @@ export const useTabListContext = () => useContext(TabListContext);
14
15
  export default function TabPanelList({ children, targetScopeName, defaultValue }: TabPanelListProps) {
15
16
  const { activeTab, registerDefault } = useTab(targetScopeName);
16
17
 
17
- // Initialize defaultValue into state if it's the first execution pass
18
+ // Initialize defaultValue into the global Zustand store on first render execution
18
19
  useEffect(() => {
19
20
  registerDefault(defaultValue);
20
21
  }, [defaultValue, registerDefault]);
21
22
 
22
23
  const activeTabId = activeTab || defaultValue;
23
24
 
25
+ // Root canvas frame styling object using pure inline layout logic
26
+ const listContainerInlineStyles: React.CSSProperties = {
27
+ position: 'relative',
28
+ width: '100%',
29
+ height: '100%',
30
+ minHeight: 0,
31
+ flex: '1 1 0%',
32
+ overflow: 'hidden',
33
+ backgroundColor: searchTokens.colors.bgInput,
34
+ fontFamily: searchTokens.typography.sans,
35
+ boxSizing: 'border-box'
36
+ };
37
+
24
38
  return (
25
39
  <TabListContext.Provider value={{ activeTabId }}>
26
- <div className="relative w-full h-full min-h-0 flex-1 overflow-hidden bg-vsc-bg">
40
+ <div style={listContainerInlineStyles}>
27
41
  {children}
28
42
  </div>
29
43
  </TabListContext.Provider>
@@ -0,0 +1,22 @@
1
+
2
+ export const searchTokens = {
3
+ colors: {
4
+ bgInput: 'var(--color-vsc-bg-input, #f6f8fa)',
5
+ border: 'var(--color-vsc-border, #e4e4e7)',
6
+ borderAccent: 'var(--color-vsc-accent, #007acc)',
7
+ borderAccentHover: 'var(--color-vsc-accent-hover, #0062a3)',
8
+ text: 'var(--color-vsc-text, #333333)',
9
+ muted: 'var(--color-vsc-muted, #6a737d)',
10
+ sidebarBg: 'var(--color-vsc-sidebar, #f3f3f3)',
11
+ hoverBg: 'var(--color-vsc-hover, #e8e8e8)',
12
+ accentBgLight: 'rgba(0, 122, 204, 0.1)'
13
+ },
14
+ typography: {
15
+ /* ⚡ Pulls Tailwind's native font configuration maps from your global layout shell App context */
16
+ sans: 'var(--font-sans, font-sans, ui-sans-serif, system-ui, sans-serif)',
17
+ mono: 'var(--font-mono, font-mono, ui-monospace, SFMono-Regular, monospace)'
18
+ },
19
+ transitions: {
20
+ smooth: 'all 200ms cubic-bezier(0.34, 1.56, 0.64, 1)'
21
+ }
22
+ };
@@ -1,86 +0,0 @@
1
- import { t as e } from "./jsx-runtime-Boo2vksn.js";
2
- import { createContext as t, useContext as n, useEffect as r, useState as i } from "react";
3
- import { create as a } from "zustand";
4
- //#region src/components/tabs/useTab.ts
5
- var o = a((e) => ({
6
- activeTabs: {},
7
- setActiveTab: (t, n) => e((e) => ({ activeTabs: {
8
- ...e.activeTabs,
9
- [t]: n
10
- } })),
11
- initializeTab: (t, n) => e((e) => e.activeTabs[t] ? {} : { activeTabs: {
12
- ...e.activeTabs,
13
- [t]: n
14
- } })
15
- }));
16
- function s(e) {
17
- let t = o((t) => t.activeTabs[e]), n = o((e) => e.setActiveTab), r = o((e) => e.initializeTab);
18
- return {
19
- activeTab: t,
20
- changeTab: (t) => n(e, t),
21
- registerDefault: (t) => r(e, t)
22
- };
23
- }
24
- //#endregion
25
- //#region src/components/tabs/TabPanelList.tsx
26
- var c = e(), l = t({ activeTabId: void 0 }), u = () => n(l);
27
- function d({ children: e, targetScopeName: t, defaultValue: n }) {
28
- let { activeTab: i, registerDefault: a } = s(t);
29
- r(() => {
30
- a(n);
31
- }, [n, a]);
32
- let o = i || n;
33
- return /* @__PURE__ */ (0, c.jsx)(l.Provider, {
34
- value: { activeTabId: o },
35
- children: /* @__PURE__ */ (0, c.jsx)("div", {
36
- className: "relative w-full h-full min-h-0 flex-1 overflow-hidden bg-vsc-bg",
37
- children: e
38
- })
39
- });
40
- }
41
- //#endregion
42
- //#region src/components/tabs/TabPanel.tsx
43
- function f({ children: e, id: t, persist: n = !1 }) {
44
- let { activeTabId: a } = u(), o = a === t, [s, l] = i(!1);
45
- return r(() => {
46
- o && !s && l(!0);
47
- }, [o, s]), !s || !n && !o ? null : /* @__PURE__ */ (0, c.jsx)("div", {
48
- className: `absolute inset-0 w-full h-full bg-vsc-bg transition-all duration-300 ease-in-out ${o ? "opacity-100 scale-100 z-10 pointer-events-auto visible" : "opacity-0 scale-[0.99] z-0 pointer-events-none invisible delay-75"}`,
49
- children: /* @__PURE__ */ (0, c.jsx)("div", {
50
- className: `w-full h-full transition-opacity duration-300 ${o ? "opacity-100" : "opacity-0"}`,
51
- children: e
52
- })
53
- });
54
- }
55
- //#endregion
56
- //#region src/components/tabs/TabButton.tsx
57
- function p({ id: e, scopeName: t, children: n, variant: r = "underline", startIcon: i, endIcon: a }) {
58
- let { activeTab: o, changeTab: l } = s(t), u = o === e;
59
- return /* @__PURE__ */ (0, c.jsxs)("button", {
60
- "data-id": e,
61
- onClick: () => l(e),
62
- className: `flex items-center justify-center gap-1.5 focus:outline-none border-none outline-none z-10 transition-colors select-none h-full ${{
63
- underline: `pb-2 pt-1 px-3 text-xs font-semibold cursor-pointer border-b-2 ${u ? "border-vsc-accent text-vsc-text" : "border-transparent text-vsc-muted hover:text-vsc-text"}`,
64
- "sliding-underline": `py-2 px-4 text-xs font-semibold cursor-pointer transition-colors duration-200 ${u ? "text-vsc-text font-bold" : "text-vsc-muted hover:text-vsc-text"}`,
65
- pill: `px-3.5 py-1.5 text-xs font-bold rounded-full cursor-pointer scale-100 ${u ? "bg-vsc-accent text-vsc-button-text shadow-sm" : "bg-vsc-hover/40 text-vsc-muted hover:bg-vsc-hover"}`,
66
- vscode: `px-4 text-xs font-medium border-r border-vsc-border cursor-pointer ${u ? "bg-vsc-bg text-vsc-text border-t-2 border-t-vsc-accent -mt-[1px]" : "bg-vsc-sidebar text-vsc-muted hover:bg-vsc-hover/50"}`,
67
- ghost: `px-3 py-1.5 text-xs font-semibold rounded cursor-pointer ${u ? "bg-vsc-hover text-vsc-text font-bold" : "text-vsc-muted hover:bg-vsc-hover/30"}`
68
- }[r]}`,
69
- children: [
70
- i && /* @__PURE__ */ (0, c.jsx)("span", {
71
- className: "shrink-0 opacity-80",
72
- children: i
73
- }),
74
- /* @__PURE__ */ (0, c.jsx)("span", {
75
- className: "truncate",
76
- children: n
77
- }),
78
- a && /* @__PURE__ */ (0, c.jsx)("span", {
79
- className: "shrink-0 opacity-70",
80
- children: a
81
- })
82
- ]
83
- });
84
- }
85
- //#endregion
86
- export { s as i, f as n, d as r, p as t };