@knymbus/voxel-ui 1.0.11 → 1.0.14
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/chunks/search-CIhA-ti4.js +457 -0
- package/dist/components/search/SearchInput.d.ts +2 -9
- package/dist/components/search/SearchMenu.d.ts +11 -0
- package/dist/components/search/index.js +2 -2
- package/dist/components/search/types.d.ts +23 -0
- package/dist/index.js +2 -3
- package/package.json +1 -1
- package/src/components/search/SearchInput.tsx +144 -134
- package/src/components/search/SearchMenu.tsx +119 -0
- package/src/components/search/types.ts +29 -2
- package/src/index.ts +0 -1
- package/vite.config.mts +0 -4
- package/dist/chunks/search-BnD-97mv.js +0 -205
|
@@ -0,0 +1,457 @@
|
|
|
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", {
|
|
27
|
+
style: {
|
|
28
|
+
position: "absolute",
|
|
29
|
+
top: "36px",
|
|
30
|
+
left: 0,
|
|
31
|
+
width: "100%",
|
|
32
|
+
backgroundColor: s.colors.sidebarBg,
|
|
33
|
+
border: `1px solid ${s.colors.border}`,
|
|
34
|
+
borderRadius: "4px",
|
|
35
|
+
boxShadow: "0 10px 15px -3px rgba(0, 0, 0, 0.2)",
|
|
36
|
+
zIndex: 50,
|
|
37
|
+
padding: "4px",
|
|
38
|
+
display: "flex",
|
|
39
|
+
flexDirection: "column",
|
|
40
|
+
maxHeight: "256px"
|
|
41
|
+
},
|
|
42
|
+
children: [/* @__PURE__ */ (0, c.jsx)("div", {
|
|
43
|
+
style: {
|
|
44
|
+
overflowY: "auto",
|
|
45
|
+
flex: 1
|
|
46
|
+
},
|
|
47
|
+
children: n.length === 0 ? /* @__PURE__ */ (0, c.jsx)("div", {
|
|
48
|
+
style: {
|
|
49
|
+
padding: "16px",
|
|
50
|
+
textAlign: "center",
|
|
51
|
+
fontSize: "11px",
|
|
52
|
+
color: s.colors.muted,
|
|
53
|
+
fontStyle: "italic"
|
|
54
|
+
},
|
|
55
|
+
children: "No indexed record entities match your text query constraints."
|
|
56
|
+
}) : n.map((e) => /* @__PURE__ */ (0, c.jsxs)("div", {
|
|
57
|
+
onMouseEnter: () => u(e.id),
|
|
58
|
+
onMouseLeave: () => u(null),
|
|
59
|
+
onClick: () => {
|
|
60
|
+
r && r(e), a();
|
|
61
|
+
},
|
|
62
|
+
style: {
|
|
63
|
+
width: "100%",
|
|
64
|
+
padding: "8px",
|
|
65
|
+
backgroundColor: l === e.id ? s.colors.hoverBg : "transparent",
|
|
66
|
+
borderRadius: "2px",
|
|
67
|
+
cursor: "pointer",
|
|
68
|
+
display: "flex",
|
|
69
|
+
flexDirection: "column",
|
|
70
|
+
gap: "2px",
|
|
71
|
+
transition: "background-color 100ms",
|
|
72
|
+
boxSizing: "border-box"
|
|
73
|
+
},
|
|
74
|
+
children: [/* @__PURE__ */ (0, c.jsxs)("div", {
|
|
75
|
+
style: {
|
|
76
|
+
fontWeight: 600,
|
|
77
|
+
color: s.colors.text,
|
|
78
|
+
display: "flex",
|
|
79
|
+
justifyContent: "space-between",
|
|
80
|
+
alignItems: "center",
|
|
81
|
+
width: "100%"
|
|
82
|
+
},
|
|
83
|
+
children: [/* @__PURE__ */ (0, c.jsx)("span", {
|
|
84
|
+
style: {
|
|
85
|
+
whiteSpace: "nowrap",
|
|
86
|
+
overflow: "hidden",
|
|
87
|
+
textOverflow: "ellipsis",
|
|
88
|
+
flex: 1
|
|
89
|
+
},
|
|
90
|
+
children: e.title
|
|
91
|
+
}), e.category && /* @__PURE__ */ (0, c.jsx)("span", {
|
|
92
|
+
style: {
|
|
93
|
+
fontSize: "9px",
|
|
94
|
+
fontFamily: "monospace",
|
|
95
|
+
fontWeight: "bold",
|
|
96
|
+
backgroundColor: s.colors.accentBgLight,
|
|
97
|
+
border: "1px solid rgba(0, 122, 204, 0.2)",
|
|
98
|
+
color: s.colors.borderAccent,
|
|
99
|
+
padding: "2px 4px",
|
|
100
|
+
borderRadius: "2px",
|
|
101
|
+
textTransform: "uppercase",
|
|
102
|
+
marginLeft: "8px",
|
|
103
|
+
flexShrink: 0
|
|
104
|
+
},
|
|
105
|
+
children: e.category
|
|
106
|
+
})]
|
|
107
|
+
}), e.subtitle && /* @__PURE__ */ (0, c.jsx)("div", {
|
|
108
|
+
style: {
|
|
109
|
+
fontSize: "10px",
|
|
110
|
+
color: s.colors.muted,
|
|
111
|
+
whiteSpace: "nowrap",
|
|
112
|
+
overflow: "hidden",
|
|
113
|
+
textOverflow: "ellipsis"
|
|
114
|
+
},
|
|
115
|
+
children: e.subtitle
|
|
116
|
+
})]
|
|
117
|
+
}, e.id))
|
|
118
|
+
}), n.length > 0 && i && /* @__PURE__ */ (0, c.jsx)("button", {
|
|
119
|
+
onMouseEnter: () => f(!0),
|
|
120
|
+
onMouseLeave: () => f(!1),
|
|
121
|
+
onClick: () => {
|
|
122
|
+
i(), a();
|
|
123
|
+
},
|
|
124
|
+
style: {
|
|
125
|
+
width: "100%",
|
|
126
|
+
border: "none",
|
|
127
|
+
borderTop: `1px solid ${s.colors.border}`,
|
|
128
|
+
backgroundColor: d ? s.colors.hoverBg : "transparent",
|
|
129
|
+
padding: "8px",
|
|
130
|
+
textAlign: "center",
|
|
131
|
+
fontSize: "10px",
|
|
132
|
+
fontWeight: "bold",
|
|
133
|
+
color: s.colors.borderAccent,
|
|
134
|
+
letterSpacing: "0.5px",
|
|
135
|
+
textTransform: "uppercase",
|
|
136
|
+
transition: "background-color 150ms",
|
|
137
|
+
borderRadius: "0 0 2px 2px",
|
|
138
|
+
cursor: "pointer"
|
|
139
|
+
},
|
|
140
|
+
children: "View All Matching Search Metrics Records →"
|
|
141
|
+
})]
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
//#endregion
|
|
145
|
+
//#region src/components/search/SearchInput.tsx
|
|
146
|
+
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(() => {
|
|
149
|
+
let t = (t) => {
|
|
150
|
+
k.current && !k.current.contains(t.target) && (w(!1), e === "float" && u === "" && S(!1));
|
|
151
|
+
};
|
|
152
|
+
return window.addEventListener("mousedown", t), () => window.removeEventListener("mousedown", t);
|
|
153
|
+
}, [e, u]);
|
|
154
|
+
let j = (e) => {
|
|
155
|
+
e.stopPropagation(), d(""), f && f(), A.current && A.current.focus();
|
|
156
|
+
}, M = () => {
|
|
157
|
+
S(!0), setTimeout(() => A.current?.focus(), 50);
|
|
158
|
+
}, N = {
|
|
159
|
+
position: "relative",
|
|
160
|
+
display: "flex",
|
|
161
|
+
flexDirection: "column",
|
|
162
|
+
fontFamily: s.typography.sans,
|
|
163
|
+
fontSize: "12px",
|
|
164
|
+
userSelect: "none",
|
|
165
|
+
boxSizing: "border-box"
|
|
166
|
+
}, P = {
|
|
167
|
+
position: "relative",
|
|
168
|
+
display: "flex",
|
|
169
|
+
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}`,
|
|
172
|
+
borderRadius: "6px",
|
|
173
|
+
height: "32px",
|
|
174
|
+
transition: s.transitions.smooth,
|
|
175
|
+
boxSizing: "border-box"
|
|
176
|
+
}, F = {
|
|
177
|
+
width: "100%",
|
|
178
|
+
height: "100%",
|
|
179
|
+
backgroundColor: "transparent",
|
|
180
|
+
color: s.colors.text,
|
|
181
|
+
border: "none",
|
|
182
|
+
outline: "none",
|
|
183
|
+
padding: "0 32px",
|
|
184
|
+
fontSize: "12px",
|
|
185
|
+
fontFamily: s.typography.sans,
|
|
186
|
+
boxSizing: "border-box"
|
|
187
|
+
};
|
|
188
|
+
if (e === "simple") {
|
|
189
|
+
let e = m > 0 && u.length > 0, i = b || /* @__PURE__ */ (0, c.jsxs)("p", {
|
|
190
|
+
style: {
|
|
191
|
+
margin: 0,
|
|
192
|
+
fontSize: "10px",
|
|
193
|
+
fontFamily: s.typography.mono,
|
|
194
|
+
color: s.colors.muted,
|
|
195
|
+
whiteSpace: "nowrap",
|
|
196
|
+
overflow: "hidden",
|
|
197
|
+
textOverflow: "ellipsis"
|
|
198
|
+
},
|
|
199
|
+
children: [
|
|
200
|
+
"Showing ",
|
|
201
|
+
/* @__PURE__ */ (0, c.jsx)("span", {
|
|
202
|
+
style: {
|
|
203
|
+
color: s.colors.borderAccent,
|
|
204
|
+
fontWeight: "bold"
|
|
205
|
+
},
|
|
206
|
+
children: m
|
|
207
|
+
}),
|
|
208
|
+
" matching database metrics records"
|
|
209
|
+
]
|
|
210
|
+
});
|
|
211
|
+
return /* @__PURE__ */ (0, c.jsxs)("div", {
|
|
212
|
+
style: N,
|
|
213
|
+
className: v,
|
|
214
|
+
children: [/* @__PURE__ */ (0, c.jsxs)("div", {
|
|
215
|
+
style: P,
|
|
216
|
+
onMouseEnter: () => E(!0),
|
|
217
|
+
onMouseLeave: () => E(!1),
|
|
218
|
+
children: [
|
|
219
|
+
/* @__PURE__ */ (0, c.jsx)("div", {
|
|
220
|
+
style: {
|
|
221
|
+
position: "absolute",
|
|
222
|
+
left: "10px",
|
|
223
|
+
display: "flex",
|
|
224
|
+
alignItems: "center",
|
|
225
|
+
color: T ? s.colors.text : s.colors.muted
|
|
226
|
+
},
|
|
227
|
+
children: /* @__PURE__ */ (0, c.jsx)(r, { size: 14 })
|
|
228
|
+
}),
|
|
229
|
+
/* @__PURE__ */ (0, c.jsx)("input", {
|
|
230
|
+
ref: A,
|
|
231
|
+
type: "text",
|
|
232
|
+
value: u,
|
|
233
|
+
onChange: (e) => d(e.target.value),
|
|
234
|
+
onFocus: () => O(!0),
|
|
235
|
+
onBlur: () => O(!1),
|
|
236
|
+
placeholder: p,
|
|
237
|
+
style: F
|
|
238
|
+
}),
|
|
239
|
+
u && /* @__PURE__ */ (0, c.jsx)("div", {
|
|
240
|
+
style: {
|
|
241
|
+
position: "absolute",
|
|
242
|
+
right: "4px",
|
|
243
|
+
top: "50%",
|
|
244
|
+
transform: "translateY(-50%)",
|
|
245
|
+
display: "flex",
|
|
246
|
+
alignItems: "center"
|
|
247
|
+
},
|
|
248
|
+
children: /* @__PURE__ */ (0, c.jsx)(t, {
|
|
249
|
+
icon: n,
|
|
250
|
+
color: "ghost",
|
|
251
|
+
iconOnly: !0,
|
|
252
|
+
onClick: j,
|
|
253
|
+
size: "xs"
|
|
254
|
+
})
|
|
255
|
+
})
|
|
256
|
+
]
|
|
257
|
+
}), /* @__PURE__ */ (0, c.jsx)("div", {
|
|
258
|
+
style: {
|
|
259
|
+
position: "absolute",
|
|
260
|
+
left: 0,
|
|
261
|
+
right: 0,
|
|
262
|
+
top: "32px",
|
|
263
|
+
zIndex: 10,
|
|
264
|
+
overflow: "hidden",
|
|
265
|
+
transition: s.transitions.smooth,
|
|
266
|
+
height: e ? "24px" : "0px",
|
|
267
|
+
opacity: +!!e,
|
|
268
|
+
transform: e ? "translateY(0px)" : "translateY(-4px)",
|
|
269
|
+
pointerEvents: "none"
|
|
270
|
+
},
|
|
271
|
+
children: /* @__PURE__ */ (0, c.jsx)("div", {
|
|
272
|
+
style: {
|
|
273
|
+
backgroundColor: s.colors.sidebarBg,
|
|
274
|
+
border: `1px solid ${s.colors.border}`,
|
|
275
|
+
borderTop: "none",
|
|
276
|
+
padding: "4px 6px",
|
|
277
|
+
borderRadius: "0 0 6px 6px",
|
|
278
|
+
boxShadow: "0 4px 6px -1px rgba(0,0,0,0.1)"
|
|
279
|
+
},
|
|
280
|
+
children: i
|
|
281
|
+
})
|
|
282
|
+
})]
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
if (e === "float") {
|
|
286
|
+
let e = y && m > 0 && u.length > 0, i = x || u.length > 0, a = b || /* @__PURE__ */ (0, c.jsxs)("p", {
|
|
287
|
+
style: {
|
|
288
|
+
margin: 0,
|
|
289
|
+
fontSize: "9px",
|
|
290
|
+
fontFamily: s.typography.mono,
|
|
291
|
+
color: s.colors.borderAccent,
|
|
292
|
+
whiteSpace: "nowrap",
|
|
293
|
+
overflow: "hidden",
|
|
294
|
+
textOverflow: "ellipsis"
|
|
295
|
+
},
|
|
296
|
+
children: [
|
|
297
|
+
"Quick Peek: Found ",
|
|
298
|
+
m,
|
|
299
|
+
" rows"
|
|
300
|
+
]
|
|
301
|
+
});
|
|
302
|
+
return /* @__PURE__ */ (0, c.jsxs)("div", {
|
|
303
|
+
ref: k,
|
|
304
|
+
style: N,
|
|
305
|
+
className: v,
|
|
306
|
+
children: [/* @__PURE__ */ (0, c.jsx)("div", {
|
|
307
|
+
onMouseEnter: () => E(!0),
|
|
308
|
+
onMouseLeave: () => E(!1),
|
|
309
|
+
style: {
|
|
310
|
+
...P,
|
|
311
|
+
width: i ? "256px" : "32px",
|
|
312
|
+
justifyContent: i ? "flex-start" : "center",
|
|
313
|
+
backgroundColor: i ? s.colors.bgInput : "transparent",
|
|
314
|
+
borderColor: i ? s.colors.borderAccent : "transparent",
|
|
315
|
+
padding: i ? "0 8px" : "0"
|
|
316
|
+
},
|
|
317
|
+
children: i ? /* @__PURE__ */ (0, c.jsxs)("div", {
|
|
318
|
+
style: {
|
|
319
|
+
position: "relative",
|
|
320
|
+
display: "flex",
|
|
321
|
+
alignItems: "center",
|
|
322
|
+
width: "100%",
|
|
323
|
+
height: "100%"
|
|
324
|
+
},
|
|
325
|
+
children: [
|
|
326
|
+
/* @__PURE__ */ (0, c.jsx)(r, {
|
|
327
|
+
size: 14,
|
|
328
|
+
style: {
|
|
329
|
+
color: s.colors.text,
|
|
330
|
+
flexShrink: 0
|
|
331
|
+
}
|
|
332
|
+
}),
|
|
333
|
+
/* @__PURE__ */ (0, c.jsx)("input", {
|
|
334
|
+
ref: A,
|
|
335
|
+
type: "text",
|
|
336
|
+
value: u,
|
|
337
|
+
onChange: (e) => d(e.target.value),
|
|
338
|
+
placeholder: p,
|
|
339
|
+
style: {
|
|
340
|
+
...F,
|
|
341
|
+
padding: "0 24px 0 8px"
|
|
342
|
+
}
|
|
343
|
+
}),
|
|
344
|
+
u && /* @__PURE__ */ (0, c.jsx)("div", {
|
|
345
|
+
style: {
|
|
346
|
+
position: "absolute",
|
|
347
|
+
right: 0,
|
|
348
|
+
top: "50%",
|
|
349
|
+
transform: "translateY(-50%)",
|
|
350
|
+
display: "flex",
|
|
351
|
+
alignItems: "center"
|
|
352
|
+
},
|
|
353
|
+
children: /* @__PURE__ */ (0, c.jsx)(t, {
|
|
354
|
+
iconOnly: !0,
|
|
355
|
+
color: "ghost",
|
|
356
|
+
icon: n,
|
|
357
|
+
onClick: j,
|
|
358
|
+
size: "xs"
|
|
359
|
+
})
|
|
360
|
+
})
|
|
361
|
+
]
|
|
362
|
+
}) : /* @__PURE__ */ (0, c.jsx)(t, {
|
|
363
|
+
iconOnly: !0,
|
|
364
|
+
size: "sm",
|
|
365
|
+
icon: r,
|
|
366
|
+
onClick: M,
|
|
367
|
+
color: "ghost",
|
|
368
|
+
style: { color: s.colors.muted },
|
|
369
|
+
title: "Open Expandable Search"
|
|
370
|
+
})
|
|
371
|
+
}), /* @__PURE__ */ (0, c.jsx)("div", {
|
|
372
|
+
style: {
|
|
373
|
+
position: "absolute",
|
|
374
|
+
top: "32px",
|
|
375
|
+
width: "256px",
|
|
376
|
+
zIndex: 10,
|
|
377
|
+
overflow: "hidden",
|
|
378
|
+
transition: s.transitions.smooth,
|
|
379
|
+
height: e ? "24px" : "0px",
|
|
380
|
+
opacity: +!!e,
|
|
381
|
+
transform: e ? "translateY(0px)" : "translateY(-4px)",
|
|
382
|
+
pointerEvents: "none"
|
|
383
|
+
},
|
|
384
|
+
children: /* @__PURE__ */ (0, c.jsx)("div", {
|
|
385
|
+
style: {
|
|
386
|
+
backgroundColor: s.colors.sidebarBg,
|
|
387
|
+
border: `1px solid ${s.colors.border}`,
|
|
388
|
+
borderTop: "none",
|
|
389
|
+
padding: "4px",
|
|
390
|
+
borderRadius: "0 0 2px 2px",
|
|
391
|
+
boxShadow: "0 4px 6px -1px rgba(0,0,0,0.1)"
|
|
392
|
+
},
|
|
393
|
+
children: a
|
|
394
|
+
})
|
|
395
|
+
})]
|
|
396
|
+
});
|
|
397
|
+
}
|
|
398
|
+
return /* @__PURE__ */ (0, c.jsxs)("div", {
|
|
399
|
+
ref: k,
|
|
400
|
+
style: N,
|
|
401
|
+
className: v,
|
|
402
|
+
children: [/* @__PURE__ */ (0, c.jsxs)("div", {
|
|
403
|
+
style: P,
|
|
404
|
+
onMouseEnter: () => E(!0),
|
|
405
|
+
onMouseLeave: () => E(!1),
|
|
406
|
+
children: [
|
|
407
|
+
/* @__PURE__ */ (0, c.jsx)("div", {
|
|
408
|
+
style: {
|
|
409
|
+
position: "absolute",
|
|
410
|
+
left: "10px",
|
|
411
|
+
display: "flex",
|
|
412
|
+
alignItems: "center",
|
|
413
|
+
color: s.colors.muted
|
|
414
|
+
},
|
|
415
|
+
children: /* @__PURE__ */ (0, c.jsx)(r, { size: 14 })
|
|
416
|
+
}),
|
|
417
|
+
/* @__PURE__ */ (0, c.jsx)("input", {
|
|
418
|
+
ref: A,
|
|
419
|
+
type: "text",
|
|
420
|
+
value: u,
|
|
421
|
+
onChange: (e) => {
|
|
422
|
+
d(e.target.value), w(!0);
|
|
423
|
+
},
|
|
424
|
+
onFocus: () => w(!0),
|
|
425
|
+
placeholder: p,
|
|
426
|
+
style: F
|
|
427
|
+
}),
|
|
428
|
+
u && /* @__PURE__ */ (0, c.jsx)("div", {
|
|
429
|
+
style: {
|
|
430
|
+
position: "absolute",
|
|
431
|
+
right: "4px",
|
|
432
|
+
top: "50%",
|
|
433
|
+
transform: "translateY(-50%)",
|
|
434
|
+
display: "flex",
|
|
435
|
+
alignItems: "center"
|
|
436
|
+
},
|
|
437
|
+
children: /* @__PURE__ */ (0, c.jsx)(t, {
|
|
438
|
+
iconOnly: !0,
|
|
439
|
+
icon: n,
|
|
440
|
+
color: "ghost",
|
|
441
|
+
onClick: j,
|
|
442
|
+
size: "xs"
|
|
443
|
+
})
|
|
444
|
+
})
|
|
445
|
+
]
|
|
446
|
+
}), /* @__PURE__ */ (0, c.jsx)(l, {
|
|
447
|
+
isOpen: C,
|
|
448
|
+
value: u,
|
|
449
|
+
menuResults: h,
|
|
450
|
+
onResultClick: g,
|
|
451
|
+
onViewMoreClick: _,
|
|
452
|
+
onCloseMenu: () => w(!1)
|
|
453
|
+
})]
|
|
454
|
+
});
|
|
455
|
+
}
|
|
456
|
+
//#endregion
|
|
457
|
+
export { s as n, u as t };
|
|
@@ -1,10 +1,3 @@
|
|
|
1
|
-
import { default as React
|
|
1
|
+
import { default as React } from 'react';
|
|
2
2
|
import { SearchInputProps } from './types';
|
|
3
|
-
|
|
4
|
-
variant?: 'simple' | 'float' | 'menu';
|
|
5
|
-
showFloatPeek?: boolean;
|
|
6
|
-
resultIndicatorPanel?: string | ReactNode;
|
|
7
|
-
}
|
|
8
|
-
export default function SearchInput({ variant, value, onChange, onClear, placeholder, resultsCount, menuResults, onResultClick, onViewMoreClick, className, showFloatPeek, // Optional feature flag default boundary
|
|
9
|
-
resultIndicatorPanel }: AdvancedSearchInputProps): React.JSX.Element;
|
|
10
|
-
export {};
|
|
3
|
+
export default function SearchInput({ variant, value, onChange, onClear, placeholder, resultsCount, menuResults, onResultClick, onViewMoreClick, className, showFloatPeek, peekContent }: SearchInputProps): React.JSX.Element;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { SearchResultItem } from './types';
|
|
2
|
+
interface SearchMenuProps {
|
|
3
|
+
isOpen: boolean;
|
|
4
|
+
value: string;
|
|
5
|
+
menuResults: SearchResultItem[];
|
|
6
|
+
onResultClick?: (item: SearchResultItem) => void;
|
|
7
|
+
onViewMoreClick?: () => void;
|
|
8
|
+
onCloseMenu: () => void;
|
|
9
|
+
}
|
|
10
|
+
export default function SearchMenu({ isOpen, value, menuResults, onResultClick, onViewMoreClick, onCloseMenu }: SearchMenuProps): import("react").JSX.Element | null;
|
|
11
|
+
export {};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export {
|
|
1
|
+
import { n as e, t } from "../../chunks/search-CIhA-ti4.js";
|
|
2
|
+
export { t as SearchInput, e as searchTokens };
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
1
2
|
export type SearchVariant = 'simple' | 'float' | 'menu';
|
|
2
3
|
export interface SearchResultItem {
|
|
3
4
|
id: string;
|
|
@@ -16,4 +17,26 @@ export interface SearchInputProps {
|
|
|
16
17
|
onResultClick?: (item: SearchResultItem) => void;
|
|
17
18
|
onViewMoreClick?: () => void;
|
|
18
19
|
className?: string;
|
|
20
|
+
showFloatPeek?: boolean;
|
|
21
|
+
peekContent?: React.ReactNode;
|
|
19
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
|
+
};
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
(function(){try{if(typeof document<`u`){var e=document.createElement(`style`);e.appendChild(document.createTextNode(`/*! tailwindcss v4.3.2 | MIT License | https://tailwindcss.com */@layer theme{:root,:host{--voxel-font-sans:ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--voxel-font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--voxel-default-font-family:var(--voxel-font-sans);--voxel-default-mono-font-family:var(--voxel-font-mono)}}@layer base{@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--voxel-default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--voxel-default-font-feature-settings,normal);font-variation-settings:var(--voxel-default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--voxel-default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--voxel-default-mono-font-feature-settings,normal);font-variation-settings:var(--voxel-default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}.dark{--color-vsc-bg:#1e1e1e;--color-vsc-sidebar:#252526;--color-vsc-border:#3c3c3c;--color-vsc-accent:#007acc;--color-vsc-accent-hover:#0062a3;--color-vsc-hover:#2a2d2e;--color-vsc-text:#ccc;--color-vsc-muted:#8b949e;--color-vsc-bg-input:#1f1f1f}}@layer components,utilities;/*$vite$:1*/`)),document.head.appendChild(e)}}catch(e){console.error(`vite-plugin-css-injected-by-js`,e)}})();
|
|
2
1
|
import { t as e } from "./chunks/resizable-ImB8dfG_.js";
|
|
3
2
|
import { i as t, n, r, t as i } from "./chunks/tabs-MaVN00hJ.js";
|
|
4
3
|
import { t as a } from "./chunks/Button-BgQwvn3C.js";
|
|
5
4
|
import { n as o, t as s } from "./chunks/button-dHcpTNIG.js";
|
|
6
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";
|
|
7
|
-
import {
|
|
8
|
-
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,
|
|
6
|
+
import { n as P, t as F } from "./chunks/search-CIhA-ti4.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 };
|
package/package.json
CHANGED
|
@@ -1,14 +1,8 @@
|
|
|
1
|
-
import React, { useState, useRef, useEffect
|
|
2
|
-
import { SearchInputProps } from './types';
|
|
1
|
+
import React, { useState, useRef, useEffect } from 'react';
|
|
2
|
+
import { SearchInputProps, searchTokens } from './types';
|
|
3
3
|
import { Search, Close } from '../icons';
|
|
4
4
|
import { Button } from '../button/Button';
|
|
5
|
-
|
|
6
|
-
// Extend your props declaration interface locally to support the new feature flags
|
|
7
|
-
interface AdvancedSearchInputProps extends Omit<SearchInputProps, 'variant'> {
|
|
8
|
-
variant?: 'simple' | 'float' | 'menu';
|
|
9
|
-
showFloatPeek?: boolean; // When true, float variant slides down a results indicator bar
|
|
10
|
-
resultIndicatorPanel?: string | ReactNode
|
|
11
|
-
}
|
|
5
|
+
import SearchMenu from './SearchMenu';
|
|
12
6
|
|
|
13
7
|
export default function SearchInput({
|
|
14
8
|
variant = 'simple',
|
|
@@ -21,15 +15,17 @@ export default function SearchInput({
|
|
|
21
15
|
onResultClick,
|
|
22
16
|
onViewMoreClick,
|
|
23
17
|
className = '',
|
|
24
|
-
showFloatPeek = false,
|
|
25
|
-
|
|
26
|
-
}:
|
|
18
|
+
showFloatPeek = false,
|
|
19
|
+
peekContent
|
|
20
|
+
}: SearchInputProps) {
|
|
27
21
|
const [isExpanded, setIsExpanded] = useState<boolean>(false);
|
|
28
22
|
const [isMenuOpen, setIsMenuOpen] = useState<boolean>(false);
|
|
23
|
+
const [isInputHovered, setIsInputHovered] = useState<boolean>(false);
|
|
24
|
+
const [isInputFocused, setIsInputFocused] = useState<boolean>(false);
|
|
25
|
+
|
|
29
26
|
const containerRef = useRef<HTMLDivElement | null>(null);
|
|
30
27
|
const inputRef = useRef<HTMLInputElement | null>(null);
|
|
31
28
|
|
|
32
|
-
// Auto-close overlay dropdowns if the user clicks completely out of the component framework bounding box
|
|
33
29
|
useEffect(() => {
|
|
34
30
|
const handleOutsideClick = (e: MouseEvent) => {
|
|
35
31
|
if (containerRef.current && !containerRef.current.contains(e.target as Node)) {
|
|
@@ -55,67 +51,101 @@ export default function SearchInput({
|
|
|
55
51
|
setTimeout(() => inputRef.current?.focus(), 50);
|
|
56
52
|
};
|
|
57
53
|
|
|
58
|
-
const
|
|
54
|
+
const baseWrapperStyles: React.CSSProperties = {
|
|
55
|
+
position: 'relative',
|
|
56
|
+
display: 'flex',
|
|
57
|
+
flexDirection: 'column',
|
|
58
|
+
fontFamily: searchTokens.typography.sans, // ⚡ Applied global Tailwind fonts variables
|
|
59
|
+
fontSize: '12px',
|
|
60
|
+
userSelect: 'none',
|
|
61
|
+
boxSizing: 'border-box'
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
const inputContainerBaseStyles: React.CSSProperties = {
|
|
65
|
+
position: 'relative',
|
|
66
|
+
display: 'flex',
|
|
67
|
+
alignItems: 'center',
|
|
68
|
+
backgroundColor: searchTokens.colors.bgInput,
|
|
69
|
+
border: `1px solid ${isInputFocused || (variant === 'float' && isExpanded)
|
|
70
|
+
? searchTokens.colors.borderAccent
|
|
71
|
+
: isInputHovered
|
|
72
|
+
? searchTokens.colors.borderAccentHover
|
|
73
|
+
: searchTokens.colors.border
|
|
74
|
+
}`,
|
|
75
|
+
borderRadius: '6px',
|
|
76
|
+
height: '32px',
|
|
77
|
+
transition: searchTokens.transitions.smooth,
|
|
78
|
+
boxSizing: 'border-box'
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
const rawInputStyles: React.CSSProperties = {
|
|
82
|
+
width: '100%',
|
|
83
|
+
height: '100%',
|
|
84
|
+
backgroundColor: 'transparent',
|
|
85
|
+
color: searchTokens.colors.text,
|
|
86
|
+
border: 'none',
|
|
87
|
+
outline: 'none',
|
|
88
|
+
padding: '0 32px',
|
|
89
|
+
fontSize: '12px',
|
|
90
|
+
fontFamily: searchTokens.typography.sans,
|
|
91
|
+
boxSizing: 'border-box'
|
|
92
|
+
};
|
|
59
93
|
|
|
60
|
-
// --- 1. SIMPLE VARIANT
|
|
94
|
+
// --- 1. SIMPLE VARIANT ---
|
|
61
95
|
if (variant === 'simple') {
|
|
62
|
-
const hasResults = value.length > 0;
|
|
96
|
+
const hasResults = resultsCount > 0 && value.length > 0;
|
|
97
|
+
|
|
98
|
+
// ⚡ Fallback logic: check if the dev supplied a custom peek content block component
|
|
99
|
+
const renderedPeek = peekContent || (
|
|
100
|
+
<p style={{ margin: 0, fontSize: '10px', fontFamily: searchTokens.typography.mono, color: searchTokens.colors.muted, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>
|
|
101
|
+
Showing <span style={{ color: searchTokens.colors.borderAccent, fontWeight: 'bold' }}>{resultsCount}</span> matching database metrics records
|
|
102
|
+
</p>
|
|
103
|
+
);
|
|
63
104
|
|
|
64
105
|
return (
|
|
65
|
-
<div
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
106
|
+
<div style={baseWrapperStyles} className={className}>
|
|
107
|
+
<div
|
|
108
|
+
style={inputContainerBaseStyles}
|
|
109
|
+
onMouseEnter={() => setIsInputHovered(true)}
|
|
110
|
+
onMouseLeave={() => setIsInputHovered(false)}
|
|
111
|
+
>
|
|
112
|
+
<div style={{ position: 'absolute', left: '10px', display: 'flex', alignItems: 'center', color: isInputHovered ? searchTokens.colors.text : searchTokens.colors.muted }}>
|
|
113
|
+
<Search size={14} />
|
|
114
|
+
</div>
|
|
69
115
|
<input
|
|
70
116
|
ref={inputRef}
|
|
71
117
|
type="text"
|
|
72
118
|
value={value}
|
|
73
119
|
onChange={(e) => onChange(e.target.value)}
|
|
120
|
+
onFocus={() => setIsInputFocused(true)}
|
|
121
|
+
onBlur={() => setIsInputFocused(false)}
|
|
74
122
|
placeholder={placeholder}
|
|
75
|
-
|
|
123
|
+
style={rawInputStyles}
|
|
76
124
|
/>
|
|
77
125
|
{value && (
|
|
78
|
-
<div
|
|
79
|
-
<Button
|
|
80
|
-
icon={Close}
|
|
81
|
-
color="ghost"
|
|
82
|
-
iconOnly={true}
|
|
83
|
-
onClick={handleClearTrigger}
|
|
84
|
-
size="xs"
|
|
85
|
-
/>
|
|
126
|
+
<div style={{ position: 'absolute', right: '4px', top: '50%', transform: 'translateY(-50%)', display: 'flex', alignItems: 'center' }}>
|
|
127
|
+
<Button icon={Close} color="ghost" iconOnly={true} onClick={handleClearTrigger} size="xs" />
|
|
86
128
|
</div>
|
|
87
129
|
)}
|
|
88
130
|
</div>
|
|
89
131
|
|
|
90
|
-
{/*
|
|
91
|
-
🎛️ HIGH-FIDELITY FLOATING SLIDE-DOWN INDICATOR PANEL
|
|
92
|
-
- Uses 'absolute' so it zero-impacts the parent height layout block.
|
|
93
|
-
- Utilizes hardware-accelerated transforms (translateY) for a smooth glide effect.
|
|
94
|
-
*/}
|
|
95
132
|
<div
|
|
96
|
-
className={`absolute left-0 right-0 top-8 z-50 overflow-hidden transition-all duration-200 cubic-bezier(0.34, 1.56, 0.64, 1) ${!hasResults ? 'pointer-events-none' : ''}`}
|
|
97
133
|
style={{
|
|
98
|
-
|
|
134
|
+
position: 'absolute',
|
|
135
|
+
left: 0,
|
|
136
|
+
right: 0,
|
|
137
|
+
top: '32px',
|
|
138
|
+
zIndex: 10,
|
|
139
|
+
overflow: 'hidden',
|
|
140
|
+
transition: searchTokens.transitions.smooth,
|
|
141
|
+
height: hasResults ? '24px' : '0px',
|
|
99
142
|
opacity: hasResults ? 1 : 0,
|
|
100
|
-
transform: hasResults ? 'translateY(0px)' : 'translateY(-4px)'
|
|
143
|
+
transform: hasResults ? 'translateY(0px)' : 'translateY(-4px)',
|
|
144
|
+
pointerEvents: 'none'
|
|
101
145
|
}}
|
|
102
146
|
>
|
|
103
|
-
<div
|
|
104
|
-
{
|
|
105
|
-
resultsCount === 0 ? (
|
|
106
|
-
<div className="pl-1 text-start text-[11px] text-vsc-muted italic">
|
|
107
|
-
No record match your search query constraints.
|
|
108
|
-
</div>
|
|
109
|
-
) : (
|
|
110
|
-
|
|
111
|
-
resultIndicatorPanel ? resultIndicatorPanel : (
|
|
112
|
-
<p className="text-[10px] font-mono text-vsc-muted pl-1 truncate">
|
|
113
|
-
Showing <span className="text-vsc-accent font-bold">{resultsCount}</span> matching database metrics records
|
|
114
|
-
</p>
|
|
115
|
-
)
|
|
116
|
-
|
|
117
|
-
)
|
|
118
|
-
}
|
|
147
|
+
<div style={{ backgroundColor: searchTokens.colors.sidebarBg, border: `1px solid ${searchTokens.colors.border}`, borderTop: 'none', padding: '4px 6px', borderRadius: '0 0 6px 6px', boxShadow: '0 4px 6px -1px rgba(0,0,0,0.1)' }}>
|
|
148
|
+
{renderedPeek}
|
|
119
149
|
</div>
|
|
120
150
|
</div>
|
|
121
151
|
</div>
|
|
@@ -125,32 +155,42 @@ export default function SearchInput({
|
|
|
125
155
|
// --- 2. FLOAT EXPANDABLE VARIANT ---
|
|
126
156
|
if (variant === 'float') {
|
|
127
157
|
const showPeekIndicator = showFloatPeek && resultsCount > 0 && value.length > 0;
|
|
158
|
+
const isOpened = isExpanded || value.length > 0;
|
|
159
|
+
|
|
160
|
+
const renderedFloatPeek = peekContent || (
|
|
161
|
+
<p style={{ margin: 0, fontSize: '9px', fontFamily: searchTokens.typography.mono, color: searchTokens.colors.borderAccent, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>
|
|
162
|
+
Quick Peek: Found {resultsCount} rows
|
|
163
|
+
</p>
|
|
164
|
+
);
|
|
165
|
+
|
|
128
166
|
return (
|
|
129
|
-
<div ref={containerRef}
|
|
167
|
+
<div ref={containerRef} style={baseWrapperStyles} className={className}>
|
|
130
168
|
<div
|
|
131
|
-
|
|
132
|
-
|
|
169
|
+
onMouseEnter={() => setIsInputHovered(true)}
|
|
170
|
+
onMouseLeave={() => setIsInputHovered(false)}
|
|
171
|
+
style={{
|
|
172
|
+
...inputContainerBaseStyles,
|
|
173
|
+
width: isOpened ? '256px' : '32px',
|
|
174
|
+
justifyContent: isOpened ? 'flex-start' : 'center',
|
|
175
|
+
backgroundColor: isOpened ? searchTokens.colors.bgInput : 'transparent',
|
|
176
|
+
borderColor: isOpened ? searchTokens.colors.borderAccent : 'transparent',
|
|
177
|
+
padding: isOpened ? '0 8px' : '0'
|
|
178
|
+
}}
|
|
133
179
|
>
|
|
134
|
-
{
|
|
135
|
-
<div
|
|
136
|
-
<Search size={14}
|
|
180
|
+
{isOpened ? (
|
|
181
|
+
<div style={{ position: 'relative', display: 'flex', alignItems: 'center', width: '100%', height: '100%' }}>
|
|
182
|
+
<Search size={14} style={{ color: searchTokens.colors.text, flexShrink: 0 }} />
|
|
137
183
|
<input
|
|
138
184
|
ref={inputRef}
|
|
139
185
|
type="text"
|
|
140
186
|
value={value}
|
|
141
187
|
onChange={(e) => onChange(e.target.value)}
|
|
142
188
|
placeholder={placeholder}
|
|
143
|
-
|
|
189
|
+
style={{ ...rawInputStyles, padding: '0 24px 0 8px' }}
|
|
144
190
|
/>
|
|
145
191
|
{value && (
|
|
146
|
-
<div
|
|
147
|
-
<Button
|
|
148
|
-
iconOnly={true}
|
|
149
|
-
color="ghost"
|
|
150
|
-
icon={Close}
|
|
151
|
-
onClick={handleClearTrigger}
|
|
152
|
-
size="xs"
|
|
153
|
-
/>
|
|
192
|
+
<div style={{ position: 'absolute', right: 0, top: '50%', transform: 'translateY(-50%)', display: 'flex', alignItems: 'center' }}>
|
|
193
|
+
<Button iconOnly={true} color="ghost" icon={Close} onClick={handleClearTrigger} size="xs" />
|
|
154
194
|
</div>
|
|
155
195
|
)}
|
|
156
196
|
</div>
|
|
@@ -161,33 +201,45 @@ export default function SearchInput({
|
|
|
161
201
|
icon={Search}
|
|
162
202
|
onClick={handleFloatActivation}
|
|
163
203
|
color="ghost"
|
|
164
|
-
|
|
204
|
+
style={{ color: searchTokens.colors.muted }}
|
|
165
205
|
title="Open Expandable Search"
|
|
166
206
|
/>
|
|
167
207
|
)}
|
|
168
208
|
</div>
|
|
169
209
|
|
|
170
|
-
{/* Optional dynamic slider line badge dropdown block */}
|
|
171
210
|
<div
|
|
172
|
-
className="overflow-hidden transition-all duration-200 ease-out w-64 absolute top-8"
|
|
173
211
|
style={{
|
|
174
|
-
|
|
175
|
-
|
|
212
|
+
position: 'absolute',
|
|
213
|
+
top: '32px',
|
|
214
|
+
width: '256px',
|
|
215
|
+
zIndex: 10,
|
|
216
|
+
overflow: 'hidden',
|
|
217
|
+
transition: searchTokens.transitions.smooth,
|
|
218
|
+
height: showPeekIndicator ? '24px' : '0px',
|
|
219
|
+
opacity: showPeekIndicator ? 1 : 0,
|
|
220
|
+
transform: showPeekIndicator ? 'translateY(0px)' : 'translateY(-4px)',
|
|
221
|
+
pointerEvents: 'none'
|
|
176
222
|
}}
|
|
177
223
|
>
|
|
178
|
-
<
|
|
179
|
-
|
|
180
|
-
</
|
|
224
|
+
<div style={{ backgroundColor: searchTokens.colors.sidebarBg, border: `1px solid ${searchTokens.colors.border}`, borderTop: 'none', padding: '4px', borderRadius: '0 0 2px 2px', boxShadow: '0 4px 6px -1px rgba(0,0,0,0.1)' }}>
|
|
225
|
+
{renderedFloatPeek}
|
|
226
|
+
</div>
|
|
181
227
|
</div>
|
|
182
228
|
</div>
|
|
183
229
|
);
|
|
184
230
|
}
|
|
185
231
|
|
|
186
|
-
// --- 3. MENU
|
|
232
|
+
// --- 3. MENU DROPDOWN VARIANT ---
|
|
187
233
|
return (
|
|
188
|
-
<div ref={containerRef}
|
|
189
|
-
<div
|
|
190
|
-
|
|
234
|
+
<div ref={containerRef} style={baseWrapperStyles} className={className}>
|
|
235
|
+
<div
|
|
236
|
+
style={inputContainerBaseStyles}
|
|
237
|
+
onMouseEnter={() => setIsInputHovered(true)}
|
|
238
|
+
onMouseLeave={() => setIsInputHovered(false)}
|
|
239
|
+
>
|
|
240
|
+
<div style={{ position: 'absolute', left: '10px', display: 'flex', alignItems: 'center', color: searchTokens.colors.muted }}>
|
|
241
|
+
<Search size={14} />
|
|
242
|
+
</div>
|
|
191
243
|
<input
|
|
192
244
|
ref={inputRef}
|
|
193
245
|
type="text"
|
|
@@ -198,65 +250,23 @@ export default function SearchInput({
|
|
|
198
250
|
}}
|
|
199
251
|
onFocus={() => setIsMenuOpen(true)}
|
|
200
252
|
placeholder={placeholder}
|
|
201
|
-
|
|
253
|
+
style={rawInputStyles}
|
|
202
254
|
/>
|
|
203
255
|
{value && (
|
|
204
|
-
<div
|
|
205
|
-
<Button
|
|
206
|
-
iconOnly={true}
|
|
207
|
-
icon={Close}
|
|
208
|
-
color="ghost"
|
|
209
|
-
onClick={handleClearTrigger}
|
|
210
|
-
size="xs"
|
|
211
|
-
/>
|
|
256
|
+
<div style={{ position: 'absolute', right: '4px', top: '50%', transform: 'translateY(-50%)', display: 'flex', alignItems: 'center' }}>
|
|
257
|
+
<Button iconOnly={true} icon={Close} color="ghost" onClick={handleClearTrigger} size="xs" />
|
|
212
258
|
</div>
|
|
213
259
|
)}
|
|
214
260
|
</div>
|
|
215
261
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
menuResults.map((item) => (
|
|
225
|
-
<div
|
|
226
|
-
key={item.id}
|
|
227
|
-
onClick={() => {
|
|
228
|
-
if (onResultClick) onResultClick(item);
|
|
229
|
-
setIsMenuOpen(false);
|
|
230
|
-
}}
|
|
231
|
-
className="w-full p-2 hover:bg-vsc-hover text-left rounded-sm cursor-pointer flex flex-col space-y-0.5 transition-colors"
|
|
232
|
-
>
|
|
233
|
-
<div className="font-semibold text-vsc-text flex justify-between items-center">
|
|
234
|
-
<span className="truncate">{item.title}</span>
|
|
235
|
-
{item.category && (
|
|
236
|
-
<span className="text-[9px] font-mono font-bold bg-vsc-accent/10 border border-vsc-accent/20 text-vsc-accent px-1 rounded-sm uppercase tracking-wide">
|
|
237
|
-
{item.category}
|
|
238
|
-
</span>
|
|
239
|
-
)}
|
|
240
|
-
</div>
|
|
241
|
-
{item.subtitle && <div className="text-[10px] text-vsc-muted truncate">{item.subtitle}</div>}
|
|
242
|
-
</div>
|
|
243
|
-
))
|
|
244
|
-
)}
|
|
245
|
-
</div>
|
|
246
|
-
|
|
247
|
-
{menuResults.length > 0 && onViewMoreClick && (
|
|
248
|
-
<button
|
|
249
|
-
onClick={() => {
|
|
250
|
-
onViewMoreClick();
|
|
251
|
-
setIsMenuOpen(false);
|
|
252
|
-
}}
|
|
253
|
-
className="w-full border-t border-vsc-border bg-vsc-bg hover:bg-vsc-hover/60 p-2 text-center text-[10px] font-bold text-vsc-accent tracking-wide uppercase transition-colors rounded-b-sm border-none cursor-pointer"
|
|
254
|
-
>
|
|
255
|
-
View All Matching Search Metrics Records →
|
|
256
|
-
</button>
|
|
257
|
-
)}
|
|
258
|
-
</div>
|
|
259
|
-
)}
|
|
262
|
+
<SearchMenu
|
|
263
|
+
isOpen={isMenuOpen}
|
|
264
|
+
value={value}
|
|
265
|
+
menuResults={menuResults}
|
|
266
|
+
onResultClick={onResultClick}
|
|
267
|
+
onViewMoreClick={onViewMoreClick}
|
|
268
|
+
onCloseMenu={() => setIsMenuOpen(false)}
|
|
269
|
+
/>
|
|
260
270
|
</div>
|
|
261
271
|
);
|
|
262
|
-
}
|
|
272
|
+
}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { useState } from 'react';
|
|
2
|
+
import { SearchResultItem, searchTokens } from './types';
|
|
3
|
+
|
|
4
|
+
interface SearchMenuProps {
|
|
5
|
+
isOpen: boolean;
|
|
6
|
+
value: string;
|
|
7
|
+
menuResults: SearchResultItem[];
|
|
8
|
+
onResultClick?: (item: SearchResultItem) => void;
|
|
9
|
+
onViewMoreClick?: () => void;
|
|
10
|
+
onCloseMenu: () => void;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export default function SearchMenu({
|
|
14
|
+
isOpen,
|
|
15
|
+
value,
|
|
16
|
+
menuResults,
|
|
17
|
+
onResultClick,
|
|
18
|
+
onViewMoreClick,
|
|
19
|
+
onCloseMenu
|
|
20
|
+
}: SearchMenuProps) {
|
|
21
|
+
const [hoveredResultId, setHoveredResultId] = useState<string | null>(null);
|
|
22
|
+
const [isViewMoreHovered, setIsViewMoreHovered] = useState<boolean>(false);
|
|
23
|
+
|
|
24
|
+
if (!isOpen || !value) return null;
|
|
25
|
+
|
|
26
|
+
return (
|
|
27
|
+
<div
|
|
28
|
+
style={{
|
|
29
|
+
position: 'absolute',
|
|
30
|
+
top: '36px',
|
|
31
|
+
left: 0,
|
|
32
|
+
width: '100%',
|
|
33
|
+
backgroundColor: searchTokens.colors.sidebarBg,
|
|
34
|
+
border: `1px solid ${searchTokens.colors.border}`,
|
|
35
|
+
borderRadius: '4px',
|
|
36
|
+
boxShadow: '0 10px 15px -3px rgba(0, 0, 0, 0.2)',
|
|
37
|
+
zIndex: 50,
|
|
38
|
+
padding: '4px',
|
|
39
|
+
display: 'flex',
|
|
40
|
+
flexDirection: 'column',
|
|
41
|
+
maxHeight: '256px'
|
|
42
|
+
}}
|
|
43
|
+
>
|
|
44
|
+
<div style={{ overflowY: 'auto', flex: 1 }}>
|
|
45
|
+
{menuResults.length === 0 ? (
|
|
46
|
+
<div style={{ padding: '16px', textAlign: 'center', fontSize: '11px', color: searchTokens.colors.muted, fontStyle: 'italic' }}>
|
|
47
|
+
No indexed record entities match your text query constraints.
|
|
48
|
+
</div>
|
|
49
|
+
) : (
|
|
50
|
+
menuResults.map((item) => {
|
|
51
|
+
const isItemHovered = hoveredResultId === item.id;
|
|
52
|
+
return (
|
|
53
|
+
<div
|
|
54
|
+
key={item.id}
|
|
55
|
+
onMouseEnter={() => setHoveredResultId(item.id)}
|
|
56
|
+
onMouseLeave={() => setHoveredResultId(null)}
|
|
57
|
+
onClick={() => {
|
|
58
|
+
if (onResultClick) onResultClick(item);
|
|
59
|
+
onCloseMenu();
|
|
60
|
+
}}
|
|
61
|
+
style={{
|
|
62
|
+
width: '100%',
|
|
63
|
+
padding: '8px',
|
|
64
|
+
backgroundColor: isItemHovered ? searchTokens.colors.hoverBg : 'transparent',
|
|
65
|
+
borderRadius: '2px',
|
|
66
|
+
cursor: 'pointer',
|
|
67
|
+
display: 'flex',
|
|
68
|
+
flexDirection: 'column',
|
|
69
|
+
gap: '2px',
|
|
70
|
+
transition: 'background-color 100ms',
|
|
71
|
+
boxSizing: 'border-box'
|
|
72
|
+
}}
|
|
73
|
+
>
|
|
74
|
+
<div style={{ fontWeight: 600, color: searchTokens.colors.text, display: 'flex', justifyContent: 'space-between', alignItems: 'center', width: '100%' }}>
|
|
75
|
+
<span style={{ whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis', flex: 1 }}>{item.title}</span>
|
|
76
|
+
{item.category && (
|
|
77
|
+
<span style={{ fontSize: '9px', fontFamily: 'monospace', fontWeight: 'bold', backgroundColor: searchTokens.colors.accentBgLight, border: `1px solid rgba(0, 122, 204, 0.2)`, color: searchTokens.colors.borderAccent, padding: '2px 4px', borderRadius: '2px', textTransform: 'uppercase', marginLeft: '8px', flexShrink: 0 }}>
|
|
78
|
+
{item.category}
|
|
79
|
+
</span>
|
|
80
|
+
)}
|
|
81
|
+
</div>
|
|
82
|
+
{item.subtitle && <div style={{ fontSize: '10px', color: searchTokens.colors.muted, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{item.subtitle}</div>}
|
|
83
|
+
</div>
|
|
84
|
+
);
|
|
85
|
+
})
|
|
86
|
+
)}
|
|
87
|
+
</div>
|
|
88
|
+
|
|
89
|
+
{menuResults.length > 0 && onViewMoreClick && (
|
|
90
|
+
<button
|
|
91
|
+
onMouseEnter={() => setIsViewMoreHovered(true)}
|
|
92
|
+
onMouseLeave={() => setIsViewMoreHovered(false)}
|
|
93
|
+
onClick={() => {
|
|
94
|
+
onViewMoreClick();
|
|
95
|
+
onCloseMenu();
|
|
96
|
+
}}
|
|
97
|
+
style={{
|
|
98
|
+
width: '100%',
|
|
99
|
+
border: 'none',
|
|
100
|
+
borderTop: `1px solid ${searchTokens.colors.border}`,
|
|
101
|
+
backgroundColor: isViewMoreHovered ? searchTokens.colors.hoverBg : 'transparent',
|
|
102
|
+
padding: '8px',
|
|
103
|
+
textAlign: 'center',
|
|
104
|
+
fontSize: '10px',
|
|
105
|
+
fontWeight: 'bold',
|
|
106
|
+
color: searchTokens.colors.borderAccent,
|
|
107
|
+
letterSpacing: '0.5px',
|
|
108
|
+
textTransform: 'uppercase',
|
|
109
|
+
transition: 'background-color 150ms',
|
|
110
|
+
borderRadius: '0 0 2px 2px',
|
|
111
|
+
cursor: 'pointer'
|
|
112
|
+
}}
|
|
113
|
+
>
|
|
114
|
+
View All Matching Search Metrics Records →
|
|
115
|
+
</button>
|
|
116
|
+
)}
|
|
117
|
+
</div>
|
|
118
|
+
);
|
|
119
|
+
}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
1
3
|
export type SearchVariant = 'simple' | 'float' | 'menu';
|
|
2
4
|
|
|
3
5
|
export interface SearchResultItem {
|
|
@@ -13,9 +15,34 @@ export interface SearchInputProps {
|
|
|
13
15
|
onChange: (value: string) => void;
|
|
14
16
|
onClear?: () => void;
|
|
15
17
|
placeholder?: string;
|
|
16
|
-
resultsCount?: number;
|
|
17
|
-
menuResults?: SearchResultItem[];
|
|
18
|
+
resultsCount?: number;
|
|
19
|
+
menuResults?: SearchResultItem[];
|
|
18
20
|
onResultClick?: (item: SearchResultItem) => void;
|
|
19
21
|
onViewMoreClick?: () => void;
|
|
20
22
|
className?: string;
|
|
23
|
+
showFloatPeek?: boolean;
|
|
24
|
+
// ⚡ Accepts either a plain text string label or a fully rendered sub-component node
|
|
25
|
+
peekContent?: React.ReactNode;
|
|
21
26
|
}
|
|
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
|
+
};
|
package/src/index.ts
CHANGED
package/vite.config.mts
CHANGED
|
@@ -9,13 +9,11 @@ import { storybookTest } from '@storybook/addon-vitest/vitest-plugin';
|
|
|
9
9
|
import { playwright } from '@vitest/browser-playwright';
|
|
10
10
|
const dirname = typeof __dirname !== 'undefined' ? __dirname : path.dirname(fileURLToPath(import.meta.url));
|
|
11
11
|
import tailwindcss from '@tailwindcss/vite';
|
|
12
|
-
import cssInjectedByJsPlugin from 'vite-plugin-css-injected-by-js';
|
|
13
12
|
|
|
14
13
|
// More info at: https://storybook.js.org/docs/next/writing-tests/integrations/vitest-addon
|
|
15
14
|
export default defineConfig({
|
|
16
15
|
plugins: [
|
|
17
16
|
tailwindcss(),
|
|
18
|
-
cssInjectedByJsPlugin(),
|
|
19
17
|
react(),
|
|
20
18
|
// Auto-generates independent TypeScript type declaration files (.d.ts) matching paths
|
|
21
19
|
dts({
|
|
@@ -33,8 +31,6 @@ export default defineConfig({
|
|
|
33
31
|
'components/icons/index': resolve(__dirname, 'src/components/icons/index.ts'),
|
|
34
32
|
|
|
35
33
|
},
|
|
36
|
-
name: "voxelUi",
|
|
37
|
-
fileName: (format) => `index.${format}.js`,
|
|
38
34
|
formats: ['es'] // Output strictly as modern ES Modules for dead-code elimination (tree-shaking)
|
|
39
35
|
},
|
|
40
36
|
rollupOptions: {
|
|
@@ -1,205 +0,0 @@
|
|
|
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/SearchInput.tsx
|
|
6
|
-
var s = e();
|
|
7
|
-
function c({ variant: e = "simple", value: c, onChange: l, onClear: u, placeholder: d = "Search manifests or tracking codes...", resultsCount: f = 0, menuResults: p = [], onResultClick: m, onViewMoreClick: h, className: g = "", showFloatPeek: _ = !1, resultIndicatorPanel: v }) {
|
|
8
|
-
let [y, b] = o(!1), [x, S] = o(!1), C = a(null), w = a(null);
|
|
9
|
-
i(() => {
|
|
10
|
-
let t = (t) => {
|
|
11
|
-
C.current && !C.current.contains(t.target) && (S(!1), e === "float" && c === "" && b(!1));
|
|
12
|
-
};
|
|
13
|
-
return window.addEventListener("mousedown", t), () => window.removeEventListener("mousedown", t);
|
|
14
|
-
}, [e, c]);
|
|
15
|
-
let T = (e) => {
|
|
16
|
-
e.stopPropagation(), l(""), u && u(), w.current && w.current.focus();
|
|
17
|
-
}, E = () => {
|
|
18
|
-
b(!0), setTimeout(() => w.current?.focus(), 50);
|
|
19
|
-
}, D = "relative flex flex-col font-sans text-xs select-none";
|
|
20
|
-
if (e === "simple") {
|
|
21
|
-
let e = c.length > 0;
|
|
22
|
-
return /* @__PURE__ */ (0, s.jsxs)("div", {
|
|
23
|
-
className: `${D} ${g}`.trim(),
|
|
24
|
-
children: [/* @__PURE__ */ (0, s.jsxs)("div", {
|
|
25
|
-
className: "relative flex items-center bg-vsc-bg-input border border-vsc-border rounded-sm h-8 group hover:border-vsc-accent transition-colors z-20",
|
|
26
|
-
children: [
|
|
27
|
-
/* @__PURE__ */ (0, s.jsx)(r, {
|
|
28
|
-
size: 14,
|
|
29
|
-
className: "absolute left-2.5 text-vsc-muted group-hover:text-vsc-text"
|
|
30
|
-
}),
|
|
31
|
-
/* @__PURE__ */ (0, s.jsx)("input", {
|
|
32
|
-
ref: w,
|
|
33
|
-
type: "text",
|
|
34
|
-
value: c,
|
|
35
|
-
onChange: (e) => l(e.target.value),
|
|
36
|
-
placeholder: d,
|
|
37
|
-
className: "w-full h-full pl-8 pr-10 bg-transparent text-vsc-text border-none outline-none focus:outline-none placeholder-vsc-muted"
|
|
38
|
-
}),
|
|
39
|
-
c && /* @__PURE__ */ (0, s.jsx)("div", {
|
|
40
|
-
className: "absolute right-1 top-1/2 -translate-y-1/2 flex items-center",
|
|
41
|
-
children: /* @__PURE__ */ (0, s.jsx)(t, {
|
|
42
|
-
icon: n,
|
|
43
|
-
color: "ghost",
|
|
44
|
-
iconOnly: !0,
|
|
45
|
-
onClick: T,
|
|
46
|
-
size: "xs"
|
|
47
|
-
})
|
|
48
|
-
})
|
|
49
|
-
]
|
|
50
|
-
}), /* @__PURE__ */ (0, s.jsx)("div", {
|
|
51
|
-
className: `absolute left-0 right-0 top-8 z-50 overflow-hidden transition-all duration-200 cubic-bezier(0.34, 1.56, 0.64, 1) ${e ? "" : "pointer-events-none"}`,
|
|
52
|
-
style: {
|
|
53
|
-
height: e ? "auto" : "0px",
|
|
54
|
-
opacity: +!!e,
|
|
55
|
-
transform: e ? "translateY(0px)" : "translateY(-4px)"
|
|
56
|
-
},
|
|
57
|
-
children: /* @__PURE__ */ (0, s.jsx)("div", {
|
|
58
|
-
className: "bg-vsc-sidebar shadow-sm p-1.5 pt-1 ",
|
|
59
|
-
children: f === 0 ? /* @__PURE__ */ (0, s.jsx)("div", {
|
|
60
|
-
className: "pl-1 text-start text-[11px] text-vsc-muted italic",
|
|
61
|
-
children: "No record match your search query constraints."
|
|
62
|
-
}) : v || /* @__PURE__ */ (0, s.jsxs)("p", {
|
|
63
|
-
className: "text-[10px] font-mono text-vsc-muted pl-1 truncate",
|
|
64
|
-
children: [
|
|
65
|
-
"Showing ",
|
|
66
|
-
/* @__PURE__ */ (0, s.jsx)("span", {
|
|
67
|
-
className: "text-vsc-accent font-bold",
|
|
68
|
-
children: f
|
|
69
|
-
}),
|
|
70
|
-
" matching database metrics records"
|
|
71
|
-
]
|
|
72
|
-
})
|
|
73
|
-
})
|
|
74
|
-
})]
|
|
75
|
-
});
|
|
76
|
-
}
|
|
77
|
-
if (e === "float") {
|
|
78
|
-
let e = _ && f > 0 && c.length > 0;
|
|
79
|
-
return /* @__PURE__ */ (0, s.jsxs)("div", {
|
|
80
|
-
ref: C,
|
|
81
|
-
className: `${D} ${g}`.trim(),
|
|
82
|
-
children: [/* @__PURE__ */ (0, s.jsx)("div", {
|
|
83
|
-
className: `flex items-center bg-vsc-bg-input border rounded-sm h-8 transition-all duration-300 ease-in-out overflow-hidden ${y || c ? "w-64 border-vsc-accent px-2" : "w-8 border-transparent bg-transparent justify-center"}`,
|
|
84
|
-
children: y || c ? /* @__PURE__ */ (0, s.jsxs)("div", {
|
|
85
|
-
className: "relative flex items-center w-full h-full",
|
|
86
|
-
children: [
|
|
87
|
-
/* @__PURE__ */ (0, s.jsx)(r, {
|
|
88
|
-
size: 14,
|
|
89
|
-
className: "text-vsc-text shrink-0"
|
|
90
|
-
}),
|
|
91
|
-
/* @__PURE__ */ (0, s.jsx)("input", {
|
|
92
|
-
ref: w,
|
|
93
|
-
type: "text",
|
|
94
|
-
value: c,
|
|
95
|
-
onChange: (e) => l(e.target.value),
|
|
96
|
-
placeholder: d,
|
|
97
|
-
className: "w-full h-full pl-2 pr-6 bg-transparent text-vsc-text border-none outline-none focus:outline-none placeholder-vsc-muted"
|
|
98
|
-
}),
|
|
99
|
-
c && /* @__PURE__ */ (0, s.jsx)("div", {
|
|
100
|
-
className: "absolute right-0 top-1/2 -translate-y-1/2 flex items-center",
|
|
101
|
-
children: /* @__PURE__ */ (0, s.jsx)(t, {
|
|
102
|
-
iconOnly: !0,
|
|
103
|
-
color: "ghost",
|
|
104
|
-
icon: n,
|
|
105
|
-
onClick: T,
|
|
106
|
-
size: "xs"
|
|
107
|
-
})
|
|
108
|
-
})
|
|
109
|
-
]
|
|
110
|
-
}) : /* @__PURE__ */ (0, s.jsx)(t, {
|
|
111
|
-
iconOnly: !0,
|
|
112
|
-
size: "sm",
|
|
113
|
-
icon: r,
|
|
114
|
-
onClick: E,
|
|
115
|
-
color: "ghost",
|
|
116
|
-
className: "text-vsc-muted hover:text-vsc-text transition-colors",
|
|
117
|
-
title: "Open Expandable Search"
|
|
118
|
-
})
|
|
119
|
-
}), /* @__PURE__ */ (0, s.jsx)("div", {
|
|
120
|
-
className: "overflow-hidden transition-all duration-200 ease-out w-64 absolute top-8",
|
|
121
|
-
style: {
|
|
122
|
-
height: e ? "20px" : "0px",
|
|
123
|
-
opacity: +!!e
|
|
124
|
-
},
|
|
125
|
-
children: /* @__PURE__ */ (0, s.jsxs)("p", {
|
|
126
|
-
className: "text-[9px] font-mono text-vsc-accent pt-1 pl-1 truncate bg-vsc-sidebar border border-t-0 border-vsc-border p-1 rounded-b shadow-sm",
|
|
127
|
-
children: [
|
|
128
|
-
"Quick Peek: Found ",
|
|
129
|
-
f,
|
|
130
|
-
" rows"
|
|
131
|
-
]
|
|
132
|
-
})
|
|
133
|
-
})]
|
|
134
|
-
});
|
|
135
|
-
}
|
|
136
|
-
return /* @__PURE__ */ (0, s.jsxs)("div", {
|
|
137
|
-
ref: C,
|
|
138
|
-
className: `${D} ${g}`.trim(),
|
|
139
|
-
children: [/* @__PURE__ */ (0, s.jsxs)("div", {
|
|
140
|
-
className: "relative flex items-center bg-vsc-bg-input border border-vsc-border rounded-sm h-8 focus-within:border-vsc-accent",
|
|
141
|
-
children: [
|
|
142
|
-
/* @__PURE__ */ (0, s.jsx)(r, {
|
|
143
|
-
size: 14,
|
|
144
|
-
className: "absolute left-2.5 text-vsc-muted"
|
|
145
|
-
}),
|
|
146
|
-
/* @__PURE__ */ (0, s.jsx)("input", {
|
|
147
|
-
ref: w,
|
|
148
|
-
type: "text",
|
|
149
|
-
value: c,
|
|
150
|
-
onChange: (e) => {
|
|
151
|
-
l(e.target.value), S(!0);
|
|
152
|
-
},
|
|
153
|
-
onFocus: () => S(!0),
|
|
154
|
-
placeholder: d,
|
|
155
|
-
className: "w-full h-full pl-8 pr-10 bg-transparent text-vsc-text border-none outline-none focus:outline-none placeholder-vsc-muted"
|
|
156
|
-
}),
|
|
157
|
-
c && /* @__PURE__ */ (0, s.jsx)("div", {
|
|
158
|
-
className: "absolute right-1 top-1/2 -translate-y-1/2 flex items-center",
|
|
159
|
-
children: /* @__PURE__ */ (0, s.jsx)(t, {
|
|
160
|
-
iconOnly: !0,
|
|
161
|
-
icon: n,
|
|
162
|
-
color: "ghost",
|
|
163
|
-
onClick: T,
|
|
164
|
-
size: "xs"
|
|
165
|
-
})
|
|
166
|
-
})
|
|
167
|
-
]
|
|
168
|
-
}), x && c && /* @__PURE__ */ (0, s.jsxs)("div", {
|
|
169
|
-
className: "absolute top-9 left-0 w-full bg-vsc-sidebar border border-vsc-border rounded shadow-xl z-50 p-1 flex flex-col max-h-64 animate-in fade-in slide-in-from-top-1 duration-150",
|
|
170
|
-
children: [/* @__PURE__ */ (0, s.jsx)("div", {
|
|
171
|
-
className: "overflow-y-auto flex-1",
|
|
172
|
-
children: p.length === 0 ? /* @__PURE__ */ (0, s.jsx)("div", {
|
|
173
|
-
className: "p-4 text-center text-[11px] text-vsc-muted italic",
|
|
174
|
-
children: "No indexed record entities match your text query constraints."
|
|
175
|
-
}) : p.map((e) => /* @__PURE__ */ (0, s.jsxs)("div", {
|
|
176
|
-
onClick: () => {
|
|
177
|
-
m && m(e), S(!1);
|
|
178
|
-
},
|
|
179
|
-
className: "w-full p-2 hover:bg-vsc-hover text-left rounded-sm cursor-pointer flex flex-col space-y-0.5 transition-colors",
|
|
180
|
-
children: [/* @__PURE__ */ (0, s.jsxs)("div", {
|
|
181
|
-
className: "font-semibold text-vsc-text flex justify-between items-center",
|
|
182
|
-
children: [/* @__PURE__ */ (0, s.jsx)("span", {
|
|
183
|
-
className: "truncate",
|
|
184
|
-
children: e.title
|
|
185
|
-
}), e.category && /* @__PURE__ */ (0, s.jsx)("span", {
|
|
186
|
-
className: "text-[9px] font-mono font-bold bg-vsc-accent/10 border border-vsc-accent/20 text-vsc-accent px-1 rounded-sm uppercase tracking-wide",
|
|
187
|
-
children: e.category
|
|
188
|
-
})]
|
|
189
|
-
}), e.subtitle && /* @__PURE__ */ (0, s.jsx)("div", {
|
|
190
|
-
className: "text-[10px] text-vsc-muted truncate",
|
|
191
|
-
children: e.subtitle
|
|
192
|
-
})]
|
|
193
|
-
}, e.id))
|
|
194
|
-
}), p.length > 0 && h && /* @__PURE__ */ (0, s.jsx)("button", {
|
|
195
|
-
onClick: () => {
|
|
196
|
-
h(), S(!1);
|
|
197
|
-
},
|
|
198
|
-
className: "w-full border-t border-vsc-border bg-vsc-bg hover:bg-vsc-hover/60 p-2 text-center text-[10px] font-bold text-vsc-accent tracking-wide uppercase transition-colors rounded-b-sm border-none cursor-pointer",
|
|
199
|
-
children: "View All Matching Search Metrics Records →"
|
|
200
|
-
})]
|
|
201
|
-
})]
|
|
202
|
-
});
|
|
203
|
-
}
|
|
204
|
-
//#endregion
|
|
205
|
-
export { c as t };
|