React Material UI – Open Left Menu (Navigation Drawer) on AppBar’s Hamburger Icon Click

This is more of a quick tip on a Material UI integration than a detailed article. We’ll see how to open the LeftNav component on clicking the AppBar’s left icon (hamburger menu icon). Unfortunately the documentation as of now doesn’t show the ReactJS code for this. Obviously it’s not too hard to figure it out either if you go through the website’s source itself on Github.

Let’s get started. Let’s say our main app’s component name is App that renders eventually on the screen and contains the AppBar and LeftNav inside it. Then this is how the integration code would look like:

What's the one thing every developer wants? More screens! Enhance your coding experience with an external monitor to increase screen real estate.

import React from 'react';
import mui from 'material-ui';

let ThemeManager = new mui.Styles.ThemeManager();
let AppBar = mui.AppBar
  , LeftNav = mui.LeftNav
  , MenuItem = mui.MenuItem;
  
class App extends React.Component {

  constructor() {
    super();

    this._handleClick = this._handleClick.bind(this);
  }

  getChildContext() {
    return {
      muiTheme: ThemeManager.getCurrentTheme()
    };
  }

  _handleClick(e) {
    e.preventDefault();

    // Show/Hide the LeftMenu
    this.refs.leftNav.toggle();
  }

  render() {
    var menuItems = [
      { route: 'get-started', text: 'Get Started' },
      { route: 'customization', text: 'Customization' },
      { route: 'components', text: 'Components' },
      { type: MenuItem.Types.SUBHEADER, text: 'Resources' },
      {
         type: MenuItem.Types.LINK,
         payload: 'https://github.com/callemall/material-ui',
         text: 'GitHub'
      },
      {
         text: 'Disabled',
         disabled: true
      },
      {
         type: MenuItem.Types.LINK,
         payload: 'https://www.google.com',
         text: 'Disabled Link',
         disabled: true
      },
    ];

    return (
      <div id="page_container">

        <LeftNav
          ref="leftNav"
          docked={false}
          menuItems={menuItems} />

        <header>
          <AppBar title='ZoomFleet' onLeftIconButtonTouchTap={this._handleClick}
            isInitiallyOpen={true}
            />
        </header>
        
      </div>
    );
  }

}

App.childContextTypes = {
  muiTheme: React.PropTypes.object
};

React.render(<App />, document.querySelector('body'));

This should give you a navigation drawer sliding from left that would be pretty much similar to what you see on documentation site. All we did is passed a custom event handler for click/touch/tap to the AppBar through the `onLeftIconButtonTouchTap` event. If you’d like to check more events and properties, go through the docs it’s fairly simple.

Note: You’ll need the react-tap-event-plugin until React 1.0 is launched which will address the problems solved by this plugin. This is very important, missing this could cause a good amount of time wastage. From the plugin’s README:

You’ve probably heard of iOS’s dreaded 300ms tap delay. React’s onClick attribute falls prey to it. Facebook’s working on a solution in the form of TapEventPlugin, but it won’t be made available until 1.0.

If you’re reading this, you’re probably working on a project that can’t wait until they figure out how they want to publish it. This repo is for you.

When Facebook solves #436 and #1170, this repo will disappear.

Using it is very simple:

// Before you do any rendering, initialize the plugin
import injectTapEventPlugin from 'react-tap-event-plugin';
injectTapEventPlugin();

Infact it is also mentioned in the material UI docs, but there’s a good chance you’ll miss it while hurriedly integrating it.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download

Author: Rishabh

Rishabh is a full stack web and mobile developer from India. Follow me on Twitter.

3 thoughts on “React Material UI – Open Left Menu (Navigation Drawer) on AppBar’s Hamburger Icon Click”

Leave a Reply to Marcus Cancel reply

Your email address will not be published. Required fields are marked *