From 56b1b8d3e4f78b56c4e5cc8e3d0079c0dc2d4fdc Mon Sep 17 00:00:00 2001 From: thePR0M3TH3AN <53631862+PR0M3TH3AN@users.noreply.github.com> Date: Sun, 19 Oct 2025 18:59:34 -0400 Subject: [PATCH] Fix zap toggle behavior in video modal --- js/ui/components/VideoModal.js | 53 ++++++++++++++++++++---- tests/video-modal-accessibility.test.mjs | 33 ++++++++++++++- 2 files changed, 78 insertions(+), 8 deletions(-) diff --git a/js/ui/components/VideoModal.js b/js/ui/components/VideoModal.js index 938ed1eb..9ee79189 100644 --- a/js/ui/components/VideoModal.js +++ b/js/ui/components/VideoModal.js @@ -436,10 +436,7 @@ export class VideoModal { return; } - const popoverIsOpen = - typeof this.modalZapPopover?.isOpen === "function" - ? this.modalZapPopover.isOpen() - : this.modalZapDialogOpen === true; + const popoverIsOpen = this.isZapDialogOpen(); if (this.modalZapOpenPromise) { this.modalZapPendingToggle = "close"; @@ -601,6 +598,9 @@ export class VideoModal { this.modalZapDialog.hidden = false; this.modalZapDialog.setAttribute("aria-hidden", "false"); this.modalZapDialogOpen = true; + if (this.modalZapBtn) { + this.modalZapBtn.setAttribute("aria-expanded", "true"); + } this.focusZapAmount(); } return result; @@ -620,6 +620,9 @@ export class VideoModal { this.modalZapDialog.setAttribute("aria-hidden", "true"); this.modalZapDialog.hidden = true; this.modalZapDialogOpen = false; + if (this.modalZapBtn) { + this.modalZapBtn.setAttribute("aria-expanded", "false"); + } if (!silent) { this.dispatch("zap:close", { video: this.activeVideo }); } @@ -1133,7 +1136,25 @@ export class VideoModal { if (restoreFocus !== undefined) { options.restoreFocus = restoreFocus; } - this.modalZapPopover.close(options); + const closeResult = this.modalZapPopover.close(options); + + if ( + closeResult !== true && + this.modalZapDialog && + this.modalZapDialogOpen + ) { + this.modalZapDialog.dataset.state = "closed"; + this.modalZapDialog.setAttribute("aria-hidden", "true"); + this.modalZapDialog.hidden = true; + this.modalZapDialogOpen = false; + if (this.modalZapBtn) { + this.modalZapBtn.setAttribute("aria-expanded", "false"); + } + if (!silent) { + this.dispatch("zap:close", { video: this.activeVideo }); + } + } + return; } @@ -1155,9 +1176,27 @@ export class VideoModal { } isZapDialogOpen() { - if (typeof this.modalZapPopover?.isOpen === "function") { - return this.modalZapPopover.isOpen(); + const popoverIsOpen = + typeof this.modalZapPopover?.isOpen === "function" + ? this.modalZapPopover.isOpen() + : null; + + if (popoverIsOpen === true) { + return true; } + + if (popoverIsOpen === false && this.modalZapDialogOpen) { + return true; + } + + if (this.modalZapDialog?.dataset?.state === "open") { + return true; + } + + if (this.modalZapDialog && this.modalZapDialog.hidden === false) { + return true; + } + return !!this.modalZapDialogOpen; } diff --git a/tests/video-modal-accessibility.test.mjs b/tests/video-modal-accessibility.test.mjs index 81893fe8..c54d2324 100644 --- a/tests/video-modal-accessibility.test.mjs +++ b/tests/video-modal-accessibility.test.mjs @@ -39,6 +39,19 @@ async function setupModal({ lazyLoad = false } = {}) { applyDesignSystemAttributes(document); + if (!window.ResizeObserver) { + class ResizeObserverStub { + constructor(callback) { + this.callback = callback; + } + observe() {} + unobserve() {} + disconnect() {} + } + window.ResizeObserver = ResizeObserverStub; + globalThis.ResizeObserver = ResizeObserverStub; + } + let restoreFetch = null; if (lazyLoad) { const originalFetch = globalThis.fetch; @@ -730,7 +743,25 @@ for (const _ of [0]) { assert.equal(zapDialog.dataset.state, "open"); assert.equal(zapDialog.getAttribute("aria-hidden"), "false"); assert.equal(zapButton.getAttribute("aria-expanded"), "true"); - assert.strictEqual(document.activeElement, amountInput); + + zapButton.dispatchEvent( + new window.MouseEvent("click", { bubbles: true, cancelable: true }) + ); + + assert.equal(zapDialog.hidden, true); + assert.equal(zapDialog.dataset.state, "closed"); + assert.equal(zapDialog.getAttribute("aria-hidden"), "true"); + assert.equal(zapButton.getAttribute("aria-expanded"), "false"); + + zapButton.dispatchEvent( + new window.MouseEvent("click", { bubbles: true, cancelable: true }) + ); + await Promise.resolve(); + + assert.equal(zapDialog.hidden, false); + assert.equal(zapDialog.dataset.state, "open"); + assert.equal(zapDialog.getAttribute("aria-hidden"), "false"); + assert.equal(zapButton.getAttribute("aria-expanded"), "true"); const closeButton = document.getElementById("modalZapCloseBtn"); assert.ok(closeButton, "zap close button should exist");