Files
vega-frontend-monorepo/libs/react-helpers/src/hooks/use-theme.ts
T

64 lines
1.4 KiB
TypeScript

import { useEffect } from 'react';
import create from 'zustand';
import { LocalStorage } from '../lib/storage';
type ThemeVariant = typeof darkTheme | typeof lightTheme;
const darkTheme = 'dark';
const lightTheme = 'light';
const storageKey = 'theme';
const getCurrentTheme = () => {
const theme = LocalStorage.getItem(storageKey);
if (
theme === darkTheme ||
(!theme &&
typeof window !== 'undefined' &&
window.matchMedia('(prefers-color-scheme: dark)').matches)
) {
return darkTheme;
}
return lightTheme;
};
const applyClass = (theme: ThemeVariant) => {
if (theme === darkTheme) {
document.documentElement.classList.add(darkTheme);
} else {
document.documentElement.classList.remove(darkTheme);
}
};
interface ThemeStore {
theme: ThemeVariant;
toggle: (theme?: ThemeVariant) => void;
}
export const useThemeStore = create<ThemeStore>((set) => ({
theme: lightTheme,
toggle: (theme) => {
set((curr) => {
let newTheme: ThemeVariant;
if (theme) {
newTheme = theme;
} else {
newTheme = curr.theme === lightTheme ? darkTheme : lightTheme;
}
LocalStorage.setItem(storageKey, newTheme);
applyClass(newTheme);
return { theme: newTheme };
});
},
}));
export function useTheme() {
const { theme, toggle } = useThemeStore();
useEffect(() => {
const storedTheme = getCurrentTheme();
toggle(storedTheme);
}, [toggle]);
return { theme, toggle };
}