diff --git a/src/lib/components/NoteEditor.svelte b/src/lib/components/NoteEditor.svelte index 1f79ed5..8ec3f67 100644 --- a/src/lib/components/NoteEditor.svelte +++ b/src/lib/components/NoteEditor.svelte @@ -335,11 +335,11 @@ bgStyle = `background-color: ${getNoteColor(color, getIsDarkMode())}`; }); - // Use pointer events to detect backdrop clicks. Unlike mouse events, - // pointer events are never synthetically re-dispatched from touch, so - // the tap that opened the editor on mobile cannot ghost-click the overlay. - // Both pointerdown and pointerup must target the overlay itself to close. + // Close on backdrop tap/click. On close, a transparent shield stays in the DOM + // for 400ms to absorb the browser's delayed synthetic click that would otherwise + // pass through to NoteCards underneath (ghost click). let pointerdownOnOverlay = false; + let closing = $state(false); function handleOverlayPointerdown(e: PointerEvent) { pointerdownOnOverlay = e.target === e.currentTarget; @@ -350,13 +350,18 @@ pointerdownOnOverlay = false; } + function dismissOverlay() { + closing = true; + setTimeout(() => onClose(), 400); + } + async function saveAndClose() { clearTimeout(autoSaveTimer); // Wait for any in-flight auto-save to finish if (savingPromise) await savingPromise; if (!title.trim() && !content.trim()) { - onClose(); + dismissOverlay(); return; } @@ -364,7 +369,7 @@ if (hasUnsavedChanges()) { await performSave(); } - onClose(); + dismissOverlay(); } /** Auto-save a new note without closing, returns the new note ID */ @@ -408,7 +413,7 @@ showOverflowMenu = false; if (noteId) { await archiveNote(noteId); - onClose(); + dismissOverlay(); } } @@ -416,7 +421,7 @@ showOverflowMenu = false; if (noteId) { await trashNote(noteId); - onClose(); + dismissOverlay(); } } @@ -435,12 +440,13 @@
+ {#if !closing}
{/if} + {/if}
{#if showShareDialog && noteId}