Merge branch 'main' into menu-links-no-icon

pull/4260/head
Divyansh Singh 11 months ago committed by GitHub
commit dd5551ebc1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -187,7 +187,7 @@ You may set custom title by appending the text right after the "type" of the con
Danger zone, do not proceed Danger zone, do not proceed
::: :::
::: details Click me to view the code ::: details Click me to toggle the code
```js ```js
console.log('Hello, VitePress!') console.log('Hello, VitePress!')
``` ```
@ -200,7 +200,7 @@ console.log('Hello, VitePress!')
Danger zone, do not proceed Danger zone, do not proceed
::: :::
::: details Click me to view the code ::: details Click me to toggle the code
```js ```js
console.log('Hello, VitePress!') console.log('Hello, VitePress!')
``` ```
@ -225,6 +225,28 @@ export default defineConfig({
}) })
``` ```
### Additional Attributes
You can add additional attributes to the custom containers. We use [markdown-it-attrs](https://github.com/arve0/markdown-it-attrs) for this feature, and it is supported on almost all markdown elements. For example, you can set the `open` attribute to make the details block open by default:
**Input**
````md
::: details Click me to toggle the code {open}
```js
console.log('Hello, VitePress!')
```
:::
````
**Output**
::: details Click me to toggle the code {open}
```js
console.log('Hello, VitePress!')
```
:::
### `raw` ### `raw`
This is a special container that can be used to prevent style and router conflicts with VitePress. This is especially useful when you're documenting component libraries. You might also wanna check out [whyframe](https://whyframe.dev/docs/integrations/vitepress) for better isolation. This is a special container that can be used to prevent style and router conflicts with VitePress. This is especially useful when you're documenting component libraries. You might also wanna check out [whyframe](https://whyframe.dev/docs/integrations/vitepress) for better isolation.

@ -156,22 +156,24 @@ You can customize the mapping between the source directory structure and the gen
``` ```
. .
─ packages ─ packages
├─ pkg-a ├─ pkg-a
│ └─ src │ └─ src
│ │ ├─ pkg-a-code.ts │ ├─ foo.md
│ │ └─ pkg-a-docs.md │ └─ index.md
└─ pkg-b └─ pkg-b
└─ src └─ src
│ ├─ pkg-b-code.ts ├─ bar.md
│ └─ pkg-b-docs.md └─ index.md
``` ```
And you want the VitePress pages to be generated like this: And you want the VitePress pages to be generated like this:
``` ```
packages/pkg-a/src/pkg-a-docs.md --> /pkg-a/index.html packages/pkg-a/src/index.md --> /pkg-a/index.html
packages/pkg-b/src/pkg-b-docs.md --> /pkg-b/index.html packages/pkg-a/src/foo.md --> /pkg-a/foo.html
packages/pkg-b/src/index.md --> /pkg-b/index.html
packages/pkg-b/src/bar.md --> /pkg-b/bar.html
``` ```
You can achieve this by configuring the [`rewrites`](../reference/site-config#rewrites) option like this: You can achieve this by configuring the [`rewrites`](../reference/site-config#rewrites) option like this:
@ -180,8 +182,10 @@ You can achieve this by configuring the [`rewrites`](../reference/site-config#re
// .vitepress/config.js // .vitepress/config.js
export default { export default {
rewrites: { rewrites: {
'packages/pkg-a/src/pkg-a-docs.md': 'pkg-a/index.md', 'packages/pkg-a/src/index.md': 'pkg-a/index.md',
'packages/pkg-b/src/pkg-b-docs.md': 'pkg-b/index.md' 'packages/pkg-a/src/foo.md': 'pkg-a/foo.md',
'packages/pkg-b/src/index.md': 'pkg-b/index.md',
'packages/pkg-b/src/bar.md': 'pkg-b/bar.md'
} }
} }
``` ```
@ -191,12 +195,22 @@ The `rewrites` option also supports dynamic route parameters. In the above examp
```ts ```ts
export default { export default {
rewrites: { rewrites: {
'packages/:pkg/src/(.*)': ':pkg/index.md' 'packages/:pkg/src/:slug*': ':pkg/:slug*'
} }
} }
``` ```
The rewrite paths are compiled using the `path-to-regexp` package - consult [its documentation](https://github.com/pillarjs/path-to-regexp#parameters) for more advanced syntax. The rewrite paths are compiled using the `path-to-regexp` package - consult [its documentation](https://github.com/pillarjs/path-to-regexp/tree/6.x#parameters) for more advanced syntax.
`rewrites` can also be a function that receives the original path and returns the new path:
```ts
export default {
rewrites(id) {
return id.replace(/^packages\/([^/]+)\/src\//, '$1/')
}
}
```
::: warning Relative Links with Rewrites ::: warning Relative Links with Rewrites

@ -1,6 +0,0 @@
/assets/*
cache-control: max-age=31536000
cache-control: immutable
/_translations/*
x-robots-tag: noindex

@ -1 +0,0 @@
https://vitepress.vuejs.org/* https://vitepress.dev/:splat 301!

@ -4,3 +4,24 @@
[build] [build]
publish = "docs/.vitepress/dist" publish = "docs/.vitepress/dist"
command = "pnpm docs:build && pnpm docs:lunaria:build" command = "pnpm docs:build && pnpm docs:lunaria:build"
[[headers]]
for = "/assets/*"
[headers.values]
cache-control = '''
max-age=31536000,
immutable'''
[[headers]]
for = "/_translations/*"
[headers.values]
x-robots-tag = "noindex"
[[redirects]]
from = "https://vitepress.vuejs.org/*"
to = "https://vitepress.dev/:splat"
force = true
[[redirects]]
from = "/guide/"
to = "/guide/getting-started"

@ -87,7 +87,7 @@ function createHeadElement([tag, attrs, innerHTML]: HeadConfig) {
if (innerHTML) { if (innerHTML) {
el.innerHTML = innerHTML el.innerHTML = innerHTML
} }
if (tag === 'script' && !attrs.async) { if (tag === 'script' && attrs.async == null) {
// async is true by default for dynamically created scripts // async is true by default for dynamically created scripts
;(el as HTMLScriptElement).async = false ;(el as HTMLScriptElement).async = false
} }

@ -1,5 +1,5 @@
import siteData from '@siteData' import siteData from '@siteData'
import { useDark } from '@vueuse/core' import { useDark, usePreferredDark } from '@vueuse/core'
import { import {
computed, computed,
inject, inject,
@ -79,13 +79,15 @@ export function initData(route: Route): VitePressData {
const isDark = const isDark =
appearance === 'force-dark' appearance === 'force-dark'
? ref(true) ? ref(true)
: appearance : appearance === 'force-auto'
? useDark({ ? usePreferredDark()
storageKey: APPEARANCE_KEY, : appearance
initialValue: () => (appearance === 'dark' ? 'dark' : 'auto'), ? useDark({
...(typeof appearance === 'object' ? appearance : {}) storageKey: APPEARANCE_KEY,
}) initialValue: () => (appearance === 'dark' ? 'dark' : 'auto'),
: ref(false) ...(typeof appearance === 'object' ? appearance : {})
})
: ref(false)
const hashRef = ref(inBrowser ? location.hash : '') const hashRef = ref(inBrowser ? location.hash : '')

@ -440,10 +440,20 @@ function formMarkRegex(terms: Set<string>) {
<input <input
ref="searchInput" ref="searchInput"
v-model="filterText" v-model="filterText"
:placeholder="buttonText" :aria-activedescendant="selectedIndex > -1 ? ('localsearch-item-' + selectedIndex) : undefined"
id="localsearch-input" aria-autocomplete="both"
:aria-controls="results?.length ? 'localsearch-list' : undefined"
aria-labelledby="localsearch-label" aria-labelledby="localsearch-label"
autocapitalize="off"
autocomplete="off"
autocorrect="off"
class="search-input" class="search-input"
id="localsearch-input"
enterkeyhint="go"
maxlength="64"
:placeholder="buttonText"
spellcheck="false"
type="search"
/> />
<div class="search-actions"> <div class="search-actions">
<button <button
@ -482,8 +492,9 @@ function formMarkRegex(terms: Set<string>) {
<li <li
v-for="(p, index) in results" v-for="(p, index) in results"
:key="p.id" :key="p.id"
role="option" :id="'localsearch-item-' + index"
:aria-selected="selectedIndex === index ? 'true' : 'false'" :aria-selected="selectedIndex === index ? 'true' : 'false'"
role="option"
> >
<a <a
:href="p.id" :href="p.id"

@ -63,14 +63,14 @@ export async function createMarkdownToVueRenderFn(
const dynamicRoutes = new Map( const dynamicRoutes = new Map(
siteConfig?.dynamicRoutes?.routes.map((r) => [ siteConfig?.dynamicRoutes?.routes.map((r) => [
r.fullPath, r.fullPath,
path.join(srcDir, r.route) slash(path.join(srcDir, r.route))
]) || [] ]) || []
) )
const rewrites = new Map( const rewrites = new Map(
Object.entries(siteConfig?.rewrites.map || {}).map(([key, value]) => [ Object.entries(siteConfig?.rewrites.map || {}).map(([key, value]) => [
path.join(srcDir, key), slash(path.join(srcDir, key)),
path.join(srcDir, value!) slash(path.join(srcDir, value!))
]) || [] ]) || []
) )

@ -6,22 +6,35 @@ export function resolveRewrites(
pages: string[], pages: string[],
userRewrites: UserConfig['rewrites'] userRewrites: UserConfig['rewrites']
) { ) {
const rewriteRules = Object.entries(userRewrites || {}).map(([from, to]) => ({
toPath: compile(`/${to}`, { validate: false }),
matchUrl: match(from.startsWith('^') ? new RegExp(from) : from)
}))
const pageToRewrite: Record<string, string> = {} const pageToRewrite: Record<string, string> = {}
const rewriteToPage: Record<string, string> = {} const rewriteToPage: Record<string, string> = {}
if (rewriteRules.length) {
if (typeof userRewrites === 'function') {
for (const page of pages) { for (const page of pages) {
for (const { matchUrl, toPath } of rewriteRules) { const dest = userRewrites(page)
const res = matchUrl(page) if (dest && dest !== page) {
if (res) { pageToRewrite[page] = dest
const dest = toPath(res.params).slice(1) rewriteToPage[dest] = page
pageToRewrite[page] = dest }
rewriteToPage[dest] = page }
break } else if (typeof userRewrites === 'object') {
const rewriteRules = Object.entries(userRewrites || {}).map(
([from, to]) => ({
toPath: compile(`/${to}`, { validate: false }),
matchUrl: match(from.startsWith('^') ? new RegExp(from) : from)
})
)
if (rewriteRules.length) {
for (const page of pages) {
for (const { matchUrl, toPath } of rewriteRules) {
const res = matchUrl(page)
if (res) {
const dest = toPath(res.params).slice(1)
pageToRewrite[page] = dest
rewriteToPage[dest] = page
break
}
} }
} }
} }

@ -162,7 +162,7 @@ export interface UserConfig<ThemeConfig = any>
* *
* source -> destination * source -> destination
*/ */
rewrites?: Record<string, string> rewrites?: Record<string, string> | ((id: string) => string)
/** /**
* @experimental * @experimental

Loading…
Cancel
Save