3
  • Have a mat-sidenav (opened="true") with mat-nav-list
  • Each mat-list-item has a mat-icon and a span
  • mat-sidenav-container has autosize directive

But there is no animation during resizing (collapse/expand) of mat-sidenav.

HTML

<mat-sidenav-container class="example-container" autosize>
  <mat-sidenav mode="side" [opened]="true" #sidenav>
    <mat-nav-list>
      <mat-list-item (click)="isExpanded=!isExpanded">
        <mat-icon matListIcon>reorder</mat-icon>
      </mat-list-item>
      <mat-list-item>
        <mat-icon matListIcon>home</mat-icon>
        <span *ngIf="isExpanded">Home</span>
      </mat-list-item>
      <mat-list-item>
        <mat-icon matListIcon>person</mat-icon>
        <span *ngIf="isExpanded">Athlets</span>
      </mat-list-item>
      <mat-list-item>
        <mat-icon matListIcon>group</mat-icon>
        <span *ngIf="isExpanded">Teams & Partnerships</span>
      </mat-list-item>
    </mat-nav-list>
  </mat-sidenav>
  <mat-sidenav-content>
    <h3>Dashboard</h3>
  </mat-sidenav-content>
</mat-sidenav-container>

CSS

.example-container {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
  }
  .mat-sidenav {
    background-color:#3a3636;
  }
  .mat-list-item {      
    color: #faf6f6;
  }
  .mat-list-item:hover {      
    color: #3a3636;
    background-color:#faf6f6;
  }

TS

import { Component } from '@angular/core';
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  isExpanded = true;
}

If there is no inbuilt implementation for this in Angular Material2, how can I achieve the animation?

Ramanujan R
  • 1,601
  • 2
  • 23
  • 43

1 Answers1

4

If you want to hide the menu, here is a way to do it :

With animations states, you can simply use the style transform to translate your sidebar.

animations.ts

import {
  trigger,
  state,
  style,
  animate,
  transition
} from '@angular/animations';

export const hideAnimation =
  trigger('hideAnimation', [
    state('opened', style({ transform: 'translateX(0%)' })),
    state('closed', style({ transform: 'translateX(-100%)' })),
    transition('* => *', [
      animate(500)
    ])
  ]);

app.component.ts

@Component({
  ...
  animations: [hideAnimation]
})
export class AppComponent { 
  state = 'opened';

  toggleState() {
    this.state = this.state === 'opened' ? 'closed' : 'opened';
  }
}

app.component.html

<mat-sidenav-container class="example-container" autosize>
  <mat-sidenav [@hideAnimation]="state" mode="side" [opened]="true" #sidenav>
    <mat-nav-list>
      <mat-list-item (click)="toggleState()">
        <mat-icon matListIcon>reorder</mat-icon>
      </mat-list-item>
      <mat-list-item>
        <mat-icon matListIcon>home</mat-icon>
        <span>Home</span>
      </mat-list-item>
      <mat-list-item>
        <mat-icon matListIcon>person</mat-icon>
        <span>Athlets</span>
      </mat-list-item>
      <mat-list-item>
        <mat-icon matListIcon>group</mat-icon>
        <span>Teams & Partnerships</span>
      </mat-list-item>
    </mat-nav-list>
  </mat-sidenav>
  <mat-sidenav-content>
    <h3>Dashboard</h3>
  </mat-sidenav-content>
</mat-sidenav-container>

EDIT

To hide only the span and reduce the size of the sidenav, this can help you get closer to what you want to achieve :

animations.ts

export const menuAnimation =
  trigger('menuAnimation', [
    state('opened', style({ opacity: 1 })),
    state('closed', style({ opacity: 0, width: '0px', display: 'none' })),
    transition('* => *', [
      animate(500)
    ])
  ]);

app.component.html

<mat-sidenav-container class="example-container" autosize>
  <mat-sidenav mode="side" [opened]="true" #sidenav>
    <mat-nav-list>
      <mat-list-item (click)="toggleState()">
        <mat-icon matListIcon>reorder</mat-icon>
      </mat-list-item>
      <mat-list-item>
        <mat-icon matListIcon>home</mat-icon>
        <span [@menuAnimation]="state">Home</span>
      </mat-list-item>
      <mat-list-item>
        <mat-icon matListIcon>person</mat-icon>
        <span [@menuAnimation]="state">Athlets</span>
      </mat-list-item>
      <mat-list-item>
        <mat-icon matListIcon>group</mat-icon>
        <span [@menuAnimation]="state">Teams & Partnerships</span>
      </mat-list-item>
    </mat-nav-list>
  </mat-sidenav>
  <mat-sidenav-content>
    <h3>Dashboard</h3>
  </mat-sidenav-content>
</mat-sidenav-container>
br.julien
  • 3,420
  • 2
  • 23
  • 44
  • Don't want to hide the full `mat-sidenav`. For that i could use `sidenav.toggle()`. Need to hide/show only the `span` elements. Putting `[@hideAnimation]` on span. Makes the text "Home" move left. But the whole `mat-sidenav` stays there. – Ramanujan R Jan 12 '18 at 10:00
  • Yeah that was close. But problem with `

    Dashboard

    `, which moves left when opening `mat-sidenav'`
    – Ramanujan R Jan 12 '18 at 10:14
  • It doesn't move when I test my code. It has to come from your css, but the animation is this one – br.julien Jan 12 '18 at 10:35
  • Ok. Thanks for the info. Will check it again – Ramanujan R Jan 12 '18 at 10:42