adding a dark mode toggle for Vue
This commit is contained in:
parent
a14e1b20c0
commit
78bb0f72d5
81
src/resources/js/Components/DarkModeToggle.vue
Normal file
81
src/resources/js/Components/DarkModeToggle.vue
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
<script setup>
|
||||||
|
import { reactive, computed, onBeforeMount, provide } from 'vue'
|
||||||
|
|
||||||
|
const emit = defineEmits(['themeUpdate'])
|
||||||
|
|
||||||
|
let settings = reactive({
|
||||||
|
theme: 'light',
|
||||||
|
})
|
||||||
|
|
||||||
|
const htmlNode = document.documentElement
|
||||||
|
let mediaQuery = window.matchMedia('(prefers-color-scheme: dark)')
|
||||||
|
|
||||||
|
// computed properties
|
||||||
|
const isDarkMode = computed(() => {
|
||||||
|
return settings.theme === 'dark'
|
||||||
|
})
|
||||||
|
|
||||||
|
const isLightMode = computed(() => {
|
||||||
|
return settings.theme === 'light'
|
||||||
|
})
|
||||||
|
|
||||||
|
// lifecycle hooks
|
||||||
|
onBeforeMount(() => {
|
||||||
|
window.addEventListener('storage', update)
|
||||||
|
|
||||||
|
if (mediaQuery?.addEventListener) {
|
||||||
|
mediaQuery.addEventListener('change', update)
|
||||||
|
}
|
||||||
|
|
||||||
|
update()
|
||||||
|
})
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
provide('darkMode', isDarkMode)
|
||||||
|
})
|
||||||
|
|
||||||
|
// methods
|
||||||
|
const update = () => {
|
||||||
|
if (localStorage.theme === 'dark' || (!('theme' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
|
||||||
|
setModeDark()
|
||||||
|
} else {
|
||||||
|
setModeLight()
|
||||||
|
}
|
||||||
|
|
||||||
|
emit('themeUpdate')
|
||||||
|
}
|
||||||
|
|
||||||
|
const setModeDark = () => {
|
||||||
|
settings.theme = 'dark'
|
||||||
|
localStorage.theme = 'dark'
|
||||||
|
htmlNode.classList.remove('light')
|
||||||
|
htmlNode.classList.add('dark')
|
||||||
|
}
|
||||||
|
|
||||||
|
const setModeLight = () => {
|
||||||
|
settings.theme = 'light'
|
||||||
|
localStorage.theme = 'light'
|
||||||
|
htmlNode.classList.remove('dark')
|
||||||
|
htmlNode.classList.add('light')
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="flex items-center cursor-pointer">
|
||||||
|
<svg v-show="isDarkMode" @click="setModeLight" viewBox="0 0 24 24" width="24" height="24" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round" preserveAspectRatio="xMidYMid meet">
|
||||||
|
<circle cx="12" cy="12" r="5"></circle>
|
||||||
|
<line x1="12" y1="1" x2="12" y2="3"></line>
|
||||||
|
<line x1="12" y1="21" x2="12" y2="23"></line>
|
||||||
|
<line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line>
|
||||||
|
<line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line>
|
||||||
|
<line x1="1" y1="12" x2="3" y2="12"></line>
|
||||||
|
<line x1="21" y1="12" x2="23" y2="12"></line>
|
||||||
|
<line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line>
|
||||||
|
<line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line>
|
||||||
|
</svg>
|
||||||
|
|
||||||
|
<svg v-show="isLightMode" @click="setModeDark" viewBox="0 0 24 24" width="24" height="24" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round" preserveAspectRatio="xMidYMid meet">
|
||||||
|
<path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"></path>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
</template>
|
Loading…
x
Reference in New Issue
Block a user