content logo

React Accordions:

One Open, Multi Open and Nested Accordions using React JS

One of the most critical parts of any website is its menu. So, it is better to use a menu on your website to gain more viewers. We are going to introduce the One Open, Multi Open and Nested Accordions using React JS in the current paper. This React JS Accordion code is simple and as a result, you can use it for different kinds of websites with various themes. Besides its simplicity, this Nested Accordion Code allows you to categorize different contents of your website into some items and increase the beauty of your website.

If you look at the preview of this Multi Open Accordion Code, you can realize it has a black background with white writing. There is a triangle on the right side of each field presented in white color. When you click on this part of the One Open Accordion code, a sub-category will be present below with a white background and black writing. If you want to close this item, click on the triangle again. All the texts of this code are customizable and you are able to change them based on the content of your website.

#

React JS Accordion

#

Nested Accordion Code

#

Multi Open Accordion Code

#

One Open Accordion

<!-- This script got from frontendfreecode.com -->
<div id="root"></div><a style="font-size: 8pt; text-decoration: none" target="_blank" href="http://frontendfreecode.com">Free Frontend</a>
                                                                            
body {
	padding: 30px;
}
h2 {
	font-size: 18px;
	line-height: 1em;
	margin-bottom: 5px;
}
.accordion-box {
	margin-bottom: 100px;
}
.accordion-list .accordion-box:last-child {
	margin-bottom: 5px;
}
.accordion-label {
	position: relative;
	cursor: pointer;
	display: block;
	padding: 10px 50px 10px 10px;
	color: #fff;
	background-color: #222;
}
.accordion-content {
	max-height: 0;
	overflow: hidden;
}
.accordion-inner {
	background-color: #eee;
	padding: 15px;
}
.accordion-list.actived>.accordion-content {
	max-height: none;
}
.acd-sub {
	padding: 10px;
}
.acd-arrow {
	position: absolute;
	right: 15px;
	top: 16px;
	display: inline-block;
	vertical-align: middle;
	width: 0;
	height: 0;
	border-style: solid;
	border-color: transparent;
	border-width: 8px 8px 0px 8px;
	border-top-color: #fff;
}
.accordion-list.actived>.accordion-label>.acd-arrow {
	-webkit-transform: rotate(180deg);
	transform: rotate(180deg);
}
.acd-transition>.accordion-label>.acd-arrow {
	-webkit-transition: -webkit-transform 0.3s ease;
	transition: transform 0.3s ease;
}
"use strict";
class App extends React.Component {
    render() {
        return (React.createElement("div", null,
            React.createElement("h2", null, "Only One Open"),
            React.createElement(Accordion, { muitipleOpen: false },
                React.createElement(AccordionList, { expanded: true, id: "1", key: "1", headTitle: "Title 1" }, "Content 1"),
                React.createElement(AccordionList, { expanded: false, id: "2", key: "2", headTitle: "Title 2" }, "Content 2"),
                React.createElement(AccordionList, { expanded: false, id: "3", key: "3", headTitle: "Title 3" }, "Content 3"),
                React.createElement(AccordionList, { expanded: false, id: "4", key: "4", headTitle: "Title 4" }, "Content 4")),
            React.createElement("h2", null, "Multiple Open"),
            React.createElement(Accordion, { muitipleOpen: true },
                React.createElement(AccordionList, { expanded: false, id: "1", key: "1", headTitle: "Title 1" }, "Content 1"),
                React.createElement(AccordionList, { expanded: true, id: "2", key: "2", headTitle: "Title 2" }, "Content 2"),
                React.createElement(AccordionList, { expanded: false, id: "3", key: "3", headTitle: "Title 3" }, "Content 3"),
                React.createElement(AccordionList, { expanded: false, id: "4", key: "4", headTitle: "Title 4" }, "Content 4")),
            React.createElement("h2", null, "Nested Accordion"),
            React.createElement(Accordion, { muitipleOpen: false },
                React.createElement(AccordionList, { expanded: true, id: "1", key: "1", headTitle: "Title 1" },
                    "Content 1",
                    React.createElement("br", null),
                    React.createElement("br", null),
                    React.createElement(Accordion, { muitipleOpen: false },
                        React.createElement(AccordionList, { expanded: false, id: "1", key: "1", headTitle: "Nested Title 1" }, "Content 1"),
                        React.createElement(AccordionList, { expanded: false, id: "2", key: "2", headTitle: "Nested Title 2" }, "Content 2"),
                        React.createElement(AccordionList, { expanded: false, id: "3", key: "3", headTitle: "Nested Title 3" }, "Content 3"))),
                React.createElement(AccordionList, { expanded: false, id: "2", key: "2", headTitle: "Title 2" }, "Content 2"))));
    }
}
class Accordion extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            activedIndex: this.getID(),
            acdTransition: false
        };
    }
    getID() {
        let expandedIndex = [];
        let children = this.props.children;
        React.Children.map(children, (items, i) => {
            if (items.props.expanded) {
                expandedIndex.push(items.props.id);
            }
        });
        return expandedIndex;
    }
    addTransition() {
        if (this.state.acdTransition === true) {
            return 'acd-transition';
        }
        else {
            return "";
        }
    }
    handleClick(acdID) {
        let muitipleOpen = this.props.muitipleOpen;
        let activedList = [...this.state.activedIndex];
        let activedItem = this.state.activedIndex.indexOf(acdID);
        if (muitipleOpen) {
            if (activedItem !== -1) {
                activedList.splice(activedItem, 1);
                this.setState({ activedIndex: activedList });
            }
            else {
                this.setState({ activedIndex: [...activedList, acdID] });
            }
        }
        else {
            if (activedItem !== -1) {
                activedList.splice(activedItem, 1);
                this.setState({ activedIndex: activedList });
            }
            else {
                this.setState({ activedIndex: [acdID] });
            }
        }
        if (this.state.acdTransition === false) {
            this.setState({ acdTransition: true });
        }
    }
    isExpanded(acdID) {
        if (this.state.activedIndex.includes(acdID)) {
            return 'actived';
        }
        else {
            return '';
        }
    }
    render() {
        let childArr = this.props.children;
        if (childArr.length === undefined) {
            childArr = [this.props.children];
        }
        const items = childArr.map((child, i) => {
            //let newIndex = i + 1;
            return React.cloneElement(child, {
                isExpanded: this.isExpanded.bind(this),
                handleClick: this.handleClick.bind(this),
                addTransition: this.addTransition.bind(this)
            });
        });
        return (React.createElement("div", { className: `accordion-box` }, items));
    }
}
class AccordionList extends React.Component {
    render() {
        return (React.createElement("div", { className: `accordion-list ${this.props.isExpanded(this.props.id)} ${this.props.addTransition()}` },
            React.createElement("div", { className: `accordion-label`, onClick: () => { this.props.handleClick(this.props.id); } },
                this.props.headTitle,
                " ",
                React.createElement("span", { className: "acd-arrow" })),
            React.createElement("div", { className: `accordion-content` },
                React.createElement("div", { className: "accordion-inner" }, this.props.children))));
    }
}
ReactDOM.render(React.createElement(App, null), document.getElementById('root'));
<script src='https://cdnjs.cloudflare.com/ajax/libs/react/15.3.1/react.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/react/15.3.1/react-dom.min.js'></script>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<!-- This script got from frontendfreecode.com -->

<script src='https://cdnjs.cloudflare.com/ajax/libs/react/15.3.1/react.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/react/15.3.1/react-dom.min.js'></script>
<style>
body {
	padding: 30px;
}
h2 {
	font-size: 18px;
	line-height: 1em;
	margin-bottom: 5px;
}
.accordion-box {
	margin-bottom: 100px;
}
.accordion-list .accordion-box:last-child {
	margin-bottom: 5px;
}
.accordion-label {
	position: relative;
	cursor: pointer;
	display: block;
	padding: 10px 50px 10px 10px;
	color: #fff;
	background-color: #222;
}
.accordion-content {
	max-height: 0;
	overflow: hidden;
}
.accordion-inner {
	background-color: #eee;
	padding: 15px;
}
.accordion-list.actived>.accordion-content {
	max-height: none;
}
.acd-sub {
	padding: 10px;
}
.acd-arrow {
	position: absolute;
	right: 15px;
	top: 16px;
	display: inline-block;
	vertical-align: middle;
	width: 0;
	height: 0;
	border-style: solid;
	border-color: transparent;
	border-width: 8px 8px 0px 8px;
	border-top-color: #fff;
}
.accordion-list.actived>.accordion-label>.acd-arrow {
	-webkit-transform: rotate(180deg);
	transform: rotate(180deg);
}
.acd-transition>.accordion-label>.acd-arrow {
	-webkit-transition: -webkit-transform 0.3s ease;
	transition: transform 0.3s ease;
}
</style>

</head>
<body>
<div id="root"></div><div id="bcl"><a style="font-size:8pt;text-decoration:none;" href="http://www.devanswer.com">Free Frontend</a></div>
<script>
"use strict";
class App extends React.Component {
    render() {
        return (React.createElement("div", null,
            React.createElement("h2", null, "Only One Open"),
            React.createElement(Accordion, { muitipleOpen: false },
                React.createElement(AccordionList, { expanded: true, id: "1", key: "1", headTitle: "Title 1" }, "Content 1"),
                React.createElement(AccordionList, { expanded: false, id: "2", key: "2", headTitle: "Title 2" }, "Content 2"),
                React.createElement(AccordionList, { expanded: false, id: "3", key: "3", headTitle: "Title 3" }, "Content 3"),
                React.createElement(AccordionList, { expanded: false, id: "4", key: "4", headTitle: "Title 4" }, "Content 4")),
            React.createElement("h2", null, "Multiple Open"),
            React.createElement(Accordion, { muitipleOpen: true },
                React.createElement(AccordionList, { expanded: false, id: "1", key: "1", headTitle: "Title 1" }, "Content 1"),
                React.createElement(AccordionList, { expanded: true, id: "2", key: "2", headTitle: "Title 2" }, "Content 2"),
                React.createElement(AccordionList, { expanded: false, id: "3", key: "3", headTitle: "Title 3" }, "Content 3"),
                React.createElement(AccordionList, { expanded: false, id: "4", key: "4", headTitle: "Title 4" }, "Content 4")),
            React.createElement("h2", null, "Nested Accordion"),
            React.createElement(Accordion, { muitipleOpen: false },
                React.createElement(AccordionList, { expanded: true, id: "1", key: "1", headTitle: "Title 1" },
                    "Content 1",
                    React.createElement("br", null),
                    React.createElement("br", null),
                    React.createElement(Accordion, { muitipleOpen: false },
                        React.createElement(AccordionList, { expanded: false, id: "1", key: "1", headTitle: "Nested Title 1" }, "Content 1"),
                        React.createElement(AccordionList, { expanded: false, id: "2", key: "2", headTitle: "Nested Title 2" }, "Content 2"),
                        React.createElement(AccordionList, { expanded: false, id: "3", key: "3", headTitle: "Nested Title 3" }, "Content 3"))),
                React.createElement(AccordionList, { expanded: false, id: "2", key: "2", headTitle: "Title 2" }, "Content 2"))));
    }
}
class Accordion extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            activedIndex: this.getID(),
            acdTransition: false
        };
    }
    getID() {
        let expandedIndex = [];
        let children = this.props.children;
        React.Children.map(children, (items, i) => {
            if (items.props.expanded) {
                expandedIndex.push(items.props.id);
            }
        });
        return expandedIndex;
    }
    addTransition() {
        if (this.state.acdTransition === true) {
            return 'acd-transition';
        }
        else {
            return "";
        }
    }
    handleClick(acdID) {
        let muitipleOpen = this.props.muitipleOpen;
        let activedList = [...this.state.activedIndex];
        let activedItem = this.state.activedIndex.indexOf(acdID);
        if (muitipleOpen) {
            if (activedItem !== -1) {
                activedList.splice(activedItem, 1);
                this.setState({ activedIndex: activedList });
            }
            else {
                this.setState({ activedIndex: [...activedList, acdID] });
            }
        }
        else {
            if (activedItem !== -1) {
                activedList.splice(activedItem, 1);
                this.setState({ activedIndex: activedList });
            }
            else {
                this.setState({ activedIndex: [acdID] });
            }
        }
        if (this.state.acdTransition === false) {
            this.setState({ acdTransition: true });
        }
    }
    isExpanded(acdID) {
        if (this.state.activedIndex.includes(acdID)) {
            return 'actived';
        }
        else {
            return '';
        }
    }
    render() {
        let childArr = this.props.children;
        if (childArr.length === undefined) {
            childArr = [this.props.children];
        }
        const items = childArr.map((child, i) => {
            //let newIndex = i + 1;
            return React.cloneElement(child, {
                isExpanded: this.isExpanded.bind(this),
                handleClick: this.handleClick.bind(this),
                addTransition: this.addTransition.bind(this)
            });
        });
        return (React.createElement("div", { className: `accordion-box` }, items));
    }
}
class AccordionList extends React.Component {
    render() {
        return (React.createElement("div", { className: `accordion-list ${this.props.isExpanded(this.props.id)} ${this.props.addTransition()}` },
            React.createElement("div", { className: `accordion-label`, onClick: () => { this.props.handleClick(this.props.id); } },
                this.props.headTitle,
                " ",
                React.createElement("span", { className: "acd-arrow" })),
            React.createElement("div", { className: `accordion-content` },
                React.createElement("div", { className: "accordion-inner" }, this.props.children))));
    }
}
ReactDOM.render(React.createElement(App, null), document.getElementById('root'));
</script>

</body>
</html>
Preview