@@ -4,6 +4,11 @@ import type { Hit } from "@algolia/client-search";
4
4
import Link from "@docusaurus/Link" ;
5
5
import SearchIcon from "/img/icons/search.svg" ;
6
6
import CloseIcon from "/img/icons/x.svg" ;
7
+ import HashIcon from "/img/icons/hash.svg" ;
8
+ import GithubIcon from "/img/icons/github.svg" ;
9
+ import FileIcon from "/img/icons/file.svg" ;
10
+ import TerminalIcon from "/img/icons/terminal.svg" ;
11
+ import CodeIcon from "/img/icons/code.svg" ;
7
12
import { createContext , useCallback , useContext , useEffect , useMemo , useRef , useState } from "react" ;
8
13
import { search , SearchResult } from "../lib" ;
9
14
@@ -70,17 +75,20 @@ function SearchModal() {
70
75
const [ searchQuery , setSearchQuery ] = useState ( "" ) ;
71
76
const { isModalOpen, setIsModalOpen } = useContext ( SearchButtonContext ) ;
72
77
const [ selectedTab , setSelectedTab ] = useState ( "all" ) ;
73
- const tabsRef = useRef < HTMLElement [ ] > ( new Array ( 5 ) . fill ( null ) ) ;
78
+ const tabsRef = useRef < HTMLElement [ ] > ( [ ] ) ;
74
79
75
80
const onKeyDown = useCallback ( ( event : KeyboardEvent ) => {
81
+ if ( ! tabsRef . current ) return ;
76
82
if ( ! event . ctrlKey ) return ;
77
83
78
- if ( [ "1" , "2" , "3" , "4" , "5" ] . includes ( event . key ) ) {
84
+ const numericKeys = tabsRef . current . map ( ( _ , index ) => `${ index + 1 } ` ) ;
85
+ if ( numericKeys . includes ( event . key ) ) {
79
86
const tabElement = tabsRef . current [ Number ( event . key ) - 1 ] ;
80
87
if ( ! tabElement ) return ;
81
88
const tabValue = tabElement . getAttribute ( "data-value" ) ;
82
89
if ( ! tabValue ) return ;
83
90
setSelectedTab ( tabValue ) ;
91
+ return ;
84
92
}
85
93
86
94
if ( event . key === "]" ) {
@@ -91,6 +99,7 @@ function SearchModal() {
91
99
const nextTabValue = nextTabElement . getAttribute ( "data-value" ) ;
92
100
if ( ! nextTabValue ) return ;
93
101
setSelectedTab ( nextTabValue ) ;
102
+ return ;
94
103
}
95
104
96
105
if ( event . key === "[" ) {
@@ -102,6 +111,7 @@ function SearchModal() {
102
111
const previousTabValue = previousTabElement . getAttribute ( "data-value" ) ;
103
112
if ( ! previousTabValue ) return ;
104
113
setSelectedTab ( previousTabValue ) ;
114
+ return ;
105
115
}
106
116
} , [ ] ) ;
107
117
@@ -161,60 +171,26 @@ function SearchModal() {
161
171
</ Box >
162
172
< Tabs . Root value = { selectedTab } onValueChange = { setSelectedTab } >
163
173
< Tabs . List wrap = "wrap" className = "search-modal__tabs-list" >
164
- < Tabs . Trigger
165
- key = "all"
166
- value = "all"
167
- data-value = "all"
168
- ref = { ( el ) => {
169
- tabsRef . current [ 0 ] = el ;
170
- } }
171
- >
172
- All
173
- </ Tabs . Trigger >
174
- < Tabs . Trigger
175
- key = "tutorial"
176
- value = "tutorial"
177
- data-value = "tutorial"
178
- ref = { ( el ) => {
179
- tabsRef . current [ 1 ] = el ;
180
- } }
181
- >
182
- Tutorials
183
- </ Tabs . Trigger >
184
- < Tabs . Trigger
185
- key = "guide"
186
- value = "guide"
187
- data-value = "guide"
188
- ref = { ( el ) => {
189
- tabsRef . current [ 2 ] = el ;
190
- } }
191
- >
192
- Guides
193
- </ Tabs . Trigger >
194
- < Tabs . Trigger
195
- key = "sdk-reference"
196
- value = "sdk-reference"
197
- data-value = "sdk-reference"
198
- ref = { ( el ) => {
199
- tabsRef . current [ 3 ] = el ;
200
- } }
201
- >
202
- SDK References
203
- </ Tabs . Trigger >
204
- < Tabs . Trigger
205
- key = "api-reference"
206
- value = "api-reference"
207
- data-value = "api-reference"
208
- ref = { ( el ) => {
209
- tabsRef . current [ 4 ] = el ;
210
- } }
211
- >
212
- API References
213
- </ Tabs . Trigger >
174
+ { [
175
+ { name : "all" , label : "All" } ,
176
+ { name : "documentation" , label : "Documentation" } ,
177
+ { name : "sdk-reference" , label : "SDK References" } ,
178
+ { name : "api-reference" , label : "API References" } ,
179
+ ] . map ( ( tab , index ) => (
180
+ < Tabs . Trigger
181
+ key = { tab . name }
182
+ value = { tab . name }
183
+ data-value = { tab . name }
184
+ ref = { ( el ) => {
185
+ tabsRef . current [ index ] = el ;
186
+ } }
187
+ >
188
+ { tab . label }
189
+ </ Tabs . Trigger >
190
+ ) ) }
214
191
</ Tabs . List >
215
192
< AllSearchResultsTabContent />
216
- < GuidesSearchResultsTabContent />
217
- < TutorialsSearchResultsTabContent />
193
+ < DocumentationSearchResultsTabContent />
218
194
< SDKReferencesSearchResultsTabContent />
219
195
< APIReferencesSearchResultsTabContent />
220
196
</ Tabs . Root >
@@ -224,7 +200,6 @@ function SearchModal() {
224
200
}
225
201
226
202
function AllSearchResultsTabContent ( ) {
227
- const { query } = useContext ( SearchModalContext ) ;
228
203
const searchFn = useCallback ( async ( searchQuery : string ) => {
229
204
return search ( searchQuery ) ;
230
205
} , [ ] ) ;
@@ -238,40 +213,25 @@ function AllSearchResultsTabContent() {
238
213
) ;
239
214
}
240
215
241
- function GuidesSearchResultsTabContent ( ) {
242
- const { query } = useContext ( SearchModalContext ) ;
243
- const searchFn = useCallback ( async ( searchQuery : string ) => {
244
- return search ( searchQuery , [ "supertokens_documentation" ] , "guide" ) ;
245
- } , [ ] ) ;
246
-
247
- return (
248
- < SearchProvider searchFn = { searchFn } >
249
- < Tabs . Content value = "guide" >
250
- < SearchResultsList />
251
- </ Tabs . Content >
252
- </ SearchProvider >
253
- ) ;
254
- }
255
-
256
- function TutorialsSearchResultsTabContent ( ) {
257
- const { query } = useContext ( SearchModalContext ) ;
216
+ function DocumentationSearchResultsTabContent ( ) {
258
217
const searchFn = useCallback ( async ( searchQuery : string ) => {
259
- return search ( searchQuery , [ "supertokens_documentation" ] , "tutorial" ) ;
218
+ return search ( searchQuery , [
219
+ { indexName : "supertokens_documentation" , facetFilters : [ [ "type:guide" , "type:tutorial" ] ] } ,
220
+ ] ) ;
260
221
} , [ ] ) ;
261
222
262
223
return (
263
224
< SearchProvider searchFn = { searchFn } >
264
- < Tabs . Content value = "tutorial " >
225
+ < Tabs . Content value = "documentation " >
265
226
< SearchResultsList />
266
227
</ Tabs . Content >
267
228
</ SearchProvider >
268
229
) ;
269
230
}
270
231
271
232
function SDKReferencesSearchResultsTabContent ( ) {
272
- const { query } = useContext ( SearchModalContext ) ;
273
233
const searchFn = useCallback ( async ( searchQuery : string ) => {
274
- return search ( searchQuery , [ "supertokens_documentation" ] , " sdk-reference") ;
234
+ return search ( searchQuery , [ { indexName : "supertokens_documentation" , facetFilters : [ "type: sdk-reference"] } ] ) ;
275
235
} , [ ] ) ;
276
236
277
237
return (
@@ -284,9 +244,8 @@ function SDKReferencesSearchResultsTabContent() {
284
244
}
285
245
286
246
function APIReferencesSearchResultsTabContent ( ) {
287
- const { query } = useContext ( SearchModalContext ) ;
288
247
const searchFn = useCallback ( async ( searchQuery : string ) => {
289
- return search ( searchQuery , [ "supertokens_documentation" ] , " api-reference") ;
248
+ return search ( searchQuery , [ { indexName : "supertokens_documentation" , facetFilters : [ "type: api-reference"] } ] ) ;
290
249
} , [ ] ) ;
291
250
292
251
return (
@@ -298,16 +257,6 @@ function APIReferencesSearchResultsTabContent() {
298
257
) ;
299
258
}
300
259
301
- function NoResultsTabContent ( ) {
302
- return (
303
- < Box className = "search-modal__no-results" >
304
- < Text size = "7" color = "gray" >
305
- No results found
306
- </ Text >
307
- </ Box >
308
- ) ;
309
- }
310
-
311
260
type SearchContextType = {
312
261
searchResults : SearchResult [ ] | null ;
313
262
searchState : "idle" | "loading" | "error" | "fetched" ;
@@ -466,10 +415,27 @@ function SearchResultsList() {
466
415
) ;
467
416
}
468
417
418
+ type SearchResultItemType = "page-title" | "page-heading" | "api-reference" | "sdk-reference" | "github-page" ;
419
+
420
+ TerminalIcon ;
421
+ const SearchResultItemTypeIcons : Record < SearchResultItemType , React . ComponentType < React . SVGProps < SVGElement > > > = {
422
+ "page-title" : FileIcon ,
423
+ "page-heading" : HashIcon ,
424
+ "api-reference" : TerminalIcon ,
425
+ "sdk-reference" : CodeIcon ,
426
+ "github-page" : GithubIcon ,
427
+ } ;
428
+
469
429
function SearchResultListItem ( { result } : { result : SearchResult } ) {
470
430
const ref = useRef < HTMLLIElement > ( null ) ;
471
431
const { interactionMode, setInteractionMode } = useContext ( SearchResultListContext ) ;
472
432
const { onCloseModal } = useContext ( SearchModalContext ) ;
433
+ const searchResultItemType = useMemo ( ( ) => {
434
+ if ( result . type === "sdk-reference" ) return "sdk-reference" ;
435
+ if ( result . type === "api-reference" ) return "api-reference" ;
436
+ if ( result . hierarchy . length === 1 ) return "page-title" ;
437
+ return "page-heading" ;
438
+ } , [ result ] ) ;
473
439
const breadcrumbs = useMemo ( ( ) => {
474
440
if ( ! result . hierarchy ) return undefined ;
475
441
return result . hierarchy . join ( " › " ) ;
@@ -516,6 +482,8 @@ function SearchResultListItem({ result }: { result: SearchResult }) {
516
482
return result . url ;
517
483
} , [ result ] ) ;
518
484
485
+ const Icon = SearchResultItemTypeIcons [ searchResultItemType ] ;
486
+
519
487
return (
520
488
< li
521
489
className = "search-modal__item"
@@ -525,17 +493,22 @@ function SearchResultListItem({ result }: { result: SearchResult }) {
525
493
onMouseMove = { onMouseMove }
526
494
>
527
495
< Link href = { urlOrPath } onClick = { onClick } className = "reset-link" >
528
- < Flex direction = "column" gap = "2" p = "2" className = "search-result-item" >
529
- < Text
530
- className = "search-modal__item-highlight"
531
- as = "div"
532
- size = "3"
533
- m = "0"
534
- dangerouslySetInnerHTML = { { __html : result . highlight } }
535
- />
536
- < Text className = "search-result__item-breadcrumbs" as = "div" size = "2" color = "gray" trim = "both" >
537
- { breadcrumbs }
538
- </ Text >
496
+ < Flex direction = "row" gap = "1" >
497
+ < Flex align = "center" className = "search-modal__item-icon" >
498
+ < Icon width = "20px" height = "20px" />
499
+ </ Flex >
500
+ < Flex direction = "column" gap = "2" p = "2" className = "search-modal__item-content" >
501
+ < Text
502
+ className = "search-modal__item-highlight"
503
+ as = "div"
504
+ size = "3"
505
+ m = "0"
506
+ dangerouslySetInnerHTML = { { __html : result . highlight } }
507
+ />
508
+ < Text className = "search-modal__item-breadcrumbs" as = "div" size = "2" color = "gray" trim = "both" >
509
+ { breadcrumbs }
510
+ </ Text >
511
+ </ Flex >
539
512
</ Flex >
540
513
</ Link >
541
514
</ li >
0 commit comments