vitepress 1.0.0-draft.3 → 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.
@@ -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 = (pageTitle ? pageTitle + ` | ` : ``) + siteData.title;
57
+ document.title = createTitle(siteData, pageData);
58
58
  document
59
59
  .querySelector(`meta[name=description]`)
60
60
  .setAttribute('content', pageDescription || siteData.description);
@@ -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.title
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;
@@ -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>
@@ -77,6 +79,7 @@ export declare interface SiteData<ThemeConfig = any> {
77
79
  lang: string
78
80
 
79
81
  title: string
82
+ titleTemplate?: string | boolean
80
83
  description: string
81
84
  head: HeadConfig[]
82
85
  appearance: boolean
@@ -53,6 +53,27 @@ export function resolveSiteDataByRoute(siteData, route) {
53
53
  langs: createLangDictionary(siteData)
54
54
  });
55
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
+ }
56
77
  /**
57
78
  * Clean up the route by removing the `base` path if it's set in config.
58
79
  */
@@ -31,15 +31,16 @@ const { hasSidebar } = useSidebar()
31
31
  <template #home-features-after><slot name="home-features-after" /></template>
32
32
  </VPHome>
33
33
 
34
- <VPDoc v-else :class="{ 'has-sidebar': hasSidebar }" />
34
+ <VPDoc v-else />
35
35
  </div>
36
36
  </template>
37
37
 
38
38
  <style scoped>
39
39
  .VPContent {
40
40
  flex-grow: 1;
41
+ flex-shrink: 0;
41
42
  margin: 0 auto;
42
- max-width: var(--vp-layout-max-width);
43
+ width: 100%;
43
44
  }
44
45
 
45
46
  .VPContent.is-home {
@@ -47,12 +48,6 @@ const { hasSidebar } = useSidebar()
47
48
  max-width: 100%;
48
49
  }
49
50
 
50
- @media (max-width: 768px) {
51
- .VPContent {
52
- overflow-x: hidden;
53
- }
54
- }
55
-
56
51
  @media (min-width: 960px) {
57
52
  .VPContent {
58
53
  padding-top: var(--vp-nav-height);
@@ -61,14 +56,13 @@ const { hasSidebar } = useSidebar()
61
56
  .VPContent.has-sidebar {
62
57
  margin: 0;
63
58
  padding-left: var(--vp-sidebar-width);
64
- max-width: 100%;
65
59
  }
66
60
  }
67
61
 
68
62
  @media (min-width: 1440px) {
69
63
  .VPContent.has-sidebar {
70
64
  padding-right: calc((100vw - var(--vp-layout-max-width)) / 2);
71
- padding-left: calc((100vw - var(--vp-layout-max-width)) / 2 + var(--vp-sidebar-width) - 32px);
65
+ padding-left: calc((100vw - var(--vp-layout-max-width)) / 2 + var(--vp-sidebar-width));
72
66
  }
73
67
  }
74
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 { useSidebar } from '../composables/sidebar'
4
5
  import VPDocOutline from './VPDocOutline.vue'
5
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,7 +14,7 @@ const pageName = computed(() => {
12
14
  </script>
13
15
 
14
16
  <template>
15
- <div class="VPDoc has-aside">
17
+ <div class="VPDoc" :class="{ 'has-sidebar': hasSidebar }">
16
18
  <div class="container">
17
19
  <div class="aside">
18
20
  <div class="aside-container">
@@ -24,11 +26,13 @@ const pageName = computed(() => {
24
26
  </div>
25
27
 
26
28
  <div class="content">
27
- <main class="main">
28
- <Content class="vp-doc" :class="pageName" />
29
- </main>
29
+ <div class="content-container">
30
+ <main class="main">
31
+ <Content class="vp-doc" :class="pageName" />
32
+ </main>
30
33
 
31
- <VPDocFooter />
34
+ <VPDocFooter />
35
+ </div>
32
36
  </div>
33
37
  </div>
34
38
  </div>
@@ -37,6 +41,7 @@ const pageName = computed(() => {
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) {
@@ -47,60 +52,63 @@ const pageName = computed(() => {
47
52
 
48
53
  @media (min-width: 960px) {
49
54
  .VPDoc {
50
- padding: 32px 64px 96px;
55
+ padding: 32px 32px 128px;
51
56
  }
52
- }
53
57
 
54
- @media (min-width: 1280px) {
55
- .VPDoc {
56
- padding: 32px 0 128px 64px;
58
+ .VPDoc:not(.has-sidebar) .container {
59
+ display: flex;
60
+ justify-content: center;
61
+ max-width: 992px;
57
62
  }
58
63
 
59
- .VPDoc:not(.has-sidebar.has-aside) {
60
- padding-left: calc((100vw - 688px) / 2);
64
+ .VPDoc:not(.has-sidebar) .aside {
65
+ display: block;
61
66
  }
62
67
 
63
- .VPDoc.has-aside:not(.has-sidebar) {
64
- padding-left: calc((100vw - 688px - 320px) / 2);
68
+ .VPDoc:not(.has-sidebar) .content {
69
+ max-width: 752px;
70
+ }
71
+ }
72
+
73
+ @media (min-width: 1280px) {
74
+ .VPDoc .container {
75
+ display: flex;
76
+ justify-content: center;
65
77
  }
66
78
 
67
- .VPDoc:not(.has-aside) .content {
68
- min-width: 688px;
79
+ .VPDoc .aside {
80
+ display: block;
69
81
  }
70
82
  }
71
83
 
72
84
  @media (min-width: 1440px) {
73
- .VPDoc {
74
- padding: 32px 0 128px 96px;
85
+ .VPDoc:not(.has-sidebar) .content {
86
+ max-width: 784px;
75
87
  }
76
- }
77
88
 
78
- @media (min-width: 1280px) {
79
- .container {
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
- padding-left: 64px;
91
- padding-right: 32px;
92
- min-width: 320px;
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: 96px;
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: 224px;
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
- max-width: 688px;
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: 632px;
163
+ min-width: 640px;
151
164
  }
152
165
  }
153
166
 
167
+ @media (min-width: 1440px) {
168
+ .content {
169
+ padding-left: 64px;
170
+ }
171
+ }
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
  }
@@ -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 { resolveHeaders, useActiveAnchor } from '../composables/outline'
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="VPDocOutline" ref="container">
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>
@@ -56,12 +62,17 @@ function handleClick({ target: el }: Event) {
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;
@@ -66,7 +66,7 @@ defineEmits<{
66
66
  display: flex;
67
67
  justify-content: space-between;
68
68
  margin: 0 auto;
69
- max-width: var(--vp-layout-max-width);
69
+ max-width: calc(var(--vp-layout-max-width) - 64px);
70
70
  }
71
71
 
72
72
  .content {
@@ -91,8 +91,8 @@ watchPostEffect(async () => {
91
91
 
92
92
  @media (min-width: 1440px) {
93
93
  .VPSidebar {
94
- padding-left: calc((100% - var(--vp-layout-max-width)) / 2);
95
- width: calc((100% - var(--vp-layout-max-width)) / 2 + var(--vp-sidebar-width) - 32px);
94
+ padding-left: calc((100% - (var(--vp-layout-max-width) - 64px)) / 2);
95
+ width: calc((100% - (var(--vp-layout-max-width) - 64px)) / 2 + var(--vp-sidebar-width) - 32px);
96
96
  }
97
97
  }
98
98
 
@@ -1,8 +1,18 @@
1
- import { onMounted, onUpdated, onUnmounted } from 'vue';
1
+ import { computed, onMounted, onUpdated, onUnmounted } from 'vue';
2
+ import { useData } from 'vitepress';
2
3
  import { useMediaQuery } from '@vueuse/core';
3
4
  import { throttleAndDebounce } from '../support/utils';
4
5
  // magic number to avoid repeated retrieval
5
6
  const PAGE_OFFSET = 56;
7
+ export function useOutline() {
8
+ const { page } = useData();
9
+ const hasOutline = computed(() => {
10
+ return page.value.headers.length > 0;
11
+ });
12
+ return {
13
+ hasOutline
14
+ };
15
+ }
6
16
  export function resolveHeaders(headers) {
7
17
  return mapHeaders(groupHeaders(headers));
8
18
  }
@@ -2,8 +2,9 @@ import './styles/fonts.css';
2
2
  import './styles/vars.css';
3
3
  import './styles/base.css';
4
4
  import './styles/utils.css';
5
- import './styles/vp-doc.css';
6
- import './styles/vp-sponsor.css';
5
+ import './styles/components/custom-block.css';
6
+ import './styles/components/vp-doc.css';
7
+ import './styles/components/vp-sponsor.css';
7
8
  import Layout from './Layout.vue';
8
9
  import NotFound from './NotFound.vue';
9
10
  export { default as VPHomeHero } from './components/VPHomeHero.vue';
@@ -0,0 +1,90 @@
1
+ .custom-block {
2
+ border: 1px solid transparent;
3
+ border-radius: 8px;
4
+ padding: 16px 16px 8px;
5
+ line-height: 20px;
6
+ font-size: 14px;
7
+ color: var(--vp-c-text-2);
8
+ }
9
+
10
+ .custom-block.info {
11
+ border-color: var(--vp-custom-block-info-border);
12
+ color: var(--vp-custom-block-info-text);
13
+ background-color: var(--vp-custom-block-info-bg);
14
+ }
15
+
16
+ .custom-block.info code {
17
+ background-color: var(--vp-custom-block-info-code-bg);
18
+ }
19
+
20
+ .custom-block.tip {
21
+ border-color: var(--vp-custom-block-tip-border);
22
+ color: var(--vp-custom-block-tip-text);
23
+ background-color: var(--vp-custom-block-tip-bg);
24
+ }
25
+
26
+ .custom-block.tip code {
27
+ background-color: var(--vp-custom-block-tip-code-bg);
28
+ }
29
+
30
+ .custom-block.warning {
31
+ border-color: var(--vp-custom-block-warning-border);
32
+ color: var(--vp-custom-block-warning-text);
33
+ background-color: var(--vp-custom-block-warning-bg);
34
+ }
35
+
36
+ .custom-block.warning code {
37
+ background-color: var(--vp-custom-block-warning-code-bg);
38
+ }
39
+
40
+ .custom-block.danger {
41
+ border-color: var(--vp-custom-block-danger-border);
42
+ color: var(--vp-custom-block-danger-text);
43
+ background-color: var(--vp-custom-block-danger-bg);
44
+ }
45
+
46
+ .custom-block.danger code {
47
+ background-color: var(--vp-custom-block-danger-code-bg);
48
+ }
49
+
50
+ .custom-block.details {
51
+ border-color: var(--vp-custom-block-details-border);
52
+ color: var(--vp-custom-block-details-text);
53
+ background-color: var(--vp-custom-block-details-bg);
54
+ }
55
+
56
+ .custom-block.details code {
57
+ background-color: var(--vp-custom-block-details-code-bg);
58
+ }
59
+
60
+ .custom-block-title {
61
+ font-weight: 700;
62
+ }
63
+
64
+ .custom-block p + p {
65
+ margin: 8px 0;
66
+ }
67
+
68
+ .custom-block.details summary {
69
+ margin: 0 0 8px;
70
+ font-weight: 700;
71
+ }
72
+
73
+ .custom-block.details summary + p {
74
+ margin: 8px 0;
75
+ }
76
+
77
+ .custom-block a {
78
+ color: inherit;
79
+ font-weight: 600;
80
+ text-decoration: underline;
81
+ transition: opacity .25s;
82
+ }
83
+
84
+ .custom-block a:hover {
85
+ opacity: 0.6;
86
+ }
87
+
88
+ .custom-block code {
89
+ font-size: var(--vp-custom-block-code-font-size);
90
+ }
@@ -115,18 +115,27 @@
115
115
 
116
116
  .vp-doc ul,
117
117
  .vp-doc ol {
118
+ padding-left: 1.25rem;
118
119
  margin: 16px 0;
119
120
  }
120
121
 
121
122
  .vp-doc ul {
122
- padding-left: 1.25rem;
123
123
  list-style: disc;
124
124
  }
125
125
 
126
+ .vp-doc ol {
127
+ list-style: decimal;
128
+ }
129
+
126
130
  .vp-doc li + li {
127
131
  margin-top: 8px;
128
132
  }
129
133
 
134
+ .vp-doc li > ol,
135
+ .vp-doc li > ul {
136
+ margin: 8px 0 0;
137
+ }
138
+
130
139
  /**
131
140
  * Table
132
141
  * -------------------------------------------------------------------------- */
@@ -177,6 +186,49 @@
177
186
  border-top: 1px solid var(--vp-c-divider-light);
178
187
  }
179
188
 
189
+ /**
190
+ * Custom Block
191
+ * -------------------------------------------------------------------------- */
192
+
193
+ .vp-doc .custom-block {
194
+ margin: 16px 0;
195
+ }
196
+
197
+ .vp-doc .custom-block p {
198
+ margin: 8px 0;
199
+ line-height: 24px;
200
+ }
201
+
202
+ .vp-doc .custom-block p:first-child {
203
+ margin: 0;
204
+ }
205
+
206
+ .vp-doc .custom-block a {
207
+ color: inherit;
208
+ font-weight: 600;
209
+ text-decoration: underline;
210
+ transition: opacity .25s;
211
+ }
212
+
213
+ .vp-doc .custom-block a:hover {
214
+ opacity: 0.6;
215
+ }
216
+
217
+ .vp-doc .custom-block code {
218
+ font-size: var(--vp-custom-block-code-font-size);
219
+ font-weight: 600;
220
+ color: inherit;
221
+ }
222
+
223
+ .vp-doc .custom-block div[class*='language-'] {
224
+ margin: 8px 0;
225
+ }
226
+
227
+ .vp-doc .custom-block div[class*='language-'] code {
228
+ font-weight: 400;
229
+ background-color: var(--vp-code-block-bg);
230
+ }
231
+
180
232
  /**
181
233
  * Code
182
234
  * -------------------------------------------------------------------------- */
@@ -200,19 +252,13 @@
200
252
  font-size: 0.9em;
201
253
  }
202
254
 
203
- @media (min-width: 768px) {
204
- .vp-doc :not(pre) > code {
205
- white-space: nowrap;
206
- }
207
- }
208
-
209
255
  .vp-doc a > code {
210
256
  color: var(--vp-c-brand-dark);
211
257
  }
212
258
 
213
259
  .vp-doc div[class*='language-'] {
214
260
  position: relative;
215
- margin: 20px -24px;
261
+ margin: 16px -24px;
216
262
  background-color: var(--vp-code-block-bg);
217
263
  overflow-x: auto;
218
264
  transition: background-color 0.5s;
@@ -221,7 +267,7 @@
221
267
  @media (min-width: 640px) {
222
268
  .vp-doc div[class*='language-'] {
223
269
  border-radius: 8px;
224
- margin: 24px 0;
270
+ margin: 16px 0;
225
271
  }
226
272
  }
227
273
 
@@ -234,7 +280,7 @@
234
280
  .vp-doc div[class*='language-'] + div[class*='language-'],
235
281
  .vp-doc div[class$='-api'] + div[class*='language-'],
236
282
  .vp-doc div[class*='language-'] + div[class$='-api'] > div[class*='language-'] {
237
- margin-top: -12px;
283
+ margin-top: -8px;
238
284
  }
239
285
 
240
286
  .vp-doc [class*='language-'] pre,
@@ -43,12 +43,6 @@
43
43
  --vp-c-text-dark-3: rgba(235, 235, 235, 0.38);
44
44
  --vp-c-text-dark-4: rgba(235, 235, 235, 0.18);
45
45
 
46
- --vp-c-green: #42b883;
47
- --vp-c-green-light: #42d392;
48
- --vp-c-green-lighter: #35eb9a;
49
- --vp-c-green-dark: #33a06f;
50
- --vp-c-green-darker: #155f3e;
51
-
52
46
  --vp-c-indigo: #213547;
53
47
  --vp-c-indigo-soft: #476582;
54
48
  --vp-c-indigo-light: #aac8e4;
@@ -56,29 +50,26 @@
56
50
  --vp-c-indigo-dark: #1d2f3f;
57
51
  --vp-c-indigo-darker: #14212e;
58
52
 
59
- --vp-c-blue: #3b8eed;
60
- --vp-c-blue-light: #549ced;
61
- --vp-c-blue-lighter: #50a2ff;
62
- --vp-c-blue-dark: #3468a3;
63
- --vp-c-blue-darker: #255489;
53
+ --vp-c-green: #42b883;
54
+ --vp-c-green-light: #42d392;
55
+ --vp-c-green-lighter: #35eb9a;
56
+ --vp-c-green-dark: #33a06f;
57
+ --vp-c-green-darker: #155f3e;
58
+ --vp-c-green-dimm: rgba(66, 184, 131, 0.08);
64
59
 
65
60
  --vp-c-yellow: #ffc517;
66
61
  --vp-c-yellow-light: #ffe417;
67
62
  --vp-c-yellow-lighter: #ffff17;
68
63
  --vp-c-yellow-dark: #e0ad15;
69
- --vp-c-yellow-darker: #bc9112;
64
+ --vp-c-yellow-darker: #ad850e;
65
+ --vp-c-yellow-dimm: rgba(255, 197, 23, 0.08);
70
66
 
71
67
  --vp-c-red: #ed3c50;
72
68
  --vp-c-red-light: #f43771;
73
69
  --vp-c-red-lighter: #fd1d7c;
74
70
  --vp-c-red-dark: #cd2d3f;
75
71
  --vp-c-red-darker: #ab2131;
76
-
77
- --vp-c-purple: #de41e0;
78
- --vp-c-purple-light: #e936eb;
79
- --vp-c-purple-lighter: #f616f8;
80
- --vp-c-purple-dark: #823c83;
81
- --vp-c-purple-darker: #602960;
72
+ --vp-c-red-dimm: rgba(237, 60, 80, 0.08);
82
73
  }
83
74
 
84
75
  /**
@@ -185,31 +176,7 @@
185
176
  * -------------------------------------------------------------------------- */
186
177
 
187
178
  :root {
188
- --vp-layout-max-width: 1376px;
189
- }
190
-
191
- /**
192
- * Component: Nav
193
- * -------------------------------------------------------------------------- */
194
-
195
- :root {
196
- --vp-nav-height: var(--vp-nav-height-mobile);
197
- --vp-nav-height-mobile: 56px;
198
- --vp-nav-height-desktop: 72px;
199
- }
200
-
201
- @media (min-width: 960px) {
202
- :root {
203
- --vp-nav-height: var(--vp-nav-height-desktop);
204
- }
205
- }
206
-
207
- /**
208
- * Component: Sidebar
209
- * -------------------------------------------------------------------------- */
210
-
211
- :root {
212
- --vp-sidebar-width: 272px;
179
+ --vp-layout-max-width: 1440px;
213
180
  }
214
181
 
215
182
  /**
@@ -289,6 +256,75 @@
289
256
  --vp-button-sponsor-text: var(--vp-c-text-dark-2);
290
257
  }
291
258
 
259
+ /**
260
+ * Component: Custom Block
261
+ * -------------------------------------------------------------------------- */
262
+
263
+ :root {
264
+ --vp-custom-block-code-font-size: 13px;
265
+
266
+ --vp-custom-block-info-border: var(--vp-c-divider-light);
267
+ --vp-custom-block-info-text: var(--vp-c-text-2);
268
+ --vp-custom-block-info-bg: var(--vp-c-white-soft);
269
+ --vp-custom-block-info-code-bg: var(--vp-c-gray-light-4);
270
+
271
+ --vp-custom-block-tip-border: var(--vp-c-green);
272
+ --vp-custom-block-tip-text: var(--vp-c-green-darker);
273
+ --vp-custom-block-tip-bg: var(--vp-c-green-dimm);
274
+ --vp-custom-block-tip-code-bg: var(--vp-custom-block-tip-bg);
275
+
276
+ --vp-custom-block-warning-border: var(--vp-c-yellow);
277
+ --vp-custom-block-warning-text: var(--vp-c-yellow-darker);
278
+ --vp-custom-block-warning-bg: var(--vp-c-yellow-dimm);
279
+ --vp-custom-block-warning-code-bg: var(--vp-custom-block-warning-bg);
280
+
281
+ --vp-custom-block-danger-border: var(--vp-c-red);
282
+ --vp-custom-block-danger-text: var(--vp-c-red-darker);
283
+ --vp-custom-block-danger-bg: var(--vp-c-red-dimm);
284
+ --vp-custom-block-danger-code-bg: var(--vp-custom-block-danger-bg);
285
+
286
+ --vp-custom-block-details-border: var(--vp-custom-block-info-border);
287
+ --vp-custom-block-details-text: var(--vp-custom-block-info-text);
288
+ --vp-custom-block-details-bg: var(--vp-custom-block-info-bg);
289
+ --vp-custom-block-details-code-bg: var(--vp-custom-block-details-bg);
290
+ }
291
+
292
+ .dark {
293
+ --vp-custom-block-info-border: var(--vp-c-divider-light);
294
+ --vp-custom-block-info-bg: var(--vp-c-black-mute);
295
+ --vp-custom-block-info-code-bg: var(--vp-c-gray-dark-4);
296
+
297
+ --vp-custom-block-tip-text: var(--vp-c-green);
298
+
299
+ --vp-custom-block-warning-text: var(--vp-c-yellow);
300
+
301
+ --vp-custom-block-danger-text: var(--vp-c-red);
302
+ }
303
+
304
+ /**
305
+ * Component: Nav
306
+ * -------------------------------------------------------------------------- */
307
+
308
+ :root {
309
+ --vp-nav-height: var(--vp-nav-height-mobile);
310
+ --vp-nav-height-mobile: 56px;
311
+ --vp-nav-height-desktop: 72px;
312
+ }
313
+
314
+ @media (min-width: 960px) {
315
+ :root {
316
+ --vp-nav-height: var(--vp-nav-height-desktop);
317
+ }
318
+ }
319
+
320
+ /**
321
+ * Component: Sidebar
322
+ * -------------------------------------------------------------------------- */
323
+
324
+ :root {
325
+ --vp-sidebar-width: 272px;
326
+ }
327
+
292
328
  /**
293
329
  * Component: Home
294
330
  * -------------------------------------------------------------------------- */
package/dist/node/cli.js CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var serve = require('./serve-b5dc02b2.js');
3
+ var serve = require('./serve-b3182d88.js');
4
4
  require('fs');
5
5
  require('path');
6
6
  require('url');
@@ -222,6 +222,7 @@ export declare interface Header {
222
222
  export declare interface LocaleConfig {
223
223
  lang: string
224
224
  title?: string
225
+ titleTemplate?: string | boolean
225
226
  description?: string
226
227
  head?: HeadConfig[]
227
228
  label?: string
@@ -293,6 +294,7 @@ export declare interface SiteData<ThemeConfig = any> {
293
294
  lang: string
294
295
 
295
296
  title: string
297
+ titleTemplate?: string | boolean
296
298
  description: string
297
299
  head: HeadConfig[]
298
300
  appearance: boolean
@@ -327,6 +329,7 @@ export declare interface UserConfig<ThemeConfig = any> {
327
329
  base?: string;
328
330
  lang?: string;
329
331
  title?: string;
332
+ titleTemplate?: string | boolean;
330
333
  description?: string;
331
334
  head?: HeadConfig[];
332
335
  appearance?: boolean;
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var serve = require('./serve-b5dc02b2.js');
5
+ var serve = require('./serve-b3182d88.js');
6
6
  require('vite');
7
7
  require('readline');
8
8
  require('assert');
@@ -12293,6 +12293,25 @@ function resolveSiteDataByRoute(siteData, route) {
12293
12293
  langs: createLangDictionary(siteData)
12294
12294
  });
12295
12295
  }
12296
+ function createTitle(siteData, pageData) {
12297
+ var _a;
12298
+ const title = pageData.title || siteData.title;
12299
+ const template = (_a = pageData.titleTemplate) != null ? _a : siteData.titleTemplate;
12300
+ const templateString = createTitleTemplate(siteData.title, template);
12301
+ return `${title}${templateString}`;
12302
+ }
12303
+ function createTitleTemplate(siteTitle, template) {
12304
+ if (template === false) {
12305
+ return "";
12306
+ }
12307
+ if (template === true || template === void 0) {
12308
+ return ` | ${siteTitle}`;
12309
+ }
12310
+ if (siteTitle === template) {
12311
+ return "";
12312
+ }
12313
+ return ` | ${template}`;
12314
+ }
12296
12315
  function cleanRoute(siteData, route) {
12297
12316
  if (!inBrowser) {
12298
12317
  return route;
@@ -13455,6 +13474,7 @@ async function resolveSiteData(root, userConfig, command = "serve", mode = "deve
13455
13474
  return {
13456
13475
  lang: userConfig.lang || "en-US",
13457
13476
  title: userConfig.title || "VitePress",
13477
+ titleTemplate: userConfig.titleTemplate,
13458
13478
  description: userConfig.description || "A VitePress site",
13459
13479
  base: userConfig.base ? userConfig.base.replace(/([^/])$/, "$1/") : "/",
13460
13480
  head: resolveSiteDataHead(userConfig),
@@ -34956,7 +34976,7 @@ var markdownItContainer = function container_plugin(md, name, options) {
34956
34976
  };
34957
34977
 
34958
34978
  const containerPlugin = (md) => {
34959
- md.use(...createContainer("tip", "TIP")).use(...createContainer("info", "INFO")).use(...createContainer("warning", "WARNING")).use(...createContainer("danger", "WARNING")).use(...createContainer("details", "Details")).use(markdownItContainer, "v-pre", {
34979
+ md.use(...createContainer("tip", "TIP")).use(...createContainer("info", "INFO")).use(...createContainer("warning", "WARNING")).use(...createContainer("danger", "DANGER")).use(...createContainer("details", "Details")).use(markdownItContainer, "v-pre", {
34960
34980
  render: (tokens, idx) => tokens[idx].nesting === 1 ? `<div v-pre>
34961
34981
  ` : `</div>
34962
34982
  `
@@ -34972,7 +34992,7 @@ function createContainer(klass, defaultTitle) {
34972
34992
  const info = token.info.trim().slice(klass.length).trim();
34973
34993
  if (token.nesting === 1) {
34974
34994
  if (klass === "details") {
34975
- return `<details class="${klass} custom-block">${info ? `<summary>${info}</summary>` : ""}
34995
+ return `<details class="${klass} custom-block">${info ? `<summary>${info}</summary>` : `<summary>Details</summary>`}
34976
34996
  `;
34977
34997
  }
34978
34998
  return `<div class="${klass} custom-block"><p class="custom-block-title">${info || defaultTitle}</p>
@@ -37203,6 +37223,7 @@ function createMarkdownToVueRenderFn(srcDir, options = {}, pages, userDefines, i
37203
37223
  }
37204
37224
  const pageData = {
37205
37225
  title: inferTitle(frontmatter, content),
37226
+ titleTemplate: frontmatter.titleTemplate,
37206
37227
  description: inferDescription(frontmatter),
37207
37228
  frontmatter,
37208
37229
  headers: data.headers || [],
@@ -37251,9 +37272,6 @@ const inferTitle = (frontmatter, content) => {
37251
37272
  if (frontmatter.title) {
37252
37273
  return deeplyParseHeader(frontmatter.title);
37253
37274
  }
37254
- if (frontmatter.home) {
37255
- return "Home";
37256
- }
37257
37275
  const match = content.match(/^\s*#+\s+(.*)/m);
37258
37276
  if (match) {
37259
37277
  return deeplyParseHeader(match[1].trim());
@@ -40951,7 +40969,7 @@ async function renderPage(config, page, result, appChunk, cssChunk, pageToHashMa
40951
40969
  return `<link rel="prefetch" href="${siteData.base}${file}">`;
40952
40970
  }).join("\n ");
40953
40971
  const stylesheetLink = cssChunk ? `<link rel="stylesheet" href="${siteData.base}${cssChunk.fileName}">` : "";
40954
- const title = pageData.title && pageData.title !== "Home" ? `${pageData.title} | ${siteData.title}` : siteData.title;
40972
+ const title = createTitle(siteData, pageData);
40955
40973
  const description = pageData.description || siteData.description;
40956
40974
  const head = addSocialTags(title, ...siteData.head, ...filterOutHeadDescription(pageData.frontmatter.head));
40957
40975
  let inlinedScript = "";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vitepress",
3
- "version": "1.0.0-draft.3",
3
+ "version": "1.0.0-draft.4",
4
4
  "packageManager": "pnpm@7.0.1",
5
5
  "description": "Vite & Vue powered static site generator",
6
6
  "main": "dist/node/index.js",
@@ -139,6 +139,5 @@
139
139
  "docs-build-only": "node ./bin/vitepress build docs",
140
140
  "docs-serve": "node ./bin/vitepress serve docs",
141
141
  "ci-docs": "run-s build docs-build"
142
- },
143
- "readme": "# (WIP) VitePress 📝💨\n\n[![Test](https://github.com/vuejs/vitepress/workflows/Test/badge.svg)](https://github.com/vuejs/vitepress/actions)\n[![npm](https://img.shields.io/npm/v/vitepress)](https://www.npmjs.com/package/vitepress)\n\n---\n\nVitePress is [VuePress](https://vuepress.vuejs.org)' spiritual successor, built on top of [vite](https://github.com/vitejs/vite).\n\n## Documentation\n\nTo check out docs, visit [vitepress.vuejs.org](https://vitepress.vuejs.org).\n\n## Changelog\n\nDetailed changes for each release are documented in the [CHANGELOG](https://github.com/vuejs/vitepress/blob/main/CHANGELOG.md).\n\n## Contribution\n\nPlease make sure to read the [Contributing Guide](https://github.com/vuejs/vitepress/blob/main/.github/contributing.md) before making a pull request.\n\n## License\n\n[MIT](https://github.com/vuejs/vitepress/blob/main/LICENSE)\n\nCopyright (c) 2019-present, Yuxi (Evan) You\n"
142
+ }
144
143
  }
package/types/shared.d.ts CHANGED
@@ -5,6 +5,7 @@ export { DefaultTheme } from './default-theme'
5
5
  export interface PageData {
6
6
  relativePath: string
7
7
  title: string
8
+ titleTemplate?: string | boolean
8
9
  description: string
9
10
  headers: Header[]
10
11
  frontmatter: Record<string, any>
@@ -28,6 +29,7 @@ export interface SiteData<ThemeConfig = any> {
28
29
  lang: string
29
30
 
30
31
  title: string
32
+ titleTemplate?: string | boolean
31
33
  description: string
32
34
  head: HeadConfig[]
33
35
  appearance: boolean
@@ -64,6 +66,7 @@ export type HeadConfig =
64
66
  export interface LocaleConfig {
65
67
  lang: string
66
68
  title?: string
69
+ titleTemplate?: string | boolean
67
70
  description?: string
68
71
  head?: HeadConfig[]
69
72
  label?: string