Skip to content
This repository has been archived by the owner on Oct 7, 2020. It is now read-only.

Commit

Permalink
feat(snackbar): Improvements + test coverage (#200)
Browse files Browse the repository at this point in the history
* Remove `mdc-button` from snackbar dependency : ref MDC v0.21 update.
* Refactor individual snackbar directive files into the `snackbar.component.ts`
* Add return type to functions.
* Add initial test coverage.
  • Loading branch information
trimox authored Sep 20, 2017
1 parent 3f0afbb commit b9f978f
Show file tree
Hide file tree
Showing 7 changed files with 115 additions and 71 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ import { SnackbarMessage, MdcSnackbarComponent } from '../../../lib/public_api';
})
export class SnackbarDemoComponent {
message: SnackbarMessage = {
message: 'Hello',
actionText: 'Ok',
message: 'Message deleted',
actionText: 'Undo',
};
@ViewChild('snack') snack: MdcSnackbarComponent;
@ViewChild('snackStart') snackStart: MdcSnackbarComponent;
Expand Down
19 changes: 9 additions & 10 deletions src/lib/snackbar/index.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import { NgModule } from '@angular/core';

import { MdcSnackbarComponent } from './snackbar.component';
import { MdcSnackbarTextDirective } from './snackbar-text.directive';
import { MdcSnackbarActionWrapperDirective } from './snackbar-action-wrapper.directive';
import { MdcSnackbarActionButtonDirective } from './snackbar-action-button.directive';
import {
MdcSnackbarComponent,
MdcSnackbarText,
MdcSnackbarActionWrapper,
MdcSnackbarActionButton,
} from './snackbar.component';

const SNACKBAR_COMPONENTS = [
MdcSnackbarComponent,
MdcSnackbarTextDirective,
MdcSnackbarActionWrapperDirective,
MdcSnackbarActionButtonDirective
MdcSnackbarText,
MdcSnackbarActionWrapper,
MdcSnackbarActionButton,
];

@NgModule({
Expand All @@ -20,6 +22,3 @@ export class MdcSnackbarModule { }

export * from './snackbar.component';
export * from './snackbar-message';
export * from './snackbar-text.directive';
export * from './snackbar-action-wrapper.directive';
export * from './snackbar-action-button.directive';
15 changes: 0 additions & 15 deletions src/lib/snackbar/snackbar-action-button.directive.ts

This file was deleted.

14 changes: 0 additions & 14 deletions src/lib/snackbar/snackbar-action-wrapper.directive.ts

This file was deleted.

14 changes: 0 additions & 14 deletions src/lib/snackbar/snackbar-text.directive.ts

This file was deleted.

61 changes: 45 additions & 16 deletions src/lib/snackbar/snackbar.component.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import {
AfterViewInit,
Component,
Directive,
ElementRef,
HostBinding,
Input,
OnDestroy,
OnInit,
Renderer2,
ViewChild,
ViewEncapsulation
Expand All @@ -13,28 +14,56 @@ import { isBrowser } from '../common';
import { EventRegistry } from '../common/event-registry';

import { MDCSnackbarAdapter } from './snackbar-adapter';
import { MdcSnackbarTextDirective } from './snackbar-text.directive';
import { MdcSnackbarActionWrapperDirective } from './snackbar-action-wrapper.directive';
import { MdcSnackbarActionButtonDirective } from './snackbar-action-button.directive';
import { SnackbarMessage } from './snackbar-message';

import { MDCSnackbarFoundation } from '@material/snackbar';
import { getCorrectEventName } from '@material/animation';

@Component({
selector: 'mdc-snackbar-action-button',
template:
`
<button type="button"></button>
`
})
export class MdcSnackbarActionButton {
@HostBinding('class.mdc-snackbar__action-button') isHostClass = true;

constructor(public elementRef: ElementRef) { }
}

@Directive({
selector: '[mdc-snackbar-text], mdc-snackbar-text'
})
export class MdcSnackbarText {
@HostBinding('class.mdc-snackbar__text') isHostClass = true;

constructor(public elementRef: ElementRef) { }
}

@Directive({
selector: 'mdc-snackbar-action-wrapper'
})
export class MdcSnackbarActionWrapper {
@HostBinding('class.mdc-snackbar__action-wrapper') isHostClass = true;

constructor(public elementRef: ElementRef) { }
}

@Component({
selector: 'mdc-snackbar',
template:
`
<mdc-snackbar-text></mdc-snackbar-text>
<mdc-snackbar-action-wrapper>
<button mdc-snackbar-action-button></button>
<mdc-snackbar-action-button></mdc-snackbar-action-button>
</mdc-snackbar-action-wrapper>
`,
encapsulation: ViewEncapsulation.None,
providers: [EventRegistry]
})
export class MdcSnackbarComponent implements AfterViewInit, OnDestroy {
@Input() alignStart: boolean;
export class MdcSnackbarComponent implements OnInit, OnDestroy {
@Input() alignStart: boolean = false;
@Input()
get dismissOnAction() { return this._foundation.dismissesOnAction(); }
set dismissOnAction(value) {
Expand All @@ -47,9 +76,9 @@ export class MdcSnackbarComponent implements AfterViewInit, OnDestroy {
@HostBinding('class.mdc-snackbar--align-start') get classAlignStart(): string {
return this.alignStart ? 'mdc-snackbar--align-start' : '';
}
@ViewChild(MdcSnackbarTextDirective) snackText: MdcSnackbarTextDirective;
@ViewChild(MdcSnackbarActionWrapperDirective) actionWrapper: MdcSnackbarActionWrapperDirective;
@ViewChild(MdcSnackbarActionButtonDirective) actionButton: MdcSnackbarActionButtonDirective;
@ViewChild(MdcSnackbarText) snackText: MdcSnackbarText;
@ViewChild(MdcSnackbarActionWrapper) actionWrapper: MdcSnackbarActionWrapper;
@ViewChild(MdcSnackbarActionButton) actionButton: MdcSnackbarActionButton;

private _mdcAdapter: MDCSnackbarAdapter = {
addClass: (className: string) => {
Expand Down Expand Up @@ -90,7 +119,7 @@ export class MdcSnackbarComponent implements AfterViewInit, OnDestroy {
}
},
visibilityIsHidden: () => {
return isBrowser ? document.hidden : false;
return isBrowser() ? document.hidden : false;
},
registerCapturedBlurHandler: (handler: EventListener) => {
if (this._root && this.actionButton) {
Expand All @@ -103,12 +132,12 @@ export class MdcSnackbarComponent implements AfterViewInit, OnDestroy {
}
},
registerVisibilityChangeHandler: (handler: EventListener) => {
if (this._root && isBrowser()) {
this._registry.listen_(this._renderer, 'visibilitychange', handler, this._root);
if (isBrowser()) {
this._registry.listen_(this._renderer, 'visibilitychange', handler, 'document');
}
},
deregisterVisibilityChangeHandler: (handler: EventListener) => {
if (this._root && isBrowser()) {
if (isBrowser()) {
this._registry.unlisten_('visibilitychange', handler);
}
},
Expand Down Expand Up @@ -155,14 +184,14 @@ export class MdcSnackbarComponent implements AfterViewInit, OnDestroy {
private _root: ElementRef,
private _registry: EventRegistry) { }

ngAfterViewInit() {
ngOnInit() {
this._foundation.init();
}
ngOnDestroy() {
this._foundation.destroy();
}

show(data: SnackbarMessage) {
show(data: SnackbarMessage): void {
if (data) {
if (!data.actionHandler && data.actionText) {
data.actionHandler = () => { };
Expand Down
59 changes: 59 additions & 0 deletions test/unit/snackbar/snackbar.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { Component, DebugElement } from '@angular/core';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import {
MdcSnackbarComponent,
MdcSnackbarModule,
} from '../../../src/lib/public_api';

describe('MdcSnackbarComponent', () => {
let fixture: ComponentFixture<any>;

beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [MdcSnackbarModule],
declarations: [
SimpleSnack,
]
});
TestBed.compileComponents();
}));

describe('behaviors', () => {
let snackBarDebugElement: DebugElement;
let snackBarInstance: MdcSnackbarComponent;
let testComponent: SimpleSnack;

beforeEach(() => {
fixture = TestBed.createComponent(SimpleSnack);
fixture.detectChanges();

snackBarDebugElement = fixture.debugElement.query(By.directive(MdcSnackbarComponent));
snackBarInstance = snackBarDebugElement.componentInstance;
testComponent = fixture.debugElement.componentInstance;
});

it('#should have mdc-snackbar by default', () => {
expect(snackBarDebugElement.nativeElement.classList)
.toContain('mdc-snackbar', 'Expected to have mdc-snackbar');
});

it('#should apply class based on property', () => {
testComponent.isAlignStart = true;
fixture.detectChanges();
expect(snackBarDebugElement.nativeElement.classList.contains('mdc-snackbar--align-start')).toBe(true);
});
});
});

@Component({
template:
`
<mdc-snackbar
[alignStart]="isAlignStart">
</mdc-snackbar>
`
})
class SimpleSnack {
isAlignStart: boolean = false;
}

0 comments on commit b9f978f

Please sign in to comment.