Angular MaterialでNavigation Drawerをつくる

環境

  • macOS Mojave 10.14.4

  • Angular CLI: 8.2.0

  • Node: 10.16.0

  • OS: darwin x64

  • Angular: 8.2.0

  • @angular/material 8.1.2

  • rxjs 6.4.0

  • typescript 3.5.3





Angular Materialのナビゲーションドロワーを導入する前にフレックスレイアウトを適用します。マテリアルデザインを採用するとよく使うので、メモしときます。

とう言うわけで、早速、flex-layoutをインストールします。Angular CLIでインストールできるので、そちらを使ってインストールしていきます。

Using Angular CLI

$ npm install @angular/flex-layout @angular/cdk --save

インストールしたらapp.module.tsに追記。

# src/app/app.module.ts

import {NgModule} from '@angular/core';
import {FlexLayoutModule} from '@angular/flex-layout';
// other imports 
@NgModule({
  imports: [FlexLayoutModule],
  ...
})
export class AppModule {}





Angular Sidenav

MatSidenavModuleをインポートします。サイドナビはすべてのページで共通になるので、app.component.htmlをこんな感じにします。

# app.component.html

<mat-sidenav-container>
  <mat-sidenav #sidenav role="navigation">
    <p>ここはサイドナビです</p>
  </mat-sidenav>
  <mat-sidenav-content>
    <button (click)="sidenav.toggle()">show</button>
    <router-outlet></router-outlet>
  </mat-sidenav-content>
</mat-sidenav-container>

showボタンを押すとナビゲーションのコンテツが出てくると思います。

これが基本形の形です。あとは、これを綺麗な形に直していきます。





完成形

# app.component.html

<mat-sidenav-container>
  <mat-sidenav #sidenav role="navigation">
    <mat-nav-list>
      <a mat-list-item href="#" (click)="sidenav.close()">
        <mat-icon>face</mat-icon>
        <span class="nav-caption">新規作成</span>
      </a>
      <a mat-list-item href="#" (click)="sidenav.close()">
        <mat-icon>input</mat-icon>
        <span class="nav-caption">ログイン</span>
      </a>
      <mat-list-item>
        <button mat-icon-button (click)="sidenav.close()">
          <mat-icon>eject</mat-icon>
          <span class="nav-caption">ログアウト</span>
        </button>
      </mat-list-item>
    </mat-nav-list>
  </mat-sidenav>
  <mat-sidenav-content>
    <mat-toolbar color="primary">
      <div fxHide.gt-xs>
        <button mat-icon-button (click)="sidenav.toggle()">
          <mat-icon>menu</mat-icon>
        </button></div>
      <div><a routerLink="/">LOGO</a></div>
      <div fxFlex fxLayout fxLayoutAlign="flex-end" fxHide.xs>
        <ul fxLayout fxLayoutGap="10px" class="navigation-items" >
          <li><a href="#">新規作成</a></li>
          <li><a href="#">ログイン</a></li>
        </ul>
      </div>
    </mat-toolbar>
    <main>
      <router-outlet></router-outlet>
    </main>
  </mat-sidenav-content>
</mat-sidenav-container>

参照変数#sidenavmat-sidenavに設定し、mat-list-itemsidenav.closeにアクセスできるようにします。これでリストをクリックするとサイドナビがcloseします。

flex-layoutfxHideを使って画面が小さくなった時に非表示になるようにします。





デザインと整える

ナビゲーションドロワー画面いっぱいになるようにデザインを作成します。まずは完成形から。

# app.component.scss

mat-sidenav-container, mat-sidenav-content mat-sidenav {
  height: 100%;
}

mat-sidenav {
  width: 250px;
}

a {
  text-decoration: none;
  color: white;
}

a:hover,
a:active {
  color: lightgray;
}

.navigation-items {
  list-style: none;
  padding: 0;
  margin: 0;
}

.nav-caption {
  display: inline-block;
  padding-left: 6px;
}

全体のレイアウトも設定するので、styles.scssで高さを設定します。

# styles.scss

/* You can add global styles to this file, and also import other style files */
@import "~@angular/material/prebuilt-themes/indigo-pink.css";

html, body {
  height: 100%;
}

body {
  margin: 0;
}





参照先

Angular Flex-Layout

Angular Sidenav

See Also