Skip to content

Commit

Permalink
fix: share animationend listener reference in notification (#7342) (C…
Browse files Browse the repository at this point in the history
…P: 24.3) (#7344)

Co-authored-by: Tomi Virkki <tomivirkki@users.noreply.github.com>
  • Loading branch information
vaadin-bot and tomivirkki authored Apr 17, 2024
1 parent cc012a0 commit 7e0ab7f
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 9 deletions.
24 changes: 16 additions & 8 deletions packages/notification/src/vaadin-notification.js
Original file line number Diff line number Diff line change
Expand Up @@ -484,16 +484,22 @@ class Notification extends OverlayClassMixin(ThemePropertyMixin(ElementMixin(Pol
}
}

/** @private */
__cleanUpOpeningClosingState() {
this._card.removeAttribute('opening');
this._card.removeAttribute('closing');
this._card.removeEventListener('animationend', this.__animationEndListener);
}

/** @private */
_animatedAppendNotificationCard() {
if (this._card) {
this.__cleanUpOpeningClosingState();

this._card.setAttribute('opening', '');
this._appendNotificationCard();
const listener = () => {
this._card.removeEventListener('animationend', listener);
this._card.removeAttribute('opening');
};
this._card.addEventListener('animationend', listener);
this.__animationEndListener = () => this.__cleanUpOpeningClosingState();
this._card.addEventListener('animationend', this.__animationEndListener);
this._didAnimateNotificationAppend = true;
} else {
this._didAnimateNotificationAppend = false;
Expand Down Expand Up @@ -538,14 +544,16 @@ class Notification extends OverlayClassMixin(ThemePropertyMixin(ElementMixin(Pol

/** @private */
_animatedRemoveNotificationCard() {
this.__cleanUpOpeningClosingState();

this._card.setAttribute('closing', '');
const name = getComputedStyle(this._card).getPropertyValue('animation-name');
if (name && name !== 'none') {
const listener = () => {
this.__animationEndListener = () => {
this._removeNotificationCard();
this._card.removeEventListener('animationend', listener);
this.__cleanUpOpeningClosingState();
};
this._card.addEventListener('animationend', listener);
this._card.addEventListener('animationend', this.__animationEndListener);
} else {
this._removeNotificationCard();
}
Expand Down
47 changes: 46 additions & 1 deletion packages/notification/test/animation.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,12 @@ describe('animated notifications', () => {
await aTimeout(duration);
});

afterEach(() => {
afterEach(async () => {
notifications.forEach((n) => n.close());
// Wait for the notification container to be removed
while (document.querySelector('body > vaadin-notification-container')) {
await aTimeout(1);
}
});

describe('animation', () => {
Expand Down Expand Up @@ -85,9 +89,50 @@ describe('animated notifications', () => {
});

it('should set `opening` attribute and remove later', async () => {
await oneEvent(notifications[1]._card, 'animationend');
notifications[1].open();
expect(notifications[1]._card.hasAttribute('opening')).to.be.true;
await oneEvent(notifications[1]._card, 'animationend');
expect(notifications[1]._card.hasAttribute('opening')).to.be.false;
});

describe('simultaneous opening and closing', () => {
let notification, card;

beforeEach(() => {
// Use the animated notification for these tests
notification = notifications[1];
notification.duration = -1;
card = notification._card;
// Close the non-animated notification as it's not relevant for these tests
notifications[0].close();
});

it('should remain opened after closing and opening', async () => {
// Simultanously close and open the animated notification
notification.close();
notification.open();
await oneEvent(card, 'animationend');

expect(notification.opened).to.be.true;
expect(card.hasAttribute('closing')).to.be.false;
expect(card.hasAttribute('opening')).to.be.false;
expect(container.parentNode).to.equal(document.body);
expect(container.contains(card)).to.be.true;
});

it('should remain closed after opening and closing', async () => {
// Simultanously open and close the animated notification
notification.close();
notification.open();
notification.close();
await oneEvent(card, 'animationend');

expect(notification.opened).to.be.false;
expect(card.hasAttribute('closing')).to.be.false;
expect(card.hasAttribute('opening')).to.be.false;
expect(container.parentNode).to.not.equal(document.body);
});
});
});
});

0 comments on commit 7e0ab7f

Please sign in to comment.