From 6cae8d36582c7d1cbe1584382e03ce37c6dfb12c Mon Sep 17 00:00:00 2001 From: Carter Date: Mon, 14 Apr 2025 16:25:50 -0600 Subject: [PATCH] got new theme system to work without re-rendering --- src/theme/AppThemeProvider.tsx | 62 ++++++++++++++++++++++++++ src/theme/theme_old.ts | 80 ++++++++++++++++++++++++++++++++++ 2 files changed, 142 insertions(+) create mode 100644 src/theme/AppThemeProvider.tsx create mode 100644 src/theme/theme_old.ts diff --git a/src/theme/AppThemeProvider.tsx b/src/theme/AppThemeProvider.tsx new file mode 100644 index 0000000..4cedb98 --- /dev/null +++ b/src/theme/AppThemeProvider.tsx @@ -0,0 +1,62 @@ +import React, { createContext, useContext, useMemo, useState, useEffect } from "react"; +import { ThemeProvider, createTheme, PaletteMode } from "@mui/material/styles"; +import useMediaQuery from "@mui/material/useMediaQuery"; + +// --- You can import your own makePaletteColor() here if needed --- + +type ThemeMode = "light" | "dark" | "system"; + +interface ThemeModeContextType { + mode: ThemeMode; + resolvedMode: PaletteMode; // actual value used + toggleMode: () => void; + setMode: (mode: ThemeMode) => void; +} + +const ThemeModeContext = createContext(undefined); + +export const useThemeMode = () => { + const context = useContext(ThemeModeContext); + if (!context) { + throw new Error("useThemeMode must be used within ThemeModeProvider"); + } + return context; +}; + +export const AppThemeProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => { + const [mode, setMode] = useState("system"); + + const prefersDark = useMediaQuery("(prefers-color-scheme: dark)"); + const resolvedMode: PaletteMode = mode === "system" ? (prefersDark ? "dark" : "light") : mode; + + const theme = useMemo(() => createTheme({ + palette: { + mode: resolvedMode, + primary: { main: "#1976d2" }, // Or use makePaletteColor() + secondary: { main: "#e91e63" }, + }, + }), [resolvedMode]); + + const toggleMode = () => { + setMode(prev => + prev === "light" ? "dark" : + prev === "dark" ? "system" : + "light" + ); + }; + + const contextValue = useMemo(() => ({ + mode, + resolvedMode, + toggleMode, + setMode, + }), [mode, resolvedMode]); + + return ( + + + {children} + + + ); +}; diff --git a/src/theme/theme_old.ts b/src/theme/theme_old.ts new file mode 100644 index 0000000..0640544 --- /dev/null +++ b/src/theme/theme_old.ts @@ -0,0 +1,80 @@ +import { createTheme, responsiveFontSizes, ThemeOptions } from "@mui/material"; + +export const options = (themeType: "light" | "dark"): ThemeOptions => ({ + palette: { + mode: themeType, + ...(themeType === "light" + ? { + background: { + default: "#f5f5f5", + paper: "#fff" + }, + } + : { + background: { + default: "#0c101b", + paper: "#1c1f26" + }, + }), + primary: { + main: "#00AEEF" + }, + secondary: { + main: "#F39200" + }, + error: { + main: "#e53935" + }, + warning: { + main: "#fdd835" + }, + info: { + main: "#29b6f6" + }, + success: { + main: "#43a047" + }, + divider: "rgba(0, 0, 0, 0.12)" + }, + typography: { + fontFamily: `"Roboto", "Helvetica", "Arial", sans-serif`, + fontSize: 14, + h1: { + fontSize: "2.5rem" + }, + h2: { + fontSize: "2rem" + }, + h3: { + fontSize: "1.75rem" + }, + h4: { + fontSize: "1.5rem" + }, + h5: { + fontSize: "1.25rem" + }, + h6: { + fontSize: "1rem" + }, + button: { + textTransform: "none" + } + }, + components: { + MuiCssBaseline: { + styleOverrides: { + body: { + margin: 0, + padding: 0, + } + } + } + }, + cssVarPrefix: "mui", // optional prefix for CSS vars + cssVariables: true +}); + +// Create both themes once for reuse +export const lightTheme = responsiveFontSizes(createTheme(options("light"))); +export const darkTheme = responsiveFontSizes(createTheme(options("dark")));