33

I just started using Material UI version 5. Originally to use my custom theme's styles, I would use makestyles, but it seems that does not work in v.5. My themes are on their own component, and to import those, I used {createTheme} instead of the old {createMuiTheme}. I have my theme imported into the Parent component as usual and have it set up as <ThemeProvider theme{theme}></ThemeProvider>.

Now, on my other component, I again was trying to use useStyles, but it was not working because it is not used in version 5. I am having a hard time trying to figure out how to convert it so that it can be used in version 5. Here is some of the unfinished code I was working on:

const useStyles = makeStyles((theme) => ({
    logo: {
        height: "8em",
        marginLeft: "0.2em",
    },
    tabContainer: {
        marginLeft: "auto",
    },
    tab: {
        ...theme.typography.tab,
        minWidth: 10,
        marginRight: "50px",
        opacity: 1,
        "&hover": {
            color: theme.palette.common.purple,
            textDecoration:"none",
        },
    },
}));

export default function Navigation(props) {
    const classes = useStyles();

    const [value, setValue] = useState(0);

    const handleChange = (e, value) => {
        setValue(value);
    };
    const refreshPage = () => {
        window.location.reload();
    };
    
    useEffect(() => {
        switch (window.location.pathname) {
            case "/":
                if (value !== 0) {
                    setValue(0);
                }
                break;
                default:
                break;
        }
    }, [value]);


    return (
      <React.Fragment>
        <ElevationScroll>
          <AppBar
            position="relative"
            style={{
              borderBottom: "2px solid black",
            }}
          >
            <Toolbar disableGutters>
                <img src={logo} alt="nasa logo" className={classes.logo}/>
                <Typography variant="h1" style={{ textAlign: "center" }}>
                  Nasa<br></br>Photos
                </Typography>
                <Tabs
                  value={value}
                  onChange={handleChange}
                  className={classes.tabContainer}
                  indicatorColor="primary"
                >
                  <Tab
                    className={classes.tab}
                    component={Link}
                    onClick={refreshPage}
                    to="/"
                    label="Home"
                  />
                </Tabs>
            </Toolbar>
          </AppBar>
        </ElevationScroll>
      </React.Fragment>
    );
}

I have read about the xs property and I have also heard of the styled() through Material UI's documentation, but I am having a hard time applying it to the code that I have written and would like a push in the right direction.

So to edit what I had earlier, I am going to also add my Theme.js file as well. I thought that this has been done correctly, but again it isn't reading my tab nor my palette.

import {createTheme} from "@mui/material/styles";

const pink = "#FFC0CB";
const lightblue = "#ADD8E6";
const purple = "#800080";
const black = "#000000";

const theme = createTheme({
    palette: {
        common: {
            pink: pink,
            lightblue: lightblue,
            purple: purple,
            black: black
        },
        primary: {
            main: pink,
            mainGradient: "linear-gradient(to left, purple, pink)",
        },
        secondary: {
            main: lightblue,
            mainGradient: "linear-gradient(to right, lightblue, pink)"
        },
    },
    typography: {
        tab: {
            fontFamily:"Orbitron",
            textTransform: "none",
            fontSize: "2.5rem",
            color: black,
        },
        h1: {
            fontFamily: "Orbitron",
            fontSize: "2.5em"
        },
        h2: {
            fontFamily: "Orbitron",
            fontSize: "2.5em"
        },
        subtitle1: {
            fontFamily: "Orbitron"
        },
        subtitle2: {
            fontFamily: "Orbitron",
            fontSize: "1.5rem"
        },
        buttons: {
            fontFamily: "Orbitron",
            textTransform: "none"
        },
    },
});

export default theme

I have imported my theme into my App.js file which is my top level file, I will include that here just in case something has been done wrong with that:

import React,{useState} from "react";
import PicOfDay from "./Components/PictureOfDay";
import Navigation from "./Components/Navigation";
import {
  Typography,
} from "@mui/material";
import {ThemeProvider} from '@mui/material/styles'
import theme from "../src/ui/Theme";
import {BrowserRouter as Router} from "react-router-dom";

function App(props) {
  const [date, setDate] = useState(new Date());
  return (
    <ThemeProvider theme={theme}>
      <Router>
        <Navigation date={date} setDate={setDate} />
        <Typography
          variant="h1"
          style={{fontSize: "5rem", textAlign: "center", marginTop:"2rem"}}
          >
            Astronomy Picture of the Day
        </Typography>  
        {/* <PicOfDay date={date} /> */}
      </Router>
    </ThemeProvider>
  );
}

export default App;

I did look at some documentation a couple of you sent me, and I was looking at the troubleshooting part where it said "[Types] Property "palette", "spacing" does not exist on type 'DefaultTheme'" because makeStyles is exported differently and it does not know about Theme. There seems to be a snipet to put in a typescript project (which I am not running, I am using javascript) and there was a section to add a ts file to my javascript and put the snippet it recommended, which I tried, but am I missing something because it did not do anything and I am not sure if I need to put something in my App.js file in order for it to read that?

Natsuko Izuki
  • 443
  • 1
  • 4
  • 10

5 Answers5

13

You can still use the makeStyles utils as what you're using, but in material v5 if you love to do it you need to install one more package @mui/styles and

import { makeStyles } from '@mui/styles';

https://mui.com/guides/migration-v4/#mui-material-styles

The makeStyles JSS utility is no longer exported from @mui/material/styles. You can use @mui/styles/makeStyles instead.

Also, you need to add tab and purple to createTheme if you need them

const theme = createTheme({
  typography: {
    tab: {
      fontSize: 20,
    },
  },
  palette: {
    common: {
      purple: 'purple',
    },
  },
})
Fred Nguyen
  • 285
  • 1
  • 3
  • I checked and I already had @mui/styles installed. I have makestyles imported as: `import {makeStyles} from "@mui/styles"` and it still is not working. I notice in my vs code when hoovering over my spread of `...theme.typography.tab` and `color: theme.palette.common.purple` it says (parameter) theme: DefaultTheme, when it used to in v.4 say (paramter) theme: Theme – Natsuko Izuki Sep 21 '21 at 13:19
  • yes, that true, in v5 the theme has the type is `DefaultTheme` instead of on Theme as v4 >Since makeStyles is now exported from @mui/styles package which does not know about Theme in the core package. https://mui.com/guides/migration-v4/#types-property-quot-palette-quot-quot-spacing-quot-does-not-exist-on-type-defaulttheme In your case you need to add `tab` and `purple` to `createTheme` ` const theme = createTheme({ typography: { tab: { fontSize: 20, }, }, palette: { common: { purple: 'purple', }, }, }) ` – Fred Nguyen Sep 21 '21 at 14:12
  • I've added more to my original post – Natsuko Izuki Sep 21 '21 at 20:17
  • 3
    Ok one important thing when doing this kind of migration *you need to have the `StyledEngineProvider` with the injectFirst option at the top of your component tree* https://mui.com/guides/migration-v4/#style-library – Fred Nguyen Sep 22 '21 at 14:01
  • That did it! When I used it fixed my issues with the styles not working. I just realized I had a typo in one of my makestyles, I spelled typography wrong. After realizing that, it worked. Besides that, I am just having a weird issue where my first Tab is not being displayed. If I have a second tab, the 2nd tab shows, but the first one still doesn't display. I think it's probably better to ask that as another question. Can you put that in your answer as well – Natsuko Izuki Sep 23 '21 at 04:35
  • 4
    @mui/styles is the legacy styling solution for MUI. It is deprecated in v5. – Reza Dec 07 '21 at 15:33
11

Based on documentation:

@mui/styles is the legacy styling solution for MUI. It is deprecated in v5. It depends on JSS as a styling solution, which is not used in the @mui/material anymore.

You can use the-sx-prop or styled

Reza
  • 493
  • 5
  • 14
1
import * as React from 'react';
import { StyledEngineProvider } from '@mui/material/styles';

export default function GlobalCssPriority() {
  return (
    <StyledEngineProvider injectFirst>
      {/* Your component tree. Now you can override MUI's styles. */}
    </StyledEngineProvider>
  );
}

You need to use provider on main file to get default styles first.
Visit here Material UI injections!

1

@mui/styles is not compatible with React.StrictMode or React 18.

it's recommanded to use the sx props

import * as React from 'react';
import { Box } from '@mui/system';

export default function BasicUsage() {
  return (
    <Box
      component= 'div'
      sx={{
        color: 'darkslategray',
        backgroundColor: 'aliceblue',
        padding: 8,
        borderRadius: 4,
      }}
    >
      Styled div
    </Box>
  );
}

or

you can use styled() function from @mui/system package or @mui/material/styles package, if no theme be created, the difference is in the default theme used in these packages.

import * as React from 'react'; 
import { styled } from '@mui/system';
     
const MyComponent = styled('div')({   
  color: 'darkslategray',  
  backgroundColor: 'aliceblue',   
  padding: 8,   
  borderRadius: 4, 
});
     
export default function BasicUsage() {   
  return <MyComponent>Styled div</MyComponent>;
}
0

so what i understood from this question is that you want to add custom classes to the material-ui components. and makestyles is giving you error about theme.. you can resolve this by providing default theme to makestyles. you can use ThemeProvider to do that.. all you've to do is create a default theme with createTheme() then use that in ThemeProvider to pass it to all components in tree below ThemeProvider.. just use ThemeProvider to wrap your root component and that will provide default theme to each makeStyles that are currently in use..

import { makeStyles } from '@mui/styles';
import { createTheme, ThemeProvider } from '@mui/material/styles';

const theme = createTheme();

 const useStyles = makeStyles((theme) => (
 root : {
   background: theme.palette.primary.main,
 }));

 function Component() {
   const classes = useStyles();
   return <div className={classes.root} />
 }

 // In the root of your app
 function App(props) {

 return <ThemeProvider theme={theme}><Component {...props} /></ThemeProvider>;
 }