Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(theme): allow defining dark as the default theme #1498

Merged
merged 4 commits into from
Oct 18, 2022
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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