feat(theme): allow forcing dark mode (#2974)

pull/2975/head
Divyansh Singh 1 year ago committed by GitHub
parent a18e5e48a4
commit 1fb5d228a2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -426,7 +426,7 @@ When set to `true`, the production app will be built in [MPA Mode](../guide/mpa-
### appearance ### appearance
- Type: `boolean | 'dark' | import('@vueuse/core').UseDarkOptions` - Type: `boolean | 'dark' | 'force-dark' | import('@vueuse/core').UseDarkOptions`
- Default: `true` - Default: `true`
Whether to enable dark mode (by adding the `.dark` class to the `<html>` element). Whether to enable dark mode (by adding the `.dark` class to the `<html>` element).

@ -69,18 +69,18 @@ export function initData(route: Route): VitePressData {
resolveSiteDataByRoute(siteDataRef.value, route.data.relativePath) resolveSiteDataByRoute(siteDataRef.value, route.data.relativePath)
) )
const isDark = site.value.appearance const appearance = site.value.appearance // fine with reactivity being lost here, config change triggers a restart
? useDark({ const isDark =
storageKey: APPEARANCE_KEY, appearance === 'force-dark'
initialValue: () => ? ref(true)
typeof site.value.appearance === 'string' : appearance
? site.value.appearance ? useDark({
: 'auto', storageKey: APPEARANCE_KEY,
...(typeof site.value.appearance === 'object' initialValue: () =>
? site.value.appearance typeof appearance === 'string' ? appearance : 'auto',
: {}) ...(typeof appearance === 'object' ? appearance : {})
}) })
: ref(false) : ref(false)
return { return {
site, site,

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

@ -255,24 +255,25 @@ function resolveSiteDataHead(userConfig?: UserConfig): HeadConfig[] {
? userConfig.appearance.initialValue ?? 'auto' ? userConfig.appearance.initialValue ?? 'auto'
: 'auto' : 'auto'
head.push( head.push([
[ 'script',
'script', { id: 'check-dark-mode' },
{ id: 'check-dark-light' }, fallbackPreference === 'force-dark'
`;(() => { ? `document.documentElement.classList.add('dark')`
const preference = localStorage.getItem('${APPEARANCE_KEY}') || '${fallbackPreference}' : `;(() => {
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches const preference = localStorage.getItem('${APPEARANCE_KEY}') || '${fallbackPreference}'
if (!preference || preference === 'auto' ? prefersDark : preference === 'dark') const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches
document.documentElement.classList.add('dark') if (!preference || preference === 'auto' ? prefersDark : preference === 'dark')
})()` document.documentElement.classList.add('dark')
], })()`
[ ])
'script',
{ id: 'check-mac-os' },
`document.documentElement.classList.toggle('mac', /Mac|iPhone|iPod|iPad/i.test(navigator.platform))`
]
)
} }
head.push([
'script',
{ id: 'check-mac-os' },
`document.documentElement.classList.toggle('mac', /Mac|iPhone|iPod|iPad/i.test(navigator.platform))`
])
return head return head
} }

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

1
types/shared.d.ts vendored

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

Loading…
Cancel
Save