@@ -11,6 +11,14 @@ const INDEX_NAME = 'tailwindcss'
11
11
const API_KEY = '5fc87cef58bb80203d2207578309fab6'
12
12
const APP_ID = 'KNPXZI5B0M'
13
13
14
+ function isTailwindUIURL ( url ) {
15
+ return url . startsWith ( 'https://tailwindui.com' )
16
+ }
17
+
18
+ function isExternalURL ( url ) {
19
+ return url . startsWith ( 'https://' )
20
+ }
21
+
14
22
const SearchContext = createContext ( )
15
23
16
24
export function SearchProvider ( { children } ) {
@@ -40,6 +48,22 @@ export function SearchProvider({ children }) {
40
48
onClose,
41
49
} )
42
50
51
+ useEffect ( ( ) => {
52
+ // Prepend "Components" to Tailwind UI results that are shown in the "recent" view
53
+ if ( ! isOpen ) {
54
+ let key = `__DOCSEARCH_RECENT_SEARCHES__${ INDEX_NAME } `
55
+ try {
56
+ let data = JSON . parse ( window . localStorage . getItem ( key ) )
57
+ for ( let item of data ) {
58
+ if ( isTailwindUIURL ( item . url ) && ! item . hierarchy . lvl1 . startsWith ( 'Components' ) ) {
59
+ item . hierarchy . lvl1 = `Components / ${ item . hierarchy . lvl1 } `
60
+ }
61
+ }
62
+ window . localStorage . setItem ( key , JSON . stringify ( data ) )
63
+ } catch { }
64
+ }
65
+ } , [ isOpen ] )
66
+
43
67
return (
44
68
< >
45
69
< Head >
@@ -57,59 +81,97 @@ export function SearchProvider({ children }) {
57
81
</ SearchContext . Provider >
58
82
{ isOpen &&
59
83
createPortal (
60
- < DocSearchModal
61
- initialQuery = { initialQuery }
62
- initialScrollY = { window . scrollY }
63
- searchParameters = { {
64
- facetFilters : 'version:v3' ,
65
- distinct : 1 ,
84
+ < div
85
+ onClick = { ( event ) => {
86
+ let link = event . target . closest ( 'a' )
87
+ if ( ! link ) return
88
+ if ( isExternalURL ( link . href ) && link . target !== '_blank' ) {
89
+ event . preventDefault ( )
90
+ window . open ( link . href , '_blank' )
91
+ }
66
92
} }
67
- placeholder = "Search documentation"
68
- onClose = { onClose }
69
- indexName = { INDEX_NAME }
70
- apiKey = { API_KEY }
71
- appId = { APP_ID }
72
- navigator = { {
73
- navigate ( { itemUrl } ) {
74
- setIsOpen ( false )
75
- router . push ( itemUrl )
76
- } ,
77
- } }
78
- hitComponent = { Hit }
79
- transformItems = { ( items ) => {
80
- return items . map ( ( item , index ) => {
81
- // We transform the absolute URL into a relative URL to
82
- // leverage Next's preloading.
83
- const a = document . createElement ( 'a' )
84
- a . href = item . url
85
-
86
- const hash = a . hash === '#content-wrapper' || a . hash === '#header' ? '' : a . hash
87
-
88
- if ( item . hierarchy ?. lvl0 ) {
89
- item . hierarchy . lvl0 = item . hierarchy . lvl0 . replace ( / & a m p ; / g, '&' )
90
- }
91
-
92
- if ( item . _highlightResult ?. hierarchy ?. lvl0 ?. value ) {
93
- item . _highlightResult . hierarchy . lvl0 . value =
94
- item . _highlightResult . hierarchy . lvl0 . value . replace ( / & a m p ; / g, '&' )
95
- }
96
-
97
- return {
98
- ...item ,
99
- url : `${ a . pathname } ${ hash } ` ,
100
- __is_result : ( ) => true ,
101
- __is_parent : ( ) => item . type === 'lvl1' && items . length > 1 && index === 0 ,
102
- __is_child : ( ) =>
103
- item . type !== 'lvl1' &&
104
- items . length > 1 &&
105
- items [ 0 ] . type === 'lvl1' &&
106
- index !== 0 ,
107
- __is_first : ( ) => index === 1 ,
108
- __is_last : ( ) => index === items . length - 1 && index !== 0 ,
109
- }
110
- } )
111
- } }
112
- /> ,
93
+ >
94
+ < DocSearchModal
95
+ initialQuery = { initialQuery }
96
+ initialScrollY = { window . scrollY }
97
+ searchParameters = { {
98
+ facetFilters : 'version:v3' ,
99
+ distinct : 1 ,
100
+ attributesToRetrieve : [
101
+ 'hierarchy.lvl0' ,
102
+ 'hierarchy.lvl1' ,
103
+ 'hierarchy.lvl2' ,
104
+ 'hierarchy.lvl3' ,
105
+ 'hierarchy.lvl4' ,
106
+ 'hierarchy.lvl5' ,
107
+ 'hierarchy.lvl6' ,
108
+ 'content' ,
109
+ 'type' ,
110
+ 'url' ,
111
+ 'product' ,
112
+ 'product_category' ,
113
+ ] ,
114
+ } }
115
+ placeholder = "Search documentation"
116
+ onClose = { onClose }
117
+ indexName = { INDEX_NAME }
118
+ apiKey = { API_KEY }
119
+ appId = { APP_ID }
120
+ navigator = { {
121
+ navigate ( { itemUrl } ) {
122
+ setIsOpen ( false )
123
+ if ( isExternalURL ( itemUrl ) ) {
124
+ window . open ( itemUrl , '_blank' )
125
+ } else {
126
+ router . push ( itemUrl )
127
+ }
128
+ } ,
129
+ } }
130
+ hitComponent = { Hit }
131
+ transformItems = { ( items ) => {
132
+ return items . map ( ( item , index ) => {
133
+ // We transform the absolute URL into a relative URL to
134
+ // leverage Next's preloading.
135
+ const a = document . createElement ( 'a' )
136
+ a . href = item . url
137
+
138
+ const hash = a . hash === '#content-wrapper' || a . hash === '#header' ? '' : a . hash
139
+
140
+ if ( item . hierarchy ?. lvl0 ) {
141
+ item . hierarchy . lvl0 = item . hierarchy . lvl0 . replace ( / & a m p ; / g, '&' )
142
+ }
143
+
144
+ if ( item . _highlightResult ?. hierarchy ?. lvl0 ?. value ) {
145
+ item . _highlightResult . hierarchy . lvl0 . value =
146
+ item . _highlightResult . hierarchy . lvl0 . value . replace ( / & a m p ; / g, '&' )
147
+ }
148
+
149
+ let isTailwindUI = isTailwindUIURL ( item . url )
150
+
151
+ return {
152
+ ...item ,
153
+ hierarchy : {
154
+ ...item . hierarchy ,
155
+ ...( isTailwindUI
156
+ ? { lvl1 : `${ item . product } / ${ item . product_category } ` }
157
+ : { } ) ,
158
+ } ,
159
+ url : isTailwindUI ? item . url . split ( '#' ) [ 0 ] : `${ a . pathname } ${ hash } ` ,
160
+ __is_result : ( ) => true ,
161
+ __is_parent : ( ) => item . type === 'lvl1' && items . length > 1 && index === 0 ,
162
+ __is_child : ( ) =>
163
+ item . type !== 'lvl1' &&
164
+ items . length > 1 &&
165
+ items [ 0 ] . type === 'lvl1' &&
166
+ index !== 0 ,
167
+ __is_first : ( ) => index === 1 ,
168
+ __is_last : ( ) => index === items . length - 1 && index !== 0 ,
169
+ __is_tailwindui : ( ) => isTailwindUI ,
170
+ }
171
+ } )
172
+ } }
173
+ />
174
+ </ div > ,
113
175
document . body
114
176
) }
115
177
</ >
@@ -120,12 +182,14 @@ function Hit({ hit, children }) {
120
182
return (
121
183
< Link
122
184
href = { hit . url }
185
+ target = { hit . __is_tailwindui ?. ( ) ? '_blank' : undefined }
123
186
className = { clsx ( {
124
187
'DocSearch-Hit--Result' : hit . __is_result ?. ( ) ,
125
188
'DocSearch-Hit--Parent' : hit . __is_parent ?. ( ) ,
126
189
'DocSearch-Hit--FirstChild' : hit . __is_first ?. ( ) ,
127
190
'DocSearch-Hit--LastChild' : hit . __is_last ?. ( ) ,
128
191
'DocSearch-Hit--Child' : hit . __is_child ?. ( ) ,
192
+ 'DocSearch-Hit--TailwindUI' : hit . __is_tailwindui ?. ( ) ,
129
193
} ) }
130
194
>
131
195
{ children }
0 commit comments