Angular Material 2 - Responsive Toolbar

3.3k views Asked by At

Using Angular 4 I am trying to have a toolbar on the top of the page that has the following behaviour:

Big Screens

Show the "Main"-Logo/Link on the left, the other top-nav links on the right.

Small screens

Show the "Main"-Logo Link centered and a menu button on the left for showing the sidenav (containing the links that were visible on the right if the screen is big).

Note:

The sidenav should not go over the toolbar if visible.

Note 2:

The centering of the "Main"-Logo/Link should be centered regarding the overall screen width. It should not be pushed to the right by the menu button.

What I have

<div fxLayout="column" fxFlex>
  <md-toolbar color="primary">
    <button md-icon-button (click)="sidenav.toggle()" fxHide="false" fxHide.gt-sm>
      <md-icon>menu</md-icon>
    </button>
    <button md-button routerLink="/">
      <md-icon>code</md-icon>
      <span>{{title}}</span>
    </button>
    <div fxFlex fxShow="false" fxShow.gt-sm></div>
    <div fxLayout="row" fxShow="false" fxShow.gt-sm>
      <button md-button routerLink="/about">About</button>
      <button md-button routerLink="/legal">Legal Notice</button>
    </div>
  </md-toolbar>
  <md-sidenav-container fxFlex>
    <md-sidenav #sidenav fxHide="false" fxHide.gt-sm>
      <md-nav-list>
        <a md-list-item href="">Main</a>
        <a md-list-item href="/about">About</a>
        <a md-list-item href="/legal">Legal Notice</a>
      </md-nav-list>
    </md-sidenav>
  </md-sidenav-container>
</div>

Where I struggle

  • I do not know how to center the "Main"-Logo/Link correctly
  • If I show the menu in a small screen and switch back the layout to a bigger screen, the menu does not hide

Any help would be greatly appreciated, so thank you already!

1

There are 1 answers

4
FAISAL On BEST ANSWER

Answer to your First Question:

Create a css class say fill-space and use that to center the logo:

.fill-space {
    flex: 1 1 auto;
}

... and in your template:

<span fxFlex fxHide="false" fxHide.gt-sm class="fill-space"></span>
<button md-button routerLink="/">
  <md-icon>code</md-icon>
  <span>{{title}}</span>
</button>
<span class="fill-space"></span>  

Answer to your Second Question:

You will have to close() the sidenav manually on screen resize. You can detect that using @HostListener('window:resize', ['$event']):

In your typescript, do the following changes:

// Import the following in your ts file
import { ViewChild, HostListener } from '@angular/core';
import { MdSidenav } from '@angular/material';

// Add the following in your component class to get sidenav
@ViewChild('sidenav') sidenav: MdSidenav;

// Add the method to detect screen-resize
@HostListener('window:resize', ['$event'])
onResize(event) {
    if(this.sidenav !== undefined){
        this.sidenav.close();
    } 
}

Link to working demo.