Putting Svelte stores inside context for fun and profit
In Critical Notes I use modals with forms inside of them. The basic (simplified) layout is like this, inside a detail page:
{#if editModalOpen}
<Modal title="Edit Character" close={() => editModalOpen = false}>
<CharacterForm {character} />
</Modal>
{/if}
A modal looks like this:

Modals can be nested infinitely. Inside of this character form are multiple buttons that will open another modal with another form, for example to create a new lore item:

Every modal has code that detects when the escape key is pressed, and then it will close the top-most modal. The core of the code looks like this:
Modal.svelte<script lang="ts">
export let title: string;
export let close = () => {};
let modal: HTMLElement;
function isTopModal() {
const nodes = modal.querySelectorAll(".modal");
return nodes.length === 0;
}
function handleKeydown(e: KeyboardEvent) {
if (e.key === "Escape" && isTopModal()) {
e.preventDefault();
close();
}
}
</script>
<svelte:window on:keydown={handleKeydown} />
<div role="dialog" aria-modal="true" bind:this={modal}>
<h1>{title}</h1>
<slot />
</div>
Every modal listens for key presses, and if the escape key is pressed and the modal has no child modals, then the modal closes itself. When multiple modals are opened, you can press the escape key multiple times to close them all. This works perfectly fine, but there is one problem: it’s way too easy to accidentally close a modal with a bunch of unsaved changes, just by pressing the wrong key. I wanted to make it impossible to close the modal with the escape key when there are unsaved changed in the form.
At its core, the Modal component needs to know if its form has changes, and then just ignore the escape key:
let hasChanges = false;
function handleKeydown(e: KeyboardEvent) {
if (e.key === "Escape" && isTopModal() MARKUP0