Merge branch 'main' into scroll-to-top

pull/4522/head
Hichem Fantar 5 months ago committed by GitHub
commit d2840dc100
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -18,7 +18,7 @@ jobs:
strategy:
matrix:
os: [ubuntu-latest]
node_version: [18, 20, 22]
node_version: [20, 22, latest]
include:
- os: windows-latest
node_version: 22

@ -1,3 +1,47 @@
## [2.0.0-alpha.4](https://github.com/vuejs/vitepress/compare/v2.0.0-alpha.3...v2.0.0-alpha.4) (2025-03-09)
### Bug Fixes
- **build/regression:** langAlias not working ([06ae2bf](https://github.com/vuejs/vitepress/commit/06ae2bf3a4ee02351530b0bd055e577ca6509d62)), closes [#4581](https://github.com/vuejs/vitepress/issues/4581)
- don't hardcode `tabindex` attr in table renderer ([#4082](https://github.com/vuejs/vitepress/issues/4082)) ([aadc517](https://github.com/vuejs/vitepress/commit/aadc517c69fb239bdda99173bbc123ace567484b))
- hmr not working for watched files in path loaders ([e271695](https://github.com/vuejs/vitepress/commit/e271695d716247455ca620948f814e6c8ca0e3c4)), closes [#4525](https://github.com/vuejs/vitepress/issues/4525)
- ignore non-text content in permalink generation and fix types of markdown.config ([a8a1800](https://github.com/vuejs/vitepress/commit/a8a1800ae578be88027aa4ec7561ada4d055b888))
- prevent reload on first server start in fresh installations ([d8a884e](https://github.com/vuejs/vitepress/commit/d8a884ed0f754523765058a70149cdbaf6942341))
- properly merge classes in custom containers ([#4128](https://github.com/vuejs/vitepress/issues/4128)) ([8aad617](https://github.com/vuejs/vitepress/commit/8aad617446c03d39a65a0b21e9fce43bc484af1e))
- rebuild dynamic routes cache on server restart ([9f54714](https://github.com/vuejs/vitepress/commit/9f54714e7db69fd4902f1917f927456c71b5a292)), closes [#4525](https://github.com/vuejs/vitepress/issues/4525)
### Features
- allow matching region end in snippets without tag ([#4287](https://github.com/vuejs/vitepress/issues/4287)) ([1a2f81d](https://github.com/vuejs/vitepress/commit/1a2f81de4d6549dd1adf86ae131d1a861158bd2d))
- improve region regexes for snippet plugin ([1a6684c](https://github.com/vuejs/vitepress/commit/1a6684cf1054d326bc1dd6eeb9fb78b150ac2b2a))
- support using header anchors in markdown file inclusion ([#4608](https://github.com/vuejs/vitepress/issues/4608)) ([b99d512](https://github.com/vuejs/vitepress/commit/b99d5123c9b2afdc7461089e03476c34d7816faf)), closes [#4375](https://github.com/vuejs/vitepress/issues/4375) [#4382](https://github.com/vuejs/vitepress/issues/4382)
## [2.0.0-alpha.3](https://github.com/vuejs/vitepress/compare/v2.0.0-alpha.2...v2.0.0-alpha.3) (2025-02-24)
### Bug Fixes
- **build:** `--minify` not working as documented ([9b5c037](https://github.com/vuejs/vitepress/commit/9b5c0377cd3474447c84b2901801287f3caf3d82)), closes [#4523](https://github.com/vuejs/vitepress/issues/4523)
- **build:** deterministic code group ids ([#4565](https://github.com/vuejs/vitepress/issues/4565)) ([b930b8d](https://github.com/vuejs/vitepress/commit/b930b8d5310f1691d8d9f009f45b70122e4ce800))
- **markdown:** include content of all tokens in heading ids ([68dff2a](https://github.com/vuejs/vitepress/commit/68dff2af8547ae70f6622ac826affd76f2f6378e)), closes [#4561](https://github.com/vuejs/vitepress/issues/4561)
- **client:** set correct oldURL and newURL for hashchange ([#4573](https://github.com/vuejs/vitepress/issues/4573)) ([d1f2afd](https://github.com/vuejs/vitepress/commit/d1f2afdf0fbb022f12cc12295723b3b7c7ef5cb1))
- **theme:** allow interactions behind scroll shadow ([#4537](https://github.com/vuejs/vitepress/issues/4537)) ([091d584](https://github.com/vuejs/vitepress/commit/091d5840ae15b64e04e8c07fbc0263a2749571bd))
- **theme:** code block contrast ratio ([#4487](https://github.com/vuejs/vitepress/issues/4487)) ([5dccaee](https://github.com/vuejs/vitepress/commit/5dccaeef055beb109919f8990032975a0d630384))
- **build:** fix flaky embedded languages highlighting ([#4566](https://github.com/vuejs/vitepress/issues/4566)) ([1969cf4](https://github.com/vuejs/vitepress/commit/1969cf4f3b93ad105595e4e2f8b030b04eb1c975))
### Features
- **cli:** support custom `srcDir` ([#4270](https://github.com/vuejs/vitepress/issues/4270)) ([518c094](https://github.com/vuejs/vitepress/commit/518c0945f159aae679ef710bb48ae3ab3891cc9f))
- **cli:** support custom npm scripts prefix ([#4271](https://github.com/vuejs/vitepress/issues/4271)) ([e5a0ee8](https://github.com/vuejs/vitepress/commit/e5a0ee8161752a77c5bb9546245a940cb5f28fb8))
- **build:** dynamic routes plugin overhaul ([#4525](https://github.com/vuejs/vitepress/issues/4525)) ([a62ea6a](https://github.com/vuejs/vitepress/commit/a62ea6a832a33b756642b24ad5d38c248e08b554))
- **build:** update to shiki v3 ([#4571](https://github.com/vuejs/vitepress/issues/4571)) ([52c2aa1](https://github.com/vuejs/vitepress/commit/52c2aa178d4b3fa98b863cf28f0ccf6d2aabcd93))
- **build:** use `markdown-it-async`, remove `synckit` ([#4507](https://github.com/vuejs/vitepress/issues/4507)) ([8062235](https://github.com/vuejs/vitepress/commit/80622356f1d648577ee47ee3a44b04bb015ee462))
### BREAKING CHANGES
- markdown-it-async is used instead of markdown-it. If you're using custom content renderer for local search, you'll need to do `await md.renderAsync` instead of `md.render`.
- Internals are modified a bit to better support vite 6 and handle HMR more correctly. For most users this won't need any change on their side.
- shiki is upgraded to v3. There shouldn't be any breaking change but if you see any issue, please report it.
## [2.0.0-alpha.2](https://github.com/vuejs/vitepress/compare/v2.0.0-alpha.1...v2.0.0-alpha.2) (2025-01-23)
### Bug Fixes

@ -173,5 +173,13 @@ export default defineConfig({
}
}
}
},
vite: {
server: {
watch: {
usePolling: true,
interval: 100
}
}
}
})

@ -30,7 +30,7 @@ function removeSpaces(str: string) {
<input
type="radio"
:id="option.key"
:name="name"
:name
:value="option.value"
v-model="selected"
/>

@ -1,8 +1,14 @@
export default {
async paths() {
return [
{ params: { id: 'foo' }, content: `# Foo` },
{ params: { id: 'bar' }, content: `# Bar` }
]
import { defineRoutes } from 'vitepress'
import paths from './paths'
export default defineRoutes({
async paths(watchedFiles: string[]) {
// console.log('watchedFiles', watchedFiles)
return paths
},
watch: ['**/data-loading/**/*.json'],
async transformPageData(pageData) {
// console.log('transformPageData', pageData.filePath)
pageData.title += ' - transformed'
}
}
})

@ -0,0 +1,4 @@
export default [
{ params: { id: 'foo' }, content: `# Foo` },
{ params: { id: 'bar' }, content: `# Bar` }
]

@ -0,0 +1,27 @@
# header 1
header 1 content
## header 1.1
header 1.1 content
### header 1.1.1
header 1.1.1 content
### header 1.1.2
header 1.1.2 content
## header 1.2
header 1.2 content
### header 1.2.1
header 1.2.1 content
### header 1.2.2
header 1.2.2 content

@ -213,6 +213,10 @@ export default config
<!--@include: ./region-include.md#range-region{5,}-->
## Markdown File Inclusion with Header
<!--@include: ./header-include.md#header-1-1-->
## Image Lazy Loading
![vitepress logo](/vitepress.png)
![vitepress logo](/vitepress.png)

@ -64,8 +64,61 @@ describe('Emoji', () => {
describe('Table of Contents', () => {
test('render toc', async () => {
const items = page.locator('#table-of-contents + nav ul li')
const count = await items.count()
expect(count).toBe(44)
expect(
await items.evaluateAll((elements) =>
elements.map((el) => el.childNodes[0].textContent)
)
).toMatchInlineSnapshot(`
[
"Links",
"Internal Links",
"External Links",
"GitHub-Style Tables",
"Emoji",
"Table of Contents",
"Custom Containers",
"Default Title",
"Custom Title",
"Line Highlighting in Code Blocks",
"Single Line",
"Multiple single lines, ranges",
"Comment Highlight",
"Line Numbers",
"Import Code Snippets",
"Basic Code Snippet",
"Specify Region",
"With Other Features",
"Code Groups",
"Basic Code Group",
"With Other Features",
"Markdown File Inclusion",
"Region",
"Markdown At File Inclusion",
"Markdown Nested File Inclusion",
"Region",
"After Foo",
"Sub sub",
"Sub sub sub",
"Markdown File Inclusion with Range",
"Region",
"Markdown File Inclusion with Range without Start",
"Region",
"Markdown File Inclusion with Range without End",
"Region",
"Markdown At File Region Snippet",
"Region Snippet",
"Markdown At File Range Region Snippet",
"Range Region Line 2",
"Markdown At File Range Region Snippet without start",
"Range Region Line 1",
"Markdown At File Range Region Snippet without end",
"Range Region Line 3",
"Markdown File Inclusion with Header",
"header 1.1.1",
"header 1.1.2",
"Image Lazy Loading",
]
`)
})
})

@ -1,4 +1,9 @@
import { dedent, rawPathToToken } from 'node/markdown/plugins/snippet'
import {
dedent,
findRegion,
rawPathToToken
} from 'node/markdown/plugins/snippet'
import { expect } from 'vitest'
const removeEmptyKeys = <T extends Record<string, unknown>>(obj: T) => {
return Object.fromEntries(
@ -94,9 +99,228 @@ describe('node/markdown/plugins/snippet', () => {
})
})
test('rawPathToToken', () => {
rawPathTokenMap.forEach(([rawPath, token]) => {
describe('rawPathToToken', () => {
test.each(rawPathTokenMap)('%s', (rawPath, token) => {
expect(removeEmptyKeys(rawPathToToken(rawPath))).toEqual(token)
})
})
describe('findRegion', () => {
it('returns null when no region markers are present', () => {
const lines = ['function foo() {', ' console.log("hello");', '}']
expect(findRegion(lines, 'foo')).toBeNull()
})
it('ignores non-matching region names', () => {
const lines = [
'// #region regionA',
'some code here',
'// #endregion regionA'
]
expect(findRegion(lines, 'regionC')).toBeNull()
})
it('returns null if a region start marker exists without a matching end marker', () => {
const lines = [
'// #region missingEnd',
'console.log("inside region");',
'console.log("still inside");'
]
expect(findRegion(lines, 'missingEnd')).toBeNull()
})
it('returns null if an end marker exists without a preceding start marker', () => {
const lines = [
'// #endregion ghostRegion',
'console.log("stray end marker");'
]
expect(findRegion(lines, 'ghostRegion')).toBeNull()
})
it('detects C#/JavaScript style region markers with matching tags', () => {
const lines = [
'Console.WriteLine("Before region");',
'#region hello',
'Console.WriteLine("Hello, World!");',
'#endregion hello',
'Console.WriteLine("After region");'
]
const result = findRegion(lines, 'hello')
expect(result).not.toBeNull()
if (result) {
expect(lines.slice(result.start, result.end).join('\n')).toBe(
'Console.WriteLine("Hello, World!");'
)
}
})
it('detects region markers even when the end marker omits the region name', () => {
const lines = [
'Console.WriteLine("Before region");',
'#region hello',
'Console.WriteLine("Hello, World!");',
'#endregion',
'Console.WriteLine("After region");'
]
const result = findRegion(lines, 'hello')
expect(result).not.toBeNull()
if (result) {
expect(lines.slice(result.start, result.end).join('\n')).toBe(
'Console.WriteLine("Hello, World!");'
)
}
})
it('handles indented region markers correctly', () => {
const lines = [
' Console.WriteLine("Before region");',
' #region hello',
' Console.WriteLine("Hello, World!");',
' #endregion hello',
' Console.WriteLine("After region");'
]
const result = findRegion(lines, 'hello')
expect(result).not.toBeNull()
if (result) {
expect(lines.slice(result.start, result.end).join('\n')).toBe(
' Console.WriteLine("Hello, World!");'
)
}
})
it('detects TypeScript style region markers', () => {
const lines = [
'let regexp: RegExp[] = [];',
'// #region foo',
'let start = -1;',
'// #endregion foo'
]
const result = findRegion(lines, 'foo')
expect(result).not.toBeNull()
if (result) {
expect(lines.slice(result.start, result.end).join('\n')).toBe(
'let start = -1;'
)
}
})
it('detects CSS style region markers', () => {
const lines = [
'.body-content {',
'/* #region foo */',
' padding-left: 15px;',
'/* #endregion foo */',
' padding-right: 15px;',
'}'
]
const result = findRegion(lines, 'foo')
expect(result).not.toBeNull()
if (result) {
expect(lines.slice(result.start, result.end).join('\n')).toBe(
' padding-left: 15px;'
)
}
})
it('detects HTML style region markers', () => {
const lines = [
'<div>Some content</div>',
'<!-- #region foo -->',
' <h1>Hello world</h1>',
'<!-- #endregion foo -->',
'<div>Other content</div>'
]
const result = findRegion(lines, 'foo')
expect(result).not.toBeNull()
if (result) {
expect(lines.slice(result.start, result.end).join('\n')).toBe(
' <h1>Hello world</h1>'
)
}
})
it('detects Visual Basic style region markers (with case-insensitive "End")', () => {
const lines = [
'Console.WriteLine("VB")',
'#Region VBRegion',
' Console.WriteLine("Inside region")',
'#End Region VBRegion',
'Console.WriteLine("Done")'
]
const result = findRegion(lines, 'VBRegion')
expect(result).not.toBeNull()
if (result) {
expect(lines.slice(result.start, result.end).join('\n')).toBe(
' Console.WriteLine("Inside region")'
)
}
})
it('detects Bat style region markers', () => {
const lines = ['::#region foo', 'echo off', '::#endregion foo']
const result = findRegion(lines, 'foo')
expect(result).not.toBeNull()
if (result) {
expect(lines.slice(result.start, result.end).join('\n')).toBe(
'echo off'
)
}
})
it('detects C/C++ style region markers using #pragma', () => {
const lines = [
'#pragma region foo',
'int a = 1;',
'#pragma endregion foo'
]
const result = findRegion(lines, 'foo')
expect(result).not.toBeNull()
if (result) {
expect(lines.slice(result.start, result.end).join('\n')).toBe(
'int a = 1;'
)
}
})
it('returns the first complete region when multiple regions exist', () => {
const lines = [
'// #region foo',
'first region content',
'// #endregion foo',
'// #region foo',
'second region content',
'// #endregion foo'
]
const result = findRegion(lines, 'foo')
expect(result).not.toBeNull()
if (result) {
expect(lines.slice(result.start, result.end).join('\n')).toBe(
'first region content'
)
}
})
it('handles nested regions with different names properly', () => {
const lines = [
'// #region foo',
"console.log('line before nested');",
'// #region bar',
"console.log('nested content');",
'// #endregion bar',
'// #endregion foo'
]
const result = findRegion(lines, 'foo')
expect(result).not.toBeNull()
if (result) {
const extracted = lines.slice(result.start, result.end).join('\n')
const expected = [
"console.log('line before nested');",
'// #region bar',
"console.log('nested content');",
'// #endregion bar'
].join('\n')
expect(extracted).toBe(expected)
}
})
})
})

@ -0,0 +1,72 @@
import { ModuleGraph } from 'node/utils/moduleGraph'
describe('node/utils/moduleGraph', () => {
let graph: ModuleGraph
beforeEach(() => {
graph = new ModuleGraph()
})
it('should correctly delete a module and its dependents', () => {
graph.add('A', ['B', 'C'])
graph.add('B', ['D'])
graph.add('C', [])
graph.add('D', [])
expect(graph.delete('D')).toEqual(new Set(['D', 'B', 'A']))
})
it('should handle shared dependencies correctly', () => {
graph.add('A', ['B', 'C'])
graph.add('B', ['D'])
graph.add('C', ['D']) // Shared dependency
graph.add('D', [])
expect(graph.delete('D')).toEqual(new Set(['A', 'B', 'C', 'D']))
})
it('merges dependencies correctly', () => {
// Add module A with dependency B
graph.add('A', ['B'])
// Merge new dependency C into module A (B should remain)
graph.add('A', ['C'])
// Deleting B should remove A as well, since A depends on B.
expect(graph.delete('B')).toEqual(new Set(['B', 'A']))
})
it('handles cycles gracefully', () => {
// Create a cycle: A -> B, B -> C, C -> A.
graph.add('A', ['B'])
graph.add('B', ['C'])
graph.add('C', ['A'])
// Deleting any module in the cycle should delete all modules in the cycle.
expect(graph.delete('A')).toEqual(new Set(['A', 'B', 'C']))
})
it('cleans up dependencies when deletion', () => {
// Setup A -> B relationship.
graph.add('A', ['B'])
graph.add('B', [])
// Deleting B should remove both B and A from the graph.
expect(graph.delete('B')).toEqual(new Set(['B', 'A']))
// After deletion, add modules again.
graph.add('C', [])
graph.add('A', ['C']) // Now A depends only on C.
expect(graph.delete('C')).toEqual(new Set(['C', 'A']))
})
it('handles independent modules', () => {
// Modules with no dependencies.
graph.add('X', [])
graph.add('Y', [])
// Deletion of one should only remove that module.
expect(graph.delete('X')).toEqual(new Set(['X']))
expect(graph.delete('Y')).toEqual(new Set(['Y']))
})
})

@ -1,4 +1,4 @@
<svg width="160" height="192" viewBox="0 0 160 192" fill="none" xmlns="http://www.w3.org/2000/svg">
<svg viewBox="0 0 160 192" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_1288_1252)">
<path d="M0.12699 43.8989C-0.863275 37.1255 4.04575 30.863 11.0915 29.911L113.152 16.1221C120.197 15.1702 126.712 19.8893 127.702 26.6627L147.873 164.635C148.863 171.409 143.954 177.671 136.908 178.623L39.1006 191.837C29.7063 193.107 21.0203 186.814 19.7001 177.784L0.12699 43.8989Z" fill="url(#paint0_linear_1288_1252)"/>
<path d="M10.1376 30.5728C9.06487 22.8787 14.3827 15.7647 22.0152 14.6834L124.678 0.138664C132.31 -0.942678 139.367 4.41806 140.44 12.1122L159.862 151.427C160.935 159.121 155.617 166.235 147.985 167.317L45.3224 181.861C37.6899 182.943 30.6329 177.582 29.5602 169.888L10.1376 30.5728Z" fill="url(#paint1_linear_1288_1252)"/>

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB

@ -1,9 +1,9 @@
@import url('https://fonts.googleapis.com/css2?family=Vazirmatn:wght@100..900&display=swap');
:root:where(:lang(fa)) {
--vp-font-family-base: 'Vazirmatn', 'Inter', ui-sans-serif, system-ui,
sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol',
'Noto Color Emoji';
--vp-font-family-base:
'Vazirmatn', 'Inter', ui-sans-serif, system-ui, sans-serif,
'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
}
:root {
@ -33,6 +33,11 @@
}
}
.VPHero .VPImage {
filter: drop-shadow(-2px 4px 6px rgba(0, 0, 0, 0.2));
padding: 18px;
}
/* used in reference/default-theme-search */
img[src='/search.png'] {
width: 100%;

@ -111,7 +111,7 @@ Set up a new project and change these settings using your dashboard:
- **Build Command:** `npm run docs:build`
- **Output Directory:** `docs/.vitepress/dist`
- **Node Version:** `18` (or above)
- **Node Version:** `20` (or above)
::: warning
Don't enable options like _Auto Minify_ for HTML code. It will remove comments from output which have meaning to Vue. You may see hydration mismatch errors if they get removed.
@ -163,7 +163,7 @@ Don't enable options like _Auto Minify_ for HTML code. It will remove comments f
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 20
node-version: 22
cache: npm # or pnpm / yarn
- name: Setup Pages
uses: actions/configure-pages@v4

@ -255,7 +255,7 @@ This is a special container that can be used to prevent style and router conflic
```md
::: raw
Wraps in a <div class="vp-raw">
Wraps in a `<div class="vp-raw">`
:::
```
@ -824,7 +824,7 @@ It also supports selecting a line range:
**Input**
```md
```md:line-numbers
# Docs
## Basics
@ -834,7 +834,7 @@ It also supports selecting a line range:
**Part file** (`parts/basics.md`)
```md
```md:line-numbers
Some getting started stuff.
### Configuration
@ -844,7 +844,7 @@ Can be created using `.foorc.json`.
**Equivalent code**
```md
```md:line-numbers
# Docs
## Basics
@ -860,7 +860,7 @@ You can also use a [VS Code region](https://code.visualstudio.com/docs/editor/co
**Input**
```md
```md:line-numbers
# Docs
## Basics
@ -871,7 +871,7 @@ You can also use a [VS Code region](https://code.visualstudio.com/docs/editor/co
**Part file** (`parts/basics.md`)
```md
```md:line-numbers
<!-- #region basic-usage -->
## Usage Line 1
@ -883,7 +883,7 @@ You can also use a [VS Code region](https://code.visualstudio.com/docs/editor/co
**Equivalent code**
```md
```md:line-numbers
# Docs
## Basics
@ -897,6 +897,53 @@ You can also use a [VS Code region](https://code.visualstudio.com/docs/editor/co
Note that this does not throw errors if your file is not present. Hence, when using this feature make sure that the contents are being rendered as expected.
:::
Instead of VS Code regions, you can also use header anchors to include a specific section of the file. For example, if you have a header in your markdown file like this:
```md
## My Base Section
Some content here.
### My Sub Section
Some more content here.
## Another Section
Content outside `My Base Section`.
```
You can include the `My Base Section` section like this:
```md
## My Extended Section
<!--@include: ./parts/basics.md#my-base-section-->
```
**Equivalent code**
```md
## My Extended Section
Some content here.
### My Sub Section
Some more content here.
```
Here, `my-base-section` is the generated id of the heading element. In case it's not easily guessable, you can open the part file in your browser and click on the heading anchor (`#` symbol left to the heading when hovered) to see the id in the URL bar. Or use browser dev tools to inspect the element. Alternatively, you can also specify the id to the part file like this:
```md
## My Base Section {#custom-id}
```
and include it like this:
```md
<!--@include: ./parts/basics.md#custom-id-->
```
## Math Equations
This is currently opt-in. To enable it, you need to install `markdown-it-mathjax3` and set `markdown.math` to `true` in your config file:

@ -288,4 +288,4 @@ Vue provides IntelliSense support out of the box via the [Vue - Official VS Code
"vue.server.includeLanguages": ["vue", "markdown"]
}
```
:::
:::

@ -19,7 +19,7 @@ hero:
text: GitHub
link: https://github.com/vuejs/vitepress
image:
src: /vitepress-logo-large.webp
src: /vitepress-logo-large.svg
alt: VitePress
features:

@ -457,3 +457,38 @@ Can be used to customize the label of the skip to content link. This link is sho
- Default: `false`
Whether to show an external link icon next to external links in markdown.
## `useLayout` <Badge type="info" text="composable" />
Returns layout-related data. The returned object has the following type:
```ts
interface {
isHome: ComputedRef<boolean>
sidebar: ComputedRef<DefaultTheme.SidebarItem[]>
sidebarGroups: ComputedRef<DefaultTheme.SidebarItem[]>
hasSidebar: ComputedRef<boolean>
isSidebarEnabled: ComputedRef<boolean>
hasAside: ComputedRef<boolean>
leftAside: ComputedRef<boolean>
headers: ShallowRef<DefaultTheme.OutlineItem[]>
hasLocalNav: ComputedRef<boolean>
}
```
**Example:**
```vue
<script setup>
import { useLayout } from 'vitepress/theme'
const { hasSidebar } = useLayout()
</script>
<template>
<div v-if="hasSidebar">Only show when sidebar exists</div>
</template>
```

@ -180,36 +180,3 @@ export default {
}
}
```
## `useSidebar` <Badge type="info" text="composable" />
Returns sidebar-related data. The returned object has the following type:
```ts
export interface DocSidebar {
isOpen: Ref<boolean>
sidebar: ComputedRef<DefaultTheme.SidebarItem[]>
sidebarGroups: ComputedRef<DefaultTheme.SidebarItem[]>
hasSidebar: ComputedRef<boolean>
hasAside: ComputedRef<boolean>
leftAside: ComputedRef<boolean>
isSidebarEnabled: ComputedRef<boolean>
open: () => void
close: () => void
toggle: () => void
}
```
**Example:**
```vue
<script setup>
import { useSidebar } from 'vitepress/theme'
const { hasSidebar } = useSidebar()
</script>
<template>
<div v-if="hasSidebar">Only show when sidebar exists</div>
</template>
```

@ -53,12 +53,12 @@ const members = [
Say hello to our awesome team.
<VPTeamMembers size="small" :members="members" />
<VPTeamMembers size="small" :members />
```
The above will display a team member in card looking element. It should display something similar to below.
<VPTeamMembers size="small" :members="members" />
<VPTeamMembers size="small" :members />
`<VPTeamMembers>` component comes in 2 different sizes, `small` and `medium`. While it boils down to your preference, usually `small` size should fit better when used in doc page. Also, you may add more properties to each member such as adding "description" or "sponsor" button. Learn more about it in [`<VPTeamMembers>`](#vpteammembers).
@ -107,9 +107,7 @@ const members = [
team, some of whom have chosen to be featured below.
</template>
</VPTeamPageTitle>
<VPTeamMembers
:members="members"
/>
<VPTeamMembers :members />
</VPTeamPage>
```

@ -225,3 +225,16 @@ Then you can customize styles of this specific page in `.vitepress/theme/custom.
/* page-specific styles */
}
```
### isHome
- Type: `boolean`
The default theme relies on checks like `frontmatter.layout === 'home'` to determine if the current page is the home page.\
This is useful when you want to force show the home page elements in a custom layout.
```yaml
---
isHome: true
---
```

@ -163,7 +163,7 @@ No active opciones como _Auto Minify_ para código HTML. Eso removera comentario
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 20
node-version: 22
cache: npm # o pnpm / yarn
- name: Setup Pages
uses: actions/configure-pages@v4

@ -234,7 +234,7 @@ Este es un recipiente especial que puee ser usado para evitar conflictos de esti
```md
::: raw
Envuelve en un <div class="vp-raw">
Envuelve en un `<div class="vp-raw">`
:::
```

@ -286,4 +286,4 @@ Vue ofrece soporte para IntelliSense de forma predeterminada mediante el [Plugin
"vue.server.includeLanguages": ["vue", "markdown"]
}
```
:::
:::

@ -19,7 +19,7 @@ hero:
text: GitHub
link: https://github.com/vuejs/vitepress
image:
src: /vitepress-logo-large.webp
src: /vitepress-logo-large.svg
alt: VitePress
features:

@ -181,37 +181,3 @@ export default {
}
}
```
## `useSidebar` <Badge type="info" text="composable" />
Devuelve datos relacionados con la barra lateral. El objeto devuelto tiene el siguiente tipo:
```ts
export interface DocSidebar {
isOpen: Ref<boolean>
sidebar: ComputedRef<DefaultTheme.SidebarItem[]>
sidebarGroups: ComputedRef<DefaultTheme.SidebarItem[]>
hasSidebar: ComputedRef<boolean>
hasAside: ComputedRef<boolean>
leftAside: ComputedRef<boolean>
isSidebarEnabled: ComputedRef<boolean>
open: () => void
close: () => void
toggle: () => void
}
```
**Exemplo:**
```vue
<script setup>
import { useSidebar } from 'vitepress/theme'
const { hasSidebar } = useSidebar()
</script>
<template>
<div v-if="hasSidebar">Sólo visible cuando existe la barra lateral
</div>
</template>
```

@ -53,12 +53,12 @@ const members = [
Saluda a nuestro increible equipo.
<VPTeamMembers size="small" :members="members" />
<VPTeamMembers size="small" :members />
```
El código anterior mostrará a un miembro del equipo en un elemento similar a una tarjeta. Debería mostrar algo similar a lo siguiente.
<VPTeamMembers size="small" :members="members" />
<VPTeamMembers size="small" :members />
El componente `<VPTeamMembers>` viene en dos tamaños diferentes, pequeño `small` y médio `medium`. Si bien es una cuestión de preferencia, generalmente el tamaño `small` debería encajar mejor cuando se use en la página del documento. Además, puede agregar más propiedades a cada miembro, como agregar el botón "descripción" o "patrocinador". Obtenga más información sobre en [`<VPTeamMembers>`](#vpteammembers).
@ -107,9 +107,7 @@ const members = [
Algunos de los miembros han elegido aparecer a continuación.
</template>
</VPTeamPageTitle>
<VPTeamMembers
:members="members"
/>
<VPTeamMembers :members />
</VPTeamPage>
```

@ -60,4 +60,4 @@ const { theme } = useData()
<template>
<img :src="withBase(theme.logoPath)" />
</template>
```
```

@ -161,7 +161,7 @@ Cache-Control: max-age=31536000,immutable
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 20
node-version: 22
cache: npm # or pnpm / yarn
- name: Setup Pages
uses: actions/configure-pages@v4

@ -45,4 +45,4 @@ editLink: true
"editLink": true
}
---
```
```

@ -233,7 +233,7 @@ export default defineConfig({
```md
::: raw
بسته‌بندی در یک <div class="vp-raw">
بسته‌بندی در یک `<div class="vp-raw">`
:::
```

@ -20,4 +20,4 @@
## پیکربندی Frontmatter
- گزینه `home: true` به `layout: home` تغییر کرده است. همچنین، تنظیمات مربوط به صفحه اصلی بسیار تغییر کرده‌اند تا ویژگی‌های اضافی را ارائه دهند. برای جزئیات بیشتر، [راهنمای صفحه اصلی](../reference/default-theme-home-page) را ببینید.
- گزینه `footer` به [`themeConfig.footer`](../reference/default-theme-config#footer) منتقل شده است.
- گزینه `footer` به [`themeConfig.footer`](../reference/default-theme-config#footer) منتقل شده است.

@ -27,4 +27,4 @@
---
ادامه دارد...
ادامه دارد...

@ -20,4 +20,4 @@ document.querySelector('h1').addEventListener('click', () => {
`<script client>` یک ویژگی تنها برای ویت‌پرس است، نه یک ویژگی Vue. این در هر دو فایل `.md` و `.vue` کار می‌کند، اما فقط در حالت MPA. اسکریپت‌های کلاینت در تمام اجزای تم با هم بسته می‌شوند، در حالی که اسکریپت کلاینت برای یک صفحه خاص، فقط برای آن صفحه تقسیم می‌شود.
توجه داشته باشید که `<script client>` به عنوان **کد مؤلفه مؤلفه Vue** ارزیابی نمی‌شود: به عنوان یک ماژول جاوااسکریپت معمولی پردازش می‌شود. به همین دلیل، حالت MPA فقط باید در صورتی استفاده شود که سایت شما به تعامل کمینه‌ای از جانب کلاینت نیاز دارد.
توجه داشته باشید که `<script client>` به عنوان **کد مؤلفه مؤلفه Vue** ارزیابی نمی‌شود: به عنوان یک ماژول جاوااسکریپت معمولی پردازش می‌شود. به همین دلیل، حالت MPA فقط باید در صورتی استفاده شود که سایت شما به تعامل کمینه‌ای از جانب کلاینت نیاز دارد.

@ -55,4 +55,4 @@ export default {
}
}
}
```
```

@ -254,4 +254,4 @@ import ComponentInHeader from '../../components/ComponentInHeader.vue'
border-radius: 8px;
padding: 0 20px;
}
</style>
</style>

@ -54,4 +54,4 @@
تفاوت API بین ویت‌پرس و VuePress عمدتاً در زمینه تم‌سازی و سفارشی‌سازی است. اگر از VuePress 1 با تم پیش‌فرض استفاده می‌کنید، باید مهاجرت به ویت‌پرس نسبتاً ساده باشد.
همچنین تلاش‌هایی برای VuePress 2 انجام شده است، که از Vue 3 و Vite با سازگاری بیشتر با VuePress 1 پشتیبانی می‌کند. با این حال، نگهداری دو SSG به صورت موازی پایدار نیست، بنابراین تیم Vue تصمیم گرفته است که در دراز مدت بر روی ویت‌پرس به عنوان SSG اصلی توصیه شده تمرکز کند.
همچنین تلاش‌هایی برای VuePress 2 انجام شده است، که از Vue 3 و Vite با سازگاری بیشتر با VuePress 1 پشتیبانی می‌کند. با این حال، نگهداری دو SSG به صورت موازی پایدار نیست، بنابراین تیم Vue تصمیم گرفته است که در دراز مدت بر روی ویت‌پرس به عنوان SSG اصلی توصیه شده تمرکز کند.

@ -19,7 +19,7 @@ hero:
text: گیت‌هاب
link: https://github.com/vuejs/vitepress
image:
src: /vitepress-logo-large.webp
src: /vitepress-logo-large.svg
alt: ویت‌پرس
features:

@ -69,4 +69,4 @@ interface Props {
// پیش‌فرض به `tip`.
type?: 'info' | 'tip' | 'warning' | 'danger'
}
```
```

@ -19,4 +19,4 @@ export default {
`//cdn.carbonads.com/carbon.js?serve=${code}&placement=${placement}`
```
برای یادگیری بیشتر درباره پیکربندی تبلیغات Carbon، لطفاً به [وب‌سایت Carbon Ads](https://www.carbonads.net/) مراجعه کنید.
برای یادگیری بیشتر درباره پیکربندی تبلیغات Carbon، لطفاً به [وب‌سایت Carbon Ads](https://www.carbonads.net/) مراجعه کنید.

@ -466,4 +466,4 @@ export interface DocFooter {
- نوع: `boolean`
- پیش‌فرض: `false`
آیا باید نمایش آیکون لینک خارجی کنار لینک‌های خارجی در مارک‌داون باشد.
آیا باید نمایش آیکون لینک خارجی کنار لینک‌های خارجی در مارک‌داون باشد.

@ -50,4 +50,4 @@ export default {
---
footer: false
---
```
```

@ -190,4 +190,4 @@ npx vitepress init
::: info اطلاعات
ویت‌پرس همیشه استایل اضافی محتوای صفحه `layout: home` را خودکار نمی‌کند. برای بازگشت به رفتار قدیمی، می‌توانید `markdownStyles: false` را به frontmatter اضافه کنید.
:::
:::

@ -24,4 +24,4 @@ lastUpdated: false
---
```
همچنین به [پیکربندی پیش‌فرض: آخرین بروزرسانی](./default-theme-config#lastupdated) مراجعه کنید تا اطلاعات بیشتری دریافت کنید. هر مقدار حقیقی در سطح تم از ویژگی را فعال خواهد کرد مگر آنکه به صورت صریح در سطح سایت یا صفحه غیرفعال شود.
همچنین به [پیکربندی پیش‌فرض: آخرین بروزرسانی](./default-theme-config#lastupdated) مراجعه کنید تا اطلاعات بیشتری دریافت کنید. هر مقدار حقیقی در سطح تم از ویژگی را فعال خواهد کرد مگر آنکه به صورت صریح در سطح سایت یا صفحه غیرفعال شود.

@ -59,4 +59,4 @@ export default {
app.component('foo', Foo)
}
}
```
```

@ -178,38 +178,3 @@ export default {
}
}
```
## `useSidebar` <Badge type="info" text="composable" /> {#usesidebar}
داده‌های مربوط به نوار کناری را برمی‌گرداند. شیء برگردانده شده دارای نوع‌های زیر است:
```ts
export interface DocSidebar {
isOpen: Ref<boolean>
sidebar: ComputedRef<DefaultTheme.SidebarItem[]>
sidebarGroups: ComputedRef<DefaultTheme.SidebarItem[]>
hasSidebar: ComputedRef<boolean>
hasAside: ComputedRef<boolean>
leftAside: ComputedRef<boolean>
isSidebarEnabled: ComputedRef<boolean>
open: () => void
close: () => void
toggle: () => void
}
```
**مثال:**
```vue
<script setup>
import { useSidebar } from 'vitepress/theme'
const { hasSidebar } = useSidebar()
</script>
<template>
<div v-if="hasSidebar">فقط ن
مایش داده شود زمانی که نوار کناری وجود دارد</div>
</template>
```

@ -53,12 +53,12 @@ const members = [
با سلام به تیم فوق‌العاده‌ی ما خوش آمدید.
<VPTeamMembers size="small" :members="members" />
<VPTeamMembers size="small" :members />
```
بالا به صورت عنصری با شکل کارتی اعضای تیم را نمایش می‌دهد. باید به شکل زیر نمایش داده شود.
<VPTeamMembers size="small" :members="members" />
<VPTeamMembers size="small" :members />
کامپوننت `<VPTeamMembers>` دارای دو اندازه مختلف، `small` و `medium` است. معمولاً اندازه `small` برای استفاده در صفحات مستندات مناسب‌تر است. همچنین می‌توانید ویژگی‌های بیشتری برای هر عضو اضافه کنید مانند "توضیحات" یا "دکمه حامی". جهت کسب اطلاعات بیشتر به [`<VPTeamMembers>`](#vpteammembers) مراجعه کنید.
@ -106,9 +106,7 @@ const members = [
توسعه ویت‌پرس توسط تیمی بین‌المللی راهنمایی می‌شود، برخی از اعضا که انتخاب کرده‌اند تا در زیر نمایش داده شوند.
</template>
</VPTeamPageTitle>
<VPTeamMembers
:members="members"
/>
<VPTeamMembers :members />
</VPTeamPage>
```

@ -165,4 +165,4 @@ title: سلام
```md
- نام بسته: {{ $params.pkg }}
- نسخه: {{ $params.version }}
```
```

@ -723,4 +723,4 @@ export default {
interface TransformPageContext {
siteConfig: SiteConfig
}
```
```

@ -162,7 +162,7 @@ HTML 코드에 대해 _Auto Minify_ 옵션을 활성화하지 마세요. 이는
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 20
node-version: 22
cache: npm # 또는 pnpm / yarn
- name: Setup Pages
uses: actions/configure-pages@v4

@ -233,7 +233,7 @@ export default defineConfig({
```md
::: raw
<div class="vp-raw">로 감쌉니다
`<div class="vp-raw">`로 감쌉니다
:::
```

@ -19,7 +19,7 @@ hero:
text: GitHub
link: https://github.com/vuejs/vitepress
image:
src: /vitepress-logo-large.webp
src: /vitepress-logo-large.svg
alt: VitePress
features:

@ -180,36 +180,3 @@ export default {
}
}
```
## `useSidebar` <Badge type="info" text="composable" />
사이드바 관련 데이터를 반환합니다. 반환된 객체는 다음과 같은 타입을 가집니다:
```ts
export interface DocSidebar {
isOpen: Ref<boolean>
sidebar: ComputedRef<DefaultTheme.SidebarItem[]>
sidebarGroups: ComputedRef<DefaultTheme.SidebarItem[]>
hasSidebar: ComputedRef<boolean>
hasAside: ComputedRef<boolean>
leftAside: ComputedRef<boolean>
isSidebarEnabled: ComputedRef<boolean>
open: () => void
close: () => void
toggle: () => void
}
```
**예제:**
```vue
<script setup>
import { useSidebar } from 'vitepress/theme'
const { hasSidebar } = useSidebar()
</script>
<template>
<div v-if="hasSidebar">사이드바가 있을 때만 보여줍니다</div>
</template>
```

@ -53,12 +53,12 @@ const members = [
Say hello to our awesome team.
<VPTeamMembers size="small" :members="members" />
<VPTeamMembers size="small" :members />
```
위 코드는 카드 형태의 엘리먼트로 팀 구성원을 표시합니다. 아래와 비슷한 형태로 표시됩니다.
<VPTeamMembers size="small" :members="members" />
<VPTeamMembers size="small" :members />
`<VPTeamMembers>` 컴포넌트는 `small``medium` 두 가지 크기로 제공됩니다. 개인의 선호도에 따라 선택할 수 있지만, 일반적으로 `small` 사이즈가 문서 페이지에 더 적합합니다. 또한, 각 구성원에 "설명"이나 "후원" 버튼과 같은 프로퍼티를 추가할 수도 있습니다. 자세한 내용은 [`<VPTeamMembers>`](#vpteammembers)에서 확인할 수 있습니다.
@ -107,9 +107,7 @@ const members = [
team, some of whom have chosen to be featured below.
</template>
</VPTeamPageTitle>
<VPTeamMembers
:members="members"
/>
<VPTeamMembers :members />
</VPTeamPage>
```

@ -15,6 +15,6 @@
"open-cli": "^8.0.0",
"postcss-rtlcss": "^5.6.0",
"vitepress": "workspace:*",
"vitepress-plugin-group-icons": "^1.3.5"
"vitepress-plugin-group-icons": "^1.3.8"
}
}

@ -163,7 +163,7 @@ Não ative opções como _Auto Minify_ para código HTML. Isso removerá coment
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 20
node-version: 22
cache: npm # ou pnpm / yarn
- name: Setup Pages
uses: actions/configure-pages@v4

@ -233,7 +233,7 @@ Este é um recipiente especial que pode ser usado para evitar conflitos de estil
```md
::: raw
Envolve em um <div class="vp-raw">
Envolve em um `<div class="vp-raw">`
:::
```

@ -19,7 +19,7 @@ hero:
text: GitHub
link: https://github.com/vuejs/vitepress
image:
src: /vitepress-logo-large.webp
src: /vitepress-logo-large.svg
alt: VitePress
features:

@ -180,36 +180,3 @@ export default {
}
}
```
## `useSidebar` <Badge type="info" text="composable" />
Retorna dados relacionados à barra lateral. O objeto retornado tem o seguinte tipo:
```ts
export interface DocSidebar {
isOpen: Ref<boolean>
sidebar: ComputedRef<DefaultTheme.SidebarItem[]>
sidebarGroups: ComputedRef<DefaultTheme.SidebarItem[]>
hasSidebar: ComputedRef<boolean>
hasAside: ComputedRef<boolean>
leftAside: ComputedRef<boolean>
isSidebarEnabled: ComputedRef<boolean>
open: () => void
close: () => void
toggle: () => void
}
```
**Exemplo:**
```vue
<script setup>
import { useSidebar } from 'vitepress/theme'
const { hasSidebar } = useSidebar()
</script>
<template>
<div v-if="hasSidebar">Visível apenas quando a barra lateral existe</div>
</template>
```

@ -53,12 +53,12 @@ const members = [
Diga olá à nossa equipe incrível.
<VPTeamMembers size="small" :members="members" />
<VPTeamMembers size="small" :members />
```
O código acima exibirá um membro da equipe em um elemento tipo cartão. Ele deve exibir algo semelhante ao abaixo.
<VPTeamMembers size="small" :members="members" />
<VPTeamMembers size="small" :members />
O componente `<VPTeamMembers>` vem em 2 tamanhos diferentes, pequeno `small` e médio `medium`. Enquanto é uma questão de preferência, geralmente o tamanho `small` deve encaixar melhor quando usado na página de documento. Além disso, você pode adicionar mais propriedades a cada membro, como adicionar o botão "descrição" ou "patrocinador". Saiba mais sobre em [`<VPTeamMembers>`](#vpteammembers).
@ -107,9 +107,7 @@ const members = [
alguns dos membros escolheram ser apresentados abaixo.
</template>
</VPTeamPageTitle>
<VPTeamMembers
:members="members"
/>
<VPTeamMembers :members />
</VPTeamPage>
```

@ -0,0 +1 @@
../../art/vitepress-logo.svg

@ -1,21 +0,0 @@
<svg width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M5.03628 7.87818C4.75336 5.83955 6.15592 3.95466 8.16899 3.66815L33.6838 0.0367403C35.6969 -0.24977 37.5581 1.1706 37.841 3.20923L42.9637 40.1218C43.2466 42.1604 41.8441 44.0453 39.831 44.3319L14.3162 47.9633C12.3031 48.2498 10.4419 46.8294 10.159 44.7908L5.03628 7.87818Z" fill="url(#paint0_linear_1287_1214)"/>
<path d="M6.85877 7.6188C6.71731 6.59948 7.41859 5.65703 8.42512 5.51378L33.9399 1.88237C34.9465 1.73911 35.8771 2.4493 36.0186 3.46861L41.1412 40.3812C41.2827 41.4005 40.5814 42.343 39.5749 42.4862L14.0601 46.1176C13.0535 46.2609 12.1229 45.5507 11.9814 44.5314L6.85877 7.6188Z" fill="white"/>
<path d="M33.1857 14.9195L25.8505 34.1576C25.6991 34.5547 25.1763 34.63 24.9177 34.2919L12.3343 17.8339C12.0526 17.4655 12.3217 16.9339 12.7806 16.9524L22.9053 17.3607C22.9698 17.3633 23.0344 17.3541 23.0956 17.3337L32.5088 14.1992C32.9431 14.0546 33.3503 14.4878 33.1857 14.9195Z" fill="url(#paint1_linear_1287_1214)"/>
<path d="M27.0251 12.5756L19.9352 15.0427C19.8187 15.0832 19.7444 15.1986 19.7546 15.3231L20.3916 23.063C20.4066 23.2453 20.5904 23.3628 20.7588 23.2977L22.7226 22.5392C22.9064 22.4682 23.1021 22.6138 23.0905 22.8128L22.9102 25.8903C22.8982 26.0974 23.1093 26.2436 23.295 26.1567L24.4948 25.5953C24.6808 25.5084 24.892 25.6549 24.8795 25.8624L24.5855 30.6979C24.5671 31.0004 24.9759 31.1067 25.1013 30.8321L25.185 30.6487L29.4298 17.8014C29.5008 17.5863 29.2968 17.3809 29.0847 17.454L27.0519 18.1547C26.8609 18.2205 26.6675 18.0586 26.6954 17.8561L27.3823 12.8739C27.4103 12.6712 27.2163 12.5091 27.0251 12.5756Z" fill="url(#paint2_linear_1287_1214)"/>
<defs>
<linearGradient id="paint0_linear_1287_1214" x1="6.48163" y1="1.9759" x2="39.05" y2="48.2064" gradientUnits="userSpaceOnUse">
<stop stop-color="#49C7FF"/>
<stop offset="1" stop-color="#BD36FF"/>
</linearGradient>
<linearGradient id="paint1_linear_1287_1214" x1="11.8848" y1="16.4266" x2="26.7246" y2="31.4177" gradientUnits="userSpaceOnUse">
<stop stop-color="#41D1FF"/>
<stop offset="1" stop-color="#BD34FE"/>
</linearGradient>
<linearGradient id="paint2_linear_1287_1214" x1="21.8138" y1="13.7046" x2="26.2464" y2="28.8069" gradientUnits="userSpaceOnUse">
<stop stop-color="#FFEA83"/>
<stop offset="0.0833333" stop-color="#FFDD35"/>
<stop offset="1" stop-color="#FFA800"/>
</linearGradient>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 33 B

@ -0,0 +1 @@
../../art/vitepress-logo-mini.svg

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 33 B

@ -111,7 +111,7 @@ Cache-Control: max-age=31536000,immutable
- **Build Command:** `npm run docs:build`
- **Output Directory:** `docs/.vitepress/dist`
- **Node Version:** `18` (или выше)
- **Node Version:** `20` (или выше)
::: warning ПРЕДУПРЕЖДЕНИЕ
Не включайте такие опции, как _Auto Minify_ для HTML-кода. Он удалит из вывода комментарии, которые имеют значение для Vue. При их удалении могут возникать ошибки несоответствия гидратации.
@ -163,7 +163,7 @@ Cache-Control: max-age=31536000,immutable
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 20
node-version: 22
cache: npm # или pnpm / yarn
- name: Setup Pages
uses: actions/configure-pages@v4

@ -123,7 +123,7 @@ export default {
## Слоты макета {#layout-slots}
Компонент `<Layout/>` темы по умолчанию имеет несколько слотов, которые можно использовать для вставки содержимого в определённые места страницы. Вот пример внедрения компонента в структуру before:
Компонент `<Layout/>` темы по умолчанию имеет несколько слотов, которые можно использовать для вставки содержимого в определённые места страницы. Вот пример внедрения компонента перед оглавлением:
```js [.vitepress/theme/index.js]
import DefaultTheme from 'vitepress/theme'
@ -131,8 +131,8 @@ import MyLayout from './MyLayout.vue'
export default {
extends: DefaultTheme,
// переопределяем макет с помощью компонента-обёртки, который
// вводит слоты
// переопределяем макет с помощью компонента-обёртки,
// который внедряет слоты
Layout: MyLayout
}
```
@ -147,7 +147,7 @@ const { Layout } = DefaultTheme
<template>
<Layout>
<template #aside-outline-before>
Верхнее содержимое моей пользовательской боковой панели
Мой пользовательский контент в верхней части боковой панели
</template>
</Layout>
</template>

@ -27,7 +27,7 @@ export default defineConfig({
ru: {
label: 'Русский',
lang: 'ru', // необязательный, будет добавлен как атрибут `lang` в тег `html`
link: '/ru/guide' // по умолчанию /ru/ -- отображается в меню переводов на панели навигации, может быть внешним
link: '/ru/guide' // по умолчанию /ru/ -- ссылка в меню переводов на панели навигации, может быть внешней
// другие свойства, специфичные для локали...
}

@ -259,7 +259,7 @@ console.log('Привет, VitePress!')
```md
::: raw
Заворачивается в <div class="vp-raw">
Заворачивается в `<div class="vp-raw">`
:::
```
@ -844,7 +844,7 @@ export default config
Может быть создана с помощью `.foorc.json`.
```
**Эквивалентный код**
**Соответствующий код**
```md
# Документация
@ -883,7 +883,7 @@ export default config
<!-- #endregion basic-usage -->
```
**Эквивалентный код**
**Соответствующий код**
```md
# Документация
@ -899,6 +899,53 @@ export default config
Обратите внимание, что это не приводит к ошибкам, если ваш файл отсутствует. Поэтому при использовании этой функции убедитесь, что содержимое отображается так, как ожидается.
:::
Вместо регионов VS Code вы также можете использовать якоря заголовков, чтобы включить определённый раздел файла. Например, если у вас есть заголовок в вашем markdown-файле, например:
```md
## Мой основной раздел
Какой-то контент здесь.
### Мой подраздел
Ещё немного контента здесь.
## Другой раздел
Контент вне `Моего основного раздела`.
```
Вы можете включить раздел `Мой основной раздел` следующим образом:
```md
## Мой дополнительный раздел
<!--@include: ./parts/basics.md#мои-основнои-раздел-->
```
**Соответствующий код**
```md
## Мой дополнительный раздел
Какой-то контент здесь.
### Мой подраздел
Ещё немного контента здесь.
```
Здесь `мои-основнои-раздел` — это сгенерированный идентификатор элемента заголовка. Если его нелегко угадать, вы можете открыть файл в браузере и нажать на якорь заголовка (символ `#` слева от заголовка при наведении), чтобы увидеть идентификатор в адресной строке. Или используйте инструменты разработчика браузера для проверки элемента. Кроме того, вы также можете указать идентификатор для файла части следующим образом:
```md
## Мой основной раздел {#custom-id}
```
и включить его следующим образом:
```md
<!--@include: ./parts/basics.md#custom-id-->
```
## Математические уравнения {#math-equations}
В настоящее время эта фича предоставляется по желанию. Чтобы включить её, вам нужно установить `markdown-it-mathjax3` и установить значение `true` для опции `markdown.math` в вашем файле конфигурации:

@ -148,13 +148,13 @@ HTML, обёрнутый `<code>`, будет отображаться как е
**Разметка**
```md
Это <span v-pre>{{ будет отображаться как есть}}</span>.
Это <span v-pre>{{ будет отображаться как есть }}</span>.
```
**Результат**
<div class="escape-demo">
<p>Это <span v-pre>{{ будет отображаться как есть}}</span></p>
<p>Это <span v-pre>{{ будет отображаться как есть }}</span></p>
</div>
В качестве альтернативы вы можете обернуть весь абзац в пользовательский контейнер `v-pre`:
@ -175,7 +175,7 @@ HTML, обёрнутый `<code>`, будет отображаться как е
</div>
## Unescape в блоках кода {#unescape-in-code-blocks}
## Отключение экранирования в блоках кода {#unescape-in-code-blocks}
По умолчанию все изолированные блоки кода автоматически оборачиваются `v-pre`, поэтому внутри них не будет обрабатываться синтаксис Vue. Чтобы включить интерполяцию в стиле Vue внутри фигурных скобок, можно добавить к языку суффикс `-vue`, например `js-vue`:
@ -199,7 +199,9 @@ HTML, обёрнутый `<code>`, будет отображаться как е
VitePress имеет [встроенную поддержку](https://vitejs.dev/guide/features.html#css-pre-processors) для препроцессоров CSS: файлы `.scss`, `.sass`, `.less`, `.styl` и `.stylus`. Для них не нужно устанавливать специфические для Vite плагины, но сам соответствующий препроцессор должен быть установлен:
```
::: code-group
```sh [npm]
# .scss и .sass
npm install -D sass
@ -210,7 +212,41 @@ npm install -D less
npm install -D stylus
```
Затем вы можете использовать следующее в Markdown и компонентах темы:
```sh [pnpm]
# .scss и .sass
pnpm add -D sass
# .less
pnpm add -D less
# .styl и .stylus
pnpm add -D stylus
```
```sh [yarn]
# .scss и .sass
yarn add -D sass
# .less
yarn add -D less
# .styl и .stylus
yarn add -D stylus
```
```sh [bun]
# .scss и .sass
bun add -D sass
# .less
bun add -D less
# .styl и .stylus
bun add -D stylus
```
:::
Затем вы можете использовать соответствующий атрибут `lang` в Markdown и компонентах темы:
```vue
<style lang="sass">
@ -284,4 +320,4 @@ Vue предоставляет поддержку IntelliSense из коробк
"vue.server.includeLanguages": ["vue", "markdown"]
}
```
:::
:::

@ -7,7 +7,7 @@ titleTemplate: Генератор статических сайтов на ос
hero:
name: VitePress
text: Генератор статических сайтов на основе Vite и Vue
tagline: Из Markdown в красивую документацию за считанные минуты
tagline: Преобразуйте Markdown в красивую документацию за минуты
actions:
- theme: brand
text: Что такое VitePress?
@ -19,7 +19,7 @@ hero:
text: GitHub
link: https://github.com/vuejs/vitepress
image:
src: /vitepress-logo-large.webp
src: /vitepress-logo-large.svg
alt: VitePress
features:

@ -178,36 +178,3 @@ export default {
}
}
```
## `useSidebar` <Badge type="info" text="композабл" /> {#usesidebar}
Возвращает данные, связанные с сайдбаром. Возвращаемый объект имеет следующий тип:
```ts
export interface DocSidebar {
isOpen: Ref<boolean>
sidebar: ComputedRef<DefaultTheme.SidebarItem[]>
sidebarGroups: ComputedRef<DefaultTheme.SidebarItem[]>
hasSidebar: ComputedRef<boolean>
hasAside: ComputedRef<boolean>
leftAside: ComputedRef<boolean>
isSidebarEnabled: ComputedRef<boolean>
open: () => void
close: () => void
toggle: () => void
}
```
**Пример:**
```vue
<script setup>
import { useSidebar } from 'vitepress/theme'
const { hasSidebar } = useSidebar()
</script>
<template>
<div v-if="hasSidebar">Показывать только при наличии сайдбара</div>
</template>
```

@ -51,12 +51,12 @@ const members = [
# Поприветствуйте нашу замечательную команду
<VPTeamMembers size="small" :members="members" />
<VPTeamMembers size="small" :members />
```
Вышеуказанное отобразит члена команды в виде карточки. Должно отобразиться что-то похожее на то, что показано ниже.
<VPTeamMembers size="small" :members="members" />
<VPTeamMembers size="small" :members />
Компонент `<VPTeamMembers>` поставляется в двух различных размерах, `small` и `medium`. Хотя это зависит от ваших предпочтений, обычно размер `small` лучше подходит для использования на странице с макетом `doc`. Кроме того, вы можете добавить дополнительные свойства для карточки члена команды, например, добавить «описание» или кнопку «спонсировать». Подробнее об этом в секции [`<VPTeamMembers>`](#vpteammembers).
@ -104,7 +104,7 @@ layout: page
которой представлены ниже.
</template>
</VPTeamPageTitle>
<VPTeamMembers :members="members" />
<VPTeamMembers :members />
</VPTeamPage>
```

@ -1,16 +1,30 @@
┌ Welcome to VitePress!
│
◇ Where should VitePress initialize the config?
│ ./docs
│
◇ Site title:
│ My Awesome Project
│
◇ Site description:
│ A VitePress Site
│
◆ Theme:
│ ● Default Theme (Out of the box, good-looking docs)
│ ○ Default Theme + Customization
│ ○ Custom Theme
└
┌ Welcome to VitePress!
│
◇ Where should VitePress initialize the config?
│ ./docs
│
◇ Where should VitePress look for your markdown files?
│ ./docs
│
◇ Site title:
│ My Awesome Project
│
◇ Site description:
│ A VitePress Site
│
◇ Theme:
│ Default Theme
│
◇ Use TypeScript for config and theme files?
│ Yes
│
◇ Add VitePress npm scripts to package.json?
│ Yes
│
◇ Add a prefix for VitePress npm scripts?
│ Yes
│
◇ Prefix for VitePress npm scripts:
│ docs
│
└ Done! Now run pnpm run docs:dev and start writing.

@ -111,7 +111,7 @@ Cache-Control: max-age=31536000,immutable
- **构建命令:** `npm run docs:build`
- **输出目录:** `docs/.vitepress/dist`
- **node 版本:** `18` (或更高版本)
- **node 版本:** `20` (或更高版本)
::: warning
不要为 HTML 代码启用 _Auto Minify_ 等选项。它将从输出中删除对 Vue 有意义的注释。如果被删除,你可能会看到激活不匹配错误。
@ -163,7 +163,7 @@ Cache-Control: max-age=31536000,immutable
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 20
node-version: 22
cache: npm # 或 pnpm / yarn
- name: Setup Pages
uses: actions/configure-pages@v4

@ -233,7 +233,7 @@ export default defineConfig({
```md
::: raw
Wraps in a <div class="vp-raw">
Wraps in a `<div class="vp-raw">`
:::
```

@ -19,7 +19,7 @@ hero:
text: GitHub
link: https://github.com/vuejs/vitepress
image:
src: /vitepress-logo-large.webp
src: /vitepress-logo-large.svg
alt: VitePress
features:

@ -178,36 +178,3 @@ export default {
}
}
```
## `useSidebar` <Badge type="info" text="composable" />
返回侧边栏相关数据。返回的对象具有以下类型:
```ts
export interface DocSidebar {
isOpen: Ref<boolean>
sidebar: ComputedRef<DefaultTheme.SidebarItem[]>
sidebarGroups: ComputedRef<DefaultTheme.SidebarItem[]>
hasSidebar: ComputedRef<boolean>
hasAside: ComputedRef<boolean>
leftAside: ComputedRef<boolean>
isSidebarEnabled: ComputedRef<boolean>
open: () => void
close: () => void
toggle: () => void
}
```
**示例:**
```vue
<script setup>
import { useSidebar } from 'vitepress/theme'
const { hasSidebar } = useSidebar()
</script>
<template>
<div v-if="hasSidebar">Only show when sidebar exists</div>
</template>
```

@ -53,12 +53,12 @@ const members = [
Say hello to our awesome team.
<VPTeamMembers size="small" :members="members" />
<VPTeamMembers size="small" :members />
```
以上将在卡片外观元素中显示团队成员。它应该显示类似于下面的内容。
<VPTeamMembers size="small" :members="members" />
<VPTeamMembers size="small" :members />
`<VPTeamMembers>` 组件有 2 种不同的尺寸,`small` 和 `medium`。虽然它取决于你的偏好,但通常尺寸在文档页面中使用时 `small` 应该更适合。此外,你可以为每个成员添加更多属性,例如添加“描述”或“赞助”按钮。在 [`<VPTeamMembers>`](#vpteammembers) 中了解更多信息。
@ -107,9 +107,7 @@ const members = [
team, some of whom have chosen to be featured below.
</template>
</VPTeamPageTitle>
<VPTeamMembers
:members="members"
/>
<VPTeamMembers :members />
</VPTeamPage>
```

@ -1,5 +1,5 @@
[build.environment]
NODE_VERSION = "20"
NODE_VERSION = "22"
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD = "1"
[build]

@ -1,6 +1,6 @@
{
"name": "vitepress",
"version": "2.0.0-alpha.2",
"version": "2.0.0-alpha.4",
"description": "Vite & Vue powered static site generator",
"keywords": [
"vite",
@ -95,27 +95,27 @@
"*": "prettier --write --ignore-unknown"
},
"dependencies": {
"@docsearch/css": "^3.8.3",
"@docsearch/js": "^3.8.3",
"@iconify-json/simple-icons": "^1.2.21",
"@shikijs/core": "^2.1.0",
"@shikijs/transformers": "^2.1.0",
"@shikijs/types": "^2.1.0",
"@vitejs/plugin-vue": "^5.2.1",
"@vue/devtools-api": "^7.7.0",
"@docsearch/css": "^3.9.0",
"@docsearch/js": "^3.9.0",
"@iconify-json/simple-icons": "^1.2.30",
"@shikijs/core": "^3.2.1",
"@shikijs/transformers": "^3.2.1",
"@shikijs/types": "^3.2.1",
"@vitejs/plugin-vue": "^5.2.3",
"@vue/devtools-api": "^7.7.2",
"@vue/shared": "^3.5.13",
"@vueuse/core": "^12.5.0",
"@vueuse/integrations": "^12.5.0",
"@vueuse/core": "^13.0.0",
"@vueuse/integrations": "^13.0.0",
"focus-trap": "^7.6.4",
"mark.js": "8.11.1",
"minisearch": "^7.1.1",
"shiki": "^2.1.0",
"vite": "^6.0.11",
"minisearch": "^7.1.2",
"shiki": "^3.2.1",
"vite": "^6.2.5",
"vue": "^3.5.13"
},
"devDependencies": {
"@clack/prompts": "^0.9.1",
"@iconify/utils": "^2.2.1",
"@clack/prompts": "^0.10.0",
"@iconify/utils": "^2.3.0",
"@mdit-vue/plugin-component": "^2.1.3",
"@mdit-vue/plugin-frontmatter": "^2.1.3",
"@mdit-vue/plugin-headers": "^2.1.3",
@ -125,9 +125,9 @@
"@mdit-vue/shared": "^2.1.3",
"@polka/compression": "^1.0.0-next.28",
"@rollup/plugin-alias": "^5.1.1",
"@rollup/plugin-commonjs": "^28.0.2",
"@rollup/plugin-commonjs": "^28.0.3",
"@rollup/plugin-json": "^6.1.0",
"@rollup/plugin-node-resolve": "^16.0.0",
"@rollup/plugin-node-resolve": "^16.0.1",
"@rollup/plugin-replace": "^6.0.2",
"@types/cross-spawn": "^6.0.6",
"@types/debug": "^4.1.12",
@ -139,56 +139,56 @@
"@types/markdown-it-container": "^2.0.10",
"@types/markdown-it-emoji": "^3.0.1",
"@types/minimist": "^1.2.5",
"@types/node": "^22.10.9",
"@types/picomatch": "^3.0.2",
"@types/node": "^22.14.0",
"@types/picomatch": "^4.0.0",
"@types/postcss-prefix-selector": "^1.16.3",
"@types/prompts": "^2.4.9",
"chokidar": "^4.0.3",
"conventional-changelog-cli": "^5.0.0",
"cross-spawn": "^7.0.6",
"debug": "^4.4.0",
"esbuild": "^0.24.2",
"esbuild": "^0.25.2",
"execa": "^9.5.2",
"fs-extra": "^11.3.0",
"get-port": "^7.1.0",
"gray-matter": "^4.0.3",
"lint-staged": "^15.4.2",
"lint-staged": "^15.5.0",
"lodash.template": "^4.5.0",
"lru-cache": "^11.0.2",
"lru-cache": "^11.1.0",
"markdown-it": "^14.1.0",
"markdown-it-anchor": "^9.2.0",
"markdown-it-async": "^2.0.0",
"markdown-it-async": "^2.2.0",
"markdown-it-attrs": "^4.3.1",
"markdown-it-container": "^4.0.0",
"markdown-it-emoji": "^3.0.0",
"markdown-it-mathjax3": "^4.3.2",
"minimist": "^1.2.8",
"nanoid": "^5.0.9",
"ora": "^8.1.1",
"nanoid": "^5.1.5",
"ora": "^8.2.0",
"p-map": "^7.0.3",
"path-to-regexp": "^6.3.0",
"picocolors": "^1.1.1",
"picomatch": "^4.0.2",
"pkg-dir": "^8.0.0",
"playwright-chromium": "^1.50.0",
"playwright-chromium": "^1.51.1",
"polka": "^1.0.0-next.28",
"postcss-prefix-selector": "^2.1.0",
"prettier": "^3.4.2",
"postcss-prefix-selector": "^2.1.1",
"prettier": "^3.5.3",
"prompts": "^2.4.2",
"punycode": "^2.3.1",
"rimraf": "^6.0.1",
"rollup": "^4.31.0",
"rollup-plugin-dts": "^6.1.1",
"rollup-plugin-esbuild": "^6.1.1",
"semver": "^7.6.3",
"simple-git-hooks": "^2.11.1",
"sirv": "^3.0.0",
"rollup": "^4.39.0",
"rollup-plugin-dts": "6.1.1",
"rollup-plugin-esbuild": "^6.2.1",
"semver": "^7.7.1",
"simple-git-hooks": "^2.12.1",
"sirv": "^3.0.1",
"sitemap": "^8.0.0",
"tinyglobby": "^0.2.10",
"typescript": "^5.7.3",
"vitest": "^3.0.4",
"vue-tsc": "^2.2.0",
"wait-on": "^8.0.2"
"tinyglobby": "^0.2.12",
"typescript": "^5.8.3",
"vitest": "^3.1.1",
"vue-tsc": "^2.2.8",
"wait-on": "^8.0.3"
},
"peerDependencies": {
"markdown-it-mathjax3": "^4",
@ -217,6 +217,11 @@
"patchedDependencies": {
"@types/mdurl@2.0.0": "patches/@types__mdurl@2.0.0.patch",
"markdown-it-anchor@9.2.0": "patches/markdown-it-anchor@9.2.0.patch"
}
},
"onlyBuiltDependencies": [
"esbuild",
"playwright-chromium",
"simple-git-hooks"
]
}
}

File diff suppressed because it is too large Load Diff

@ -62,7 +62,7 @@ export const siteDataRef: Ref<SiteData> = shallowRef(
// hmr
if (import.meta.hot) {
import.meta.hot.accept('/@siteData', (m) => {
import.meta.hot.accept('@siteData', (m) => {
if (m) {
siteDataRef.value = m.default
}

@ -325,12 +325,12 @@ async function changeRoute(
{ smoothScroll = false, initialLoad = false } = {}
): Promise<boolean> {
const loc = normalizeHref(location.href)
const { pathname, hash } = new URL(href, fakeHost)
const currentLoc = new URL(loc, fakeHost)
const nextUrl = new URL(href, location.origin)
const currentUrl = new URL(loc, location.origin)
if (href === loc) {
if (!initialLoad) {
scrollTo(hash, smoothScroll)
scrollTo(nextUrl.hash, smoothScroll)
return false
}
} else {
@ -338,16 +338,16 @@ async function changeRoute(
history.replaceState({ scrollPosition: window.scrollY }, '')
history.pushState({}, '', href)
if (pathname === currentLoc.pathname) {
if (nextUrl.pathname === currentUrl.pathname) {
// scroll between hash anchors on the same page, avoid duplicate entries
if (hash !== currentLoc.hash) {
if (nextUrl.hash !== currentUrl.hash) {
window.dispatchEvent(
new HashChangeEvent('hashchange', {
oldURL: currentLoc.href,
newURL: href
oldURL: currentUrl.href,
newURL: nextUrl.href
})
)
scrollTo(hash, smoothScroll)
scrollTo(nextUrl.hash, smoothScroll)
}
return false

@ -1,10 +1,5 @@
import {
h,
onMounted,
onUnmounted,
shallowRef,
type AsyncComponentLoader
} from 'vue'
import { tryOnUnmounted } from '@vueuse/core'
import { h, onMounted, shallowRef, type AsyncComponentLoader } from 'vue'
import {
EXTERNAL_URL_RE,
inBrowser,
@ -81,7 +76,7 @@ export let contentUpdatedCallbacks: (() => any)[] = []
*/
export function onContentUpdated(fn: () => any) {
contentUpdatedCallbacks.push(fn)
onUnmounted(() => {
tryOnUnmounted(() => {
contentUpdatedCallbacks = contentUpdatedCallbacks.filter((f) => f !== fn)
})
}

@ -1,6 +1,5 @@
<script setup lang="ts">
import { useRoute } from 'vitepress'
import { computed, provide, useSlots, watch } from 'vue'
import { computed, provide, useSlots } from 'vue'
import VPBackdrop from './components/VPBackdrop.vue'
import VPContent from './components/VPContent.vue'
import VPFooter from './components/VPFooter.vue'
@ -9,18 +8,16 @@ import VPNav from './components/VPNav.vue'
import VPSidebar from './components/VPSidebar.vue'
import VPSkipLink from './components/VPSkipLink.vue'
import { useData } from './composables/data'
import { useCloseSidebarOnEscape, useSidebar } from './composables/sidebar'
import { registerWatchers } from './composables/layout'
import { useSidebarControl } from './composables/sidebar'
const {
isOpen: isSidebarOpen,
open: openSidebar,
close: closeSidebar
} = useSidebar()
} = useSidebarControl()
const route = useRoute()
watch(() => route.path, closeSidebar)
useCloseSidebarOnEscape(isSidebarOpen, closeSidebar)
registerWatchers({ closeSidebar })
const { frontmatter } = useData()
@ -31,7 +28,11 @@ provide('hero-image-slot-exists', heroImageSlotExists)
</script>
<template>
<div v-if="frontmatter.layout !== false" class="Layout" :class="frontmatter.pageClass" >
<div
v-if="frontmatter.layout !== false"
class="Layout"
:class="frontmatter.pageClass"
>
<slot name="layout-top" />
<VPSkipLink />
<VPBackdrop class="backdrop" :show="isSidebarOpen" @click="closeSidebar" />

@ -22,7 +22,7 @@ const { currentLang } = useLangs()
<div class="action">
<a
class="link"
:href="withBase(currentLang.link)"
:href="withBase(theme.notFound?.link ?? currentLang.link)"
:aria-label="theme.notFound?.linkLabel ?? 'go to home'"
>
{{ theme.notFound?.linkText ?? 'Take me home' }}

@ -1,23 +1,20 @@
<script setup lang="ts">
import NotFound from '../NotFound.vue'
import { useData } from '../composables/data'
import { useSidebar } from '../composables/sidebar'
import { useLayout } from '../composables/layout'
import VPDoc from './VPDoc.vue'
import VPHome from './VPHome.vue'
import VPPage from './VPPage.vue'
const { page, frontmatter } = useData()
const { hasSidebar } = useSidebar()
const { isHome, hasSidebar } = useLayout()
</script>
<template>
<div
class="VPContent"
id="VPContent"
:class="{
'has-sidebar': hasSidebar,
'is-home': frontmatter.layout === 'home'
}"
:class="{ 'has-sidebar': hasSidebar, 'is-home': isHome }"
>
<slot name="not-found" v-if="page.isNotFound"><NotFound /></slot>

@ -2,14 +2,14 @@
import { useRoute } from 'vitepress'
import { computed } from 'vue'
import { useData } from '../composables/data'
import { useSidebar } from '../composables/sidebar'
import { useLayout } from '../composables/layout'
import VPDocAside from './VPDocAside.vue'
import VPDocFooter from './VPDocFooter.vue'
const { theme } = useData()
const route = useRoute()
const { hasSidebar, hasAside, leftAside } = useSidebar()
const { hasSidebar, hasAside, leftAside } = useLayout()
const pageName = computed(() =>
route.path.replace(/[./]+/g, '_').replace(/_html$/, '')
@ -154,6 +154,7 @@ const pageName = computed(() =>
width: 224px;
height: 32px;
background: linear-gradient(transparent, var(--vp-c-bg) 70%);
pointer-events: none;
}
.aside-content {

@ -1,26 +1,17 @@
<script setup lang="ts">
import { onContentUpdated } from 'vitepress'
import { ref, shallowRef } from 'vue'
import { ref } from 'vue'
import { useData } from '../composables/data'
import {
getHeaders,
resolveTitle,
useActiveAnchor,
type MenuItem
} from '../composables/outline'
import { resolveTitle, useActiveAnchor } from '../composables/outline'
import VPDocOutlineItem from './VPDocOutlineItem.vue'
import { useLayout } from '../composables/layout'
const { frontmatter, theme } = useData()
const headers = shallowRef<MenuItem[]>([])
onContentUpdated(() => {
headers.value = getHeaders(frontmatter.value.outline ?? theme.value.outline)
})
const { theme } = useData()
const container = ref()
const marker = ref()
const { headers, hasLocalNav } = useLayout()
useActiveAnchor(container, marker)
function scrollToTop() {
@ -33,7 +24,7 @@ function scrollToTop() {
<nav
aria-labelledby="doc-outline-aria-label"
class="VPDocAsideOutline"
:class="{ 'has-outline': headers.length > 0 }"
:class="{ 'has-outline': hasLocalNav }"
ref="container"
>
<div class="content">
@ -48,7 +39,7 @@ function scrollToTop() {
{{ resolveTitle(theme) }}
</div>
<VPDocOutlineItem :headers="headers" :root="true" />
<VPDocOutlineItem :headers :root="true" />
<button @click="scrollToTop" class="back-to-top-button">
<span>{{ theme.returnToTopLabel || 'Return to top' }}</span>

@ -12,6 +12,6 @@ defineProps<{
<template>
<div class="VPDocAsideSponsors">
<VPSponsors mode="aside" :tier="tier" :size="size" :data="data" />
<VPSponsors mode="aside" :tier :size :data />
</div>
</template>

@ -1,8 +1,8 @@
<script setup lang="ts">
import type { MenuItem } from '../composables/outline'
import type { DefaultTheme } from 'vitepress/theme'
defineProps<{
headers: MenuItem[]
headers: DefaultTheme.OutlineItem[]
root?: boolean
}>()
@ -16,7 +16,9 @@ function onClick({ target: el }: Event) {
<template>
<ul class="VPDocOutlineItem" :class="root ? 'root' : 'nested'">
<li v-for="{ children, link, title } in headers">
<a class="outline-link" :href="link" @click="onClick" :title="title">{{ title }}</a>
<a class="outline-link" :href="link" @click="onClick" :title>
{{ title }}
</a>
<template v-if="children?.length">
<VPDocOutlineItem :headers="children" />
</template>

@ -18,8 +18,8 @@ defineProps<{
<VPLink
class="VPFeature"
:href="link"
:rel="rel"
:target="target"
:rel
:target
:no-icon="true"
:tag="link ? 'a' : 'div'"
>

@ -45,7 +45,7 @@ function onBlur() {
</button>
<div class="menu">
<VPMenu :items="items">
<VPMenu :items>
<slot />
</VPMenu>
</div>

@ -1,9 +1,9 @@
<script setup lang="ts">
import { useData } from '../composables/data'
import { useSidebar } from '../composables/sidebar'
import { useLayout } from '../composables/layout'
const { theme, frontmatter } = useData()
const { hasSidebar } = useSidebar()
const { hasSidebar } = useLayout()
</script>
<template>

@ -57,7 +57,7 @@ const heroImageSlotExists = inject('hero-image-slot-exists') as Ref<boolean>
<div class="image-container">
<div class="image-bg" />
<slot name="home-hero-image">
<VPImage v-if="image" class="image-src" :image="image" />
<VPImage v-if="image" class="image-src" :image />
</slot>
</div>
</div>
@ -322,6 +322,9 @@ const heroImageSlotExists = inject('hero-image-slot-exists') as Ref<boolean>
left: 50%;
max-width: 192px;
max-height: 192px;
width: 100%;
height: 100%;
object-fit: contain;
/*rtl:ignore*/
transform: translate(-50%, -50%);
}

@ -36,7 +36,7 @@ withDefaults(defineProps<Props>(), {
</div>
<div class="sponsors">
<VPSponsors :data="data" />
<VPSponsors :data />
</div>
<div v-if="actionLink" class="action">

@ -1,11 +1,8 @@
<script lang="ts" setup>
import { useWindowScroll } from '@vueuse/core'
import { onContentUpdated } from 'vitepress'
import { computed, onMounted, ref } from 'vue'
import { useData } from '../composables/data'
import { useLocalNav } from '../composables/local-nav'
import { getHeaders } from '../composables/outline'
import { useSidebar } from '../composables/sidebar'
import { useLayout } from '../composables/layout'
import VPLocalNavOutlineDropdown from './VPLocalNavOutlineDropdown.vue'
defineProps<{
@ -16,9 +13,8 @@ defineEmits<{
(e: 'open-menu'): void
}>()
const { theme, frontmatter } = useData()
const { hasSidebar } = useSidebar()
const { headers } = useLocalNav()
const { theme } = useData()
const { isHome, hasSidebar, headers, hasLocalNav } = useLayout()
const { y } = useWindowScroll()
const navHeight = ref(0)
@ -31,31 +27,19 @@ onMounted(() => {
)
})
onContentUpdated(() => {
headers.value = getHeaders(frontmatter.value.outline ?? theme.value.outline)
})
const empty = computed(() => {
return headers.value.length === 0
})
const emptyAndNoSidebar = computed(() => {
return empty.value && !hasSidebar.value
})
const classes = computed(() => {
return {
VPLocalNav: true,
'has-sidebar': hasSidebar.value,
empty: empty.value,
fixed: emptyAndNoSidebar.value
empty: !hasLocalNav.value,
fixed: !hasLocalNav.value && !hasSidebar.value,
}
})
</script>
<template>
<div
v-if="frontmatter.layout !== 'home' && (!emptyAndNoSidebar || y >= navHeight)"
v-if="!isHome && (hasLocalNav || hasSidebar || y >= navHeight)"
:class="classes"
>
<div class="container">
@ -72,7 +56,7 @@ const classes = computed(() => {
</span>
</button>
<VPLocalNavOutlineDropdown :headers="headers" :navHeight="navHeight" />
<VPLocalNavOutlineDropdown :headers :navHeight />
</div>
</div>
</template>

@ -1,13 +1,14 @@
<script setup lang="ts">
import { onKeyStroke } from '@vueuse/core'
import { onContentUpdated } from 'vitepress'
import type { DefaultTheme } from 'vitepress/theme'
import { nextTick, ref, watch } from 'vue'
import { useData } from '../composables/data'
import { resolveTitle, type MenuItem } from '../composables/outline'
import { resolveTitle } from '../composables/outline'
import VPDocOutlineItem from './VPDocOutlineItem.vue'
const props = defineProps<{
headers: MenuItem[]
headers: DefaultTheme.OutlineItem[]
navHeight: number
}>()
@ -83,7 +84,7 @@ function scrollToTop() {
</a>
</div>
<div class="outline">
<VPDocOutlineItem :headers="headers" />
<VPDocOutlineItem :headers />
</div>
</div>
</Transition>
@ -125,7 +126,7 @@ function scrollToTop() {
vertical-align: middle;
margin-left: 2px;
font-size: 14px;
transform: rotate(0)/*rtl:rotate(180deg)*/;
transform: rotate(0) /*rtl:rotate(180deg)*/;
transition: transform 0.25s;
}

@ -46,7 +46,7 @@ const searchIndexData = shallowRef(localSearchIndex)
// hmr
if (import.meta.hot) {
import.meta.hot.accept('/@localSearchIndex', (m) => {
import.meta.hot.accept('@localSearchIndex', (m) => {
if (m) {
searchIndexData.value = m.default
}

@ -11,7 +11,7 @@ defineProps<{
<div class="VPMenu">
<div v-if="items" class="items">
<template v-for="item in items" :key="JSON.stringify(item)">
<VPMenuLink v-if="'link' in item" :item="item" />
<VPMenuLink v-if="'link' in item" :item />
<component
v-else-if="'component' in item"
:is="item.component"

@ -12,7 +12,7 @@ defineProps<{
<p v-if="text" class="title">{{ text }}</p>
<template v-for="item in items">
<VPMenuLink v-if="'link' in item" :item="item" />
<VPMenuLink v-if="'link' in item" :item />
</template>
</div>
</template>

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save