Peter Boomsma
Peter Boomsma

Reputation: 9808

How to use MUI v5 makeStyles without ThemeProvider?

I have a styles.tsx file because I rather not put the styling in my components:

//styles.tsx

import {grey, purple} from '@mui/material/colors';
import {styled, Theme} from '@mui/material/styles';
import {createStyles, makeStyles} from '@mui/styles';

export const drawerStyles = makeStyles((theme: Theme) =>
  createStyles({
    logo: {
      'fontSize': '2em',
      'fontFamily': 'Oleo Script Swash Caps',
      'background': 'transparent',
      'border': 'none',
      'marginLeft': theme.spacing(1),
      'width': '41px',
      'overflow': 'hidden',
      'transition': 'all 0.1s ease-out',
      'cursor': 'pointer',
      '&:hover': {
        color: purple[700],
      },
    },
    slide: {
      paddingLeft: '8px',
      width: '100%',
    },
  }),
);

In another component I import the drawerStyles:

// drawerContainer.tsx

import {drawerStyles} from 'Src/styles';

export const DrawerContainer = () => {
  const classes = drawerStyles();

  return (
    <Box className={`${classes.logo}>
      <p>some text</p>
    </Box>
  )

The code compiles but the browser is returning an error:

MUI: The styles argument provided is invalid. You are providing a function without a theme in the context. One of the parent elements needs to use a ThemeProvider.

On my index.tsx I use ThemeProvider:

// index.tsx

import {ThemeProvider, StyledEngineProvider} from '@mui/material/styles';
import {theme} from 'Src/theme';

  const Root = () => {
    return (
      <ApolloProvider client={client}>
        <StyledEngineProvider injectFirst>
          <ThemeProvider theme={theme}>
            <CssBaseline>
              <App />
            </CssBaseline>
          </ThemeProvider>
        </StyledEngineProvider>
      </ApolloProvider>
    );
  };

  render(<Root />, document.getElementById('root'));

I think the issue is because styles.tsx isn't inside the index.tsx scope. So it doesn't have the themeprovider context when the browser loads the file.

Should I just move all the styling in the component? Or is there another way?

// edit //

Created the styling with the styled api:

// styles.tsx

export const Logo = styled(Box)(({theme}) => ({
  'fontSize': '2em',
  'fontFamily': 'Oleo Script Swash Caps',
  'background': 'transparent',
  'border': 'none',
  'marginLeft': theme.spacing(1),
  'width': '41px',
  'overflow': 'hidden',
  'transition': 'all 0.1s ease-out',
  'cursor': 'pointer',
  '&:hover': {
    color: purple[700],
  },
}));
// DrawerContainer.tsx

  <Link data-cy='btn_home' to='/'>
    <Logo component='button'>Movieseat</Logo>
  </Link>

I kind of dislike this syntax, it's not clear what type of object Logo is.

Upvotes: 2

Views: 7142

Answers (1)

NearHuscarl
NearHuscarl

Reputation: 81370

See this answer for more detail. In short, makesStyles/withStyles is not the first class APIs in MUI v5 anymore and is scheduled to be removed in v6. If you use the old API, you have to add a theme yourself.

In v4 you can import makeStyles from @material-ui/core/styles without having to supply a custom theme. You can do the same in v5 but only with the new styled API that is being used by all of the MUI components internally.

Upvotes: 5

Related Questions