77 lines
2.3 KiB
JavaScript
77 lines
2.3 KiB
JavaScript
/* eslint-disable @typescript-eslint/strict-boolean-expressions */
|
|
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
|
import { ref, readonly, onBeforeMount, onBeforeUnmount } from 'vue';
|
|
import { hasInstance } from './utils';
|
|
let usedCount = 0;
|
|
// Mql means media query list
|
|
const supportMatchMedia = typeof window !== 'undefined' && window.matchMedia !== undefined;
|
|
const osTheme = ref(null);
|
|
let darkMql;
|
|
let lightMql;
|
|
function handleDarkMqlChange(e) {
|
|
if (e.matches) {
|
|
osTheme.value = 'dark';
|
|
}
|
|
}
|
|
function handleLightMqlChange(e) {
|
|
if (e.matches) {
|
|
osTheme.value = 'light';
|
|
}
|
|
}
|
|
function init() {
|
|
darkMql = window.matchMedia('(prefers-color-scheme: dark)');
|
|
lightMql = window.matchMedia('(prefers-color-scheme: light)');
|
|
if (darkMql.matches) {
|
|
osTheme.value = 'dark';
|
|
}
|
|
else if (lightMql.matches) {
|
|
osTheme.value = 'light';
|
|
}
|
|
else {
|
|
osTheme.value = null;
|
|
}
|
|
if (darkMql.addEventListener) {
|
|
darkMql.addEventListener('change', handleDarkMqlChange);
|
|
lightMql.addEventListener('change', handleLightMqlChange);
|
|
}
|
|
else if (darkMql.addListener) {
|
|
darkMql.addListener(handleDarkMqlChange);
|
|
lightMql.addListener(handleLightMqlChange);
|
|
}
|
|
}
|
|
function clean() {
|
|
if ('removeEventListener' in darkMql) {
|
|
darkMql.removeEventListener('change', handleDarkMqlChange);
|
|
lightMql.removeEventListener('change', handleLightMqlChange);
|
|
}
|
|
else if ('removeListener' in darkMql) {
|
|
darkMql.removeListener(handleDarkMqlChange);
|
|
lightMql.removeListener(handleLightMqlChange);
|
|
}
|
|
darkMql = undefined;
|
|
lightMql = undefined;
|
|
}
|
|
let managable = true;
|
|
export default function useOsTheme() {
|
|
/* istanbul ignore next */
|
|
if (process.env.NODE_ENV !== 'test' && !supportMatchMedia) {
|
|
return readonly(osTheme);
|
|
}
|
|
if (process.env.NODE_ENV === 'test' && window.matchMedia === undefined) {
|
|
return readonly(osTheme);
|
|
}
|
|
if (usedCount === 0)
|
|
init();
|
|
if (managable && (managable = hasInstance())) {
|
|
onBeforeMount(() => {
|
|
usedCount += 1;
|
|
});
|
|
onBeforeUnmount(() => {
|
|
usedCount -= 1;
|
|
if (usedCount === 0)
|
|
clean();
|
|
});
|
|
}
|
|
return readonly(osTheme);
|
|
}
|