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