Skip to content

Commit

Permalink
feat(tooltip): add tooltip animations (#1644)
Browse files Browse the repository at this point in the history
  • Loading branch information
andrewseguin authored and hansl committed Nov 1, 2016
1 parent ad3100e commit 52582f4
Show file tree
Hide file tree
Showing 5 changed files with 308 additions and 130 deletions.
24 changes: 21 additions & 3 deletions src/demo-app/tooltip/tooltip-demo.html
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
<div class="demo-tooltip">
<h1>Tooltip Demo</h1>

<p class="centered">
<button
<button #tooltip="mdTooltip"
md-raised-button
color="primary"
md-tooltip="to see a tooltip"
[md-tooltip]="message"
[tooltip-position]="position">
Mouse over this link
Mouse over to see the tooltip
</button>
</p>

<p>
<md-radio-group [(ngModel)]="position">
<md-radio-button value="below">Below</md-radio-button>
Expand All @@ -17,4 +19,20 @@ <h1>Tooltip Demo</h1>
<md-radio-button value="after">After</md-radio-button>
</md-radio-group>
</p>

<p>
<strong>Message: </strong>
<md-input type="text" [(ngModel)]="message"></md-input>
</p>

<strong>Mouse over to</strong>
<button md-raised-button color="primary" (mouseenter)="tooltip.show()">
Show tooltip
</button>
<button md-raised-button color="primary" (mouseenter)="tooltip.hide(0)">
Hide tooltip
</button>
<button md-raised-button color="primary" (mouseenter)="tooltip.toggle()">
Toggle tooltip
</button>
</div>
1 change: 1 addition & 0 deletions src/demo-app/tooltip/tooltip-demo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ import {TooltipPosition} from '@angular/material';
})
export class TooltipDemo {
position: TooltipPosition = 'below';
message: string = 'Here is the tooltip';
}
6 changes: 6 additions & 0 deletions src/lib/tooltip/tooltip.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<div class="md-tooltip"
[style.transform-origin]="_transformOrigin"
[@state]="_visibility"
(@state.done)="this._afterVisibilityAnimation($event)">
{{message}}
</div>
92 changes: 79 additions & 13 deletions src/lib/tooltip/tooltip.spec.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
import {
async, ComponentFixture, TestBed, tick, fakeAsync,
flushMicrotasks
} from '@angular/core/testing';
import {Component, DebugElement} from '@angular/core';
import {By} from '@angular/platform-browser';
import {TooltipPosition, MdTooltip} from './tooltip';
import {TooltipPosition, MdTooltip, TOOLTIP_HIDE_DELAY, MdTooltipModule} from './tooltip';
import {OverlayContainer} from '../core';
import {MdTooltipModule} from './tooltip';

const initialTooltipMessage = 'initial tooltip message';

describe('MdTooltip', () => {
let overlayContainerElement: HTMLElement;


beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [MdTooltipModule.forRoot()],
Expand Down Expand Up @@ -38,22 +42,83 @@ describe('MdTooltip', () => {
tooltipDirective = buttonDebugElement.injector.get(MdTooltip);
});

it('should show/hide on mouse enter/leave', () => {
expect(tooltipDirective.visible).toBeFalsy();
it('should show and hide the tooltip', fakeAsync(() => {
expect(tooltipDirective._tooltipInstance).toBeUndefined();

tooltipDirective._handleMouseEnter(null);
expect(tooltipDirective.visible).toBeTruthy();
tooltipDirective.show();
expect(tooltipDirective._isTooltipVisible()).toBe(true);

fixture.detectChanges();
expect(overlayContainerElement.textContent).toBe('some message');
expect(overlayContainerElement.textContent).toContain(initialTooltipMessage);

tooltipDirective._handleMouseLeave(null);
expect(overlayContainerElement.textContent).toBe('');
// After hide called, a timeout delay is created that will to hide the tooltip.
tooltipDirective.hide();
expect(tooltipDirective._isTooltipVisible()).toBe(true);

// After the tooltip delay elapses, expect that the tooltip is not visible.
tick(TOOLTIP_HIDE_DELAY);
fixture.detectChanges();
expect(tooltipDirective._isTooltipVisible()).toBe(false);

// On animation complete, should expect that the tooltip has been detached.
flushMicrotasks();
expect(tooltipDirective._tooltipInstance).toBeNull();
}));

it('should not follow through with hide if show is called after', fakeAsync(() => {
tooltipDirective.show();
expect(tooltipDirective._isTooltipVisible()).toBe(true);

// After hide called, a timeout delay is created that will to hide the tooltip.
tooltipDirective.hide();
expect(tooltipDirective._isTooltipVisible()).toBe(true);

// Before delay time has passed, call show which should cancel intent to hide tooltip.
tooltipDirective.show();
tick(TOOLTIP_HIDE_DELAY);
expect(tooltipDirective._isTooltipVisible()).toBe(true);
}));

it('should remove the tooltip when changing position', () => {
const initialPosition: TooltipPosition = 'below';
const changedPosition: TooltipPosition = 'above';

expect(tooltipDirective._tooltipInstance).toBeUndefined();

tooltipDirective.position = initialPosition;
tooltipDirective.show();
expect(tooltipDirective._tooltipInstance).toBeDefined();

// Same position value should not remove the tooltip
tooltipDirective.position = initialPosition;
expect(tooltipDirective._tooltipInstance).toBeDefined();

// Different position value should destroy the tooltip
tooltipDirective.position = changedPosition;
expect(tooltipDirective._tooltipInstance).toBeNull();
expect(tooltipDirective._overlayRef).toBeNull();
});

it('should be able to modify the tooltip message', () => {
expect(tooltipDirective._tooltipInstance).toBeUndefined();

tooltipDirective.show();
expect(tooltipDirective._tooltipInstance._visibility).toBe('visible');

fixture.detectChanges();
expect(overlayContainerElement.textContent).toContain(initialTooltipMessage);

const newMessage = 'new tooltip message';
tooltipDirective.message = newMessage;

fixture.detectChanges();
expect(overlayContainerElement.textContent).toContain(newMessage);
});

it('should be removed after parent destroyed', () => {
tooltipDirective._handleMouseEnter(null);
expect(tooltipDirective.visible).toBeTruthy();
tooltipDirective.show();
expect(tooltipDirective._isTooltipVisible()).toBe(true);

fixture.destroy();
expect(overlayContainerElement.childNodes.length).toBe(0);
expect(overlayContainerElement.textContent).toBe('');
Expand All @@ -63,8 +128,9 @@ describe('MdTooltip', () => {

@Component({
selector: 'app',
template: `<button md-tooltip="some message" [tooltip-position]="position">Button</button>`
template: `<button [md-tooltip]="message" [tooltip-position]="position">Button</button>`
})
class BasicTooltipDemo {
position: TooltipPosition = 'below';
message: string = initialTooltipMessage;
}
Loading

0 comments on commit 52582f4

Please sign in to comment.