Merge branch 'main' into feat/footer-with-sidebar

pull/4532/head
Leo 7 months ago committed by GitHub
commit b990fe37d5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -9,6 +9,7 @@ on:
types: [opened, synchronize, labeled, ready_for_review]
paths-ignore:
- '.github/**'
- '!.github/workflows/cr.yml'
- '__tests__/**'
- 'art/**'
- 'docs/**'
@ -17,6 +18,7 @@ on:
branches: [main]
paths-ignore:
- '.github/**'
- '!.github/workflows/cr.yml'
- '__tests__/**'
- 'art/**'
- 'docs/**'

@ -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,31 @@
## [2.0.0-alpha.5](https://github.com/vuejs/vitepress/compare/v2.0.0-alpha.4...v2.0.0-alpha.5) (2025-04-21)
### Bug Fixes
- don't remove shiki styles from `pre` and remove unnecessary transformers (#4652) ([db58af5](https://github.com/vuejs/vitepress/commit/db58af5c66e563e7663084057a9853d8f2da984c)), closes [#4652](https://github.com/vuejs/vitepress/issues/4652)
- normalize url fragments in internal links to correctly resolve to anchors ([#4628](https://github.com/vuejs/vitepress/issues/4628)) ([e25d080](https://github.com/vuejs/vitepress/commit/e25d0805505db2f1116e99d38a488d5cb39ed426)), closes [#4605](https://github.com/vuejs/vitepress/issues/4605)
- **theme-default:** ensure proper sizing of SVG hero images ([#4639](https://github.com/vuejs/vitepress/issues/4639)) ([7d94481](https://github.com/vuejs/vitepress/commit/7d9448192079e59493aa5c1e86cdf6d6deae8e36))
### Features
- add `isHome` frontmatter option (#4673) ([544cd81](https://github.com/vuejs/vitepress/commit/544cd8125985b9e3af7fee68ea9592d159799e01)), closes [#4673](https://github.com/vuejs/vitepress/issues/4673)
- add `custom-block-title-default` class when default title is used for containers ([#4643](https://github.com/vuejs/vitepress/issues/4643)) ([63079bf](https://github.com/vuejs/vitepress/commit/63079bff03b15861d174199f7361a2aff84380e0))
- add `dir=ltr` by default on code block pre elements instead of relying on css ([19faa16](https://github.com/vuejs/vitepress/commit/19faa16169b44f52bedf1401b4a97b2a8ffdeacb))
- **default-theme:** make VPButton slottable ([#4689](https://github.com/vuejs/vitepress/issues/4689)) ([0b70397](https://github.com/vuejs/vitepress/commit/0b7039719782e85119ad22be5c89ef3d233ffaae))
- support distributed config files ([#4660](https://github.com/vuejs/vitepress/issues/4660)) ([c5e2e4d](https://github.com/vuejs/vitepress/commit/c5e2e4db818c06f3c1b458753f22fb6ec1609628))
- **theme:** make "Take me home" button's link customizable ([#4658](https://github.com/vuejs/vitepress/issues/4658)) ([0267dca](https://github.com/vuejs/vitepress/commit/0267dcafa20beea24ef359d24bb1fa99e1ffda49))
### Performance Improvements
- call `module.enableCompileCache()` ([70de34c](https://github.com/vuejs/vitepress/commit/70de34c0387d9668ada3ea9a795f9ebee3535f5b))
- hoist expensive operations in useLayout ([e5ab067](https://github.com/vuejs/vitepress/commit/e5ab0676a9a8dc607e213eb691439b2e4ee472b7))
### BREAKING CHANGES
- `useLocalNav` and `useSidebar` are removed in favor of `useLayout`. To migrate, just do find and replace. Sidebar controls are no longer exported, but we didn't find any usage on GitHub. If there is demand, we can export respective composables later. `DefaultTheme.DocSidebar` and `DefaultTheme.DocLocalNav` types are also removed.
- `vp-adaptive-theme` class is no longer added to code blocks when there is single theme. Theme authors supporting single code theme can use `.shiki:not(.shiki-themes)` as selector. Alternatively, it might be better to use the bg/fg variables set on the `.shiki` block to keep things generic.
- `vp-code` class is no longer added to code blocks. Use `.shiki` or `pre.shiki` or `[class*='language-'] pre` instead. People not customizing their themes are not affected.
## [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

@ -1,6 +1,6 @@
# VitePress 📝💨
[![test](https://github.com/vuejs/vitepress/workflows/Test/badge.svg)](https://github.com/vuejs/vitepress/actions)
[![test](https://github.com/vuejs/vitepress/actions/workflows/test.yml/badge.svg?branch=main)](https://github.com/vuejs/vitepress/actions/workflows/test.yml)
[![npm](https://img.shields.io/npm/v/vitepress)](https://www.npmjs.com/package/vitepress)
[![nightly releases](https://img.shields.io/badge/nightly-releases-orange)](https://nightly.akryum.dev/vuejs/vitepress)
[![chat](https://img.shields.io/badge/chat-discord-blue?logo=discord)](https://chat.vuejs.org)

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

@ -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,2 +1,16 @@
#!/usr/bin/env node
// @ts-check
import module from 'node:module'
// https://github.com/vitejs/vite/blob/6c8a5a27e645a182f5b03a4ed6aa726eab85993f/packages/vite/bin/vite.js#L48-L63
try {
module.enableCompileCache?.()
setTimeout(() => {
try {
module.flushCompileCache?.()
} catch {}
}, 10 * 1000).unref()
} catch {}
import('../dist/node/cli.js')

@ -1,17 +1,18 @@
import { defineConfig } from 'vitepress'
import {
defineConfig,
resolveSiteDataByRoute,
type HeadConfig
} from 'vitepress'
import {
groupIconMdPlugin,
groupIconVitePlugin,
localIconLoader
} from 'vitepress-plugin-group-icons'
import { search as esSearch } from './es'
import { search as faSearch } from './fa'
import { search as koSearch } from './ko'
import { search as ptSearch } from './pt'
import { search as ruSearch } from './ru'
import { search as zhSearch } from './zh'
import llmstxt from 'vitepress-plugin-llms'
const prod = !!process.env.NETLIFY
export const shared = defineConfig({
export default defineConfig({
title: 'VitePress',
rewrites: {
@ -77,8 +78,6 @@ export const shared = defineConfig({
['link', { rel: 'icon', type: 'image/png', href: '/vitepress-logo-mini.png' }],
['meta', { name: 'theme-color', content: '#5f67ee' }],
['meta', { property: 'og:type', content: 'website' }],
['meta', { property: 'og:locale', content: 'en' }],
['meta', { property: 'og:title', content: 'VitePress | Vite & Vue Powered Static Site Generator' }],
['meta', { property: 'og:site_name', content: 'VitePress' }],
['meta', { property: 'og:image', content: 'https://vitepress.dev/vitepress-og.jpg' }],
['meta', { property: 'og:url', content: 'https://vitepress.dev/' }],
@ -97,31 +96,53 @@ export const shared = defineConfig({
options: {
appId: '8J64VVRP8K',
apiKey: '52f578a92b88ad6abde815aae2b0ad7c',
indexName: 'vitepress',
locales: {
...zhSearch,
...ptSearch,
...ruSearch,
...esSearch,
...koSearch,
...faSearch
}
indexName: 'vitepress'
}
},
carbonAds: { code: 'CEBDT27Y', placement: 'vuejsorg' }
},
locales: {
root: { label: 'English' },
zh: { label: '简体中文' },
pt: { label: 'Português' },
ru: { label: 'Русский' },
es: { label: 'Español' },
ko: { label: '한국어' },
fa: { label: 'فارسی' }
},
vite: {
plugins: [
groupIconVitePlugin({
customIcon: {
vitepress: localIconLoader(
import.meta.url,
'../../public/vitepress-logo-mini.svg'
'../public/vitepress-logo-mini.svg'
),
firebase: 'logos:firebase'
}
})
}),
prod &&
llmstxt({
workDir: 'en',
ignoreFiles: ['index.md']
})
]
}
},
transformPageData: prod
? (pageData, ctx) => {
const site = resolveSiteDataByRoute(
ctx.siteConfig.site,
pageData.relativePath
)
const title = `${pageData.title || site.title} | ${pageData.description || site.description}`
;((pageData.frontmatter.head ??= []) as HeadConfig[]).push(
['meta', { property: 'og:locale', content: site.lang }],
['meta', { property: 'og:title', content: title }]
)
}
: undefined
})

@ -1,22 +0,0 @@
import { defineConfig } from 'vitepress'
import { shared } from './shared'
import { en } from './en'
import { zh } from './zh'
import { pt } from './pt'
import { ru } from './ru'
import { es } from './es'
import { ko } from './ko'
import { fa } from './fa'
export default defineConfig({
...shared,
locales: {
root: { label: 'English', ...en },
zh: { label: '简体中文', ...zh },
pt: { label: 'Português', ...pt },
ru: { label: 'Русский', ...ru },
es: { label: 'Español', ...es },
ko: { label: '한국어', ...ko },
fa: { label: 'فارسی', ...fa }
}
})

@ -1,5 +1,3 @@
@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,
@ -33,6 +31,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%;

@ -1,10 +1,10 @@
import { createRequire } from 'module'
import { defineConfig, type DefaultTheme } from 'vitepress'
import { defineAdditionalConfig, type DefaultTheme } from 'vitepress'
const require = createRequire(import.meta.url)
const pkg = require('vitepress/package.json')
export const en = defineConfig({
export default defineAdditionalConfig({
lang: 'en-US',
description: 'Vite & Vue powered static site generator.',

@ -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

@ -70,7 +70,7 @@ If your font is a local file referenced via `@font-face`, it will be processed a
export default {
transformHead({ assets }) {
// adjust the regex accordingly to match your font
const myFontFile = assets.find(file => /font-name\.\w+\.woff2/)
const myFontFile = assets.find(file => /font-name\.[\w-]+\.woff2/.test(file))
if (myFontFile) {
return [
[

@ -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

@ -1,9 +1,6 @@
---
layout: home
title: VitePress
titleTemplate: Vite & Vue Powered Static Site Generator
hero:
name: VitePress
text: Vite & Vue Powered Static Site Generator
@ -19,7 +16,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: Readonly<ShallowRef<DefaultTheme.SidebarItem[]>>
sidebarGroups: ComputedRef<DefaultTheme.SidebarItem[]>
hasSidebar: ComputedRef<boolean>
isSidebarEnabled: ComputedRef<boolean>
hasAside: ComputedRef<boolean>
leftAside: ComputedRef<boolean>
headers: Readonly<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
---
```

@ -1,16 +1,18 @@
import { createRequire } from 'module'
import { defineConfig, type DefaultTheme } from 'vitepress'
import { defineAdditionalConfig, type DefaultTheme } from 'vitepress'
const require = createRequire(import.meta.url)
const pkg = require('vitepress/package.json')
export const es = defineConfig({
export default defineAdditionalConfig({
lang: 'es-CO',
description: 'Generador de Sitios Estaticos desarrollado con Vite y Vue.',
themeConfig: {
nav: nav(),
search: { options: searchOptions() },
sidebar: {
'/es/guide/': { base: '/es/guide/', items: sidebarGuide() },
'/es/reference/': { base: '/es/reference/', items: sidebarReference() }
@ -36,11 +38,15 @@ export const es = defineConfig({
},
lastUpdated: {
text: 'Actualizado en',
formatOptions: {
dateStyle: 'short',
timeStyle: 'medium'
}
text: 'Actualizado en'
},
notFound: {
title: 'PÁGINA NO ENCONTRADA',
quote:
'Pero si no cambias de dirección y sigues buscando, podrías terminar donde te diriges.',
linkLabel: 'ir a inicio',
linkText: 'Llévame a casa'
},
langMenuLabel: 'Cambiar Idioma',
@ -170,8 +176,8 @@ function sidebarReference(): DefaultTheme.SidebarItem[] {
]
}
export const search: DefaultTheme.AlgoliaSearchOptions['locales'] = {
es: {
function searchOptions(): Partial<DefaultTheme.AlgoliaSearchOptions> {
return {
placeholder: 'Buscar documentos',
translations: {
button: {

@ -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

@ -70,7 +70,7 @@ Si su fuente es un archivo local referenciado via `@font-face`, ella será proce
export default {
transformHead({ assets }) {
// ajuste el regex para corresponder a su fuente
const myFontFile = assets.find(file => /font-name\.\w+\.woff2/)
const myFontFile = assets.find(file => /font-name\.[\w-]+\.woff2/.test(file))
if (myFontFile) {
return [
[

@ -1,9 +1,6 @@
---
layout: home
title: VitePress
titleTemplate: Generador de Sitios Estáticos desarrollado con Vite y Vue
hero:
name: VitePress
text: Generador de Sitios Estáticos Vite y Vue
@ -19,7 +16,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,36 +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>
```

@ -1,25 +1,26 @@
import { createRequire } from 'module'
import { defineConfig, type DefaultTheme } from 'vitepress'
import { defineAdditionalConfig, type DefaultTheme } from 'vitepress'
const require = createRequire(import.meta.url)
const pkg = require('vitepress/package.json')
export const fa = defineConfig({
title: 'ویت‌پرس',
export default defineAdditionalConfig({
lang: 'fa-IR',
description: 'Vite & Vue powered static site generator.',
description: 'ژنراتور استاتیک وب‌سایت با Vite و Vue',
dir: 'rtl',
markdown: {
container: {
tipLabel: 'نکته',
warningLabel: 'هشدار',
dangerLabel: 'خطر',
infoLabel: 'اطلاعات',
detailsLabel: 'جزئیات'
}
},
// prettier-ignore
head: [
['link', { rel: 'preconnect', href: 'https://fonts.googleapis.com' }],
['link', { rel: 'preconnect', href: 'https://fonts.gstatic.com', crossorigin: '' }],
['link', { href: 'https://fonts.googleapis.com/css2?family=Vazirmatn:wght@100..900&display=swap', rel: 'stylesheet' }],
],
themeConfig: {
nav: nav(),
search: { options: searchOptions() },
sidebar: {
'/fa/guide/': { base: '/fa/guide/', items: sidebarGuide() },
'/fa/reference/': { base: '/fa/reference/', items: sidebarReference() }
@ -45,11 +46,15 @@ export const fa = defineConfig({
},
lastUpdated: {
text: 'آخرین به‌روزرسانی‌',
formatOptions: {
dateStyle: 'short',
timeStyle: 'medium'
}
text: 'آخرین به‌روزرسانی‌'
},
notFound: {
title: 'صفحه پیدا نشد',
quote:
'اما اگر جهت خود را تغییر ندهید و همچنان به جستجو ادامه دهید، ممکن است در نهایت به جایی برسید که در حال رفتن به آن هستید.',
linkLabel: 'برو به خانه',
linkText: 'من را به خانه ببر'
},
langMenuLabel: 'تغییر زبان',
@ -58,14 +63,6 @@ export const fa = defineConfig({
darkModeSwitchLabel: 'تم تاریک',
lightModeSwitchTitle: 'رفتن به حالت روشن',
darkModeSwitchTitle: 'رفتن به حالت تاریک',
notFound: {
linkLabel: 'بازگشت به خانه',
linkText: 'بازگشت به خانه',
title: 'صفحه مورد نظر یافت نشد',
code: '۴۰۴',
quote:
'اما اگر جهت خود را تغییر ندهید و اگر ادامه دهید به دنبال چیزی که دنبال می‌کنید، ممکن است در نهایت به جایی که در حال رفتن به سمتش هستید، برسید.'
},
siteTitle: 'ویت‌پرس'
}
})
@ -181,8 +178,8 @@ function sidebarReference(): DefaultTheme.SidebarItem[] {
]
}
export const search: DefaultTheme.AlgoliaSearchOptions['locales'] = {
fa: {
function searchOptions(): Partial<DefaultTheme.AlgoliaSearchOptions> {
return {
placeholder: 'جستجوی مستندات',
translations: {
button: {

@ -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

@ -70,7 +70,7 @@ export default DefaultTheme
export default {
transformHead({ assets }) {
// منظور شده برای همسان سازی font خود، regex مورد نیاز را تنظیم کنید
const myFontFile = assets.find(file => /font-name\.\w+\.woff2/)
const myFontFile = assets.find(file => /font-name\.[\w-]+\.woff2/.test(file))
if (myFontFile) {
return [
[

@ -1,9 +1,6 @@
---
layout: home
title: ویت‌پرس
titleTemplate: Vite & Vue Powered Static Site Generator
hero:
name: ویت‌پرس
text: سازنده سایت‌های ایستا به کمک Vite و Vue
@ -19,7 +16,7 @@ hero:
text: گیت‌هاب
link: https://github.com/vuejs/vitepress
image:
src: /vitepress-logo-large.webp
src: /vitepress-logo-large.svg
alt: ویت‌پرس
features:

@ -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>
```

@ -1,16 +1,18 @@
import { createRequire } from 'module'
import { defineConfig, type DefaultTheme } from 'vitepress'
import { defineAdditionalConfig, type DefaultTheme } from 'vitepress'
const require = createRequire(import.meta.url)
const pkg = require('vitepress/package.json')
export const ko = defineConfig({
export default defineAdditionalConfig({
lang: 'ko-KR',
description: 'Vite 및 Vue 기반 정적 사이트 생성기.',
themeConfig: {
nav: nav(),
search: { options: searchOptions() },
sidebar: {
'/ko/guide/': { base: '/ko/guide/', items: sidebarGuide() },
'/ko/reference/': { base: '/ko/reference/', items: sidebarReference() }
@ -39,6 +41,14 @@ export const ko = defineConfig({
text: '업데이트 날짜'
},
notFound: {
title: '페이지를 찾을 수 없습니다',
quote:
'방향을 바꾸지 않고 계속 찾다 보면 결국 당신이 가고 있는 곳에 도달할 수도 있습니다.',
linkLabel: '홈으로 가기',
linkText: '집으로 데려가줘'
},
langMenuLabel: '언어 변경',
returnToTopLabel: '맨 위로 돌아가기',
sidebarMenuLabel: '사이드바 메뉴',
@ -208,8 +218,8 @@ function sidebarReference(): DefaultTheme.SidebarItem[] {
]
}
export const search: DefaultTheme.AlgoliaSearchOptions['locales'] = {
ko: {
function searchOptions(): Partial<DefaultTheme.AlgoliaSearchOptions> {
return {
placeholder: '문서 검색',
translations: {
button: {

@ -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

@ -70,7 +70,7 @@ export default DefaultTheme
export default {
transformHead({ assets }) {
// 폰트를 매칭하기 위해 정규식을 적절히 조정하세요
const myFontFile = assets.find(file => /font-name\.\w+\.woff2/)
const myFontFile = assets.find(file => /font-name\.[\w-]+\.woff2/.test(file))
if (myFontFile) {
return [
[

@ -125,7 +125,7 @@ import CustomComponent from '../components/CustomComponent.vue'
컴포넌트가 대부분의 페이지에서 사용될 경우, Vue 앱 인스턴스를 커스텀하여 전역적으로 등록할 수 있습니다. [기본 테마 확장](./extending-default-theme#registering-global-components)의 관련 섹션을 예제를 참고하세요.
::: warning 중요
커스텀 컴포넌트의 이름에 하이픈이 포함되어 있거나 파스칼케이스(PascalCase)e인지 확인하세요. 그렇지 않으면 인라인 요소로 처리되어 `<p>` 태그 안에 래핑됩니다. `<p>`는 블록 엘리먼트를 내부에 배치할 수 없기 때문에 하이드레이션 불일치가 발생합니다.
커스텀 컴포넌트의 이름에 하이픈이 포함되어 있거나 파스칼케이스(PascalCase)인지 확인하세요. 그렇지 않으면 인라인 요소로 처리되어 `<p>` 태그 안에 래핑됩니다. `<p>`는 블록 엘리먼트를 내부에 배치할 수 없기 때문에 하이드레이션 불일치가 발생합니다.
:::
### 헤더에 <ComponentInHeader /> 컴포넌트 사용하기 {#using-components-in-headers}

@ -1,9 +1,6 @@
---
layout: home
title: VitePress
titleTemplate: Vite & Vue 기반 정적 사이트 생성기
hero:
name: VitePress
text: Vite & Vue 기반 정적 사이트 생성기
@ -19,7 +16,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>
```

@ -6,8 +6,8 @@
},
"files": [
{
"location": ".vitepress/config/{en,zh,pt,ru,es,ko,fa}.ts",
"pattern": ".vitepress/config/@lang.ts",
"location": "**/config.ts",
"pattern": "@lang/@path",
"type": "universal"
},
{

@ -13,8 +13,9 @@
"@lunariajs/core": "^0.1.1",
"markdown-it-mathjax3": "^4.3.2",
"open-cli": "^8.0.0",
"postcss-rtlcss": "^5.6.0",
"postcss-rtlcss": "^5.7.0",
"vitepress": "workspace:*",
"vitepress-plugin-group-icons": "^1.3.6"
"vitepress-plugin-group-icons": "^1.5.2",
"vitepress-plugin-llms": "^1.1.0"
}
}

@ -1,16 +1,18 @@
import { createRequire } from 'module'
import { defineConfig, type DefaultTheme } from 'vitepress'
import { defineAdditionalConfig, type DefaultTheme } from 'vitepress'
const require = createRequire(import.meta.url)
const pkg = require('vitepress/package.json')
export const pt = defineConfig({
export default defineAdditionalConfig({
lang: 'pt-BR',
description: 'Gerador de Site Estático desenvolvido com Vite e Vue.',
themeConfig: {
nav: nav(),
search: { options: searchOptions() },
sidebar: {
'/pt/guide/': { base: '/pt/guide/', items: sidebarGuide() },
'/pt/reference/': { base: '/pt/reference/', items: sidebarReference() }
@ -36,11 +38,15 @@ export const pt = defineConfig({
},
lastUpdated: {
text: 'Atualizado em',
formatOptions: {
dateStyle: 'short',
timeStyle: 'medium'
}
text: 'Atualizado em'
},
notFound: {
title: 'PÁGINA NÃO ENCONTRADA',
quote:
'Mas se você não mudar de direção e continuar procurando, pode acabar onde está indo.',
linkLabel: 'ir para a página inicial',
linkText: 'Me leve para casa'
},
langMenuLabel: 'Alterar Idioma',
@ -167,8 +173,8 @@ function sidebarReference(): DefaultTheme.SidebarItem[] {
]
}
export const search: DefaultTheme.AlgoliaSearchOptions['locales'] = {
pt: {
function searchOptions(): Partial<DefaultTheme.AlgoliaSearchOptions> {
return {
placeholder: 'Pesquisar documentos',
translations: {
button: {

@ -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

@ -70,7 +70,7 @@ Se a sua fonte é um arquivo local referenciado via `@font-face`, ela será proc
export default {
transformHead({ assets }) {
// ajuste o regex para corresponder à sua fonte
const myFontFile = assets.find(file => /font-name\.\w+\.woff2/)
const myFontFile = assets.find(file => /font-name\.[\w-]+\.woff2/.test(file))
if (myFontFile) {
return [
[

@ -1,9 +1,6 @@
---
layout: home
title: VitePress
titleTemplate: Gerador de Site Estático desenvolvido com Vite & Vue
hero:
name: VitePress
text: Gerador de Site Estático Vite & Vue
@ -19,7 +16,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

@ -1,16 +1,18 @@
import { createRequire } from 'module'
import { defineConfig, type DefaultTheme } from 'vitepress'
import { defineAdditionalConfig, type DefaultTheme } from 'vitepress'
const require = createRequire(import.meta.url)
const pkg = require('vitepress/package.json')
export const ru = defineConfig({
export default defineAdditionalConfig({
lang: 'ru-RU',
description: 'Генератор статических сайтов на основе Vite и Vue.',
themeConfig: {
nav: nav(),
search: { options: searchOptions() },
sidebar: {
'/ru/guide/': { base: '/ru/guide/', items: sidebarGuide() },
'/ru/reference/': { base: '/ru/reference/', items: sidebarReference() }
@ -37,6 +39,14 @@ export const ru = defineConfig({
text: 'Обновлено'
},
notFound: {
title: 'СТРАНИЦА НЕ НАЙДЕНА',
quote:
'Но если ты не изменишь направление и продолжишь искать, ты можешь оказаться там, куда направляешься.',
linkLabel: 'перейти на главную',
linkText: 'Отведи меня домой'
},
darkModeSwitchLabel: 'Оформление',
lightModeSwitchTitle: 'Переключить на светлую тему',
darkModeSwitchTitle: 'Переключить на тёмную тему',
@ -163,8 +173,8 @@ function sidebarReference(): DefaultTheme.SidebarItem[] {
]
}
export const search: DefaultTheme.AlgoliaSearchOptions['locales'] = {
ru: {
function searchOptions(): Partial<DefaultTheme.AlgoliaSearchOptions> {
return {
placeholder: 'Поиск в документации',
translations: {
button: {

@ -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

@ -70,7 +70,7 @@ export default DefaultTheme
export default {
transformHead({ assets }) {
// настраиваем regex соответствующим образом, чтобы он соответствовал вашему шрифту
const myFontFile = assets.find((file) => /font-name\.\w+\.woff2/)
const myFontFile = assets.find(file => /font-name\.[\w-]+\.woff2/.test(file))
if (myFontFile) {
return [
[

@ -1,9 +1,6 @@
---
layout: home
title: VitePress
titleTemplate: Генератор статических сайтов на основе Vite и Vue
hero:
name: VitePress
text: Генератор статических сайтов на основе Vite и Vue
@ -19,7 +16,7 @@ hero:
text: GitHub
link: https://github.com/vuejs/vitepress
image:
src: /vitepress-logo-large.webp
src: /vitepress-logo-large.svg
alt: VitePress
features:

@ -19,13 +19,13 @@ export default {
**Параметры, описанные на этой странице, применимы только к теме по умолчанию.** Разные темы предполагают разные конфигурации темы. При использовании пользовательской темы объект конфигурации темы будет передан теме, чтобы она могла определить условное поведение на его основе.
## i18nRouting {#i18nrouting}
## i18nRouting
- Тип: `boolean`
При смене локали на `ru` URL изменится с `/foo` (или `/en/foo/`) на `/ru/foo`. Вы можете отключить это поведение, установив для параметра `themeConfig.i18nRouting` значение `false`.
## logo {#logo}
## logo
- Тип: `ThemeableImage`
@ -46,7 +46,7 @@ type ThemeableImage =
| { light: string; dark: string; alt?: string }
```
## siteTitle {#sitetitle}
## siteTitle
- Тип: `string | false`
@ -60,7 +60,7 @@ export default {
}
```
## nav {#nav}
## nav
- Тип: `NavItem`
@ -108,7 +108,7 @@ interface NavItemWithChildren {
}
```
## sidebar {#sidebar}
## sidebar
- Тип: `Sidebar`
@ -135,7 +135,7 @@ export default {
export type Sidebar = SidebarItem[] | SidebarMulti
export interface SidebarMulti {
[path: string]: SidebarItem[]
[path: string]: SidebarItem[] | { items: SidebarItem[]; base: string }
}
export type SidebarItem = {
@ -162,10 +162,23 @@ export type SidebarItem = {
* Если `false`, группа сворачивается, но по умолчанию разворачивается
*/
collapsed?: boolean
/**
* Базовый путь для дочерних элементов
*/
base?: string
/**
* Настройте текст, который отображается в футере предыдущей/следующей страницы
*/
docFooterText?: string
rel?: string
target?: string
}
```
## aside {#aside}
## aside
- Тип: `boolean | 'left'`
- По умолчанию: `true`
@ -177,7 +190,7 @@ export type SidebarItem = {
Если вы хотите отключить его для всех режимов просмотра, используйте `aside: false`.
## outline {#outline}
## outline
- Тип: `Outline | Outline['level'] | false`
- Уровень можно переопределить для каждой страницы с помощью [метаданных](./frontmatter-config#outline)
@ -205,7 +218,7 @@ interface Outline {
}
```
## socialLinks {#sociallinks}
## socialLinks
- Тип: `SocialLink[]`
@ -215,6 +228,7 @@ interface Outline {
export default {
themeConfig: {
socialLinks: [
// Можно добавить любую иконку из simple-icons (https://simpleicons.org/):
{ icon: 'github', link: 'https://github.com/vuejs/vitepress' },
{ icon: 'twitter', link: '...' },
// Можно добавить пользовательские иконки, передав SVG в виде строки:
@ -239,7 +253,7 @@ interface SocialLink {
}
```
## footer {#footer}
## footer
- Тип: `Footer`
- Можно переопределить для каждой страницы с помощью [метаданных](./frontmatter-config#footer)
@ -264,7 +278,7 @@ export interface Footer {
}
```
## editLink {#editlink}
## editLink
- Тип: `EditLink`
- Можно переопределить для каждой страницы с помощью [метаданных](./frontmatter-config#editlink)
@ -289,7 +303,7 @@ export interface EditLink {
}
```
## lastUpdated {#lastupdated}
## lastUpdated
- Тип: `LastUpdatedOptions`
@ -324,7 +338,7 @@ export interface LastUpdatedOptions {
}
```
## algolia {#algolia}
## algolia
- Тип: `AlgoliaSearch`
@ -364,7 +378,7 @@ export interface CarbonAdsOptions {
Подробнее в главе [Тема по умолчанию: Carbon Ads](./default-theme-carbon-ads)
## docFooter {#docfooter}
## docFooter
- Тип: `DocFooter`
@ -388,47 +402,47 @@ export interface DocFooter {
}
```
## darkModeSwitchLabel {#darkmodeswitchlabel}
## darkModeSwitchLabel
- Тип: `string`
- По умолчанию: `Appearance`
Можно использовать для настройки надписи переключателя тёмного режима. Этот ярлык отображается только в мобильном представлении.
## lightModeSwitchTitle {#lightmodeswitchtitle}
## lightModeSwitchTitle
- Тип: `string`
- По умолчанию: `Switch to light theme`
Может использоваться для настройки заголовка переключателя светлого режима, который появляется при наведении курсора.
## darkModeSwitchTitle {#darkmodeswitchtitle}
## darkModeSwitchTitle
- Тип: `string`
- По умолчанию: `Switch to dark theme`
Можно использовать для настройки заголовка переключателя тёмного режима, который появляется при наведении курсора.
## sidebarMenuLabel {#sidebarmenulabel}
## sidebarMenuLabel
- Тип: `string`
- По умолчанию: `Menu`
Может использоваться для настройки метки бокового меню. Эта метка отображается только в мобильном представлении.
## returnToTopLabel {#returntotoplabel}
## returnToTopLabel
- Тип: `string`
- По умолчанию: `Return to top`
Может использоваться для настройки метки кнопки возврата наверх. Эта метка отображается только в мобильном представлении.
## langMenuLabel {#langmenulabel}
## langMenuLabel
- Тип: `string`
- По умолчанию: `Change language`
Можно использовать для настройки aria-метки кнопки переключения языка в панели навигации. Это используется только в том случае, если вы используете [i18n](../guide/i18n).
Можно использовать для настройки aria-метки кнопки переключения языка в панели навигации. Применяется только в том случае, если вы используете [i18n](../guide/i18n).
## skipToContentLabel
@ -437,9 +451,44 @@ export interface DocFooter {
Можно использовать для настройки метки ссылки перехода к содержимому. Эта ссылка отображается, когда пользователь перемещается по сайту с помощью клавиатуры.
## externalLinkIcon {#externallinkicon}
## externalLinkIcon
- Тип: `boolean`
- По умолчанию: `false`
Отображать ли значок внешней ссылки рядом с внешними ссылками в Markdown.
## `useLayout` <Badge type="info" text="composable" />
Возвращает данные, относящиеся к макету. Возвращаемый объект имеет следующий тип:
```ts
interface {
isHome: ComputedRef<boolean>
sidebar: Readonly<ShallowRef<DefaultTheme.SidebarItem[]>>
sidebarGroups: ComputedRef<DefaultTheme.SidebarItem[]>
hasSidebar: ComputedRef<boolean>
isSidebarEnabled: ComputedRef<boolean>
hasAside: ComputedRef<boolean>
leftAside: ComputedRef<boolean>
headers: Readonly<ShallowRef<DefaultTheme.OutlineItem[]>>
hasLocalNav: ComputedRef<boolean>
}
```
**Пример:**
```vue
<script setup>
import { useLayout } from 'vitepress/theme'
const { hasSidebar } = useLayout()
</script>
<template>
<div v-if="hasSidebar">Отображается только если есть боковая панель</div>
</template>
```

@ -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>
```

@ -21,7 +21,7 @@ editLink: true
{{ $frontmatter.title }}
```
## title {#title}
## title
- Тип: `string`
@ -33,7 +33,7 @@ title: VitePress
---
```
## titleTemplate {#titletemplate}
## titleTemplate
- Тип: `string | boolean`
@ -46,7 +46,7 @@ titleTemplate: Генератор статических сайтов на ос
---
```
## description {#description}
## description
- Тип: `string`
@ -58,7 +58,7 @@ description: VitePress
---
```
## head {#head}
## head
- Тип: `HeadConfig[]`
@ -86,7 +86,7 @@ type HeadConfig =
Следующие параметры метаданных применимы только при использовании темы по умолчанию.
### layout {#layout}
### layout
- Тип: `doc | home | page`
- По умолчанию: `doc`
@ -103,15 +103,15 @@ layout: doc
---
```
### hero <Badge type="info" text="только для страниц с макетом home" /> {#hero}
### hero <Badge type="info" text="только для страниц с макетом home" />
Определяет содержимое секции `hero`, когда `layout` имеет значение `home`. Подробнее в главе [Тема по умолчанию: Главная страница](./default-theme-home-page).
### features <Badge type="info" text="только для страниц с макетом home" /> {#features}
### features <Badge type="info" text="только для страниц с макетом home" />
Определяет элементы для отображения в секции `features`, когда `layout` имеет значение `home`. Подробнее в главе [Тема по умолчанию: Главная страница](./default-theme-home-page).
### navbar {#navbar}
### navbar
- Тип: `boolean`
- По умолчанию: `true`
@ -124,7 +124,7 @@ navbar: false
---
```
### sidebar {#sidebar}
### sidebar
- Тип: `boolean`
- По умолчанию: `true`
@ -137,7 +137,7 @@ sidebar: false
---
```
### aside {#aside}
### aside
- Тип: `boolean | 'left'`
- По умолчанию: `true`
@ -154,7 +154,7 @@ aside: false
---
```
### outline {#outline}
### outline
- Тип: `number | [number, number] | 'deep' | false`
- По умолчанию: `2`
@ -167,7 +167,7 @@ outline: [2, 4]
---
```
### lastUpdated {#lastupdated}
### lastUpdated
- Тип: `boolean | Date`
- По умолчанию: `true`
@ -180,7 +180,7 @@ lastUpdated: false
---
```
### editLink {#editlink}
### editLink
- Тип: `boolean`
- По умолчанию: `true`
@ -193,7 +193,7 @@ editLink: false
---
```
### footer {#footer}
### footer
- Тип: `boolean`
- По умолчанию: `true`
@ -206,7 +206,7 @@ footer: false
---
```
### pageClass {#pageclass}
### pageClass
- Тип: `string`
@ -225,3 +225,16 @@ pageClass: custom-page-class
/* стили для конкретной страницы */
}
```
### isHome
- Тип: `boolean`
Стандартная тема полагается на проверки типа `frontmatter.layout === 'home'`, чтобы определить, является ли текущая страница домашней (главной).\
Это полезно, когда вы хотите принудительно показывать элементы домашней страницы в пользовательском макете.
```yaml
---
isHome: true
---
```

@ -10,7 +10,7 @@ outline: deep
### Разрешение конфигурации {#config-resolution}
Файл конфигурации всегда разрешается из `<root>/.vitepress/config.[ext]`, где `<root>` — это корень вашего [проекта](../guide/routing#root-and-source-directory) VitePress, а `[ext]` — одно из поддерживаемых расширений файла. TypeScript поддерживается из коробки. Поддерживаемые расширения включают `.js`, `.ts`, `.mjs` и `.mts`.
Конфигурация всегда считывается из файла `<root>/.vitepress/config.[ext]`, где `<root>` — это корень вашего [проекта](../guide/routing#root-and-source-directory) VitePress, а `[ext]` — одно из поддерживаемых расширений файла. TypeScript поддерживается из коробки. Поддерживаемые расширения включают `.js`, `.ts`, `.mjs` и `.mts`.
В файлах конфигурации рекомендуется использовать синтаксис ES-модулей. Файл конфигурации должен по умолчанию экспортировать объект:

@ -1,16 +1,18 @@
import { createRequire } from 'module'
import { defineConfig, type DefaultTheme } from 'vitepress'
import { defineAdditionalConfig, type DefaultTheme } from 'vitepress'
const require = createRequire(import.meta.url)
const pkg = require('vitepress/package.json')
export const zh = defineConfig({
export default defineAdditionalConfig({
lang: 'zh-Hans',
description: '由 Vite 和 Vue 驱动的静态站点生成器',
themeConfig: {
nav: nav(),
search: { options: searchOptions() },
sidebar: {
'/zh/guide/': { base: '/zh/guide/', items: sidebarGuide() },
'/zh/reference/': { base: '/zh/reference/', items: sidebarReference() }
@ -36,11 +38,15 @@ export const zh = defineConfig({
},
lastUpdated: {
text: '最后更新于',
formatOptions: {
dateStyle: 'short',
timeStyle: 'medium'
}
text: '最后更新于'
},
notFound: {
title: '页面未找到',
quote:
'但如果你不改变方向,并且继续寻找,你可能最终会到达你所前往的地方。',
linkLabel: '前往首页',
linkText: '带我回首页'
},
langMenuLabel: '多语言',
@ -160,8 +166,8 @@ function sidebarReference(): DefaultTheme.SidebarItem[] {
]
}
export const search: DefaultTheme.AlgoliaSearchOptions['locales'] = {
zh: {
function searchOptions(): Partial<DefaultTheme.AlgoliaSearchOptions> {
return {
placeholder: '搜索文档',
translations: {
button: {

@ -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

@ -70,7 +70,7 @@ export default DefaultTheme
export default {
transformHead({ assets }) {
// 相应地调整正则表达式以匹配字体
const myFontFile = assets.find(file => /font-name\.\w+\.woff2/)
const myFontFile = assets.find(file => /font-name\.[\w-]+\.woff2/.test(file))
if (myFontFile) {
return [
[

@ -1,9 +1,6 @@
---
layout: home
title: VitePress
titleTemplate: 由 Vite 和 Vue 驱动的静态站点生成器
hero:
name: VitePress
text: 由 Vite 和 Vue 驱动的静态站点生成器
@ -19,7 +16,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>
```

@ -26,3 +26,13 @@
[[redirects]]
from = "/guide/"
to = "/guide/getting-started"
[[redirects]]
from = "/llms.md"
status = 301
to = "/llms.txt"
[[redirects]]
from = "/llms-full.md"
status = 301
to = "/llms-full.txt"

@ -1,6 +1,6 @@
{
"name": "vitepress",
"version": "2.0.0-alpha.4",
"version": "2.0.0-alpha.5",
"description": "Vite & Vue powered static site generator",
"keywords": [
"vite",
@ -97,37 +97,37 @@
"dependencies": {
"@docsearch/css": "^3.9.0",
"@docsearch/js": "^3.9.0",
"@iconify-json/simple-icons": "^1.2.27",
"@shikijs/core": "^3.1.0",
"@shikijs/transformers": "^3.1.0",
"@shikijs/types": "^3.1.0",
"@vitejs/plugin-vue": "^5.2.1",
"@vue/devtools-api": "^7.7.2",
"@iconify-json/simple-icons": "^1.2.32",
"@shikijs/core": "^3.2.2",
"@shikijs/transformers": "^3.2.2",
"@shikijs/types": "^3.2.2",
"@vitejs/plugin-vue": "^5.2.3",
"@vue/devtools-api": "^7.7.5",
"@vue/shared": "^3.5.13",
"@vueuse/core": "^12.8.2",
"@vueuse/integrations": "^12.8.2",
"@vueuse/core": "^13.1.0",
"@vueuse/integrations": "^13.1.0",
"focus-trap": "^7.6.4",
"mark.js": "8.11.1",
"minisearch": "^7.1.2",
"shiki": "^3.1.0",
"vite": "^6.2.1",
"shiki": "^3.2.2",
"vite": "^6.3.2",
"vue": "^3.5.13"
},
"devDependencies": {
"@clack/prompts": "^0.10.0",
"@clack/prompts": "^0.10.1",
"@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",
"@mdit-vue/plugin-sfc": "^2.1.3",
"@mdit-vue/plugin-title": "^2.1.3",
"@mdit-vue/plugin-toc": "^2.1.3",
"@mdit-vue/shared": "^2.1.3",
"@mdit-vue/plugin-component": "^2.1.4",
"@mdit-vue/plugin-frontmatter": "^2.1.4",
"@mdit-vue/plugin-headers": "^2.1.4",
"@mdit-vue/plugin-sfc": "^2.1.4",
"@mdit-vue/plugin-title": "^2.1.4",
"@mdit-vue/plugin-toc": "^2.1.4",
"@mdit-vue/shared": "^2.1.4",
"@polka/compression": "^1.0.0-next.28",
"@rollup/plugin-alias": "^5.1.1",
"@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,22 +139,22 @@
"@types/markdown-it-container": "^2.0.10",
"@types/markdown-it-emoji": "^3.0.1",
"@types/minimist": "^1.2.5",
"@types/node": "^22.13.9",
"@types/picomatch": "^3.0.2",
"@types/node": "^22.14.1",
"@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.25.0",
"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.3",
"lint-staged": "^15.5.1",
"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.2.0",
@ -163,32 +163,32 @@
"markdown-it-emoji": "^3.0.0",
"markdown-it-mathjax3": "^4.3.2",
"minimist": "^1.2.8",
"nanoid": "^5.1.3",
"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.51.0",
"playwright-chromium": "^1.52.0",
"polka": "^1.0.0-next.28",
"postcss-prefix-selector": "^2.1.0",
"postcss-prefix-selector": "^2.1.1",
"prettier": "^3.5.3",
"prompts": "^2.4.2",
"punycode": "^2.3.1",
"rimraf": "^6.0.1",
"rollup": "^4.34.9",
"rollup-plugin-dts": "^6.1.1",
"rollup": "^4.40.0",
"rollup-plugin-dts": "6.1.1",
"rollup-plugin-esbuild": "^6.2.1",
"semver": "^7.7.1",
"simple-git-hooks": "^2.11.1",
"simple-git-hooks": "^2.12.1",
"sirv": "^3.0.1",
"sitemap": "^8.0.0",
"tinyglobby": "^0.2.12",
"typescript": "^5.8.2",
"vitest": "^3.0.8",
"tinyglobby": "^0.2.13",
"typescript": "^5.8.3",
"vitest": "^3.1.2",
"vue-tsc": "^2.2.8",
"wait-on": "^8.0.2"
"wait-on": "^8.0.3"
},
"peerDependencies": {
"markdown-it-mathjax3": "^4",

File diff suppressed because it is too large Load Diff

@ -55,24 +55,17 @@ const esmBuild: RollupOptions = {
const typesExternal = [
...external,
/\/vitepress\/(?!(dist|node_modules)\/).*\.d\.ts$/,
/\/vitepress\/(?!(dist|node_modules|vitepress)\/).*\.d\.ts$/,
'source-map-js',
'fast-glob'
]
const dtsNode = dts({
respectExternal: true,
tsconfig: 'src/node/tsconfig.json'
tsconfig: 'src/node/tsconfig.json',
compilerOptions: { preserveSymlinks: false }
})
const originalResolveId = dtsNode.resolveId
dtsNode.resolveId = async function (source, importer) {
const res = await (originalResolveId as Function).call(this, source, importer)
if (res?.id) res.id = await fs.realpath(res.id)
return res
}
const nodeTypes: RollupOptions = {
input: 'src/node/index.ts',
output: {

@ -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' }}

@ -7,7 +7,7 @@ interface Props {
tag?: string
size?: 'medium' | 'big'
theme?: 'brand' | 'alt' | 'sponsor'
text: string
text?: string
href?: string
target?: string;
rel?: string;
@ -35,7 +35,7 @@ const component = computed(() => {
:target="props.target ?? (isExternal ? '_blank' : undefined)"
:rel="props.rel ?? (isExternal ? 'noreferrer' : undefined)"
>
{{ text }}
<slot>{{ text }}</slot>
</component>
</template>

@ -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$/, '')

@ -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)
</script>
@ -28,7 +19,7 @@ useActiveAnchor(container, marker)
<nav
aria-labelledby="doc-outline-aria-label"
class="VPDocAsideOutline"
:class="{ 'has-outline': headers.length > 0 }"
:class="{ 'has-outline': hasLocalNav }"
ref="container"
>
<div class="content">
@ -43,7 +34,7 @@ useActiveAnchor(container, marker)
{{ resolveTitle(theme) }}
</div>
<VPDocOutlineItem :headers="headers" :root="true" />
<VPDocOutlineItem :headers :root="true" />
</div>
</nav>
</template>

@ -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;
}

@ -663,6 +663,10 @@ function onMouseMove(e: MouseEvent) {
width: 100%;
}
.search-input::-webkit-search-cancel-button {
display: none;
}
@media (max-width: 767px) {
.search-input {
padding: 6px 4px;

@ -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>

@ -1,8 +1,7 @@
<script lang="ts" setup>
import { useWindowScroll } from '@vueuse/core'
import { ref, watchPostEffect } from 'vue'
import { useData } from '../composables/data'
import { useSidebar } from '../composables/sidebar'
import { useLayout } from '../composables/layout'
import VPNavBarAppearance from './VPNavBarAppearance.vue'
import VPNavBarExtra from './VPNavBarExtra.vue'
import VPNavBarHamburger from './VPNavBarHamburger.vue'
@ -21,15 +20,14 @@ defineEmits<{
}>()
const { y } = useWindowScroll()
const { hasSidebar } = useSidebar()
const { frontmatter } = useData()
const { isHome, hasSidebar } = useLayout()
const classes = ref<Record<string, boolean>>({})
watchPostEffect(() => {
classes.value = {
'has-sidebar': hasSidebar.value,
'home': frontmatter.value.layout === 'home',
'home': isHome.value,
'top': y.value === 0,
'screen-open': props.isScreenOpen
}

@ -16,13 +16,13 @@ const { theme } = useData()
Main Navigation
</span>
<template v-for="item in theme.nav" :key="JSON.stringify(item)">
<VPNavBarMenuLink v-if="'link' in item" :item="item" />
<VPNavBarMenuLink v-if="'link' in item" :item />
<component
v-else-if="'component' in item"
:is="item.component"
v-bind="item.props"
/>
<VPNavBarMenuGroup v-else :item="item" />
<VPNavBarMenuGroup v-else :item />
</template>
</nav>
</template>

@ -1,13 +1,13 @@
<script lang="ts" setup>
import '@docsearch/css'
import { onKeyStroke } from '@vueuse/core'
import type { DefaultTheme } from 'vitepress/theme'
import {
defineAsyncComponent,
onMounted,
onUnmounted,
ref
} from 'vue'
import type { DefaultTheme } from '../../shared'
import { useData } from '../composables/data'
import VPNavBarSearchButton from './VPNavBarSearchButton.vue'

@ -2,12 +2,12 @@
import { computed } from 'vue'
import { useData } from '../composables/data'
import { useLangs } from '../composables/langs'
import { useSidebar } from '../composables/sidebar'
import { useLayout } from '../composables/layout'
import { normalizeLink } from '../support/utils'
import VPImage from './VPImage.vue'
const { site, theme } = useData()
const { hasSidebar } = useSidebar()
const { hasSidebar } = useLayout()
const { currentLang } = useLangs()
const link = computed(() =>
@ -34,8 +34,8 @@ const target = computed(() =>
<a
class="title"
:href="link ?? normalizeLink(currentLang.link)"
:rel="rel"
:target="target"
:rel
:target
>
<slot name="nav-bar-title-before" />
<VPImage v-if="theme.logo" class="logo" :image="theme.logo" />

@ -9,7 +9,7 @@ const { theme } = useData()
<template>
<nav v-if="theme.nav" class="VPNavScreenMenu">
<template v-for="item in theme.nav" :key="JSON.stringify(item)">
<VPNavScreenMenuLink v-if="'link' in item" :item="item" />
<VPNavScreenMenuLink v-if="'link' in item" :item />
<component
v-else-if="'component' in item"
:is="item.component"

@ -34,7 +34,7 @@ function toggle() {
<div :id="groupId" class="items">
<template v-for="item in items" :key="JSON.stringify(item)">
<div v-if="'link' in item" class="item">
<VPNavScreenMenuGroupLink :item="item" />
<VPNavScreenMenuGroupLink :item />
</div>
<div v-else-if="'component' in item" class="item">

@ -11,11 +11,7 @@ defineProps<{
<template>
<div class="VPNavScreenMenuGroupSection">
<p v-if="text" class="title">{{ text }}</p>
<VPNavScreenMenuGroupLink
v-for="item in items"
:key="item.text"
:item="item"
/>
<VPNavScreenMenuGroupLink v-for="item in items" :key="item.text" :item />
</div>
</template>

@ -2,10 +2,10 @@
import { useScrollLock } from '@vueuse/core'
import { inBrowser } from 'vitepress'
import { ref, watch } from 'vue'
import { useSidebar } from '../composables/sidebar'
import { useLayout } from '../composables/layout'
import VPSidebarGroup from './VPSidebarGroup.vue'
const { sidebarGroups, hasSidebar } = useSidebar()
const { sidebarGroups, hasSidebar } = useLayout()
const props = defineProps<{
open: boolean
@ -58,7 +58,7 @@ watch(
</span>
<slot name="sidebar-nav-before" />
<VPSidebarGroup :items="sidebarGroups" :key="key" />
<VPSidebarGroup :items="sidebarGroups" :key />
<slot name="sidebar-nav-after" />
</nav>
</aside>

@ -33,7 +33,7 @@ onBeforeUnmount(() => {
class="group"
:class="{ 'no-transition': disableTransition }"
>
<VPSidebarItem :item="item" :depth="0" />
<VPSidebarItem :item :depth="0" />
</div>
</template>

@ -1,7 +1,7 @@
<script setup lang="ts">
import type { DefaultTheme } from 'vitepress/theme'
import { computed } from 'vue'
import { useSidebarControl } from '../composables/sidebar'
import { useSidebarItemControl } from '../composables/sidebar'
import VPLink from './VPLink.vue'
const props = defineProps<{
@ -17,7 +17,7 @@ const {
hasActiveLink,
hasChildren,
toggle
} = useSidebarControl(computed(() => props.item))
} = useSidebarItemControl(computed(() => props.item))
const sectionTag = computed(() => (hasChildren.value ? 'section' : `div`))

@ -12,9 +12,9 @@ defineProps<{
<VPSocialLink
v-for="{ link, icon, ariaLabel } in links"
:key="link"
:icon="icon"
:link="link"
:ariaLabel="ariaLabel"
:icon
:link
:ariaLabel
/>
</div>
</template>

@ -19,7 +19,7 @@ const classes = computed(() => [props.size, `count-${props.members.length}`])
<div class="VPTeamMembers" :class="classes">
<div class="container">
<div v-for="member in members" :key="member.name" class="item">
<VPTeamMembersItem :size="size" :member="member" />
<VPTeamMembersItem :size :member />
</div>
</div>
</div>

@ -1,9 +1,9 @@
import { useMediaQuery } from '@vueuse/core'
import { computed } from 'vue'
import { useSidebar } from './sidebar'
import { useLayout } from './layout'
export function useAside() {
const { hasSidebar } = useSidebar()
const { hasSidebar } = useLayout()
const is960 = useMediaQuery('(min-width: 960px)')
const is1280 = useMediaQuery('(min-width: 1280px)')

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

Loading…
Cancel
Save