feat: support `force-auto` as an option for appearance

closes #3946
pull/3291/head
Divyansh Singh 3 weeks ago
parent e24899a073
commit 1e8bb48bc2

@ -489,7 +489,7 @@ When set to `true`, the production app will be built in [MPA Mode](../guide/mpa-
### appearance
- Type: `boolean | 'dark' | 'force-dark' | import('@vueuse/core').UseDarkOptions`
- Type: `boolean | 'dark' | 'force-dark' | 'force-auto' | import('@vueuse/core').UseDarkOptions`
- Default: `true`
Whether to enable dark mode (by adding the `.dark` class to the `<html>` element).
@ -497,6 +497,8 @@ Whether to enable dark mode (by adding the `.dark` class to the `<html>` element
- If the option is set to `true`, the default theme will be determined by the user's preferred color scheme.
- If the option is set to `dark`, the theme will be dark by default, unless the user manually toggles it.
- If the option is set to `false`, users will not be able to toggle the theme.
- If the option is set to `'force-dark'`, the theme will always be dark and users will not be able to toggle it.
- If the option is set to `'force-auto'`, the theme will always be determined by the user's preferred color scheme and users will not be able to toggle it.
This option injects an inline script that restores users settings from local storage using the `vitepress-theme-appearance` key. This ensures the `.dark` class is applied before the page is rendered to avoid flickering.

@ -82,8 +82,7 @@ export function initData(route: Route): VitePressData {
: appearance
? useDark({
storageKey: APPEARANCE_KEY,
initialValue: () =>
typeof appearance === 'string' ? appearance : 'auto',
initialValue: () => (appearance === 'dark' ? 'dark' : 'auto'),
...(typeof appearance === 'object' ? appearance : {})
})
: ref(false)

@ -6,7 +6,14 @@ const { site } = useData()
</script>
<template>
<div v-if="site.appearance && site.appearance !== 'force-dark'" class="VPNavBarAppearance">
<div
v-if="
site.appearance &&
site.appearance !== 'force-dark' &&
site.appearance !== 'force-auto'
"
class="VPNavBarAppearance"
>
<VPSwitchAppearance />
</div>
</template>

@ -19,8 +19,15 @@ const hasExtraContent = computed(
</script>
<template>
<VPFlyout v-if="hasExtraContent" class="VPNavBarExtra" label="extra navigation">
<div v-if="localeLinks.length && currentLang.label" class="group translations">
<VPFlyout
v-if="hasExtraContent"
class="VPNavBarExtra"
label="extra navigation"
>
<div
v-if="localeLinks.length && currentLang.label"
class="group translations"
>
<p class="trans-title">{{ currentLang.label }}</p>
<template v-for="locale in localeLinks" :key="locale.link">
@ -28,7 +35,14 @@ const hasExtraContent = computed(
</template>
</div>
<div v-if="site.appearance && site.appearance !== 'force-dark'" class="group">
<div
v-if="
site.appearance &&
site.appearance !== 'force-dark' &&
site.appearance !== 'force-auto'
"
class="group"
>
<div class="item appearance">
<p class="label">
{{ theme.darkModeSwitchLabel || 'Appearance' }}

@ -6,7 +6,14 @@ const { site, theme } = useData()
</script>
<template>
<div v-if="site.appearance && site.appearance !== 'force-dark'" class="VPNavScreenAppearance">
<div
v-if="
site.appearance &&
site.appearance !== 'force-dark' &&
site.appearance !== 'force-auto'
"
class="VPNavScreenAppearance"
>
<p class="text">
{{ theme.darkModeSwitchLabel || 'Appearance' }}
</p>

@ -278,12 +278,17 @@ function resolveSiteDataHead(userConfig?: UserConfig): HeadConfig[] {
{ id: 'check-dark-mode' },
fallbackPreference === 'force-dark'
? `document.documentElement.classList.add('dark')`
: `;(() => {
const preference = localStorage.getItem('${APPEARANCE_KEY}') || '${fallbackPreference}'
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches
if (!preference || preference === 'auto' ? prefersDark : preference === 'dark')
document.documentElement.classList.add('dark')
})()`
: fallbackPreference === 'force-auto'
? `;(() => {
if (window.matchMedia('(prefers-color-scheme: dark)').matches)
document.documentElement.classList.add('dark')
})()`
: `;(() => {
const preference = localStorage.getItem('${APPEARANCE_KEY}') || '${fallbackPreference}'
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches
if (!preference || preference === 'auto' ? prefersDark : preference === 'dark')
document.documentElement.classList.add('dark')
})()`
])
}

@ -77,6 +77,7 @@ export interface UserConfig<ThemeConfig = any>
| boolean
| 'dark'
| 'force-dark'
| 'force-auto'
| (Omit<UseDarkOptions, 'initialValue'> & { initialValue?: 'dark' })
lastUpdated?: boolean
contentProps?: Record<string, any>

1
types/shared.d.ts vendored

@ -120,6 +120,7 @@ export interface SiteData<ThemeConfig = any> {
| boolean
| 'dark'
| 'force-dark'
| 'force-auto'
| (Omit<UseDarkOptions, 'initialValue'> & { initialValue?: 'dark' })
themeConfig: ThemeConfig
scrollOffset:

Loading…
Cancel
Save