test/node_modules/@vuepress/theme-default/lib/client/composables/useDarkMode.js
2024-08-13 09:27:52 +08:00

59 lines
2.0 KiB
JavaScript

import { useThemeLocaleData } from '@theme/useThemeData';
import { usePreferredDark, useStorage } from '@vueuse/core';
import { computed, inject, onMounted, onUnmounted, provide, watch } from 'vue';
export const darkModeSymbol = Symbol(__VUEPRESS_DEV__ ? 'darkMode' : '');
const applyDarkmodeToHTML = (isDarkMode) => {
const update = (value = isDarkMode.value) => {
// set `class="dark"` on `<html>` element
const el = window.document.documentElement;
el.classList.toggle('dark', value);
el.dataset.theme = value ? 'dark' : 'light';
};
onMounted(() => {
watch(isDarkMode, update, { immediate: true });
});
onUnmounted(() => update());
};
/**
* Inject dark mode global computed
*/
export const useDarkMode = () => {
const isDarkMode = inject(darkModeSymbol);
if (!isDarkMode) {
throw new Error('useDarkMode() is called without provider.');
}
return isDarkMode;
};
/**
* Create dark mode ref and provide as global computed in setup
*/
export const setupDarkMode = () => {
const themeLocale = useThemeLocaleData();
const isDarkPreferred = usePreferredDark();
const darkStorage = useStorage('vuepress-color-scheme', themeLocale.value.colorMode);
const isDarkMode = computed({
get() {
// disable color mode switching
if (!themeLocale.value.colorModeSwitch) {
return themeLocale.value.colorMode === 'dark';
}
// auto detected from prefers-color-scheme
if (darkStorage.value === 'auto') {
return isDarkPreferred.value;
}
// storage value
return darkStorage.value === 'dark';
},
set(val) {
if (val === isDarkPreferred.value) {
darkStorage.value = 'auto';
}
else {
darkStorage.value = val ? 'dark' : 'light';
}
},
});
provide(darkModeSymbol, isDarkMode);
applyDarkmodeToHTML(isDarkMode);
};