Skip to content

Commit 004e0fe

Browse files
amcdnlandrewseguin
authored andcommitted
chore(api): new output api #6677 (#7450)
* chore(api): new output api #6677 * chore(nit): add 2way test and nit spacing
1 parent 57f19cd commit 004e0fe

File tree

2 files changed

+76
-19
lines changed

2 files changed

+76
-19
lines changed

src/lib/sidenav/drawer.spec.ts

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ describe('MatDrawer', () => {
2020
DrawerSetToOpenedTrue,
2121
DrawerDynamicPosition,
2222
DrawerWitFocusableElements,
23+
DrawerOpenBinding,
2324
],
2425
});
2526

@@ -287,6 +288,20 @@ describe('MatDrawer', () => {
287288

288289
expect(() => fixture.detectChanges()).not.toThrow();
289290
});
291+
292+
it('should bind 2-way bind on opened property', fakeAsync(() => {
293+
const fixture = TestBed.createComponent(DrawerOpenBinding);
294+
fixture.detectChanges();
295+
296+
let drawer: MatDrawer = fixture.debugElement
297+
.query(By.directive(MatDrawer)).componentInstance;
298+
299+
drawer.open();
300+
fixture.detectChanges();
301+
tick();
302+
303+
expect(fixture.componentInstance.isOpen).toBe(true);
304+
}));
290305
});
291306

292307
describe('focus trapping behavior', () => {
@@ -474,8 +489,8 @@ class DrawerContainerTwoDrawerTestApp {
474489
template: `
475490
<mat-drawer-container (backdropClick)="backdropClicked()">
476491
<mat-drawer #drawer position="start"
477-
(open)="open()"
478-
(close)="close()">
492+
(opened)="open()"
493+
(closed)="close()">
479494
<button #drawerButton>Content.</button>
480495
</mat-drawer>
481496
<button (click)="drawer.open()" class="open" #openButton></button>
@@ -517,7 +532,7 @@ class DrawerSetToOpenedFalse { }
517532
@Component({
518533
template: `
519534
<mat-drawer-container>
520-
<mat-drawer #drawer mode="side" opened="true" (open)="openCallback()">
535+
<mat-drawer #drawer mode="side" opened="true" (opened)="openCallback()">
521536
Closed Drawer.
522537
</mat-drawer>
523538
</mat-drawer-container>`,
@@ -526,6 +541,18 @@ class DrawerSetToOpenedTrue {
526541
openCallback = jasmine.createSpy('open callback');
527542
}
528543

544+
@Component({
545+
template: `
546+
<mat-drawer-container>
547+
<mat-drawer #drawer mode="side" [(opened)]="isOpen">
548+
Closed Drawer.
549+
</mat-drawer>
550+
</mat-drawer-container>`,
551+
})
552+
class DrawerOpenBinding {
553+
isOpen = false;
554+
}
555+
529556
@Component({
530557
template: `
531558
<mat-drawer-container>

src/lib/sidenav/drawer.ts

Lines changed: 46 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ import {
3434
import {DOCUMENT} from '@angular/platform-browser';
3535
import {merge} from 'rxjs/observable/merge';
3636
import {Subject} from 'rxjs/Subject';
37-
import {RxChain, filter, first, startWith, takeUntil} from '@angular/cdk/rxjs';
37+
import {Observable} from 'rxjs/Observable';
38+
import {RxChain, filter, map, first, startWith, takeUntil} from '@angular/cdk/rxjs';
3839

3940

4041
/** Throws an exception when two MatDrawer are matching the same position. */
@@ -177,11 +178,38 @@ export class MatDrawer implements AfterContentInit, OnDestroy {
177178
/** Current state of the sidenav animation. */
178179
_animationState: 'open-instant' | 'open' | 'void' = 'void';
179180

180-
/** Event emitted when the drawer is fully opened. */
181-
@Output('open') onOpen = new EventEmitter<MatDrawerToggleResult | void>();
181+
/** Event emitted when the drawer open state is changed. */
182+
@Output() openedChange: EventEmitter<boolean> = new EventEmitter<boolean>();
182183

183-
/** Event emitted when the drawer is fully closed. */
184-
@Output('close') onClose = new EventEmitter<MatDrawerToggleResult | void>();
184+
/** Event emitted when the drawer has been opened. */
185+
@Output('opened')
186+
get _openedStream(): Observable<void> {
187+
return RxChain.from(this.openedChange)
188+
.call(filter, o => o)
189+
.call(map, () => {})
190+
.result();
191+
}
192+
193+
/** Event emitted when the drawer has been closed. */
194+
@Output('closed')
195+
get _closedStream(): Observable<void> {
196+
return RxChain.from(this.openedChange)
197+
.call(filter, o => !o)
198+
.call(map, () => {})
199+
.result();
200+
}
201+
202+
/**
203+
* Event emitted when the drawer is fully opened.
204+
* @deprecated Use `openedChange` instead.
205+
*/
206+
@Output('open') onOpen = this._openedStream;
207+
208+
/**
209+
* Event emitted when the drawer is fully closed.
210+
* @deprecated Use `openedChange` instead.
211+
*/
212+
@Output('close') onClose = this._closedStream;
185213

186214
/** Event emitted when the drawer's position changes. */
187215
@Output('positionChanged') onPositionChanged = new EventEmitter<void>();
@@ -203,17 +231,19 @@ export class MatDrawer implements AfterContentInit, OnDestroy {
203231
constructor(private _elementRef: ElementRef,
204232
private _focusTrapFactory: FocusTrapFactory,
205233
@Optional() @Inject(DOCUMENT) private _doc: any) {
206-
this.onOpen.subscribe(() => {
207-
if (this._doc) {
208-
this._elementFocusedBeforeDrawerWasOpened = this._doc.activeElement as HTMLElement;
209-
}
234+
this.openedChange.subscribe((opened: boolean) => {
235+
if (opened) {
236+
if (this._doc) {
237+
this._elementFocusedBeforeDrawerWasOpened = this._doc.activeElement as HTMLElement;
238+
}
210239

211-
if (this._isFocusTrapEnabled && this._focusTrap) {
212-
this._focusTrap.focusInitialElementWhenReady();
240+
if (this._isFocusTrapEnabled && this._focusTrap) {
241+
this._focusTrap.focusInitialElementWhenReady();
242+
}
243+
} else {
244+
this._restoreFocus();
213245
}
214246
});
215-
216-
this.onClose.subscribe(() => this._restoreFocus());
217247
}
218248

219249
/**
@@ -309,9 +339,9 @@ export class MatDrawer implements AfterContentInit, OnDestroy {
309339
const {fromState, toState} = event;
310340

311341
if (toState.indexOf('open') === 0 && fromState === 'void') {
312-
this.onOpen.emit(new MatDrawerToggleResult('open', true));
342+
this.openedChange.emit(true);
313343
} else if (toState === 'void' && fromState.indexOf('open') === 0) {
314-
this.onClose.emit(new MatDrawerToggleResult('close', true));
344+
this.openedChange.emit(false);
315345
}
316346
}
317347

@@ -438,7 +468,7 @@ export class MatDrawerContainer implements AfterContentInit, OnDestroy {
438468
});
439469

440470
if (drawer.mode !== 'side') {
441-
takeUntil.call(merge(drawer.onOpen, drawer.onClose), this._drawers.changes).subscribe(() =>
471+
takeUntil.call(drawer.openedChange, this._drawers.changes).subscribe(() =>
442472
this._setContainerClass(drawer.opened));
443473
}
444474
}

0 commit comments

Comments
 (0)