'Material-UI theme not working in shared-component

I'm building a reusable shared-component library using material-ui which is being imported in my main app like this:

import { theme, StepperComponent } from '@company/shared-components';
import { ThemeProvider } from '@mui/material/styles';

...

return (
  <ThemeProvider theme={theme}>
     <StepperComponent steps={stepperTitles} />
     ...
)

The stepper component is in my shared-components repository which I'm npm-linking

import React from 'react';
import Step from '@mui/material/Step';
import StepLabel from '@mui/material/StepLabel';
import { StyledStepper, StyledStepConnector, StyledStepIcon } from './Stepper.styles';

const StepperComponent = ({ steps, ...props }) => {
  return (
    <StyledStepper {...props} connector={<StyledStepConnector />} alternativeLabel>

However, for some reason the theme isn't getting applied to this component even though I'm wrapping it in the theme provider. When I log out the theme it doesn't include the colors that are in the theme being imported to my main app.

Does anyone know why this might be happening?



Solution 1:[1]

I'm dealing with something similar and haven't resolved it completely, but I have a strong feeling it involves multiple React contexts being created inside material-ui and emotion/react.

The ThemeProvider only exposes the theme to the components that have access to its context - the components within your main application.

I was able to achieve the desired behavior by making sure material-ui's ThemeProvider and it's context lives in the shared component library and not the main application. I did this by exporting a simple wrapper of ThemeProvider from the component library; literally just:

interface LibraryThemeProviderProps {
  children?: React.ReactNode;
  theme: Theme;
}

const LibraryThemeProvider: React.FC<LibraryThemeProviderProps> = ({ children, theme }) => (
  <ThemeProvider theme={theme}>
    {children}
  </ThemeProvider>
)

and then using LibraryThemeProvider in the place of material's ThemeProvider in the main application.

If you want the same theme applied within your main application you only need to leave the original ThemeProvider in place alongside the new LibraryThemeProvider.

I'd prefer to solve this with a single ThemeProvider but haven't been able to yet :/

Note: I am using the useTheme hook inside all my components to access the theme. useTheme will use material's default theme if it doesn't see one provided by the ThemeProvider context - all this happens under the hood.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Kaschman