@@ -13,6 +13,7 @@ import {
1313 Type ,
1414 ChangeDetectionStrategy ,
1515 EventEmitter ,
16+ Renderer
1617} from 'angular2/core' ;
1718import { BaseException } from 'angular2/src/facade/exceptions' ;
1819import { Dir } from '../../core/rtl/dir' ;
@@ -49,7 +50,7 @@ export class MdSidenav {
4950 @Input ( ) mode : 'over' | 'push' | 'side' = 'over' ;
5051
5152 /** Whether the sidenav is opened. */
52- @Input ( 'opened' ) private _opened : boolean ;
53+ @Input ( 'opened' ) private _opened : boolean = false ;
5354
5455 /** Event emitted when the sidenav is being opened. Use this to synchronize animations. */
5556 @Output ( 'open-start' ) onOpenStart = new EventEmitter < void > ( ) ;
@@ -247,7 +248,8 @@ export class MdSidenavLayout implements AfterContentInit {
247248 get start ( ) { return this . _start ; }
248249 get end ( ) { return this . _end ; }
249250
250- constructor ( @Optional ( ) @Host ( ) private _dir : Dir ) {
251+ constructor ( @Optional ( ) @Host ( ) private _dir : Dir , private _element : ElementRef ,
252+ private _renderer : Renderer ) {
251253 // If a `Dir` directive exists up the tree, listen direction changes and update the left/right
252254 // properties to point to the proper start/end.
253255 if ( _dir != null ) {
@@ -258,9 +260,28 @@ export class MdSidenavLayout implements AfterContentInit {
258260 ngAfterContentInit ( ) {
259261 // On changes, assert on consistency.
260262 this . _sidenavs . changes . subscribe ( ( ) => this . _validateDrawers ( ) ) ;
263+ this . _sidenavs . forEach ( ( sidenav : MdSidenav ) => this . _watchSidenavToggle ( sidenav ) ) ;
261264 this . _validateDrawers ( ) ;
262265 }
263266
267+ /*
268+ * Subscribes to sidenav events in order to set a class on the main layout element when the sidenav
269+ * is open and the backdrop is visible. This ensures any overflow on the layout element is properly
270+ * hidden.
271+ * */
272+ private _watchSidenavToggle ( sidenav : MdSidenav ) : void {
273+ if ( ! sidenav || sidenav . mode === 'side' ) { return ; }
274+ sidenav . onOpen . subscribe ( ( ) => this . _setLayoutClass ( sidenav , true ) ) ;
275+ sidenav . onClose . subscribe ( ( ) => this . _setLayoutClass ( sidenav , false ) ) ;
276+ }
277+
278+ /*
279+ * Toggles the 'md-sidenav-opened' class on the main 'md-sidenav-layout' element.
280+ * */
281+ private _setLayoutClass ( sidenav : MdSidenav , bool : boolean ) : void {
282+ this . _renderer . setElementClass ( this . _element . nativeElement , 'md-sidenav-opened' , bool ) ;
283+ }
284+
264285
265286 /** The sidenav at the start/end alignment, independent of direction. */
266287 private _start : MdSidenav ;
@@ -318,9 +339,13 @@ export class MdSidenavLayout implements AfterContentInit {
318339 }
319340 }
320341
321- private _isShowingBackdrop ( ) {
322- return ( this . _start != null && this . _start . mode != 'side' && this . _start . opened )
323- || ( this . _end != null && this . _end . mode != 'side' && this . _end . opened ) ;
342+ private _isShowingBackdrop ( ) : boolean {
343+ return ( this . _isSidenavOpen ( this . _start ) && this . _start . mode != 'side' )
344+ || ( this . _isSidenavOpen ( this . _end ) && this . _end . mode != 'side' ) ;
345+ }
346+
347+ private _isSidenavOpen ( side : MdSidenav ) : boolean {
348+ return side != null && side . opened ;
324349 }
325350
326351 /**
@@ -330,10 +355,7 @@ export class MdSidenavLayout implements AfterContentInit {
330355 * @private
331356 */
332357 private _getSidenavEffectiveWidth ( sidenav : MdSidenav , mode : string ) : number {
333- if ( sidenav != null && sidenav . mode == mode && sidenav . opened ) {
334- return sidenav . _width ;
335- }
336- return 0 ;
358+ return ( this . _isSidenavOpen ( sidenav ) && sidenav . mode == mode ) ? sidenav . _width : 0 ;
337359 }
338360
339361 private _getMarginLeft ( ) {
0 commit comments