chobo2
chobo2

Reputation: 85765

Reactjs way of hide sidebar in layout?

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

Answers (1)

Anand S
Anand S

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

Related Questions