mirror of https://github.com/buster-so/buster.git
58 lines
1.7 KiB
TypeScript
58 lines
1.7 KiB
TypeScript
'use client';
|
|
|
|
import { ENABLE_DARK_MODE } from '@/context/BusterStyles/BusterStyles';
|
|
import { useMemoizedFn } from 'ahooks';
|
|
import { useEffect, useLayoutEffect, useState } from 'react';
|
|
import { isServer } from '@tanstack/react-query';
|
|
|
|
const DARK_MODE_MEDIA = '(prefers-color-scheme: dark)';
|
|
|
|
export const useThemeDetector = ({ addDarkClass }: { addDarkClass?: boolean }) => {
|
|
const [isDarkTheme, setIsDarkTheme] = useState(() => getSystemTheme());
|
|
|
|
const getSystemTheme = (e?: MediaQueryList | MediaQueryListEvent) => {
|
|
if (!ENABLE_DARK_MODE) return false;
|
|
if (isServer) return false;
|
|
if (!e) e = window.matchMedia(DARK_MODE_MEDIA);
|
|
const isDark = e.matches;
|
|
return isDark;
|
|
};
|
|
|
|
const getCurrentTheme = useMemoizedFn(() => {
|
|
if (!isServer) {
|
|
document.documentElement.style.display = 'none';
|
|
|
|
const isDarkMode = getSystemTheme();
|
|
|
|
if (addDarkClass) {
|
|
const d = document.documentElement;
|
|
d.classList.toggle('dark', isDarkMode);
|
|
d.classList.toggle('bg-black', isDarkMode);
|
|
d.setAttribute('data-color-scheme', !isDarkMode ? 'light' : 'dark');
|
|
}
|
|
|
|
// trigger reflow so that overflow style is applied
|
|
document.documentElement.style.display = '';
|
|
|
|
return isDarkMode;
|
|
}
|
|
return false;
|
|
});
|
|
|
|
const mqListener = useMemoizedFn(() => {
|
|
setIsDarkTheme(getCurrentTheme());
|
|
});
|
|
|
|
useEffect(() => {
|
|
const darkThemeMq = window.matchMedia(DARK_MODE_MEDIA);
|
|
darkThemeMq.addEventListener('change', mqListener);
|
|
return () => darkThemeMq.removeEventListener('change', mqListener);
|
|
}, []);
|
|
|
|
useLayoutEffect(() => {
|
|
setIsDarkTheme(getCurrentTheme());
|
|
}, []);
|
|
|
|
return isDarkTheme;
|
|
};
|