Reputation: 85765
I am wondering how I can handle these 2 layouts.
First I have a css grid layout that gets used on resolutions of 1024px or bigger and if they support current grid standard.
Pretty standard layout with a header, sidebar and main area.
.container {
display: grid;
grid-template-columns: 0.30fr 0.70fr;
grid-template-rows: auto;
grid-template-areas: "header header" "sidebar main";
}
.header {
grid-area: header;
background-color: yellow;
}
.sidebar {
grid-area: sidebar;
background-color: lightblue;
}
.main {
grid-area: main;
background-color: green;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div class="container">
<div class="header">
header
</div>
<div class="sidebar">
side
</div>
<div class="main">
main
</div>
</div>
</body>
</html>
Now if the browser does not support grid or they are below 1024px then they go to the mobile layout.
This layout would be made by flex and becomes a layout of header and main area with the sidebar being hidden and only shown by user interaction.
I just can't figure out a react way of doing this that I am happy with.
My problem is that I can hide the side menu with media selectors and then on click of the hamburger menu toggle the display but I don't know if this feels like a reactjs way of doing it as I rather just not render the side bar instead of hiding it.
I would also have to have something to handle window on resize.
Upvotes: 2
Views: 11249
Reputation: 1138
If you really want to do this only in reactjs way you can do this using life cycle methods like componentWillMount
, componentDidMount
and componentWillUnmount
along with resize
event and document's width.
I did not do much work the CSS part in this example, but you will get the idea.
Try resizing the window after running this script in full-page view.
class MyLayout extends React.Component {
constructor() {
super();
this.state = {
mobileView: false,
showSidebar: true
};
this.updateViewState = this.updateViewState.bind(this);
this.toggleSideBar = this.toggleSideBar.bind(this);
}
updateViewState() {
if (!this.state.mobileView && document.documentElement.clientWidth < 1024) {
this.setState({
mobileView: true,
showSidebar: false
});
} else if (document.documentElement.clientWidth > 1024) {
this.setState({
mobileView: false,
showSidebar: true
});
}
}
toggleSideBar() {
this.setState({
showSidebar: !this.state.showSidebar
});
}
componentWillMount() {
this.updateViewState();
}
componentDidMount() {
window.addEventListener("resize", this.updateViewState);
}
componentWillUnmount() {
window.removeEventListener("resize", this.updateViewState);
}
render() {
let containerClass = 'container';
if (this.state.mobileView) containerClass = containerClass + ' mobileview';
return (
<div className = { containerClass }>
<div className="header"> {this.state.mobileView && <button onClick={this.toggleSideBar} />} header
</div>
{
this.state.showSidebar &&
<div className = "sidebar" >
side
</div>
}
<div className="main">
main
</div>
</div>);
}
}
ReactDOM.render(
<MyLayout /> ,
document.getElementById('container')
);
.container {
display: grid;
grid-template-columns: 0.30fr 0.70fr;
grid-template-rows: auto;
grid-template-areas: "header header" "sidebar main";
}
.mobileview {
grid-template-columns: 0fr 1fr;
}
.mobileview.sidebar {
float: left;
}
.header {
grid-area: header;
background-color: yellow;
}
.sidebar {
grid-area: sidebar;
background-color: lightblue;
}
.main {
grid-area: main;
background-color: green;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="container">
<!-- This element's contents will be replaced with your component. -->
</div>
Upvotes: 2