In this React tutorial, we’ll learn how to implement the Accordion component in React application using the Material-UI library.
The accordion component consists of a tabular structure where each tab contains a section data in a horizontal layout. A user can click on the heading to expand the section and view its content.
Accordion component is used to adjust more information in less space. This makes data representation more interactive where users can view information selectively.
The panels of the accordion can be configured to show only one section so that the open panel collapses automatically when the other panel is clicked to expand.
Material UI library is created exclusively for React applications. It consists of a number of easy to use components with flexible configuration options.
Today we’re going to discuss the use of Material UI Accordion component and its various options by implementing it in a React Js application.
Let’s check how to implement Accordion panels in React using the Material UI library.
Create a React Application
First, we’ll create a new React application using npx create-react-app
command
$ npx create-react-app react-materialui-accordion-app
Move inside the react app
$ cd react-materialui-accordion-app
Run application
$ npm start
Install Material-UI package
After creating the React application, install the Material-UI library package to use its components
$ npm install @material-ui/core
This will install the core package for Material UI
For using Material SVG Icons, run following npm command to install Material UI Icons package
$ npm install @material-ui/icons
Using Accordion Component
The simple and basic Material Accordion is created by adding three components <Accordion/>, <AccordionSummary/>
and <AccordionDetails>.
By default, all the panels of the Accordion can expand or collapse at the same time.
Update the App.js file to implement the Accordion.
import React from 'react';
import './App.css';
import { ExpandMore } from '@material-ui/icons';
import { Accordion, AccordionSummary, AccordionDetails } from '@material-ui/core';
function App() {
return (
<div className="App">
<Accordion>
<AccordionSummary expandIcon={<ExpandMore />}>
Accordion 1
</AccordionSummary>
<AccordionDetails>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse malesuada lacus ex,
sit amet blandit leo lobortis eget.
</AccordionDetails>
</Accordion>
<Accordion>
<AccordionSummary expandIcon={<ExpandMore />}>
Accordion 2
</AccordionSummary>
<AccordionDetails>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse malesuada lacus ex,
sit amet blandit leo lobortis eget.
</AccordionDetails>
</Accordion>
<Accordion>
<AccordionSummary expandIcon={<ExpandMore />}>
Accordion 3
</AccordionSummary>
<AccordionDetails>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse malesuada lacus ex,
sit amet blandit leo lobortis eget.
</AccordionDetails>
</Accordion>
</div>
);
}
export default App;
This will create an Accordion component where the user can open all the panels at the same time.
Open Only One Panel using Controlled Accordion
The expanded
property of <Accordion/>
component can be used to control the behavior of Accordion by passing an expression.
Here we, ll deploy a state by using the useState
hook inside the App functional component and handling the onChange
event to update the state.
const [expandedPanel, setExpandedPanel] = useState(false);
const handleAccordionChange = (panel) => (event, isExpanded) => {
console.log({ event, isExpanded });
setExpandedPanel(isExpanded ? panel : false);
};
Now update the App.js with Accordion components having expanded
and onChange
event handler
import React, { useState } from 'react';
import './App.css';
import { ExpandMore } from '@material-ui/icons';
import { Accordion, AccordionSummary, AccordionDetails } from '@material-ui/core';
function App() {
const [expandedPanel, setExpandedPanel] = useState(false);
const handleAccordionChange = (panel) => (event, isExpanded) => {
console.log({ event, isExpanded });
setExpandedPanel(isExpanded ? panel : false);
};
return (
<div className="App">
<Accordion expanded={expandedPanel === 'panel1'} onChange={handleAccordionChange('panel1')}>
<AccordionSummary expandIcon={<ExpandMore />}>
Accordion 1
</AccordionSummary>
<AccordionDetails>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse malesuada lacus ex,
sit amet blandit leo lobortis eget.
</AccordionDetails>
</Accordion>
<Accordion expanded={expandedPanel === 'panel2'} onChange={handleAccordionChange('panel2')}>
<AccordionSummary expandIcon={<ExpandMore />}>
Accordion 2
</AccordionSummary>
<AccordionDetails>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse malesuada lacus ex,
sit amet blandit leo lobortis eget.
</AccordionDetails>
</Accordion>
<Accordion expanded={expandedPanel === 'panel3'} onChange={handleAccordionChange('panel3')}>
<AccordionSummary expandIcon={<ExpandMore />}>
Accordion 3
</AccordionSummary>
<AccordionDetails>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse malesuada lacus ex,
sit amet blandit leo lobortis eget.
</AccordionDetails>
</Accordion>
</div>
);
}
export default App;
As the expandedPanel
state can have only the name of the clicked panel, only one panel will be expanded and for other false will be returned to collapse.
Adding Form Contol Elements
Form control elements like Checkboxes, Switches, Input, etc can also be added in the Accordion panels.
But control elements must stop propagation on focus and click events to disable expand.collapse function.
<div className="App">
<Accordion>
<AccordionSummary
expandIcon={<ExpandMore />}
aria-label="Expand"
aria-controls="additional-actions1-content"
id="additional-actions1-header"
>
<FormControlLabel
aria-label="Acknowledge"
onClick={(event) => event.stopPropagation()}
onFocus={(event) => event.stopPropagation()}
control={<Checkbox />}
label="I acknowledge that I should stop the click event propagation"
/>
</AccordionSummary>
<AccordionDetails>
Checkbox control on panel
</AccordionDetails>
</Accordion>
<Accordion>
<AccordionSummary
expandIcon={<ExpandMore />}
aria-label="Expand"
aria-controls="additional-actions2-content"
id="additional-actions2-header"
>
<FormControlLabel
aria-label="Enable"
onClick={(event) => event.stopPropagation()}
onFocus={(event) => event.stopPropagation()}
control={<Switch />}
label="Enable Security"
/>
</AccordionSummary>
<AccordionDetails>
Switch control on Panel
</AccordionDetails>
</Accordion>
<Accordion>
<AccordionSummary
expandIcon={<ExpandMore />}
aria-label="Expand"
aria-controls="additional-actions3-content"
id="additional-actions3-header"
>
<FormControlLabel
aria-label="Enter Name"
onClick={(event) => event.stopPropagation()}
onFocus={(event) => event.stopPropagation()}
control={<TextField />}
label="Enter your name"
/>
</AccordionSummary>
<AccordionDetails>
Text field on Panel
</AccordionDetails>
</Accordion>
</div>
Action Button bar on Accordion Panel
The <AccordionActions
/> component can be used to add action button controls.
<Accordion>
<AccordionSummary expandIcon={<ExpandMore />}>
Accordion 1
</AccordionSummary>
<AccordionDetails>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse malesuada lacus ex,
sit amet blandit leo lobortis eget.
</AccordionDetails>
<Divider />
<AccordionActions>
<Button size="small" onClick={() => alert('cancel')}>Cancel</Button>
<Button size="small" color="primary" onClick={() => alert('save')}>Save</Button>
</AccordionActions>
</Accordion>
Customize the Style of Accordion
The withStyles
function can be used to customize the style of any Material UI component.
import React from 'react';
import './App.css';
import { withStyles } from '@material-ui/core/styles';
import { ExpandMore } from '@material-ui/icons';
import MuiAccordion from '@material-ui/core/Accordion';
import MuiAccordionSummary from '@material-ui/core/AccordionSummary';
import MuiAccordionDetails from '@material-ui/core/AccordionDetails';
import { AccordionActions, Button, Divider } from '@material-ui/core';
const Accordion = withStyles({
root: {
border: '1px solid rgba(0, 0, 0, .125)',
boxShadow: 'none',
borderRadius: '30px 0px 30px 0',
'&:not(:last-child)': {
borderBottom: 0,
},
'&:before': {
display: 'none',
},
'&$expanded': {
margin: 'auto',
},
},
expanded: {},
})(MuiAccordion);
const AccordionSummary = withStyles({
root: {
backgroundColor: '#21CFFF',
borderBottom: '1px solid #12738E',
marginBottom: -1,
color: '#666666',
borderRadius: '30px 0px 30px 0',
minHeight: 56,
'&$expanded': {
minHeight: 56,
},
},
content: {
'&$expanded': {
margin: '12px 0',
},
},
expanded: {},
})(MuiAccordionSummary);
const AccordionDetails = withStyles((theme) => ({
root: {
padding: theme.spacing(2),
},
}))(MuiAccordionDetails);
function App() {
return (
<div className="App">
<Accordion>
<AccordionSummary expandIcon={<ExpandMore />}>
Accordion 1
</AccordionSummary>
<AccordionDetails>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse malesuada lacus ex,
sit amet blandit leo lobortis eget.
</AccordionDetails>
<Divider />
<AccordionActions>
<Button size="small" onClick={() => alert('cancel')}>Cancel</Button>
<Button size="small" color="primary" onClick={() => alert('save')}>Save</Button>
</AccordionActions>
</Accordion>
<Accordion>
<AccordionSummary expandIcon={<ExpandMore />}>
Accordion 2
</AccordionSummary>
<AccordionDetails>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse malesuada lacus ex,
sit amet blandit leo lobortis eget.
</AccordionDetails>
</Accordion>
<Accordion>
<AccordionSummary expandIcon={<ExpandMore />}>
Accordion 3
</AccordionSummary>
<AccordionDetails>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse malesuada lacus ex,
sit amet blandit leo lobortis eget.
</AccordionDetails>
</Accordion>
</div>
);
}
export default App;
How to Disable the Accordion Panel?
The disabled="true"
property is added to the <Accordion/> component to disable expand collapse actions.
Conclusion
Using Material UI component is very easy with support to customize any of the Components by using the style methods. Above we checked how to implement the Accordion Material UI component in React application very easily.
Leave a Reply