admin管理员组

文章数量:1279011

I am having an issue trying to use MUI Styled () on bigger scale: can someone take a look at the code we used to use in prior versions and let me know how to replicate it in MUI V5.

Old way:

const useStyles = makeStyles((theme) => ({
  root: {
    backgroundColor: "#fdfdff",
  },
  pageHeader: {
    padding: theme.spacing(4),
    display: "flex",
    marginBottom: theme.spacing,
  },
  pageIcon: {
    display: "inline-block",
    padding: theme.spacing(2),
    color: "#3c44b1",
  },
  pageTitle: {
    paddingLeft: theme.spacing(4),
    "& .MuiTypography-subtitle2": {
      opacity: "0.6",
    },
  },
}));
export default function PageHeader(props) {
  const classes = useStyles();
  const { title, subTitle, icon } = props;
  return (
    <Paper elevation={0} square className={classes.root}>
      <div className={classes.pageHeader}>
        <Card className={classes.pageIcon}>{icon}</Card>
        <div className={classes.pageTitle}>
          <Typography variant="h6" ponent="div">
            {title}
          </Typography>
          <Typography variant="subtitle2" ponent="div">
            {subTitle}
          </Typography>
        </div>
      </div>
    </Paper>
  );
}

My attempt to acplish the same in MUI V5 is not working properly. it renders but it doesn't look the same and it's all over the place.

const rootStyle = styled("div")({
  backgroundColor: "#fdfdff",
});
const headerStyle = styled("div")(({ theme }) => ({
  padding: theme.spacing(4),
  display: "flex",
  marginBottom: theme.spacing,
}));
const iconStyle = styled("div")(({ theme }) => ({
  display: "inline-block",
  padding: theme.spacing(2),
  color: "#3c44b1",
}));
const titleStyle = styled("div")(({ theme }) => ({
  paddingLeft: theme.spacing(4),
  "& .MuiTypography-subtitle2": {
    opacity: "0.6",
  },
}));

export default function PageHeader(props) {
  const { title, subTitle, icon } = props;
  return (
    <rootStyle>
      <Paper elevation={0} square>
        <headerStyle>
          <iconStyle>
            <Card>{icon}</Card>
          </iconStyle>
          <titleStyle>
            <Typography variant="h6" ponent="div">
              {title}
            </Typography>
            <Typography variant="subtitle2" ponent="div">
              {subTitle}
            </Typography>
          </titleStyle>
        </headerStyle>
      </Paper>
    </rootStyle>
  );
}

I am new to MUI and there are not a lot of examples out there that cover this. I truly appreciate your help!

I am having an issue trying to use MUI Styled () on bigger scale: can someone take a look at the code we used to use in prior versions and let me know how to replicate it in MUI V5.

Old way:

const useStyles = makeStyles((theme) => ({
  root: {
    backgroundColor: "#fdfdff",
  },
  pageHeader: {
    padding: theme.spacing(4),
    display: "flex",
    marginBottom: theme.spacing,
  },
  pageIcon: {
    display: "inline-block",
    padding: theme.spacing(2),
    color: "#3c44b1",
  },
  pageTitle: {
    paddingLeft: theme.spacing(4),
    "& .MuiTypography-subtitle2": {
      opacity: "0.6",
    },
  },
}));
export default function PageHeader(props) {
  const classes = useStyles();
  const { title, subTitle, icon } = props;
  return (
    <Paper elevation={0} square className={classes.root}>
      <div className={classes.pageHeader}>
        <Card className={classes.pageIcon}>{icon}</Card>
        <div className={classes.pageTitle}>
          <Typography variant="h6" ponent="div">
            {title}
          </Typography>
          <Typography variant="subtitle2" ponent="div">
            {subTitle}
          </Typography>
        </div>
      </div>
    </Paper>
  );
}

My attempt to acplish the same in MUI V5 is not working properly. it renders but it doesn't look the same and it's all over the place.

const rootStyle = styled("div")({
  backgroundColor: "#fdfdff",
});
const headerStyle = styled("div")(({ theme }) => ({
  padding: theme.spacing(4),
  display: "flex",
  marginBottom: theme.spacing,
}));
const iconStyle = styled("div")(({ theme }) => ({
  display: "inline-block",
  padding: theme.spacing(2),
  color: "#3c44b1",
}));
const titleStyle = styled("div")(({ theme }) => ({
  paddingLeft: theme.spacing(4),
  "& .MuiTypography-subtitle2": {
    opacity: "0.6",
  },
}));

export default function PageHeader(props) {
  const { title, subTitle, icon } = props;
  return (
    <rootStyle>
      <Paper elevation={0} square>
        <headerStyle>
          <iconStyle>
            <Card>{icon}</Card>
          </iconStyle>
          <titleStyle>
            <Typography variant="h6" ponent="div">
              {title}
            </Typography>
            <Typography variant="subtitle2" ponent="div">
              {subTitle}
            </Typography>
          </titleStyle>
        </headerStyle>
      </Paper>
    </rootStyle>
  );
}

I am new to MUI and there are not a lot of examples out there that cover this. I truly appreciate your help!

Share Improve this question edited Nov 7, 2021 at 2:54 Ryan Cogswell 81.1k9 gold badges241 silver badges212 bronze badges asked Nov 6, 2021 at 1:55 MoeMoe 1,5375 gold badges38 silver badges59 bronze badges 6
  • This should solve your problem. – NearHuscarl Commented Nov 6, 2021 at 2:13
  • Here the docs for the new way of spacing: mui./system/spacing – ale917k Commented Nov 6, 2021 at 2:26
  • I think the part in App.js is correct, the question now how can we replace makeStyles with the new way. I am not just after spacing; I am after how to use theme in v5 – Moe Commented Nov 6, 2021 at 2:33
  • @Moe you can use sx prop/styled in v5. There is a bunch of examples on the docs to show you how to use them. – NearHuscarl Commented Nov 6, 2021 at 3:55
  • I updated the question; can you provide an example of how to replicate what I have using styled – Moe Commented Nov 6, 2021 at 13:55
 |  Show 1 more ment

1 Answer 1

Reset to default 9

Below is a v5 version of your code with the same look as the v4 version. I added default values for the props just for demonstration purposes.

You had two main issues:

  1. You added additional div layers for the styling rather than styling the elements that originally received the styles (e.g. Paper, Card).

  2. You assigned the styled divs to variable names that start with a lowercase letter which caused them to be rendered as DOM tags rather than ponents (so the styling would have been pletely ignored).

From https://reactjs/docs/ponents-and-props.html#rendering-a-ponent:

React treats ponents starting with lowercase letters as DOM tags.

import Paper from "@mui/material/Paper";
import Card from "@mui/material/Card";
import Typography from "@mui/material/Typography";
import { styled } from "@mui/material/styles";
import PersonIcon from "@mui/icons-material/Person";

const StyledPaper = styled(Paper)({
  backgroundColor: "#fdfdff"
});
const HeaderDiv = styled("div")(({ theme }) => ({
  padding: theme.spacing(4),
  display: "flex",
  marginBottom: theme.spacing
}));
const StyledCard = styled(Card)(({ theme }) => ({
  display: "inline-block",
  padding: theme.spacing(2),
  color: "#3c44b1"
}));
const TitleDiv = styled("div")(({ theme }) => ({
  paddingLeft: theme.spacing(4),
  "& .MuiTypography-subtitle2": {
    opacity: "0.6"
  }
}));

export default function PageHeader(props) {
  const {
    title = "Title",
    subTitle = "sub-title",
    icon = <PersonIcon />
  } = props;
  return (
    <StyledPaper elevation={0} square>
      <HeaderDiv>
        <StyledCard>{icon}</StyledCard>
        <TitleDiv>
          <Typography variant="h6" ponent="div">
            {title}
          </Typography>
          <Typography variant="subtitle2" ponent="div">
            {subTitle}
          </Typography>
        </TitleDiv>
      </HeaderDiv>
    </StyledPaper>
  );
}

An alternative (and much more concise) way to convert the v4 code to v5 is to use the sx prop:

import Paper from "@mui/material/Paper";
import Card from "@mui/material/Card";
import Typography from "@mui/material/Typography";
import PersonIcon from "@mui/icons-material/Person";
import Box from "@mui/material/Box";

export default function PageHeader(props) {
  const {
    title = "Title",
    subTitle = "sub-title",
    icon = <PersonIcon />
  } = props;
  return (
    <Paper elevation={0} square sx={{ bgcolor: "#fdfdff" }}>
      <Box sx={{ p: 4, display: "flex", mb: 1 }}>
        <Card sx={{ display: "inline-block", p: 2, color: "#3c44b1" }}>
          {icon}
        </Card>
        <Box sx={{ pl: 4, "& .MuiTypography-subtitle2": { opacity: 0.6 } }}>
          <Typography variant="h6" ponent="div">
            {title}
          </Typography>
          <Typography variant="subtitle2" ponent="div">
            {subTitle}
          </Typography>
        </Box>
      </Box>
    </Paper>
  );
}

Here is one more option using a single styled call, though in my opinion this would be more brittle to maintain than the other options:

import Paper from "@mui/material/Paper";
import Card from "@mui/material/Card";
import Typography from "@mui/material/Typography";
import { styled } from "@mui/material/styles";
import PersonIcon from "@mui/icons-material/Person";

const StyledPaper = styled(Paper)(({ theme }) => ({
  backgroundColor: "#fdfdff",
  "& > div": {
    padding: theme.spacing(4),
    display: "flex",
    marginBottom: theme.spacing(1),
    "& .MuiCard-root": {
      display: "inline-block",
      padding: theme.spacing(2),
      color: "#3c44b1"
    },
    "& > div": {
      paddingLeft: theme.spacing(4),
      "& .MuiTypography-subtitle2": {
        opacity: "0.6"
      }
    }
  }
}));

export default function PageHeader(props) {
  const {
    title = "Title",
    subTitle = "sub-title",
    icon = <PersonIcon />
  } = props;
  return (
    <StyledPaper elevation={0} square>
      <div>
        <Card>{icon}</Card>
        <div>
          <Typography variant="h6" ponent="div">
            {title}
          </Typography>
          <Typography variant="subtitle2" ponent="div">
            {subTitle}
          </Typography>
        </div>
      </div>
    </StyledPaper>
  );
}

本文标签: javascriptHow to properly use Styled() with MUI V5Stack Overflow