vitepress 1.0.0-alpha.1 → 1.0.0-alpha.2
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/devtools.js +28 -0
- package/dist/client/app/index.js +5 -21
- package/dist/client/app/router.js +21 -11
- package/dist/client/index.d.ts +1 -3
- package/dist/client/index.js +0 -2
- package/dist/client/shared.js +8 -0
- package/dist/client/theme-default/Layout.vue +3 -0
- package/dist/client/theme-default/components/VPButton.vue +2 -1
- package/dist/client/theme-default/components/VPContent.vue +3 -0
- package/dist/client/theme-default/components/VPDoc.vue +7 -6
- package/dist/client/theme-default/components/VPDocAsideOutline.vue +4 -2
- package/dist/client/theme-default/components/VPDocFooter.vue +10 -8
- package/dist/client/theme-default/components/{VPBox.vue → VPFeature.vue} +4 -4
- package/dist/client/theme-default/components/VPFeatures.vue +107 -0
- package/dist/client/theme-default/components/VPFlyout.vue +1 -1
- package/dist/client/theme-default/components/VPHero.vue +17 -12
- package/dist/client/theme-default/components/VPHome.vue +2 -0
- package/dist/client/theme-default/components/VPHomeFeatures.vue +6 -89
- package/dist/client/theme-default/components/VPHomeHero.vue +9 -9
- package/dist/client/theme-default/components/VPHomeSponsors.vue +1 -1
- package/dist/client/theme-default/components/VPNav.vue +6 -1
- package/dist/client/theme-default/components/VPNavBar.vue +8 -1
- package/dist/client/theme-default/components/VPNavBarTitle.vue +1 -2
- package/dist/client/theme-default/components/VPSidebar.vue +2 -4
- package/dist/client/theme-default/components/VPSidebarGroup.vue +7 -2
- package/dist/client/theme-default/components/VPSidebarLink.vue +16 -12
- package/dist/client/theme-default/composables/edit-link.js +4 -15
- package/dist/node/cli.js +2 -2
- package/dist/node/index.d.ts +18 -20
- package/dist/node/index.js +1 -1
- package/dist/node/{serve-e8d58be3.js → serve-42a92e2f.js} +48 -37
- package/dist/node-cjs/cli.cjs +2 -2
- package/dist/node-cjs/index.cjs +1 -1
- package/dist/node-cjs/{serve-2fc02922.cjs → serve-507b373b.cjs} +51 -40
- package/package.json +3 -2
- package/types/default-theme.d.ts +17 -19
- package/types/shared.d.ts +5 -0
- package/dist/client/app/components/Debug.vue +0 -86
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { setupDevtoolsPlugin } from '@vue/devtools-api';
|
|
2
|
+
const COMPONENT_STATE_TYPE = 'VitePress';
|
|
3
|
+
export const setupDevtools = (app, router, data) => {
|
|
4
|
+
setupDevtoolsPlugin({
|
|
5
|
+
// fix recursive reference
|
|
6
|
+
app: app,
|
|
7
|
+
id: 'org.vuejs.vitepress',
|
|
8
|
+
label: 'VitePress',
|
|
9
|
+
packageName: 'vitepress',
|
|
10
|
+
homepage: 'https://vitepress.vuejs.org',
|
|
11
|
+
componentStateTypes: [COMPONENT_STATE_TYPE]
|
|
12
|
+
}, (api) => {
|
|
13
|
+
api.on.inspectComponent((payload) => {
|
|
14
|
+
payload.instanceData.state.push({
|
|
15
|
+
type: COMPONENT_STATE_TYPE,
|
|
16
|
+
key: 'route',
|
|
17
|
+
value: router.route,
|
|
18
|
+
editable: false
|
|
19
|
+
});
|
|
20
|
+
payload.instanceData.state.push({
|
|
21
|
+
type: COMPONENT_STATE_TYPE,
|
|
22
|
+
key: 'data',
|
|
23
|
+
value: data,
|
|
24
|
+
editable: false
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
};
|
package/dist/client/app/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createApp as createClientApp, createSSRApp,
|
|
1
|
+
import { createApp as createClientApp, createSSRApp, h, onMounted, watch } from 'vue';
|
|
2
2
|
import Theme from '/@theme/index';
|
|
3
3
|
import { inBrowser, pathToFile } from './utils';
|
|
4
4
|
import { RouterSymbol, createRouter } from './router';
|
|
@@ -28,7 +28,6 @@ const VitePressApp = {
|
|
|
28
28
|
};
|
|
29
29
|
export function createApp() {
|
|
30
30
|
const router = newRouter();
|
|
31
|
-
handleHMR(router);
|
|
32
31
|
const app = newApp();
|
|
33
32
|
app.provide(RouterSymbol, router);
|
|
34
33
|
const data = initData(router.route);
|
|
@@ -36,9 +35,6 @@ export function createApp() {
|
|
|
36
35
|
// install global components
|
|
37
36
|
app.component('Content', Content);
|
|
38
37
|
app.component('ClientOnly', ClientOnly);
|
|
39
|
-
app.component('Debug', import.meta.env.PROD
|
|
40
|
-
? () => null
|
|
41
|
-
: defineAsyncComponent(() => import('./components/Debug.vue')));
|
|
42
38
|
// expose $frontmatter
|
|
43
39
|
Object.defineProperty(app.config.globalProperties, '$frontmatter', {
|
|
44
40
|
get() {
|
|
@@ -52,6 +48,10 @@ export function createApp() {
|
|
|
52
48
|
siteData: siteDataRef
|
|
53
49
|
});
|
|
54
50
|
}
|
|
51
|
+
// setup devtools in dev mode
|
|
52
|
+
if (import.meta.env.DEV || __VUE_PROD_DEVTOOLS__) {
|
|
53
|
+
import('./devtools').then(({ setupDevtools }) => setupDevtools(app, router, data));
|
|
54
|
+
}
|
|
55
55
|
return { app, router, data };
|
|
56
56
|
}
|
|
57
57
|
function newApp() {
|
|
@@ -79,22 +79,6 @@ function newRouter() {
|
|
|
79
79
|
return import(/*@vite-ignore*/ pageFilePath);
|
|
80
80
|
}, NotFound);
|
|
81
81
|
}
|
|
82
|
-
function handleHMR(router) {
|
|
83
|
-
// update route.data on HMR updates of active page
|
|
84
|
-
if (import.meta.hot) {
|
|
85
|
-
// hot reload pageData
|
|
86
|
-
import.meta.hot.on('vitepress:pageData', (payload) => {
|
|
87
|
-
if (shouldHotReload(payload)) {
|
|
88
|
-
router.route.data = payload.pageData;
|
|
89
|
-
}
|
|
90
|
-
});
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
function shouldHotReload(payload) {
|
|
94
|
-
const payloadPath = payload.path.replace(/(\bindex)?\.md$/, '');
|
|
95
|
-
const locationPath = location.pathname.replace(/(\bindex)?\.html$/, '');
|
|
96
|
-
return payloadPath === locationPath;
|
|
97
|
-
}
|
|
98
82
|
if (inBrowser) {
|
|
99
83
|
const { app, router, data } = createApp();
|
|
100
84
|
// wait until page component is fetched before mounting
|
|
@@ -1,18 +1,11 @@
|
|
|
1
1
|
import { reactive, inject, markRaw, nextTick, readonly } from 'vue';
|
|
2
|
+
import { notFoundPageData } from '../shared';
|
|
2
3
|
import { inBrowser, withBase } from './utils';
|
|
3
4
|
import { siteDataRef } from './data';
|
|
4
5
|
export const RouterSymbol = Symbol();
|
|
5
6
|
// we are just using URL to parse the pathname and hash - the base doesn't
|
|
6
7
|
// matter and is only passed to support same-host hrefs.
|
|
7
8
|
const fakeHost = `http://a.com`;
|
|
8
|
-
const notFoundPageData = {
|
|
9
|
-
relativePath: '',
|
|
10
|
-
title: '404',
|
|
11
|
-
description: 'Not Found',
|
|
12
|
-
headers: [],
|
|
13
|
-
frontmatter: {},
|
|
14
|
-
lastUpdated: 0
|
|
15
|
-
};
|
|
16
9
|
const getDefaultRoute = () => ({
|
|
17
10
|
path: '/',
|
|
18
11
|
component: null,
|
|
@@ -54,8 +47,8 @@ export function createRouter(loadPageModule, fallbackComponent) {
|
|
|
54
47
|
route.path = inBrowser ? pendingPath : withBase(pendingPath);
|
|
55
48
|
route.component = markRaw(comp);
|
|
56
49
|
route.data = import.meta.env.PROD
|
|
57
|
-
? markRaw(
|
|
58
|
-
: readonly(
|
|
50
|
+
? markRaw(__pageData)
|
|
51
|
+
: readonly(__pageData);
|
|
59
52
|
if (inBrowser) {
|
|
60
53
|
nextTick(() => {
|
|
61
54
|
if (targetLoc.hash && !scrollPosition) {
|
|
@@ -77,7 +70,7 @@ export function createRouter(loadPageModule, fallbackComponent) {
|
|
|
77
70
|
}
|
|
78
71
|
}
|
|
79
72
|
catch (err) {
|
|
80
|
-
if (!err.message.match(/fetch/)) {
|
|
73
|
+
if (!err.message.match(/fetch/) && !href.match(/^[\\/]404\.html$/)) {
|
|
81
74
|
console.error(err);
|
|
82
75
|
}
|
|
83
76
|
// retry on fetch fail: the page to hash map may have been invalidated
|
|
@@ -140,6 +133,7 @@ export function createRouter(loadPageModule, fallbackComponent) {
|
|
|
140
133
|
e.preventDefault();
|
|
141
134
|
});
|
|
142
135
|
}
|
|
136
|
+
handleHMR(route);
|
|
143
137
|
return {
|
|
144
138
|
route,
|
|
145
139
|
go
|
|
@@ -190,3 +184,19 @@ function scrollTo(el, hash, smooth = false) {
|
|
|
190
184
|
}
|
|
191
185
|
}
|
|
192
186
|
}
|
|
187
|
+
function handleHMR(route) {
|
|
188
|
+
// update route.data on HMR updates of active page
|
|
189
|
+
if (import.meta.hot) {
|
|
190
|
+
// hot reload pageData
|
|
191
|
+
import.meta.hot.on('vitepress:pageData', (payload) => {
|
|
192
|
+
if (shouldHotReload(payload)) {
|
|
193
|
+
route.data = payload.pageData;
|
|
194
|
+
}
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
function shouldHotReload(payload) {
|
|
199
|
+
const payloadPath = payload.path.replace(/(\bindex)?\.md$/, '');
|
|
200
|
+
const locationPath = location.pathname.replace(/(\bindex)?\.html$/, '');
|
|
201
|
+
return payloadPath === locationPath;
|
|
202
|
+
}
|
package/dist/client/index.d.ts
CHANGED
|
@@ -118,6 +118,4 @@ declare const Content: vue.DefineComponent<{}, () => vue.VNode<vue.RendererNode,
|
|
|
118
118
|
[key: string]: any;
|
|
119
119
|
}>, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, vue.EmitsOptions, string, vue.VNodeProps & vue.AllowedComponentProps & vue.ComponentCustomProps, Readonly<vue.ExtractPropTypes<{}>>, {}>;
|
|
120
120
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
export { Content, Debug, EnhanceAppContext, HeadConfig, Header, LocaleConfig, PageData, Route, Router, SiteData, Theme, VitePressData, inBrowser, useData, useRoute, useRouter, withBase };
|
|
121
|
+
export { Content, EnhanceAppContext, HeadConfig, Header, LocaleConfig, PageData, Route, Router, SiteData, Theme, VitePressData, inBrowser, useData, useRoute, useRouter, withBase };
|
package/dist/client/index.js
CHANGED
package/dist/client/shared.js
CHANGED
|
@@ -2,6 +2,14 @@ export const EXTERNAL_URL_RE = /^https?:/i;
|
|
|
2
2
|
export const APPEARANCE_KEY = 'vitepress-theme-appearance';
|
|
3
3
|
// @ts-ignore
|
|
4
4
|
export const inBrowser = typeof window !== 'undefined';
|
|
5
|
+
export const notFoundPageData = {
|
|
6
|
+
relativePath: '',
|
|
7
|
+
title: '404',
|
|
8
|
+
description: 'Not Found',
|
|
9
|
+
headers: [],
|
|
10
|
+
frontmatter: {},
|
|
11
|
+
lastUpdated: 0
|
|
12
|
+
};
|
|
5
13
|
function findMatchRoot(route, roots) {
|
|
6
14
|
// first match to the routes with the most deep level.
|
|
7
15
|
roots.sort((a, b) => {
|
|
@@ -34,6 +34,9 @@ provide('close-sidebar', closeSidebar)
|
|
|
34
34
|
<template #home-features-before><slot name="home-features-before" /></template>
|
|
35
35
|
<template #home-features-after><slot name="home-features-after" /></template>
|
|
36
36
|
|
|
37
|
+
<template #doc-before><slot name="doc-before" /></template>
|
|
38
|
+
<template #doc-after><slot name="doc-after" /></template>
|
|
39
|
+
|
|
37
40
|
<template #aside-top><slot name="aside-top" /></template>
|
|
38
41
|
<template #aside-bottom><slot name="aside-bottom" /></template>
|
|
39
42
|
<template #aside-outline-before><slot name="aside-outline-before" /></template>
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import { computed } from 'vue'
|
|
3
|
+
import { withBase } from 'vitepress'
|
|
3
4
|
|
|
4
5
|
const props = defineProps<{
|
|
5
6
|
tag?: string
|
|
@@ -30,7 +31,7 @@ const component = computed(() => {
|
|
|
30
31
|
:is="component"
|
|
31
32
|
class="VPButton"
|
|
32
33
|
:class="classes"
|
|
33
|
-
:href="href"
|
|
34
|
+
:href="href ? withBase(href) : undefined"
|
|
34
35
|
:target="isExternal ? '_blank' : undefined"
|
|
35
36
|
:rel="isExternal ? 'noopener noreferrer' : undefined"
|
|
36
37
|
>
|
|
@@ -35,6 +35,9 @@ useCopyCode()
|
|
|
35
35
|
</VPHome>
|
|
36
36
|
|
|
37
37
|
<VPDoc v-else>
|
|
38
|
+
<template #doc-before><slot name="doc-before" /></template>
|
|
39
|
+
<template #doc-after><slot name="doc-after" /></template>
|
|
40
|
+
|
|
38
41
|
<template #aside-top><slot name="aside-top" /></template>
|
|
39
42
|
<template #aside-outline-before><slot name="aside-outline-before" /></template>
|
|
40
43
|
<template #aside-outline-after><slot name="aside-outline-after" /></template>
|
|
@@ -1,16 +1,13 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import {
|
|
3
|
-
import { useData } from 'vitepress'
|
|
2
|
+
import { useRoute } from 'vitepress'
|
|
4
3
|
import { useSidebar } from '../composables/sidebar'
|
|
5
4
|
import VPDocAside from './VPDocAside.vue'
|
|
6
5
|
import VPDocFooter from './VPDocFooter.vue'
|
|
7
6
|
|
|
8
|
-
const {
|
|
7
|
+
const { path } = useRoute()
|
|
9
8
|
const { hasSidebar } = useSidebar()
|
|
10
9
|
|
|
11
|
-
const pageName =
|
|
12
|
-
return page.value.relativePath.slice(0, page.value.relativePath.indexOf('/'))
|
|
13
|
-
})
|
|
10
|
+
const pageName = path.replace(/[./]+/g, '_').replace(/_html$/, '')
|
|
14
11
|
</script>
|
|
15
12
|
|
|
16
13
|
<template>
|
|
@@ -34,11 +31,15 @@ const pageName = computed(() => {
|
|
|
34
31
|
|
|
35
32
|
<div class="content">
|
|
36
33
|
<div class="content-container">
|
|
34
|
+
<slot name="doc-before" />
|
|
35
|
+
|
|
37
36
|
<main class="main">
|
|
38
37
|
<Content class="vp-doc" :class="pageName" />
|
|
39
38
|
</main>
|
|
40
39
|
|
|
41
40
|
<VPDocFooter />
|
|
41
|
+
|
|
42
|
+
<slot name="doc-after" />
|
|
42
43
|
</div>
|
|
43
44
|
</div>
|
|
44
45
|
</div>
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
useActiveAnchor
|
|
8
8
|
} from '../composables/outline'
|
|
9
9
|
|
|
10
|
-
const { page, frontmatter } = useData()
|
|
10
|
+
const { page, frontmatter, theme } = useData()
|
|
11
11
|
|
|
12
12
|
const { hasOutline } = useOutline()
|
|
13
13
|
|
|
@@ -32,7 +32,9 @@ function handleClick({ target: el }: Event) {
|
|
|
32
32
|
<div class="content">
|
|
33
33
|
<div class="outline-marker" ref="marker" />
|
|
34
34
|
|
|
35
|
-
<div class="outline-title">
|
|
35
|
+
<div class="outline-title">
|
|
36
|
+
{{ theme.outlineTitle || 'On this page' }}
|
|
37
|
+
</div>
|
|
36
38
|
|
|
37
39
|
<nav aria-labelledby="doc-outline-aria-label">
|
|
38
40
|
<span class="visually-hidden" id="doc-outline-aria-label">
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
+
import { computed } from 'vue'
|
|
2
3
|
import { useData } from 'vitepress'
|
|
3
4
|
import { normalizeLink } from '../support/utils'
|
|
4
5
|
import { useEditLink } from '../composables/edit-link'
|
|
@@ -11,6 +12,10 @@ const { theme, page, frontmatter } = useData()
|
|
|
11
12
|
|
|
12
13
|
const editLink = useEditLink()
|
|
13
14
|
const control = usePrevNext()
|
|
15
|
+
|
|
16
|
+
const hasLastUpdated = computed(() => {
|
|
17
|
+
return page.value.lastUpdated && frontmatter.value.lastUpdated !== false
|
|
18
|
+
})
|
|
14
19
|
</script>
|
|
15
20
|
|
|
16
21
|
<template>
|
|
@@ -23,7 +28,7 @@ const control = usePrevNext()
|
|
|
23
28
|
</VPLink>
|
|
24
29
|
</div>
|
|
25
30
|
|
|
26
|
-
<div v-if="
|
|
31
|
+
<div v-if="hasLastUpdated" class="last-updated">
|
|
27
32
|
<VPDocFooterLastUpdated />
|
|
28
33
|
</div>
|
|
29
34
|
</div>
|
|
@@ -58,21 +63,18 @@ const control = usePrevNext()
|
|
|
58
63
|
.edit-info {
|
|
59
64
|
display: flex;
|
|
60
65
|
justify-content: space-between;
|
|
61
|
-
align-items:
|
|
66
|
+
align-items: center;
|
|
62
67
|
padding-bottom: 14px;
|
|
63
68
|
}
|
|
64
69
|
}
|
|
65
70
|
|
|
66
|
-
.edit-link {
|
|
67
|
-
line-height: 32px;
|
|
68
|
-
font-size: 14px;
|
|
69
|
-
font-weight: 500;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
71
|
.edit-link-button {
|
|
73
72
|
display: flex;
|
|
74
73
|
align-items: center;
|
|
75
74
|
border: 0;
|
|
75
|
+
line-height: 32px;
|
|
76
|
+
font-size: 14px;
|
|
77
|
+
font-weight: 500;
|
|
76
78
|
color: var(--vp-c-brand);
|
|
77
79
|
transition: color 0.25s;
|
|
78
80
|
}
|
|
@@ -7,16 +7,16 @@ defineProps<{
|
|
|
7
7
|
</script>
|
|
8
8
|
|
|
9
9
|
<template>
|
|
10
|
-
<article class="
|
|
10
|
+
<article class="VPFeature">
|
|
11
11
|
<div v-if="icon" class="icon">{{ icon }}</div>
|
|
12
|
-
<
|
|
12
|
+
<h2 class="title">{{ title }}</h2>
|
|
13
13
|
<p class="details">{{ details }}</p>
|
|
14
14
|
</article>
|
|
15
15
|
</template>
|
|
16
16
|
|
|
17
17
|
<style scoped>
|
|
18
|
-
.
|
|
19
|
-
border: 1px solid var(--vp-c-
|
|
18
|
+
.VPFeature {
|
|
19
|
+
border: 1px solid var(--vp-c-bg-soft);
|
|
20
20
|
border-radius: 12px;
|
|
21
21
|
padding: 24px;
|
|
22
22
|
height: 100%;
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { computed } from 'vue'
|
|
3
|
+
import VPFeature from './VPFeature.vue'
|
|
4
|
+
|
|
5
|
+
export interface Feature {
|
|
6
|
+
icon?: string
|
|
7
|
+
title: string
|
|
8
|
+
details: string
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const props = defineProps<{
|
|
12
|
+
features: Feature[]
|
|
13
|
+
}>()
|
|
14
|
+
|
|
15
|
+
const grid = computed(() => {
|
|
16
|
+
const length = props.features.length
|
|
17
|
+
|
|
18
|
+
if (!length) {
|
|
19
|
+
return
|
|
20
|
+
} else if (length === 2) {
|
|
21
|
+
return 'grid-2'
|
|
22
|
+
} else if (length === 3) {
|
|
23
|
+
return 'grid-3'
|
|
24
|
+
} else if (length % 3 === 0) {
|
|
25
|
+
return 'grid-6'
|
|
26
|
+
} else if (length % 2 === 0) {
|
|
27
|
+
return 'grid-4'
|
|
28
|
+
}
|
|
29
|
+
})
|
|
30
|
+
</script>
|
|
31
|
+
|
|
32
|
+
<template>
|
|
33
|
+
<div v-if="features" class="VPFeatures">
|
|
34
|
+
<div class="container">
|
|
35
|
+
<div class="items">
|
|
36
|
+
<div v-for="feature in features" :key="feature.title" class="item" :class="[grid]">
|
|
37
|
+
<VPFeature
|
|
38
|
+
:icon="feature.icon"
|
|
39
|
+
:title="feature.title"
|
|
40
|
+
:details="feature.details"
|
|
41
|
+
/>
|
|
42
|
+
</div>
|
|
43
|
+
</div>
|
|
44
|
+
</div>
|
|
45
|
+
</div>
|
|
46
|
+
</template>
|
|
47
|
+
|
|
48
|
+
<style scoped>
|
|
49
|
+
.VPFeatures {
|
|
50
|
+
position: relative;
|
|
51
|
+
padding: 0 24px;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
@media (min-width: 640px) {
|
|
55
|
+
.VPFeatures {
|
|
56
|
+
padding: 0 48px;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
@media (min-width: 960px) {
|
|
61
|
+
.VPFeatures {
|
|
62
|
+
padding: 0 64px;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.container {
|
|
67
|
+
margin: 0 auto;
|
|
68
|
+
max-width: 1152px;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.items {
|
|
72
|
+
display: flex;
|
|
73
|
+
flex-wrap: wrap;
|
|
74
|
+
margin: -8px;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
.item {
|
|
78
|
+
padding: 8px;
|
|
79
|
+
width: 100%;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
@media (min-width: 640px) {
|
|
83
|
+
.item.grid-2,
|
|
84
|
+
.item.grid-4,
|
|
85
|
+
.item.grid-6 {
|
|
86
|
+
width: calc(100% / 2);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
@media (min-width: 768px) {
|
|
91
|
+
.item.grid-2,
|
|
92
|
+
.item.grid-4 {
|
|
93
|
+
width: calc(100% / 2);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
.item.grid-3,
|
|
97
|
+
.item.grid-6 {
|
|
98
|
+
width: calc(100% / 3);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
@media (min-width: 960px) {
|
|
103
|
+
.item.grid-4 {
|
|
104
|
+
width: calc(100% / 4);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
</style>
|
|
@@ -25,8 +25,8 @@ defineProps<{
|
|
|
25
25
|
<div class="VPHero" :class="{ 'has-image': image }">
|
|
26
26
|
<div class="container">
|
|
27
27
|
<div class="main">
|
|
28
|
-
<
|
|
29
|
-
<
|
|
28
|
+
<h1 v-if="name" class="name"><span class="clip">{{ name }}</span></h1>
|
|
29
|
+
<p v-if="text" class="text">{{ text }}</p>
|
|
30
30
|
<p v-if="tagline" class="tagline">{{ tagline }}</p>
|
|
31
31
|
|
|
32
32
|
<div v-if="actions" class="actions">
|
|
@@ -64,11 +64,17 @@ defineProps<{
|
|
|
64
64
|
}
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
+
@media (min-width: 960px) {
|
|
68
|
+
.VPHero {
|
|
69
|
+
padding: calc(var(--vp-nav-height) + 80px) 64px 64px;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
67
73
|
.container {
|
|
68
74
|
display: flex;
|
|
69
75
|
flex-direction: column;
|
|
70
76
|
margin: 0 auto;
|
|
71
|
-
max-width:
|
|
77
|
+
max-width: 1152px;
|
|
72
78
|
}
|
|
73
79
|
|
|
74
80
|
@media (min-width: 960px) {
|
|
@@ -98,13 +104,11 @@ defineProps<{
|
|
|
98
104
|
@media (min-width: 960px) {
|
|
99
105
|
.main {
|
|
100
106
|
order: 1;
|
|
107
|
+
width: calc((100% / 3) * 2);
|
|
101
108
|
}
|
|
102
|
-
}
|
|
103
109
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
width: 100%;
|
|
107
|
-
max-width: calc((100% / 3) * 2);
|
|
110
|
+
.VPHero.has-image .main {
|
|
111
|
+
max-width: 592px;
|
|
108
112
|
}
|
|
109
113
|
}
|
|
110
114
|
|
|
@@ -115,6 +119,7 @@ defineProps<{
|
|
|
115
119
|
line-height: 40px;
|
|
116
120
|
font-size: 32px;
|
|
117
121
|
font-weight: 700;
|
|
122
|
+
white-space: pre-wrap;
|
|
118
123
|
}
|
|
119
124
|
|
|
120
125
|
.VPHero.has-image .name,
|
|
@@ -156,11 +161,12 @@ defineProps<{
|
|
|
156
161
|
}
|
|
157
162
|
|
|
158
163
|
.tagline {
|
|
159
|
-
padding-top:
|
|
164
|
+
padding-top: 8px;
|
|
160
165
|
max-width: 392px;
|
|
161
166
|
line-height: 28px;
|
|
162
167
|
font-size: 18px;
|
|
163
168
|
font-weight: 500;
|
|
169
|
+
white-space: pre-wrap;
|
|
164
170
|
color: var(--vp-c-text-2);
|
|
165
171
|
}
|
|
166
172
|
|
|
@@ -170,7 +176,7 @@ defineProps<{
|
|
|
170
176
|
|
|
171
177
|
@media (min-width: 640px) {
|
|
172
178
|
.tagline {
|
|
173
|
-
padding-top:
|
|
179
|
+
padding-top: 12px;
|
|
174
180
|
max-width: 576px;
|
|
175
181
|
line-height: 32px;
|
|
176
182
|
font-size: 20px;
|
|
@@ -179,7 +185,6 @@ defineProps<{
|
|
|
179
185
|
|
|
180
186
|
@media (min-width: 960px) {
|
|
181
187
|
.tagline {
|
|
182
|
-
padding-top: 24px;
|
|
183
188
|
line-height: 36px;
|
|
184
189
|
font-size: 24px;
|
|
185
190
|
}
|
|
@@ -230,9 +235,9 @@ defineProps<{
|
|
|
230
235
|
|
|
231
236
|
@media (min-width: 960px) {
|
|
232
237
|
.image {
|
|
238
|
+
flex-grow: 1;
|
|
233
239
|
order: 2;
|
|
234
240
|
margin: 0;
|
|
235
|
-
width: calc(100% / 3);
|
|
236
241
|
min-height: 100%;
|
|
237
242
|
}
|
|
238
243
|
}
|
|
@@ -1,97 +1,14 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import { computed } from 'vue'
|
|
3
2
|
import { useData } from 'vitepress'
|
|
4
|
-
import
|
|
3
|
+
import VPFeatures from './VPFeatures.vue'
|
|
5
4
|
|
|
6
5
|
const { frontmatter: fm } = useData()
|
|
7
|
-
|
|
8
|
-
const grid = computed(() => {
|
|
9
|
-
const length = fm.value.features?.length
|
|
10
|
-
|
|
11
|
-
if (!length) {
|
|
12
|
-
return
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
if (length === 2) {
|
|
16
|
-
return 'grid-2'
|
|
17
|
-
} else if (length === 3) {
|
|
18
|
-
return 'grid-3'
|
|
19
|
-
} else if (length % 3 === 0) {
|
|
20
|
-
return 'grid-6'
|
|
21
|
-
} else if (length % 2 === 0) {
|
|
22
|
-
return 'grid-4'
|
|
23
|
-
}
|
|
24
|
-
})
|
|
25
6
|
</script>
|
|
26
7
|
|
|
27
8
|
<template>
|
|
28
|
-
<
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
:icon="feature.icon"
|
|
34
|
-
:title="feature.title"
|
|
35
|
-
:details="feature.details"
|
|
36
|
-
/>
|
|
37
|
-
</div>
|
|
38
|
-
</div>
|
|
39
|
-
</div>
|
|
40
|
-
</div>
|
|
9
|
+
<VPFeatures
|
|
10
|
+
v-if="fm.features"
|
|
11
|
+
class="VPHomeFeatures"
|
|
12
|
+
:features="fm.features"
|
|
13
|
+
/>
|
|
41
14
|
</template>
|
|
42
|
-
|
|
43
|
-
<style scoped>
|
|
44
|
-
.VPHomeFeatures {
|
|
45
|
-
position: relative;
|
|
46
|
-
padding: 0 24px;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
@media (min-width: 640px) {
|
|
50
|
-
.VPHomeFeatures {
|
|
51
|
-
padding: 0 48px;
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
.container {
|
|
56
|
-
margin: 0 auto;
|
|
57
|
-
max-width: 960px;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
.items {
|
|
61
|
-
display: flex;
|
|
62
|
-
flex-wrap: wrap;
|
|
63
|
-
margin: -8px;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
.item {
|
|
67
|
-
padding: 8px;
|
|
68
|
-
width: 100%;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
@media (min-width: 640px) {
|
|
72
|
-
.item.grid-2,
|
|
73
|
-
.item.grid-4,
|
|
74
|
-
.item.grid-6 {
|
|
75
|
-
width: calc(100% / 2);
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
@media (min-width: 768px) {
|
|
80
|
-
.item.grid-2,
|
|
81
|
-
.item.grid-4 {
|
|
82
|
-
width: calc(100% / 2);
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
.item.grid-3,
|
|
86
|
-
.item.grid-6 {
|
|
87
|
-
width: calc(100% / 3);
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
@media (min-width: 960px) {
|
|
92
|
-
.item.grid-4 {
|
|
93
|
-
width: calc(100% / 4);
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
</style>
|