React + Material UI | Accordion Tabs Tutorial with Example

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.

 

 

2 thoughts on “React + Material UI | Accordion Tabs Tutorial with Example”

Leave a Comment

Your email address will not be published. Required fields are marked *