question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

md-sidenav: make it automatically responsive

See original GitHub issue

Feature request Version: Angular Material 2.0.0-alpha.7 wax-umpire

I’d like to have an option where the sidenav can be responsive automatically, by having a breakpoint where the sidenav is shown by default when the width is higher than X.

This was already implemented in Angular Material (1) as the md-is-locked-open: https://material.angularjs.org/latest/api/directive/mdSidenav

Is there any plan to have this? I could submit a PR if this is wanted.

Issue Analytics

  • State:open
  • Created 7 years ago
  • Reactions:17
  • Comments:12 (2 by maintainers)

github_iconTop GitHub Comments

26reactions
angularexamplecommented, May 17, 2017

Here are 2 ways to make mdsidenav responsive automatically.

  1. You can bind to the window resize event and open or close the sidenav by doing everything in the template:
<md-sidenav #xxxMenu (window:resize)="$event.target.innerWidth<769?xxxMenu.close():xxxMenu.open()"> 
  1. Or, here is how to make MdSidenav automatically responsive, using the new FlexLayoutModule

In your component,

  1. Set a public boolean “isMobileView” by examining the media observable “isActive”.
  2. Subscribe to the “MediaChange” to responsively change the boolean that will control the state of the sidenav.
  ngOnInit():void {
    this.isMobileView = (this.media.isActive('xs') || this.media.isActive('sm'));

    this.subscriptionMedia = this.media.subscribe((change:MediaChange) => {
      this.isMobileView = (change.mqAlias === 'xs' || change.mqAlias === 'sm');
    });

In your component, add a responsive handler for link click:

  onLinkClick():void {
    if (this.isMobileView) {
      this.menuSidenav.close();
    }
  }

The onLinkClick() handler needs to added to each of the menu links in your template.
It will close the menu after clicking a link, but not when the menu should stay open.

In your template, bind the md-sidenav’s “mode”, “opened”, and “disableClose” attributes to your component’s responsive boolean.

<md-sidenav #xxxMenu mode="{{isMobileView?'over':'side'}}" opened="{{!isMobileView}}" disableClose="{{!isMobileView}}">

Now, based on your responsive breakpoint…

  • The sidenav will be in the correct state at the initial view.
  • The sidenav mode will change from “side” to “over”.
  • The sidenav will automatically open or close.
  • The disableClose prevents closing with the escape key.
10reactions
krisklostermancommented, Mar 23, 2017

This seems to work too:

import { Component, ViewChild, OnInit, HostListener } from '@angular/core';
import { MdSidenav } from "@angular/material";

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  @ViewChild('sidenav') sidenav: MdSidenav;

  constructor(
  ) { }

  ngOnInit() {
  }

  @HostListener('window:resize', ['$event'])
    onResize(event) {
        if (event.target.innerWidth < 500) {
            this.sidenav.close();
        }
        if (event.target.innerWidth > 500) {
           this.sidenav.open();
        }
    }
}

Another idea

import { Component, ViewChild, OnInit, HostListener } from '@angular/core';
import { MdSidenav } from "@angular/material";

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {

  @ViewChild('sidenav') sidenav: MdSidenav;
  navMode = 'side';

  constructor(
  ) { }

  ngOnInit() {
    if (window.innerWidth < 768) {
      this.navMode = 'over';
    }
  }

  @HostListener('window:resize', ['$event'])
    onResize(event) {
        if (event.target.innerWidth < 768) {
            this.navMode = 'over';
            this.sidenav.close();
        }
        if (event.target.innerWidth > 768) {
           this.navMode = 'side';
           this.sidenav.open();
        }
    }
}

HTML

<md-sidenav-container class="wrapper">
    <md-sidenav #sidenav mode="{{navMode}}" opened="true" class="app-sidenav">
    <app-sidebar></app-sidebar></div>
    </md-sidenav>
    <div class='main-container'>
        <app-navbar></app-navbar>
        <router-outlet></router-outlet>
    </div>
</md-sidenav-container>
Read more comments on GitHub >

github_iconTop Results From Across the Web

Angular Material: a responsive Sidenav | by Frederic Lopes
In this story, I am going to explain how to create a responsive sidenav using the ... <md-sidenav #sidenav [opened]="screenWidth > 840" ...
Read more >
Angular Material SideNav autosize not working - Stack Overflow
1. sidenav.opened unable to work but I use [style. · Use sidenav.toggle() on click of button that regulates sidenav . · the [style.left]...
Read more >
Sidenav - Angular Material
Creating a responsive layout for mobile & desktop. A sidenav often needs to behave differently on a mobile vs a desktop display. On...
Read more >
Angular Material: Adaptive Layouts - Egghead.io
Combine responsive functionality with media query support and your web ... And we will see how the $mdSideNav service can be used to ......
Read more >
Layout Containers - AngularJS Material
Layouts and Responsive Breakpoints ... To make your layout automatically change depending upon the device screen size, use one to the following layout...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found