Skip to content

Instantly share code, notes, and snippets.

@r2dev
Created May 4, 2018 03:23
Show Gist options
  • Save r2dev/269e0cff049f3cdcbf0f48aac91185ba to your computer and use it in GitHub Desktop.
Save r2dev/269e0cff049f3cdcbf0f48aac91185ba to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta content="width=device-width,minimum-scale=1.0" name="viewport">
<title>Hello World</title>
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/[email protected]/babel.min.js"></script>
<style>
* {
padding: 0;
margin: 0;
}
.menu {
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: hidden;
pointer-events: none;
z-index: 150;
}
.menu--visible {
pointer-events: auto;
}
.app-menu {
background-color: #fff;
color: #fff;
position: relative;
max-width: 400px;
width: 60%;
height: 100%;
-webkit-transform: translateX(-103%);
transform: translateX(-103%);
display: flex;
flex-direction: column;
will-change: transform;
z-index: 160;
pointer-events: auto;
}
.menu--visible .app-menu {
-webkit-transform: none;
transform: none;
}
.menu--animatable .app-menu {
transition: all 130ms ease-in;
}
.menu--visible.menu--animatable .app-menu {
transition: all 330ms ease-out;
}
.menu:after {
content: '';
display: block;
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.4);
opacity: 0;
will-change: opacity;
pointer-events: none;
transition: opacity 0.3s cubic-bezier(0, 0, 0.3, 1);
}
.menu--visible.menu:after {
opacity: 1;
pointer-events: auto;
}
.banner {
height: 50px;
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: stretch;
}
.toggle {
width: 50px;
background: lightskyblue;
}
</style>
</head>
<body>
<div id="root"></div>
<script type="text/babel">
class App extends React.Component {
state = {
showMenu: false,
currentOpenAccordion: -1
};
toggleOpenMenu = () =>
this.setState(prevState => ({
showMenu: !prevState.showMenu
}));
toggleAccordion = index => {
this.setState(prevState => ({
currentOpenAccordion:
prevState.currentOpenAccordion !== index ? index : -1
}));
};
render() {
return (
<React.Fragment>
<Drawer
showMenu={this.state.showMenu}
toggleOpenMenu={this.toggleOpenMenu}
/>
<Main
toggleOpenMenu={this.toggleOpenMenu}
currentOpenAccordion={this.state.currentOpenAccordion}
toggleAccordion={this.toggleAccordion}
/>
</React.Fragment>
);
}
}
class Drawer extends React.Component {
state = {
animationStart: false
};
static getDerivedStateFromProps(nextProps, prevState) {
if (!prevState.animationStart && nextProps.showMenu) {
return {
animationStart: true
};
} else {
return null;
}
}
removeAnimationClass = () => {
this.setState({
animationStart: false
});
};
render() {
const menuClass = `menu${
this.state.animationStart ? " menu--animatable" : ""
}${this.props.showMenu ? " menu--visible" : ""}`;
return (
<div
className={menuClass}
onTransitionEnd={this.removeAnimationClass}
onClick={this.props.toggleOpenMenu}
>
<div className="app-menu" onClick={e => e.stopPropagation()} />
</div>
);
}
}
class Accordion extends React.Component {
render() {
return (
<div>
{this.props.config.map((item, index) => (
<div key={index}>
<div onClick={this.props.toggleAccordion.bind(null, index)}>
{item.name}
</div>
{index === this.props.currentOpenAccordion ? item.element : null}
</div>
))}
</div>
);
}
}
class Main extends React.Component {
render() {
return (
<div>
<Banner {...this.props} />
<Accordion
config={[
{
name: "TD",
element: <div style={{ background: "green", height: 80 }} />
},
{
name: "RBC",
element: <div style={{ background: "blue", height: 80 }} />
},
{
name: "CIBC",
element: <div style={{ background: "red", height: 80 }} />
}
]}
{...this.props}
/>
</div>
);
}
}
class Banner extends React.Component {
render() {
return (
<div className="banner">
<div className="toggle" onClick={this.props.toggleOpenMenu} />
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));
</script>
<!--
Note: this page is a great way to try React but it's not suitable for production.
It slowly compiles JSX with Babel in the browser and uses a large development build of React.
To set up a production-ready React build environment, follow these instructions:
* https://reactjs.org/docs/add-react-to-a-new-app.html
* https://reactjs.org/docs/add-react-to-an-existing-app.html
You can also use React without JSX, in which case you can remove Babel:
* https://reactjs.org/docs/react-without-jsx.html
* https://reactjs.org/docs/cdn-links.html
-->
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment