@gmickel/gno 0.35.0 → 0.36.0
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/package.json +1 -1
- package/src/serve/public/app.tsx +7 -3
- package/src/serve/public/components/BrowseDetailPane.tsx +18 -1
- package/src/serve/public/components/QuickSwitcher.tsx +226 -88
- package/src/serve/public/components/ui/command.tsx +19 -9
- package/src/serve/public/components/ui/dialog.tsx +1 -1
- package/src/serve/public/globals.built.css +2 -2
- package/src/serve/public/globals.css +47 -0
- package/src/serve/public/lib/browse.ts +1 -0
- package/src/serve/public/pages/DocView.tsx +33 -10
- package/src/store/sqlite/adapter.ts +19 -19
package/package.json
CHANGED
package/src/serve/public/app.tsx
CHANGED
|
@@ -220,7 +220,8 @@ function AppContent({
|
|
|
220
220
|
}
|
|
221
221
|
|
|
222
222
|
function App() {
|
|
223
|
-
const initialLocation =
|
|
223
|
+
const initialLocation =
|
|
224
|
+
window.location.pathname + window.location.search + window.location.hash;
|
|
224
225
|
const [workspace, setWorkspace] = useState<WorkspaceState>(() =>
|
|
225
226
|
loadWorkspaceState(initialLocation)
|
|
226
227
|
);
|
|
@@ -231,7 +232,8 @@ function App() {
|
|
|
231
232
|
const location = activeTab?.location ?? "/";
|
|
232
233
|
|
|
233
234
|
useEffect(() => {
|
|
234
|
-
const currentLocation =
|
|
235
|
+
const currentLocation =
|
|
236
|
+
window.location.pathname + window.location.search + window.location.hash;
|
|
235
237
|
if (location !== currentLocation) {
|
|
236
238
|
window.history.replaceState({}, "", location);
|
|
237
239
|
}
|
|
@@ -242,7 +244,9 @@ function App() {
|
|
|
242
244
|
setWorkspace((current) =>
|
|
243
245
|
updateActiveTabLocation(
|
|
244
246
|
current,
|
|
245
|
-
window.location.pathname +
|
|
247
|
+
window.location.pathname +
|
|
248
|
+
window.location.search +
|
|
249
|
+
window.location.hash
|
|
246
250
|
)
|
|
247
251
|
);
|
|
248
252
|
};
|
|
@@ -43,6 +43,19 @@ export function BrowseDetailPane({
|
|
|
43
43
|
selectedPath: string;
|
|
44
44
|
total: number;
|
|
45
45
|
}) {
|
|
46
|
+
const formatModified = (value?: string) => {
|
|
47
|
+
if (!value) return "—";
|
|
48
|
+
try {
|
|
49
|
+
return new Date(value).toLocaleDateString("en-US", {
|
|
50
|
+
month: "short",
|
|
51
|
+
day: "numeric",
|
|
52
|
+
year: "numeric",
|
|
53
|
+
});
|
|
54
|
+
} catch {
|
|
55
|
+
return value;
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
|
|
46
59
|
if (docsLoading && docs.length === 0) {
|
|
47
60
|
return (
|
|
48
61
|
<div className="flex flex-col items-center justify-center gap-4 py-20">
|
|
@@ -107,7 +120,8 @@ export function BrowseDetailPane({
|
|
|
107
120
|
<Table className="table-fixed">
|
|
108
121
|
<TableHeader>
|
|
109
122
|
<TableRow>
|
|
110
|
-
<TableHead className="w-[
|
|
123
|
+
<TableHead className="w-[56%]">Document</TableHead>
|
|
124
|
+
<TableHead className="w-[130px]">Modified</TableHead>
|
|
111
125
|
<TableHead className="w-[220px]">Collection</TableHead>
|
|
112
126
|
<TableHead className="w-[72px] text-right">Type</TableHead>
|
|
113
127
|
</TableRow>
|
|
@@ -151,6 +165,9 @@ export function BrowseDetailPane({
|
|
|
151
165
|
<ChevronRight className="ml-auto size-4 shrink-0 text-muted-foreground opacity-0 transition-opacity group-hover:opacity-100" />
|
|
152
166
|
</div>
|
|
153
167
|
</TableCell>
|
|
168
|
+
<TableCell className="align-top whitespace-normal text-muted-foreground text-xs">
|
|
169
|
+
{formatModified(doc.updatedAt)}
|
|
170
|
+
</TableCell>
|
|
154
171
|
<TableCell className="align-top whitespace-normal">
|
|
155
172
|
<Badge
|
|
156
173
|
className="inline-flex min-h-[2.5rem] max-w-[180px] cursor-pointer items-center px-3 py-1 text-center whitespace-normal break-words font-mono text-xs leading-tight transition-colors hover:border-primary hover:text-primary"
|
|
@@ -158,7 +158,19 @@ export function QuickSwitcher({
|
|
|
158
158
|
return () => clearTimeout(timer);
|
|
159
159
|
}, [open, query]);
|
|
160
160
|
|
|
161
|
-
const recentItems = useMemo(() =>
|
|
161
|
+
const recentItems = useMemo(() => {
|
|
162
|
+
const seenHref = new Set<string>();
|
|
163
|
+
const seenUri = new Set<string>();
|
|
164
|
+
return recentDocs
|
|
165
|
+
.filter((doc) => {
|
|
166
|
+
if (seenHref.has(doc.href) || seenUri.has(doc.uri)) return false;
|
|
167
|
+
seenHref.add(doc.href);
|
|
168
|
+
seenUri.add(doc.uri);
|
|
169
|
+
return true;
|
|
170
|
+
})
|
|
171
|
+
.slice(0, 6);
|
|
172
|
+
}, [recentDocs]);
|
|
173
|
+
const normalizedQuery = query.trim().toLowerCase();
|
|
162
174
|
const favoriteDocItems = useMemo(
|
|
163
175
|
() => favoriteDocs.slice(0, 6),
|
|
164
176
|
[favoriteDocs]
|
|
@@ -167,12 +179,63 @@ export function QuickSwitcher({
|
|
|
167
179
|
() => favoriteCollections.slice(0, 6),
|
|
168
180
|
[favoriteCollections]
|
|
169
181
|
);
|
|
182
|
+
const filteredRecentItems = useMemo(
|
|
183
|
+
() =>
|
|
184
|
+
recentItems.filter(
|
|
185
|
+
(item) =>
|
|
186
|
+
!normalizedQuery ||
|
|
187
|
+
item.label.toLowerCase().includes(normalizedQuery) ||
|
|
188
|
+
item.uri.toLowerCase().includes(normalizedQuery)
|
|
189
|
+
),
|
|
190
|
+
[normalizedQuery, recentItems]
|
|
191
|
+
);
|
|
192
|
+
const filteredFavoriteDocItems = useMemo(
|
|
193
|
+
() =>
|
|
194
|
+
favoriteDocItems.filter(
|
|
195
|
+
(item) =>
|
|
196
|
+
!normalizedQuery ||
|
|
197
|
+
item.label.toLowerCase().includes(normalizedQuery) ||
|
|
198
|
+
item.uri.toLowerCase().includes(normalizedQuery)
|
|
199
|
+
),
|
|
200
|
+
[favoriteDocItems, normalizedQuery]
|
|
201
|
+
);
|
|
202
|
+
const filteredFavoriteCollectionItems = useMemo(
|
|
203
|
+
() =>
|
|
204
|
+
favoriteCollectionItems.filter(
|
|
205
|
+
(item) =>
|
|
206
|
+
!normalizedQuery || item.label.toLowerCase().includes(normalizedQuery)
|
|
207
|
+
),
|
|
208
|
+
[favoriteCollectionItems, normalizedQuery]
|
|
209
|
+
);
|
|
170
210
|
const workspaceActions = useMemo(
|
|
171
211
|
() => getWorkspaceActions({ location }),
|
|
172
212
|
[location]
|
|
173
213
|
);
|
|
214
|
+
const matchingWorkspaceActions = useMemo(
|
|
215
|
+
() =>
|
|
216
|
+
workspaceActions.filter((action) => {
|
|
217
|
+
if (
|
|
218
|
+
["new-note", "new-note-in-context", "create-folder-here"].includes(
|
|
219
|
+
action.id
|
|
220
|
+
)
|
|
221
|
+
) {
|
|
222
|
+
return true;
|
|
223
|
+
}
|
|
224
|
+
if (!normalizedQuery) {
|
|
225
|
+
return true;
|
|
226
|
+
}
|
|
227
|
+
const haystack = [
|
|
228
|
+
action.label,
|
|
229
|
+
action.description ?? "",
|
|
230
|
+
...action.keywords,
|
|
231
|
+
]
|
|
232
|
+
.join(" ")
|
|
233
|
+
.toLowerCase();
|
|
234
|
+
return haystack.includes(normalizedQuery);
|
|
235
|
+
}),
|
|
236
|
+
[normalizedQuery, workspaceActions]
|
|
237
|
+
);
|
|
174
238
|
const exactResult = useMemo(() => {
|
|
175
|
-
const normalizedQuery = query.trim().toLowerCase();
|
|
176
239
|
if (!normalizedQuery) {
|
|
177
240
|
return null;
|
|
178
241
|
}
|
|
@@ -191,7 +254,7 @@ export function QuickSwitcher({
|
|
|
191
254
|
);
|
|
192
255
|
}) ?? null
|
|
193
256
|
);
|
|
194
|
-
}, [
|
|
257
|
+
}, [normalizedQuery, results]);
|
|
195
258
|
|
|
196
259
|
const openTarget = useCallback(
|
|
197
260
|
(target: { uri: string; lineStart?: number; lineEnd?: number }) => {
|
|
@@ -234,12 +297,31 @@ export function QuickSwitcher({
|
|
|
234
297
|
section.title.toLowerCase().includes(normalizedQuery)
|
|
235
298
|
);
|
|
236
299
|
}, [query, sections]);
|
|
300
|
+
const hasQuery = query.trim().length > 0;
|
|
301
|
+
const hasPriorityMatches =
|
|
302
|
+
filteredSections.length > 0 ||
|
|
303
|
+
results.length > 0 ||
|
|
304
|
+
filteredRecentItems.length > 0 ||
|
|
305
|
+
filteredFavoriteDocItems.length > 0 ||
|
|
306
|
+
filteredFavoriteCollectionItems.length > 0;
|
|
307
|
+
const commandKey = useMemo(
|
|
308
|
+
() =>
|
|
309
|
+
[
|
|
310
|
+
normalizedQuery || "__empty__",
|
|
311
|
+
filteredSections.map((section) => section.anchor).join(","),
|
|
312
|
+
results.map((result) => result.docid).join(","),
|
|
313
|
+
filteredRecentItems.map((item) => item.href).join(","),
|
|
314
|
+
].join("|"),
|
|
315
|
+
[filteredRecentItems, filteredSections, normalizedQuery, results]
|
|
316
|
+
);
|
|
237
317
|
|
|
238
318
|
return (
|
|
239
319
|
<CommandDialog
|
|
320
|
+
commandKey={commandKey}
|
|
240
321
|
description="Jump to notes, open recent documents, or create a new note."
|
|
241
322
|
onOpenChange={onOpenChange}
|
|
242
323
|
open={open}
|
|
324
|
+
shouldFilter={false}
|
|
243
325
|
title="Quick Switcher"
|
|
244
326
|
>
|
|
245
327
|
<CommandInput
|
|
@@ -253,16 +335,87 @@ export function QuickSwitcher({
|
|
|
253
335
|
{loading ? "Searching..." : "No matching documents."}
|
|
254
336
|
</CommandEmpty>
|
|
255
337
|
|
|
256
|
-
{
|
|
338
|
+
{hasQuery && filteredSections.length > 0 && (
|
|
339
|
+
<CommandGroup heading="Sections">
|
|
340
|
+
{filteredSections.map((section) => {
|
|
341
|
+
const target = parseDocumentDeepLink(
|
|
342
|
+
location.includes("?") ? `?${location.split("?")[1] ?? ""}` : ""
|
|
343
|
+
);
|
|
344
|
+
if (!target.uri) {
|
|
345
|
+
return null;
|
|
346
|
+
}
|
|
347
|
+
return (
|
|
348
|
+
<CommandItem
|
|
349
|
+
key={section.anchor}
|
|
350
|
+
onSelect={() => {
|
|
351
|
+
navigate(
|
|
352
|
+
`${buildDocDeepLink({
|
|
353
|
+
uri: target.uri,
|
|
354
|
+
view: "rendered",
|
|
355
|
+
})}#${section.anchor}`
|
|
356
|
+
);
|
|
357
|
+
onOpenChange(false);
|
|
358
|
+
}}
|
|
359
|
+
value={`${section.title} section heading outline`}
|
|
360
|
+
>
|
|
361
|
+
<SearchIcon />
|
|
362
|
+
<span>{section.title}</span>
|
|
363
|
+
<CommandShortcut>{`H${section.level}`}</CommandShortcut>
|
|
364
|
+
</CommandItem>
|
|
365
|
+
);
|
|
366
|
+
})}
|
|
367
|
+
</CommandGroup>
|
|
368
|
+
)}
|
|
369
|
+
|
|
370
|
+
{hasQuery && results.length > 0 && (
|
|
371
|
+
<CommandGroup heading="Documents">
|
|
372
|
+
{results.map((result) => (
|
|
373
|
+
<CommandItem
|
|
374
|
+
key={result.docid}
|
|
375
|
+
onSelect={() =>
|
|
376
|
+
openTarget({
|
|
377
|
+
uri: result.uri,
|
|
378
|
+
lineStart: result.snippetRange?.startLine,
|
|
379
|
+
lineEnd: result.snippetRange?.endLine,
|
|
380
|
+
})
|
|
381
|
+
}
|
|
382
|
+
value={`${result.title ?? result.uri} ${result.uri}`}
|
|
383
|
+
>
|
|
384
|
+
{loading ? (
|
|
385
|
+
<Loader2Icon className="animate-spin" />
|
|
386
|
+
) : (
|
|
387
|
+
<SearchIcon />
|
|
388
|
+
)}
|
|
389
|
+
<div className="min-w-0 flex-1">
|
|
390
|
+
<div className="truncate">{result.title || result.uri}</div>
|
|
391
|
+
<div className="truncate text-muted-foreground text-xs">
|
|
392
|
+
{result.uri}
|
|
393
|
+
</div>
|
|
394
|
+
</div>
|
|
395
|
+
{result.snippetRange && (
|
|
396
|
+
<CommandShortcut>
|
|
397
|
+
L{result.snippetRange.startLine}
|
|
398
|
+
{result.snippetRange.endLine !==
|
|
399
|
+
result.snippetRange.startLine
|
|
400
|
+
? `-${result.snippetRange.endLine}`
|
|
401
|
+
: ""}
|
|
402
|
+
</CommandShortcut>
|
|
403
|
+
)}
|
|
404
|
+
</CommandItem>
|
|
405
|
+
))}
|
|
406
|
+
</CommandGroup>
|
|
407
|
+
)}
|
|
408
|
+
|
|
409
|
+
{!hasQuery && filteredRecentItems.length > 0 && (
|
|
257
410
|
<CommandGroup heading="Recent">
|
|
258
|
-
{
|
|
411
|
+
{filteredRecentItems.map((item) => (
|
|
259
412
|
<CommandItem
|
|
260
413
|
key={item.href}
|
|
261
414
|
onSelect={() => {
|
|
262
415
|
navigate(item.href);
|
|
263
416
|
onOpenChange(false);
|
|
264
417
|
}}
|
|
265
|
-
value={item.label}
|
|
418
|
+
value={`recent-${item.href}-${item.label}`}
|
|
266
419
|
>
|
|
267
420
|
<FileTextIcon />
|
|
268
421
|
<span>{item.label}</span>
|
|
@@ -272,34 +425,34 @@ export function QuickSwitcher({
|
|
|
272
425
|
</CommandGroup>
|
|
273
426
|
)}
|
|
274
427
|
|
|
275
|
-
{!
|
|
276
|
-
(
|
|
277
|
-
|
|
428
|
+
{!hasQuery &&
|
|
429
|
+
(filteredFavoriteDocItems.length > 0 ||
|
|
430
|
+
filteredFavoriteCollectionItems.length > 0) && (
|
|
278
431
|
<>
|
|
279
432
|
<CommandSeparator />
|
|
280
433
|
<CommandGroup heading="Favorites">
|
|
281
|
-
{
|
|
434
|
+
{filteredFavoriteDocItems.map((item) => (
|
|
282
435
|
<CommandItem
|
|
283
436
|
key={item.href}
|
|
284
437
|
onSelect={() => {
|
|
285
438
|
navigate(item.href);
|
|
286
439
|
onOpenChange(false);
|
|
287
440
|
}}
|
|
288
|
-
value={`favorite-doc-${item.
|
|
441
|
+
value={`favorite-doc-${item.href}`}
|
|
289
442
|
>
|
|
290
443
|
<StarIcon />
|
|
291
444
|
<span>{item.label}</span>
|
|
292
445
|
<CommandShortcut>Doc</CommandShortcut>
|
|
293
446
|
</CommandItem>
|
|
294
447
|
))}
|
|
295
|
-
{
|
|
448
|
+
{filteredFavoriteCollectionItems.map((item) => (
|
|
296
449
|
<CommandItem
|
|
297
450
|
key={item.href}
|
|
298
451
|
onSelect={() => {
|
|
299
452
|
navigate(item.href);
|
|
300
453
|
onOpenChange(false);
|
|
301
454
|
}}
|
|
302
|
-
value={`favorite-collection-${item.
|
|
455
|
+
value={`favorite-collection-${item.href}`}
|
|
303
456
|
>
|
|
304
457
|
<FolderIcon />
|
|
305
458
|
<span>{item.label}</span>
|
|
@@ -310,7 +463,58 @@ export function QuickSwitcher({
|
|
|
310
463
|
</>
|
|
311
464
|
)}
|
|
312
465
|
|
|
313
|
-
{
|
|
466
|
+
{!hasQuery && filteredSections.length > 0 && (
|
|
467
|
+
<CommandGroup heading="Sections">
|
|
468
|
+
{filteredSections.map((section) => {
|
|
469
|
+
const target = parseDocumentDeepLink(
|
|
470
|
+
location.includes("?") ? `?${location.split("?")[1] ?? ""}` : ""
|
|
471
|
+
);
|
|
472
|
+
if (!target.uri) {
|
|
473
|
+
return null;
|
|
474
|
+
}
|
|
475
|
+
return (
|
|
476
|
+
<CommandItem
|
|
477
|
+
key={section.anchor}
|
|
478
|
+
onSelect={() => {
|
|
479
|
+
navigate(
|
|
480
|
+
`${buildDocDeepLink({
|
|
481
|
+
uri: target.uri,
|
|
482
|
+
view: "rendered",
|
|
483
|
+
})}#${section.anchor}`
|
|
484
|
+
);
|
|
485
|
+
onOpenChange(false);
|
|
486
|
+
}}
|
|
487
|
+
value={`${section.title} section heading outline`}
|
|
488
|
+
>
|
|
489
|
+
<SearchIcon />
|
|
490
|
+
<span>{section.title}</span>
|
|
491
|
+
<CommandShortcut>{`H${section.level}`}</CommandShortcut>
|
|
492
|
+
</CommandItem>
|
|
493
|
+
);
|
|
494
|
+
})}
|
|
495
|
+
</CommandGroup>
|
|
496
|
+
)}
|
|
497
|
+
|
|
498
|
+
{hasQuery && filteredRecentItems.length > 0 && (
|
|
499
|
+
<CommandGroup heading="Recent">
|
|
500
|
+
{filteredRecentItems.map((item) => (
|
|
501
|
+
<CommandItem
|
|
502
|
+
key={item.href}
|
|
503
|
+
onSelect={() => {
|
|
504
|
+
navigate(item.href);
|
|
505
|
+
onOpenChange(false);
|
|
506
|
+
}}
|
|
507
|
+
value={`recent-${item.href}-${item.label}`}
|
|
508
|
+
>
|
|
509
|
+
<FileTextIcon />
|
|
510
|
+
<span>{item.label}</span>
|
|
511
|
+
<CommandShortcut>Recent</CommandShortcut>
|
|
512
|
+
</CommandItem>
|
|
513
|
+
))}
|
|
514
|
+
</CommandGroup>
|
|
515
|
+
)}
|
|
516
|
+
|
|
517
|
+
{showCreateAction && (!hasQuery || !hasPriorityMatches) && (
|
|
314
518
|
<>
|
|
315
519
|
<CommandGroup heading="Actions">
|
|
316
520
|
{exactResult && (
|
|
@@ -338,7 +542,7 @@ export function QuickSwitcher({
|
|
|
338
542
|
<span>Create new note</span>
|
|
339
543
|
<CommandShortcut>{query.trim()}</CommandShortcut>
|
|
340
544
|
</CommandItem>
|
|
341
|
-
{
|
|
545
|
+
{matchingWorkspaceActions
|
|
342
546
|
.filter((action) =>
|
|
343
547
|
[
|
|
344
548
|
"new-note-in-context",
|
|
@@ -360,7 +564,12 @@ export function QuickSwitcher({
|
|
|
360
564
|
query.trim()
|
|
361
565
|
)
|
|
362
566
|
}
|
|
363
|
-
value={`${
|
|
567
|
+
value={`${
|
|
568
|
+
action.id === "new-note-in-context" ||
|
|
569
|
+
action.id === "new-note"
|
|
570
|
+
? `${action.label} ${action.keywords.join(" ")} ${query}`
|
|
571
|
+
: `${action.label} ${action.keywords.join(" ")}`
|
|
572
|
+
}`}
|
|
364
573
|
>
|
|
365
574
|
<FolderIcon />
|
|
366
575
|
<span>{action.label}</span>
|
|
@@ -377,7 +586,7 @@ export function QuickSwitcher({
|
|
|
377
586
|
)}
|
|
378
587
|
|
|
379
588
|
<CommandGroup heading="Go To">
|
|
380
|
-
{
|
|
589
|
+
{matchingWorkspaceActions
|
|
381
590
|
.filter((action) => action.group === "Go To" && action.available)
|
|
382
591
|
.map((action) => (
|
|
383
592
|
<CommandItem
|
|
@@ -420,78 +629,7 @@ export function QuickSwitcher({
|
|
|
420
629
|
</CommandGroup>
|
|
421
630
|
)}
|
|
422
631
|
|
|
423
|
-
{filteredSections.length > 0 && (
|
|
424
|
-
<CommandGroup heading="Sections">
|
|
425
|
-
{filteredSections.map((section) => {
|
|
426
|
-
const target = parseDocumentDeepLink(
|
|
427
|
-
location.includes("?") ? `?${location.split("?")[1] ?? ""}` : ""
|
|
428
|
-
);
|
|
429
|
-
if (!target.uri) {
|
|
430
|
-
return null;
|
|
431
|
-
}
|
|
432
|
-
return (
|
|
433
|
-
<CommandItem
|
|
434
|
-
key={section.anchor}
|
|
435
|
-
onSelect={() => {
|
|
436
|
-
navigate(
|
|
437
|
-
`${buildDocDeepLink({
|
|
438
|
-
uri: target.uri,
|
|
439
|
-
view: "rendered",
|
|
440
|
-
})}#${section.anchor}`
|
|
441
|
-
);
|
|
442
|
-
onOpenChange(false);
|
|
443
|
-
}}
|
|
444
|
-
value={`${section.title} section heading outline`}
|
|
445
|
-
>
|
|
446
|
-
<SearchIcon />
|
|
447
|
-
<span>{section.title}</span>
|
|
448
|
-
<CommandShortcut>{`H${section.level}`}</CommandShortcut>
|
|
449
|
-
</CommandItem>
|
|
450
|
-
);
|
|
451
|
-
})}
|
|
452
|
-
</CommandGroup>
|
|
453
|
-
)}
|
|
454
|
-
|
|
455
632
|
{!query.trim() && <CommandSeparator />}
|
|
456
|
-
|
|
457
|
-
{query.trim() && (
|
|
458
|
-
<CommandGroup heading="Documents">
|
|
459
|
-
{results.map((result) => (
|
|
460
|
-
<CommandItem
|
|
461
|
-
key={result.docid}
|
|
462
|
-
onSelect={() =>
|
|
463
|
-
openTarget({
|
|
464
|
-
uri: result.uri,
|
|
465
|
-
lineStart: result.snippetRange?.startLine,
|
|
466
|
-
lineEnd: result.snippetRange?.endLine,
|
|
467
|
-
})
|
|
468
|
-
}
|
|
469
|
-
value={`${result.title ?? result.uri} ${result.uri}`}
|
|
470
|
-
>
|
|
471
|
-
{loading ? (
|
|
472
|
-
<Loader2Icon className="animate-spin" />
|
|
473
|
-
) : (
|
|
474
|
-
<SearchIcon />
|
|
475
|
-
)}
|
|
476
|
-
<div className="min-w-0 flex-1">
|
|
477
|
-
<div className="truncate">{result.title || result.uri}</div>
|
|
478
|
-
<div className="truncate text-muted-foreground text-xs">
|
|
479
|
-
{result.uri}
|
|
480
|
-
</div>
|
|
481
|
-
</div>
|
|
482
|
-
{result.snippetRange && (
|
|
483
|
-
<CommandShortcut>
|
|
484
|
-
L{result.snippetRange.startLine}
|
|
485
|
-
{result.snippetRange.endLine !==
|
|
486
|
-
result.snippetRange.startLine
|
|
487
|
-
? `-${result.snippetRange.endLine}`
|
|
488
|
-
: ""}
|
|
489
|
-
</CommandShortcut>
|
|
490
|
-
)}
|
|
491
|
-
</CommandItem>
|
|
492
|
-
))}
|
|
493
|
-
</CommandGroup>
|
|
494
|
-
)}
|
|
495
633
|
</CommandList>
|
|
496
634
|
</CommandDialog>
|
|
497
635
|
);
|
|
@@ -22,6 +22,7 @@ function Command({
|
|
|
22
22
|
"flex h-full w-full flex-col overflow-hidden rounded-md bg-popover text-popover-foreground",
|
|
23
23
|
className
|
|
24
24
|
)}
|
|
25
|
+
cmdk-root=""
|
|
25
26
|
data-slot="command"
|
|
26
27
|
{...props}
|
|
27
28
|
/>
|
|
@@ -33,13 +34,17 @@ function CommandDialog({
|
|
|
33
34
|
description = "Search for a command to run...",
|
|
34
35
|
children,
|
|
35
36
|
className,
|
|
37
|
+
commandKey,
|
|
36
38
|
showCloseButton = true,
|
|
39
|
+
shouldFilter = true,
|
|
37
40
|
...props
|
|
38
41
|
}: React.ComponentProps<typeof Dialog> & {
|
|
39
42
|
title?: string;
|
|
40
43
|
description?: string;
|
|
41
44
|
className?: string;
|
|
45
|
+
commandKey?: React.Key;
|
|
42
46
|
showCloseButton?: boolean;
|
|
47
|
+
shouldFilter?: boolean;
|
|
43
48
|
}) {
|
|
44
49
|
return (
|
|
45
50
|
<Dialog {...props}>
|
|
@@ -48,10 +53,14 @@ function CommandDialog({
|
|
|
48
53
|
<DialogDescription>{description}</DialogDescription>
|
|
49
54
|
</DialogHeader>
|
|
50
55
|
<DialogContent
|
|
51
|
-
className={cn("overflow-hidden p-0", className)}
|
|
56
|
+
className={cn("overflow-hidden border-none p-0 shadow-2xl", className)}
|
|
52
57
|
showCloseButton={showCloseButton}
|
|
53
58
|
>
|
|
54
|
-
<Command
|
|
59
|
+
<Command
|
|
60
|
+
className="**:data-[slot=command-input-wrapper]:h-12 [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-group]]:px-2 [&_[cmdk-input-wrapper]_svg]:h-4 [&_[cmdk-input-wrapper]_svg]:w-4 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-1.5 [&_[cmdk-item]_svg]:h-4 [&_[cmdk-item]_svg]:w-4"
|
|
61
|
+
key={commandKey}
|
|
62
|
+
shouldFilter={shouldFilter}
|
|
63
|
+
>
|
|
55
64
|
{children}
|
|
56
65
|
</Command>
|
|
57
66
|
</DialogContent>
|
|
@@ -65,16 +74,17 @@ function CommandInput({
|
|
|
65
74
|
}: React.ComponentProps<typeof CommandPrimitive.Input>) {
|
|
66
75
|
return (
|
|
67
76
|
<div
|
|
68
|
-
className="flex h-11 items-center gap-2
|
|
77
|
+
className="flex h-11 items-center gap-2 border-border/20 border-b bg-muted/10 px-3 ring-0 shadow-none outline-none focus-within:border-border/20 focus-within:bg-background/95 focus-within:ring-0 focus-within:shadow-none focus-within:outline-none"
|
|
69
78
|
data-slot="command-input-wrapper"
|
|
70
79
|
>
|
|
71
|
-
<SearchIcon className="size-4 shrink-0
|
|
80
|
+
<SearchIcon className="size-4 shrink-0 text-muted-foreground/50" />
|
|
72
81
|
<CommandPrimitive.Input
|
|
73
82
|
className={cn(
|
|
74
|
-
"flex h-10 w-full rounded-
|
|
83
|
+
"appearance-none flex h-10 w-full rounded-none border-none bg-transparent px-0 py-3 text-sm placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50",
|
|
75
84
|
className
|
|
76
85
|
)}
|
|
77
86
|
data-slot="command-input"
|
|
87
|
+
style={{ boxShadow: "none", outline: "none" }}
|
|
78
88
|
{...props}
|
|
79
89
|
/>
|
|
80
90
|
</div>
|
|
@@ -116,7 +126,7 @@ function CommandGroup({
|
|
|
116
126
|
return (
|
|
117
127
|
<CommandPrimitive.Group
|
|
118
128
|
className={cn(
|
|
119
|
-
"overflow-hidden p-1 text-foreground [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:font-
|
|
129
|
+
"overflow-hidden p-1 text-foreground [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:font-mono [&_[cmdk-group-heading]]:text-[10px] [&_[cmdk-group-heading]]:text-muted-foreground/60 [&_[cmdk-group-heading]]:uppercase [&_[cmdk-group-heading]]:tracking-[0.15em]",
|
|
120
130
|
className
|
|
121
131
|
)}
|
|
122
132
|
data-slot="command-group"
|
|
@@ -131,7 +141,7 @@ function CommandSeparator({
|
|
|
131
141
|
}: React.ComponentProps<typeof CommandPrimitive.Separator>) {
|
|
132
142
|
return (
|
|
133
143
|
<CommandPrimitive.Separator
|
|
134
|
-
className={cn("-mx-1 h-px bg-border", className)}
|
|
144
|
+
className={cn("-mx-1 h-px bg-border/20", className)}
|
|
135
145
|
data-slot="command-separator"
|
|
136
146
|
{...props}
|
|
137
147
|
/>
|
|
@@ -145,7 +155,7 @@ function CommandItem({
|
|
|
145
155
|
return (
|
|
146
156
|
<CommandPrimitive.Item
|
|
147
157
|
className={cn(
|
|
148
|
-
"relative flex cursor-
|
|
158
|
+
"relative flex cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm data-[disabled=true]:pointer-events-none data-[disabled=true]:cursor-not-allowed data-[disabled=true]:opacity-50 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0",
|
|
149
159
|
className
|
|
150
160
|
)}
|
|
151
161
|
data-slot="command-item"
|
|
@@ -161,7 +171,7 @@ function CommandShortcut({
|
|
|
161
171
|
return (
|
|
162
172
|
<span
|
|
163
173
|
className={cn(
|
|
164
|
-
"ml-auto text-muted-foreground
|
|
174
|
+
"ml-auto font-mono text-[10px] text-muted-foreground/50 tabular-nums",
|
|
165
175
|
className
|
|
166
176
|
)}
|
|
167
177
|
data-slot="command-shortcut"
|
|
@@ -58,7 +58,7 @@ function DialogContent({
|
|
|
58
58
|
<DialogOverlay />
|
|
59
59
|
<DialogPrimitive.Content
|
|
60
60
|
className={cn(
|
|
61
|
-
"data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border bg-[#0f1115] p-6 shadow-lg outline-none duration-200 data-[state=closed]:animate-out data-[state=open]:animate-in sm:max-w-lg",
|
|
61
|
+
"data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border border-border/40 bg-[#0f1115] p-6 shadow-lg outline-none duration-200 data-[state=closed]:animate-out data-[state=open]:animate-in sm:max-w-lg",
|
|
62
62
|
className
|
|
63
63
|
)}
|
|
64
64
|
data-slot="dialog-content"
|