@knymbus/voxel-ui 1.0.11 → 1.0.13
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-BCvuXqOX.js +452 -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 +17 -0
- package/dist/index.js +2 -3
- package/package.json +1 -1
- package/src/components/search/SearchInput.tsx +132 -133
- package/src/components/search/SearchMenu.tsx +119 -0
- package/src/components/search/types.ts +20 -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,452 @@
|
|
|
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
|
+
transitions: { smooth: "all 200ms cubic-bezier(0.34, 1.56, 0.64, 1)" }
|
|
19
|
+
}, c = e();
|
|
20
|
+
function l({ isOpen: e, value: t, menuResults: n, onResultClick: r, onViewMoreClick: i, onCloseMenu: a }) {
|
|
21
|
+
let [l, u] = o(null), [d, f] = o(!1);
|
|
22
|
+
return !e || !t ? null : /* @__PURE__ */ (0, c.jsxs)("div", {
|
|
23
|
+
style: {
|
|
24
|
+
position: "absolute",
|
|
25
|
+
top: "36px",
|
|
26
|
+
left: 0,
|
|
27
|
+
width: "100%",
|
|
28
|
+
backgroundColor: s.colors.sidebarBg,
|
|
29
|
+
border: `1px solid ${s.colors.border}`,
|
|
30
|
+
borderRadius: "4px",
|
|
31
|
+
boxShadow: "0 10px 15px -3px rgba(0, 0, 0, 0.2)",
|
|
32
|
+
zIndex: 50,
|
|
33
|
+
padding: "4px",
|
|
34
|
+
display: "flex",
|
|
35
|
+
flexDirection: "column",
|
|
36
|
+
maxHeight: "256px"
|
|
37
|
+
},
|
|
38
|
+
children: [/* @__PURE__ */ (0, c.jsx)("div", {
|
|
39
|
+
style: {
|
|
40
|
+
overflowY: "auto",
|
|
41
|
+
flex: 1
|
|
42
|
+
},
|
|
43
|
+
children: n.length === 0 ? /* @__PURE__ */ (0, c.jsx)("div", {
|
|
44
|
+
style: {
|
|
45
|
+
padding: "16px",
|
|
46
|
+
textAlign: "center",
|
|
47
|
+
fontSize: "11px",
|
|
48
|
+
color: s.colors.muted,
|
|
49
|
+
fontStyle: "italic"
|
|
50
|
+
},
|
|
51
|
+
children: "No indexed record entities match your text query constraints."
|
|
52
|
+
}) : n.map((e) => /* @__PURE__ */ (0, c.jsxs)("div", {
|
|
53
|
+
onMouseEnter: () => u(e.id),
|
|
54
|
+
onMouseLeave: () => u(null),
|
|
55
|
+
onClick: () => {
|
|
56
|
+
r && r(e), a();
|
|
57
|
+
},
|
|
58
|
+
style: {
|
|
59
|
+
width: "100%",
|
|
60
|
+
padding: "8px",
|
|
61
|
+
backgroundColor: l === e.id ? s.colors.hoverBg : "transparent",
|
|
62
|
+
borderRadius: "2px",
|
|
63
|
+
cursor: "pointer",
|
|
64
|
+
display: "flex",
|
|
65
|
+
flexDirection: "column",
|
|
66
|
+
gap: "2px",
|
|
67
|
+
transition: "background-color 100ms",
|
|
68
|
+
boxSizing: "border-box"
|
|
69
|
+
},
|
|
70
|
+
children: [/* @__PURE__ */ (0, c.jsxs)("div", {
|
|
71
|
+
style: {
|
|
72
|
+
fontWeight: 600,
|
|
73
|
+
color: s.colors.text,
|
|
74
|
+
display: "flex",
|
|
75
|
+
justifyContent: "space-between",
|
|
76
|
+
alignItems: "center",
|
|
77
|
+
width: "100%"
|
|
78
|
+
},
|
|
79
|
+
children: [/* @__PURE__ */ (0, c.jsx)("span", {
|
|
80
|
+
style: {
|
|
81
|
+
whiteSpace: "nowrap",
|
|
82
|
+
overflow: "hidden",
|
|
83
|
+
textOverflow: "ellipsis",
|
|
84
|
+
flex: 1
|
|
85
|
+
},
|
|
86
|
+
children: e.title
|
|
87
|
+
}), e.category && /* @__PURE__ */ (0, c.jsx)("span", {
|
|
88
|
+
style: {
|
|
89
|
+
fontSize: "9px",
|
|
90
|
+
fontFamily: "monospace",
|
|
91
|
+
fontWeight: "bold",
|
|
92
|
+
backgroundColor: s.colors.accentBgLight,
|
|
93
|
+
border: "1px solid rgba(0, 122, 204, 0.2)",
|
|
94
|
+
color: s.colors.borderAccent,
|
|
95
|
+
padding: "2px 4px",
|
|
96
|
+
borderRadius: "2px",
|
|
97
|
+
textTransform: "uppercase",
|
|
98
|
+
marginLeft: "8px",
|
|
99
|
+
flexShrink: 0
|
|
100
|
+
},
|
|
101
|
+
children: e.category
|
|
102
|
+
})]
|
|
103
|
+
}), e.subtitle && /* @__PURE__ */ (0, c.jsx)("div", {
|
|
104
|
+
style: {
|
|
105
|
+
fontSize: "10px",
|
|
106
|
+
color: s.colors.muted,
|
|
107
|
+
whiteSpace: "nowrap",
|
|
108
|
+
overflow: "hidden",
|
|
109
|
+
textOverflow: "ellipsis"
|
|
110
|
+
},
|
|
111
|
+
children: e.subtitle
|
|
112
|
+
})]
|
|
113
|
+
}, e.id))
|
|
114
|
+
}), n.length > 0 && i && /* @__PURE__ */ (0, c.jsx)("button", {
|
|
115
|
+
onMouseEnter: () => f(!0),
|
|
116
|
+
onMouseLeave: () => f(!1),
|
|
117
|
+
onClick: () => {
|
|
118
|
+
i(), a();
|
|
119
|
+
},
|
|
120
|
+
style: {
|
|
121
|
+
width: "100%",
|
|
122
|
+
border: "none",
|
|
123
|
+
borderTop: `1px solid ${s.colors.border}`,
|
|
124
|
+
backgroundColor: d ? s.colors.hoverBg : "transparent",
|
|
125
|
+
padding: "8px",
|
|
126
|
+
textAlign: "center",
|
|
127
|
+
fontSize: "10px",
|
|
128
|
+
fontWeight: "bold",
|
|
129
|
+
color: s.colors.borderAccent,
|
|
130
|
+
letterSpacing: "0.5px",
|
|
131
|
+
textTransform: "uppercase",
|
|
132
|
+
transition: "background-color 150ms",
|
|
133
|
+
borderRadius: "0 0 2px 2px",
|
|
134
|
+
cursor: "pointer"
|
|
135
|
+
},
|
|
136
|
+
children: "View All Matching Search Metrics Records →"
|
|
137
|
+
})]
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
//#endregion
|
|
141
|
+
//#region src/components/search/SearchInput.tsx
|
|
142
|
+
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 }) {
|
|
143
|
+
let [b, x] = o(!1), [S, C] = o(!1), [w, T] = o(!1), [E, D] = o(!1), O = a(null), k = a(null);
|
|
144
|
+
i(() => {
|
|
145
|
+
let t = (t) => {
|
|
146
|
+
O.current && !O.current.contains(t.target) && (C(!1), e === "float" && u === "" && x(!1));
|
|
147
|
+
};
|
|
148
|
+
return window.addEventListener("mousedown", t), () => window.removeEventListener("mousedown", t);
|
|
149
|
+
}, [e, u]);
|
|
150
|
+
let A = (e) => {
|
|
151
|
+
e.stopPropagation(), d(""), f && f(), k.current && k.current.focus();
|
|
152
|
+
}, j = () => {
|
|
153
|
+
x(!0), setTimeout(() => k.current?.focus(), 50);
|
|
154
|
+
}, M = {
|
|
155
|
+
position: "relative",
|
|
156
|
+
display: "flex",
|
|
157
|
+
flexDirection: "column",
|
|
158
|
+
fontFamily: "sans-serif",
|
|
159
|
+
fontSize: "12px",
|
|
160
|
+
userSelect: "none",
|
|
161
|
+
boxSizing: "border-box"
|
|
162
|
+
}, N = {
|
|
163
|
+
position: "relative",
|
|
164
|
+
display: "flex",
|
|
165
|
+
alignItems: "center",
|
|
166
|
+
backgroundColor: s.colors.bgInput,
|
|
167
|
+
border: `1px solid ${E || e === "float" && b ? s.colors.borderAccent : w ? s.colors.borderAccentHover : s.colors.border}`,
|
|
168
|
+
borderRadius: "2px",
|
|
169
|
+
height: "32px",
|
|
170
|
+
transition: s.transitions.smooth,
|
|
171
|
+
boxSizing: "border-box"
|
|
172
|
+
}, P = {
|
|
173
|
+
width: "100%",
|
|
174
|
+
height: "100%",
|
|
175
|
+
backgroundColor: "transparent",
|
|
176
|
+
color: s.colors.text,
|
|
177
|
+
border: "none",
|
|
178
|
+
outline: "none",
|
|
179
|
+
padding: "0 32px",
|
|
180
|
+
fontSize: "12px",
|
|
181
|
+
boxSizing: "border-box"
|
|
182
|
+
};
|
|
183
|
+
if (e === "simple") {
|
|
184
|
+
let e = m > 0 && u.length > 0;
|
|
185
|
+
return /* @__PURE__ */ (0, c.jsxs)("div", {
|
|
186
|
+
style: M,
|
|
187
|
+
className: v,
|
|
188
|
+
children: [/* @__PURE__ */ (0, c.jsxs)("div", {
|
|
189
|
+
style: N,
|
|
190
|
+
onMouseEnter: () => T(!0),
|
|
191
|
+
onMouseLeave: () => T(!1),
|
|
192
|
+
children: [
|
|
193
|
+
/* @__PURE__ */ (0, c.jsx)("div", {
|
|
194
|
+
style: {
|
|
195
|
+
position: "absolute",
|
|
196
|
+
left: "10px",
|
|
197
|
+
display: "flex",
|
|
198
|
+
alignItems: "center",
|
|
199
|
+
color: w ? s.colors.text : s.colors.muted
|
|
200
|
+
},
|
|
201
|
+
children: /* @__PURE__ */ (0, c.jsx)(r, { size: 14 })
|
|
202
|
+
}),
|
|
203
|
+
/* @__PURE__ */ (0, c.jsx)("input", {
|
|
204
|
+
ref: k,
|
|
205
|
+
type: "text",
|
|
206
|
+
value: u,
|
|
207
|
+
onChange: (e) => d(e.target.value),
|
|
208
|
+
onFocus: () => D(!0),
|
|
209
|
+
onBlur: () => D(!1),
|
|
210
|
+
placeholder: p,
|
|
211
|
+
style: P
|
|
212
|
+
}),
|
|
213
|
+
u && /* @__PURE__ */ (0, c.jsx)("div", {
|
|
214
|
+
style: {
|
|
215
|
+
position: "absolute",
|
|
216
|
+
right: "4px",
|
|
217
|
+
top: "50%",
|
|
218
|
+
transform: "translateY(-50%)",
|
|
219
|
+
display: "flex",
|
|
220
|
+
alignItems: "center"
|
|
221
|
+
},
|
|
222
|
+
children: /* @__PURE__ */ (0, c.jsx)(t, {
|
|
223
|
+
icon: n,
|
|
224
|
+
color: "ghost",
|
|
225
|
+
iconOnly: !0,
|
|
226
|
+
onClick: A,
|
|
227
|
+
size: "xs"
|
|
228
|
+
})
|
|
229
|
+
})
|
|
230
|
+
]
|
|
231
|
+
}), /* @__PURE__ */ (0, c.jsx)("div", {
|
|
232
|
+
style: {
|
|
233
|
+
position: "absolute",
|
|
234
|
+
left: 0,
|
|
235
|
+
right: 0,
|
|
236
|
+
top: "32px",
|
|
237
|
+
zIndex: 10,
|
|
238
|
+
overflow: "hidden",
|
|
239
|
+
transition: s.transitions.smooth,
|
|
240
|
+
height: e ? "24px" : "0px",
|
|
241
|
+
opacity: +!!e,
|
|
242
|
+
transform: e ? "translateY(0px)" : "translateY(-4px)",
|
|
243
|
+
pointerEvents: "none"
|
|
244
|
+
},
|
|
245
|
+
children: /* @__PURE__ */ (0, c.jsx)("div", {
|
|
246
|
+
style: {
|
|
247
|
+
backgroundColor: s.colors.sidebarBg,
|
|
248
|
+
border: `1px solid ${s.colors.border}`,
|
|
249
|
+
borderTop: "none",
|
|
250
|
+
padding: "4px 6px",
|
|
251
|
+
borderRadius: "0 0 2px 2px",
|
|
252
|
+
boxShadow: "0 4px 6px -1px rgba(0,0,0,0.1)"
|
|
253
|
+
},
|
|
254
|
+
children: /* @__PURE__ */ (0, c.jsxs)("p", {
|
|
255
|
+
style: {
|
|
256
|
+
margin: 0,
|
|
257
|
+
fontSize: "10px",
|
|
258
|
+
fontFamily: "monospace",
|
|
259
|
+
color: s.colors.muted,
|
|
260
|
+
whiteSpace: "nowrap",
|
|
261
|
+
overflow: "hidden",
|
|
262
|
+
textOverflow: "ellipsis"
|
|
263
|
+
},
|
|
264
|
+
children: [
|
|
265
|
+
"Showing ",
|
|
266
|
+
/* @__PURE__ */ (0, c.jsx)("span", {
|
|
267
|
+
style: {
|
|
268
|
+
color: s.colors.borderAccent,
|
|
269
|
+
fontWeight: "bold"
|
|
270
|
+
},
|
|
271
|
+
children: m
|
|
272
|
+
}),
|
|
273
|
+
" matching database metrics records"
|
|
274
|
+
]
|
|
275
|
+
})
|
|
276
|
+
})
|
|
277
|
+
})]
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
if (e === "float") {
|
|
281
|
+
let e = y && m > 0 && u.length > 0, i = b || u.length > 0;
|
|
282
|
+
return /* @__PURE__ */ (0, c.jsxs)("div", {
|
|
283
|
+
ref: O,
|
|
284
|
+
style: M,
|
|
285
|
+
className: v,
|
|
286
|
+
children: [/* @__PURE__ */ (0, c.jsx)("div", {
|
|
287
|
+
onMouseEnter: () => T(!0),
|
|
288
|
+
onMouseLeave: () => T(!1),
|
|
289
|
+
style: {
|
|
290
|
+
...N,
|
|
291
|
+
width: i ? "256px" : "32px",
|
|
292
|
+
justifyContent: i ? "flex-start" : "center",
|
|
293
|
+
backgroundColor: i ? s.colors.bgInput : "transparent",
|
|
294
|
+
borderColor: i ? s.colors.borderAccent : "transparent",
|
|
295
|
+
padding: i ? "0 8px" : "0"
|
|
296
|
+
},
|
|
297
|
+
children: i ? /* @__PURE__ */ (0, c.jsxs)("div", {
|
|
298
|
+
style: {
|
|
299
|
+
position: "relative",
|
|
300
|
+
display: "flex",
|
|
301
|
+
alignItems: "center",
|
|
302
|
+
width: "100%",
|
|
303
|
+
height: "100%"
|
|
304
|
+
},
|
|
305
|
+
children: [
|
|
306
|
+
/* @__PURE__ */ (0, c.jsx)(r, {
|
|
307
|
+
size: 14,
|
|
308
|
+
style: {
|
|
309
|
+
color: s.colors.text,
|
|
310
|
+
flexShrink: 0
|
|
311
|
+
}
|
|
312
|
+
}),
|
|
313
|
+
/* @__PURE__ */ (0, c.jsx)("input", {
|
|
314
|
+
ref: k,
|
|
315
|
+
type: "text",
|
|
316
|
+
value: u,
|
|
317
|
+
onChange: (e) => d(e.target.value),
|
|
318
|
+
placeholder: p,
|
|
319
|
+
style: {
|
|
320
|
+
...P,
|
|
321
|
+
padding: "0 24px 0 8px"
|
|
322
|
+
}
|
|
323
|
+
}),
|
|
324
|
+
u && /* @__PURE__ */ (0, c.jsx)("div", {
|
|
325
|
+
style: {
|
|
326
|
+
position: "absolute",
|
|
327
|
+
right: 0,
|
|
328
|
+
top: "50%",
|
|
329
|
+
transform: "translateY(-50%)",
|
|
330
|
+
display: "flex",
|
|
331
|
+
alignItems: "center"
|
|
332
|
+
},
|
|
333
|
+
children: /* @__PURE__ */ (0, c.jsx)(t, {
|
|
334
|
+
iconOnly: !0,
|
|
335
|
+
color: "ghost",
|
|
336
|
+
icon: n,
|
|
337
|
+
onClick: A,
|
|
338
|
+
size: "xs"
|
|
339
|
+
})
|
|
340
|
+
})
|
|
341
|
+
]
|
|
342
|
+
}) : /* @__PURE__ */ (0, c.jsx)(t, {
|
|
343
|
+
iconOnly: !0,
|
|
344
|
+
size: "sm",
|
|
345
|
+
icon: r,
|
|
346
|
+
onClick: j,
|
|
347
|
+
color: "ghost",
|
|
348
|
+
style: { color: s.colors.muted },
|
|
349
|
+
title: "Open Expandable Search"
|
|
350
|
+
})
|
|
351
|
+
}), /* @__PURE__ */ (0, c.jsx)("div", {
|
|
352
|
+
style: {
|
|
353
|
+
position: "absolute",
|
|
354
|
+
top: "32px",
|
|
355
|
+
width: "256px",
|
|
356
|
+
zIndex: 10,
|
|
357
|
+
overflow: "hidden",
|
|
358
|
+
transition: s.transitions.smooth,
|
|
359
|
+
height: e ? "24px" : "0px",
|
|
360
|
+
opacity: +!!e,
|
|
361
|
+
transform: e ? "translateY(0px)" : "translateY(-4px)",
|
|
362
|
+
pointerEvents: "none"
|
|
363
|
+
},
|
|
364
|
+
children: /* @__PURE__ */ (0, c.jsx)("div", {
|
|
365
|
+
style: {
|
|
366
|
+
backgroundColor: s.colors.sidebarBg,
|
|
367
|
+
border: `1px solid ${s.colors.border}`,
|
|
368
|
+
borderTop: "none",
|
|
369
|
+
padding: "4px",
|
|
370
|
+
borderRadius: "0 0 2px 2px",
|
|
371
|
+
boxShadow: "0 4px 6px -1px rgba(0,0,0,0.1)"
|
|
372
|
+
},
|
|
373
|
+
children: /* @__PURE__ */ (0, c.jsxs)("p", {
|
|
374
|
+
style: {
|
|
375
|
+
margin: 0,
|
|
376
|
+
fontSize: "9px",
|
|
377
|
+
fontFamily: "monospace",
|
|
378
|
+
color: s.colors.borderAccent,
|
|
379
|
+
whiteSpace: "nowrap",
|
|
380
|
+
overflow: "hidden",
|
|
381
|
+
textOverflow: "ellipsis"
|
|
382
|
+
},
|
|
383
|
+
children: [
|
|
384
|
+
"Quick Peek: Found ",
|
|
385
|
+
m,
|
|
386
|
+
" rows"
|
|
387
|
+
]
|
|
388
|
+
})
|
|
389
|
+
})
|
|
390
|
+
})]
|
|
391
|
+
});
|
|
392
|
+
}
|
|
393
|
+
return /* @__PURE__ */ (0, c.jsxs)("div", {
|
|
394
|
+
ref: O,
|
|
395
|
+
style: M,
|
|
396
|
+
className: v,
|
|
397
|
+
children: [/* @__PURE__ */ (0, c.jsxs)("div", {
|
|
398
|
+
style: N,
|
|
399
|
+
onMouseEnter: () => T(!0),
|
|
400
|
+
onMouseLeave: () => T(!1),
|
|
401
|
+
children: [
|
|
402
|
+
/* @__PURE__ */ (0, c.jsx)("div", {
|
|
403
|
+
style: {
|
|
404
|
+
position: "absolute",
|
|
405
|
+
left: "10px",
|
|
406
|
+
display: "flex",
|
|
407
|
+
alignItems: "center",
|
|
408
|
+
color: s.colors.muted
|
|
409
|
+
},
|
|
410
|
+
children: /* @__PURE__ */ (0, c.jsx)(r, { size: 14 })
|
|
411
|
+
}),
|
|
412
|
+
/* @__PURE__ */ (0, c.jsx)("input", {
|
|
413
|
+
ref: k,
|
|
414
|
+
type: "text",
|
|
415
|
+
value: u,
|
|
416
|
+
onChange: (e) => {
|
|
417
|
+
d(e.target.value), C(!0);
|
|
418
|
+
},
|
|
419
|
+
onFocus: () => C(!0),
|
|
420
|
+
placeholder: p,
|
|
421
|
+
style: P
|
|
422
|
+
}),
|
|
423
|
+
u && /* @__PURE__ */ (0, c.jsx)("div", {
|
|
424
|
+
style: {
|
|
425
|
+
position: "absolute",
|
|
426
|
+
right: "4px",
|
|
427
|
+
top: "50%",
|
|
428
|
+
transform: "translateY(-50%)",
|
|
429
|
+
display: "flex",
|
|
430
|
+
alignItems: "center"
|
|
431
|
+
},
|
|
432
|
+
children: /* @__PURE__ */ (0, c.jsx)(t, {
|
|
433
|
+
iconOnly: !0,
|
|
434
|
+
icon: n,
|
|
435
|
+
color: "ghost",
|
|
436
|
+
onClick: A,
|
|
437
|
+
size: "xs"
|
|
438
|
+
})
|
|
439
|
+
})
|
|
440
|
+
]
|
|
441
|
+
}), /* @__PURE__ */ (0, c.jsx)(l, {
|
|
442
|
+
isOpen: S,
|
|
443
|
+
value: u,
|
|
444
|
+
menuResults: h,
|
|
445
|
+
onResultClick: g,
|
|
446
|
+
onViewMoreClick: _,
|
|
447
|
+
onCloseMenu: () => C(!1)
|
|
448
|
+
})]
|
|
449
|
+
});
|
|
450
|
+
}
|
|
451
|
+
//#endregion
|
|
452
|
+
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 }: 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-BCvuXqOX.js";
|
|
2
|
+
export { t as SearchInput, e as searchTokens };
|
|
@@ -16,4 +16,21 @@ export interface SearchInputProps {
|
|
|
16
16
|
onResultClick?: (item: SearchResultItem) => void;
|
|
17
17
|
onViewMoreClick?: () => void;
|
|
18
18
|
className?: string;
|
|
19
|
+
showFloatPeek?: boolean;
|
|
19
20
|
}
|
|
21
|
+
export declare const searchTokens: {
|
|
22
|
+
colors: {
|
|
23
|
+
bgInput: string;
|
|
24
|
+
border: string;
|
|
25
|
+
borderAccent: string;
|
|
26
|
+
borderAccentHover: string;
|
|
27
|
+
text: string;
|
|
28
|
+
muted: string;
|
|
29
|
+
sidebarBg: string;
|
|
30
|
+
hoverBg: string;
|
|
31
|
+
accentBgLight: string;
|
|
32
|
+
};
|
|
33
|
+
transitions: {
|
|
34
|
+
smooth: string;
|
|
35
|
+
};
|
|
36
|
+
};
|
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-BCvuXqOX.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,16 @@ export default function SearchInput({
|
|
|
21
15
|
onResultClick,
|
|
22
16
|
onViewMoreClick,
|
|
23
17
|
className = '',
|
|
24
|
-
showFloatPeek = false
|
|
25
|
-
|
|
26
|
-
}: AdvancedSearchInputProps) {
|
|
18
|
+
showFloatPeek = false
|
|
19
|
+
}: SearchInputProps) {
|
|
27
20
|
const [isExpanded, setIsExpanded] = useState<boolean>(false);
|
|
28
21
|
const [isMenuOpen, setIsMenuOpen] = useState<boolean>(false);
|
|
22
|
+
const [isInputHovered, setIsInputHovered] = useState<boolean>(false);
|
|
23
|
+
const [isInputFocused, setIsInputFocused] = useState<boolean>(false);
|
|
24
|
+
|
|
29
25
|
const containerRef = useRef<HTMLDivElement | null>(null);
|
|
30
26
|
const inputRef = useRef<HTMLInputElement | null>(null);
|
|
31
27
|
|
|
32
|
-
// Auto-close overlay dropdowns if the user clicks completely out of the component framework bounding box
|
|
33
28
|
useEffect(() => {
|
|
34
29
|
const handleOutsideClick = (e: MouseEvent) => {
|
|
35
30
|
if (containerRef.current && !containerRef.current.contains(e.target as Node)) {
|
|
@@ -55,67 +50,95 @@ export default function SearchInput({
|
|
|
55
50
|
setTimeout(() => inputRef.current?.focus(), 50);
|
|
56
51
|
};
|
|
57
52
|
|
|
58
|
-
const
|
|
53
|
+
const baseWrapperStyles: React.CSSProperties = {
|
|
54
|
+
position: 'relative',
|
|
55
|
+
display: 'flex',
|
|
56
|
+
flexDirection: 'column',
|
|
57
|
+
fontFamily: 'sans-serif',
|
|
58
|
+
fontSize: '12px',
|
|
59
|
+
userSelect: 'none',
|
|
60
|
+
boxSizing: 'border-box'
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
const inputContainerBaseStyles: React.CSSProperties = {
|
|
64
|
+
position: 'relative',
|
|
65
|
+
display: 'flex',
|
|
66
|
+
alignItems: 'center',
|
|
67
|
+
backgroundColor: searchTokens.colors.bgInput,
|
|
68
|
+
border: `1px solid ${isInputFocused || (variant === 'float' && isExpanded)
|
|
69
|
+
? searchTokens.colors.borderAccent
|
|
70
|
+
: isInputHovered
|
|
71
|
+
? searchTokens.colors.borderAccentHover
|
|
72
|
+
: searchTokens.colors.border
|
|
73
|
+
}`,
|
|
74
|
+
borderRadius: '2px',
|
|
75
|
+
height: '32px',
|
|
76
|
+
transition: searchTokens.transitions.smooth,
|
|
77
|
+
boxSizing: 'border-box'
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
const rawInputStyles: React.CSSProperties = {
|
|
81
|
+
width: '100%',
|
|
82
|
+
height: '100%',
|
|
83
|
+
backgroundColor: 'transparent',
|
|
84
|
+
color: searchTokens.colors.text,
|
|
85
|
+
border: 'none',
|
|
86
|
+
outline: 'none',
|
|
87
|
+
padding: '0 32px',
|
|
88
|
+
fontSize: '12px',
|
|
89
|
+
boxSizing: 'border-box'
|
|
90
|
+
};
|
|
59
91
|
|
|
60
|
-
// --- 1. SIMPLE VARIANT
|
|
92
|
+
// --- 1. SIMPLE VARIANT ---
|
|
61
93
|
if (variant === 'simple') {
|
|
62
|
-
const hasResults = value.length > 0;
|
|
94
|
+
const hasResults = resultsCount > 0 && value.length > 0;
|
|
63
95
|
|
|
64
96
|
return (
|
|
65
|
-
<div
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
97
|
+
<div style={baseWrapperStyles} className={className}>
|
|
98
|
+
<div
|
|
99
|
+
style={inputContainerBaseStyles}
|
|
100
|
+
onMouseEnter={() => setIsInputHovered(true)}
|
|
101
|
+
onMouseLeave={() => setIsInputHovered(false)}
|
|
102
|
+
>
|
|
103
|
+
<div style={{ position: 'absolute', left: '10px', display: 'flex', alignItems: 'center', color: isInputHovered ? searchTokens.colors.text : searchTokens.colors.muted }}>
|
|
104
|
+
<Search size={14} />
|
|
105
|
+
</div>
|
|
69
106
|
<input
|
|
70
107
|
ref={inputRef}
|
|
71
108
|
type="text"
|
|
72
109
|
value={value}
|
|
73
110
|
onChange={(e) => onChange(e.target.value)}
|
|
111
|
+
onFocus={() => setIsInputFocused(true)}
|
|
112
|
+
onBlur={() => setIsInputFocused(false)}
|
|
74
113
|
placeholder={placeholder}
|
|
75
|
-
|
|
114
|
+
style={rawInputStyles}
|
|
76
115
|
/>
|
|
77
116
|
{value && (
|
|
78
|
-
<div
|
|
79
|
-
<Button
|
|
80
|
-
icon={Close}
|
|
81
|
-
color="ghost"
|
|
82
|
-
iconOnly={true}
|
|
83
|
-
onClick={handleClearTrigger}
|
|
84
|
-
size="xs"
|
|
85
|
-
/>
|
|
117
|
+
<div style={{ position: 'absolute', right: '4px', top: '50%', transform: 'translateY(-50%)', display: 'flex', alignItems: 'center' }}>
|
|
118
|
+
<Button icon={Close} color="ghost" iconOnly={true} onClick={handleClearTrigger} size="xs" />
|
|
86
119
|
</div>
|
|
87
120
|
)}
|
|
88
121
|
</div>
|
|
89
122
|
|
|
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
123
|
<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
124
|
style={{
|
|
98
|
-
|
|
125
|
+
position: 'absolute',
|
|
126
|
+
left: 0,
|
|
127
|
+
right: 0,
|
|
128
|
+
top: '32px',
|
|
129
|
+
zIndex: 10,
|
|
130
|
+
overflow: 'hidden',
|
|
131
|
+
transition: searchTokens.transitions.smooth,
|
|
132
|
+
height: hasResults ? '24px' : '0px',
|
|
99
133
|
opacity: hasResults ? 1 : 0,
|
|
100
|
-
transform: hasResults ? 'translateY(0px)' : 'translateY(-4px)'
|
|
134
|
+
transform: hasResults ? 'translateY(0px)' : 'translateY(-4px)',
|
|
135
|
+
pointerEvents: 'none'
|
|
101
136
|
}}
|
|
102
137
|
>
|
|
103
|
-
<div
|
|
104
|
-
{
|
|
105
|
-
resultsCount
|
|
106
|
-
|
|
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
|
-
}
|
|
138
|
+
<div style={{ backgroundColor: searchTokens.colors.sidebarBg, border: `1px solid ${searchTokens.colors.border}`, borderTop: 'none', padding: '4px 6px', borderRadius: '0 0 2px 2px', boxShadow: '0 4px 6px -1px rgba(0,0,0,0.1)' }}>
|
|
139
|
+
<p style={{ margin: 0, fontSize: '10px', fontFamily: 'monospace', color: searchTokens.colors.muted, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>
|
|
140
|
+
Showing <span style={{ color: searchTokens.colors.borderAccent, fontWeight: 'bold' }}>{resultsCount}</span> matching database metrics records
|
|
141
|
+
</p>
|
|
119
142
|
</div>
|
|
120
143
|
</div>
|
|
121
144
|
</div>
|
|
@@ -125,32 +148,36 @@ export default function SearchInput({
|
|
|
125
148
|
// --- 2. FLOAT EXPANDABLE VARIANT ---
|
|
126
149
|
if (variant === 'float') {
|
|
127
150
|
const showPeekIndicator = showFloatPeek && resultsCount > 0 && value.length > 0;
|
|
151
|
+
const isOpened = isExpanded || value.length > 0;
|
|
152
|
+
|
|
128
153
|
return (
|
|
129
|
-
<div ref={containerRef}
|
|
154
|
+
<div ref={containerRef} style={baseWrapperStyles} className={className}>
|
|
130
155
|
<div
|
|
131
|
-
|
|
132
|
-
|
|
156
|
+
onMouseEnter={() => setIsInputHovered(true)}
|
|
157
|
+
onMouseLeave={() => setIsInputHovered(false)}
|
|
158
|
+
style={{
|
|
159
|
+
...inputContainerBaseStyles,
|
|
160
|
+
width: isOpened ? '256px' : '32px',
|
|
161
|
+
justifyContent: isOpened ? 'flex-start' : 'center',
|
|
162
|
+
backgroundColor: isOpened ? searchTokens.colors.bgInput : 'transparent',
|
|
163
|
+
borderColor: isOpened ? searchTokens.colors.borderAccent : 'transparent',
|
|
164
|
+
padding: isOpened ? '0 8px' : '0'
|
|
165
|
+
}}
|
|
133
166
|
>
|
|
134
|
-
{
|
|
135
|
-
<div
|
|
136
|
-
<Search size={14}
|
|
167
|
+
{isOpened ? (
|
|
168
|
+
<div style={{ position: 'relative', display: 'flex', alignItems: 'center', width: '100%', height: '100%' }}>
|
|
169
|
+
<Search size={14} style={{ color: searchTokens.colors.text, flexShrink: 0 }} />
|
|
137
170
|
<input
|
|
138
171
|
ref={inputRef}
|
|
139
172
|
type="text"
|
|
140
173
|
value={value}
|
|
141
174
|
onChange={(e) => onChange(e.target.value)}
|
|
142
175
|
placeholder={placeholder}
|
|
143
|
-
|
|
176
|
+
style={{ ...rawInputStyles, padding: '0 24px 0 8px' }}
|
|
144
177
|
/>
|
|
145
178
|
{value && (
|
|
146
|
-
<div
|
|
147
|
-
<Button
|
|
148
|
-
iconOnly={true}
|
|
149
|
-
color="ghost"
|
|
150
|
-
icon={Close}
|
|
151
|
-
onClick={handleClearTrigger}
|
|
152
|
-
size="xs"
|
|
153
|
-
/>
|
|
179
|
+
<div style={{ position: 'absolute', right: 0, top: '50%', transform: 'translateY(-50%)', display: 'flex', alignItems: 'center' }}>
|
|
180
|
+
<Button iconOnly={true} color="ghost" icon={Close} onClick={handleClearTrigger} size="xs" />
|
|
154
181
|
</div>
|
|
155
182
|
)}
|
|
156
183
|
</div>
|
|
@@ -161,33 +188,47 @@ export default function SearchInput({
|
|
|
161
188
|
icon={Search}
|
|
162
189
|
onClick={handleFloatActivation}
|
|
163
190
|
color="ghost"
|
|
164
|
-
|
|
191
|
+
style={{ color: searchTokens.colors.muted }}
|
|
165
192
|
title="Open Expandable Search"
|
|
166
193
|
/>
|
|
167
194
|
)}
|
|
168
195
|
</div>
|
|
169
196
|
|
|
170
|
-
{/* Optional dynamic slider line badge dropdown block */}
|
|
171
197
|
<div
|
|
172
|
-
className="overflow-hidden transition-all duration-200 ease-out w-64 absolute top-8"
|
|
173
198
|
style={{
|
|
174
|
-
|
|
175
|
-
|
|
199
|
+
position: 'absolute',
|
|
200
|
+
top: '32px',
|
|
201
|
+
width: '256px',
|
|
202
|
+
zIndex: 10,
|
|
203
|
+
overflow: 'hidden',
|
|
204
|
+
transition: searchTokens.transitions.smooth,
|
|
205
|
+
height: showPeekIndicator ? '24px' : '0px',
|
|
206
|
+
opacity: showPeekIndicator ? 1 : 0,
|
|
207
|
+
transform: showPeekIndicator ? 'translateY(0px)' : 'translateY(-4px)',
|
|
208
|
+
pointerEvents: 'none'
|
|
176
209
|
}}
|
|
177
210
|
>
|
|
178
|
-
<
|
|
179
|
-
|
|
180
|
-
|
|
211
|
+
<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)' }}>
|
|
212
|
+
<p style={{ margin: 0, fontSize: '9px', fontFamily: 'monospace', color: searchTokens.colors.borderAccent, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>
|
|
213
|
+
Quick Peek: Found {resultsCount} rows
|
|
214
|
+
</p>
|
|
215
|
+
</div>
|
|
181
216
|
</div>
|
|
182
217
|
</div>
|
|
183
218
|
);
|
|
184
219
|
}
|
|
185
220
|
|
|
186
|
-
// --- 3. MENU
|
|
221
|
+
// --- 3. MENU DROPDOWN VARIANT ---
|
|
187
222
|
return (
|
|
188
|
-
<div ref={containerRef}
|
|
189
|
-
<div
|
|
190
|
-
|
|
223
|
+
<div ref={containerRef} style={baseWrapperStyles} className={className}>
|
|
224
|
+
<div
|
|
225
|
+
style={inputContainerBaseStyles}
|
|
226
|
+
onMouseEnter={() => setIsInputHovered(true)}
|
|
227
|
+
onMouseLeave={() => setIsInputHovered(false)}
|
|
228
|
+
>
|
|
229
|
+
<div style={{ position: 'absolute', left: '10px', display: 'flex', alignItems: 'center', color: searchTokens.colors.muted }}>
|
|
230
|
+
<Search size={14} />
|
|
231
|
+
</div>
|
|
191
232
|
<input
|
|
192
233
|
ref={inputRef}
|
|
193
234
|
type="text"
|
|
@@ -198,65 +239,23 @@ export default function SearchInput({
|
|
|
198
239
|
}}
|
|
199
240
|
onFocus={() => setIsMenuOpen(true)}
|
|
200
241
|
placeholder={placeholder}
|
|
201
|
-
|
|
242
|
+
style={rawInputStyles}
|
|
202
243
|
/>
|
|
203
244
|
{value && (
|
|
204
|
-
<div
|
|
205
|
-
<Button
|
|
206
|
-
iconOnly={true}
|
|
207
|
-
icon={Close}
|
|
208
|
-
color="ghost"
|
|
209
|
-
onClick={handleClearTrigger}
|
|
210
|
-
size="xs"
|
|
211
|
-
/>
|
|
245
|
+
<div style={{ position: 'absolute', right: '4px', top: '50%', transform: 'translateY(-50%)', display: 'flex', alignItems: 'center' }}>
|
|
246
|
+
<Button iconOnly={true} icon={Close} color="ghost" onClick={handleClearTrigger} size="xs" />
|
|
212
247
|
</div>
|
|
213
248
|
)}
|
|
214
249
|
</div>
|
|
215
250
|
|
|
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
|
-
)}
|
|
251
|
+
<SearchMenu
|
|
252
|
+
isOpen={isMenuOpen}
|
|
253
|
+
value={value}
|
|
254
|
+
menuResults={menuResults}
|
|
255
|
+
onResultClick={onResultClick}
|
|
256
|
+
onViewMoreClick={onViewMoreClick}
|
|
257
|
+
onCloseMenu={() => setIsMenuOpen(false)}
|
|
258
|
+
/>
|
|
260
259
|
</div>
|
|
261
260
|
);
|
|
262
261
|
}
|
|
@@ -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
|
+
}
|
|
@@ -13,9 +13,27 @@ export interface SearchInputProps {
|
|
|
13
13
|
onChange: (value: string) => void;
|
|
14
14
|
onClear?: () => void;
|
|
15
15
|
placeholder?: string;
|
|
16
|
-
resultsCount?: number;
|
|
17
|
-
menuResults?: SearchResultItem[];
|
|
16
|
+
resultsCount?: number;
|
|
17
|
+
menuResults?: SearchResultItem[];
|
|
18
18
|
onResultClick?: (item: SearchResultItem) => void;
|
|
19
19
|
onViewMoreClick?: () => void;
|
|
20
20
|
className?: string;
|
|
21
|
+
showFloatPeek?: boolean;
|
|
21
22
|
}
|
|
23
|
+
|
|
24
|
+
export const searchTokens = {
|
|
25
|
+
colors: {
|
|
26
|
+
bgInput: 'var(--color-vsc-bg-input, #f6f8fa)',
|
|
27
|
+
border: 'var(--color-vsc-border, #e4e4e7)',
|
|
28
|
+
borderAccent: 'var(--color-vsc-accent, #007acc)',
|
|
29
|
+
borderAccentHover: 'var(--color-vsc-accent-hover, #0062a3)',
|
|
30
|
+
text: 'var(--color-vsc-text, #333333)',
|
|
31
|
+
muted: 'var(--color-vsc-muted, #6a737d)',
|
|
32
|
+
sidebarBg: 'var(--color-vsc-sidebar, #f3f3f3)',
|
|
33
|
+
hoverBg: 'var(--color-vsc-hover, #e8e8e8)',
|
|
34
|
+
accentBgLight: 'rgba(0, 122, 204, 0.1)'
|
|
35
|
+
},
|
|
36
|
+
transitions: {
|
|
37
|
+
smooth: 'all 200ms cubic-bezier(0.34, 1.56, 0.64, 1)'
|
|
38
|
+
}
|
|
39
|
+
};
|
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 };
|