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

fix: handle tooltip controller closing state properly #8131

Merged
merged 1 commit into from
Nov 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion packages/tooltip/src/vaadin-tooltip-mixin.js
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,11 @@ class TooltipStateController {
clearTimeout(this.__closeTimeout);
this.__closeTimeout = null;
}

// Remove the tooltip from the closing queue.
if (this.isClosing) {
closing.delete(this.host);
}
}

/** @private */
Expand All @@ -181,7 +186,9 @@ class TooltipStateController {

/** @private */
__scheduleClose() {
if (this._isOpened()) {
// Do not schedule closing if it was already scheduled
// to avoid overriding reference to the close timeout.
if (this._isOpened() && !this.isClosing) {
closing.add(this.host);

this.__closeTimeout = setTimeout(() => {
Expand Down
33 changes: 33 additions & 0 deletions packages/tooltip/test/tooltip-timers.common.js
Original file line number Diff line number Diff line change
Expand Up @@ -705,4 +705,37 @@ describe('timers', () => {
expect(overlays[0].opened).to.be.false;
});
});

describe('state controller', () => {
let tooltip, controller;

beforeEach(async () => {
tooltip = fixtureSync(`
<vaadin-tooltip text="tooltip 1" hover-delay="2" hide-delay="2" manual></vaadin-tooltip>
`);
await nextRender();
controller = tooltip._stateController;
});

it('should not clear opened state on the tooltip when closing scheduled twice', async () => {
controller.open({ hover: true });
await aTimeout(2);
// Emulate closing on two different events e.g. `mouseleave` and `mouseover`
controller.close();
controller.close();
controller.open({ hover: true });
await aTimeout(2);
expect(tooltip.opened).to.be.true;
});

it('should not call close() on the controller when open is called', async () => {
controller.open({ hover: true });
await aTimeout(2);
controller.close();
const spy = sinon.spy(controller, 'close');
controller.open({ hover: true });
await aTimeout(2);
expect(spy).to.not.be.called;
});
});
});