Skip to content

Commit

Permalink
feat(theme): allow defining dark as the default theme (#1498)
Browse files Browse the repository at this point in the history
Co-authored-by: Divyansh Singh <[email protected]>
  • Loading branch information
innocenzi and brc-dd authored Oct 18, 2022
1 parent dac59a8 commit d404753
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 13 deletions.
10 changes: 7 additions & 3 deletions docs/config/app-configs.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,14 @@ export default {

## appearance

- Type: `boolean`
- Type: `boolean | 'dark'`
- Default: `true`

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.
Whether to enable dark mode or not.

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

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.

Expand Down Expand Up @@ -199,7 +203,7 @@ export default {
- Type: `string`
- Default: `.`

The directory where your markdown pages are stored, relative to project root.
The directory where your markdown pages are stored, relative to project root.

```ts
export default {
Expand Down
12 changes: 8 additions & 4 deletions src/client/theme-default/components/VPSwitchAppearance.vue
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
<script lang="ts" setup>
import { ref, onMounted } from 'vue'
import { useData } from 'vitepress'
import { APPEARANCE_KEY } from '../../shared.js'
import VPSwitch from './VPSwitch.vue'
import VPIconSun from './icons/VPIconSun.vue'
import VPIconMoon from './icons/VPIconMoon.vue'
const { site } = useData()
const checked = ref(false)
const toggle = typeof localStorage !== 'undefined' ? useAppearance() : () => {}
Expand All @@ -16,11 +18,13 @@ function useAppearance() {
const query = window.matchMedia('(prefers-color-scheme: dark)')
const classList = document.documentElement.classList
let userPreference = localStorage.getItem(APPEARANCE_KEY) || 'auto'
let userPreference =
localStorage.getItem(APPEARANCE_KEY) || site.value.appearance !== true
? site.value.appearance
: 'auto'
let isDark = userPreference === 'auto'
? query.matches
: userPreference === 'dark'
let isDark =
userPreference === 'auto' ? query.matches : userPreference === 'dark'
query.onchange = (e) => {
if (userPreference === 'auto') {
Expand Down
15 changes: 10 additions & 5 deletions src/node/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export interface UserConfig<ThemeConfig = any> {
titleTemplate?: string | boolean
description?: string
head?: HeadConfig[]
appearance?: boolean
appearance?: boolean | 'dark'
themeConfig?: ThemeConfig
locales?: Record<string, LocaleConfig>
markdown?: MarkdownOptions
Expand Down Expand Up @@ -332,16 +332,21 @@ function resolveSiteDataHead(userConfig?: UserConfig): HeadConfig[] {
const head = userConfig?.head ?? []

// add inline script to apply dark mode, if user enables the feature.
// this is required to prevent "flush" on initial page load.
// this is required to prevent "flash" on initial page load.
if (userConfig?.appearance ?? true) {
// if appearance mode set to light or dark, default to the defined mode
// in case the user didn't specify a preference - otherwise, default to auto
const fallbackPreference =
userConfig?.appearance !== true ? userConfig?.appearance ?? '' : 'auto'

head.push([
'script',
{ id: 'check-dark-light' },
`
;(() => {
const saved = localStorage.getItem('${APPEARANCE_KEY}')
const prefereDark = window.matchMedia('(prefers-color-scheme: dark)').matches
if (!saved || saved === 'auto' ? prefereDark : saved === '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
2 changes: 1 addition & 1 deletion types/shared.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ export interface SiteData<ThemeConfig = any> {
titleTemplate?: string | boolean
description: string
head: HeadConfig[]
appearance: boolean
appearance: boolean | 'dark'
themeConfig: ThemeConfig
scrollOffset: number | string
locales: Record<string, LocaleConfig>
Expand Down

0 comments on commit d404753

Please sign in to comment.