Skip to content

Commit d404753

Browse files
innocenzibrc-dd
andauthored
feat(theme): allow defining dark as the default theme (#1498)
Co-authored-by: Divyansh Singh <40380293+brc-dd@users.noreply.github.com>
1 parent dac59a8 commit d404753

File tree

4 files changed

+26
-13
lines changed

4 files changed

+26
-13
lines changed

docs/config/app-configs.md

+7-3
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,14 @@ export default {
1414

1515
## appearance
1616

17-
- Type: `boolean`
17+
- Type: `boolean | 'dark'`
1818
- Default: `true`
1919

20-
Whether to enable "Dark Mode" or not. If the option is set to `true`, it adds `.dark` class to the `<html>` tag depending on the users preference.
20+
Whether to enable dark mode or not.
21+
22+
- If the option is set to `true`, the default theme will be determined by the user's preferred color scheme.
23+
- If the option is set to `dark`, the theme will be dark by default, unless the user manually toggles it.
24+
- If the option is set to `false`, users will not be able to toggle the theme.
2125

2226
It also injects inline script that tries to read users settings from local storage by `vitepress-theme-appearance` key and restores users preferred color mode.
2327

@@ -199,7 +203,7 @@ export default {
199203
- Type: `string`
200204
- Default: `.`
201205

202-
The directory where your markdown pages are stored, relative to project root.
206+
The directory where your markdown pages are stored, relative to project root.
203207

204208
```ts
205209
export default {

src/client/theme-default/components/VPSwitchAppearance.vue

+8-4
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
<script lang="ts" setup>
22
import { ref, onMounted } from 'vue'
3+
import { useData } from 'vitepress'
34
import { APPEARANCE_KEY } from '../../shared.js'
45
import VPSwitch from './VPSwitch.vue'
56
import VPIconSun from './icons/VPIconSun.vue'
67
import VPIconMoon from './icons/VPIconMoon.vue'
78
9+
const { site } = useData()
810
const checked = ref(false)
911
const toggle = typeof localStorage !== 'undefined' ? useAppearance() : () => {}
1012
@@ -16,11 +18,13 @@ function useAppearance() {
1618
const query = window.matchMedia('(prefers-color-scheme: dark)')
1719
const classList = document.documentElement.classList
1820
19-
let userPreference = localStorage.getItem(APPEARANCE_KEY) || 'auto'
21+
let userPreference =
22+
localStorage.getItem(APPEARANCE_KEY) || site.value.appearance !== true
23+
? site.value.appearance
24+
: 'auto'
2025
21-
let isDark = userPreference === 'auto'
22-
? query.matches
23-
: userPreference === 'dark'
26+
let isDark =
27+
userPreference === 'auto' ? query.matches : userPreference === 'dark'
2428
2529
query.onchange = (e) => {
2630
if (userPreference === 'auto') {

src/node/config.ts

+10-5
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ export interface UserConfig<ThemeConfig = any> {
3636
titleTemplate?: string | boolean
3737
description?: string
3838
head?: HeadConfig[]
39-
appearance?: boolean
39+
appearance?: boolean | 'dark'
4040
themeConfig?: ThemeConfig
4141
locales?: Record<string, LocaleConfig>
4242
markdown?: MarkdownOptions
@@ -332,16 +332,21 @@ function resolveSiteDataHead(userConfig?: UserConfig): HeadConfig[] {
332332
const head = userConfig?.head ?? []
333333

334334
// add inline script to apply dark mode, if user enables the feature.
335-
// this is required to prevent "flush" on initial page load.
335+
// this is required to prevent "flash" on initial page load.
336336
if (userConfig?.appearance ?? true) {
337+
// if appearance mode set to light or dark, default to the defined mode
338+
// in case the user didn't specify a preference - otherwise, default to auto
339+
const fallbackPreference =
340+
userConfig?.appearance !== true ? userConfig?.appearance ?? '' : 'auto'
341+
337342
head.push([
338343
'script',
339344
{ id: 'check-dark-light' },
340345
`
341346
;(() => {
342-
const saved = localStorage.getItem('${APPEARANCE_KEY}')
343-
const prefereDark = window.matchMedia('(prefers-color-scheme: dark)').matches
344-
if (!saved || saved === 'auto' ? prefereDark : saved === 'dark') {
347+
const preference = localStorage.getItem('${APPEARANCE_KEY}') || '${fallbackPreference}'
348+
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches
349+
if (!preference || preference === 'auto' ? prefersDark : preference === 'dark') {
345350
document.documentElement.classList.add('dark')
346351
}
347352
})()

types/shared.d.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ export interface SiteData<ThemeConfig = any> {
6262
titleTemplate?: string | boolean
6363
description: string
6464
head: HeadConfig[]
65-
appearance: boolean
65+
appearance: boolean | 'dark'
6666
themeConfig: ThemeConfig
6767
scrollOffset: number | string
6868
locales: Record<string, LocaleConfig>

0 commit comments

Comments
 (0)