Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(tooltip): added Tooltip delay functionality #1116

Merged
merged 3 commits into from
Oct 13, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 comment was marked as off-topic.

This comment was marked as off-topic.

This comment was marked as off-topic.

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