vitepress 1.0.0-draft.1 → 1.0.0-draft.4
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/head.js +2 -2
- package/dist/client/app/data.js +2 -4
- package/dist/client/index.d.ts +8 -0
- package/dist/client/shared.js +22 -0
- package/dist/client/theme-default/Layout.vue +18 -1
- package/dist/client/theme-default/components/VPBackdrop.vue +1 -1
- package/dist/client/theme-default/components/VPBox.vue +59 -0
- package/dist/client/theme-default/components/VPButton.vue +123 -0
- package/dist/client/theme-default/components/VPContent.vue +34 -10
- package/dist/client/theme-default/components/{VPContentDoc.vue → VPDoc.vue} +66 -42
- package/dist/client/theme-default/components/{VPContentDocFooter.vue → VPDocFooter.vue} +3 -2
- package/dist/client/theme-default/components/{VPContentDocOutline.vue → VPDocOutline.vue} +14 -3
- package/dist/client/theme-default/components/VPFooter.vue +53 -0
- package/dist/client/theme-default/components/VPHero.vue +144 -0
- package/dist/client/theme-default/components/VPHome.vue +33 -0
- package/dist/client/theme-default/components/VPHomeFeatures.vue +96 -0
- package/dist/client/theme-default/components/VPHomeHero.vue +17 -0
- package/dist/client/theme-default/components/VPHomeSponsors.vue +93 -0
- package/dist/client/theme-default/components/VPNavBar.vue +2 -1
- package/dist/client/theme-default/components/VPNavBarAppearance.vue +4 -1
- package/dist/client/theme-default/components/VPNavBarExtra.vue +2 -2
- package/dist/client/theme-default/components/VPNavBarSearch.vue +3 -3
- package/dist/client/theme-default/components/VPNavBarTitle.vue +26 -13
- package/dist/client/theme-default/components/VPNavScreenAppearance.vue +4 -1
- package/dist/client/theme-default/components/VPPage.vue +5 -0
- package/dist/client/theme-default/components/VPSidebar.vue +2 -2
- package/dist/client/theme-default/components/VPSponsors.vue +77 -0
- package/dist/client/theme-default/components/VPSponsorsGrid.vue +32 -0
- package/dist/client/theme-default/components/VPSwitchAppearance.vue +3 -3
- package/dist/client/theme-default/components/icons/VPIconHeart.vue +5 -0
- package/dist/client/theme-default/composables/outline.js +12 -20
- package/dist/client/theme-default/composables/sponsor-grid.js +92 -0
- package/dist/client/theme-default/index.js +6 -1
- package/dist/client/theme-default/styles/base.css +3 -0
- package/dist/client/theme-default/styles/components/custom-block.css +90 -0
- package/dist/client/theme-default/styles/{vp-doc.css → components/vp-doc.css} +63 -11
- package/dist/client/theme-default/styles/components/vp-sponsor.css +86 -0
- package/dist/client/theme-default/styles/vars.css +150 -29
- package/dist/client/theme-default/support/utils.js +19 -0
- package/dist/node/cli.js +1 -1
- package/dist/node/index.d.ts +22 -1
- package/dist/node/index.js +1 -1
- package/dist/node/{serve-428d4610.js → serve-b3182d88.js} +50 -8
- package/package.json +2 -1
- package/types/default-theme.d.ts +12 -0
- package/types/shared.d.ts +14 -6
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { watchEffect } from 'vue';
|
|
2
|
+
import { createTitle } from '../../shared';
|
|
2
3
|
export function useUpdateHead(route, siteDataByRouteRef) {
|
|
3
4
|
let managedHeadTags = [];
|
|
4
5
|
let isFirstUpdate = true;
|
|
@@ -50,11 +51,10 @@ export function useUpdateHead(route, siteDataByRouteRef) {
|
|
|
50
51
|
watchEffect(() => {
|
|
51
52
|
const pageData = route.data;
|
|
52
53
|
const siteData = siteDataByRouteRef.value;
|
|
53
|
-
const pageTitle = pageData && pageData.title;
|
|
54
54
|
const pageDescription = pageData && pageData.description;
|
|
55
55
|
const frontmatterHead = pageData && pageData.frontmatter.head;
|
|
56
56
|
// update title and description
|
|
57
|
-
document.title = (
|
|
57
|
+
document.title = createTitle(siteData, pageData);
|
|
58
58
|
document
|
|
59
59
|
.querySelector(`meta[name=description]`)
|
|
60
60
|
.setAttribute('content', pageDescription || siteData.description);
|
package/dist/client/app/data.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { shallowRef, readonly, computed, inject } from 'vue';
|
|
2
2
|
import serializedSiteData from '@siteData';
|
|
3
|
-
import { resolveSiteDataByRoute } from '../shared';
|
|
3
|
+
import { resolveSiteDataByRoute, createTitle } from '../shared';
|
|
4
4
|
import { withBase } from './utils';
|
|
5
5
|
export const dataSymbol = Symbol();
|
|
6
6
|
export const siteDataRef = shallowRef(parse(serializedSiteData));
|
|
@@ -29,9 +29,7 @@ export function initData(route) {
|
|
|
29
29
|
return withBase(path || '/');
|
|
30
30
|
}),
|
|
31
31
|
title: computed(() => {
|
|
32
|
-
return route.data
|
|
33
|
-
? route.data.title + ' | ' + site.value.title
|
|
34
|
-
: site.value.title;
|
|
32
|
+
return createTitle(site.value, route.data);
|
|
35
33
|
}),
|
|
36
34
|
description: computed(() => {
|
|
37
35
|
return route.data.description || site.value.description;
|
package/dist/client/index.d.ts
CHANGED
|
@@ -40,6 +40,7 @@ export declare const inBrowser: boolean;
|
|
|
40
40
|
export declare interface LocaleConfig {
|
|
41
41
|
lang: string
|
|
42
42
|
title?: string
|
|
43
|
+
titleTemplate?: string | boolean
|
|
43
44
|
description?: string
|
|
44
45
|
head?: HeadConfig[]
|
|
45
46
|
label?: string
|
|
@@ -49,6 +50,7 @@ export declare interface LocaleConfig {
|
|
|
49
50
|
export declare interface PageData {
|
|
50
51
|
relativePath: string
|
|
51
52
|
title: string
|
|
53
|
+
titleTemplate?: string | boolean
|
|
52
54
|
description: string
|
|
53
55
|
headers: Header[]
|
|
54
56
|
frontmatter: Record<string, any>
|
|
@@ -68,17 +70,23 @@ export declare interface Router {
|
|
|
68
70
|
|
|
69
71
|
export declare interface SiteData<ThemeConfig = any> {
|
|
70
72
|
base: string
|
|
73
|
+
|
|
71
74
|
/**
|
|
72
75
|
* Language of the site as it should be set on the `html` element.
|
|
76
|
+
*
|
|
73
77
|
* @example `en-US`, `zh-CN`
|
|
74
78
|
*/
|
|
75
79
|
lang: string
|
|
80
|
+
|
|
76
81
|
title: string
|
|
82
|
+
titleTemplate?: string | boolean
|
|
77
83
|
description: string
|
|
78
84
|
head: HeadConfig[]
|
|
85
|
+
appearance: boolean
|
|
79
86
|
themeConfig: ThemeConfig
|
|
80
87
|
scrollOffset: number | string
|
|
81
88
|
locales: Record<string, LocaleConfig>
|
|
89
|
+
|
|
82
90
|
/**
|
|
83
91
|
* Available locales for the site when it has defined `locales` in its
|
|
84
92
|
* `themeConfig`. This object is otherwise empty. Keys are paths like `/` or
|
package/dist/client/shared.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export const EXTERNAL_URL_RE = /^https?:/i;
|
|
2
|
+
export const APPEARANCE_KEY = 'vitepress-theme-appearance';
|
|
2
3
|
// @ts-ignore
|
|
3
4
|
export const inBrowser = typeof window !== 'undefined';
|
|
4
5
|
function findMatchRoot(route, roots) {
|
|
@@ -52,6 +53,27 @@ export function resolveSiteDataByRoute(siteData, route) {
|
|
|
52
53
|
langs: createLangDictionary(siteData)
|
|
53
54
|
});
|
|
54
55
|
}
|
|
56
|
+
/**
|
|
57
|
+
* Create the page title string based on configs.
|
|
58
|
+
*/
|
|
59
|
+
export function createTitle(siteData, pageData) {
|
|
60
|
+
const title = pageData.title || siteData.title;
|
|
61
|
+
const template = pageData.titleTemplate ?? siteData.titleTemplate;
|
|
62
|
+
const templateString = createTitleTemplate(siteData.title, template);
|
|
63
|
+
return `${title}${templateString}`;
|
|
64
|
+
}
|
|
65
|
+
function createTitleTemplate(siteTitle, template) {
|
|
66
|
+
if (template === false) {
|
|
67
|
+
return '';
|
|
68
|
+
}
|
|
69
|
+
if (template === true || template === undefined) {
|
|
70
|
+
return ` | ${siteTitle}`;
|
|
71
|
+
}
|
|
72
|
+
if (siteTitle === template) {
|
|
73
|
+
return '';
|
|
74
|
+
}
|
|
75
|
+
return ` | ${template}`;
|
|
76
|
+
}
|
|
55
77
|
/**
|
|
56
78
|
* Clean up the route by removing the `base` path if it's set in config.
|
|
57
79
|
*/
|
|
@@ -7,6 +7,7 @@ import VPNav from './components/VPNav.vue'
|
|
|
7
7
|
import VPLocalNav from './components/VPLocalNav.vue'
|
|
8
8
|
import VPSidebar from './components/VPSidebar.vue'
|
|
9
9
|
import VPContent from './components/VPContent.vue'
|
|
10
|
+
import VPFooter from './components/VPFooter.vue'
|
|
10
11
|
|
|
11
12
|
const {
|
|
12
13
|
isOpen: isSidebarOpen,
|
|
@@ -26,6 +27,22 @@ provide('close-sidebar', closeSidebar)
|
|
|
26
27
|
<VPNav />
|
|
27
28
|
<VPLocalNav :open="isSidebarOpen" @open-menu="openSidebar" />
|
|
28
29
|
<VPSidebar :open="isSidebarOpen" />
|
|
29
|
-
|
|
30
|
+
|
|
31
|
+
<VPContent>
|
|
32
|
+
<template #home-hero-before><slot name="home-hero-before" /></template>
|
|
33
|
+
<template #home-hero-after><slot name="home-hero-after" /></template>
|
|
34
|
+
<template #home-features-before><slot name="home-features-before" /></template>
|
|
35
|
+
<template #home-features-after><slot name="home-features-after" /></template>
|
|
36
|
+
</VPContent>
|
|
37
|
+
|
|
38
|
+
<VPFooter />
|
|
30
39
|
</div>
|
|
31
40
|
</template>
|
|
41
|
+
|
|
42
|
+
<style scoped>
|
|
43
|
+
.Layout {
|
|
44
|
+
display: flex;
|
|
45
|
+
flex-direction: column;
|
|
46
|
+
min-height: 100vh;
|
|
47
|
+
}
|
|
48
|
+
</style>
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
defineProps<{
|
|
3
|
+
icon?: string
|
|
4
|
+
title: string
|
|
5
|
+
details: string
|
|
6
|
+
}>()
|
|
7
|
+
</script>
|
|
8
|
+
|
|
9
|
+
<template>
|
|
10
|
+
<article class="VPBox">
|
|
11
|
+
<div v-if="icon" class="icon">{{ icon }}</div>
|
|
12
|
+
<h1 class="title">{{ title }}</h1>
|
|
13
|
+
<p class="details">{{ details }}</p>
|
|
14
|
+
</article>
|
|
15
|
+
</template>
|
|
16
|
+
|
|
17
|
+
<style scoped>
|
|
18
|
+
.VPBox {
|
|
19
|
+
border: 1px solid var(--vp-c-divider-light);
|
|
20
|
+
border-radius: 8px;
|
|
21
|
+
padding: 24px;
|
|
22
|
+
height: 100%;
|
|
23
|
+
background-color: var(--vp-c-bg-soft);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.dark .VPBox {
|
|
27
|
+
background-color: var(--vp-c-bg-mute);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.icon {
|
|
31
|
+
display: flex;
|
|
32
|
+
justify-content: center;
|
|
33
|
+
align-items: center;
|
|
34
|
+
margin-bottom: 20px;
|
|
35
|
+
border-radius: 6px;
|
|
36
|
+
background-color: var(--vp-c-gray-light-4);
|
|
37
|
+
width: 48px;
|
|
38
|
+
height: 48px;
|
|
39
|
+
font-size: 24px;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.dark .icon {
|
|
43
|
+
background-color: var(--vp-c-bg-soft);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.title {
|
|
47
|
+
line-height: 24px;
|
|
48
|
+
font-size: 16px;
|
|
49
|
+
font-weight: 600;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.details {
|
|
53
|
+
padding-top: 8px;
|
|
54
|
+
line-height: 24px;
|
|
55
|
+
font-size: 14px;
|
|
56
|
+
font-weight: 500;
|
|
57
|
+
color: var(--vp-c-text-2);
|
|
58
|
+
}
|
|
59
|
+
</style>
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { computed } from 'vue'
|
|
3
|
+
|
|
4
|
+
const props = defineProps<{
|
|
5
|
+
tag?: string
|
|
6
|
+
size?: 'medium' | 'big'
|
|
7
|
+
theme?: 'brand' | 'alt' | 'sponsor'
|
|
8
|
+
text: string
|
|
9
|
+
href?: string
|
|
10
|
+
}>()
|
|
11
|
+
|
|
12
|
+
const classes = computed(() => [
|
|
13
|
+
props.size ?? 'medium',
|
|
14
|
+
props.theme ?? 'brand'
|
|
15
|
+
])
|
|
16
|
+
|
|
17
|
+
const isExternal = computed(() => props.href && /^[a-z]+:/i.test(props.href))
|
|
18
|
+
|
|
19
|
+
const component = computed(() => {
|
|
20
|
+
if (props.tag) {
|
|
21
|
+
return props.tag
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return props.href ? 'a' : 'button'
|
|
25
|
+
})
|
|
26
|
+
</script>
|
|
27
|
+
|
|
28
|
+
<template>
|
|
29
|
+
<component
|
|
30
|
+
:is="component"
|
|
31
|
+
class="VPButton"
|
|
32
|
+
:class="classes"
|
|
33
|
+
:href="href"
|
|
34
|
+
:target="isExternal ? '_blank' : undefined"
|
|
35
|
+
:rel="isExternal ? 'noopener noreferrer' : undefined"
|
|
36
|
+
>
|
|
37
|
+
{{ text }}
|
|
38
|
+
</component>
|
|
39
|
+
</template>
|
|
40
|
+
|
|
41
|
+
<style scoped>
|
|
42
|
+
.VPButton {
|
|
43
|
+
display: inline-block;
|
|
44
|
+
border: 1px solid transparent;
|
|
45
|
+
|
|
46
|
+
text-align: center;
|
|
47
|
+
font-weight: 500;
|
|
48
|
+
white-space: nowrap;
|
|
49
|
+
transition: color 0.25s, border-color 0.25s, background-color 0.25s;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.VPButton:active {
|
|
53
|
+
transition: color 0.1s, border-color 0.1s, background-color 0.1s;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.VPButton.medium {
|
|
57
|
+
border-radius: 20px;
|
|
58
|
+
padding: 0 20px;
|
|
59
|
+
line-height: 38px;
|
|
60
|
+
font-size: 14px;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.VPButton.big {
|
|
64
|
+
border-radius: 24px;
|
|
65
|
+
padding: 0 24px;
|
|
66
|
+
line-height: 46px;
|
|
67
|
+
font-size: 16px;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.VPButton.brand {
|
|
71
|
+
border-color: var(--vp-button-brand-border);
|
|
72
|
+
color: var(--vp-button-brand-text);
|
|
73
|
+
background-color: var(--vp-button-brand-bg);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
.VPButton.brand:hover {
|
|
77
|
+
border-color: var(--vp-button-brand-hover-border);
|
|
78
|
+
color: var(--vp-button-brand-hover-text);
|
|
79
|
+
background-color: var(--vp-button-brand-hover-bg);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
.VPButton.brand:active {
|
|
83
|
+
border-color: var(--vp-button-brand-active-border);
|
|
84
|
+
color: var(--vp-button-brand-active-text);
|
|
85
|
+
background-color: var(--vp-button-brand-active-bg);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
.VPButton.alt {
|
|
89
|
+
border-color: var(--vp-button-alt-border);
|
|
90
|
+
color: var(--vp-button-alt-text);
|
|
91
|
+
background-color: var(--vp-button-alt-bg);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
.VPButton.alt:hover {
|
|
95
|
+
border-color: var(--vp-button-alt-hover-border);
|
|
96
|
+
color: var(--vp-button-alt-hover-text);
|
|
97
|
+
background-color: var(--vp-button-alt-hover-bg);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
.VPButton.alt:active {
|
|
101
|
+
border-color: var(--vp-button-alt-active-border);
|
|
102
|
+
color: var(--vp-button-alt-active-text);
|
|
103
|
+
background-color: var(--vp-button-alt-active-bg);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
.VPButton.sponsor {
|
|
107
|
+
border-color: var(--vp-button-sponsor-border);
|
|
108
|
+
color: var(--vp-button-sponsor-text);
|
|
109
|
+
background-color: var(--vp-button-sponsor-bg);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
.VPButton.sponsor:hover {
|
|
113
|
+
border-color: var(--vp-button-sponsor-hover-border);
|
|
114
|
+
color: var(--vp-button-sponsor-hover-text);
|
|
115
|
+
background-color: var(--vp-button-sponsor-hover-bg);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
.VPButton.sponsor:active {
|
|
119
|
+
border-color: var(--vp-button-sponsor-active-border);
|
|
120
|
+
color: var(--vp-button-sponsor-active-text);
|
|
121
|
+
background-color: var(--vp-button-sponsor-active-bg);
|
|
122
|
+
}
|
|
123
|
+
</style>
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import { useRoute } from 'vitepress'
|
|
2
|
+
import { useRoute, useData } from 'vitepress'
|
|
3
3
|
import { useSidebar } from '../composables/sidebar'
|
|
4
4
|
import NotFound from '../NotFound.vue'
|
|
5
|
-
import
|
|
5
|
+
import VPPage from './VPPage.vue'
|
|
6
|
+
import VPHome from './VPHome.vue'
|
|
7
|
+
import VPDoc from './VPDoc.vue'
|
|
6
8
|
|
|
7
9
|
const route = useRoute()
|
|
10
|
+
const { frontmatter } = useData()
|
|
8
11
|
const { hasSidebar } = useSidebar()
|
|
9
12
|
</script>
|
|
10
13
|
|
|
@@ -12,33 +15,54 @@ const { hasSidebar } = useSidebar()
|
|
|
12
15
|
<div
|
|
13
16
|
class="VPContent"
|
|
14
17
|
id="VPContent"
|
|
15
|
-
:class="{
|
|
18
|
+
:class="{
|
|
19
|
+
'has-sidebar': hasSidebar,
|
|
20
|
+
'is-home': frontmatter.layout === 'home'
|
|
21
|
+
}"
|
|
16
22
|
>
|
|
17
23
|
<NotFound v-if="route.component === NotFound" />
|
|
18
|
-
|
|
24
|
+
|
|
25
|
+
<VPPage v-else-if="frontmatter.layout === 'page'" />
|
|
26
|
+
|
|
27
|
+
<VPHome v-else-if="frontmatter.layout === 'home'">
|
|
28
|
+
<template #home-hero-before><slot name="home-hero-before" /></template>
|
|
29
|
+
<template #home-hero-after><slot name="home-hero-after" /></template>
|
|
30
|
+
<template #home-features-before><slot name="home-features-before" /></template>
|
|
31
|
+
<template #home-features-after><slot name="home-features-after" /></template>
|
|
32
|
+
</VPHome>
|
|
33
|
+
|
|
34
|
+
<VPDoc v-else />
|
|
19
35
|
</div>
|
|
20
36
|
</template>
|
|
21
37
|
|
|
22
38
|
<style scoped>
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
39
|
+
.VPContent {
|
|
40
|
+
flex-grow: 1;
|
|
41
|
+
flex-shrink: 0;
|
|
42
|
+
margin: 0 auto;
|
|
43
|
+
width: 100%;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.VPContent.is-home {
|
|
47
|
+
width: 100%;
|
|
48
|
+
max-width: 100%;
|
|
27
49
|
}
|
|
28
50
|
|
|
29
51
|
@media (min-width: 960px) {
|
|
30
52
|
.VPContent {
|
|
31
|
-
padding-top: var(--vp-nav-height
|
|
53
|
+
padding-top: var(--vp-nav-height);
|
|
32
54
|
}
|
|
33
55
|
|
|
34
56
|
.VPContent.has-sidebar {
|
|
57
|
+
margin: 0;
|
|
35
58
|
padding-left: var(--vp-sidebar-width);
|
|
36
59
|
}
|
|
37
60
|
}
|
|
38
61
|
|
|
39
62
|
@media (min-width: 1440px) {
|
|
40
63
|
.VPContent.has-sidebar {
|
|
41
|
-
padding-
|
|
64
|
+
padding-right: calc((100vw - var(--vp-layout-max-width)) / 2);
|
|
65
|
+
padding-left: calc((100vw - var(--vp-layout-max-width)) / 2 + var(--vp-sidebar-width));
|
|
42
66
|
}
|
|
43
67
|
}
|
|
44
68
|
</style>
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import { computed } from 'vue'
|
|
3
3
|
import { useData } from 'vitepress'
|
|
4
|
-
import
|
|
5
|
-
import
|
|
4
|
+
import { useSidebar } from '../composables/sidebar'
|
|
5
|
+
import VPDocOutline from './VPDocOutline.vue'
|
|
6
|
+
import VPDocFooter from './VPDocFooter.vue'
|
|
6
7
|
|
|
7
8
|
const { page } = useData()
|
|
9
|
+
const { hasSidebar } = useSidebar()
|
|
8
10
|
|
|
9
11
|
const pageName = computed(() => {
|
|
10
12
|
return page.value.relativePath.slice(0, page.value.relativePath.indexOf('/'))
|
|
@@ -12,95 +14,101 @@ const pageName = computed(() => {
|
|
|
12
14
|
</script>
|
|
13
15
|
|
|
14
16
|
<template>
|
|
15
|
-
<div class="
|
|
17
|
+
<div class="VPDoc" :class="{ 'has-sidebar': hasSidebar }">
|
|
16
18
|
<div class="container">
|
|
17
19
|
<div class="aside">
|
|
18
20
|
<div class="aside-container">
|
|
19
21
|
<div class="aside-curtain" />
|
|
20
22
|
<div class="aside-content">
|
|
21
|
-
<
|
|
23
|
+
<VPDocOutline v-if="page.headers" />
|
|
22
24
|
</div>
|
|
23
25
|
</div>
|
|
24
26
|
</div>
|
|
25
27
|
|
|
26
28
|
<div class="content">
|
|
27
|
-
<
|
|
28
|
-
<
|
|
29
|
-
|
|
29
|
+
<div class="content-container">
|
|
30
|
+
<main class="main">
|
|
31
|
+
<Content class="vp-doc" :class="pageName" />
|
|
32
|
+
</main>
|
|
30
33
|
|
|
31
|
-
|
|
34
|
+
<VPDocFooter />
|
|
35
|
+
</div>
|
|
32
36
|
</div>
|
|
33
37
|
</div>
|
|
34
38
|
</div>
|
|
35
39
|
</template>
|
|
36
40
|
|
|
37
41
|
<style scoped>
|
|
38
|
-
.
|
|
42
|
+
.VPDoc {
|
|
39
43
|
padding: 32px 24px 96px;
|
|
44
|
+
width: 100%;
|
|
40
45
|
}
|
|
41
46
|
|
|
42
47
|
@media (min-width: 768px) {
|
|
43
|
-
.
|
|
48
|
+
.VPDoc {
|
|
44
49
|
padding: 48px 32px 128px;
|
|
45
50
|
}
|
|
46
51
|
}
|
|
47
52
|
|
|
48
53
|
@media (min-width: 960px) {
|
|
49
|
-
.
|
|
50
|
-
padding: 32px
|
|
54
|
+
.VPDoc {
|
|
55
|
+
padding: 32px 32px 128px;
|
|
51
56
|
}
|
|
52
|
-
}
|
|
53
57
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
58
|
+
.VPDoc:not(.has-sidebar) .container {
|
|
59
|
+
display: flex;
|
|
60
|
+
justify-content: center;
|
|
61
|
+
max-width: 992px;
|
|
57
62
|
}
|
|
58
63
|
|
|
59
|
-
.
|
|
60
|
-
|
|
64
|
+
.VPDoc:not(.has-sidebar) .aside {
|
|
65
|
+
display: block;
|
|
61
66
|
}
|
|
62
67
|
|
|
63
|
-
.
|
|
64
|
-
|
|
68
|
+
.VPDoc:not(.has-sidebar) .content {
|
|
69
|
+
max-width: 752px;
|
|
65
70
|
}
|
|
71
|
+
}
|
|
66
72
|
|
|
67
|
-
|
|
68
|
-
|
|
73
|
+
@media (min-width: 1280px) {
|
|
74
|
+
.VPDoc .container {
|
|
75
|
+
display: flex;
|
|
76
|
+
justify-content: center;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.VPDoc .aside {
|
|
80
|
+
display: block;
|
|
69
81
|
}
|
|
70
82
|
}
|
|
71
83
|
|
|
72
84
|
@media (min-width: 1440px) {
|
|
73
|
-
.
|
|
74
|
-
|
|
85
|
+
.VPDoc:not(.has-sidebar) .content {
|
|
86
|
+
max-width: 784px;
|
|
75
87
|
}
|
|
76
|
-
}
|
|
77
88
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
display: flex;
|
|
89
|
+
.VPDoc:not(.has-sidebar) .container {
|
|
90
|
+
max-width: 1104px;
|
|
81
91
|
}
|
|
82
92
|
}
|
|
83
93
|
|
|
94
|
+
.container {
|
|
95
|
+
margin: 0 auto;
|
|
96
|
+
width: 100%;
|
|
97
|
+
}
|
|
98
|
+
|
|
84
99
|
.aside {
|
|
85
100
|
position: relative;
|
|
86
101
|
display: none;
|
|
87
102
|
order: 2;
|
|
88
|
-
flex-shrink: 0;
|
|
89
103
|
flex-grow: 1;
|
|
90
|
-
|
|
91
|
-
padding-
|
|
92
|
-
min-width:
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
@media (min-width: 1280px) {
|
|
96
|
-
.aside {
|
|
97
|
-
display: block;
|
|
98
|
-
}
|
|
104
|
+
flex-shrink: 0;
|
|
105
|
+
padding-left: 32px;
|
|
106
|
+
min-width: 240px;
|
|
99
107
|
}
|
|
100
108
|
|
|
101
109
|
@media (min-width: 1440px) {
|
|
102
110
|
.aside {
|
|
103
|
-
padding-left:
|
|
111
|
+
padding-left: 64px;
|
|
104
112
|
}
|
|
105
113
|
}
|
|
106
114
|
|
|
@@ -109,7 +117,7 @@ const pageName = computed(() => {
|
|
|
109
117
|
top: var(--vp-nav-height-desktop);
|
|
110
118
|
bottom: 0;
|
|
111
119
|
padding-top: 32px;
|
|
112
|
-
width:
|
|
120
|
+
width: 208px;
|
|
113
121
|
overflow-x: hidden;
|
|
114
122
|
overflow-y: auto;
|
|
115
123
|
}
|
|
@@ -140,17 +148,33 @@ const pageName = computed(() => {
|
|
|
140
148
|
.content {
|
|
141
149
|
position: relative;
|
|
142
150
|
margin: 0 auto;
|
|
143
|
-
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
@media (min-width: 960px) {
|
|
154
|
+
.content {
|
|
155
|
+
padding: 0 32px;
|
|
156
|
+
}
|
|
144
157
|
}
|
|
145
158
|
|
|
146
159
|
@media (min-width: 1280px) {
|
|
147
160
|
.content {
|
|
148
161
|
order: 1;
|
|
149
162
|
margin: 0;
|
|
150
|
-
min-width:
|
|
163
|
+
min-width: 640px;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
@media (min-width: 1440px) {
|
|
168
|
+
.content {
|
|
169
|
+
padding-left: 64px;
|
|
151
170
|
}
|
|
152
171
|
}
|
|
153
172
|
|
|
173
|
+
.content-container {
|
|
174
|
+
margin: 0 auto;
|
|
175
|
+
max-width: 688px;
|
|
176
|
+
}
|
|
177
|
+
|
|
154
178
|
.edit-link {
|
|
155
179
|
margin: 0 0 32px;
|
|
156
180
|
}
|
|
@@ -13,7 +13,7 @@ const control = usePrevNext()
|
|
|
13
13
|
</script>
|
|
14
14
|
|
|
15
15
|
<template>
|
|
16
|
-
<footer v-if="control.prev || control.next" class="
|
|
16
|
+
<footer v-if="control.prev || control.next" class="VPDocFooter">
|
|
17
17
|
<div v-if="theme.editLink && frontmatter.editLink !== false" class="edit-link">
|
|
18
18
|
<VPLink class="edit-link-button" :href="editLink.url" :no-icon="true">
|
|
19
19
|
<VPIconEdit class="edit-link-icon" />
|
|
@@ -39,7 +39,7 @@ const control = usePrevNext()
|
|
|
39
39
|
</template>
|
|
40
40
|
|
|
41
41
|
<style scoped>
|
|
42
|
-
.
|
|
42
|
+
.VPDocFooter {
|
|
43
43
|
margin-top: 64px;
|
|
44
44
|
}
|
|
45
45
|
|
|
@@ -94,6 +94,7 @@ const control = usePrevNext()
|
|
|
94
94
|
}
|
|
95
95
|
|
|
96
96
|
.pager.has-prev {
|
|
97
|
+
padding-top: 0;
|
|
97
98
|
padding-left: 16px;
|
|
98
99
|
}
|
|
99
100
|
}
|
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import { ref, computed } from 'vue'
|
|
3
3
|
import { useData } from 'vitepress'
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
resolveHeaders,
|
|
6
|
+
useOutline,
|
|
7
|
+
useActiveAnchor
|
|
8
|
+
} from '../composables/outline'
|
|
5
9
|
|
|
6
10
|
const { page, frontmatter } = useData()
|
|
7
11
|
|
|
12
|
+
const { hasOutline } = useOutline()
|
|
13
|
+
|
|
8
14
|
const container = ref()
|
|
9
15
|
const marker = ref()
|
|
10
16
|
|
|
@@ -22,7 +28,7 @@ function handleClick({ target: el }: Event) {
|
|
|
22
28
|
</script>
|
|
23
29
|
|
|
24
30
|
<template>
|
|
25
|
-
<div class="
|
|
31
|
+
<div class="VPDocOutline" :class="{ 'has-outline': hasOutline }" ref="container">
|
|
26
32
|
<div class="outline-marker" ref="marker" />
|
|
27
33
|
|
|
28
34
|
<div class="outline-title">On this page</div>
|
|
@@ -54,14 +60,19 @@ function handleClick({ target: el }: Event) {
|
|
|
54
60
|
</template>
|
|
55
61
|
|
|
56
62
|
<style scoped>
|
|
57
|
-
.
|
|
63
|
+
.VPDocOutline {
|
|
58
64
|
position: relative;
|
|
65
|
+
display: none;
|
|
59
66
|
border-left: 1px solid var(--vp-c-divider-light);
|
|
60
67
|
padding-left: 16px;
|
|
61
68
|
font-size: 13px;
|
|
62
69
|
font-weight: 500;
|
|
63
70
|
}
|
|
64
71
|
|
|
72
|
+
.VPDocOutline.has-outline {
|
|
73
|
+
display: block;
|
|
74
|
+
}
|
|
75
|
+
|
|
65
76
|
.outline-marker {
|
|
66
77
|
position: absolute;
|
|
67
78
|
top: 32px;
|