diff --git a/docs/reference/site-config.md b/docs/reference/site-config.md index 1bc97b92..4fbffae7 100644 --- a/docs/reference/site-config.md +++ b/docs/reference/site-config.md @@ -426,7 +426,7 @@ When set to `true`, the production app will be built in [MPA Mode](../guide/mpa- ### appearance -- Type: `boolean | 'dark'` +- Type: `boolean | 'dark' | import('@vueuse/core').UseDarkOptions` - Default: `true` Whether to enable dark mode (by adding the `.dark` class to the `` element). @@ -437,6 +437,8 @@ Whether to enable dark mode (by adding the `.dark` class to the `` element 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. +`appearance.initialValue` can only be `'dark' | undefined`. Refs or getters are not supported. + ### lastUpdated - Type: `boolean` diff --git a/src/client/app/data.ts b/src/client/app/data.ts index d6d3efa3..b75f2611 100644 --- a/src/client/app/data.ts +++ b/src/client/app/data.ts @@ -1,20 +1,22 @@ +import siteData from '@siteData' +import { useDark } from '@vueuse/core' import { - type InjectionKey, - type Ref, computed, inject, readonly, ref, - shallowRef + shallowRef, + type InjectionKey, + type Ref } from 'vue' -import type { Route } from './router' -import siteData from '@siteData' import { - type PageData, - type SiteData, + APPEARANCE_KEY, + createTitle, resolveSiteDataByRoute, - createTitle + type PageData, + type SiteData } from '../shared' +import type { Route } from './router' export const dataSymbol: InjectionKey = Symbol() @@ -67,6 +69,19 @@ export function initData(route: Route): VitePressData { resolveSiteDataByRoute(siteDataRef.value, route.data.relativePath) ) + const isDark = site.value.appearance + ? useDark({ + storageKey: APPEARANCE_KEY, + initialValue: () => + typeof site.value.appearance === 'string' + ? site.value.appearance + : 'auto', + ...(typeof site.value.appearance === 'object' + ? site.value.appearance + : {}) + }) + : ref(false) + return { site, theme: computed(() => site.value.themeConfig), @@ -82,7 +97,7 @@ export function initData(route: Route): VitePressData { description: computed(() => { return route.data.description || site.value.description }), - isDark: ref(false) + isDark } } diff --git a/src/client/theme-default/components/VPSwitch.vue b/src/client/theme-default/components/VPSwitch.vue index 71fd33eb..db51312f 100644 --- a/src/client/theme-default/components/VPSwitch.vue +++ b/src/client/theme-default/components/VPSwitch.vue @@ -18,7 +18,7 @@ flex-shrink: 0; border: 1px solid var(--vp-input-border-color); background-color: var(--vp-input-switch-bg-color); - transition: border-color 0.25s; + transition: border-color 0.25s !important; } .VPSwitch:hover { @@ -35,7 +35,7 @@ border-radius: 50%; background-color: var(--vp-c-neutral-inverse); box-shadow: var(--vp-shadow-1); - transition: transform 0.25s; + transition: transform 0.25s !important; } .icon { @@ -58,6 +58,6 @@ .dark .icon :deep(svg) { fill: var(--vp-c-text-1); - transition: opacity 0.25s; + transition: opacity 0.25s !important; } diff --git a/src/client/theme-default/components/VPSwitchAppearance.vue b/src/client/theme-default/components/VPSwitchAppearance.vue index 1a9f06c4..ee9ecedc 100644 --- a/src/client/theme-default/components/VPSwitchAppearance.vue +++ b/src/client/theme-default/components/VPSwitchAppearance.vue @@ -1,85 +1,18 @@