Material UI is a Material Design library made for React.
It’s a set of React components that have Material Design styles.
In this article, we’ll look at how to add expansion panels with Material UI.
Expansion Panel
Expansion panels let us add boxes that can be expanded and collapsed.
To add a simple one, we can write:
import React from "react";
import ExpansionPanel from "@material-ui/core/ExpansionPanel";
import ExpansionPanelSummary from "@material-ui/core/ExpansionPanelSummary";
import ExpansionPanelDetails from "@material-ui/core/ExpansionPanelDetails";
import Typography from "@material-ui/core/Typography";
import ExpandMoreIcon from "@material-ui/icons/ExpandMore";
export default function App() {
return (
<>
<ExpansionPanel>
<ExpansionPanelSummary
expandIcon={<ExpandMoreIcon />}
id="panel1-header"
>
<Typography>Expansion Panel 1</Typography>
</ExpansionPanelSummary>
<ExpansionPanelDetails>
<Typography>
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
</Typography>
</ExpansionPanelDetails>
</ExpansionPanel>
<ExpansionPanel>
<ExpansionPanelSummary
expandIcon={<ExpandMoreIcon />}
id="panel2-header"
>
<Typography>Expansion Panel 2</Typography>
</ExpansionPanelSummary>
<ExpansionPanelDetails>
<Typography>Sit amet blandit leo lobortis eget.</Typography>
</ExpansionPanelDetails>
</ExpansionPanel>
</>
);
}
to add 2 expansion panels with the ExpansionPanel
s.
The expandIcon
prop holds the icon that’s displayed for letting us expand the panel.
ExpansionPanelDetails
has the content of the expansion panel.
ExpansionPanelSummary
has the content of the heading.
Controlled Accordion
We can make it a controlled component buy passing in the expanded
and onChange
props to the ExpansionPanel
.
For example, we can write:
import React from "react";
import ExpansionPanel from "@material-ui/core/ExpansionPanel";
import ExpansionPanelSummary from "@material-ui/core/ExpansionPanelSummary";
import ExpansionPanelDetails from "@material-ui/core/ExpansionPanelDetails";
import Typography from "@material-ui/core/Typography";
import ExpandMoreIcon from "@material-ui/icons/ExpandMore";
export default function App() {
const [expanded, setExpanded] = React.useState(false);
const handleChange = panel => (event, isExpanded) => {
setExpanded(isExpanded ? panel : false);
};
return (
<>
<ExpansionPanel
expanded={expanded === "panel1"}
onChange={handleChange("panel1")}
>
<ExpansionPanelSummary
expandIcon={<ExpandMoreIcon />}
id="panel1-header"
>
<Typography>Expansion Panel 1</Typography>
</ExpansionPanelSummary>
<ExpansionPanelDetails>
<Typography>
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
</Typography>
</ExpansionPanelDetails>
</ExpansionPanel>
<ExpansionPanel
expanded={expanded === "panel2"}
onChange={handleChange("panel2")}
>
<ExpansionPanelSummary
expandIcon={<ExpandMoreIcon />}
id="panel2-header"
>
<Typography>Expansion Panel 2</Typography>
</ExpansionPanelSummary>
<ExpansionPanelDetails>
<Typography>Sit amet blandit leo lobortis eget.</Typography>
</ExpansionPanelDetails>
</ExpansionPanel>
</>
);
}
to make the expansion panels work together as an accordion.
We have the expanded
prop that sets whether the expansion panel should be expanded.
onChange
is a function that lets us set the panel to be expanded.
We set the panel name with the panel
parameter of the handleChange
function.
Customized Expansion Panels
We can change the styles of the expansion panel components with the withStyles
higher order component.
For instance, we can write:
import React from "react";
import { withStyles } from "@material-ui/core/styles";
import MuiExpansionPanel from "@material-ui/core/ExpansionPanel";
import MuiExpansionPanelSummary from "@material-ui/core/ExpansionPanelSummary";
import MuiExpansionPanelDetails from "@material-ui/core/ExpansionPanelDetails";
import Typography from "@material-ui/core/Typography";
const ExpansionPanel = withStyles({
root: {
color: "blue"
},
expanded: {}
})(MuiExpansionPanel);
const ExpansionPanelSummary = withStyles({
root: {
backgroundColor: "pink"
},
content: {
"&$expanded": {
margin: "12px 0"
}
},
expanded: {}
})(MuiExpansionPanelSummary);
const ExpansionPanelDetails = withStyles(theme => ({
root: {
padding: theme.spacing(2)
}
}))(MuiExpansionPanelDetails);
export default function App() {
const [expanded, setExpanded] = React.useState(false);
const handleChange = panel => (event, isExpanded) => {
setExpanded(isExpanded ? panel : false);
};
return (
<>
<ExpansionPanel
expanded={expanded === "panel1"}
onChange={handleChange("panel1")}
>
<ExpansionPanelSummary id="panel1-header">
<Typography>Expansion Panel 1</Typography>
</ExpansionPanelSummary>
<ExpansionPanelDetails>
<Typography>
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
</Typography>
</ExpansionPanelDetails>
</ExpansionPanel>
<ExpansionPanel
expanded={expanded === "panel2"}
onChange={handleChange("panel2")}
>
<ExpansionPanelSummary id="panel2-header">
<Typography>Expansion Panel 2</Typography>
</ExpansionPanelSummary>
<ExpansionPanelDetails>
<Typography>Sit amet blandit leo lobortis eget.</Typography>
</ExpansionPanelDetails>
</ExpansionPanel>
</>
);
}
We pass in the MuiExpansionPanel
, MuiExpansionPanelSummary
and MuiExpansionPanelDetails
into the function returned by the withStyles
higher-order component.
We make the text color blue and the background of the summary pink.
If we use the component, then we’ll see those colors displayed.
Conclusion
We can create expansion panels that expands or collapses as we wish.
Also, we can change the styles of each component to fit our needs.