Skip to content

Commit

Permalink
fix(tooltip): fix tooltip not being hide + tests (#1123)
Browse files Browse the repository at this point in the history
  • Loading branch information
nnixaa authored Jan 8, 2019
1 parent a466175 commit 9360a4b
Show file tree
Hide file tree
Showing 3 changed files with 197 additions and 4 deletions.
6 changes: 5 additions & 1 deletion src/framework/theme/components/tooltip/tooltip.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export class NbTooltipComponent {

@HostBinding('class')
get binding() {
return `${this.position} ${this.context.status}-tooltip`;
return `${this.position} ${this.statusClass}`;
}

@HostBinding('@showTooltip')
Expand All @@ -73,4 +73,8 @@ export class NbTooltipComponent {

@Input()
context: { icon?: string, status?: string } = {};

get statusClass() {
return this.context.status ? `${this.context.status}-tooltip` : '';
}
}
14 changes: 11 additions & 3 deletions src/framework/theme/components/tooltip/tooltip.directive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,10 +121,15 @@ export class NbTooltipDirective implements AfterViewInit, OnDestroy {

ngAfterViewInit() {
this.subscribeOnTriggers();
this.subscribeOnPositionChange();
}

ngOnDestroy() {
this.alive = false;
this.hide();
if (this.ref) {
this.ref.dispose();
}
}

show() {
Expand All @@ -136,7 +141,11 @@ export class NbTooltipDirective implements AfterViewInit, OnDestroy {
}

hide() {
this.ref.detach();
if (this.ref) {
this.ref.detach();
}

this.container = null;
}

toggle() {
Expand All @@ -148,12 +157,10 @@ export class NbTooltipDirective implements AfterViewInit, OnDestroy {
}

protected createOverlay() {
this.positionStrategy = this.createPositionStrategy();
this.ref = this.overlay.create({
positionStrategy: this.positionStrategy,
scrollStrategy: this.overlay.scrollStrategies.reposition(),
});
this.subscribeOnPositionChange();
}

protected openTooltip() {
Expand Down Expand Up @@ -182,6 +189,7 @@ export class NbTooltipDirective implements AfterViewInit, OnDestroy {
}

protected subscribeOnPositionChange() {
this.positionStrategy = this.createPositionStrategy();
this.positionStrategy.positionChange
.pipe(takeWhile(() => this.alive))
.subscribe((position: NbPosition) => patch(this.container, { position }));
Expand Down
181 changes: 181 additions & 0 deletions src/framework/theme/components/tooltip/tooltip.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
import { Component, ElementRef, Input, NgModule, ViewChild } from '@angular/core';
import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';

import { Subject } from 'rxjs';

import { NbThemeModule } from '../../theme.module';
import { NbLayoutModule } from '../layout/layout.module';
import { NbAdjustment, NbPosition, NbPositionBuilderService } from '../cdk';
import { NbTooltipDirective } from './tooltip.directive';
import { NbTooltipModule } from './tooltip.module';


@Component({
selector: 'nb-tooltip-string-test',
template: `
<nb-layout>
<nb-layout-column>
<button #button nbTooltip="test" [nbTooltipIcon]="icon" [nbTooltipStatus]="status"></button>
</nb-layout-column>
</nb-layout>
`,
})
export class NbTooltipStringTestComponent {
@Input() icon;
@Input() status;
@ViewChild('button') button: ElementRef;
@ViewChild(NbTooltipDirective) tooltip: NbTooltipDirective;
}

@NgModule({
imports: [
RouterTestingModule.withRoutes([]),
NbThemeModule.forRoot(),
NbLayoutModule,
NoopAnimationsModule,
NbTooltipModule,
],
declarations: [
NbTooltipStringTestComponent,
],
})
export class TooltipTestModule {
}

export class MockPositionBuilder {
positionChange = new Subject();
_connectedTo: ElementRef<any>;
_position: NbPosition;
_adjustment: NbAdjustment;

connectedTo(connectedTo: ElementRef<any>) {
this._connectedTo = connectedTo;
return this;
}

position(position: NbPosition) {
this._position = position;
return this;
}

adjustment(adjustment: NbAdjustment) {
this._adjustment = adjustment;
return this;
}

offset() {
return this;
};

attach() {
};

apply() {
};

detach() {
};

dispose() {
};
}


describe('Directive: NbTooltipDirective', () => {
beforeEach(() => {
TestBed.configureTestingModule({ imports: [TooltipTestModule] });
});

let fixture: ComponentFixture<NbTooltipStringTestComponent>;

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

afterEach(() => {
fixture.destroy();
});

it('should render string', () => {
fixture.componentInstance.tooltip.show();
fixture.detectChanges();

const textContainer = fixture.nativeElement.querySelector('nb-tooltip .content span');
expect(textContainer.textContent).toContain('test');
});

it('should hide', fakeAsync(() => {
fixture.componentInstance.tooltip.show();
fixture.detectChanges();


const textContainer = fixture.nativeElement.querySelector('nb-tooltip .content span');
expect(textContainer.textContent).toContain('test');
fixture.componentInstance.tooltip.hide();
fixture.detectChanges();

tick(); // we need this tick for animations
const tooltip = fixture.nativeElement.querySelector('nb-tooltip');
expect(tooltip).toBeNull();
}));

it('should toogle', fakeAsync(() => {
let textContainer;

fixture.componentInstance.tooltip.show();
fixture.detectChanges();

textContainer = fixture.nativeElement.querySelector('nb-tooltip .content span');
expect(textContainer.textContent).toContain('test');
fixture.componentInstance.tooltip.toggle();
fixture.detectChanges();

tick(); // we need this tick for animations
const tooltip = fixture.nativeElement.querySelector('nb-tooltip');
expect(tooltip).toBeNull();

fixture.componentInstance.tooltip.toggle();
fixture.detectChanges();

textContainer = fixture.nativeElement.querySelector('nb-tooltip .content span');
expect(textContainer.textContent).toContain('test');
}));

it('should display icon', () => {
fixture.componentInstance.icon = 'some-icon';
fixture.detectChanges();
fixture.componentInstance.tooltip.show();
fixture.detectChanges();

const iconContainer = fixture.nativeElement.querySelector('nb-tooltip .content i');
expect(iconContainer.className).toContain('icon some-icon');
});

it('should display status', () => {
fixture.componentInstance.status = 'danger';
fixture.detectChanges();
fixture.componentInstance.tooltip.show();
fixture.detectChanges();

const iconContainer = fixture.nativeElement.querySelector('nb-tooltip');
expect(iconContainer.className).toContain('danger-tooltip');
});

it('should build position strategy', () => {
const mockPositionBuilder = new MockPositionBuilder();
TestBed.resetTestingModule();
TestBed.configureTestingModule({
imports: [TooltipTestModule],
providers: [{ provide: NbPositionBuilderService, useValue: mockPositionBuilder }],
});
fixture = TestBed.createComponent(NbTooltipStringTestComponent);
fixture.detectChanges();

expect(mockPositionBuilder._connectedTo.nativeElement).toBe(fixture.componentInstance.button.nativeElement);
expect(mockPositionBuilder._position).toBe(NbPosition.TOP);
expect(mockPositionBuilder._adjustment).toBe(NbAdjustment.CLOCKWISE);
});
});

0 comments on commit 9360a4b

Please sign in to comment.