Skip to content

Instantly share code, notes, and snippets.

@Qt-dev
Created July 3, 2014 09:55
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save Qt-dev/4ca4c41b8ec8f6c0bb27 to your computer and use it in GitHub Desktop.
Save Qt-dev/4ca4c41b8ec8f6c0bb27 to your computer and use it in GitHub Desktop.
An accordion in ReactJS/CSS3
var backendData = [
{
"title":"Section 1",
"content":"Our content for the section 1"
},
{
"title":"Section 2",
"content":"Our content for the section 2"
},
{
"title":"Section 3",
"content":"Our content for the section 3"
}
]
/**
* @jsx React.DOM
*/
Container = React.createClass({
getInitialState: function(sectionList){
return { openSectionIndex: -1 }
},
buildSections: function(sectionList){
var sections = sectionList.map(this.buildSection)
return sections;
},
buildSection: function(section, index){
var openStatus = (index === this.state.openSectionIndex);
/* Remember to add a 'key'. React wants you to add an identifier when you instantiate a component multiple times */
return <Section key={index} data={section} toggleOne={this.toggleOne} open={openStatus} />
},
toggleOne: function(id){
if(this.state.openSectionIndex === id){
this.setState({openSectionIndex: -1});
} else {
this.setState({openSectionIndex: id});
}
},
render: function() {
var sections = this.buildSections(this.props.data);
return (
<div className="container">
{sections}
</div>
);
}
})
<html>
<head>
<title>Test page</title>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/react/0.10.0/react.min.js"></script>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/react/0.10.0/JSXTransformer.js"></script>
<script type="text/jsx" src="section.jsx"></script>
<script type="text/jsx" src="container.jsx"></script>
<link type="text/css" rel="stylesheet" href="style.css"></link>
</head>
<body>
<script type="text/jsx">
/** @jsx React.DOM */
React.renderComponent(
<Container data={backendData} />,
document.getElementsByTagName('body')[0]
);
</script>
</body>
</html>
/**
* @jsx React.DOM
*/
Section = React.createClass({
toggleContent: function(){
this.props.toggleOne(this.props.key)
},
getHeight: function(){
if(this.props.open){
return "3em"
} else {
return "0"
}
},
render: function() {
var style = { height: this.getHeight() }
return (
<div className={"section section" + this.props.key}>
<h2 className="sectionTitle" onClick={this.toggleContent} >{this.props.data.title}</h2>
<p className="sectionContent" style={style} >{this.props.data.content}</p>
</div>
);
}
})
.sectionTitle {
display: block;
cursor: pointer;
}
.sectionContent {
overflow: hidden;
-webkit-transition: height 0.3s ease-in;
-moz-transition: height 0.3s ease-in;
-o-transition: height 0.3s ease-in;
-ms-transition: height 0.3s ease-in;
transition: height 0.3s ease-in;
}
@MohitTilwani
Copy link

code doesnt show output as expected

@dmh2
Copy link

dmh2 commented Mar 31, 2015

Thanks for posting this. I was able to get a test working after changing the 'key' attribute name for each Section's data object (I used 'id' instead). Though, I'm not exactly sure why this made the difference, as I don't believe that 'key' is a reserved word in either JS or React.

@martinwells
Copy link

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment