dialogs.svelte Svelte Themes

Dialogs.svelte

A Svelte component for custom, promise-based alert, confirm, and prompt dialogs.

dialogs.svelte

Promise-based alert, confirm, and prompt dialogs for Svelte 5 – with a drop‑in provider component that lets you fully customize their UI using Svelte Snippets while keeping a simple imperative API.

Features

  • Drop‑in replacement for native alert/confirm/prompt returning promises.
  • Customizable content via Svelte 5 Snippets ({#snippet ...}) per dialog type or per individual call.
  • Queueing: multiple calls are serialized; only one dialog is visible at a time.
  • Keyboard: Escape resolves (alert: void, confirm: false, prompt: null).
  • Automatic focus handling (first button or input field).
  • Fallback to native dialogs when no provider is present – works even outside layout.

Installation

pnpm add dialogs.svelte
# or
npm install dialogs.svelte

or, You can copy the component directly into your project:

Open src/lib/dialogs.svelte
(Copying the component makes it easier to customize styles and other aspects.)

Quick Start

Wrap a layout (or page) with the Dialogs component and provide snippets for any dialogs you want to customize. Omit a snippet to use a default minimal version.

<!-- +layout.svelte -->
<script lang="ts">
    import Dialogs from 'dialogs.svelte';
    let nameInput = $state('');
</script>

<Dialogs>
    <!-- Your app -->
    <slot />

    {#snippet alert(message, ok)}
        <div class="alert">
            <p>{message}</p>
            <button onclick={ok}>OK</button>
        </div>
    {/snippet}

    {#snippet confirm(message, ok, cancel)}
        <div class="confirm">
            <p>{message}</p>
            <button onclick={ok}>OK</button>
            <button onclick={cancel}>Cancel</button>
        </div>
    {/snippet}

    {#snippet prompt(message, defaultValue, ok, cancel)}
        <div class="prompt">
            <p>{message}</p>
            <input
                bind:value={nameInput}
                {@attach defaultValue
                    ? (el) => {
                            if (defaultValue) {
                                nameInput = defaultValue;
                                el.value = defaultValue;
                                el.setSelectionRange(0, defaultValue.length);
                            }
                        }
                    : undefined}
            />
            <button
                onclick={() => {
                    ok(nameInput);
                    nameInput = '';
                }}>OK</button
            >
            <button onclick={cancel}>Cancel</button>
        </div>
    {/snippet}
</Dialogs>

<style>
    .alert,
    .confirm,
    .prompt {
        background: #fff;
        padding: 1rem 2rem 2rem;
        border-radius: 1rem;
    }
</style>

Use the dialogs from any descendant component:

<script lang="ts">
    import { useDialogs } from 'dialogs.svelte';
    const { alert, confirm, prompt } = useDialogs();

    async function run() {
        await alert('Hello');
        const ok = await confirm('Are you sure?');
        if (!ok) return;
        const name = await prompt('Your name?', 'Alice');
        console.log({ name });
    }
</script>

<button onclick={run}>Do stuff</button>

If you call useDialogs() outside of a provider, it falls back to the native blocking dialogs automatically.

Contributing

  1. Clone & install: pnpm install
  2. Dev server: pnpm dev
  3. Run checks: pnpm check / pnpm test
  4. Open a PR with a concise description + before/after behavior.

License

MIT

Top categories

Loading Svelte Themes