atoms.ts 1.2 KB

123456789101112131415161718192021222324252627282930313233
  1. import { global } from "@storybook/global";
  2. import { atomWithStorage } from "jotai/utils";
  3. import { atom } from "jotai/vanilla";
  4. import { PARAM_KEY } from "./constants";
  5. export const themeAtom = atomWithStorage(PARAM_KEY, "auto");
  6. export const evaluatedThemeAtom = atom((get) => {
  7. let theme = get(themeAtom);
  8. if (theme === "auto") {
  9. theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
  10. }
  11. global.document.documentElement.setAttribute("data-color-scheme", theme);
  12. return theme;
  13. });
  14. (evaluatedThemeAtom as any).onMount = (get: any, set: (a: any, v: any) => void) => {
  15. const mediaQueryList = window.matchMedia("(prefers-color-scheme: dark)");
  16. const callback = (event: MediaQueryListEvent) => {
  17. const theme = get(themeAtom);
  18. const evaluatedTheme = theme === "auto" ? (event.matches ? "dark" : "light") : theme;
  19. if (theme === "auto") {
  20. set(evaluatedThemeAtom, evaluatedTheme);
  21. }
  22. global.document.documentElement.setAttribute("data-color-scheme", evaluatedTheme);
  23. };
  24. mediaQueryList.addEventListener("change", callback);
  25. return () => {
  26. mediaQueryList.removeEventListener("change", callback);
  27. };
  28. };