Skip to content

Commit

Permalink
fix(toast): proper handling of autohide toggling (#3283)
Browse files Browse the repository at this point in the history
Toasts initially setup with `[autohide]="true"`were wrongly still
emitting `(hide)` output after toggling `autohide` to `false`.

A new demo has also been created to illustrate the `autohide` toggling
support, 'Prevent autohide on mouseover'.

Fixes #3280
  • Loading branch information
Benoit Charbonnier committed Jul 15, 2019
1 parent cc29290 commit ffcdad4
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 10 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<p>
In this demo, you can show a toast by clicking the button below. It will hide itself after a 5 seconds delay unless you simply hover it with your mouse.
</p>
<button class="btn btn-primary" (click)="show = true">
Click me to show a toast
</button>
<hr *ngIf="show">
<ngb-toast
*ngIf="show"
header="Autohide can be cancelled"
[delay]="5000"
[autohide]="autohide"
(mouseenter)="autohide = false"
(mouseleave)="autohide = true"
(hide)="show = false; autohide = true"
[class.bg-warning]="!autohide"
>
<div *ngIf="autohide">
Try to mouse hover me.
</div>
<div *ngIf="!autohide">
I will remain visible until you leave again.
</div>
</ngb-toast>
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import {NgModule} from '@angular/core';
import {BrowserModule} from '@angular/platform-browser';
import {NgbModule} from '@ng-bootstrap/ng-bootstrap';

import {NgbdToastPreventAutohide} from './toast-prevent-autohide';

@NgModule({
imports: [BrowserModule, NgbModule],
declarations: [NgbdToastPreventAutohide],
bootstrap: [NgbdToastPreventAutohide]
})
export class NgbdToastPreventAutohideModule {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import {Component} from '@angular/core';

@Component({selector: 'ngbd-toast-prevent-autohide', templateUrl: './toast-prevent-autohide.html'})

export class NgbdToastPreventAutohide {
show = false;
autohide = true;
}
20 changes: 17 additions & 3 deletions demo/src/app/components/toast/toast.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ import {NgbdToastGlobal} from './demos/howto-global/toast-global.component';
import {NgbdToastGlobalModule} from './demos/howto-global/toast-global.module';
import {NgbdToastInline} from './demos/inline/toast-inline';
import {NgbdToastInlineModule} from './demos/inline/toast-inline.module';
import {NgbdToastPreventAutohide} from './demos/prevent-autohide/toast-prevent-autohide';
import {NgbdToastPreventAutohideModule} from './demos/prevent-autohide/toast-prevent-autohide.module';
import {NgbdToastOverviewComponent} from './overview/toast-overview.component';



const OVERVIEW = {
'inline-usage': 'Declarative usage',
'toast-service': 'Building a toast management service'
Expand Down Expand Up @@ -48,6 +48,20 @@ const DEMOS = {
{name: 'toast-closeable.ts', source: require('!!raw-loader!./demos/closeable/toast-closeable.ts')}
]
},
'prevent-autohide': {
title: 'Prevent autohide on mouseover',
type: NgbdToastPreventAutohide,
files: [
{
name: 'toast-prevent-autohide.html',
source: require('!!raw-loader!./demos/prevent-autohide/toast-prevent-autohide.html')
},
{
name: 'toast-prevent-autohide.ts',
source: require('!!raw-loader!./demos/prevent-autohide/toast-prevent-autohide.ts')
}
]
},
global: {
title: 'Toast management service',
type: NgbdToastGlobal,
Expand Down Expand Up @@ -80,7 +94,7 @@ export const ROUTES = [
@NgModule({
imports: [
NgbdSharedModule, NgbdComponentsSharedModule, NgbdToastInlineModule, NgbdToastCloseableModule,
NgbdToastCustomHeaderModule, NgbdToastGlobalModule
NgbdToastCustomHeaderModule, NgbdToastPreventAutohideModule, NgbdToastGlobalModule
],
declarations: [NgbdToastOverviewComponent]
})
Expand Down
18 changes: 17 additions & 1 deletion src/toast/toast.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import {ComponentFixture, fakeAsync, TestBed, tick} from '@angular/core/testing'
import {createGenericTestComponent} from '../test/common';
import {NgbToastModule} from './toast.module';


const createTestComponent = (html: string) =>
createGenericTestComponent(html, TestComponent) as ComponentFixture<TestComponent>;

Expand Down Expand Up @@ -92,12 +91,29 @@ describe('ngb-toast', () => {
fixture.detectChanges();
expect(fixture.componentInstance.hide).toHaveBeenCalledTimes(1);
}));

it('should emit hide only one time regardless of autohide toggling', fakeAsync(() => {
const fixture =
createTestComponent(`<ngb-toast header="header" [autohide]="autohide" (hide)="hide()">body</ngb-toast>`);
tick(250);
fixture.componentInstance.autohide = false;
fixture.detectChanges();
tick(250);
fixture.detectChanges();
expect(fixture.componentInstance.hide).not.toHaveBeenCalled();
fixture.componentInstance.autohide = true;
fixture.detectChanges();
tick(500);
fixture.detectChanges();
expect(fixture.componentInstance.hide).toHaveBeenCalledTimes(1);
}));
});
});


@Component({selector: 'test-cmp', template: ''})
export class TestComponent {
visible = true;
autohide = true;
hide = jasmine.createSpy('hideSpy');
}
14 changes: 8 additions & 6 deletions src/toast/toast.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,16 +108,12 @@ export class NgbToast implements AfterContentInit,
this.autohide = config.autohide;
}

ngAfterContentInit() {
if (this.autohide) {
this._timeoutID = setTimeout(() => this.hide(), this.delay);
}
}
ngAfterContentInit() { this._init(); }

ngOnChanges(changes: SimpleChanges) {
if ('autohide' in changes) {
this._clearTimeout();
this.ngAfterContentInit();
this._init();
}
}

Expand All @@ -126,6 +122,12 @@ export class NgbToast implements AfterContentInit,
this.hideOutput.emit();
}

private _init() {
if (this.autohide && !this._timeoutID) {
this._timeoutID = setTimeout(() => this.hide(), this.delay);
}
}

private _clearTimeout() {
if (this._timeoutID) {
clearTimeout(this._timeoutID);
Expand Down

0 comments on commit ffcdad4

Please sign in to comment.