fix(launcher): replace Flowbite Modal with custom overlay for cfg panel

Two problems with the Flowbite <Modal> approach:
1. Built-in dismissable CloseButton rendered with no functional dismiss path
   (no title/form), appearing centered in the panel.
2. size="xl" (max-w-7xl) left no backdrop area on typical laptop screens,
   making outsideclose impossible to trigger.

Replace with a simple custom overlay: full-screen backdrop div that closes
on click, inner panel with stopPropagation. Matches the original Drawer
pattern. close_cfg() writes to store immediately on backdrop click for
reliable persistence independent of effect timing.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Scott Idem
2026-05-26 22:04:34 -04:00
parent 25d17841e4
commit 872291b0a0

View File

@@ -17,6 +17,7 @@ import { sineIn } from 'svelte/easing';
// *** Import other supporting libraries
import { liveQuery } from 'dexie';
import { Drawer, Modal } from 'flowbite-svelte';
import { fade } from 'svelte/transition';
import { listen, idle, onIdle, restartCountdown } from 'svelte-idle';
import {
@@ -122,6 +123,15 @@ $effect(() => {
});
});
// Called by backdrop click. Writes to store immediately (don't rely on effect timing).
function close_cfg() {
modal_cfg_open = false;
events_loc.update((loc) => {
if (loc.launcher) loc.launcher.hide_drawer__cfg = true;
return loc;
});
}
// Generate a stable per-device client ID on first load and persist it.
// events_loc is backed by svelte-persisted-store (localStorage) so this
// survives page reloads. Without this, client_id falls back to Date.now()
@@ -928,17 +938,27 @@ $effect(() => {
</button>
</div>
<Modal
bind:open={modal_cfg_open}
autoclose={false}
outsideclose
size="xl"
class="relative flex flex-col items-center justify-center p-0 overflow-hidden"
id="modal_cfg">
{#if modal_cfg_open}
<!-- Backdrop: full-screen overlay. Clicking anywhere on it closes the cfg panel. -->
<!-- svelte-ignore a11y_click_events_have_key_events a11y_no_static_element_interactions -->
<div
role="presentation"
class="fixed inset-0 z-50 flex items-center justify-center bg-gray-900/60 p-4"
onclick={close_cfg}
transition:fade={{ duration: 200 }}>
<!-- Panel: stop-propagation so clicks inside don't reach the backdrop handler. -->
<!-- svelte-ignore a11y_click_events_have_key_events a11y_no_static_element_interactions -->
<div
role="dialog"
aria-modal="true"
aria-label="Launcher Settings"
tabindex="-1"
class="flex max-h-[90vh] w-full max-w-5xl flex-col overflow-hidden rounded-lg shadow-2xl"
onclick={(e) => e.stopPropagation()}>
<Launcher_cfg></Launcher_cfg>
<div
class="bg-surface-100-900 flex max-w-full flex-row flex-wrap items-center justify-center gap-2 border-t border-surface-500/10 p-4">
class="bg-surface-100-900 flex flex-row flex-wrap items-center justify-center gap-2 border-t border-surface-500/10 p-4">
<a
href="/events/{$events_slct.event_id}"
class="btn btn-sm preset-tonal-primary hover:preset-filled-primary-500">
@@ -962,7 +982,9 @@ $effect(() => {
</a>
{/if}
</div>
</Modal>
</div>
</div>
{/if}
<Drawer
activateClickOutside={false}