From 5dccd24ea96c0bff249394cb432db464e4745cb5 Mon Sep 17 00:00:00 2001
From: Andrew Seguin
Date: Wed, 7 Dec 2016 13:14:11 -0800
Subject: [PATCH 1/5] feat(tooltip): add input for delaying show and hide
---
src/demo-app/tooltip/tooltip-demo.html | 16 +++++++-
src/demo-app/tooltip/tooltip-demo.ts | 2 +
src/lib/tooltip/tooltip.spec.ts | 46 ++++++++++++++++++++--
src/lib/tooltip/tooltip.ts | 54 +++++++++++++++++---------
4 files changed, 94 insertions(+), 24 deletions(-)
diff --git a/src/demo-app/tooltip/tooltip-demo.html b/src/demo-app/tooltip/tooltip-demo.html
index 6da3a8b8efc6..da2965962171 100644
--- a/src/demo-app/tooltip/tooltip-demo.html
+++ b/src/demo-app/tooltip/tooltip-demo.html
@@ -6,7 +6,9 @@ Tooltip Demo
md-raised-button
color="primary"
[md-tooltip]="message"
- [tooltip-position]="position">
+ [tooltip-position]="position"
+ [tooltip-show-delay]="showDelay"
+ [tooltip-hide-delay]="hideDelay">
Mouse over to see the tooltip
@@ -27,11 +29,21 @@ Tooltip Demo
+
+ Show Delay (ms):
+
+
+
+
+ Hide Delay (ms):
+
+
+
Mouse over to
Show tooltip
-
+
Hide tooltip
diff --git a/src/demo-app/tooltip/tooltip-demo.ts b/src/demo-app/tooltip/tooltip-demo.ts
index 5d0cc2506ac5..56046e7156c7 100644
--- a/src/demo-app/tooltip/tooltip-demo.ts
+++ b/src/demo-app/tooltip/tooltip-demo.ts
@@ -11,4 +11,6 @@ import {TooltipPosition} from '@angular/material';
export class TooltipDemo {
position: TooltipPosition = 'below';
message: string = 'Here is the tooltip';
+ showDelay = 0;
+ hideDelay = 0;
}
diff --git a/src/lib/tooltip/tooltip.spec.ts b/src/lib/tooltip/tooltip.spec.ts
index 29b722448b31..b08aca25159a 100644
--- a/src/lib/tooltip/tooltip.spec.ts
+++ b/src/lib/tooltip/tooltip.spec.ts
@@ -54,6 +54,7 @@ describe('MdTooltip', () => {
expect(tooltipDirective._tooltipInstance).toBeUndefined();
tooltipDirective.show();
+ tick(0); // Tick for the show delay (default is 0)
expect(tooltipDirective._isTooltipVisible()).toBe(true);
fixture.detectChanges();
@@ -74,32 +75,67 @@ describe('MdTooltip', () => {
expect(tooltipDirective._tooltipInstance).toBeNull();
}));
+ it('should show with delay', fakeAsync(() => {
+ expect(tooltipDirective._tooltipInstance).toBeUndefined();
+
+ const tooltipDelay = 1000;
+ tooltipDirective.show(tooltipDelay);
+ expect(tooltipDirective._isTooltipVisible()).toBe(false);
+
+ fixture.detectChanges();
+ expect(overlayContainerElement.textContent).toContain('');
+
+ tick(tooltipDelay);
+ expect(tooltipDirective._isTooltipVisible()).toBe(true);
+ expect(overlayContainerElement.textContent).toContain(initialTooltipMessage);
+ }));
+
+ it('should not show if hide is called before delay finishes', fakeAsync(() => {
+ expect(tooltipDirective._tooltipInstance).toBeUndefined();
+
+ const tooltipDelay = 1000;
+ tooltipDirective.show(tooltipDelay);
+ expect(tooltipDirective._isTooltipVisible()).toBe(false);
+
+ fixture.detectChanges();
+ expect(overlayContainerElement.textContent).toContain('');
+
+ tooltipDirective.hide();
+ tick(tooltipDelay);
+ expect(tooltipDirective._isTooltipVisible()).toBe(false);
+ }));
+
it('should not show tooltip if message is not present or empty', fakeAsync(() => {
expect(tooltipDirective._tooltipInstance).toBeUndefined();
tooltipDirective.message = undefined;
fixture.detectChanges();
tooltipDirective.show();
+ tick(0); // Tick for the show delay (default is 0)
expect(tooltipDirective._tooltipInstance).toBeUndefined();
tooltipDirective.message = null;
fixture.detectChanges();
tooltipDirective.show();
+ tick(0); // Tick for the show delay (default is 0)
expect(tooltipDirective._tooltipInstance).toBeUndefined();
tooltipDirective.message = '';
fixture.detectChanges();
tooltipDirective.show();
+ tick(0); // Tick for the show delay (default is 0)
expect(tooltipDirective._tooltipInstance).toBeUndefined();
tooltipDirective.message = ' ';
fixture.detectChanges();
tooltipDirective.show();
+ tick(0); // Tick for the show delay (default is 0)
expect(tooltipDirective._tooltipInstance).toBeUndefined();
}));
it('should not follow through with hide if show is called after', fakeAsync(() => {
tooltipDirective.show();
+ tick(0); // Tick for the show delay (default is 0)
expect(tooltipDirective._isTooltipVisible()).toBe(true);
// After hide called, a timeout delay is created that will to hide the tooltip.
@@ -133,10 +169,11 @@ describe('MdTooltip', () => {
expect(tooltipDirective._overlayRef).toBeNull();
});
- it('should be able to modify the tooltip message', () => {
+ it('should be able to modify the tooltip message', fakeAsync(() => {
expect(tooltipDirective._tooltipInstance).toBeUndefined();
tooltipDirective.show();
+ tick(0); // Tick for the show delay (default is 0)
expect(tooltipDirective._tooltipInstance._visibility).toBe('visible');
fixture.detectChanges();
@@ -147,16 +184,17 @@ describe('MdTooltip', () => {
fixture.detectChanges();
expect(overlayContainerElement.textContent).toContain(newMessage);
- });
+ }));
- it('should be removed after parent destroyed', () => {
+ it('should be removed after parent destroyed', fakeAsync(() => {
tooltipDirective.show();
+ tick(0); // Tick for the show delay (default is 0)
expect(tooltipDirective._isTooltipVisible()).toBe(true);
fixture.destroy();
expect(overlayContainerElement.childNodes.length).toBe(0);
expect(overlayContainerElement.textContent).toBe('');
- });
+ }));
it('should not try to dispose the tooltip when destroyed and done hiding', fakeAsync(() => {
tooltipDirective.show();
diff --git a/src/lib/tooltip/tooltip.ts b/src/lib/tooltip/tooltip.ts
index 4c253d85fd37..afafa44b6ec8 100644
--- a/src/lib/tooltip/tooltip.ts
+++ b/src/lib/tooltip/tooltip.ts
@@ -74,6 +74,12 @@ export class MdTooltip {
}
}
+ /** The default delay in ms before showing the tooltip after show is called */
+ @Input('tooltip-show-delay') showDelay = 0;
+
+ /** The default delay in ms before hiding the tooltip after hide is called */
+ @Input('tooltip-hide-delay') hideDelay = 0;
+
/** The message to be displayed in the tooltip */
private _message: string;
@Input('md-tooltip') get message() {
@@ -97,22 +103,20 @@ export class MdTooltip {
}
}
- /** Shows the tooltip */
- show(): void {
- if (!this._message || !this._message.trim()) {
- return;
- }
+ /** Shows the tooltip after the provided delay in ms */
+ show(delay = this.showDelay): void {
+ if (!this._message || !this._message.trim()) { return; }
if (!this._tooltipInstance) {
this._createTooltip();
}
this._setTooltipMessage(this._message);
- this._tooltipInstance.show(this._position);
+ this._tooltipInstance.show(this._position, delay);
}
- /** Hides the tooltip after the provided delay in ms, defaulting to 0ms. */
- hide(delay = 0): void {
+ /** Hides the tooltip after the provided delay in ms. */
+ hide(delay = this.hideDelay): void {
if (this._tooltipInstance) {
this._tooltipInstance.hide(delay);
}
@@ -222,7 +226,7 @@ export class MdTooltip {
}
}
-export type TooltipVisibility = 'visible' | 'hidden';
+export type TooltipVisibility = 'initial' | 'visible' | 'hidden';
@Component({
moduleId: module.id,
@@ -232,6 +236,7 @@ export type TooltipVisibility = 'visible' | 'hidden';
animations: [
trigger('state', [
state('void', style({transform: 'scale(0)'})),
+ state('initial', style({transform: 'scale(0)'})),
state('visible', style({transform: 'scale(1)'})),
state('hidden', style({transform: 'scale(0)'})),
transition('* => visible', animate('150ms cubic-bezier(0.0, 0.0, 0.2, 1)')),
@@ -246,11 +251,14 @@ export class TooltipComponent {
/** Message to display in the tooltip */
message: string;
+ /** The timeout ID of any current timer set to show the tooltip */
+ _showTimeoutId: number;
+
/** The timeout ID of any current timer set to hide the tooltip */
_hideTimeoutId: number;
/** Property watched by the animation framework to show or hide the tooltip */
- _visibility: TooltipVisibility;
+ _visibility: TooltipVisibility = 'initial';
/** Whether interactions on the page should close the tooltip */
_closeOnInteraction: boolean = false;
@@ -264,23 +272,33 @@ export class TooltipComponent {
constructor(@Optional() private _dir: Dir) {}
/** Shows the tooltip with an animation originating from the provided origin */
- show(position: TooltipPosition): void {
- this._closeOnInteraction = false;
- this._visibility = 'visible';
- this._setTransformOrigin(position);
-
+ show(position: TooltipPosition, delay: number): void {
// Cancel the delayed hide if it is scheduled
if (this._hideTimeoutId) {
clearTimeout(this._hideTimeoutId);
}
- // If this was set to true immediately, then the body click would trigger interaction and
- // close the tooltip right after it was displayed.
- setTimeout(() => { this._closeOnInteraction = true; }, 0);
+ // Body interactions should cancel the tooltip if there is a delay in showing.
+ this._closeOnInteraction = true;
+
+ this._setTransformOrigin(position);
+ this._showTimeoutId = setTimeout(() => {
+ this._visibility = 'visible';
+
+ // If this was set to true immediately, then a body click that triggers show() would
+ // trigger interaction and close the tooltip right after it was displayed.
+ this._closeOnInteraction = false;
+ setTimeout(() => { this._closeOnInteraction = true; }, 0);
+ }, delay);
}
/** Begins the animation to hide the tooltip after the provided delay in ms */
hide(delay: number): void {
+ // Cancel the delayed show if it is scheduled
+ if (this._showTimeoutId) {
+ clearTimeout(this._showTimeoutId);
+ }
+
this._hideTimeoutId = setTimeout(() => {
this._visibility = 'hidden';
this._closeOnInteraction = false;
From 2da2e5b015801b0d5f71e4a4dc4adaaba12da1c6 Mon Sep 17 00:00:00 2001
From: Andrew Seguin
Date: Wed, 7 Dec 2016 13:15:13 -0800
Subject: [PATCH 2/5] change input for delays to number
---
src/demo-app/tooltip/tooltip-demo.html | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/demo-app/tooltip/tooltip-demo.html b/src/demo-app/tooltip/tooltip-demo.html
index da2965962171..ceb672c9c9bf 100644
--- a/src/demo-app/tooltip/tooltip-demo.html
+++ b/src/demo-app/tooltip/tooltip-demo.html
@@ -31,12 +31,12 @@ Tooltip Demo
Show Delay (ms):
-
+
Hide Delay (ms):
-
+
Mouse over to
From e5d93f14769e722044ed7c103d825dae7bdce320 Mon Sep 17 00:00:00 2001
From: Andrew Seguin
Date: Wed, 7 Dec 2016 13:18:48 -0800
Subject: [PATCH 3/5] remove fakeasyc from tests that dont need show tick
---
src/lib/tooltip/tooltip.spec.ts | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/src/lib/tooltip/tooltip.spec.ts b/src/lib/tooltip/tooltip.spec.ts
index b08aca25159a..97481e8bbf80 100644
--- a/src/lib/tooltip/tooltip.spec.ts
+++ b/src/lib/tooltip/tooltip.spec.ts
@@ -105,33 +105,29 @@ describe('MdTooltip', () => {
expect(tooltipDirective._isTooltipVisible()).toBe(false);
}));
- it('should not show tooltip if message is not present or empty', fakeAsync(() => {
+ it('should not show tooltip if message is not present or empty', () => {
expect(tooltipDirective._tooltipInstance).toBeUndefined();
tooltipDirective.message = undefined;
fixture.detectChanges();
tooltipDirective.show();
- tick(0); // Tick for the show delay (default is 0)
expect(tooltipDirective._tooltipInstance).toBeUndefined();
tooltipDirective.message = null;
fixture.detectChanges();
tooltipDirective.show();
- tick(0); // Tick for the show delay (default is 0)
expect(tooltipDirective._tooltipInstance).toBeUndefined();
tooltipDirective.message = '';
fixture.detectChanges();
tooltipDirective.show();
- tick(0); // Tick for the show delay (default is 0)
expect(tooltipDirective._tooltipInstance).toBeUndefined();
tooltipDirective.message = ' ';
fixture.detectChanges();
tooltipDirective.show();
- tick(0); // Tick for the show delay (default is 0)
expect(tooltipDirective._tooltipInstance).toBeUndefined();
- }));
+ });
it('should not follow through with hide if show is called after', fakeAsync(() => {
tooltipDirective.show();
From fb4a75022e68440b54b4642dbcccbe47a625ff2c Mon Sep 17 00:00:00 2001
From: Andrew Seguin
Date: Wed, 7 Dec 2016 13:21:18 -0800
Subject: [PATCH 4/5] fix comment
---
src/lib/tooltip/tooltip.ts | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/lib/tooltip/tooltip.ts b/src/lib/tooltip/tooltip.ts
index afafa44b6ec8..342ac3b7f41f 100644
--- a/src/lib/tooltip/tooltip.ts
+++ b/src/lib/tooltip/tooltip.ts
@@ -103,8 +103,8 @@ export class MdTooltip {
}
}
- /** Shows the tooltip after the provided delay in ms */
- show(delay = this.showDelay): void {
+ /** Shows the tooltip after the delay in ms, defaults to tooltip-delay-show or 0ms if no input */
+ show(delay: number = this.showDelay): void {
if (!this._message || !this._message.trim()) { return; }
if (!this._tooltipInstance) {
@@ -115,8 +115,8 @@ export class MdTooltip {
this._tooltipInstance.show(this._position, delay);
}
- /** Hides the tooltip after the provided delay in ms. */
- hide(delay = this.hideDelay): void {
+ /** Hides the tooltip after the delay in ms, defaults to tooltip-delay-hide or 0ms if no input */
+ hide(delay: number = this.hideDelay): void {
if (this._tooltipInstance) {
this._tooltipInstance.hide(delay);
}
From a6547d198963c7a83568f14ed1fa9db562451911 Mon Sep 17 00:00:00 2001
From: Andrew Seguin
Date: Wed, 7 Dec 2016 14:14:49 -0800
Subject: [PATCH 5/5] rename new inputs to camelCase
---
src/demo-app/tooltip/tooltip-demo.html | 4 ++--
src/lib/tooltip/tooltip.ts | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/demo-app/tooltip/tooltip-demo.html b/src/demo-app/tooltip/tooltip-demo.html
index ceb672c9c9bf..4dd5a6cc475b 100644
--- a/src/demo-app/tooltip/tooltip-demo.html
+++ b/src/demo-app/tooltip/tooltip-demo.html
@@ -7,8 +7,8 @@ Tooltip Demo
color="primary"
[md-tooltip]="message"
[tooltip-position]="position"
- [tooltip-show-delay]="showDelay"
- [tooltip-hide-delay]="hideDelay">
+ [tooltipShowDelay]="showDelay"
+ [tooltipHideDelay]="hideDelay">
Mouse over to see the tooltip
diff --git a/src/lib/tooltip/tooltip.ts b/src/lib/tooltip/tooltip.ts
index 342ac3b7f41f..c14536da593d 100644
--- a/src/lib/tooltip/tooltip.ts
+++ b/src/lib/tooltip/tooltip.ts
@@ -75,10 +75,10 @@ export class MdTooltip {
}
/** The default delay in ms before showing the tooltip after show is called */
- @Input('tooltip-show-delay') showDelay = 0;
+ @Input('tooltipShowDelay') showDelay = 0;
/** The default delay in ms before hiding the tooltip after hide is called */
- @Input('tooltip-hide-delay') hideDelay = 0;
+ @Input('tooltipHideDelay') hideDelay = 0;
/** The message to be displayed in the tooltip */
private _message: string;