Skip to content

Commit

Permalink
feat: support force-auto as an option for appearance
Browse files Browse the repository at this point in the history
closes #3946
  • Loading branch information
brc-dd committed Jun 9, 2024
1 parent e24899a commit 1e8bb48
Show file tree
Hide file tree
Showing 8 changed files with 50 additions and 14 deletions.
4 changes: 3 additions & 1 deletion docs/reference/site-config.md
Original file line number Diff line number Diff line change
Expand Up @@ -489,14 +489,16 @@ 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).

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

Expand Down
3 changes: 1 addition & 2 deletions src/client/app/data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
9 changes: 8 additions & 1 deletion src/client/theme-default/components/VPNavBarAppearance.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down
20 changes: 17 additions & 3 deletions src/client/theme-default/components/VPNavBarExtra.vue
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,30 @@ 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">
<VPMenuLink :item="locale" />
</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' }}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down
17 changes: 11 additions & 6 deletions src/node/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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')
})()`
])
}

Expand Down
1 change: 1 addition & 0 deletions src/node/siteConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down
1 change: 1 addition & 0 deletions types/shared.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ export interface SiteData<ThemeConfig = any> {
| boolean
| 'dark'
| 'force-dark'
| 'force-auto'
| (Omit<UseDarkOptions, 'initialValue'> & { initialValue?: 'dark' })
themeConfig: ThemeConfig
scrollOffset:
Expand Down

0 comments on commit 1e8bb48

Please sign in to comment.