Skip to content

Instantly share code, notes, and snippets.

@hypervillain
Created October 12, 2018 16:36
Show Gist options
  • Save hypervillain/aa07401212f61623452c04c7f09d8209 to your computer and use it in GitHub Desktop.
Save hypervillain/aa07401212f61623452c04c7f09d8209 to your computer and use it in GitHub Desktop.
Generic React layout that renders routes inside a drawer
// See it in action here https://codesandbox.io/s/mkznro61j
import React, { Component } from 'react';
import { render } from 'react-dom';
import PropTypes from 'prop-types';
import {
BrowserRouter,
Link,
Route,
Switch,
} from 'react-router-dom';
import Drawer from 'rc-drawer';
import 'rc-drawer/assets/index.css';
class Main extends Component {
static propTypes = {
location: PropTypes.shape({
pathname: PropTypes.string.isRequired,
}).isRequired,
history: PropTypes.shape({ push: PropTypes.func.isRequired }).isRequired,
}
constructor(props) {
super(props);
this.previousLocation = props.location;
}
componentWillUpdate(nextProps) {
console.log(this.props);
const { location } = this.props;
if (
nextProps.history.action !== 'POP' &&
(!location.state || !location.state.modal)
) {
this.previousLocation = this.props.location;
}
}
render() {
const { location } = this.props;
const isModal = !!(
location.state &&
location.state.modal &&
this.previousLocation !== location
);
return (
<div>
<Switch location={isModal ? this.previousLocation : location}>
<Route
exact
path="/:id"
render={props => (
<div>
<p>ID: {props.match.params.id}</p>
<Link
href="/"
to={{
pathname: '/',
state: { modal: false },
}}
>
Return to main page
</Link>
</div>
)}
/>
<Route
exact
path="/"
render={() => (
<div>
<p>You are on main page</p>
<Link
href="/1"
to={{
pathname: '/1',
state: { modal: true },
}}
>
Go to page 1 inside drawer
</Link>
<br />
<Link href="/1" to="/1">Go to page 1</Link>
</div>
)}
/>
</Switch>
{isModal && (
<Drawer
ease="none"
handler={false}
onMaskClick={() =>
this.props.history.push(Object.assign(this.previousLocation, {
state: { modal: false },
}))
}
open
placement="right"
width="70%"
>
<Route
path="/:id"
render={props => (
<div style={{ padding: '20px' }}>
<p>ID: {props.match.params.id}</p>
<p>Click the mask to leave!</p>
</div>
)}
/>
</Drawer>
)}
</div>
);
}
}
const App = (
<BrowserRouter>
<Route component={Main} />
</BrowserRouter>
);
render(App, document.getElementById('root'));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment