1
+ <script setup lang="ts">
2
+ import ' @docsearch/css'
3
+ import docsearch from ' @docsearch/js'
4
+ import { useRoute , useRouter , useData } from ' vitepress'
5
+ import { getCurrentInstance , onMounted , watch } from ' vue'
6
+ import type { DefaultTheme } from ' ../config'
7
+ import type { DocSearchHit } from ' @docsearch/react/dist/esm/types'
8
+ const props = defineProps <{
9
+ options: DefaultTheme .AlgoliaSearchOptions
10
+ multilang? : boolean
11
+ }>()
12
+ const vm = getCurrentInstance ()
13
+ const route = useRoute ()
14
+ const router = useRouter ()
15
+ watch (
16
+ () => props .options ,
17
+ (value ) => {
18
+ update (value )
19
+ }
20
+ )
21
+ onMounted (() => {
22
+ initialize (props .options )
23
+ })
24
+ function isSpecialClick(event : MouseEvent ) {
25
+ return (
26
+ event .button === 1 ||
27
+ event .altKey ||
28
+ event .ctrlKey ||
29
+ event .metaKey ||
30
+ event .shiftKey
31
+ )
32
+ }
33
+ function getRelativePath(absoluteUrl : string ) {
34
+ const { pathname, hash } = new URL (absoluteUrl )
35
+ return pathname + hash
36
+ }
37
+ function update(options : any ) {
38
+ if (vm && vm .vnode .el ) {
39
+ vm .vnode .el .innerHTML =
40
+ ' <div class="algolia-search-box" id="docsearch"></div>'
41
+ initialize (options )
42
+ }
43
+ }
44
+ const { lang } = useData ()
45
+ // if the user has multiple locales, the search results should be filtered
46
+ // based on the language
47
+ const facetFilters: string [] = props .multilang ? [' lang:' + lang .value ] : []
48
+ if (props .options .searchParameters ?.facetFilters ) {
49
+ facetFilters .push (... props .options .searchParameters .facetFilters )
50
+ }
51
+ watch (lang , (newLang , oldLang ) => {
52
+ const index = facetFilters .findIndex ((filter ) => filter === ' lang:' + oldLang )
53
+ if (index > - 1 ) {
54
+ facetFilters .splice (index , 1 , ' lang:' + newLang )
55
+ }
56
+ })
57
+ function initialize(userOptions : any ) {
58
+ docsearch (
59
+ Object .assign ({}, userOptions , {
60
+ container: ' #docsearch' ,
61
+ searchParameters: Object .assign ({}, userOptions .searchParameters , {
62
+ // pass a custom lang facetFilter to allow multiple language search
63
+ // https://github.com/algolia/docsearch-configs/pull/3942
64
+ facetFilters
65
+ }),
66
+ navigator: {
67
+ navigate : ({ itemUrl }: { itemUrl: string }) => {
68
+ const { pathname : hitPathname } = new URL (
69
+ window .location .origin + itemUrl
70
+ )
71
+ // Router doesn't handle same-page navigation so we use the native
72
+ // browser location API for anchor navigation
73
+ if (route .path === hitPathname ) {
74
+ window .location .assign (window .location .origin + itemUrl )
75
+ } else {
76
+ router .go (itemUrl )
77
+ }
78
+ }
79
+ },
80
+ transformItems : (items : DocSearchHit []) => {
81
+ return items .map ((item ) => {
82
+ return Object .assign ({}, item , {
83
+ url: getRelativePath (item .url )
84
+ })
85
+ })
86
+ },
87
+ hitComponent : ({
88
+ hit ,
89
+ children
90
+ }: {
91
+ hit: DocSearchHit
92
+ children: any
93
+ }) => {
94
+ const relativeHit = hit .url .startsWith (' http' )
95
+ ? getRelativePath (hit .url as string )
96
+ : hit .url
97
+ return {
98
+ type: ' a' ,
99
+ ref: undefined ,
100
+ constructor: undefined ,
101
+ key: undefined ,
102
+ props: {
103
+ href: hit .url ,
104
+ onClick : (event : MouseEvent ) => {
105
+ if (isSpecialClick (event )) {
106
+ return
107
+ }
108
+ // we rely on the native link scrolling when user is already on
109
+ // the right anchor because Router doesn't support duplicated
110
+ // history entries
111
+ if (route .path === relativeHit ) {
112
+ return
113
+ }
114
+ // if the hits goes to another page, we prevent the native link
115
+ // behavior to leverage the Router loading feature
116
+ if (route .path !== relativeHit ) {
117
+ event .preventDefault ()
118
+ }
119
+ router .go (relativeHit )
120
+ },
121
+ children
122
+ },
123
+ __v: null
124
+ }
125
+ }
126
+ })
127
+ )
128
+ }
129
+ </script >
130
+
131
+ <template >
132
+ <div class =" algolia-search-box" id =" docsearch" />
133
+ </template >
134
+
135
+ <style >
136
+ .algolia-search-box {
137
+ padding-top : 1px ;
138
+ }
139
+ @media (min-width : 720px ) {
140
+ .algolia-search-box {
141
+ padding-left : 8px ;
142
+ }
143
+ }
144
+ @media (min-width : 751px ) {
145
+ .algolia-search-box {
146
+ min-width : 176.3px ; /* avoid layout shift */
147
+ }
148
+ .algolia-search-box .DocSearch-Button-Placeholder {
149
+ padding-left : 8px ;
150
+ font-size : 0.9rem ;
151
+ font-weight : 500 ;
152
+ }
153
+ }
154
+ body .DocSearch {
155
+ --docsearch-primary-color : var (--c-brand );
156
+ --docsearch-modal-background : var (--c-white );
157
+ --docsearch-hit-background : var (--c-white-dark );
158
+ --docsearch-searchbox-focus-background : var (--c-white-dark );
159
+ --docsearch-highlight-color : var (--docsearch-primary-color );
160
+ --docsearch-searchbox-shadow : inset 0 0 0 2px var (--c-text-lighter );
161
+ --docsearch-hit-shadow : 0 1px 3px 0 var (--c-white );
162
+ --docsearch-text-color : var (--c-text );
163
+ --docsearch-muted-color : var (--c-text-dark-1 );
164
+ --docsearch-searchbox-background : var (--c-white );
165
+ --docsearch-footer-background : var (--c-white );
166
+ --docsearch-modal-shadow : 0 3px 8px 0 var (--c-white-dark );
167
+ --docsearch-hit-color : var (--c-text );
168
+ --docsearch-footer-shadow : 0 -1px 0 0 var (--c-white-dark );
169
+ --docsearch-key-gradient : linear-gradient (-225deg ,var (--c-white-dark ),var (--c-white ));
170
+ --docsearch-key-shadow : inset 0 -2px 0 0 var (--c-white-dark ),inset 0 0 1px 1px var (--c-white ),0 1px 2px 1px var (--c-white-darker );
171
+ }
172
+ </style >
0 commit comments