Skip to content

Commit

Permalink
feat(tooltip): add new nbTooltipTrigger parameter (#1138)
Browse files Browse the repository at this point in the history
  • Loading branch information
nnixaa authored Jan 9, 2019
1 parent 1e43929 commit 113d3b0
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 17 deletions.
11 changes: 2 additions & 9 deletions src/framework/theme/components/popover/popover.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
NbTriggerStrategy,
NbTriggerStrategyBuilderService,
} from '../cdk';
import { NB_DOCUMENT } from '@nebular/theme';
import { NB_DOCUMENT } from '../../theme.options';


@Component({
Expand Down Expand Up @@ -148,15 +148,8 @@ export class MockTriggerStrategyBuilder {
_host: HTMLElement;
_container: () => ComponentRef<any>;
_trigger: NbTrigger;
_document: Document;

constructor(@Inject(NB_DOCUMENT) document) {
this.document(document);
}

document(document: Document): this {
this._document = document;
return this;
constructor(@Inject(NB_DOCUMENT) public _document: Document) {
}

trigger(trigger: NbTrigger): this {
Expand Down
23 changes: 19 additions & 4 deletions src/framework/theme/components/tooltip/tooltip.directive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,16 +61,24 @@ import { NbTooltipComponent } from './tooltip.component';
* It is also possible to specify tooltip color using `nbTooltipStatus` property:
* @stacked-example(Colored Tooltips, tooltip/tooltip-colors.component)
*
* Tooltip has a number of triggers which provides an ability to show and hide the component in different ways:
*
* - Click mode shows the component when a user clicks on the host element and hides when the user clicks
* somewhere on the document outside the component.
* - Hint provides capability to show the component when the user hovers over the host element
* and hide when the user hovers out of the host.
* - Hover works like hint mode with one exception - when the user moves mouse from host element to
* the container element the component remains open, so that it is possible to interact with it content.
* - Focus mode is applied when user focuses the element.
* - Noop mode - the component won't react to the user interaction.
*/
@Directive({ selector: '[nbTooltip]' })
export class NbTooltipDirective implements AfterViewInit, OnDestroy {

context: Object = {};

/**
* Popover content which will be rendered in NbTooltipComponent.
* Available content: template ref, component and any primitive.
*
* Tooltip message
*/
@Input('nbTooltip')
content: string;
Expand Down Expand Up @@ -106,6 +114,13 @@ export class NbTooltipDirective implements AfterViewInit, OnDestroy {
this.context = Object.assign(this.context, { status });
}

/**
* Describes when the container will be shown.
* Available options: `click`, `hover`, `hint`, `focus` and `noop`
* */
@Input('nbTooltipTrigger')
trigger: NbTrigger = NbTrigger.HINT;

protected ref: NbOverlayRef;
protected container: ComponentRef<any>;
protected positionStrategy: NbAdjustableConnectedPositionStrategy;
Expand Down Expand Up @@ -182,7 +197,7 @@ export class NbTooltipDirective implements AfterViewInit, OnDestroy {

protected createTriggerStrategy(): NbTriggerStrategy {
return this.triggerStrategyBuilder
.trigger(NbTrigger.HINT)
.trigger(this.trigger)
.host(this.hostRef.nativeElement)
.container(() => this.container)
.build();
Expand Down
77 changes: 73 additions & 4 deletions src/framework/theme/components/tooltip/tooltip.spec.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,40 @@
import { Component, ElementRef, Input, NgModule, ViewChild } from '@angular/core';
import { Component, ComponentRef, ElementRef, Inject, Injectable, 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 { of as observableOf, Subject } from 'rxjs';

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


@Component({
selector: 'nb-tooltip-string-test',
template: `
<nb-layout>
<nb-layout-column>
<button #button nbTooltip="test" [nbTooltipIcon]="icon" [nbTooltipStatus]="status"></button>
<button #button nbTooltip="test" [nbTooltipIcon]="icon" [nbTooltipStatus]="status" [nbTooltipTrigger]="trigger">
</button>
</nb-layout-column>
</nb-layout>
`,
})
export class NbTooltipStringTestComponent {
@Input() icon;
@Input() status;
@Input() trigger: NbTrigger = NbTrigger.HINT;
@ViewChild('button') button: ElementRef;
@ViewChild(NbTooltipDirective) tooltip: NbTooltipDirective;
}
Expand Down Expand Up @@ -82,6 +92,38 @@ export class MockPositionBuilder {
};
}

@Injectable()
export class MockTriggerStrategyBuilder {

_host: HTMLElement;
_container: () => ComponentRef<any>;
_trigger: NbTrigger;

constructor(@Inject(NB_DOCUMENT) public _document: Document) {
}

trigger(trigger: NbTrigger): this {
this._trigger = trigger;
return this;
}

host(host: HTMLElement): this {
this._host = host;
return this;
}

container(container: () => ComponentRef<any>): this {
this._container = container;
return this;
}

build(): NbTriggerStrategy {
return {
show$: observableOf(null),
hide$: observableOf(null),
} as NbTriggerStrategy;
}
}

describe('Directive: NbTooltipDirective', () => {
beforeEach(() => {
Expand Down Expand Up @@ -178,4 +220,31 @@ describe('Directive: NbTooltipDirective', () => {
expect(mockPositionBuilder._position).toBe(NbPosition.TOP);
expect(mockPositionBuilder._adjustment).toBe(NbAdjustment.CLOCKWISE);
});

it('should build with default trigger strategy', () => {
TestBed.resetTestingModule();
const bed = TestBed.configureTestingModule({
imports: [TooltipTestModule],
providers: [{ provide: NbTriggerStrategyBuilderService, useClass: MockTriggerStrategyBuilder }],
});
const mockTriggerStrategy = bed.get(NbTriggerStrategyBuilderService);
fixture = TestBed.createComponent(NbTooltipStringTestComponent);
fixture.detectChanges();

expect(mockTriggerStrategy._trigger).toBe(NbTrigger.HINT);
});

it('should build with custom trigger strategy', () => {
TestBed.resetTestingModule();
const bed = TestBed.configureTestingModule({
imports: [TooltipTestModule],
providers: [{ provide: NbTriggerStrategyBuilderService, useClass: MockTriggerStrategyBuilder }],
});
const mockTriggerStrategy = bed.get(NbTriggerStrategyBuilderService);
fixture = TestBed.createComponent(NbTooltipStringTestComponent);
fixture.componentInstance.trigger = NbTrigger.CLICK;
fixture.detectChanges();

expect(mockTriggerStrategy._trigger).toBe(NbTrigger.CLICK);
});
});

0 comments on commit 113d3b0

Please sign in to comment.