vitepress 1.0.0-beta.1 → 1.0.0-beta.3
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/dist/client/app/composables/copyCode.js +2 -3
- package/dist/client/index.d.ts +3 -2
- package/dist/client/index.js +1 -1
- package/dist/client/theme-default/components/VPFooter.vue +0 -3
- package/dist/client/theme-default/components/VPLocalNav.vue +38 -4
- package/dist/client/theme-default/components/VPLocalNavOutlineDropdown.vue +8 -12
- package/dist/client/theme-default/components/VPLocalSearchBox.vue +121 -90
- package/dist/client/theme-default/components/VPNavBar.vue +0 -6
- package/dist/client/theme-default/components/VPNavBarSearch.vue +3 -1
- package/dist/client/theme-default/components/VPSkipLink.vue +0 -4
- package/dist/client/theme-default/components/VPSocialLink.vue +2 -1
- package/dist/client/theme-default/components/VPSocialLinks.vue +2 -1
- package/dist/client/theme-default/components/VPSwitchAppearance.vue +2 -2
- package/dist/client/theme-default/composables/outline.js +1 -1
- package/dist/client/theme-default/composables/prev-next.js +6 -2
- package/dist/client/theme-default/styles/components/vp-code-group.css +1 -1
- package/dist/node/cli.js +28 -12
- package/dist/node/index.d.ts +118 -114
- package/dist/node/index.js +13 -11
- package/dist/node/{serve-d5608de4.js → serve-ec0537e0.js} +7603 -796
- package/dist/node-cjs/cli.cjs +28 -12
- package/dist/node-cjs/index.cjs +12 -10
- package/dist/node-cjs/{serve-cdd2176c.cjs → serve-9a16cbd6.cjs} +7528 -727
- package/package.json +21 -21
- package/template/.vitepress/theme/index.js +1 -1
- package/theme-without-fonts.d.ts +1 -0
- package/types/default-theme.d.ts +5 -4
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import { inBrowser } from 'vitepress';
|
|
2
2
|
export function useCopyCode() {
|
|
3
3
|
if (inBrowser) {
|
|
4
|
-
const timeoutIdMap = new
|
|
4
|
+
const timeoutIdMap = new WeakMap();
|
|
5
5
|
window.addEventListener('click', (e) => {
|
|
6
6
|
const el = e.target;
|
|
7
7
|
if (el.matches('div[class*="language-"] > button.copy')) {
|
|
8
8
|
const parent = el.parentElement;
|
|
9
|
-
const sibling = el.nextElementSibling
|
|
10
|
-
?.nextElementSibling;
|
|
9
|
+
const sibling = el.nextElementSibling?.nextElementSibling;
|
|
11
10
|
if (!parent || !sibling) {
|
|
12
11
|
return;
|
|
13
12
|
}
|
package/dist/client/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as vue from 'vue';
|
|
2
|
-
import { Component, Ref, App, AsyncComponentLoader } from 'vue';
|
|
2
|
+
import { Component, InjectionKey, Ref, App, AsyncComponentLoader } from 'vue';
|
|
3
3
|
import { PageData, Awaitable, SiteData } from '../../types/shared.js';
|
|
4
4
|
export { HeadConfig, Header, PageData, SiteData } from '../../types/shared.js';
|
|
5
5
|
|
|
@@ -19,6 +19,7 @@ interface Router {
|
|
|
19
19
|
declare function useRouter(): Router;
|
|
20
20
|
declare function useRoute(): Route;
|
|
21
21
|
|
|
22
|
+
declare const dataSymbol: InjectionKey<VitePressData>;
|
|
22
23
|
interface VitePressData<T = any> {
|
|
23
24
|
/**
|
|
24
25
|
* Site-level metadata
|
|
@@ -96,4 +97,4 @@ declare const Content: vue.DefineComponent<{
|
|
|
96
97
|
as: string | Record<string, any>;
|
|
97
98
|
}, {}>;
|
|
98
99
|
|
|
99
|
-
export { Content, EnhanceAppContext, Route, Router, Theme, VitePressData, defineClientComponent, inBrowser, onContentUpdated, useData, useRoute, useRouter, withBase };
|
|
100
|
+
export { Content, EnhanceAppContext, Route, Router, Theme, VitePressData, dataSymbol, defineClientComponent, inBrowser, onContentUpdated, useData, useRoute, useRouter, withBase };
|
package/dist/client/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// exports in this file are exposed to themes and md files via 'vitepress'
|
|
2
2
|
// so the user can do `import { useRoute, useSiteData } from 'vitepress'`
|
|
3
3
|
// composables
|
|
4
|
-
export { useData } from './app/data';
|
|
4
|
+
export { useData, dataSymbol } from './app/data';
|
|
5
5
|
export { useRoute, useRouter } from './app/router';
|
|
6
6
|
// utilities
|
|
7
7
|
export { inBrowser, onContentUpdated, defineClientComponent, withBase } from './app/utils';
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
<script lang="ts" setup>
|
|
2
|
+
import { useWindowScroll } from '@vueuse/core'
|
|
3
|
+
import { computed, shallowRef } from 'vue'
|
|
4
|
+
import { onContentUpdated } from 'vitepress'
|
|
2
5
|
import { useData } from '../composables/data'
|
|
6
|
+
import { getHeaders, type MenuItem } from '../composables/outline'
|
|
3
7
|
import { useSidebar } from '../composables/sidebar'
|
|
4
|
-
import VPIconAlignLeft from './icons/VPIconAlignLeft.vue'
|
|
5
8
|
import VPLocalNavOutlineDropdown from './VPLocalNavOutlineDropdown.vue'
|
|
9
|
+
import VPIconAlignLeft from './icons/VPIconAlignLeft.vue'
|
|
6
10
|
|
|
7
11
|
defineProps<{
|
|
8
12
|
open: boolean
|
|
@@ -14,10 +18,32 @@ defineEmits<{
|
|
|
14
18
|
|
|
15
19
|
const { theme, frontmatter } = useData()
|
|
16
20
|
const { hasSidebar } = useSidebar()
|
|
21
|
+
const { y } = useWindowScroll()
|
|
22
|
+
|
|
23
|
+
const headers = shallowRef<MenuItem[]>([])
|
|
24
|
+
|
|
25
|
+
onContentUpdated(() => {
|
|
26
|
+
headers.value = getHeaders(frontmatter.value.outline ?? theme.value.outline)
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
const empty = computed(() => {
|
|
30
|
+
return headers.value.length === 0 && !hasSidebar.value
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
const classes = computed(() => {
|
|
34
|
+
return {
|
|
35
|
+
VPLocalNav: true,
|
|
36
|
+
fixed: empty.value,
|
|
37
|
+
'reached-top': y.value >= 64
|
|
38
|
+
}
|
|
39
|
+
})
|
|
17
40
|
</script>
|
|
18
41
|
|
|
19
42
|
<template>
|
|
20
|
-
<div
|
|
43
|
+
<div
|
|
44
|
+
v-if="frontmatter.layout !== 'home' && (!empty || y >= 64)"
|
|
45
|
+
:class="classes"
|
|
46
|
+
>
|
|
21
47
|
<button
|
|
22
48
|
v-if="hasSidebar"
|
|
23
49
|
class="menu"
|
|
@@ -31,7 +57,7 @@ const { hasSidebar } = useSidebar()
|
|
|
31
57
|
</span>
|
|
32
58
|
</button>
|
|
33
59
|
|
|
34
|
-
<VPLocalNavOutlineDropdown />
|
|
60
|
+
<VPLocalNavOutlineDropdown :headers="headers" />
|
|
35
61
|
</div>
|
|
36
62
|
</template>
|
|
37
63
|
|
|
@@ -45,11 +71,19 @@ const { hasSidebar } = useSidebar()
|
|
|
45
71
|
display: flex;
|
|
46
72
|
justify-content: space-between;
|
|
47
73
|
align-items: center;
|
|
74
|
+
border-top: 1px solid var(--vp-c-gutter);
|
|
48
75
|
border-bottom: 1px solid var(--vp-c-gutter);
|
|
49
76
|
padding-top: var(--vp-layout-top-height, 0px);
|
|
50
77
|
width: 100%;
|
|
51
78
|
background-color: var(--vp-local-nav-bg-color);
|
|
52
|
-
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
.VPLocalNav.fixed {
|
|
82
|
+
position: fixed;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.VPLocalNav.reached-top {
|
|
86
|
+
border-top-color: transparent;
|
|
53
87
|
}
|
|
54
88
|
|
|
55
89
|
@media (min-width: 960px) {
|
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import {
|
|
2
|
+
import { onContentUpdated } from 'vitepress'
|
|
3
|
+
import { nextTick, ref } from 'vue'
|
|
3
4
|
import { useData } from '../composables/data'
|
|
4
|
-
import {
|
|
5
|
+
import { resolveTitle, type MenuItem } from '../composables/outline'
|
|
5
6
|
import VPDocOutlineItem from './VPDocOutlineItem.vue'
|
|
6
|
-
import { onContentUpdated } from 'vitepress'
|
|
7
7
|
import VPIconChevronRight from './icons/VPIconChevronRight.vue'
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
defineProps<{
|
|
10
|
+
headers: MenuItem[]
|
|
11
|
+
}>()
|
|
12
|
+
|
|
13
|
+
const { theme } = useData()
|
|
10
14
|
const open = ref(false)
|
|
11
15
|
const vh = ref(0)
|
|
12
16
|
const items = ref<HTMLDivElement>()
|
|
@@ -36,14 +40,6 @@ function scrollToTop() {
|
|
|
36
40
|
open.value = false
|
|
37
41
|
window.scrollTo({ top: 0, left: 0, behavior: 'smooth' })
|
|
38
42
|
}
|
|
39
|
-
|
|
40
|
-
const headers = shallowRef<MenuItem[]>([])
|
|
41
|
-
|
|
42
|
-
onContentUpdated(() => {
|
|
43
|
-
headers.value = getHeaders(
|
|
44
|
-
frontmatter.value.outline ?? theme.value.outline
|
|
45
|
-
)
|
|
46
|
-
})
|
|
47
43
|
</script>
|
|
48
44
|
|
|
49
45
|
<template>
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
import { useFocusTrap } from '@vueuse/integrations/useFocusTrap'
|
|
13
13
|
import Mark from 'mark.js/src/vanilla.js'
|
|
14
14
|
import MiniSearch, { type SearchResult } from 'minisearch'
|
|
15
|
-
import { useRouter } from 'vitepress'
|
|
15
|
+
import { useRouter, dataSymbol } from 'vitepress'
|
|
16
16
|
import {
|
|
17
17
|
computed,
|
|
18
18
|
createApp,
|
|
@@ -27,7 +27,6 @@ import {
|
|
|
27
27
|
type Ref
|
|
28
28
|
} from 'vue'
|
|
29
29
|
import type { ModalTranslations } from '../../../../types/local-search'
|
|
30
|
-
import { dataSymbol } from '../../app/data'
|
|
31
30
|
import { pathToFile } from '../../app/utils'
|
|
32
31
|
import { useData } from '../composables/data'
|
|
33
32
|
import { createTranslate } from '../support/translation'
|
|
@@ -119,8 +118,6 @@ watchEffect(() => {
|
|
|
119
118
|
|
|
120
119
|
const results: Ref<(SearchResult & Result)[]> = shallowRef([])
|
|
121
120
|
|
|
122
|
-
const headingRegex = /<h(\d*).*?>.*?<a.*? href="#(.*?)".*?>.*?<\/a><\/h\1>/gi
|
|
123
|
-
|
|
124
121
|
const enableNoResults = ref(false)
|
|
125
122
|
|
|
126
123
|
watch(filterText, () => {
|
|
@@ -155,8 +152,13 @@ debouncedWatch(
|
|
|
155
152
|
if (canceled) return
|
|
156
153
|
const c = new Map<string, Map<string, string>>()
|
|
157
154
|
for (const { id, mod } of mods) {
|
|
155
|
+
const mapId = id.slice(0, id.indexOf('#'))
|
|
156
|
+
let map = c.get(mapId)
|
|
157
|
+
if (map) continue
|
|
158
|
+
map = new Map()
|
|
159
|
+
c.set(mapId, map)
|
|
158
160
|
const comp = mod.default ?? mod
|
|
159
|
-
if (comp?.render) {
|
|
161
|
+
if (comp?.render || comp?.setup) {
|
|
160
162
|
const app = createApp(comp)
|
|
161
163
|
// Silence warnings about missing components
|
|
162
164
|
app.config.warnHandler = () => {}
|
|
@@ -175,20 +177,17 @@ debouncedWatch(
|
|
|
175
177
|
})
|
|
176
178
|
const div = document.createElement('div')
|
|
177
179
|
app.mount(div)
|
|
178
|
-
const
|
|
180
|
+
const headings = div.querySelectorAll('h1, h2, h3, h4, h5, h6')
|
|
181
|
+
headings.forEach((el) => {
|
|
182
|
+
const href = el.querySelector('a')?.getAttribute('href')
|
|
183
|
+
const anchor = href?.startsWith('#') && href.slice(1)
|
|
184
|
+
if (!anchor) return
|
|
185
|
+
let html = ''
|
|
186
|
+
while ((el = el.nextElementSibling!) && !/^h[1-6]$/i.test(el.tagName))
|
|
187
|
+
html += el.outerHTML
|
|
188
|
+
map!.set(anchor, html)
|
|
189
|
+
})
|
|
179
190
|
app.unmount()
|
|
180
|
-
sections.shift()
|
|
181
|
-
const mapId = id.slice(0, id.indexOf('#'))
|
|
182
|
-
let map = c.get(mapId)
|
|
183
|
-
if (!map) {
|
|
184
|
-
map = new Map()
|
|
185
|
-
c.set(mapId, map)
|
|
186
|
-
}
|
|
187
|
-
for (let i = 0; i < sections.length; i += 3) {
|
|
188
|
-
const anchor = sections[i + 1]
|
|
189
|
-
const html = sections[i + 2]
|
|
190
|
-
map.set(anchor, html)
|
|
191
|
-
}
|
|
192
191
|
}
|
|
193
192
|
if (canceled) return
|
|
194
193
|
}
|
|
@@ -241,10 +240,12 @@ async function fetchExcerpt(id: string) {
|
|
|
241
240
|
/* Search input focus */
|
|
242
241
|
|
|
243
242
|
const searchInput = ref<HTMLInputElement>()
|
|
244
|
-
|
|
245
|
-
|
|
243
|
+
const disableReset = computed(() => {
|
|
244
|
+
return filterText.value?.length <= 0
|
|
245
|
+
})
|
|
246
|
+
function focusSearchInput(select = true) {
|
|
246
247
|
searchInput.value?.focus()
|
|
247
|
-
searchInput.value?.select()
|
|
248
|
+
select && searchInput.value?.select()
|
|
248
249
|
}
|
|
249
250
|
|
|
250
251
|
onMounted(() => {
|
|
@@ -259,11 +260,11 @@ function onSearchBarClick(event: PointerEvent) {
|
|
|
259
260
|
|
|
260
261
|
/* Search keyboard selection */
|
|
261
262
|
|
|
262
|
-
const selectedIndex = ref(
|
|
263
|
+
const selectedIndex = ref(-1)
|
|
263
264
|
const disableMouseOver = ref(false)
|
|
264
265
|
|
|
265
|
-
watch(results, () => {
|
|
266
|
-
selectedIndex.value = 0
|
|
266
|
+
watch(results, (r) => {
|
|
267
|
+
selectedIndex.value = r.length ? 0 : -1
|
|
267
268
|
scrollToSelectedResult()
|
|
268
269
|
})
|
|
269
270
|
|
|
@@ -360,6 +361,11 @@ onBeforeUnmount(() => {
|
|
|
360
361
|
isLocked.value = false
|
|
361
362
|
})
|
|
362
363
|
|
|
364
|
+
function resetSearch() {
|
|
365
|
+
filterText.value = ''
|
|
366
|
+
nextTick().then(() => focusSearchInput(false))
|
|
367
|
+
}
|
|
368
|
+
|
|
363
369
|
function formMarkRegex(terms: Set<string>) {
|
|
364
370
|
return new RegExp(
|
|
365
371
|
[...terms]
|
|
@@ -377,34 +383,44 @@ function formMarkRegex(terms: Set<string>) {
|
|
|
377
383
|
|
|
378
384
|
<template>
|
|
379
385
|
<Teleport to="body">
|
|
380
|
-
<div
|
|
386
|
+
<div
|
|
387
|
+
ref="el"
|
|
388
|
+
role="button"
|
|
389
|
+
:aria-owns="results?.length ? 'localsearch-list' : undefined"
|
|
390
|
+
aria-expanded="true"
|
|
391
|
+
aria-haspopup="listbox"
|
|
392
|
+
aria-labelledby="localsearch-label"
|
|
393
|
+
class="VPLocalSearchBox"
|
|
394
|
+
>
|
|
381
395
|
<div class="backdrop" @click="$emit('close')" />
|
|
382
396
|
|
|
383
397
|
<div class="shell">
|
|
384
|
-
<
|
|
385
|
-
<
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
<g
|
|
393
|
-
fill="none"
|
|
394
|
-
stroke="currentColor"
|
|
395
|
-
stroke-linecap="round"
|
|
396
|
-
stroke-linejoin="round"
|
|
397
|
-
stroke-width="2"
|
|
398
|
+
<form class="search-bar" @pointerup="onSearchBarClick($event)" @submit.prevent="">
|
|
399
|
+
<label :title="placeholder" id="localsearch-label" for="localsearch-input">
|
|
400
|
+
<svg
|
|
401
|
+
class="search-icon"
|
|
402
|
+
width="18"
|
|
403
|
+
height="18"
|
|
404
|
+
viewBox="0 0 24 24"
|
|
405
|
+
aria-hidden="true"
|
|
398
406
|
>
|
|
399
|
-
<
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
407
|
+
<g
|
|
408
|
+
fill="none"
|
|
409
|
+
stroke="currentColor"
|
|
410
|
+
stroke-linecap="round"
|
|
411
|
+
stroke-linejoin="round"
|
|
412
|
+
stroke-width="2"
|
|
413
|
+
>
|
|
414
|
+
<circle cx="11" cy="11" r="8" />
|
|
415
|
+
<path d="m21 21l-4.35-4.35" />
|
|
416
|
+
</g>
|
|
417
|
+
</svg>
|
|
418
|
+
</label>
|
|
403
419
|
<div class="search-actions before">
|
|
404
420
|
<button
|
|
405
421
|
class="back-button"
|
|
406
422
|
:title="$t('modal.backButtonTitle')"
|
|
407
|
-
@click="$emit('close')"
|
|
423
|
+
@click="selectedIndex > -1 && $emit('close')"
|
|
408
424
|
>
|
|
409
425
|
<svg
|
|
410
426
|
width="18"
|
|
@@ -427,6 +443,8 @@ function formMarkRegex(terms: Set<string>) {
|
|
|
427
443
|
ref="searchInput"
|
|
428
444
|
v-model="filterText"
|
|
429
445
|
:placeholder="placeholder"
|
|
446
|
+
id="localsearch-input"
|
|
447
|
+
aria-labelledby="localsearch-label"
|
|
430
448
|
class="search-input"
|
|
431
449
|
/>
|
|
432
450
|
<div class="search-actions">
|
|
@@ -435,7 +453,7 @@ function formMarkRegex(terms: Set<string>) {
|
|
|
435
453
|
class="toggle-layout-button"
|
|
436
454
|
:class="{ 'detailed-list': showDetailedList }"
|
|
437
455
|
:title="$t('modal.displayDetails')"
|
|
438
|
-
@click="showDetailedList = !showDetailedList"
|
|
456
|
+
@click="selectedIndex > -1 && (showDetailedList = !showDetailedList)"
|
|
439
457
|
>
|
|
440
458
|
<svg
|
|
441
459
|
width="18"
|
|
@@ -456,8 +474,10 @@ function formMarkRegex(terms: Set<string>) {
|
|
|
456
474
|
|
|
457
475
|
<button
|
|
458
476
|
class="clear-button"
|
|
477
|
+
type="reset"
|
|
478
|
+
:disabled="disableReset"
|
|
459
479
|
:title="$t('modal.resetButtonTitle')"
|
|
460
|
-
@click="
|
|
480
|
+
@click="resetSearch"
|
|
461
481
|
>
|
|
462
482
|
<svg
|
|
463
483
|
width="18"
|
|
@@ -476,65 +496,72 @@ function formMarkRegex(terms: Set<string>) {
|
|
|
476
496
|
</svg>
|
|
477
497
|
</button>
|
|
478
498
|
</div>
|
|
479
|
-
</
|
|
499
|
+
</form>
|
|
480
500
|
|
|
481
|
-
<
|
|
501
|
+
<ul
|
|
482
502
|
ref="resultsEl"
|
|
503
|
+
:id="results?.length ? 'localsearch-list' : undefined"
|
|
504
|
+
:role="results?.length ? 'listbox' : undefined"
|
|
505
|
+
:aria-labelledby="results?.length ? 'localsearch-label' : undefined"
|
|
483
506
|
class="results"
|
|
484
507
|
@mousemove="disableMouseOver = false"
|
|
485
508
|
>
|
|
486
|
-
<
|
|
509
|
+
<li
|
|
487
510
|
v-for="(p, index) in results"
|
|
488
511
|
:key="p.id"
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
:class="{
|
|
492
|
-
selected: selectedIndex === index
|
|
493
|
-
}"
|
|
494
|
-
:aria-label="[...p.titles, p.title].join(' > ')"
|
|
495
|
-
@mouseenter="!disableMouseOver && (selectedIndex = index)"
|
|
496
|
-
@focusin="selectedIndex = index"
|
|
497
|
-
@click="$emit('close')"
|
|
512
|
+
role="option"
|
|
513
|
+
:aria-selected="selectedIndex === index ? 'true' : 'false'"
|
|
498
514
|
>
|
|
499
|
-
<
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
515
|
+
<a
|
|
516
|
+
:href="p.id"
|
|
517
|
+
class="result"
|
|
518
|
+
:class="{
|
|
519
|
+
selected: selectedIndex === index
|
|
520
|
+
}"
|
|
521
|
+
:aria-label="[...p.titles, p.title].join(' > ')"
|
|
522
|
+
@mouseenter="!disableMouseOver && (selectedIndex = index)"
|
|
523
|
+
@focusin="selectedIndex = index"
|
|
524
|
+
@click="$emit('close')"
|
|
525
|
+
>
|
|
526
|
+
<div>
|
|
527
|
+
<div class="titles">
|
|
528
|
+
<span class="title-icon">#</span>
|
|
529
|
+
<span v-for="(t, index) in p.titles" :key="index" class="title">
|
|
530
|
+
<span class="text" v-html="t" />
|
|
531
|
+
<svg width="18" height="18" viewBox="0 0 24 24">
|
|
532
|
+
<path
|
|
533
|
+
fill="none"
|
|
534
|
+
stroke="currentColor"
|
|
535
|
+
stroke-linecap="round"
|
|
536
|
+
stroke-linejoin="round"
|
|
537
|
+
stroke-width="2"
|
|
538
|
+
d="m9 18l6-6l-6-6"
|
|
539
|
+
/>
|
|
540
|
+
</svg>
|
|
541
|
+
</span>
|
|
542
|
+
<span class="title main">
|
|
543
|
+
<span class="text" v-html="p.title" />
|
|
544
|
+
</span>
|
|
545
|
+
</div>
|
|
519
546
|
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
547
|
+
<div v-if="showDetailedList" class="excerpt-wrapper">
|
|
548
|
+
<div v-if="p.text" class="excerpt" inert>
|
|
549
|
+
<div class="vp-doc" v-html="p.text" />
|
|
550
|
+
</div>
|
|
551
|
+
<div class="excerpt-gradient-bottom" />
|
|
552
|
+
<div class="excerpt-gradient-top" />
|
|
523
553
|
</div>
|
|
524
|
-
<div class="excerpt-gradient-bottom" />
|
|
525
|
-
<div class="excerpt-gradient-top" />
|
|
526
554
|
</div>
|
|
527
|
-
</
|
|
528
|
-
</
|
|
529
|
-
|
|
530
|
-
<div
|
|
555
|
+
</a>
|
|
556
|
+
</li>
|
|
557
|
+
<li
|
|
531
558
|
v-if="filterText && !results.length && enableNoResults"
|
|
532
559
|
class="no-results"
|
|
533
560
|
>
|
|
534
561
|
{{ $t('modal.noResultsText') }} "<strong>{{ filterText }}</strong
|
|
535
562
|
>"
|
|
536
|
-
</
|
|
537
|
-
</
|
|
563
|
+
</li>
|
|
564
|
+
</ul>
|
|
538
565
|
|
|
539
566
|
<div class="search-keyboard-shortcuts">
|
|
540
567
|
<span>
|
|
@@ -692,11 +719,15 @@ function formMarkRegex(terms: Set<string>) {
|
|
|
692
719
|
padding: 8px;
|
|
693
720
|
}
|
|
694
721
|
|
|
695
|
-
.search-actions button:hover,
|
|
722
|
+
.search-actions button:not([disabled]):hover,
|
|
696
723
|
.toggle-layout-button.detailed-list {
|
|
697
724
|
color: var(--vp-c-brand);
|
|
698
725
|
}
|
|
699
726
|
|
|
727
|
+
.search-actions button.clear-button:disabled {
|
|
728
|
+
opacity: 0.37;
|
|
729
|
+
}
|
|
730
|
+
|
|
700
731
|
.search-keyboard-shortcuts {
|
|
701
732
|
font-size: 0.8rem;
|
|
702
733
|
opacity: 75%;
|
|
@@ -62,15 +62,10 @@ const classes = computed(() => ({
|
|
|
62
62
|
border-bottom: 1px solid transparent;
|
|
63
63
|
padding: 0 8px 0 24px;
|
|
64
64
|
height: var(--vp-nav-height);
|
|
65
|
-
transition: border-color 0.5s, background-color 0.5s;
|
|
66
65
|
pointer-events: none;
|
|
67
66
|
white-space: nowrap;
|
|
68
67
|
}
|
|
69
68
|
|
|
70
|
-
.VPNavBar.has-sidebar {
|
|
71
|
-
border-bottom-color: var(--vp-c-gutter);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
69
|
@media (min-width: 768px) {
|
|
75
70
|
.VPNavBar {
|
|
76
71
|
padding: 0 32px;
|
|
@@ -79,7 +74,6 @@ const classes = computed(() => ({
|
|
|
79
74
|
|
|
80
75
|
@media (min-width: 960px) {
|
|
81
76
|
.VPNavBar.has-sidebar {
|
|
82
|
-
border-bottom-color: transparent;
|
|
83
77
|
padding: 0;
|
|
84
78
|
}
|
|
85
79
|
|
|
@@ -26,6 +26,7 @@ const { theme, localeIndex } = useData()
|
|
|
26
26
|
// payload), we delay initializing it until the user has actually clicked or
|
|
27
27
|
// hit the hotkey to invoke it.
|
|
28
28
|
const loaded = ref(false)
|
|
29
|
+
const actuallyLoaded = ref(false)
|
|
29
30
|
|
|
30
31
|
const buttonText = computed(() => {
|
|
31
32
|
const options = theme.value.search?.options ?? theme.value.algolia
|
|
@@ -169,9 +170,10 @@ const provider = __ALGOLIA__ ? 'algolia' : __VP_LOCAL_SEARCH__ ? 'local' : ''
|
|
|
169
170
|
<VPAlgoliaSearchBox
|
|
170
171
|
v-if="loaded"
|
|
171
172
|
:algolia="theme.search?.options ?? theme.algolia"
|
|
173
|
+
@vue:beforeMount="actuallyLoaded = true"
|
|
172
174
|
/>
|
|
173
175
|
|
|
174
|
-
<div v-
|
|
176
|
+
<div v-if="!actuallyLoaded" id="docsearch">
|
|
175
177
|
<VPNavBarSearchButton :placeholder="buttonText" @click="load" />
|
|
176
178
|
</div>
|
|
177
179
|
</template>
|
|
@@ -6,6 +6,7 @@ import { icons } from '../support/socialIcons'
|
|
|
6
6
|
const props = defineProps<{
|
|
7
7
|
icon: DefaultTheme.SocialLinkIcon
|
|
8
8
|
link: string
|
|
9
|
+
ariaLabel?: string
|
|
9
10
|
}>()
|
|
10
11
|
|
|
11
12
|
const svg = computed(() => {
|
|
@@ -18,7 +19,7 @@ const svg = computed(() => {
|
|
|
18
19
|
<a
|
|
19
20
|
class="VPSocialLink"
|
|
20
21
|
:href="link"
|
|
21
|
-
:aria-label="typeof icon === 'string' ? icon : ''"
|
|
22
|
+
:aria-label="ariaLabel ?? (typeof icon === 'string' ? icon : '')"
|
|
22
23
|
target="_blank"
|
|
23
24
|
rel="noopener"
|
|
24
25
|
v-html="svg"
|
|
@@ -10,10 +10,11 @@ defineProps<{
|
|
|
10
10
|
<template>
|
|
11
11
|
<div class="VPSocialLinks">
|
|
12
12
|
<VPSocialLink
|
|
13
|
-
v-for="{ link, icon } in links"
|
|
13
|
+
v-for="{ link, icon, ariaLabel } in links"
|
|
14
14
|
:key="link"
|
|
15
15
|
:icon="icon"
|
|
16
16
|
:link="link"
|
|
17
|
+
:ariaLabel="ariaLabel"
|
|
17
18
|
/>
|
|
18
19
|
</div>
|
|
19
20
|
</template>
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
<script lang="ts" setup>
|
|
2
2
|
import { ref, onMounted, watch } from 'vue'
|
|
3
3
|
import { useData } from '../composables/data'
|
|
4
|
-
import { APPEARANCE_KEY } from '../../shared'
|
|
4
|
+
import { inBrowser, APPEARANCE_KEY } from '../../shared'
|
|
5
5
|
import VPSwitch from './VPSwitch.vue'
|
|
6
6
|
import VPIconSun from './icons/VPIconSun.vue'
|
|
7
7
|
import VPIconMoon from './icons/VPIconMoon.vue'
|
|
8
8
|
|
|
9
9
|
const { site, isDark } = useData()
|
|
10
10
|
const checked = ref(false)
|
|
11
|
-
const toggle =
|
|
11
|
+
const toggle = inBrowser ? useAppearance() : () => {}
|
|
12
12
|
|
|
13
13
|
onMounted(() => {
|
|
14
14
|
checked.value = document.documentElement.classList.contains('dark')
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { onMounted, onUnmounted, onUpdated } from 'vue';
|
|
2
|
-
import { useAside } from '
|
|
2
|
+
import { useAside } from './aside';
|
|
3
3
|
import { throttleAndDebounce } from '../support/utils';
|
|
4
4
|
// magic number to avoid repeated retrieval
|
|
5
5
|
const PAGE_OFFSET = 71;
|
|
@@ -10,8 +10,12 @@ export function usePrevNext() {
|
|
|
10
10
|
const index = candidates.findIndex((link) => {
|
|
11
11
|
return isActive(page.value.relativePath, link.link);
|
|
12
12
|
});
|
|
13
|
+
const hidePrev = (theme.value.docFooter?.prev === false && !frontmatter.value.prev) ||
|
|
14
|
+
frontmatter.value.prev === false;
|
|
15
|
+
const hideNext = (theme.value.docFooter?.next === false && !frontmatter.value.next) ||
|
|
16
|
+
frontmatter.value.next === false;
|
|
13
17
|
return {
|
|
14
|
-
prev:
|
|
18
|
+
prev: hidePrev
|
|
15
19
|
? undefined
|
|
16
20
|
: {
|
|
17
21
|
text: (typeof frontmatter.value.prev === 'string'
|
|
@@ -23,7 +27,7 @@ export function usePrevNext() {
|
|
|
23
27
|
? frontmatter.value.prev.link
|
|
24
28
|
: undefined) ?? candidates[index - 1]?.link
|
|
25
29
|
},
|
|
26
|
-
next:
|
|
30
|
+
next: hideNext
|
|
27
31
|
? undefined
|
|
28
32
|
: {
|
|
29
33
|
text: (typeof frontmatter.value.next === 'string'
|