Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Material UI nested theme providers breaks withStyles HOC

I have a React application created with Create React App and I use the @material-ui/core npm package for theming.

To customize components I use the withStyles higher-order component provided by MaterialUI.

According to documentation it supports nested ThemeProviders https://material-ui.com/customization/theming/#nesting-the-theme.

But inside the child ThemeProvider withStyles won't apply classes.

Here is a basic application demonstrating the issue -> https://codesandbox.io/s/vibrant-tree-eh83d

ExampleComponent.tsx

import React, { FunctionComponent } from "react";
import {
  WithStyles,
  withStyles,
  createStyles,
  StepButton,
  Step,
  Stepper,
  Box
} from "@material-ui/core";

const styles = createStyles({
  button: {
    "& .MuiStepIcon-root.MuiStepIcon-active": {
      fill: "red"
    }
  }
});

interface Props extends WithStyles<typeof styles> {
  title: string;
}

const ExampleComponent: FunctionComponent<Props> = ({ title, classes }) => {
  console.log(title, classes);
  return (
    <Box display="flex" alignItems="center">
      <span>{title}</span>
      <Stepper activeStep={0}>
        <Step>
          <StepButton className={classes.button}>Test</StepButton>;
        </Step>
      </Stepper>
    </Box>
  );
};

export default withStyles(styles)(ExampleComponent);

App.tsx

import * as React from "react";
import { ThemeProvider, createMuiTheme } from "@material-ui/core";
import ExampleComponent from "./ExampleComponent";

const theme = createMuiTheme();

function App() {
  return (
    <ThemeProvider theme={theme}>
      <ExampleComponent title="Root" />
      <ThemeProvider theme={theme}>
        <ExampleComponent title="Nested" />
      </ThemeProvider>
    </ThemeProvider>
  );
}

export default App;

Inside the ExampleComponent I console.log the generated classes object.

I want to use nested ThemeProviders and override classes inside components regardless of the ThemeProvider. Am I missing something or is this not possible?

like image 546
Whotriesout Theon Avatar asked Oct 22 '25 04:10

Whotriesout Theon


1 Answers

When you are using nested themes, you cannot reliably use Material-UI's global class names (e.g. .MuiStepIcon-root.MuiStepIcon-active). Within a nested theme, the "Mui..." class names have to be different to avoid conflicting with the CSS classes for the top-level theme since the nested theme will cause some of the CSS for the "Mui..." classes to be different.

You can use the following syntax in order to successfully match the suffixed versions of the Mui class names that occur within nested themes:

const styles = createStyles({
  button: {
    '& [class*="MuiStepIcon-root"][class*="MuiStepIcon-active"]': {
      fill: "red"
    }
  }
});

Edit withStyles with nested themes

Related answer:

  • How reliable are MUI Global Class names in JSS?
like image 52
Ryan Cogswell Avatar answered Oct 23 '25 20:10

Ryan Cogswell



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!