Skip to content

Commit

Permalink
feat(tooltip): added Tooltip delay functionality (#1116)
Browse files Browse the repository at this point in the history
* Added Tooltip delay functionality

* Fix Typescript setTimeout return type

* Wrapped showTooltip in a function
  • Loading branch information
Serginho authored and valorkin committed Oct 13, 2016
1 parent ec6ccc3 commit eb90e9a
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 45 deletions.
7 changes: 4 additions & 3 deletions components/tooltip/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { TooltipModule } from 'ng2-bootstrap/components/tooltip';
### Annotations
```typescript
// class Tooltip implements OnInit
@Directive({
@Directive({
selector: '[tooltip]',
exportAs: 'bs-tooltip'
})
Expand All @@ -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<boolean>;
}
```
Expand All @@ -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<string>`) - 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
Expand All @@ -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.
- `tooltipStateChanged` - This event fires each time the state of the tooltip is changed. Argument is boolean stating if the tooltip is visible or not.
107 changes: 69 additions & 38 deletions components/tooltip/tooltip.directive.ts
Original file line number Diff line number Diff line change
@@ -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';
Expand All @@ -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<any>;
@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<any>;
@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<boolean> = new EventEmitter<boolean>();
@Output() public tooltipStateChanged: EventEmitter<boolean> = new EventEmitter<boolean>();

public viewContainerRef:ViewContainerRef;
public componentsHelper:ComponentsHelper;
public viewContainerRef: ViewContainerRef;
public componentsHelper: ComponentsHelper;

private visible:boolean = false;
private tooltip:ComponentRef<any>;
private visible: boolean = false;
private tooltip: ComponentRef<any>;

public constructor(viewContainerRef:ViewContainerRef, componentsHelper:ComponentsHelper) {
private delayTimeoutId: NodeJS.Timer;

public constructor(viewContainerRef: ViewContainerRef,
componentsHelper: ComponentsHelper) {
this.viewContainerRef = viewContainerRef;
this.componentsHelper = componentsHelper;
}
Expand All @@ -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);
}
}
8 changes: 4 additions & 4 deletions demo/components/tooltip/tooltip-demo.html
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
</p>

<p>
I can even contain HTML. <a href="#" [tooltipHtml]="htmlTooltip" (tooltipStateChanged)="tooltipStateChanged($event)">Check me out!</a>
I can even contain HTML. <a href="#" [tooltipPopupDelay]="500" [tooltipHtml]="htmlTooltip" (tooltipStateChanged)="tooltipStateChanged($event)">Check me out!</a>
</p>

<template #toolTipTemplate let-model="model">
Expand All @@ -32,13 +32,13 @@ <h5>With context binding: {{model.text}}</h5>
</template>

<p>
Or use a TemplateRef. <a href="#" [tooltipHtml]="toolTipTemplate"
[tooltipContext]="tooltipModel"
Or use a TemplateRef. <a href="#" [tooltipHtml]="toolTipTemplate"
[tooltipContext]="tooltipModel"
(tooltipStateChanged)="tooltipStateChanged($event)">Check me out!</a>
</p>
<p>
Programatically show/hide tooltip
<a href="#" [tooltip]="'Foo'"
<a href="#" [tooltip]="'Foo'"
(tooltipStateChanged)="tooltipStateChanged($event)"
#tooltip="bs-tooltip">Check me out!</a>
<button class="btn btn-primary" (click)="tooltip.show()">Show tooltip</button>
Expand Down

0 comments on commit eb90e9a

Please sign in to comment.