diff --git a/components/tooltip/readme.md b/components/tooltip/readme.md index dfe52608a8..5697090dd6 100644 --- a/components/tooltip/readme.md +++ b/components/tooltip/readme.md @@ -8,7 +8,7 @@ import { TooltipModule } from 'ng2-bootstrap/components/tooltip'; ### Annotations ```typescript // class Tooltip implements OnInit -@Directive({ +@Directive({ selector: '[tooltip]', exportAs: 'bs-tooltip' }) @@ -21,6 +21,7 @@ export class TooltipDirective { @Input('tooltipAppendToBody') private appendToBody:boolean; @Input('tooltipClass') public popupClass:string; @Input('tooltipContext') public tooltipContext:any; + @Input('tooltipPopupDelay') public delay:number = 0; @Output() public tooltipStateChanged:EventEmitter; } ``` @@ -30,7 +31,7 @@ export class TooltipDirective { - `tooltipHtml` (`string|TempalteRef`) - tooltip custom html content, defined as string or template reference - `tooltipPlacement` (`?string='top'`) - tooltip positioning instruction, supported positions: 'top', 'bottom', 'left', 'right' - `tooltipAnimation` (`?boolean=true`) - if `false` fade tooltip animation will be disabled - - `tooltipPopupDelay` (*not implemented*) (`?numer=0`) - time in milliseconds before tooltip occurs + - `tooltipPopupDelay` (`?numer=0`) - time in milliseconds before tooltip occurs - `tooltipTrigger` (*not implemented*) (`?Array`) - array of event names which triggers tooltip opening - `tooltipEnable` (`?boolean=true`) - if `false` tooltip is disabled and will not be shown - `tooltipAppendToBody` (*not implemented*) (`?boolean=false`) - if `true` tooltip will be appended to body @@ -39,4 +40,4 @@ export class TooltipDirective { - `tooltipContext` (`any`) - if a template is used for the content, then this property can be used to specify a context for that template. The template variable exposed is called 'model'. ### Tooltip events - - `tooltipStateChanged` - This event fires each time the state of the tooltip is changed. Argument is boolean stating if the tooltip is visible or not. \ No newline at end of file + - `tooltipStateChanged` - This event fires each time the state of the tooltip is changed. Argument is boolean stating if the tooltip is visible or not. diff --git a/components/tooltip/tooltip.directive.ts b/components/tooltip/tooltip.directive.ts index 21ff2c9781..0701d4e3e2 100644 --- a/components/tooltip/tooltip.directive.ts +++ b/components/tooltip/tooltip.directive.ts @@ -1,5 +1,13 @@ import { - ComponentRef, Directive, HostListener, Input, ReflectiveInjector, TemplateRef, ViewContainerRef, Output, EventEmitter + ComponentRef, + Directive, + HostListener, + Input, + ReflectiveInjector, + TemplateRef, + ViewContainerRef, + Output, + EventEmitter } from '@angular/core'; import { TooltipContainerComponent } from './tooltip-container.component'; @@ -14,26 +22,30 @@ import { ComponentsHelper } from '../utils/components-helper.service'; /* tslint:enable */ export class TooltipDirective { /* tslint:disable */ - @Input('tooltip') public content:string; - @Input('tooltipHtml') public htmlContent:string | TemplateRef; - @Input('tooltipPlacement') public placement:string = 'top'; - @Input('tooltipIsOpen') public isOpen:boolean; - @Input('tooltipEnable') public enable:boolean = true; - @Input('tooltipAnimation') public animation:boolean = true; - @Input('tooltipAppendToBody') public appendToBody:boolean; - @Input('tooltipClass') public popupClass:string; - @Input('tooltipContext') public tooltipContext:any; + @Input('tooltip') public content: string; + @Input('tooltipHtml') public htmlContent: string | TemplateRef; + @Input('tooltipPlacement') public placement: string = 'top'; + @Input('tooltipIsOpen') public isOpen: boolean; + @Input('tooltipEnable') public enable: boolean = true; + @Input('tooltipAnimation') public animation: boolean = true; + @Input('tooltipAppendToBody') public appendToBody: boolean; + @Input('tooltipClass') public popupClass: string; + @Input('tooltipContext') public tooltipContext: any; + @Input('tooltipPopupDelay') public delay: number = 0; /* tslint:enable */ - @Output() public tooltipStateChanged:EventEmitter = new EventEmitter(); + @Output() public tooltipStateChanged: EventEmitter = new EventEmitter(); - public viewContainerRef:ViewContainerRef; - public componentsHelper:ComponentsHelper; + public viewContainerRef: ViewContainerRef; + public componentsHelper: ComponentsHelper; - private visible:boolean = false; - private tooltip:ComponentRef; + private visible: boolean = false; + private tooltip: ComponentRef; - public constructor(viewContainerRef:ViewContainerRef, componentsHelper:ComponentsHelper) { + private delayTimeoutId: NodeJS.Timer; + + public constructor(viewContainerRef: ViewContainerRef, + componentsHelper: ComponentsHelper) { this.viewContainerRef = viewContainerRef; this.componentsHelper = componentsHelper; } @@ -42,44 +54,63 @@ export class TooltipDirective { // params: event, target @HostListener('focusin') @HostListener('mouseenter') - public show():void { - if (this.visible || !this.enable) { + public show(): void { + if (this.visible || !this.enable || this.delayTimeoutId) { return; } - this.visible = true; - let options = new TooltipOptions({ - content: this.content, - htmlContent: this.htmlContent, - placement: this.placement, - animation: this.animation, - hostEl: this.viewContainerRef.element, - popupClass: this.popupClass, - context: this.tooltipContext - }); - - let binding = ReflectiveInjector.resolve([ - {provide: TooltipOptions, useValue: options} - ]); - - this.tooltip = this.componentsHelper - .appendNextToLocation(TooltipContainerComponent, this.viewContainerRef, binding); - this.triggerStateChanged(); + const showTooltip = () => { + this.visible = true; + let options = new TooltipOptions({ + content: this.content, + htmlContent: this.htmlContent, + placement: this.placement, + animation: this.animation, + hostEl: this.viewContainerRef.element, + popupClass: this.popupClass, + context: this.tooltipContext + }); + + let binding = ReflectiveInjector.resolve([ + {provide: TooltipOptions, useValue: options} + ]); + + this.tooltip = this.componentsHelper + .appendNextToLocation(TooltipContainerComponent, + this.viewContainerRef, + binding); + + this.triggerStateChanged(); + }; + + if (this.delay) { + this.delayTimeoutId = setTimeout(() => { + showTooltip(); + }, this.delay); + } else { + showTooltip(); + } } // params event, target @HostListener('focusout') @HostListener('mouseleave') - public hide():void { + public hide(): void { + if (this.delayTimeoutId) { + clearTimeout(this.delayTimeoutId); + this.delayTimeoutId = undefined; + } + if (!this.visible) { return; } + this.visible = false; this.tooltip.destroy(); this.triggerStateChanged(); } - private triggerStateChanged():void { + private triggerStateChanged(): void { this.tooltipStateChanged.emit(this.visible); } } diff --git a/demo/components/tooltip/tooltip-demo.html b/demo/components/tooltip/tooltip-demo.html index 9bb7ebb810..343303e768 100644 --- a/demo/components/tooltip/tooltip-demo.html +++ b/demo/components/tooltip/tooltip-demo.html @@ -23,7 +23,7 @@

- I can even contain HTML. Check me out! + I can even contain HTML. Check me out!

- Or use a TemplateRef. Check me out!

Programatically show/hide tooltip - Check me out!