feat: light/dark modes switch immediately with the system theme (#95)
This commit is contained in:
parent
3f4e7e9f97
commit
c3ac8d9728
|
@ -1,22 +1,52 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import type { LIGHT_DARK_MODE } from '@/types/config.ts'
|
||||||
import Icon from "@iconify/svelte"
|
import {
|
||||||
import {i18n} from '@i18n/translation'
|
AUTO_MODE,
|
||||||
|
DARK_MODE,
|
||||||
|
LIGHT_MODE,
|
||||||
|
} from '@constants/constants.ts'
|
||||||
import I18nKey from '@i18n/i18nKey'
|
import I18nKey from '@i18n/i18nKey'
|
||||||
import {setTheme, getStoredTheme} from '../utils/setting-utils.ts'
|
import { i18n } from '@i18n/translation'
|
||||||
import {onMount} from "svelte";
|
import Icon from '@iconify/svelte'
|
||||||
import {AUTO_MODE, DARK_MODE, LIGHT_MODE} from "@constants/constants.ts";
|
import {
|
||||||
|
applyThemeToDocument,
|
||||||
|
getStoredTheme,
|
||||||
|
setTheme,
|
||||||
|
} from '@utils/setting-utils.ts'
|
||||||
|
import { onMount } from 'svelte'
|
||||||
|
|
||||||
const seq = [LIGHT_MODE, DARK_MODE, AUTO_MODE]
|
const seq: LIGHT_DARK_MODE[] = [
|
||||||
let mode = AUTO_MODE
|
LIGHT_MODE,
|
||||||
|
DARK_MODE,
|
||||||
|
AUTO_MODE,
|
||||||
|
]
|
||||||
|
let mode: LIGHT_DARK_MODE = AUTO_MODE
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
mode = getStoredTheme()
|
mode = getStoredTheme()
|
||||||
|
const darkModePreference = window.matchMedia(
|
||||||
|
'(prefers-color-scheme: dark)',
|
||||||
|
)
|
||||||
|
const changeThemeWhenSchemeChanged: Parameters<
|
||||||
|
typeof darkModePreference.addEventListener<'change'>
|
||||||
|
>[1] = e => {
|
||||||
|
applyThemeToDocument(mode)
|
||||||
|
}
|
||||||
|
darkModePreference.addEventListener(
|
||||||
|
'change',
|
||||||
|
changeThemeWhenSchemeChanged,
|
||||||
|
)
|
||||||
|
return () => {
|
||||||
|
darkModePreference.removeEventListener(
|
||||||
|
'change',
|
||||||
|
changeThemeWhenSchemeChanged,
|
||||||
|
)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
function switchScheme(newMode: string) {
|
function switchScheme(newMode: LIGHT_DARK_MODE) {
|
||||||
mode = newMode
|
mode = newMode
|
||||||
setTheme(newMode)
|
setTheme(newMode)
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleScheme() {
|
function toggleScheme() {
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import type { LIGHT_MODE, DARK_MODE, AUTO_MODE } from "@constants/constants"
|
||||||
|
|
||||||
export type SiteConfig = {
|
export type SiteConfig = {
|
||||||
title: string
|
title: string
|
||||||
subtitle: string
|
subtitle: string
|
||||||
|
@ -17,7 +19,7 @@ export type SiteConfig = {
|
||||||
}
|
}
|
||||||
|
|
||||||
export type Favicon = {
|
export type Favicon = {
|
||||||
src: string,
|
src: string
|
||||||
theme?: 'light' | 'dark'
|
theme?: 'light' | 'dark'
|
||||||
sizes?: string
|
sizes?: string
|
||||||
}
|
}
|
||||||
|
@ -54,3 +56,5 @@ export type LicenseConfig = {
|
||||||
name: string
|
name: string
|
||||||
url: string
|
url: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type LIGHT_DARK_MODE = typeof LIGHT_MODE | typeof DARK_MODE | typeof AUTO_MODE
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import {AUTO_MODE, DARK_MODE, DEFAULT_THEME, LIGHT_MODE} from "@constants/constants.ts";
|
import {AUTO_MODE, DARK_MODE, DEFAULT_THEME, LIGHT_MODE} from "@constants/constants.ts";
|
||||||
|
import type { LIGHT_DARK_MODE } from '@/types/config'
|
||||||
|
|
||||||
export function getDefaultHue(): number {
|
export function getDefaultHue(): number {
|
||||||
const fallback = '250'
|
const fallback = '250'
|
||||||
|
@ -20,25 +21,30 @@ export function setHue(hue: number): void {
|
||||||
r.style.setProperty('--hue', hue)
|
r.style.setProperty('--hue', hue)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function setTheme(theme: string): void {
|
|
||||||
localStorage.setItem('theme', theme)
|
export function applyThemeToDocument(theme: LIGHT_DARK_MODE) {
|
||||||
switch (theme) {
|
switch (theme) {
|
||||||
case LIGHT_MODE:
|
case LIGHT_MODE:
|
||||||
document.documentElement.classList.remove('dark');
|
document.documentElement.classList.remove('dark')
|
||||||
break
|
break
|
||||||
case DARK_MODE:
|
case DARK_MODE:
|
||||||
document.documentElement.classList.add('dark');
|
document.documentElement.classList.add('dark')
|
||||||
break
|
break
|
||||||
case AUTO_MODE:
|
case AUTO_MODE:
|
||||||
if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
|
if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
|
||||||
document.documentElement.classList.add('dark');
|
document.documentElement.classList.add('dark')
|
||||||
} else {
|
} else {
|
||||||
document.documentElement.classList.remove('dark');
|
document.documentElement.classList.remove('dark')
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getStoredTheme(): string {
|
export function setTheme(theme: LIGHT_DARK_MODE): void {
|
||||||
return localStorage.getItem('theme') || DEFAULT_THEME
|
localStorage.setItem('theme', theme)
|
||||||
|
applyThemeToDocument(theme)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getStoredTheme(): LIGHT_DARK_MODE {
|
||||||
|
return localStorage.getItem('theme') as LIGHT_DARK_MODE || DEFAULT_THEME
|
||||||
}
|
}
|
Loading…
Reference in New Issue