CSS
@import url(https://fonts.googleapis.com/css?family=Roboto:400,700,700italic,400italic);
/* http://meyerweb.com/eric/tools/css/reset/
v2.0 | 20110126
License: none (public domain)
*/
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline; }
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
display: block; }
body {
padding: 25px;
line-height: 1; }
ol, ul {
list-style: none; }
blockquote, q {
quotes: none; }
blockquote:before, blockquote:after,
q:before, q:after {
content: '';
content: none; }
table {
border-collapse: collapse;
border-spacing: 0; }
* {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box; }
/**
* For modern browsers
* 1. The space content is one way to avoid an Opera bug when the
* contenteditable attribute is included anywhere else in the document.
* Otherwise it causes space to appear at the top and bottom of elements
* that are clearfixed.
* 2. The use of `table` rather than `block` is only necessary if using
* `:before` to contain the top-margins of child elements.
*/
.cf:before,
.cf:after {
content: " ";
/* 1 */
display: table;
/* 2 */ }
.cf:after {
clear: both; }
/**
* For IE 6/7 only
* Include this rule to trigger hasLayout and contain floats.
*/
.cf {
*zoom: 1; }
html {
font-size: 16px; }
body {
...
React
// Ignore this - this is collapsible.
class Collapsible extends React.Component {
constructor(props) {
super(props)
// Bind class methods
this.handleTriggerClick = this.handleTriggerClick.bind(this);
this.handleTransitionEnd = this.handleTransitionEnd.bind(this);
this.continueOpenCollapsible = this.continueOpenCollapsible.bind(this);
// Defaults the dropdown to be closed
if (props.open) {
this.state = {
isClosed: false,
shouldSwitchAutoOnNextCycle: false,
height: 'auto',
transition: 'none',
hasBeenOpened: true,
overflow: props.overflowWhenOpen,
inTransition: false,
}
} else {
this.state = {
isClosed: true,
shouldSwitchAutoOnNextCycle: false,
height: 0,
transition: `height ${props.transitionTime}ms ${props.easing}`,
hasBeenOpened: false,
overflow: 'hidden',
inTransition: false,
}
}
}
componentDidUpdate(prevProps, prevState) {
if(this.state.shouldOpenOnNextCycle){
this.continueOpenCollapsible();
}
if (prevState.height === 'auto' && this.state.shouldSwitchAutoOnNextCycle === true) {
window.setTimeout(() => { // Set small timeout to ensure a true re-render
this.setState({
height: 0,
overflow: 'hidden',
isClosed: true,
shouldSwitchAutoOnNextCycle: false,
});
}, 50);
}
// If there has been a change in the open prop (controlled by accordion)
if (prevProps.open !== this.props.open) {
if(this.props.open === true) {
this.openCollapsible();
this.props.onOpening();
} else {
this.closeCollapsible();
this.props.onClosing();
}
}
}
closeCollapsible() {
this.setState({
shouldSwitchAutoOnNextCycle: true,
height: this.refs.inner.offsetHeight,
transition: `height ${this.props.transitionCloseTime ?
...