Theme does not apply to typography.

Hi, i created a simple refine app with react, remix and material ui using the following command: npm create refine-app@latest I selected the option for a custom theme, this generated a components folder containing Header, Layout, Title and Sider. I created the following page to show an Imprint:
import { Container, Typography } from "@pankod/refine-mui";
import { Header, Layout } from "~/components/layout";

export default function Imprint() {
    return (
        <Layout>
            <Typography variant="h3">Haftungsausschluss</Typography>
        </Layout>
    );
}
import { Container, Typography } from "@pankod/refine-mui";
import { Header, Layout } from "~/components/layout";

export default function Imprint() {
    return (
        <Layout>
            <Typography variant="h3">Haftungsausschluss</Typography>
        </Layout>
    );
}
When switch theme with button at the top, the text color does not change. What am I missing? The page is integrated like this into refine:
export default function App() {
  return (
    <Document>
      <ColorModeContextProvider>
        <CssBaseline />
        <GlobalStyles styles={{ html: { WebkitFontSmoothing: "auto" } }} />
        <RefineSnackbarProvider>
          <Refine
            routerProvider={routerProvider}
            dataProvider={dataProvider(API_URL)}
            notificationProvider={notificationProvider}
            ReadyPage={ReadyPage}
            catchAll={<ErrorComponent />}
            resources={[
              {
                name: "posts",
                list: MuiInferencer,
                edit: MuiInferencer,
                show: MuiInferencer,
                create: MuiInferencer,
                canDelete: true,
              },
              {
                name: 'imprint',
                options: {
                  label: 'Imprint',
                },
                list: () => null,
              }
            ]}
            Title={Title}
            Sider={Sider}
            Layout={Layout}
            Header={Header}
            authProvider={authProvider}
            LoginPage={AuthPage}
          >
            <Outlet />
          </Refine>
        </RefineSnackbarProvider>
      </ColorModeContextProvider>
    </Document>
  );
}
export default function App() {
  return (
    <Document>
      <ColorModeContextProvider>
        <CssBaseline />
        <GlobalStyles styles={{ html: { WebkitFontSmoothing: "auto" } }} />
        <RefineSnackbarProvider>
          <Refine
            routerProvider={routerProvider}
            dataProvider={dataProvider(API_URL)}
            notificationProvider={notificationProvider}
            ReadyPage={ReadyPage}
            catchAll={<ErrorComponent />}
            resources={[
              {
                name: "posts",
                list: MuiInferencer,
                edit: MuiInferencer,
                show: MuiInferencer,
                create: MuiInferencer,
                canDelete: true,
              },
              {
                name: 'imprint',
                options: {
                  label: 'Imprint',
                },
                list: () => null,
              }
            ]}
            Title={Title}
            Sider={Sider}
            Layout={Layout}
            Header={Header}
            authProvider={authProvider}
            LoginPage={AuthPage}
          >
            <Outlet />
          </Refine>
        </RefineSnackbarProvider>
      </ColorModeContextProvider>
    </Document>
  );
}
9 Replies
refine-support-bot
Hi, I am refine support bot :wave:. I am here to help you with your question. I searched for the answer to your question in the refine documentation and found an answer! 🏆
Answer: You need to use the ThemeProvider component to inject a custom theme that you have created yourself. SOURCES: ./docs/api-reference/mui/customization/theme.md

Note: If this is the answer you need, then we are very lucky. If not, please wait for someone from the refine core team or the community to try to help you.
harsh-harlequin
harsh-harlequin2y ago
When i switch to the example finefoods-mui i can see that this works. But the only difference I can spot is that they are not using a custom Layout. But the custom Layout was just auto generated from your command line tool, there is nothing special in there. This is the autogenerated Layout that i am using
import React from "react";
import { LayoutProps } from "@pankod/refine-core";
import { Box } from "@pankod/refine-mui";

import { Sider as DefaultSider } from "../sider";
import { Header as DefaultHeader } from "../header";

export const Layout: React.FC<LayoutProps> = ({
  Sider,
  Header,
  Footer,
  OffLayoutArea,
  children,
}) => {
  const SiderToRender = Sider ?? DefaultSider;
  const HeaderToRender = Header ?? DefaultHeader;

  return (
    <Box display="flex" flexDirection="row">
      <SiderToRender />
      <Box
        sx={{
          display: "flex",
          flexDirection: "column",
          flex: 1,
          minHeight: "100vh",
        }}
      >
        <HeaderToRender />
        <Box
          component="main"
          sx={{
            p: { xs: 1, md: 2, lg: 3 },
            flexGrow: 1,
            bgcolor: (theme) => theme.palette.background.default,
          }}
        >
          {children}
        </Box>
        {Footer && <Footer />}
      </Box>
      {OffLayoutArea && <OffLayoutArea />}
    </Box>
  );
};
import React from "react";
import { LayoutProps } from "@pankod/refine-core";
import { Box } from "@pankod/refine-mui";

import { Sider as DefaultSider } from "../sider";
import { Header as DefaultHeader } from "../header";

export const Layout: React.FC<LayoutProps> = ({
  Sider,
  Header,
  Footer,
  OffLayoutArea,
  children,
}) => {
  const SiderToRender = Sider ?? DefaultSider;
  const HeaderToRender = Header ?? DefaultHeader;

  return (
    <Box display="flex" flexDirection="row">
      <SiderToRender />
      <Box
        sx={{
          display: "flex",
          flexDirection: "column",
          flex: 1,
          minHeight: "100vh",
        }}
      >
        <HeaderToRender />
        <Box
          component="main"
          sx={{
            p: { xs: 1, md: 2, lg: 3 },
            flexGrow: 1,
            bgcolor: (theme) => theme.palette.background.default,
          }}
        >
          {children}
        </Box>
        {Footer && <Footer />}
      </Box>
      {OffLayoutArea && <OffLayoutArea />}
    </Box>
  );
};
multiple-amethyst
multiple-amethyst2y ago
Hello @Deleted User Can you try to wrap with <ThemeProvider> ? See the docs here: https://refine.dev/docs/api-reference/mui/customization/mui-custom-theme/
Theme | refine
Theme specifies the color of the components, the darkness of the surfaces, level of shadow, appropriate opacity of ink elements, etc. You can either create your own Theme or use Themes that provide from Refine. There are two types of Themes: LightTheme and DarkTheme. LightTheme tend to have dark text on a light background, while DarkTheme have l...
harsh-harlequin
harsh-harlequin2y ago
Hey @batuhanw thanks very much for the response. I think this is already being done by <ColorModeContextProvider />. Following is the code for that component:
import React, {
  PropsWithChildren,
  createContext,
  useEffect,
  useState,
} from "react";
import { ThemeProvider, useMediaQuery } from "@pankod/refine-mui";
import { DarkTheme, LightTheme } from "@pankod/refine-mui";
import { parseCookies, setCookie } from "nookies";

type ColorModeContextType = {
  mode: string;
  setMode: () => void;
};

export const ColorModeContext = createContext<ColorModeContextType>(
  {} as ColorModeContextType
);

export const ColorModeContextProvider: React.FC<PropsWithChildren> = ({
  children,
}) => {
  const [isMounted, setIsMounted] = useState(false);
  const [mode, setMode] = useState("light");

  useEffect(() => {
    setIsMounted(true);
  }, []);

  const systemTheme = useMediaQuery(`(prefers-color-scheme: dark)`);

  useEffect(() => {
    if (isMounted) {
      setMode(parseCookies()["theme"] || (systemTheme ? "dark" : "light"));
    }
  }, [isMounted, systemTheme]);

  const toggleTheme = () => {
    const nextTheme = mode === "light" ? "dark" : "light";

    setMode(nextTheme);
    setCookie(null, "theme", nextTheme);
  };

  return (
    <ColorModeContext.Provider
      value={{
        setMode: toggleTheme,
        mode,
      }}
    >
      <ThemeProvider theme={mode === "light" ? LightTheme : DarkTheme}>
        {children}
      </ThemeProvider>
    </ColorModeContext.Provider>
  );
};
import React, {
  PropsWithChildren,
  createContext,
  useEffect,
  useState,
} from "react";
import { ThemeProvider, useMediaQuery } from "@pankod/refine-mui";
import { DarkTheme, LightTheme } from "@pankod/refine-mui";
import { parseCookies, setCookie } from "nookies";

type ColorModeContextType = {
  mode: string;
  setMode: () => void;
};

export const ColorModeContext = createContext<ColorModeContextType>(
  {} as ColorModeContextType
);

export const ColorModeContextProvider: React.FC<PropsWithChildren> = ({
  children,
}) => {
  const [isMounted, setIsMounted] = useState(false);
  const [mode, setMode] = useState("light");

  useEffect(() => {
    setIsMounted(true);
  }, []);

  const systemTheme = useMediaQuery(`(prefers-color-scheme: dark)`);

  useEffect(() => {
    if (isMounted) {
      setMode(parseCookies()["theme"] || (systemTheme ? "dark" : "light"));
    }
  }, [isMounted, systemTheme]);

  const toggleTheme = () => {
    const nextTheme = mode === "light" ? "dark" : "light";

    setMode(nextTheme);
    setCookie(null, "theme", nextTheme);
  };

  return (
    <ColorModeContext.Provider
      value={{
        setMode: toggleTheme,
        mode,
      }}
    >
      <ThemeProvider theme={mode === "light" ? LightTheme : DarkTheme}>
        {children}
      </ThemeProvider>
    </ColorModeContext.Provider>
  );
};
harsh-harlequin
harsh-harlequin2y ago
GitHub
GitHub - 0x66656c6978/remix-refine-mui-theme-switch-problem
Contribute to 0x66656c6978/remix-refine-mui-theme-switch-problem development by creating an account on GitHub.
harsh-harlequin
harsh-harlequin2y ago
If you navigate to http://localhost:3000/imprint and then try to switch the theme, it doesn't apply the white text in the dark mode.
multiple-amethyst
multiple-amethyst2y ago
Thanks for the reproducible example! It seems it's not about provider as you mentioned, but the problem is with the theme itself. Themes are switching correctly, but I guess darkTheme's text definitions aren't correct. I took note on this issue, will ask folks tomorrow and get back to you! Best
harsh-harlequin
harsh-harlequin2y ago
Awesome, thank you very much 🙏 @batuhanw I changed a bunch of other things and now it is working as intended. 🎉 Thanks for reaching out!!
multiple-amethyst
multiple-amethyst2y ago
Hello @Deleted User, I'm happy the issue is resolved! 🎉 Can you share what was wrong and how you fixed it for future reference?