Components

DhModal

Native <dialog> with sizes, slots (header / body / footer), and a confirmation pattern. Browser handles focus trap + aria-modal + ESC.

Sizes

<DhModal open={isOpen} title="Small modal" size="sm" onclose={() => (isOpen = false)}>
  <p>Small modals work for quick confirmations.</p>
  {#snippet footer()}
    <DhButton variant="ghost" text="Close" onclick={() => (isOpen = false)} />
  {/snippet}
</DhModal>

Small modal

Small modals work well for quick confirmations and inline actions.

Large modal

Large modals give room for longer forms or preview content.

Fullscreen modal

Fullscreen covers the viewport — useful for mobile or immersive flows.

Confirmation pattern

Compose DhModal with DhButton. Supports a 'don't ask again' checkbox and a loading state that blocks dismissal while in flight.

<DhModal
  open={confirmOpen}
  title="Delete this item?"
  dismissOnBackground={!busy}
  closeOnEsc={!busy}
  onclose={() => !busy && (confirmOpen = false)}
>
  <p>This cannot be undone.</p>
  <label>
    <input type="checkbox" bind:checked={dontAskAgain} disabled={busy} />
    Don't ask again
  </label>
  {#snippet footer()}
    <DhButton variant="ghost" text="Cancel" disabled={busy}
      onclick={() => (confirmOpen = false)} />
    <DhButton variant="error" text="Delete" startIcon="trash-2"
      loading={busy} onclick={confirmDelete} />
  {/snippet}
</DhModal>

Delete this item?

This cannot be undone. Any comments, attachments, and history tied to this item will be removed.

Sticky modal

Disable background click, ESC dismiss, and the close button to force a choice.

<DhModal
  open={stickyOpen}
  title="You must choose"
  dismissOnBackground={false}
  closeOnEsc={false}
  showCloseButton={false}
  onclose={() => (stickyOpen = false)}
>
  ...
</DhModal>

You must choose

Neither backdrop click nor ESC will close this modal. Pick one.

Loading body

Use DhSpinner inside the modal's body for async views.

<DhModal open={loadingOpen} title="Fetching...">
  <DhSpinner label="Loading data..." />
</DhModal>

Fetching...

Loading data from the server…