From fa9a8296d2757d8b58d6bb79d2d308d096507b49 Mon Sep 17 00:00:00 2001 From: Jose Carcamo <138070439+josercarcamo@users.noreply.github.com> Date: Wed, 5 Jun 2024 16:18:26 -0700 Subject: [PATCH] fix(alert): pause auto-close alert when link focused (#9503) **Related Issue:** #5960 ## Summary Paused auto close when the focus is in the link or close buton or when the mouse is hovered over the alert dialog. --- .../src/components/alert/alert.e2e.ts | 14 ++++++ .../src/components/alert/alert.scss | 7 ++- .../src/components/alert/alert.tsx | 43 +++++++++++++++++-- .../src/components/alert/resources.ts | 1 + 4 files changed, 61 insertions(+), 4 deletions(-) diff --git a/packages/calcite-components/src/components/alert/alert.e2e.ts b/packages/calcite-components/src/components/alert/alert.e2e.ts index 63e35eabe69..daa5bc120e1 100644 --- a/packages/calcite-components/src/components/alert/alert.e2e.ts +++ b/packages/calcite-components/src/components/alert/alert.e2e.ts @@ -457,6 +457,20 @@ describe("calcite-alert", () => { await page.waitForTimeout(DURATIONS.medium + animationDurationInMs); await page.waitForSelector("#alert", { visible: false }); }); + + it("pauses on focus and resumes on blur", async () => { + await button.click(); + expect(await alert.isVisible()).toBe(true); + expect(await alert.getProperty("autoCloseDuration")).toEqual("medium"); + expect(playState).toEqual("running"); + buttonClose = await page.find(`#alert >>> .${CSS.close}`); + buttonClose.focus(); + await page.waitForTimeout(DURATIONS.medium); + expect(await alert.isVisible()).toBe(true); + await button.focus(); + await page.waitForTimeout(DURATIONS.medium + animationDurationInMs); + await page.waitForSelector("#alert", { visible: false }); + }); }); describe("translation support", () => { diff --git a/packages/calcite-components/src/components/alert/alert.scss b/packages/calcite-components/src/components/alert/alert.scss index 68c259951b4..17587b14794 100644 --- a/packages/calcite-components/src/components/alert/alert.scss +++ b/packages/calcite-components/src/components/alert/alert.scss @@ -293,11 +293,16 @@ $alertDurations: :host([auto-close-duration="#{$name}"]) .dismiss-progress:after { animation: dismissProgress $duration ease-out; } - :host(:hover[auto-close-duration="#{$name}"]) .dismiss-progress:after { + :host(:hover[auto-close-duration="#{$name}"]) .dismiss-progress:after, + :host(:focus[auto-close-duration="#{$name}"]) .dismiss-progress:after { animation-play-state: paused; } } +.container.focused .dismiss-progress:after { + animation-play-state: paused; +} + @keyframes dismissProgress { 0% { @apply w-0 opacity-75; diff --git a/packages/calcite-components/src/components/alert/alert.tsx b/packages/calcite-components/src/components/alert/alert.tsx index 0e4b2be7365..366fd9b6a81 100644 --- a/packages/calcite-components/src/components/alert/alert.tsx +++ b/packages/calcite-components/src/components/alert/alert.tsx @@ -200,6 +200,7 @@ export class Alert implements OpenCloseComponent, LoadableComponent, T9nComponen }), ); window.clearTimeout(this.autoCloseTimeoutId); + this.autoCloseTimeoutId = null; window.clearTimeout(this.queueTimeout); disconnectLocalized(this); disconnectMessages(this); @@ -226,13 +227,18 @@ export class Alert implements OpenCloseComponent, LoadableComponent, T9nComponen [CSS.containerQueued]: queued, [`${CSS.container}--${placement}`]: true, [CSS.containerSlottedInShell]: this.slottedInShell, + [CSS.focused]: this.keyBoardFocus, }} onPointerEnter={this.autoClose && this.autoCloseTimeoutId ? this.handleMouseOver : null} - onPointerLeave={this.autoClose && this.autoCloseTimeoutId ? this.handleMouseLeave : null} + onPointerLeave={this.autoClose ? this.handleMouseLeave : null} ref={this.setTransitionEl} > {effectiveIcon && this.renderIcon(effectiveIcon)} -
+
@@ -246,6 +252,18 @@ export class Alert implements OpenCloseComponent, LoadableComponent, T9nComponen ); } + private handleKeyBoardFocus = (): void => { + this.keyBoardFocus = true; + this.handleFocus(); + }; + + private handleKeyBoardBlur = (): void => { + this.keyBoardFocus = false; + if (!this.mouseFocus) { + this.handleBlur(); + } + }; + private renderCloseButton(): VNode { return (