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): add tooltip animations #1644

Merged
merged 12 commits into from
Nov 1, 2016
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';

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How can you globally configure TOOLTIP_HIDE_DELAY?

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