From 47b34c4829734ca5b6c4f0d52852bc8fbf638ba6 Mon Sep 17 00:00:00 2001 From: Ulas Date: Sat, 4 Apr 2026 14:16:00 +0200 Subject: [PATCH] fix(modal): add fallback timer for mobile close animation On mobile, closeModal() relies on the CSS animationend event to call _doClose(). When the animation does not fire (prefers-reduced-motion, tab switch, browser quirk), the modal stays stuck and the user cannot dismiss it. A 300ms fallback timer now guarantees cleanup runs. Reported in discussion #9 --- CHANGELOG.md | 5 +++++ package.json | 2 +- public/components/modal.js | 3 +++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7117c8b..8383717 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.7.7] - 2026-04-04 + +### Fixed +- Fix modal not closing on mobile when tapping Cancel or Save - add fallback timer for cases where CSS animationend event does not fire (prefers-reduced-motion, tab switch, etc.) + ## [0.7.6] - 2026-04-04 ### Fixed diff --git a/package.json b/package.json index 4cece47..65fb9ad 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "oikos", - "version": "0.7.6", + "version": "0.7.7", "description": "Self-hosted family planner - calendar, tasks, shopping, meal planning, budget and more. Private, open-source, no subscription.", "main": "server/index.js", "type": "module", diff --git a/public/components/modal.js b/public/components/modal.js index 49b5205..5327314 100644 --- a/public/components/modal.js +++ b/public/components/modal.js @@ -264,7 +264,10 @@ export function closeModal() { const isMobile = window.innerWidth < 768; if (isMobile && panel) { panel.classList.add('modal-panel--closing'); + // Fallback-Timer falls animationend nicht feuert (prefers-reduced-motion, Tab-Wechsel etc.) + const fallback = setTimeout(_doClose, 300); panel.addEventListener('animationend', () => { + clearTimeout(fallback); _doClose(); }, { once: true }); return;