diff --git a/src/framework/theme/components/popover/popover.spec.ts b/src/framework/theme/components/popover/popover.spec.ts index 9e81f1b01c..e400d0f7d4 100644 --- a/src/framework/theme/components/popover/popover.spec.ts +++ b/src/framework/theme/components/popover/popover.spec.ts @@ -16,7 +16,7 @@ import { NbTriggerStrategy, NbTriggerStrategyBuilderService, } from '../cdk'; -import { NB_DOCUMENT } from '@nebular/theme'; +import { NB_DOCUMENT } from '../../theme.options'; @Component({ @@ -148,15 +148,8 @@ export class MockTriggerStrategyBuilder { _host: HTMLElement; _container: () => ComponentRef; _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 { diff --git a/src/framework/theme/components/tooltip/tooltip.directive.ts b/src/framework/theme/components/tooltip/tooltip.directive.ts index e6d68ee399..3969697fe1 100644 --- a/src/framework/theme/components/tooltip/tooltip.directive.ts +++ b/src/framework/theme/components/tooltip/tooltip.directive.ts @@ -61,6 +61,16 @@ 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 { @@ -68,9 +78,7 @@ 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; @@ -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; protected positionStrategy: NbAdjustableConnectedPositionStrategy; @@ -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(); diff --git a/src/framework/theme/components/tooltip/tooltip.spec.ts b/src/framework/theme/components/tooltip/tooltip.spec.ts index bd94359959..b7b0c50804 100644 --- a/src/framework/theme/components/tooltip/tooltip.spec.ts +++ b/src/framework/theme/components/tooltip/tooltip.spec.ts @@ -1,15 +1,23 @@ -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({ @@ -17,7 +25,8 @@ import { NbTooltipModule } from './tooltip.module'; template: ` - + `, @@ -25,6 +34,7 @@ import { NbTooltipModule } from './tooltip.module'; export class NbTooltipStringTestComponent { @Input() icon; @Input() status; + @Input() trigger: NbTrigger = NbTrigger.HINT; @ViewChild('button') button: ElementRef; @ViewChild(NbTooltipDirective) tooltip: NbTooltipDirective; } @@ -82,6 +92,38 @@ export class MockPositionBuilder { }; } +@Injectable() +export class MockTriggerStrategyBuilder { + + _host: HTMLElement; + _container: () => ComponentRef; + _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): this { + this._container = container; + return this; + } + + build(): NbTriggerStrategy { + return { + show$: observableOf(null), + hide$: observableOf(null), + } as NbTriggerStrategy; + } +} describe('Directive: NbTooltipDirective', () => { beforeEach(() => { @@ -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); + }); });