Skip to content

Commit 166e7bc

Browse files
wip on adding hotkey support for navigation
1 parent bf85c62 commit 166e7bc

2 files changed

Lines changed: 71 additions & 30 deletions

File tree

src/app/globals.css

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,4 +66,14 @@
6666
body {
6767
@apply bg-background text-foreground;
6868
}
69+
}
70+
71+
.cm-editor .cm-gutters {
72+
background-color: transparent;
73+
border-right: none;
74+
}
75+
76+
.cm-editor .cm-lineNumbers .cm-gutterElement {
77+
padding-left: 0.5;
78+
text-align: left;
6979
}

src/app/search/searchResultsPanel.tsx

Lines changed: 61 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import { Scrollbar } from "@radix-ui/react-scroll-area";
1313
import CodeMirror, { Decoration, DecorationSet, EditorState, EditorView, ReactCodeMirrorRef, StateField, Transaction } from '@uiw/react-codemirror';
1414
import clsx from "clsx";
1515
import Image from "next/image";
16-
import { useMemo, useRef, useState } from "react";
16+
import { useCallback, useMemo, useRef, useState } from "react";
1717

1818
const MAX_MATCHES_TO_PREVIEW = 3;
1919

@@ -38,9 +38,11 @@ export const SearchResultsPanel = ({
3838
}
3939

4040
return (
41-
<ScrollArea className="h-full">
41+
<ScrollArea
42+
className="h-full"
43+
>
4244
{fileMatches.map((fileMatch, index) => (
43-
<FilePreview
45+
<FileMatchContainer
4446
key={index}
4547
file={fileMatch}
4648
onOpenFile={() => {
@@ -56,17 +58,17 @@ export const SearchResultsPanel = ({
5658
)
5759
}
5860

59-
interface FilePreviewProps {
61+
interface FileMatchContainerProps {
6062
file: SearchResultFile;
6163
onOpenFile: () => void;
6264
onMatchIndexChanged: (matchIndex: number) => void;
6365
}
6466

65-
const FilePreview = ({
67+
const FileMatchContainer = ({
6668
file,
6769
onOpenFile,
6870
onMatchIndexChanged,
69-
}: FilePreviewProps) => {
71+
}: FileMatchContainerProps) => {
7072

7173
const [showAll, setShowAll] = useState(false);
7274
const matchCount = useMemo(() => {
@@ -124,6 +126,19 @@ const FilePreview = ({
124126
return matchCount > MAX_MATCHES_TO_PREVIEW;
125127
}, [matchCount]);
126128

129+
const onShowMoreMatches = useCallback(() => {
130+
setShowAll(!showAll);
131+
}, [showAll]);
132+
133+
const onOpenMatch = useCallback((index: number) => {
134+
const matchIndex = matches.slice(0, index).reduce((acc, match) => {
135+
return acc + match.Ranges.length;
136+
}, 0);
137+
onOpenFile();
138+
onMatchIndexChanged(matchIndex);
139+
}, [matches, onMatchIndexChanged, onOpenFile]);
140+
141+
127142
return (
128143
<div>
129144
<div
@@ -148,7 +163,7 @@ const FilePreview = ({
148163
</span>
149164
<span>·</span>
150165
{!fileNameRange ? (
151-
<span>{file.FileName}</span>
166+
<span>{file.FileName}</span>
152167
) : (
153168
<span>
154169
{file.FileName.slice(0, fileNameRange.from)}
@@ -173,31 +188,45 @@ const FilePreview = ({
173188
return (
174189
<div
175190
key={index}
176-
className="cursor-pointer"
177-
onClick={() => {
178-
const matchIndex = matches.slice(0, index).reduce((acc, match) => {
179-
return acc + match.Ranges.length;
180-
}, 0);
181-
onOpenFile();
182-
onMatchIndexChanged(matchIndex);
183-
}}
184191
>
185-
<CodePreview
186-
content={content}
187-
language={file.Language}
188-
ranges={match.Ranges}
189-
lineOffset={lineOffset}
190-
/>
192+
<div
193+
tabIndex={0}
194+
className="cursor-pointer p-1 focus:ring-inset focus:ring-4 bg-white dark:bg-[#282c34]"
195+
onKeyDown={(e) => {
196+
if (e.key !== "Enter") {
197+
return;
198+
}
199+
onOpenMatch(index);
200+
}}
201+
onClick={() => onOpenMatch(index)}
202+
>
203+
<CodePreview
204+
content={content}
205+
language={file.Language}
206+
ranges={match.Ranges}
207+
lineOffset={lineOffset}
208+
/>
209+
</div>
210+
191211
{(index !== matches.length - 1 || isMoreContentButtonVisible) && (
192212
<Separator className="dark:bg-gray-400" />
193213
)}
194214
</div>
195215
);
196216
})}
197217
{isMoreContentButtonVisible && (
198-
<div className="px-4 bg-accent">
218+
<div
219+
tabIndex={0}
220+
className="px-4 bg-accent p-0.5"
221+
onKeyDown={(e) => {
222+
if (e.key !== "Enter") {
223+
return;
224+
}
225+
onShowMoreMatches();
226+
}}
227+
onClick={onShowMoreMatches}
228+
>
199229
<p
200-
onClick={() => setShowAll(!showAll)}
201230
className="text-blue-500 cursor-pointer text-sm flex flex-row items-center gap-2"
202231
>
203232
{showAll ? <DoubleArrowUpIcon className="w-3 h-3" /> : <DoubleArrowDownIcon className="w-3 h-3" />}
@@ -222,17 +251,19 @@ const cmTheme = EditorView.baseTheme({
222251
},
223252
});
224253

254+
interface CodePreviewProps {
255+
content: string,
256+
language: string,
257+
ranges: SearchResultRange[],
258+
lineOffset: number,
259+
}
260+
225261
const CodePreview = ({
226262
content,
227263
language,
228264
ranges,
229265
lineOffset,
230-
}: {
231-
content: string,
232-
language: string,
233-
ranges: SearchResultRange[],
234-
lineOffset: number,
235-
}) => {
266+
}: CodePreviewProps) => {
236267
const editorRef = useRef<ReactCodeMirrorRef>(null);
237268
const { theme } = useThemeNormalized();
238269

@@ -251,7 +282,7 @@ const CodePreview = ({
251282
.filter(({ Start, End }) => {
252283
const startLine = Start.LineNumber - lineOffset;
253284
const endLine = End.LineNumber - lineOffset;
254-
285+
255286
if (
256287
startLine < 1 ||
257288
endLine < 1 ||

0 commit comments

Comments
 (0)