content logo

React Accordions:

React Accordion with Plus / Minus Icons

This post will introduce an attractive accordion code for your website. So, if you have a page and want to differentiate it from others, download this React Accordion with Plus / Minus Icons. If you use this React Accordion Code on your page, you can have a different website from others and attract more viewers. As it is a Simple Accordion Source code, you can use it for websites with different designs.

You can look at the preview of the HTML Accordion Sample below to recognize it better. In this preview, you face various items with a gray background and black text. These items are separated with some white lines. On the right side of each item, you can see some plus (+) icons in black color. When you select these items, you will face an additional text with a hover effect in gray color. This field is connected to its related item and has the same background. Additionally, the plus icon of the selected part changes to the minus (-) icon. If you want to close your selected section, you have to click on the minus icon once again. This Accordion Plus Minus Icons is the best for all kinds of websites.

#

React Accordion Code

#

Simple Accordion Source

#

HTML Accordion Sample

#

Accordion Plus Minus Icons

<!-- This script got from frontendfreecode.com -->
<div id="app"></div><a style="font-size: 8pt; text-decoration: none" target="_blank" href="http://frontendfreecode.com">Free Frontend</a>
                                                                            
*,
*:after,
*:before {
  box-sizing: inherit;
}
body {
  display: flex;
  justify-content: center;
  padding: 50px 0;
  background-color: #fcfcfc;
  min-height: 100vh;
  font-size: 16px;
  line-height: 1.4;
  font-family: 'Montserrat', sans-serif;
  color: #372717;
  box-sizing: border-box;
  overflow-y: scroll;
}
.accordion {
  width: 100%;
  max-width: 470px;
}
.panel {
  background-color: #f0ebe1;
}
.panel__label {
  position: relative;
  display: block;
  width: 100%;
  background: none;
  border: none;
  text-align: left;
  padding: 25px 60px 25px 25px;
  font-weight: 500;
  font-size: 17px;
  font-family: inherit;
  transition: color 0.2s linear;
  cursor: pointer;
}
.panel__label:focus {
  outline: none;
}
.panel__label:after,
.panel__label:before {
  content: '';
  position: absolute;
  right: 25px;
  top: 50%;
  width: 22px;
  height: 2px;
  margin-top: -2px;
  background-color: #372717;
}
.panel__label:before {
  transform: rotate(-90deg);
  transition: transform 0.35s cubic-bezier(0.65, 0.05, 0.36, 1);
}
.panel[aria-expanded='true'] .panel__content {
  opacity: 1;
}
.panel[aria-expanded='true'] .panel__label {
  color: #957029;
}
.panel[aria-expanded='true'] .panel__label:before {
  transform: rotate(0deg);
}
.panel__inner {
  overflow: hidden;
  will-change: height;
  transition: height 0.4s cubic-bezier(0.65, 0.05, 0.36, 1);
}
.panel__content {
  margin: 5px 25px 25px;
  font-size: 14px;
  color: #756658;
  opacity: 0;
  transition: opacity 0.3s linear 0.18s;
}
.panel:not(:last-child) {
  margin-bottom: 3px;
}
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } class Panel extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            height: 0
        };
    }
    componentDidMount() {
        window.setTimeout(() => {
            const el = ReactDOM.findDOMNode(this);
            const height = el.querySelector('.panel__inner').scrollHeight;
            this.setState({
                height
            });
        }, 333);
    }
    render() {
        const { label, content, activeTab, index, activateTab } = this.props;
        const { height } = this.state;
        const isActive = activeTab === index;
        const innerStyle = {
            height: `${isActive ? height : 0}px`
        };
        return /*#__PURE__*/(
            React.createElement("div", {
                className: "panel",
                role: "tabpanel",
                "aria-expanded": isActive
            }, /*#__PURE__*/
                React.createElement("button", {
                    className: "panel__label",
                    role: "tab",
                    onClick: activateTab
                },
                    label), /*#__PURE__*/
                React.createElement("div", {
                    className: "panel__inner",
                    style: innerStyle,
                    "aria-hidden": !isActive
                }, /*#__PURE__*/
                    React.createElement("p", { className: "panel__content" },
                        content))));
    }
}
class Accordion extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            activeTab: 0
        };
        this.activateTab = this.activateTab.bind(this);
    }
    activateTab(index) {
        this.setState(prev => ({
            activeTab: prev.activeTab === index ? -1 : index
        }));
    }
    render() {
        const { panels } = this.props;
        const { activeTab } = this.state;
        return /*#__PURE__*/(
            React.createElement("div", { className: "accordion", role: "tablist" },
                panels.map((panel, index) => /*#__PURE__*/
                    React.createElement(Panel, _extends({
                        key: index,
                        activeTab: activeTab,
                        index: index
                    },
                        panel, {
                        activateTab: this.activateTab.bind(null, index)
                    })))));
    }
}
const panels = [
    {
        label: 'Lorem ipsum dolor sit',
        content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua'
    },
    {
        label: 'Screen Readers Actually Read That Stuff',
        content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.'
    },
    {
        label: 'Lorem ipsum dolor sit',
        content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.'
    },
    {
        label: 'Lorem ipsum dolor sit',
        content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.'
    },
    {
        label: 'Lorem ipsum dolor sit',
        content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua'
    }];
const App = document.querySelector('#app');
ReactDOM.render( /*#__PURE__*/React.createElement(Accordion, { panels: panels }), App);
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,500" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.min.css">
<script src='https://cdnjs.cloudflare.com/ajax/libs/react/15.4.2/react.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/react/15.4.2/react-dom.min.js'></script>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<!-- This script got from frontendfreecode.com -->

<link href="https://fonts.googleapis.com/css?family=Montserrat:400,500" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.min.css">
<script src='https://cdnjs.cloudflare.com/ajax/libs/react/15.4.2/react.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/react/15.4.2/react-dom.min.js'></script>
<style>
*,
*:after,
*:before {
  box-sizing: inherit;
}
body {
  display: flex;
  justify-content: center;
  padding: 50px 0;
  background-color: #fcfcfc;
  min-height: 100vh;
  font-size: 16px;
  line-height: 1.4;
  font-family: 'Montserrat', sans-serif;
  color: #372717;
  box-sizing: border-box;
  overflow-y: scroll;
}
.accordion {
  width: 100%;
  max-width: 470px;
}
.panel {
  background-color: #f0ebe1;
}
.panel__label {
  position: relative;
  display: block;
  width: 100%;
  background: none;
  border: none;
  text-align: left;
  padding: 25px 60px 25px 25px;
  font-weight: 500;
  font-size: 17px;
  font-family: inherit;
  transition: color 0.2s linear;
  cursor: pointer;
}
.panel__label:focus {
  outline: none;
}
.panel__label:after,
.panel__label:before {
  content: '';
  position: absolute;
  right: 25px;
  top: 50%;
  width: 22px;
  height: 2px;
  margin-top: -2px;
  background-color: #372717;
}
.panel__label:before {
  transform: rotate(-90deg);
  transition: transform 0.35s cubic-bezier(0.65, 0.05, 0.36, 1);
}
.panel[aria-expanded='true'] .panel__content {
  opacity: 1;
}
.panel[aria-expanded='true'] .panel__label {
  color: #957029;
}
.panel[aria-expanded='true'] .panel__label:before {
  transform: rotate(0deg);
}
.panel__inner {
  overflow: hidden;
  will-change: height;
  transition: height 0.4s cubic-bezier(0.65, 0.05, 0.36, 1);
}
.panel__content {
  margin: 5px 25px 25px;
  font-size: 14px;
  color: #756658;
  opacity: 0;
  transition: opacity 0.3s linear 0.18s;
}
.panel:not(:last-child) {
  margin-bottom: 3px;
}
</style>

</head>
<body>
<div id="app"></div><div id="bcl"><a style="font-size:8pt;text-decoration:none;" href="http://www.devanswer.com">Free Frontend</a></div>
<script>
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } class Panel extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            height: 0
        };
    }
    componentDidMount() {
        window.setTimeout(() => {
            const el = ReactDOM.findDOMNode(this);
            const height = el.querySelector('.panel__inner').scrollHeight;
            this.setState({
                height
            });
        }, 333);
    }
    render() {
        const { label, content, activeTab, index, activateTab } = this.props;
        const { height } = this.state;
        const isActive = activeTab === index;
        const innerStyle = {
            height: `${isActive ? height : 0}px`
        };
        return /*#__PURE__*/(
            React.createElement("div", {
                className: "panel",
                role: "tabpanel",
                "aria-expanded": isActive
            }, /*#__PURE__*/
                React.createElement("button", {
                    className: "panel__label",
                    role: "tab",
                    onClick: activateTab
                },
                    label), /*#__PURE__*/
                React.createElement("div", {
                    className: "panel__inner",
                    style: innerStyle,
                    "aria-hidden": !isActive
                }, /*#__PURE__*/
                    React.createElement("p", { className: "panel__content" },
                        content))));
    }
}
class Accordion extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            activeTab: 0
        };
        this.activateTab = this.activateTab.bind(this);
    }
    activateTab(index) {
        this.setState(prev => ({
            activeTab: prev.activeTab === index ? -1 : index
        }));
    }
    render() {
        const { panels } = this.props;
        const { activeTab } = this.state;
        return /*#__PURE__*/(
            React.createElement("div", { className: "accordion", role: "tablist" },
                panels.map((panel, index) => /*#__PURE__*/
                    React.createElement(Panel, _extends({
                        key: index,
                        activeTab: activeTab,
                        index: index
                    },
                        panel, {
                        activateTab: this.activateTab.bind(null, index)
                    })))));
    }
}
const panels = [
    {
        label: 'Lorem ipsum dolor sit',
        content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua'
    },
    {
        label: 'Screen Readers Actually Read That Stuff',
        content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.'
    },
    {
        label: 'Lorem ipsum dolor sit',
        content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.'
    },
    {
        label: 'Lorem ipsum dolor sit',
        content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.'
    },
    {
        label: 'Lorem ipsum dolor sit',
        content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua'
    }];
const App = document.querySelector('#app');
ReactDOM.render( /*#__PURE__*/React.createElement(Accordion, { panels: panels }), App);
</script>

</body>
</html>
Preview