pull/5416/merge
Achord Chan 5 days ago committed by GitHub
commit 6f6f9d157f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -197,6 +197,7 @@ const sidebar: DefaultTheme.Config['sidebar'] = {
export default defineConfig({
title: 'Example',
description: 'An example app using VitePress.',
dir: false,
srcExclude: ['**/parts/**'],
markdown: {
image: { lazyLoad: true }

@ -42,6 +42,25 @@ describe('navigation accessibility', () => {
expect(await sectionLink.getAttribute('aria-current')).toBeNull()
})
test('preserves a runtime-managed document direction', async () => {
await goto('/')
const html = page.locator('html')
expect(await html.getAttribute('dir')).toBeNull()
await page.evaluate(() => {
document.documentElement.dir = 'rtl'
})
await page
.locator('.VPNavBarMenuLink[href="/markdown-extensions/"]')
.click()
await page.waitForFunction(() =>
location.pathname.startsWith('/markdown-extensions')
)
expect(await html.getAttribute('dir')).toBe('rtl')
})
test('marks only exact sidebar links, including fragments', async () => {
const overview = '.VPSidebarItem .link[href="/sidebar-hash/"]'
const sectionOne = '.VPSidebarItem .link[href="/sidebar-hash/#section-one"]'

@ -3,10 +3,16 @@ import {
mergeConfig,
normalizeAssetsBase,
normalizeSiteBase,
resolveSiteData,
type UserConfig
} from 'node/config'
describe('node/config', () => {
test('preserves disabled automatic direction handling', async () => {
expect((await resolveSiteData('', { dir: false })).dir).toBe(false)
expect((await resolveSiteData('', {})).dir).toBe('ltr')
})
test('merges markdown hooks from extended configs', async () => {
const calls: string[] = []
const md = {} as MarkdownItAsync

@ -44,7 +44,7 @@ The following properties can be overridden for each locale (including root):
```ts
interface LocaleSpecificConfig<ThemeConfig = any> {
lang?: string
dir?: string
dir?: string | false
title?: string
titleTemplate?: string | boolean
description?: string
@ -53,6 +53,8 @@ interface LocaleSpecificConfig<ThemeConfig = any> {
}
```
Set `dir: false` at the site or locale level when application code manages the `<html dir>` attribute at runtime. VitePress will omit the attribute from generated HTML and will not overwrite it during client-side navigation.
Refer [`DefaultTheme.Config`](https://github.com/vuejs/vitepress/blob/main/types/default-theme.d.ts) interface for details on customizing the placeholder texts of the default theme. Don't override `themeConfig.algolia` or `themeConfig.carbonAds` at locale-level. Refer [Algolia docs](../reference/default-theme-search#i18n) for using multilingual search.
**Pro tip:** Config file can be stored at `docs/.vitepress/config/index.ts` too. It might help you organize stuff by creating a configuration file per locale and then merge and export them from `index.ts`.
@ -143,4 +145,4 @@ watchEffect(() => {
## RTL Support (Experimental)
For RTL support, specify `dir: 'rtl'` in config and use some RTLCSS PostCSS plugin like <https://github.com/MohammadYounes/rtlcss>, <https://github.com/vkalinichev/postcss-rtl> or <https://github.com/elchininet/postcss-rtlcss>. You'll need to configure your PostCSS plugin to use `:where([dir="ltr"])` and `:where([dir="rtl"])` as prefixes to prevent CSS specificity issues.
For RTL support, specify `dir: 'rtl'` in config and use some RTLCSS PostCSS plugin like <https://github.com/MohammadYounes/rtlcss>, <https://github.com/vkalinichev/postcss-rtl> or <https://github.com/elchininet/postcss-rtlcss>. You'll need to configure your PostCSS plugin to use `:where([dir="ltr"])` and `:where([dir="rtl"])` as prefixes to prevent CSS specificity issues. If users can switch direction at runtime, set `dir: false` and update `document.documentElement.dir` in your application code.

@ -40,7 +40,7 @@ interface VitePressData<T = any> {
description: Ref<string>
lang: Ref<string>
isDark: Ref<boolean>
dir: Ref<string>
dir: Ref<string | false>
localeIndex: Ref<string>
/**
* Current location hash

@ -58,7 +58,10 @@ export function initData(route: Route): VitePressData {
frontmatter: computed(() => route.data.frontmatter),
params: computed(() => route.data.params),
lang: computed(() => site.value.lang),
dir: computed(() => route.data.frontmatter.dir || site.value.dir),
dir: computed(() => {
const dir = route.data.frontmatter.dir
return dir === false ? false : dir || site.value.dir
}),
localeIndex: computed(() => site.value.localeIndex || 'root'),
title: computed(() => createTitle(site.value, route.data)),
description: computed(

@ -49,7 +49,9 @@ const VitePressApp = defineComponent({
onMounted(() => {
watchEffect(() => {
document.documentElement.lang = lang.value
if (dir.value !== false) {
document.documentElement.dir = dir.value
}
})
})

@ -41,7 +41,7 @@ export function useLangs({
linkToCorrespondingPage
}),
lang: value.lang,
dir: value.dir
dir: value.dir === false ? undefined : value.dir
}
)
)

@ -99,7 +99,9 @@ export async function renderPage(
const title = createTitle(siteData, pageData)
const description = pageData.description || siteData.description
const dir = pageData.frontmatter.dir || siteData.dir || 'ltr'
const frontmatterDir = pageData.frontmatter.dir
const dir = frontmatterDir === false ? false : frontmatterDir || siteData.dir
const dirAttr = dir === false ? '' : ` dir="${dir || 'ltr'}"`
const isDefault404 = page === '404.md' && !hasCustom404
// the initial load only needs the lean page js — the static content is
@ -200,7 +202,7 @@ export async function renderPage(
}
const html = `<!DOCTYPE html>
<html lang="${siteData.lang}" dir="${dir}">
<html lang="${siteData.lang}"${dirAttr}>
<head>
<meta charset="utf-8">
${

@ -409,7 +409,7 @@ export async function resolveSiteData(
return {
lang: userConfig.lang || 'en-US',
dir: userConfig.dir || 'ltr',
dir: userConfig.dir === false ? false : userConfig.dir || 'ltr',
title: userConfig.title || 'VitePress',
titleTemplate: userConfig.titleTemplate,
description: userConfig.description || 'A VitePress site',

12
types/shared.d.ts vendored

@ -184,10 +184,11 @@ export interface SiteData<ThemeConfig = any> {
*/
lang: string
/**
* The text direction (`dir` attribute) of the site.
* The text direction (`dir` attribute) of the site. Set to `false` to let
* application code manage the attribute.
* @default 'ltr'
*/
dir: string
dir: string | false
/**
* The title of the site.
* @default 'VitePress'
@ -295,7 +296,7 @@ export interface VitePressData<T = any> {
/**
* The text direction of the active locale.
*/
dir: Ref<string>
dir: Ref<string | false>
/**
* The key of the active locale.
*/
@ -379,9 +380,10 @@ export interface LocaleSpecificConfig<ThemeConfig = any> {
*/
lang?: string
/**
* The text direction of the locale.
* The text direction of the locale. Set to `false` to let application code
* manage the `dir` attribute.
*/
dir?: string
dir?: string | false
/**
* The title of the site in the locale.
*/

Loading…
Cancel
Save