Can I make my mat-sidenav responsive using opened property or open() method and flex-layout responsive api?
Like <mat-sidenav #sidenav mode="side" opened="true" [fxFlex.xs]="sidenav.close()">
3 Answers
You could consider using @angular/flex-alyout ObservableMedia to watch for media/breakpoint changes and update the mode
or other properties accordingly depending on the active media level. This done by subscribing to an injected ObservableMedia
service instance and checking the active media level. You can then bind opened
and mode
properties of <md-sidenav>
via one way []
binding to your class properties. This logic can be put into services and/or attribute directives if needed.
Using/updating the properties instead of applying CSS changes will ensure that the proper animations occur.
TS:
import { Component } from '@angular/core';
import { MediaChange, ObservableMedia } from "@angular/flex-layout";
@Component({ ... })
export class AppComponent {
mode: string = 'side';
opened: boolean = true;
constructor(private media: ObservableMedia) {
this.media.subscribe((mediaChange: MediaChange) => {
this.mode = this.getMode(mediaChange);
// this.opened = this.getOpened(mediaChange);
});
}
private getMode(mediaChange: MediaChange): string {
// set mode based on a breakpoint
if (this.media.isActive('gt-sm')) {
return 'side';
} else {
return 'over';
}
}
// open/close as needed
private getOpened(mediaChange: MediaChange): string { }
}
HTML:
<md-sidenav-container class="example-container">
<md-sidenav #sidenav class="example-sidenav" [opened]="opened" [mode]="mode">
Jolly good!
</md-sidenav>
<div class="example-sidenav-content">
<p>Sidenav content</p>
<button type="button" md-button (click)="sidenav.open()">
Open sidenav
</button>
</div>
</md-sidenav-container>
The answer from @AlexanderStaroselsky is great but outdated/deprecated for newer versions.
As he said if you use flex-layout you can use MediaQueries from responsive API:
TS:
import { Component } from '@angular/core';
import { MediaChange, MediaObserver } from '@angular/flex-layout';
@Component({
selector: 'app-component',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
sidenavMode: string = 'side';
constructor(private media: ObservableMedia) {
this.media.asObservable().subscribe((mediaChange: MediaChange[]) => {
this.sidenavMode = this.getMode(mediaChange);
});
}
private getMode(mediaChange: MediaChange[]): string {
return this.media.isActive('gt-sm') ? 'side' : 'over';
}
}
HTML:
<mat-drawer-container hasBackdrop="false">
<mat-drawer [mode]="sidenavMode">
Sidenav
</mat-drawer>
<div>
Hello world !
</div>
</mat-drawer-container>
In this example when the screen width is lower than 960px the mode will be over.