Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Leverage Theme Values in Globally Themed Components #44214

Closed
aress31 opened this issue Oct 25, 2024 · 3 comments
Closed

Leverage Theme Values in Globally Themed Components #44214

aress31 opened this issue Oct 25, 2024 · 3 comments
Assignees
Labels
customization: theme Centered around the theming features support: question Community support but can be turned into an improvement

Comments

@aress31
Copy link

aress31 commented Oct 25, 2024

Summary

I would like to leverage theme properties, such as the current mode and palette colors, to customize my themed components. However, this doesn’t currently seem possible. Please see the example below.

Examples

  • theme.js:

    import { red } from "@mui/material/colors";
    
    const colors = {
      primary: {
        dark: red[700],
        light: red[400],
      },
    };
    
    export const getDesignTokens = () => ({
      colorSchemes: {
        dark: {
          palette: {
            primary: {
              main: red[700],
            },
          },
        },
        light: {
          palette: {
            primary: {
              main: red[400],
            },
          },
        },
      },
    });
    
    // Ideally, we want to avoid passing the mode directly and instead use a callback function.
    // For example:
    // backgroundColor: (theme) => theme.mode === "dark" ? colors.primary.dark : colors.primary.light,
    export const getThemedComponents = (mode) => ({
      components: {
        MuiButton: {
          styleOverrides: {
            containedPrimary: {
              backgroundColor: mode === "dark" ? colors.primary.dark : colors.primary.light,
            },
          },
        },
      },
    });
  • App.js:

    const App = () => {
      const theme = responsiveFontSizes(
        createTheme({
          ...getDesignTokens(),
          // TODO: Access the theme info within the function
          ...getThemedComponents("dark"),
        })
      );
    
      return (
        <ThemeProvider theme={theme}>
          <CssBaseline />
          <Box
            sx={{
              backgroundColor: theme.palette.background.default,
              color: theme.palette.text.primary,
              minHeight: "100vh",
              p: 4,
            }}
          >
            <Typography variant="h4" color="primary" gutterBottom>
              Welcome to the Themed App
            </Typography>
            <Typography variant="body1">
              This is a minimal example demonstrating custom theming.
            </Typography>
            <Link href="#" color="primary">
              Learn More
            </Link>
          </Box>
        </ThemeProvider>
      );
    };
    
    export default App;

Motivation

This would be the final touch, in my opinion, for creating a theme adaptable to different color modes. It would enable a modular, easily maintainable theme that can dynamically adjust to the selected mode and access palette values for custom styling across the application.

Search keywords: themes

@aress31 aress31 added the status: waiting for maintainer These issues haven't been looked at yet by a maintainer label Oct 25, 2024
@mj12albert mj12albert added the customization: theme Centered around the theming features label Oct 28, 2024
@mj12albert mj12albert added the new feature New feature or request label Oct 28, 2024
@siriwatknp
Copy link
Member

Please use theme.applyStyles for customizing the styles in a specific mode. Also, combined classes like containedPrimary are deprecated, so you should convert to the root slot and then use variants. In your case, it will be like

{
  components: {
    MuiButton: {
      styleOverrides: {
        root: ({ theme }) => ({
          variants: [
            { 
              props: { variant: 'contained', color: 'primary' },
              style: {
                backgroundColor: colors.primary.light,
                …theme.applyStyles('dark', {
                  backgroundColor: colors.primary.dark,
                })
              }
            }
          ]
        })
      },
    },
  },
}

If the code above does not work, feel free to reopen.

@siriwatknp siriwatknp added support: question Community support but can be turned into an improvement and removed new feature New feature or request status: waiting for maintainer These issues haven't been looked at yet by a maintainer labels Oct 28, 2024
Copy link

This issue has been closed. If you have a similar problem but not exactly the same, please open a new issue.
Now, if you have additional information related to this issue or things that could help future readers, feel free to leave a comment.

Note

@aress31 How did we do? Your experience with our support team matters to us. If you have a moment, please share your thoughts in this short Support Satisfaction survey.

@aress31
Copy link
Author

aress31 commented Oct 28, 2024

Thanks, @siriwatknp! I have a quick follow-up question: what is the advantage of wrapping the variants inside styleOverrides -> root instead of defining them directly like this?

MuiSvgIcon: {
  variants: [
    {
      props: { variant: "whatever" },
      style: ({ theme }) =>
        theme.applyStyles("dark", { filter: "grayscale(0.25)" }),
    },
  ],
},

Thanks in advance!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
customization: theme Centered around the theming features support: question Community support but can be turned into an improvement
Projects
None yet
Development

No branches or pull requests

3 participants