mirror of
https://gitee.com/element-plus/element-plus.git
synced 2024-12-14 17:31:02 +08:00
48 lines
1.3 KiB
TypeScript
48 lines
1.3 KiB
TypeScript
|
import { NOOP } from '@vue/shared'
|
||
|
import { useFeatureFlag } from './feature-flag'
|
||
|
import { isServer } from '../utils'
|
||
|
|
||
|
const THEME_KEY = 'preferred_theme'
|
||
|
const PREFER_SYSTEM = 'system'
|
||
|
|
||
|
export const useTheme = () => {
|
||
|
const themeEnabled = useFeatureFlag('theme')
|
||
|
if (isServer || !themeEnabled.value) return NOOP
|
||
|
|
||
|
const cachedPreference = localStorage.getItem(THEME_KEY) || PREFER_SYSTEM
|
||
|
// refer to https://css-tricks.com/dark-modes-with-css/
|
||
|
const systemPreference = window.matchMedia('(prefers-color-scheme: dark)')
|
||
|
|
||
|
const rootElement = document.documentElement
|
||
|
|
||
|
let preferredDark = cachedPreference
|
||
|
? cachedPreference === 'dark'
|
||
|
: systemPreference.matches
|
||
|
|
||
|
systemPreference.addEventListener('change', (e: MediaQueryListEvent) => {
|
||
|
if (localStorage.getItem(THEME_KEY) === PREFER_SYSTEM) {
|
||
|
updateTheme((preferredDark = e.matches))
|
||
|
}
|
||
|
})
|
||
|
|
||
|
function updateTheme(preferredDark: boolean) {
|
||
|
rootElement.classList[preferredDark ? 'add' : 'remove']('dark')
|
||
|
}
|
||
|
|
||
|
// toggler
|
||
|
return () => {
|
||
|
updateTheme((preferredDark = !preferredDark))
|
||
|
|
||
|
localStorage.setItem(
|
||
|
THEME_KEY,
|
||
|
preferredDark
|
||
|
? systemPreference.matches
|
||
|
? PREFER_SYSTEM
|
||
|
: 'dark'
|
||
|
: systemPreference.matches
|
||
|
? 'light'
|
||
|
: PREFER_SYSTEM
|
||
|
)
|
||
|
}
|
||
|
}
|