diff --git a/packages/stacks-svelte/src/components/Modal/Modal.svelte b/packages/stacks-svelte/src/components/Modal/Modal.svelte index 8c2c3994b4..29ed49d040 100644 --- a/packages/stacks-svelte/src/components/Modal/Modal.svelte +++ b/packages/stacks-svelte/src/components/Modal/Modal.svelte @@ -86,8 +86,10 @@ } }; - const keyPress = (e: KeyboardEvent) => { - if (e.key === "Escape") { + const keyPress = (event: KeyboardEvent) => { + if (event.key === "Escape" && visible) { + event.stopImmediatePropagation(); + close(); } }; diff --git a/packages/stacks-svelte/src/components/Modal/Modal.test.ts b/packages/stacks-svelte/src/components/Modal/Modal.test.ts index 7ce7ba32c4..e7f001cb7f 100644 --- a/packages/stacks-svelte/src/components/Modal/Modal.test.ts +++ b/packages/stacks-svelte/src/components/Modal/Modal.test.ts @@ -146,6 +146,36 @@ describe("Modal", () => { expectModalVisible(false); }); + it("should stop esc press propagation when closing a visible modal", async () => { + const laterWindowListener = sinon.spy(); + render(Modal, { id: "test-modal", visible: true }); + window.addEventListener("keydown", laterWindowListener); + + try { + await userEvent.keyboard("{Escape}"); + + expectModalVisible(false); + expect(laterWindowListener).not.to.have.been.called; + } finally { + window.removeEventListener("keydown", laterWindowListener); + } + }); + + it("should not stop esc press propagation when modal is not visible", async () => { + const laterWindowListener = sinon.spy(); + render(Modal, { id: "test-modal", visible: false }); + window.addEventListener("keydown", laterWindowListener); + + try { + await userEvent.keyboard("{Escape}"); + + expectModalVisible(false); + expect(laterWindowListener).to.have.been.calledOnce; + } finally { + window.removeEventListener("keydown", laterWindowListener); + } + }); + it("should emit close event on close when modal is visible", async () => { const onClose = sinon.spy(); render(Modal, {