Bladeren bron

this shit is weird

Khaleel Al-Adhami 3 weken geleden
bovenliggende
commit
f425866756

+ 11 - 13
reflex/.templates/web/components/reflex/radix_themes_color_mode_provider.js

@@ -13,14 +13,10 @@ export default function RadixThemesColorModeProvider({ children }) {
   const [resolvedColorMode, setResolvedColorMode] = useState(
     defaultColorMode === "dark" ? "dark" : "light",
   );
-  const firstUpdate = useRef(true);
+
   useEffect(() => {
-    if (firstUpdate.current) {
-      firstUpdate.current = false;
-      setRawColorMode(theme);
-      setResolvedColorMode(resolvedTheme);
-    }
-  });
+    setTheme(rawColorMode);
+  }, [rawColorMode]);
 
   useEffect(() => {
     if (isDevMode) {
@@ -33,28 +29,30 @@ export default function RadixThemesColorModeProvider({ children }) {
         return;
       }
     }
-    setRawColorMode(theme);
+  });
+
+  useEffect(() => {
     setResolvedColorMode(resolvedTheme);
-  }, [theme, resolvedTheme]);
+  }, [resolvedTheme]);
 
   const toggleColorMode = () => {
-    setTheme(resolvedTheme === "light" ? "dark" : "light");
+    setRawColorMode(resolvedTheme === "light" ? "dark" : "light");
   };
   const setColorMode = (mode) => {
     const allowedModes = ["light", "dark", "system"];
     if (!allowedModes.includes(mode)) {
       console.error(
-        `Invalid color mode "${mode}". Defaulting to "${defaultColorMode}".`,
+        `Invalid color mode "${mode}". Defaulting to "${defaultColorMode}".`
       );
       mode = defaultColorMode;
     }
-    setTheme(mode);
+    setRawColorMode(mode);
   };
   return createElement(
     ColorModeContext.Provider,
     {
       value: {
-        rawColorMode,
+        rawColorMode: theme,
         resolvedColorMode,
         toggleColorMode,
         setColorMode,

+ 31 - 26
reflex/.templates/web/utils/react-theme.js

@@ -4,59 +4,64 @@ import {
   useState,
   useEffect,
   createElement,
+  useRef,
+  useMemo,
 } from "react";
 
 const ThemeContext = createContext();
 
-export function ThemeProvider({ children }) {
-  const [theme, setTheme] = useState("system");
-  const [resolvedTheme, setResolvedTheme] = useState("light");
+export function ThemeProvider({ children, defaultTheme = "system" }) {
+  const [theme, setTheme] = useState(defaultTheme);
+  const [systemTheme, setSystemTheme] = useState("light");
+
+  const firstRender = useRef(true);
 
   useEffect(() => {
+    if (!firstRender.current) {
+      return;
+    }
+
+    firstRender.current = false;
+
     // Load saved theme from localStorage
-    const savedTheme = localStorage.getItem("theme") || "system";
+    const savedTheme = localStorage.getItem("theme") || defaultTheme;
     setTheme(savedTheme);
+  });
 
+  const resolvedTheme = useMemo(
+    () => (theme === "system" ? systemTheme : theme),
+    [theme, systemTheme]
+  );
+
+  useEffect(() => {
     // Set up media query for system preference detection
     const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
 
-    const updateResolvedTheme = () => {
-      if (theme === "system") {
-        setResolvedTheme(mediaQuery.matches ? "dark" : "light");
-      } else {
-        setResolvedTheme(theme);
-      }
-    };
-
-    // Apply theme to document
-    const applyTheme = () => {
-      const root = window.document.documentElement;
-      root.classList.remove("light", "dark");
-      root.classList.add(resolvedTheme);
-    };
-
-    updateResolvedTheme();
-    applyTheme();
-
     // Listen for system preference changes
     const handleChange = () => {
-      if (theme === "system") {
-        updateResolvedTheme();
-      }
+      setSystemTheme(mediaQuery.matches ? "dark" : "light");
     };
 
+    handleChange();
+
     mediaQuery.addEventListener("change", handleChange);
 
     return () => {
       mediaQuery.removeEventListener("change", handleChange);
     };
-  }, [theme, resolvedTheme]);
+  });
 
   // Save theme to localStorage whenever it changes
   useEffect(() => {
     localStorage.setItem("theme", theme);
   }, [theme]);
 
+  useEffect(() => {
+    const root = window.document.documentElement;
+    root.classList.remove("light", "dark");
+    root.classList.add(resolvedTheme);
+  }, [resolvedTheme]);
+
   return createElement(
     ThemeContext.Provider,
     { value: { theme, resolvedTheme, setTheme } },