From 244c9fd986dc443b9c5c31ce798a63860f6877e4 Mon Sep 17 00:00:00 2001 From: Samsonov Ivan Date: Tue, 21 Oct 2025 18:05:53 +0500 Subject: [PATCH] fix: modal closing with a custom animation now always works, even if there are animated elements inside the modal --- .changeset/itchy-bobcats-nail.md | 5 ++ .../src/components/modal/use-modal.tsx | 46 +++++++++---------- 2 files changed, 27 insertions(+), 24 deletions(-) create mode 100644 .changeset/itchy-bobcats-nail.md diff --git a/.changeset/itchy-bobcats-nail.md b/.changeset/itchy-bobcats-nail.md new file mode 100644 index 000000000..1d9f2d50a --- /dev/null +++ b/.changeset/itchy-bobcats-nail.md @@ -0,0 +1,5 @@ +--- +'@qwik-ui/headless': patch +--- + +fix: modal closing with a custom animation now always works, even if there are animated elements inside the modal diff --git a/packages/kit-headless/src/components/modal/use-modal.tsx b/packages/kit-headless/src/components/modal/use-modal.tsx index 9e0e49038..a4694a562 100644 --- a/packages/kit-headless/src/components/modal/use-modal.tsx +++ b/packages/kit-headless/src/components/modal/use-modal.tsx @@ -19,31 +19,29 @@ export function useModal() { const { animationDuration, transitionDuration } = getComputedStyle(modal); if (animationDuration !== '0s') { - modal.addEventListener( - 'animationend', - (e) => { - if (e.target === modal) { - delete modal.dataset.closing; - modal.classList.remove('modal-closing'); - enableBodyScroll(modal); - modal.close(); - } - }, - { once: true }, - ); + const handler = (e: AnimationEvent) => { + if (e.target === modal) { + delete modal.dataset.closing; + modal.classList.remove('modal-closing'); + enableBodyScroll(modal); + modal.close(); + modal.removeEventListener('animationend', handler); + } + }; + + modal.addEventListener('animationend', handler); } else if (transitionDuration !== '0s') { - modal.addEventListener( - 'transitionend', - (e) => { - if (e.target === modal) { - delete modal.dataset.closing; - modal.classList.remove('modal-closing'); - enableBodyScroll(modal); - modal.close(); - } - }, - { once: true }, - ); + const handler = (e: TransitionEvent) => { + if (e.target === modal) { + delete modal.dataset.closing; + modal.classList.remove('modal-closing'); + enableBodyScroll(modal); + modal.close(); + modal.removeEventListener('transitionend', handler); + } + }; + + modal.addEventListener('transitionend', handler); } else if (animationDuration === '0s' && transitionDuration === '0s') { delete modal.dataset.closing; modal.classList.remove('modal-closing');