Skip to content

Commit

Permalink
feat(tooltip): add a configurable tooltip delay (#891)
Browse files Browse the repository at this point in the history
Closes #790
  • Loading branch information
mbaumims authored and mattlewis92 committed Feb 20, 2019
1 parent 3552d0c commit 07aec13
Show file tree
Hide file tree
Showing 8 changed files with 95 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import {
import { DOCUMENT } from '@angular/common';
import { PlacementArray, positionElements } from 'positioning';
import { CalendarEvent } from 'calendar-utils';
import { Observable, of, Subject, timer } from 'rxjs';
import { takeUntil } from 'rxjs/operators';

@Component({
selector: 'mwl-calendar-tooltip-window',
Expand Down Expand Up @@ -67,8 +69,11 @@ export class CalendarTooltipDirective implements OnDestroy {

@Input('tooltipAppendToBody') appendToBody: boolean; // tslint:disable-line no-input-rename

@Input('tooltipDelay') delay: number | null = null; // tslint:disable-line no-input-rename

private tooltipFactory: ComponentFactory<CalendarTooltipWindowComponent>;
private tooltipRef: ComponentRef<CalendarTooltipWindowComponent>;
private cancelTooltipDelay$ = new Subject();

constructor(
private elementRef: ElementRef,
Expand All @@ -89,7 +94,11 @@ export class CalendarTooltipDirective implements OnDestroy {

@HostListener('mouseenter')
onMouseOver(): void {
this.show();
const delay$: Observable<any> =
this.delay === null ? of('now') : timer(this.delay);
delay$.pipe(takeUntil(this.cancelTooltipDelay$)).subscribe(() => {
this.show();
});
}

@HostListener('mouseleave')
Expand Down Expand Up @@ -124,6 +133,7 @@ export class CalendarTooltipDirective implements OnDestroy {
);
this.tooltipRef = null;
}
this.cancelTooltipDelay$.next();
}

private positionTooltip(previousPosition?: string): void {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { PlacementArray } from 'positioning';
let-eventClicked="eventClicked"
let-tooltipTemplate="tooltipTemplate"
let-tooltipAppendToBody="tooltipAppendToBody"
let-tooltipDelay="tooltipDelay"
>
<div
class="cal-event"
Expand All @@ -30,6 +31,7 @@ import { PlacementArray } from 'positioning';
[tooltipEvent]="dayEvent.event"
[tooltipTemplate]="tooltipTemplate"
[tooltipAppendToBody]="tooltipAppendToBody"
[tooltipDelay]="tooltipDelay"
(mwlClick)="eventClicked.emit()"
>
<mwl-calendar-event-actions
Expand All @@ -53,7 +55,8 @@ import { PlacementArray } from 'positioning';
tooltipPlacement: tooltipPlacement,
eventClicked: eventClicked,
tooltipTemplate: tooltipTemplate,
tooltipAppendToBody: tooltipAppendToBody
tooltipAppendToBody: tooltipAppendToBody,
tooltipDelay: tooltipDelay
}"
>
</ng-template>
Expand All @@ -74,5 +77,7 @@ export class CalendarDayViewEventComponent {

@Input() tooltipTemplate: TemplateRef<any>;

@Input() tooltipDelay: number | null;

@Output() eventClicked: EventEmitter<any> = new EventEmitter();
}
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ export interface DayViewEventResize {
[tooltipPlacement]="tooltipPlacement"
[tooltipTemplate]="tooltipTemplate"
[tooltipAppendToBody]="tooltipAppendToBody"
[tooltipDelay]="tooltipDelay"
[customTemplate]="eventTemplate"
[eventTitleTemplate]="eventTitleTemplate"
[eventActionsTemplate]="eventActionsTemplate"
Expand Down Expand Up @@ -166,6 +167,7 @@ export interface DayViewEventResize {
[tooltipPlacement]="tooltipPlacement"
[tooltipTemplate]="tooltipTemplate"
[tooltipAppendToBody]="tooltipAppendToBody"
[tooltipDelay]="tooltipDelay"
[customTemplate]="eventTemplate"
[eventTitleTemplate]="eventTitleTemplate"
[eventActionsTemplate]="eventActionsTemplate"
Expand Down Expand Up @@ -283,6 +285,12 @@ export class CalendarDayViewComponent implements OnChanges, OnInit, OnDestroy {
*/
@Input() tooltipAppendToBody: boolean = true;

/**
* The delay in milliseconds before the tooltip should be displayed. If not provided the tooltip
* will be displayed immediately.
*/
@Input() tooltipDelay: number | null = null;

/**
* A custom template to use to replace the hour segment
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { PlacementArray } from 'positioning';
let-eventClicked="eventClicked"
let-tooltipTemplate="tooltipTemplate"
let-tooltipAppendToBody="tooltipAppendToBody"
let-tooltipDelay="tooltipDelay"
>
<div class="cal-cell-top">
<span class="cal-day-badge" *ngIf="day.badgeTotal > 0">{{
Expand All @@ -47,6 +48,7 @@ import { PlacementArray } from 'positioning';
[tooltipEvent]="event"
[tooltipTemplate]="tooltipTemplate"
[tooltipAppendToBody]="tooltipAppendToBody"
[tooltipDelay]="tooltipDelay"
mwlDraggable
[class.cal-draggable]="event.draggable"
dragActiveClass="cal-drag-active"
Expand All @@ -67,7 +69,8 @@ import { PlacementArray } from 'positioning';
unhighlightDay: unhighlightDay,
eventClicked: eventClicked,
tooltipTemplate: tooltipTemplate,
tooltipAppendToBody: tooltipAppendToBody
tooltipAppendToBody: tooltipAppendToBody,
tooltipDelay: tooltipDelay
}"
>
</ng-template>
Expand Down Expand Up @@ -101,6 +104,8 @@ export class CalendarMonthCellComponent {

@Input() tooltipTemplate: TemplateRef<any>;

@Input() tooltipDelay: number | null;

@Output() highlightDay: EventEmitter<any> = new EventEmitter();

@Output() unhighlightDay: EventEmitter<any> = new EventEmitter();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ export interface CalendarMonthViewEventTimesChangedEvent<
[tooltipPlacement]="tooltipPlacement"
[tooltipAppendToBody]="tooltipAppendToBody"
[tooltipTemplate]="tooltipTemplate"
[tooltipDelay]="tooltipDelay"
[customTemplate]="cellTemplate"
(mwlClick)="dayClicked.emit({ day: day })"
(highlightDay)="toggleDayHighlight($event.event, true)"
Expand Down Expand Up @@ -172,6 +173,12 @@ export class CalendarMonthViewComponent
*/
@Input() tooltipAppendToBody: boolean = true;

/**
* The delay in milliseconds before the tooltip should be displayed. If not provided the tooltip
* will be displayed immediately.
*/
@Input() tooltipDelay: number | null = null;

/**
* The start number of the week
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { PlacementArray } from 'positioning';
let-tooltipTemplate="tooltipTemplate"
let-tooltipAppendToBody="tooltipAppendToBody"
let-tooltipDisabled="tooltipDisabled"
let-tooltipDelay="tooltipDelay"
>
<div
class="cal-event"
Expand All @@ -34,6 +35,7 @@ import { PlacementArray } from 'positioning';
[tooltipEvent]="weekEvent.event"
[tooltipTemplate]="tooltipTemplate"
[tooltipAppendToBody]="tooltipAppendToBody"
[tooltipDelay]="tooltipDelay"
(mwlClick)="eventClicked.emit()"
>
<mwl-calendar-event-actions
Expand All @@ -58,7 +60,8 @@ import { PlacementArray } from 'positioning';
eventClicked: eventClicked,
tooltipTemplate: tooltipTemplate,
tooltipAppendToBody: tooltipAppendToBody,
tooltipDisabled: tooltipDisabled
tooltipDisabled: tooltipDisabled,
tooltipDelay: tooltipDelay
}"
>
</ng-template>
Expand All @@ -73,6 +76,8 @@ export class CalendarWeekViewEventComponent {

@Input() tooltipDisabled: boolean;

@Input() tooltipDelay: number | null;

@Input() customTemplate: TemplateRef<any>;

@Input() eventTitleTemplate: TemplateRef<any>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ export interface CalendarWeekViewBeforeRenderEvent extends WeekView {
[tooltipPlacement]="tooltipPlacement"
[tooltipTemplate]="tooltipTemplate"
[tooltipAppendToBody]="tooltipAppendToBody"
[tooltipDelay]="tooltipDelay"
[customTemplate]="eventTemplate"
[eventTitleTemplate]="eventTitleTemplate"
[eventActionsTemplate]="eventActionsTemplate"
Expand Down Expand Up @@ -293,6 +294,7 @@ export interface CalendarWeekViewBeforeRenderEvent extends WeekView {
[tooltipTemplate]="tooltipTemplate"
[tooltipAppendToBody]="tooltipAppendToBody"
[tooltipDisabled]="dragActive || timeEventResizes.size > 0"
[tooltipDelay]="tooltipDelay"
[customTemplate]="eventTemplate"
[eventTitleTemplate]="eventTitleTemplate"
[eventActionsTemplate]="eventActionsTemplate"
Expand Down Expand Up @@ -390,6 +392,12 @@ export class CalendarWeekViewComponent implements OnChanges, OnInit, OnDestroy {
*/
@Input() tooltipAppendToBody: boolean = true;

/**
* The delay in milliseconds before the tooltip should be displayed. If not provided the tooltip
* will be displayed immediately.
*/
@Input() tooltipDelay: number | null = null;

/**
* The start number of the week
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import {
ComponentFixture,
TestBed,
fakeAsync,
flush
flush,
tick
} from '@angular/core/testing';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import moment from 'moment';
Expand Down Expand Up @@ -541,6 +542,47 @@ describe('calendarMonthView component', () => {
expect(!!document.body.querySelector('.cal-tooltip')).to.equal(false);
}));

it('should show a tooltip on mouseover of the event after a delay', fakeAsync(() => {
const fixture: ComponentFixture<
CalendarMonthViewComponent
> = TestBed.createComponent(CalendarMonthViewComponent);
eventTitle.monthTooltip = (e: CalendarEvent) => {
return `title: ${e.title}`;
};
fixture.componentInstance.viewDate = new Date('2016-06-27');
fixture.componentInstance.events = [
{
start: new Date('2016-05-30'),
end: new Date('2016-06-02'),
title: 'foo <b>bar</b>'
}
];
fixture.componentInstance.tooltipDelay = 2000;
fixture.componentInstance.ngOnChanges({ viewDate: {}, events: {} });
fixture.detectChanges();
const event: HTMLElement = fixture.nativeElement.querySelector(
'.cal-days .cal-cell-row .cal-cell:nth-child(4) .cal-events .cal-event'
);
triggerDomEvent('mouseenter', event);
fixture.detectChanges();
tick(fixture.componentInstance.tooltipDelay - 1);
expect(!!document.body.querySelector('.cal-tooltip')).to.equal(false);
tick(1);
expect(!!document.body.querySelector('.cal-tooltip')).to.equal(true);
const tooltip: HTMLElement = document.body.querySelector(
'.cal-tooltip'
) as HTMLElement;
expect(tooltip.querySelector('.cal-tooltip-inner').innerHTML).to.equal(
'title: foo <b>bar</b>'
);
expect(tooltip.classList.contains('cal-tooltip-top')).to.equal(true);
expect(!!tooltip.style.top).to.equal(true);
expect(!!tooltip.style.left).to.equal(true);
triggerDomEvent('mouseleave', event);
fixture.detectChanges();
expect(!!document.body.querySelector('.cal-tooltip')).to.equal(false);
}));

it('should disable the tooltip', fakeAsync(() => {
const fixture: ComponentFixture<
CalendarMonthViewComponent
Expand Down

0 comments on commit 07aec13

Please sign in to comment.