@ -1,85 +1,18 @@
< script lang = "ts" setup >
import { ref , onMounted , watch } from 'vue'
import { useData } from '../composables/data'
import { inBrowser , APPEARANCE _KEY } from '../../shared'
import VPSwitch from './VPSwitch.vue'
import VPIconSun from './icons/VPIconSun.vue'
import VPIconMoon from './icons/VPIconMoon.vue'
import VPIconSun from './icons/VPIconSun.vue'
const { site , isDark } = useData ( )
const checked = ref ( false )
const toggle = inBrowser ? useAppearance ( ) : ( ) => { }
onMounted ( ( ) => {
checked . value = document . documentElement . classList . contains ( 'dark' )
} )
function useAppearance ( ) {
const query = window . matchMedia ( '(prefers-color-scheme: dark)' )
const classList = document . documentElement . classList
let userPreference = localStorage . getItem ( APPEARANCE _KEY )
let isDark =
( site . value . appearance === 'dark' && userPreference == null ) ||
( userPreference === 'auto' || userPreference == null
? query . matches
: userPreference === 'dark' )
query . onchange = ( e ) => {
if ( userPreference === 'auto' ) {
setClass ( ( isDark = e . matches ) )
}
}
function toggle ( ) {
setClass ( ( isDark = ! isDark ) )
userPreference = isDark
? query . matches ? 'auto' : 'dark'
: query . matches ? 'light' : 'auto'
localStorage . setItem ( APPEARANCE _KEY , userPreference )
}
function setClass ( dark : boolean ) : void {
const css = document . createElement ( 'style' )
css . type = 'text/css'
css . appendChild (
document . createTextNode (
` :not(.VPSwitchAppearance):not(.VPSwitchAppearance *) {
- webkit - transition : none ! important ;
- moz - transition : none ! important ;
- o - transition : none ! important ;
- ms - transition : none ! important ;
transition : none ! important ;
} `
)
)
document . head . appendChild ( css )
checked . value = dark
classList [ dark ? 'add' : 'remove' ] ( 'dark' )
/ / @ t s - e x p e c t - e r r o r k e e p u n u s e d d e c l a r a t i o n , u s e d t o f o r c e t h e b r o w s e r t o r e d r a w
const _ = window . getComputedStyle ( css ) . opacity
document . head . removeChild ( css )
}
return toggle
}
watch ( checked , ( newIsDark ) => {
isDark . value = newIsDark
} )
const { isDark } = useData ( )
< / script >
< template >
< VPSwitch
title = "toggle dark mode"
class = "VPSwitchAppearance"
: aria - checked = " checked "
@ click = " toggle "
: aria - checked = "isDark"
@ click = "isDark = !isDark"
>
< VPIconSun class = "sun" / >
< VPIconMoon class = "moon" / >