@voidzero-dev/vitepress-theme 4.4.1 → 4.5.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 +6 -4
- package/src/components/oss/Header.vue +1 -1
- package/src/components/vitepress-default/VPAlgoliaSearchBox.vue +211 -106
- package/src/components/vitepress-default/VPLocalSearchBox.vue +11 -33
- package/src/components/vitepress-default/VPMenuLink.vue +2 -1
- package/src/components/vitepress-default/VPNavBar.vue +14 -20
- package/src/components/vitepress-default/VPNavBarAskAiButton.vue +31 -0
- package/src/components/vitepress-default/VPNavBarExtra.vue +7 -1
- package/src/components/vitepress-default/VPNavBarSearch.vue +119 -70
- package/src/components/vitepress-default/VPNavBarSearchButton.vue +43 -152
- package/src/components/vitepress-default/VPNavBarTranslations.vue +7 -1
- package/src/components/vitepress-default/VPNavScreen.vue +1 -3
- package/src/shims.d.ts +10 -0
- package/src/styles/base.css +2 -0
- package/src/styles/vitepress-default/base-scoped.css +2 -0
- package/src/styles/vitepress-default/base.css +2 -0
- package/src/styles/vitepress-default/docsearch.css +120 -0
- package/src/styles/vitepress-default/icons.css +4 -1
- package/src/styles/vitepress-default/vars.css +5 -1
- package/src/support/vitepress-default/docsearch.ts +253 -0
- package/src/support/vitepress-default/reactivity.ts +14 -0
- package/src/types/docsearch.d.ts +58 -26
- package/src/types/local-search.d.ts +26 -31
|
@@ -8,13 +8,16 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import { onKeyStroke } from '@vueuse/core'
|
|
10
10
|
import type { DefaultTheme } from 'vitepress/theme'
|
|
11
|
-
import { computed, defineAsyncComponent, onMounted,
|
|
11
|
+
import { computed, defineAsyncComponent, onMounted, ref } from 'vue'
|
|
12
12
|
import { useData } from '@vp-composables/data'
|
|
13
|
+
import { resolveMode, resolveOptionsForLanguage } from '@vp-support/docsearch'
|
|
14
|
+
import { smartComputed } from '@vp-support/reactivity'
|
|
15
|
+
import VPNavBarAskAiButton from './VPNavBarAskAiButton.vue'
|
|
13
16
|
import VPNavBarSearchButton from './VPNavBarSearchButton.vue'
|
|
14
17
|
import VPSearchError from './VPSearchError.vue'
|
|
15
18
|
import { getSearchProvider, validateAlgoliaConfig } from '@vp-support/search-config'
|
|
16
19
|
|
|
17
|
-
const { theme } = useData()
|
|
20
|
+
const { theme, localeIndex, lang } = useData()
|
|
18
21
|
|
|
19
22
|
// Runtime-only provider detection
|
|
20
23
|
// NOTE: We intentionally do NOT fall back to compile-time constants (__VP_LOCAL_SEARCH__, __ALGOLIA__)
|
|
@@ -23,10 +26,18 @@ const provider = computed(() => getSearchProvider(theme.value))
|
|
|
23
26
|
|
|
24
27
|
const isLocal = computed(() => provider.value === 'local')
|
|
25
28
|
|
|
29
|
+
const algoliaOptions = smartComputed<DefaultTheme.AlgoliaSearchOptions>(() => {
|
|
30
|
+
return resolveOptionsForLanguage(
|
|
31
|
+
theme.value.search?.options || {},
|
|
32
|
+
localeIndex.value,
|
|
33
|
+
lang.value
|
|
34
|
+
)
|
|
35
|
+
})
|
|
36
|
+
|
|
26
37
|
// Validate Algolia config before attempting to render
|
|
27
38
|
const algoliaValidation = computed(() => {
|
|
28
39
|
if (provider.value !== 'algolia') return null
|
|
29
|
-
const options =
|
|
40
|
+
const options = algoliaOptions.value
|
|
30
41
|
return validateAlgoliaConfig(options)
|
|
31
42
|
})
|
|
32
43
|
|
|
@@ -63,91 +74,101 @@ const VPAlgoliaSearchBox = defineAsyncComponent({
|
|
|
63
74
|
}
|
|
64
75
|
})
|
|
65
76
|
|
|
77
|
+
// #region Algolia Search
|
|
78
|
+
|
|
79
|
+
const resolvedMode = computed(() => resolveMode(algoliaOptions.value))
|
|
80
|
+
|
|
81
|
+
const askAiSidePanelConfig = computed(() => {
|
|
82
|
+
if (!resolvedMode.value.useSidePanel) return null
|
|
83
|
+
const askAi = algoliaOptions.value.askAi
|
|
84
|
+
if (!askAi || typeof askAi === 'string') return null
|
|
85
|
+
if (!askAi.sidePanel) return null
|
|
86
|
+
return askAi.sidePanel === true ? {} : askAi.sidePanel
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
const askAiShortcutEnabled = computed(() => {
|
|
90
|
+
return askAiSidePanelConfig.value?.keyboardShortcuts?.['Ctrl/Cmd+I'] !== false
|
|
91
|
+
})
|
|
92
|
+
|
|
93
|
+
type OpenTarget = 'search' | 'askAi' | 'toggleAskAi'
|
|
94
|
+
type OpenRequest = { target: OpenTarget; nonce: number }
|
|
95
|
+
const openRequest = ref<OpenRequest | null>(null)
|
|
96
|
+
let openNonce = 0
|
|
97
|
+
|
|
66
98
|
// to avoid loading the docsearch js upfront (which is more than 1/3 of the
|
|
67
99
|
// payload), we delay initializing it until the user has actually clicked or
|
|
68
100
|
// hit the hotkey to invoke it.
|
|
69
101
|
const loaded = ref(false)
|
|
102
|
+
const actuallyLoaded = ref(false)
|
|
103
|
+
|
|
104
|
+
onMounted(() => {
|
|
105
|
+
if (!isAlgolia.value) return
|
|
70
106
|
|
|
71
|
-
const preconnect = () => {
|
|
72
107
|
const id = 'VPAlgoliaPreconnect'
|
|
108
|
+
if (document.getElementById(id)) return
|
|
109
|
+
|
|
110
|
+
const appId =
|
|
111
|
+
algoliaOptions.value.appId ||
|
|
112
|
+
(typeof algoliaOptions.value.askAi === 'object'
|
|
113
|
+
? algoliaOptions.value.askAi?.appId
|
|
114
|
+
: undefined)
|
|
115
|
+
|
|
116
|
+
if (!appId) return
|
|
73
117
|
|
|
74
118
|
const rIC = window.requestIdleCallback || setTimeout
|
|
75
119
|
rIC(() => {
|
|
76
120
|
const preconnect = document.createElement('link')
|
|
77
121
|
preconnect.id = id
|
|
78
122
|
preconnect.rel = 'preconnect'
|
|
79
|
-
preconnect.href = `https://${
|
|
80
|
-
((theme.value.search?.options as DefaultTheme.AlgoliaSearchOptions) ??
|
|
81
|
-
(theme.value as any).algolia)!.appId
|
|
82
|
-
}-dsn.algolia.net`
|
|
123
|
+
preconnect.href = `https://${appId}-dsn.algolia.net`
|
|
83
124
|
preconnect.crossOrigin = ''
|
|
84
125
|
document.head.appendChild(preconnect)
|
|
85
126
|
})
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
onMounted(() => {
|
|
89
|
-
if (!isAlgolia.value) {
|
|
90
|
-
return
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
preconnect()
|
|
127
|
+
})
|
|
94
128
|
|
|
95
|
-
|
|
129
|
+
if (isAlgolia.value) {
|
|
130
|
+
onKeyStroke('k', (event) => {
|
|
96
131
|
if (
|
|
97
|
-
|
|
98
|
-
(
|
|
132
|
+
resolvedMode.value.showKeywordSearch &&
|
|
133
|
+
(event.ctrlKey || event.metaKey)
|
|
99
134
|
) {
|
|
100
135
|
event.preventDefault()
|
|
101
|
-
|
|
102
|
-
remove()
|
|
136
|
+
loadAndOpen('search')
|
|
103
137
|
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
const remove = () => {
|
|
107
|
-
window.removeEventListener('keydown', handleSearchHotKey)
|
|
108
|
-
}
|
|
138
|
+
})
|
|
109
139
|
|
|
110
|
-
|
|
140
|
+
onKeyStroke('i', (event) => {
|
|
141
|
+
if (
|
|
142
|
+
askAiSidePanelConfig.value &&
|
|
143
|
+
askAiShortcutEnabled.value &&
|
|
144
|
+
(event.ctrlKey || event.metaKey)
|
|
145
|
+
) {
|
|
146
|
+
event.preventDefault()
|
|
147
|
+
loadAndOpen('askAi')
|
|
148
|
+
}
|
|
149
|
+
})
|
|
111
150
|
|
|
112
|
-
|
|
113
|
-
|
|
151
|
+
onKeyStroke('/', (event) => {
|
|
152
|
+
if (resolvedMode.value.showKeywordSearch && !isEditingContent(event)) {
|
|
153
|
+
event.preventDefault()
|
|
154
|
+
loadAndOpen('search')
|
|
155
|
+
}
|
|
156
|
+
})
|
|
157
|
+
}
|
|
114
158
|
|
|
115
|
-
function
|
|
159
|
+
function loadAndOpen(target: OpenTarget) {
|
|
116
160
|
if (!loaded.value) {
|
|
117
161
|
loaded.value = true
|
|
118
|
-
setTimeout(poll, 16)
|
|
119
162
|
}
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
function poll() {
|
|
123
|
-
// programmatically open the search box after initialize
|
|
124
|
-
const e = new Event('keydown') as any
|
|
125
|
-
|
|
126
|
-
e.key = 'k'
|
|
127
|
-
e.metaKey = true
|
|
128
163
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
if (!document.querySelector('.DocSearch-Modal')) {
|
|
133
|
-
poll()
|
|
134
|
-
}
|
|
135
|
-
}, 16)
|
|
164
|
+
// This will either be handled immediately if DocSearch is ready,
|
|
165
|
+
// or queued by the AlgoliaSearchBox until its instances become ready.
|
|
166
|
+
openRequest.value = { target, nonce: ++openNonce }
|
|
136
167
|
}
|
|
137
168
|
|
|
138
|
-
|
|
139
|
-
const element = event.target as HTMLElement
|
|
140
|
-
const tagName = element.tagName
|
|
169
|
+
// #endregion
|
|
141
170
|
|
|
142
|
-
|
|
143
|
-
element.isContentEditable ||
|
|
144
|
-
tagName === 'INPUT' ||
|
|
145
|
-
tagName === 'SELECT' ||
|
|
146
|
-
tagName === 'TEXTAREA'
|
|
147
|
-
)
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
// Local search
|
|
171
|
+
// #region Local Search
|
|
151
172
|
|
|
152
173
|
const showSearch = ref(false)
|
|
153
174
|
|
|
@@ -172,31 +193,58 @@ onKeyStroke('/', (event) => {
|
|
|
172
193
|
showSearch.value = true
|
|
173
194
|
}
|
|
174
195
|
})
|
|
196
|
+
|
|
197
|
+
// #endregion
|
|
198
|
+
|
|
199
|
+
function isEditingContent(event: KeyboardEvent): boolean {
|
|
200
|
+
const element = event.target as HTMLElement
|
|
201
|
+
const tagName = element.tagName
|
|
202
|
+
|
|
203
|
+
return (
|
|
204
|
+
element.isContentEditable ||
|
|
205
|
+
tagName === 'INPUT' ||
|
|
206
|
+
tagName === 'SELECT' ||
|
|
207
|
+
tagName === 'TEXTAREA'
|
|
208
|
+
)
|
|
209
|
+
}
|
|
175
210
|
</script>
|
|
176
211
|
|
|
177
212
|
<template>
|
|
178
213
|
<div class="VPNavBarSearch">
|
|
179
214
|
<!-- Local Search -->
|
|
180
215
|
<template v-if="provider === 'local'">
|
|
216
|
+
<VPNavBarSearchButton
|
|
217
|
+
:text="algoliaOptions.translations?.button?.buttonText || 'Search'"
|
|
218
|
+
:aria-label="algoliaOptions.translations?.button?.buttonAriaLabel || 'Search'"
|
|
219
|
+
:aria-keyshortcuts="'/ control+k meta+k'"
|
|
220
|
+
@click="showSearch = true"
|
|
221
|
+
/>
|
|
181
222
|
<VPLocalSearchBox
|
|
182
223
|
v-if="showSearch"
|
|
183
224
|
@close="showSearch = false"
|
|
184
225
|
/>
|
|
185
|
-
|
|
186
|
-
<div id="local-search">
|
|
187
|
-
<VPNavBarSearchButton @click="showSearch = true" />
|
|
188
|
-
</div>
|
|
189
226
|
</template>
|
|
190
227
|
|
|
191
228
|
<!-- Algolia Search - only render if config is valid -->
|
|
192
|
-
<template v-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
229
|
+
<template v-if="isAlgolia">
|
|
230
|
+
<VPNavBarSearchButton
|
|
231
|
+
v-if="resolvedMode.showKeywordSearch"
|
|
232
|
+
:text="algoliaOptions.translations?.button?.buttonText || 'Search'"
|
|
233
|
+
:aria-label="algoliaOptions.translations?.button?.buttonAriaLabel || 'Search'"
|
|
234
|
+
:aria-keyshortcuts="'/ control+k meta+k'"
|
|
235
|
+
@click="loadAndOpen('search')"
|
|
236
|
+
/>
|
|
237
|
+
<VPNavBarAskAiButton
|
|
238
|
+
v-if="askAiSidePanelConfig"
|
|
239
|
+
:aria-label="askAiSidePanelConfig.button?.translations?.buttonAriaLabel || 'Ask AI'"
|
|
240
|
+
:aria-keyshortcuts="askAiShortcutEnabled ? 'control+i meta+i' : undefined"
|
|
241
|
+
@click="actuallyLoaded ? loadAndOpen('toggleAskAi') : loadAndOpen('askAi')"
|
|
242
|
+
/>
|
|
197
243
|
<VPAlgoliaSearchBox
|
|
198
|
-
v-
|
|
199
|
-
:algolia
|
|
244
|
+
v-if="loaded"
|
|
245
|
+
:algolia-options
|
|
246
|
+
:open-request
|
|
247
|
+
@vue:beforeMount="actuallyLoaded = true"
|
|
200
248
|
/>
|
|
201
249
|
</template>
|
|
202
250
|
|
|
@@ -204,7 +252,7 @@ onKeyStroke('/', (event) => {
|
|
|
204
252
|
</div>
|
|
205
253
|
</template>
|
|
206
254
|
|
|
207
|
-
<style>
|
|
255
|
+
<style scoped>
|
|
208
256
|
.VPNavBarSearch {
|
|
209
257
|
display: flex;
|
|
210
258
|
align-items: center;
|
|
@@ -212,6 +260,7 @@ onKeyStroke('/', (event) => {
|
|
|
212
260
|
|
|
213
261
|
@media (min-width: 768px) {
|
|
214
262
|
.VPNavBarSearch {
|
|
263
|
+
gap: 8px;
|
|
215
264
|
flex-grow: 1;
|
|
216
265
|
padding-left: 8px;
|
|
217
266
|
}
|
|
@@ -1,176 +1,67 @@
|
|
|
1
1
|
<script lang="ts" setup>
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
interface ButtonTranslations {
|
|
6
|
-
buttonText?: string
|
|
7
|
-
buttonAriaLabel?: string
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
const defaultTranslations: { button: ButtonTranslations } = {
|
|
11
|
-
button: {
|
|
12
|
-
buttonText: 'Search',
|
|
13
|
-
buttonAriaLabel: 'Search'
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
const translate = createSearchTranslate(defaultTranslations)
|
|
2
|
+
defineProps<{
|
|
3
|
+
text: string
|
|
4
|
+
}>()
|
|
18
5
|
</script>
|
|
19
6
|
|
|
20
7
|
<template>
|
|
21
|
-
<button
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
aria-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
<span class="vpi-search DocSearch-Search-Icon"></span>
|
|
29
|
-
<span class="DocSearch-Button-Placeholder">{{ translate('button.buttonText') }}</span>
|
|
30
|
-
</span>
|
|
31
|
-
<span class="DocSearch-Button-Keys">
|
|
32
|
-
<kbd class="DocSearch-Button-Key"></kbd>
|
|
33
|
-
<kbd class="DocSearch-Button-Key"></kbd>
|
|
8
|
+
<button type="button" class="VPNavBarSearchButton">
|
|
9
|
+
<span class="vpi-search" aria-hidden="true"></span>
|
|
10
|
+
<span class="text">{{ text }}</span>
|
|
11
|
+
<span class="keys" aria-hidden="true">
|
|
12
|
+
<kbd class="key-cmd">⌘</kbd>
|
|
13
|
+
<kbd class="key-ctrl">Ctrl</kbd>
|
|
14
|
+
<kbd>K</kbd>
|
|
34
15
|
</span>
|
|
35
16
|
</button>
|
|
36
17
|
</template>
|
|
37
18
|
|
|
38
|
-
<style>
|
|
39
|
-
|
|
40
|
-
--docsearch-actions-height: auto;
|
|
41
|
-
--docsearch-actions-width: auto;
|
|
42
|
-
--docsearch-background-color: var(--vp-c-bg-soft);
|
|
43
|
-
--docsearch-container-background: var(--vp-backdrop-bg-color);
|
|
44
|
-
--docsearch-focus-color: var(--vp-c-brand-1);
|
|
45
|
-
--docsearch-footer-background: var(--vp-c-bg);
|
|
46
|
-
--docsearch-highlight-color: var(--vp-c-brand-1);
|
|
47
|
-
--docsearch-hit-background: var(--vp-c-default-soft);
|
|
48
|
-
--docsearch-hit-color: var(--vp-c-text-1);
|
|
49
|
-
--docsearch-hit-highlight-color: var(--vp-c-brand-soft);
|
|
50
|
-
--docsearch-icon-color: var(--vp-c-text-2);
|
|
51
|
-
--docsearch-key-background: transparent;
|
|
52
|
-
--docsearch-key-color: var(--vp-c-text-2);
|
|
53
|
-
--docsearch-modal-background: var(--vp-c-bg-soft);
|
|
54
|
-
--docsearch-muted-color: var(--vp-c-text-2);
|
|
55
|
-
--docsearch-primary-color: var(--vp-c-brand-1);
|
|
56
|
-
--docsearch-searchbox-focus-background: transparent;
|
|
57
|
-
--docsearch-secondary-text-color: var(--vp-c-text-2);
|
|
58
|
-
--docsearch-soft-primary-color: var(--vp-c-brand-soft);
|
|
59
|
-
--docsearch-subtle-color: var(--vp-c-divider);
|
|
60
|
-
--docsearch-success-color: var(--vp-c-brand-soft);
|
|
61
|
-
--docsearch-text-color: var(--vp-c-text-1);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
.dark [class*='DocSearch'] {
|
|
65
|
-
--docsearch-modal-shadow: none;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
.DocSearch-Clear {
|
|
69
|
-
padding: 0 8px;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
.DocSearch-Commands-Key {
|
|
73
|
-
padding: 4px;
|
|
74
|
-
border: 1px solid var(--docsearch-subtle-color);
|
|
75
|
-
border-radius: 4px;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
.DocSearch-Hit a:focus-visible {
|
|
79
|
-
outline: 2px solid var(--docsearch-focus-color);
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
.DocSearch-Logo [class^='cls-'] {
|
|
83
|
-
fill: currentColor;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
.DocSearch-SearchBar + .DocSearch-Footer {
|
|
87
|
-
border-top-color: transparent;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
.DocSearch-Title {
|
|
91
|
-
font-size: revert;
|
|
92
|
-
line-height: revert;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
.DocSearch-Button {
|
|
96
|
-
--docsearch-muted-color: var(--docsearch-text-color);
|
|
97
|
-
--docsearch-searchbox-background: transparent;
|
|
19
|
+
<style scoped>
|
|
20
|
+
.VPNavBarSearchButton {
|
|
98
21
|
display: flex;
|
|
99
22
|
align-items: center;
|
|
100
|
-
gap:
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
margin: 0;
|
|
105
|
-
border: none;
|
|
106
|
-
border-radius: 8px;
|
|
107
|
-
background: var(--docsearch-searchbox-background);
|
|
108
|
-
color: var(--docsearch-muted-color);
|
|
109
|
-
font-size: 14px;
|
|
110
|
-
font-weight: 500;
|
|
111
|
-
cursor: pointer;
|
|
112
|
-
transition: background 0.1s;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
.DocSearch-Button:hover {
|
|
116
|
-
background: var(--vp-c-default-soft);
|
|
23
|
+
gap: 8px;
|
|
24
|
+
height: var(--vp-nav-height);
|
|
25
|
+
padding: 8px 14px;
|
|
26
|
+
font-size: 20px;
|
|
117
27
|
}
|
|
118
28
|
|
|
119
|
-
.
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
29
|
+
.text,
|
|
30
|
+
.keys,
|
|
31
|
+
:root.mac .key-ctrl,
|
|
32
|
+
:root:not(.mac) .key-cmd {
|
|
33
|
+
display: none;
|
|
123
34
|
}
|
|
124
35
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
height: 20px;
|
|
36
|
+
kbd {
|
|
37
|
+
font-family: inherit;
|
|
38
|
+
font-weight: 500;
|
|
129
39
|
}
|
|
130
40
|
|
|
131
41
|
@media (min-width: 768px) {
|
|
132
|
-
.
|
|
133
|
-
|
|
134
|
-
|
|
42
|
+
.VPNavBarSearchButton {
|
|
43
|
+
height: auto;
|
|
44
|
+
padding: 8px 12px;
|
|
45
|
+
background-color: var(--vp-c-bg-alt);
|
|
46
|
+
border-radius: 8px;
|
|
47
|
+
font-size: 14px;
|
|
48
|
+
line-height: 1;
|
|
49
|
+
color: var(--vp-c-text-2);
|
|
135
50
|
}
|
|
136
51
|
|
|
137
|
-
.
|
|
138
|
-
|
|
139
|
-
height: 15px;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
.DocSearch-Button-Placeholder {
|
|
52
|
+
.text {
|
|
53
|
+
display: inline;
|
|
143
54
|
font-size: 13px;
|
|
144
55
|
}
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
/*
|
|
148
|
-
* Placeholder button keyboard shortcut styles.
|
|
149
|
-
* Scoped to .VPSearchButton so they don't conflict with DocSearch's real button.
|
|
150
|
-
*/
|
|
151
|
-
.VPSearchButton .DocSearch-Button-Keys {
|
|
152
|
-
min-width: auto;
|
|
153
|
-
margin: 0;
|
|
154
|
-
padding: 4px 6px;
|
|
155
|
-
background-color: var(--docsearch-key-background);
|
|
156
|
-
border: 1px solid var(--docsearch-subtle-color);
|
|
157
|
-
border-radius: 4px;
|
|
158
|
-
font-size: 12px;
|
|
159
|
-
line-height: 1;
|
|
160
|
-
color: var(--docsearch-key-color);
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
.VPSearchButton .DocSearch-Button-Keys > * {
|
|
164
|
-
display: none;
|
|
165
|
-
}
|
|
166
56
|
|
|
167
|
-
.
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
57
|
+
.keys {
|
|
58
|
+
display: flex;
|
|
59
|
+
align-items: center;
|
|
60
|
+
gap: 4px;
|
|
61
|
+
padding: 4px 6px;
|
|
62
|
+
border: 1px solid var(--vp-c-divider);
|
|
63
|
+
border-radius: 4px;
|
|
64
|
+
font-size: 12px;
|
|
65
|
+
}
|
|
175
66
|
}
|
|
176
67
|
</style>
|
|
@@ -19,7 +19,13 @@ const { localeLinks, currentLang } = useLangs({ correspondingLink: true })
|
|
|
19
19
|
<p class="title">{{ currentLang.label }}</p>
|
|
20
20
|
|
|
21
21
|
<template v-for="locale in localeLinks" :key="locale.link">
|
|
22
|
-
<VPMenuLink
|
|
22
|
+
<VPMenuLink
|
|
23
|
+
:item="locale"
|
|
24
|
+
:lang="locale.lang"
|
|
25
|
+
:hreflang="locale.lang"
|
|
26
|
+
rel="alternate"
|
|
27
|
+
:dir="locale.dir"
|
|
28
|
+
/>
|
|
23
29
|
</template>
|
|
24
30
|
</div>
|
|
25
31
|
</VPFlyout>
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import { useScrollLock } from '@vueuse/core'
|
|
3
3
|
import { inBrowser } from 'vitepress'
|
|
4
|
-
import { ref } from 'vue'
|
|
5
4
|
import VPNavScreenAppearance from './VPNavScreenAppearance.vue'
|
|
6
5
|
import VPNavScreenMenu from './VPNavScreenMenu.vue'
|
|
7
6
|
import VPNavScreenSocialLinks from './VPNavScreenSocialLinks.vue'
|
|
@@ -11,7 +10,6 @@ defineProps<{
|
|
|
11
10
|
open: boolean
|
|
12
11
|
}>()
|
|
13
12
|
|
|
14
|
-
const screen = ref<HTMLElement | null>(null)
|
|
15
13
|
const isLocked = useScrollLock(inBrowser ? document.body : null)
|
|
16
14
|
</script>
|
|
17
15
|
|
|
@@ -21,7 +19,7 @@ const isLocked = useScrollLock(inBrowser ? document.body : null)
|
|
|
21
19
|
@enter="isLocked = true"
|
|
22
20
|
@after-leave="isLocked = false"
|
|
23
21
|
>
|
|
24
|
-
<div v-if="open" class="VPNavScreen"
|
|
22
|
+
<div v-if="open" class="VPNavScreen" id="VPNavScreen">
|
|
25
23
|
<div class="container">
|
|
26
24
|
<slot name="nav-screen-content-before" />
|
|
27
25
|
<VPNavScreenMenu class="menu" />
|
package/src/shims.d.ts
ADDED
package/src/styles/base.css
CHANGED