Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to style Toolbar with Material UI v5 with 'styled' instead of 'makeStyles' with this class instance?

I'm a newbie to JS, ReactJS, and Material UI. I was following a tutorial on building a simple ReactJS webpage, but looks like the person was using Material UI v4 and now that Material UI v5 is out, a few of the APIs and tools used in the tut are outdated (withStyles, makeStyles). Around 10:46 in the video, he is showing how he is creating classes to stylize each part of the Toolbar.

I'm trying to figure out how I could accomplish the same stylizing for the Toolbar and its Typography components using that same exact structure, via injecting it with className?

My Code:

Navbar.js

import React from 'react'
import logo from '../assets/logo.svg'               // imported assets for the navbar
import logoMobile from '../assets/logoMobile.svg'
import { Toolbar, Typography } from '@mui/material' // these two needed for toolbar
import { styled } from '@mui/material'
import CustomButton from './CustomButton'

const styles = styled({
    bar:{       // class name
      paddingTop: "1.15rem",
      backgroundColor: "#fff",
      ['@media (max-width:780px)']:{flexMedia: "column"}, // media queries - for different devices and web-browser sizes
    },
    // logo: {
    //   width: "15%", 
    //   ['@media (max-width:780px)']: {display: "none"},
    // },
    // logoMobile:{
    //   width: "100%", 
    //   display: "none", 
    //   ['@media (max-width:780px)']: {display: "inline-block"},
    // },
    menuItem: {
      cursor: "pointer", 
      flexGrow: 1,
      "&:hover": {color:  "#4f25c8"},
      ['@media (max-width:780px)']: {paddingBottom: "1rem"},
    }

})

function NavBar() {
  const classes = styles()
  return (
    <Toolbar position="sticky" color="rgba(0, 0, 0, 0.87)" className={classes.bar}>
      {/* <img src={logo} className={classes.logo}/>
      <img src={logoMobile} className={classes.logoMobile}/> */}
      <Typography variant="h5" className={classes.menuItem}>
        About Me
      </Typography>
      <Typography variant="h5" className={classes.menuItem}>
        Projects
      </Typography>
      <Typography variant="h5" className={classes.menuItem}>
        Resume
      </Typography>
      <Typography variant="h5" className={classes.menuItem}>
        Contact Me
      </Typography>
      <CustomButton txt="a test button!"></CustomButton>
    </Toolbar>   
  )
}

export default NavBar

And here's what it ends up looking like

enter image description here

vs what it should look like

enter image description here

I tried utilizing {styled } from '@mui/material' but I can only get the toolbar to show. But it will not apply the styling expected, from the video -- confused as to why? Also this question accomplishes the same task, but it doesn't do it the way that I'm asking about.

like image 839
fables.fab Avatar asked Oct 17 '25 13:10

fables.fab


1 Answers

Because styled create custom components with additional styles, it attaches the styles without specifying and adding class names manually.

Here is a quick example for a styled version of your code: (live demo on: stackblitz)

First use styled to create some custom components, in this case based on the MUI components Toolbar and Typography, with some styles attached to them.

// 👇 This component based on Toolbar
const MyToolbar = styled(Toolbar)(({ theme }) => ({
  paddingTop: '1.15rem',
  backgroundColor: '#fff',
  color: 'rgba(0, 0, 0, 0.87)',
  position: 'sticky',
  // 👇 Optional: consider to use theme.breakpoints for this
  ['@media (max-width:780px)']: { flexDirection: 'column' },
}));

// 👇 This component based on Typography
const MyItem = styled(Typography)(({ theme }) => ({
  cursor: 'pointer',
  flexGrow: 1,
  '&:hover': { color: '#4f25c8' },
  // 👇 Optional: consider to use theme.breakpoints for this
  ['@media (max-width:780px)']: { paddingBottom: '1rem' },
}));

While the media queries works in here, perhaps consider to use the breakpoints syntax with theme for a potentially cleaner solution.

// 👇 Optional: replaces @media line in MyToolbar
[theme.breakpoints.down('md')]: { flexDirection: 'column' }

// 👇 Optional: replaces @media line in MyItem
[theme.breakpoints.down('md')]: { paddingBottom: '1rem' }

Otherwise, if it is in some (less common) situations that theme is not needed, then {theme} could be omitted in styled syntax, for example:

// 👇 Only when theme is not needed
const MyToolbar = styled(Toolbar)({
  paddingTop: '1.15rem',
  backgroundColor: '#fff',
  color: 'rgba(0, 0, 0, 0.87)',
  position: 'sticky',
  ['@media (max-width:780px)']: { flexDirection: 'column' },
});

// 👇 Only when theme is not needed
const MyItem = styled(Typography)({
  cursor: 'pointer',
  flexGrow: 1,
  '&:hover': { color: '#4f25c8' },
  ['@media (max-width:780px)']: { paddingBottom: '1rem' },
});

After attached with styles, the components MyToolbar and MyItem can then be used in the output, for example:

<MyToolbar>
  <MyItem variant="h5">About Me</MyItem>
  <MyItem variant="h5">Projects</MyItem>
  <MyItem variant="h5">Resume</MyItem>
  <MyItem variant="h5">Contact Me</MyItem>
  <Button>Custom Btn</Button>
</MyToolbar>

Note that the inline styles position="sticky" color="rgba(0, 0, 0, 0.87)" does not work here, and is moved to the above styled. If inline styles are needed, consider use the sx prop.

Hope this will help.

like image 140
John Li Avatar answered Oct 20 '25 03:10

John Li



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!