Skip to content

Instantly share code, notes, and snippets.

@whilelucky
Last active September 17, 2017 03:01
Show Gist options
  • Save whilelucky/4b60beca0f956d9d70e03ebfbf4c11bb to your computer and use it in GitHub Desktop.
Save whilelucky/4b60beca0f956d9d70e03ebfbf4c11bb to your computer and use it in GitHub Desktop.
Compound Components: Accordion
.accordion {
&__section {
background: #ddd;
color: #000;
font-size: 20px;
border: 2px solid #000;
}
&__title {
padding: 20px 10px;
cursor: pointer;
}
&__content {
background: #fff;
padding: 10px;
display: none;
&--open {
display: block;
}
}
}
import React from 'react';
import cn from 'classnames';
import './accordion.css';
class List extends React.Component {
state = {
open: 0,
}
toggleSection = (index) => () => {
this.setState({ open: index });
}
render() {
return (
<ul>
{React.Children.map(this.props.children, (child, index) => {
if (child.type === Section) {
return React.cloneElement(child, {
isOpen: this.state.open === index,
onClick: this.toggleSection(index),
});
}
return child;
})}
</ul>
);
}
}
class Section extends React.Component {
render() {
return (
<li className="accordion__section" onClick={this.props.onClick}>
{React.Children.map(this.props.children, (child) => {
if (child.type === Content) {
return React.cloneElement(child, {
isOpen: this.props.isOpen,
});
}
return child;
})}
</li>
);
}
}
class Title extends React.Component {
render() {
return (
<h3 className="accordion__title">
{this.props.children}
</h3>
);
}
}
class Content extends React.Component {
render() {
return (
<p
className={cn('accordion__content', {
'accordion__content--open': this.props.isOpen,
})}
>
{this.props.children}
</p>
);
}
}
export default {
List,
Section,
Title,
Content,
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment