Skip to content
This repository has been archived by the owner on Dec 8, 2022. It is now read-only.

Commit

Permalink
Popover hover close fix (#1884)
Browse files Browse the repository at this point in the history
Resolves #1816 - issues with hover state for popover
  • Loading branch information
Blackbaud-TrevorBurch authored Aug 17, 2018
1 parent f8359c6 commit 19559a6
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 25 deletions.
1 change: 1 addition & 0 deletions src/modules/popover/popover.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ export class SkyPopoverComponent implements OnInit, OnDestroy {
}
}

// TODO: This method is no longer used. Remove it when we decide to make breaking changes.
public markForCloseOnMouseLeave() {
this.isMarkedForCloseOnMouseLeave = true;
}
Expand Down
21 changes: 7 additions & 14 deletions src/modules/popover/popover.directive.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,32 +147,25 @@ describe('SkyPopoverDirective', () => {
it('should mark the popover to close on mouseleave', () => {
const caller = directiveElements[2];
const callerInstance = caller.injector.get(SkyPopoverDirective);
const popoverSpy = spyOn(callerInstance.skyPopover, 'markForCloseOnMouseLeave');
const closeSpy = spyOn((callerInstance as any), 'closePopover').and.callThrough();
const markForCloseSpy = spyOn((callerInstance as any).skyPopover, 'markForCloseOnMouseLeave').and.callThrough();

callerInstance.skyPopover.isOpen = true;
callerInstance.skyPopover.isMouseEnter = true;

SkyAppTestUtility.fireDomEvent(caller.nativeElement, 'mouseleave');
expect(popoverSpy).not.toHaveBeenCalled();
expect(closeSpy).toHaveBeenCalled();
expect(markForCloseSpy).not.toHaveBeenCalled();

popoverSpy.calls.reset();
closeSpy.calls.reset();
markForCloseSpy.calls.reset();

// Else path, popover has mouseenter.
callerInstance.skyPopover.isOpen = true;
spyOn(mockWindowService, 'getWindow').and.returnValue({
setTimeout(callback: Function) {
// Simulate the popover triggering mouseenter event:
callerInstance.skyPopover.isMouseEnter = true;
callback();
}
});

callerInstance.skyPopover.isOpen = false;
SkyAppTestUtility.fireDomEvent(caller.nativeElement, 'mouseleave');
expect(popoverSpy).toHaveBeenCalledWith();
callerInstance.skyPopover.isMouseEnter = true;
callerInstance.skyPopover.popoverOpened.emit();
expect(closeSpy).not.toHaveBeenCalled();
expect(markForCloseSpy).toHaveBeenCalled();
});

it('should close the popover when the escape key is pressed', () => {
Expand Down
32 changes: 21 additions & 11 deletions src/modules/popover/popover.directive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,14 @@ export class SkyPopoverDirective implements OnChanges, OnDestroy {
this.skyPopover.close();
}

private closePopoverOrMarkForClose() {
if (this.skyPopover.isMouseEnter) {
this.skyPopover.markForCloseOnMouseLeave();
} else {
this.closePopover();
}
}

private isPopoverOpen(): boolean {
return (this.skyPopover && this.skyPopover.isOpen);
}
Expand Down Expand Up @@ -129,17 +137,19 @@ export class SkyPopoverDirective implements OnChanges, OnDestroy {
if (this.skyPopoverTrigger === 'mouseenter') {
event.preventDefault();

// Give the popover a chance to set its isMouseEnter flag before checking to see
// if it should be closed.
this.windowRef.getWindow().setTimeout(() => {
if (this.isPopoverOpen()) {
if (this.skyPopover.isMouseEnter) {
this.skyPopover.markForCloseOnMouseLeave();
} else {
this.closePopover();
}
}
});
if (this.isPopoverOpen()) {
// Give the popover a chance to set its isMouseEnter flag before checking to see
// if it should be closed.
this.windowRef.getWindow().setTimeout(() => {
this.closePopoverOrMarkForClose();
});
} else {
// If the mouse leaves before the popover is open,
// wait for the transition to complete before closing it.
this.skyPopover.popoverOpened.take(1).subscribe(() => {
this.closePopoverOrMarkForClose();
});
}
}
});
}
Expand Down

0 comments on commit 19559a6

Please sign in to comment.