Modal

Alpine x-data overlay dialog. Click the trigger slot to open, or dispatch open-modal-{id} from elsewhere. size (sm/md/lg/xl/full), title, showClose, closeOnBackdrop props. Close via background click, Escape, or × button. x-trap for focus trap, x-teleport to append below body.

1. Minimal: with a trigger slot

<x-modal title="Confirm">
    <x-slot:trigger>
        <x-button>Open default modal</x-button>
    </x-slot:trigger>
    <p class="text-sm text-base-content/80">A centered dialog with a backdrop. Esc and a backdrop click both close it.</p>
</x-modal>
<div x-data="{ open: false }" x-on:open-modal-modal_6a7e9b5be75a1.window="open = true" x-on:close-modal-modal_6a7e9b5be75a1.window="open = false">
<div @click="open = true" class="cursor-pointer">
<button class="inline-flex items-center justify-center whitespace-nowrap font-medium tracking-wide transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 rounded-[var(--radius-field)] border-[length:var(--border)] h-[var(--h-field-md)] px-[var(--px-field-md)] text-[length:var(--text-field-md)] gap-2 bg-primary text-primary-content border-primary hover:bg-primary/90 focus-visible:ring-primary cursor-pointer">Open default modal</button>
</div>
<template x-teleport="body">
<div x-show="open" x-transition:enter="transition ease-out duration-200" x-transition:enter-start="opacity-0" x-transition:enter-end="opacity-100" x-transition:leave="transition ease-in duration-150" x-transition:leave-start="opacity-100" x-transition:leave-end="opacity-0" class="fixed inset-0 z-50 flex items-center justify-center p-4" x-cloak="">
<div class="absolute inset-0 bg-black/50" @click="open = false"></div>
<div x-show="open" x-transition:enter="transition ease-out duration-200" x-transition:enter-start="opacity-0 scale-95" x-transition:enter-end="opacity-100 scale-100" x-transition:leave="transition ease-in duration-150" x-transition:leave-start="opacity-100 scale-100" x-transition:leave-end="opacity-0 scale-95" x-trap.inert.noscroll="open" @keydown.escape.window="open = false" class="relative w-full max-w-lg flex flex-col max-h-[calc(100dvh-2rem)] bg-base-100 text-base-content text-[length:var(--text-field-md)] rounded-[var(--radius-box)] border-[length:var(--border)] border-base-300 shadow-[0_10px_30px_-8px_rgb(0_0_0_/_0.18),var(--shadow-box)] p-lg" role="dialog" aria-modal="true" aria-labelledby="modal_6a7e9b5be75a1_title">
<div class="flex shrink-0 items-center justify-between mb-sm">
<h3 id="modal_6a7e9b5be75a1_title" class="text-[length:var(--text-field-lg)] font-semibold text-base-content">
                        Confirm
                    </h3><button type="button" @click="open = false" class="text-base-content/50 hover:text-base-content transition-colors rounded-[var(--radius-field)] p-1 hover:bg-base-200" aria-label="Close"><svg class="w-5 h-5" fill="none" viewbox="0 0 24 24" stroke="currentcolor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12"></path></svg></button>
</div>
<div class="min-h-0 overflow-y-auto">
<p class="text-sm text-base-content/80">
                        A centered dialog with a backdrop. Esc and a backdrop click both close it.
                    </p>
</div>
</div>
</div>
</template>
</div>

When title is omitted — the header shows only the × button (confirms title isn't required)

<x-modal>
    <x-slot:trigger>
        <x-button appearance="soft">Open titleless modal</x-button>
    </x-slot:trigger>
    <p class="text-sm text-base-content/80">Without a title the header row is dropped and only the close button remains.</p>
</x-modal>
<div x-data="{ open: false }" x-on:open-modal-modal_6a7e9b5bf078c.window="open = true" x-on:close-modal-modal_6a7e9b5bf078c.window="open = false">
<div @click="open = true" class="cursor-pointer">
<button class="inline-flex items-center justify-center whitespace-nowrap font-medium tracking-wide transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 rounded-[var(--radius-field)] border-[length:var(--border)] h-[var(--h-field-md)] px-[var(--px-field-md)] text-[length:var(--text-field-md)] gap-2 bg-primary/10 text-primary border-transparent hover:bg-primary/20 focus-visible:ring-primary cursor-pointer">Open titleless modal</button>
</div>
<template x-teleport="body">
<div x-show="open" x-transition:enter="transition ease-out duration-200" x-transition:enter-start="opacity-0" x-transition:enter-end="opacity-100" x-transition:leave="transition ease-in duration-150" x-transition:leave-start="opacity-100" x-transition:leave-end="opacity-0" class="fixed inset-0 z-50 flex items-center justify-center p-4" x-cloak="">
<div class="absolute inset-0 bg-black/50" @click="open = false"></div>
<div x-show="open" x-transition:enter="transition ease-out duration-200" x-transition:enter-start="opacity-0 scale-95" x-transition:enter-end="opacity-100 scale-100" x-transition:leave="transition ease-in duration-150" x-transition:leave-start="opacity-100 scale-100" x-transition:leave-end="opacity-0 scale-95" x-trap.inert.noscroll="open" @keydown.escape.window="open = false" class="relative w-full max-w-lg flex flex-col max-h-[calc(100dvh-2rem)] bg-base-100 text-base-content text-[length:var(--text-field-md)] rounded-[var(--radius-box)] border-[length:var(--border)] border-base-300 shadow-[0_10px_30px_-8px_rgb(0_0_0_/_0.18),var(--shadow-box)] p-lg" role="dialog" aria-modal="true">
<button type="button" @click="open = false" class="absolute top-lg right-lg z-10 text-base-content/50 hover:text-base-content transition-colors rounded-[var(--radius-field)] p-0.5 hover:bg-base-200" aria-label="Close"><svg class="w-4 h-4" fill="none" viewbox="0 0 24 24" stroke="currentcolor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12"></path></svg></button>
<div class="min-h-0 overflow-y-auto">
<p class="text-sm text-base-content/80">
                        Without a title the header row is dropped and only the close button remains.
                    </p>
</div>
</div>
</div>
</template>
</div>

size — sm / md / lg / xl / full

<x-modal title="Small modal" size="sm">
    <x-slot:trigger><x-button size="sm">sm (max-w-sm)</x-button></x-slot:trigger>
    <p class="text-sm text-base-content/80">Best for short confirmations.</p>
</x-modal>
<x-modal title="Medium modal (default)" size="md">
    <x-slot:trigger><x-button size="sm">md (max-w-lg)</x-button></x-slot:trigger>
    <p class="text-sm text-base-content/80">The default width.</p>
</x-modal>
<x-modal title="Large modal" size="lg">
    <x-slot:trigger><x-button size="sm">lg (max-w-2xl)</x-button></x-slot:trigger>
    <p class="text-sm text-base-content/80">Room for a short form.</p>
</x-modal>
<x-modal title="Extra-large modal" size="xl">
    <x-slot:trigger><x-button size="sm">xl (max-w-4xl)</x-button></x-slot:trigger>
    <p class="text-sm text-base-content/80">Room for a table or a two-column layout.</p>
</x-modal>
<x-modal title="Full-width modal" size="full">
    <x-slot:trigger><x-button size="sm">full (max-w-full mx-4)</x-button></x-slot:trigger>
    <p class="text-sm text-base-content/80">Edge-to-edge apart from the outer margin.</p>
</x-modal>
<div x-data="{ open: false }" x-on:open-modal-modal_6a7e9b5c04acd.window="open = true" x-on:close-modal-modal_6a7e9b5c04acd.window="open = false">
<div @click="open = true" class="cursor-pointer">
<button class="inline-flex items-center justify-center whitespace-nowrap font-medium tracking-wide transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 rounded-[var(--radius-field)] border-[length:var(--border)] h-[var(--h-field-sm)] px-[var(--px-field-sm)] text-[length:var(--text-field-sm)] gap-1.5 bg-primary text-primary-content border-primary hover:bg-primary/90 focus-visible:ring-primary cursor-pointer">sm (max-w-sm)</button>
</div>
<template x-teleport="body">
<div x-show="open" x-transition:enter="transition ease-out duration-200" x-transition:enter-start="opacity-0" x-transition:enter-end="opacity-100" x-transition:leave="transition ease-in duration-150" x-transition:leave-start="opacity-100" x-transition:leave-end="opacity-0" class="fixed inset-0 z-50 flex items-center justify-center p-4" x-cloak="">
<div class="absolute inset-0 bg-black/50" @click="open = false"></div>
<div x-show="open" x-transition:enter="transition ease-out duration-200" x-transition:enter-start="opacity-0 scale-95" x-transition:enter-end="opacity-100 scale-100" x-transition:leave="transition ease-in duration-150" x-transition:leave-start="opacity-100 scale-100" x-transition:leave-end="opacity-0 scale-95" x-trap.inert.noscroll="open" @keydown.escape.window="open = false" class="relative w-full max-w-sm flex flex-col max-h-[calc(100dvh-2rem)] bg-base-100 text-base-content text-[length:var(--text-field-md)] rounded-[var(--radius-box)] border-[length:var(--border)] border-base-300 shadow-[0_10px_30px_-8px_rgb(0_0_0_/_0.18),var(--shadow-box)] p-lg" role="dialog" aria-modal="true" aria-labelledby="modal_6a7e9b5c04acd_title">
<div class="flex shrink-0 items-center justify-between mb-sm">
<h3 id="modal_6a7e9b5c04acd_title" class="text-[length:var(--text-field-lg)] font-semibold text-base-content">
                        Small modal
                    </h3><button type="button" @click="open = false" class="text-base-content/50 hover:text-base-content transition-colors rounded-[var(--radius-field)] p-1 hover:bg-base-200" aria-label="Close"><svg class="w-5 h-5" fill="none" viewbox="0 0 24 24" stroke="currentcolor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12"></path></svg></button>
</div>
<div class="min-h-0 overflow-y-auto">
<p class="text-sm text-base-content/80">
                        Best for short confirmations.
                    </p>
</div>
</div>
</div>
</template>
</div>
<div x-data="{ open: false }" x-on:open-modal-modal_6a7e9b5c04b67.window="open = true" x-on:close-modal-modal_6a7e9b5c04b67.window="open = false">
<div @click="open = true" class="cursor-pointer">
<button class="inline-flex items-center justify-center whitespace-nowrap font-medium tracking-wide transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 rounded-[var(--radius-field)] border-[length:var(--border)] h-[var(--h-field-sm)] px-[var(--px-field-sm)] text-[length:var(--text-field-sm)] gap-1.5 bg-primary text-primary-content border-primary hover:bg-primary/90 focus-visible:ring-primary cursor-pointer">md (max-w-lg)</button>
</div>
<template x-teleport="body">
<div x-show="open" x-transition:enter="transition ease-out duration-200" x-transition:enter-start="opacity-0" x-transition:enter-end="opacity-100" x-transition:leave="transition ease-in duration-150" x-transition:leave-start="opacity-100" x-transition:leave-end="opacity-0" class="fixed inset-0 z-50 flex items-center justify-center p-4" x-cloak="">
<div class="absolute inset-0 bg-black/50" @click="open = false"></div>
<div x-show="open" x-transition:enter="transition ease-out duration-200" x-transition:enter-start="opacity-0 scale-95" x-transition:enter-end="opacity-100 scale-100" x-transition:leave="transition ease-in duration-150" x-transition:leave-start="opacity-100 scale-100" x-transition:leave-end="opacity-0 scale-95" x-trap.inert.noscroll="open" @keydown.escape.window="open = false" class="relative w-full max-w-lg flex flex-col max-h-[calc(100dvh-2rem)] bg-base-100 text-base-content text-[length:var(--text-field-md)] rounded-[var(--radius-box)] border-[length:var(--border)] border-base-300 shadow-[0_10px_30px_-8px_rgb(0_0_0_/_0.18),var(--shadow-box)] p-lg" role="dialog" aria-modal="true" aria-labelledby="modal_6a7e9b5c04b67_title">
<div class="flex shrink-0 items-center justify-between mb-sm">
<h3 id="modal_6a7e9b5c04b67_title" class="text-[length:var(--text-field-lg)] font-semibold text-base-content">
                        Medium modal (default)
                    </h3><button type="button" @click="open = false" class="text-base-content/50 hover:text-base-content transition-colors rounded-[var(--radius-field)] p-1 hover:bg-base-200" aria-label="Close"><svg class="w-5 h-5" fill="none" viewbox="0 0 24 24" stroke="currentcolor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12"></path></svg></button>
</div>
<div class="min-h-0 overflow-y-auto">
<p class="text-sm text-base-content/80">
                        The default width.
                    </p>
</div>
</div>
</div>
</template>
</div>
<div x-data="{ open: false }" x-on:open-modal-modal_6a7e9b5c04bf8.window="open = true" x-on:close-modal-modal_6a7e9b5c04bf8.window="open = false">
<div @click="open = true" class="cursor-pointer">
<button class="inline-flex items-center justify-center whitespace-nowrap font-medium tracking-wide transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 rounded-[var(--radius-field)] border-[length:var(--border)] h-[var(--h-field-sm)] px-[var(--px-field-sm)] text-[length:var(--text-field-sm)] gap-1.5 bg-primary text-primary-content border-primary hover:bg-primary/90 focus-visible:ring-primary cursor-pointer">lg (max-w-2xl)</button>
</div>
<template x-teleport="body">
<div x-show="open" x-transition:enter="transition ease-out duration-200" x-transition:enter-start="opacity-0" x-transition:enter-end="opacity-100" x-transition:leave="transition ease-in duration-150" x-transition:leave-start="opacity-100" x-transition:leave-end="opacity-0" class="fixed inset-0 z-50 flex items-center justify-center p-4" x-cloak="">
<div class="absolute inset-0 bg-black/50" @click="open = false"></div>
<div x-show="open" x-transition:enter="transition ease-out duration-200" x-transition:enter-start="opacity-0 scale-95" x-transition:enter-end="opacity-100 scale-100" x-transition:leave="transition ease-in duration-150" x-transition:leave-start="opacity-100 scale-100" x-transition:leave-end="opacity-0 scale-95" x-trap.inert.noscroll="open" @keydown.escape.window="open = false" class="relative w-full max-w-2xl flex flex-col max-h-[calc(100dvh-2rem)] bg-base-100 text-base-content text-[length:var(--text-field-md)] rounded-[var(--radius-box)] border-[length:var(--border)] border-base-300 shadow-[0_10px_30px_-8px_rgb(0_0_0_/_0.18),var(--shadow-box)] p-lg" role="dialog" aria-modal="true" aria-labelledby="modal_6a7e9b5c04bf8_title">
<div class="flex shrink-0 items-center justify-between mb-sm">
<h3 id="modal_6a7e9b5c04bf8_title" class="text-[length:var(--text-field-lg)] font-semibold text-base-content">
                        Large modal
                    </h3><button type="button" @click="open = false" class="text-base-content/50 hover:text-base-content transition-colors rounded-[var(--radius-field)] p-1 hover:bg-base-200" aria-label="Close"><svg class="w-5 h-5" fill="none" viewbox="0 0 24 24" stroke="currentcolor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12"></path></svg></button>
</div>
<div class="min-h-0 overflow-y-auto">
<p class="text-sm text-base-content/80">
                        Room for a short form.
                    </p>
</div>
</div>
</div>
</template>
</div>
<div x-data="{ open: false }" x-on:open-modal-modal_6a7e9b5c04c86.window="open = true" x-on:close-modal-modal_6a7e9b5c04c86.window="open = false">
<div @click="open = true" class="cursor-pointer">
<button class="inline-flex items-center justify-center whitespace-nowrap font-medium tracking-wide transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 rounded-[var(--radius-field)] border-[length:var(--border)] h-[var(--h-field-sm)] px-[var(--px-field-sm)] text-[length:var(--text-field-sm)] gap-1.5 bg-primary text-primary-content border-primary hover:bg-primary/90 focus-visible:ring-primary cursor-pointer">xl (max-w-4xl)</button>
</div>
<template x-teleport="body">
<div x-show="open" x-transition:enter="transition ease-out duration-200" x-transition:enter-start="opacity-0" x-transition:enter-end="opacity-100" x-transition:leave="transition ease-in duration-150" x-transition:leave-start="opacity-100" x-transition:leave-end="opacity-0" class="fixed inset-0 z-50 flex items-center justify-center p-4" x-cloak="">
<div class="absolute inset-0 bg-black/50" @click="open = false"></div>
<div x-show="open" x-transition:enter="transition ease-out duration-200" x-transition:enter-start="opacity-0 scale-95" x-transition:enter-end="opacity-100 scale-100" x-transition:leave="transition ease-in duration-150" x-transition:leave-start="opacity-100 scale-100" x-transition:leave-end="opacity-0 scale-95" x-trap.inert.noscroll="open" @keydown.escape.window="open = false" class="relative w-full max-w-4xl flex flex-col max-h-[calc(100dvh-2rem)] bg-base-100 text-base-content text-[length:var(--text-field-md)] rounded-[var(--radius-box)] border-[length:var(--border)] border-base-300 shadow-[0_10px_30px_-8px_rgb(0_0_0_/_0.18),var(--shadow-box)] p-lg" role="dialog" aria-modal="true" aria-labelledby="modal_6a7e9b5c04c86_title">
<div class="flex shrink-0 items-center justify-between mb-sm">
<h3 id="modal_6a7e9b5c04c86_title" class="text-[length:var(--text-field-lg)] font-semibold text-base-content">
                        Extra-large modal
                    </h3><button type="button" @click="open = false" class="text-base-content/50 hover:text-base-content transition-colors rounded-[var(--radius-field)] p-1 hover:bg-base-200" aria-label="Close"><svg class="w-5 h-5" fill="none" viewbox="0 0 24 24" stroke="currentcolor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12"></path></svg></button>
</div>
<div class="min-h-0 overflow-y-auto">
<p class="text-sm text-base-content/80">
                        Room for a table or a two-column layout.
                    </p>
</div>
</div>
</div>
</template>
</div>
<div x-data="{ open: false }" x-on:open-modal-modal_6a7e9b5c04d14.window="open = true" x-on:close-modal-modal_6a7e9b5c04d14.window="open = false">
<div @click="open = true" class="cursor-pointer">
<button class="inline-flex items-center justify-center whitespace-nowrap font-medium tracking-wide transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 rounded-[var(--radius-field)] border-[length:var(--border)] h-[var(--h-field-sm)] px-[var(--px-field-sm)] text-[length:var(--text-field-sm)] gap-1.5 bg-primary text-primary-content border-primary hover:bg-primary/90 focus-visible:ring-primary cursor-pointer">full (max-w-full mx-4)</button>
</div>
<template x-teleport="body">
<div x-show="open" x-transition:enter="transition ease-out duration-200" x-transition:enter-start="opacity-0" x-transition:enter-end="opacity-100" x-transition:leave="transition ease-in duration-150" x-transition:leave-start="opacity-100" x-transition:leave-end="opacity-0" class="fixed inset-0 z-50 flex items-center justify-center p-4" x-cloak="">
<div class="absolute inset-0 bg-black/50" @click="open = false"></div>
<div x-show="open" x-transition:enter="transition ease-out duration-200" x-transition:enter-start="opacity-0 scale-95" x-transition:enter-end="opacity-100 scale-100" x-transition:leave="transition ease-in duration-150" x-transition:leave-start="opacity-100 scale-100" x-transition:leave-end="opacity-0 scale-95" x-trap.inert.noscroll="open" @keydown.escape.window="open = false" class="relative w-full max-w-full mx-4 flex flex-col max-h-[calc(100dvh-2rem)] bg-base-100 text-base-content text-[length:var(--text-field-md)] rounded-[var(--radius-box)] border-[length:var(--border)] border-base-300 shadow-[0_10px_30px_-8px_rgb(0_0_0_/_0.18),var(--shadow-box)] p-lg" role="dialog" aria-modal="true" aria-labelledby="modal_6a7e9b5c04d14_title">
<div class="flex shrink-0 items-center justify-between mb-sm">
<h3 id="modal_6a7e9b5c04d14_title" class="text-[length:var(--text-field-lg)] font-semibold text-base-content">
                        Full-width modal
                    </h3><button type="button" @click="open = false" class="text-base-content/50 hover:text-base-content transition-colors rounded-[var(--radius-field)] p-1 hover:bg-base-200" aria-label="Close"><svg class="w-5 h-5" fill="none" viewbox="0 0 24 24" stroke="currentcolor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12"></path></svg></button>
</div>
<div class="min-h-0 overflow-y-auto">
<p class="text-sm text-base-content/80">
                        Edge-to-edge apart from the outer margin.
                    </p>
</div>
</div>
</div>
</template>
</div>

showClose — controls whether the × button is shown

<x-modal title="showClose=false" :showClose="false">
    <x-slot:trigger><x-button appearance="outline" size="sm">showClose=false</x-button></x-slot:trigger>
    <p class="text-sm text-base-content/80">The X is hidden — give the user an explicit action instead.</p>
    <x-slot:actions>
        <x-button size="sm" @click="open = false">OK</x-button>
    </x-slot:actions>
</x-modal>
<x-modal title="showClose=true (default)">
    <x-slot:trigger><x-button appearance="outline" size="sm">showClose=true (default)</x-button></x-slot:trigger>
    <p class="text-sm text-base-content/80">The X sits in the header.</p>
</x-modal>
<div x-data="{ open: false }" x-on:open-modal-modal_6a7e9b5c2fbe8.window="open = true" x-on:close-modal-modal_6a7e9b5c2fbe8.window="open = false">
<div @click="open = true" class="cursor-pointer">
<button class="inline-flex items-center justify-center whitespace-nowrap font-medium tracking-wide transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 rounded-[var(--radius-field)] border-[length:var(--border)] h-[var(--h-field-sm)] px-[var(--px-field-sm)] text-[length:var(--text-field-sm)] gap-1.5 bg-transparent text-primary border-primary hover:bg-primary hover:text-primary-content focus-visible:ring-primary cursor-pointer">showClose=false</button>
</div>
<template x-teleport="body">
<div x-show="open" x-transition:enter="transition ease-out duration-200" x-transition:enter-start="opacity-0" x-transition:enter-end="opacity-100" x-transition:leave="transition ease-in duration-150" x-transition:leave-start="opacity-100" x-transition:leave-end="opacity-0" class="fixed inset-0 z-50 flex items-center justify-center p-4" x-cloak="">
<div class="absolute inset-0 bg-black/50" @click="open = false"></div>
<div x-show="open" x-transition:enter="transition ease-out duration-200" x-transition:enter-start="opacity-0 scale-95" x-transition:enter-end="opacity-100 scale-100" x-transition:leave="transition ease-in duration-150" x-transition:leave-start="opacity-100 scale-100" x-transition:leave-end="opacity-0 scale-95" x-trap.inert.noscroll="open" @keydown.escape.window="open = false" class="relative w-full max-w-lg flex flex-col max-h-[calc(100dvh-2rem)] bg-base-100 text-base-content text-[length:var(--text-field-md)] rounded-[var(--radius-box)] border-[length:var(--border)] border-base-300 shadow-[0_10px_30px_-8px_rgb(0_0_0_/_0.18),var(--shadow-box)] p-lg" role="dialog" aria-modal="true" aria-labelledby="modal_6a7e9b5c2fbe8_title">
<div class="flex shrink-0 items-center justify-between mb-sm">
<h3 id="modal_6a7e9b5c2fbe8_title" class="text-[length:var(--text-field-lg)] font-semibold text-base-content">
                        showClose=false
                    </h3>
</div>
<div class="min-h-0 overflow-y-auto">
<p class="text-sm text-base-content/80">
                        The X is hidden — give the user an explicit action instead.
                    </p>
</div>
<div class="flex shrink-0 items-center justify-end gap-xs mt-lg">
<button class="inline-flex items-center justify-center whitespace-nowrap font-medium tracking-wide transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 rounded-[var(--radius-field)] border-[length:var(--border)] h-[var(--h-field-sm)] px-[var(--px-field-sm)] text-[length:var(--text-field-sm)] gap-1.5 bg-primary text-primary-content border-primary hover:bg-primary/90 focus-visible:ring-primary cursor-pointer" @click="open = false">OK</button>
</div>
</div>
</div>
</template>
</div>
<div x-data="{ open: false }" x-on:open-modal-modal_6a7e9b5c2fc81.window="open = true" x-on:close-modal-modal_6a7e9b5c2fc81.window="open = false">
<div @click="open = true" class="cursor-pointer">
<button class="inline-flex items-center justify-center whitespace-nowrap font-medium tracking-wide transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 rounded-[var(--radius-field)] border-[length:var(--border)] h-[var(--h-field-sm)] px-[var(--px-field-sm)] text-[length:var(--text-field-sm)] gap-1.5 bg-transparent text-primary border-primary hover:bg-primary hover:text-primary-content focus-visible:ring-primary cursor-pointer">showClose=true (default)</button>
</div>
<template x-teleport="body">
<div x-show="open" x-transition:enter="transition ease-out duration-200" x-transition:enter-start="opacity-0" x-transition:enter-end="opacity-100" x-transition:leave="transition ease-in duration-150" x-transition:leave-start="opacity-100" x-transition:leave-end="opacity-0" class="fixed inset-0 z-50 flex items-center justify-center p-4" x-cloak="">
<div class="absolute inset-0 bg-black/50" @click="open = false"></div>
<div x-show="open" x-transition:enter="transition ease-out duration-200" x-transition:enter-start="opacity-0 scale-95" x-transition:enter-end="opacity-100 scale-100" x-transition:leave="transition ease-in duration-150" x-transition:leave-start="opacity-100 scale-100" x-transition:leave-end="opacity-0 scale-95" x-trap.inert.noscroll="open" @keydown.escape.window="open = false" class="relative w-full max-w-lg flex flex-col max-h-[calc(100dvh-2rem)] bg-base-100 text-base-content text-[length:var(--text-field-md)] rounded-[var(--radius-box)] border-[length:var(--border)] border-base-300 shadow-[0_10px_30px_-8px_rgb(0_0_0_/_0.18),var(--shadow-box)] p-lg" role="dialog" aria-modal="true" aria-labelledby="modal_6a7e9b5c2fc81_title">
<div class="flex shrink-0 items-center justify-between mb-sm">
<h3 id="modal_6a7e9b5c2fc81_title" class="text-[length:var(--text-field-lg)] font-semibold text-base-content">
                        showClose=true (default)
                    </h3><button type="button" @click="open = false" class="text-base-content/50 hover:text-base-content transition-colors rounded-[var(--radius-field)] p-1 hover:bg-base-200" aria-label="Close"><svg class="w-5 h-5" fill="none" viewbox="0 0 24 24" stroke="currentcolor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12"></path></svg></button>
</div>
<div class="min-h-0 overflow-y-auto">
<p class="text-sm text-base-content/80">
                        The X sits in the header.
                    </p>
</div>
</div>
</div>
</template>
</div>

closeOnBackdrop — backdrop click behavior

<x-modal title="closeOnBackdrop=true (default)">
    <x-slot:trigger><x-button appearance="outline" size="sm">closeOnBackdrop=true (default)</x-button></x-slot:trigger>
    <p class="text-sm text-base-content/80">Clicking the backdrop closes the dialog.</p>
</x-modal>
<x-modal title="closeOnBackdrop=false" :closeOnBackdrop="false">
    <x-slot:trigger><x-button appearance="outline" size="sm">closeOnBackdrop=false</x-button></x-slot:trigger>
    <p class="text-sm text-base-content/80">The backdrop is inert — use this for destructive confirmations.</p>
</x-modal>
<div x-data="{ open: false }" x-on:open-modal-modal_6a7e9b5c41af2.window="open = true" x-on:close-modal-modal_6a7e9b5c41af2.window="open = false">
<div @click="open = true" class="cursor-pointer">
<button class="inline-flex items-center justify-center whitespace-nowrap font-medium tracking-wide transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 rounded-[var(--radius-field)] border-[length:var(--border)] h-[var(--h-field-sm)] px-[var(--px-field-sm)] text-[length:var(--text-field-sm)] gap-1.5 bg-transparent text-primary border-primary hover:bg-primary hover:text-primary-content focus-visible:ring-primary cursor-pointer">closeOnBackdrop=true (default)</button>
</div>
<template x-teleport="body">
<div x-show="open" x-transition:enter="transition ease-out duration-200" x-transition:enter-start="opacity-0" x-transition:enter-end="opacity-100" x-transition:leave="transition ease-in duration-150" x-transition:leave-start="opacity-100" x-transition:leave-end="opacity-0" class="fixed inset-0 z-50 flex items-center justify-center p-4" x-cloak="">
<div class="absolute inset-0 bg-black/50" @click="open = false"></div>
<div x-show="open" x-transition:enter="transition ease-out duration-200" x-transition:enter-start="opacity-0 scale-95" x-transition:enter-end="opacity-100 scale-100" x-transition:leave="transition ease-in duration-150" x-transition:leave-start="opacity-100 scale-100" x-transition:leave-end="opacity-0 scale-95" x-trap.inert.noscroll="open" @keydown.escape.window="open = false" class="relative w-full max-w-lg flex flex-col max-h-[calc(100dvh-2rem)] bg-base-100 text-base-content text-[length:var(--text-field-md)] rounded-[var(--radius-box)] border-[length:var(--border)] border-base-300 shadow-[0_10px_30px_-8px_rgb(0_0_0_/_0.18),var(--shadow-box)] p-lg" role="dialog" aria-modal="true" aria-labelledby="modal_6a7e9b5c41af2_title">
<div class="flex shrink-0 items-center justify-between mb-sm">
<h3 id="modal_6a7e9b5c41af2_title" class="text-[length:var(--text-field-lg)] font-semibold text-base-content">
                        closeOnBackdrop=true (default)
                    </h3><button type="button" @click="open = false" class="text-base-content/50 hover:text-base-content transition-colors rounded-[var(--radius-field)] p-1 hover:bg-base-200" aria-label="Close"><svg class="w-5 h-5" fill="none" viewbox="0 0 24 24" stroke="currentcolor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12"></path></svg></button>
</div>
<div class="min-h-0 overflow-y-auto">
<p class="text-sm text-base-content/80">
                        Clicking the backdrop closes the dialog.
                    </p>
</div>
</div>
</div>
</template>
</div>
<div x-data="{ open: false }" x-on:open-modal-modal_6a7e9b5c41b82.window="open = true" x-on:close-modal-modal_6a7e9b5c41b82.window="open = false">
<div @click="open = true" class="cursor-pointer">
<button class="inline-flex items-center justify-center whitespace-nowrap font-medium tracking-wide transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 rounded-[var(--radius-field)] border-[length:var(--border)] h-[var(--h-field-sm)] px-[var(--px-field-sm)] text-[length:var(--text-field-sm)] gap-1.5 bg-transparent text-primary border-primary hover:bg-primary hover:text-primary-content focus-visible:ring-primary cursor-pointer">closeOnBackdrop=false</button>
</div>
<template x-teleport="body">
<div x-show="open" x-transition:enter="transition ease-out duration-200" x-transition:enter-start="opacity-0" x-transition:enter-end="opacity-100" x-transition:leave="transition ease-in duration-150" x-transition:leave-start="opacity-100" x-transition:leave-end="opacity-0" class="fixed inset-0 z-50 flex items-center justify-center p-4" x-cloak="">
<div class="absolute inset-0 bg-black/50"></div>
<div x-show="open" x-transition:enter="transition ease-out duration-200" x-transition:enter-start="opacity-0 scale-95" x-transition:enter-end="opacity-100 scale-100" x-transition:leave="transition ease-in duration-150" x-transition:leave-start="opacity-100 scale-100" x-transition:leave-end="opacity-0 scale-95" x-trap.inert.noscroll="open" @keydown.escape.window="open = false" class="relative w-full max-w-lg flex flex-col max-h-[calc(100dvh-2rem)] bg-base-100 text-base-content text-[length:var(--text-field-md)] rounded-[var(--radius-box)] border-[length:var(--border)] border-base-300 shadow-[0_10px_30px_-8px_rgb(0_0_0_/_0.18),var(--shadow-box)] p-lg" role="dialog" aria-modal="true" aria-labelledby="modal_6a7e9b5c41b82_title">
<div class="flex shrink-0 items-center justify-between mb-sm">
<h3 id="modal_6a7e9b5c41b82_title" class="text-[length:var(--text-field-lg)] font-semibold text-base-content">
                        closeOnBackdrop=false
                    </h3><button type="button" @click="open = false" class="text-base-content/50 hover:text-base-content transition-colors rounded-[var(--radius-field)] p-1 hover:bg-base-200" aria-label="Close"><svg class="w-5 h-5" fill="none" viewbox="0 0 24 24" stroke="currentcolor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12"></path></svg></button>
</div>
<div class="min-h-0 overflow-y-auto">
<p class="text-sm text-base-content/80">
                        The backdrop is inert — use this for destructive confirmations.
                    </p>
</div>
</div>
</div>
</template>
</div>

2. title + size + actions slot (a typical confirmation dialog)

<x-modal title="Delete confirmation" size="sm" :closeOnBackdrop="false">
    <x-slot:trigger><x-button color="error" size="sm">Delete…</x-button></x-slot:trigger>
    <p class="text-sm text-base-content/80">Are you sure you want to delete this? This cannot be undone.</p>
    <x-slot:actions>
        <x-button appearance="ghost" size="sm" @click="open = false">Cancel</x-button>
        <x-button color="error" size="sm" @click="open = false">Delete</x-button>
    </x-slot:actions>
</x-modal>
<x-modal title="New project" size="md">
    <x-slot:trigger><x-button color="primary" size="sm">+ Create</x-button></x-slot:trigger>
    <div class="space-y-3">
        <x-input label="Project name" placeholder="my-app" />
        <x-textarea label="Description" rows="3" placeholder="optional" />
    </div>
    <x-slot:actions>
        <x-button appearance="ghost" size="sm" @click="open = false">Cancel</x-button>
        <x-button color="primary" size="sm" @click="open = false">Create</x-button>
    </x-slot:actions>
</x-modal>
<div x-data="{ open: false }" x-on:open-modal-modal_6a7e9b5c53c69.window="open = true" x-on:close-modal-modal_6a7e9b5c53c69.window="open = false">
<div @click="open = true" class="cursor-pointer">
<button class="inline-flex items-center justify-center whitespace-nowrap font-medium tracking-wide transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 rounded-[var(--radius-field)] border-[length:var(--border)] h-[var(--h-field-sm)] px-[var(--px-field-sm)] text-[length:var(--text-field-sm)] gap-1.5 bg-error text-error-content border-error hover:bg-error/90 focus-visible:ring-error cursor-pointer">Delete…</button>
</div>
<template x-teleport="body">
<div x-show="open" x-transition:enter="transition ease-out duration-200" x-transition:enter-start="opacity-0" x-transition:enter-end="opacity-100" x-transition:leave="transition ease-in duration-150" x-transition:leave-start="opacity-100" x-transition:leave-end="opacity-0" class="fixed inset-0 z-50 flex items-center justify-center p-4" x-cloak="">
<div class="absolute inset-0 bg-black/50"></div>
<div x-show="open" x-transition:enter="transition ease-out duration-200" x-transition:enter-start="opacity-0 scale-95" x-transition:enter-end="opacity-100 scale-100" x-transition:leave="transition ease-in duration-150" x-transition:leave-start="opacity-100 scale-100" x-transition:leave-end="opacity-0 scale-95" x-trap.inert.noscroll="open" @keydown.escape.window="open = false" class="relative w-full max-w-sm flex flex-col max-h-[calc(100dvh-2rem)] bg-base-100 text-base-content text-[length:var(--text-field-md)] rounded-[var(--radius-box)] border-[length:var(--border)] border-base-300 shadow-[0_10px_30px_-8px_rgb(0_0_0_/_0.18),var(--shadow-box)] p-lg" role="dialog" aria-modal="true" aria-labelledby="modal_6a7e9b5c53c69_title">
<div class="flex shrink-0 items-center justify-between mb-sm">
<h3 id="modal_6a7e9b5c53c69_title" class="text-[length:var(--text-field-lg)] font-semibold text-base-content">
                        Delete confirmation
                    </h3><button type="button" @click="open = false" class="text-base-content/50 hover:text-base-content transition-colors rounded-[var(--radius-field)] p-1 hover:bg-base-200" aria-label="Close"><svg class="w-5 h-5" fill="none" viewbox="0 0 24 24" stroke="currentcolor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12"></path></svg></button>
</div>
<div class="min-h-0 overflow-y-auto">
<p class="text-sm text-base-content/80">
                        Are you sure you want to delete this? This cannot be undone.
                    </p>
</div>
<div class="flex shrink-0 items-center justify-end gap-xs mt-lg">
<button class="inline-flex items-center justify-center whitespace-nowrap font-medium tracking-wide transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 rounded-[var(--radius-field)] border-[length:var(--border)] h-[var(--h-field-sm)] px-[var(--px-field-sm)] text-[length:var(--text-field-sm)] gap-1.5 bg-transparent text-base-content border-transparent hover:bg-base-200 focus-visible:ring-base-300 cursor-pointer" @click="open = false">Cancel</button>
<button class="inline-flex items-center justify-center whitespace-nowrap font-medium tracking-wide transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 rounded-[var(--radius-field)] border-[length:var(--border)] h-[var(--h-field-sm)] px-[var(--px-field-sm)] text-[length:var(--text-field-sm)] gap-1.5 bg-error text-error-content border-error hover:bg-error/90 focus-visible:ring-error cursor-pointer" @click="open = false">Delete</button>
</div>
</div>
</div>
</template>
</div>
<div x-data="{ open: false }" x-on:open-modal-modal_6a7e9b5c53e9e.window="open = true" x-on:close-modal-modal_6a7e9b5c53e9e.window="open = false">
<div @click="open = true" class="cursor-pointer">
<button class="inline-flex items-center justify-center whitespace-nowrap font-medium tracking-wide transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 rounded-[var(--radius-field)] border-[length:var(--border)] h-[var(--h-field-sm)] px-[var(--px-field-sm)] text-[length:var(--text-field-sm)] gap-1.5 bg-primary text-primary-content border-primary hover:bg-primary/90 focus-visible:ring-primary cursor-pointer">+ Create</button>
</div>
<template x-teleport="body">
<div x-show="open" x-transition:enter="transition ease-out duration-200" x-transition:enter-start="opacity-0" x-transition:enter-end="opacity-100" x-transition:leave="transition ease-in duration-150" x-transition:leave-start="opacity-100" x-transition:leave-end="opacity-0" class="fixed inset-0 z-50 flex items-center justify-center p-4" x-cloak="">
<div class="absolute inset-0 bg-black/50" @click="open = false"></div>
<div x-show="open" x-transition:enter="transition ease-out duration-200" x-transition:enter-start="opacity-0 scale-95" x-transition:enter-end="opacity-100 scale-100" x-transition:leave="transition ease-in duration-150" x-transition:leave-start="opacity-100 scale-100" x-transition:leave-end="opacity-0 scale-95" x-trap.inert.noscroll="open" @keydown.escape.window="open = false" class="relative w-full max-w-lg flex flex-col max-h-[calc(100dvh-2rem)] bg-base-100 text-base-content text-[length:var(--text-field-md)] rounded-[var(--radius-box)] border-[length:var(--border)] border-base-300 shadow-[0_10px_30px_-8px_rgb(0_0_0_/_0.18),var(--shadow-box)] p-lg" role="dialog" aria-modal="true" aria-labelledby="modal_6a7e9b5c53e9e_title">
<div class="flex shrink-0 items-center justify-between mb-sm">
<h3 id="modal_6a7e9b5c53e9e_title" class="text-[length:var(--text-field-lg)] font-semibold text-base-content">
                        New project
                    </h3><button type="button" @click="open = false" class="text-base-content/50 hover:text-base-content transition-colors rounded-[var(--radius-field)] p-1 hover:bg-base-200" aria-label="Close"><svg class="w-5 h-5" fill="none" viewbox="0 0 24 24" stroke="currentcolor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12"></path></svg></button>
</div>
<div class="min-h-0 overflow-y-auto">
<div class="space-y-3">
<div class="w-full">
<div class="flex items-baseline justify-between mb-1.5">
<label for="input_6a7e9b5c53d48" class="block text-[length:var(--text-field-sm)] font-medium text-base-content">Project name</label>
</div>
<div class="flex items-stretch transition-colors rounded-[var(--radius-field)] bg-base-100 tune-border border-base-300 focus-within:border-primary focus-within:ring-1 focus-within:ring-primary h-[var(--h-field-md)]">
<div class="relative flex-1 min-w-0 flex items-stretch">
<input type="text" id="input_6a7e9b5c53d48" class="flex-1 min-w-0 w-full bg-transparent border-0 outline-none placeholder:text-base-content/40 peer text-[length:var(--text-field-md)] px-[var(--px-input-md)]" placeholder="my-app">
</div>
</div>
</div>
<div class="w-full">
<div class="flex items-baseline justify-between mb-1.5">
<label for="textarea_6a7e9b5c53dad" class="block text-[length:var(--text-field-sm)] font-medium text-base-content">Description</label>
</div>
<div class="block transition-colors rounded-[var(--radius-field)] bg-base-100 tune-border border-base-300 focus-within:border-primary focus-within:ring-1 focus-within:ring-primary">
<textarea id="textarea_6a7e9b5c53dad" rows="3" class="block w-full bg-transparent border-0 outline-none placeholder:text-base-content/40 tune-textarea-md resize-y" placeholder="optional"></textarea>
</div>
</div>
</div>
</div>
<div class="flex shrink-0 items-center justify-end gap-xs mt-lg">
<button class="inline-flex items-center justify-center whitespace-nowrap font-medium tracking-wide transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 rounded-[var(--radius-field)] border-[length:var(--border)] h-[var(--h-field-sm)] px-[var(--px-field-sm)] text-[length:var(--text-field-sm)] gap-1.5 bg-transparent text-base-content border-transparent hover:bg-base-200 focus-visible:ring-base-300 cursor-pointer" @click="open = false">Cancel</button>
<button class="inline-flex items-center justify-center whitespace-nowrap font-medium tracking-wide transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 rounded-[var(--radius-field)] border-[length:var(--border)] h-[var(--h-field-sm)] px-[var(--px-field-sm)] text-[length:var(--text-field-sm)] gap-1.5 bg-primary text-primary-content border-primary hover:bg-primary/90 focus-visible:ring-primary cursor-pointer" @click="open = false">Create</button>
</div>
</div>
</div>
</template>
</div>

Content taller than the viewport — the panel stays within the viewport and only the body scrolls; the header and actions remain visible (v0.10.9)

<x-modal title="Edit profile" size="lg">
    <x-slot:trigger><x-button color="primary" size="sm">Open a tall form</x-button></x-slot:trigger>
    <div class="space-y-3">
        <x-input label="First name" placeholder="Ada" />
        <x-input label="Last name" placeholder="Lovelace" />
        <x-input label="Email" type="email" placeholder="ada@example.com" />
        <x-input label="Phone" type="tel" placeholder="+1 555 0100" />
        <x-input label="Company" placeholder="Analytical Engines Ltd." />
        <x-input label="Job title" placeholder="Chief Engineer" />
        <x-input label="Street address" placeholder="12 Byron St." />
        <x-input label="City" placeholder="London" />
        <x-input label="Postal code" placeholder="W1K 1AA" />
        <x-input label="Country" placeholder="United Kingdom" />
        <x-input label="Website" type="url" placeholder="https://example.com" />
        <x-textarea label="Bio" rows="4" placeholder="A short introduction…" />
    </div>
    <x-slot:actions>
        <x-button appearance="ghost" size="sm" @click="open = false">Cancel</x-button>
        <x-button color="primary" size="sm" @click="open = false">Save</x-button>
    </x-slot:actions>
</x-modal>
<div x-data="{ open: false }" x-on:open-modal-modal_6a7e9b5c6ca6c.window="open = true" x-on:close-modal-modal_6a7e9b5c6ca6c.window="open = false">
<div @click="open = true" class="cursor-pointer">
<button class="inline-flex items-center justify-center whitespace-nowrap font-medium tracking-wide transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 rounded-[var(--radius-field)] border-[length:var(--border)] h-[var(--h-field-sm)] px-[var(--px-field-sm)] text-[length:var(--text-field-sm)] gap-1.5 bg-primary text-primary-content border-primary hover:bg-primary/90 focus-visible:ring-primary cursor-pointer">Open a tall form</button>
</div>
<template x-teleport="body">
<div x-show="open" x-transition:enter="transition ease-out duration-200" x-transition:enter-start="opacity-0" x-transition:enter-end="opacity-100" x-transition:leave="transition ease-in duration-150" x-transition:leave-start="opacity-100" x-transition:leave-end="opacity-0" class="fixed inset-0 z-50 flex items-center justify-center p-4" x-cloak="">
<div class="absolute inset-0 bg-black/50" @click="open = false"></div>
<div x-show="open" x-transition:enter="transition ease-out duration-200" x-transition:enter-start="opacity-0 scale-95" x-transition:enter-end="opacity-100 scale-100" x-transition:leave="transition ease-in duration-150" x-transition:leave-start="opacity-100 scale-100" x-transition:leave-end="opacity-0 scale-95" x-trap.inert.noscroll="open" @keydown.escape.window="open = false" class="relative w-full max-w-2xl flex flex-col max-h-[calc(100dvh-2rem)] bg-base-100 text-base-content text-[length:var(--text-field-md)] rounded-[var(--radius-box)] border-[length:var(--border)] border-base-300 shadow-[0_10px_30px_-8px_rgb(0_0_0_/_0.18),var(--shadow-box)] p-lg" role="dialog" aria-modal="true" aria-labelledby="modal_6a7e9b5c6ca6c_title">
<div class="flex shrink-0 items-center justify-between mb-sm">
<h3 id="modal_6a7e9b5c6ca6c_title" class="text-[length:var(--text-field-lg)] font-semibold text-base-content">
                        Edit profile
                    </h3><button type="button" @click="open = false" class="text-base-content/50 hover:text-base-content transition-colors rounded-[var(--radius-field)] p-1 hover:bg-base-200" aria-label="Close"><svg class="w-5 h-5" fill="none" viewbox="0 0 24 24" stroke="currentcolor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12"></path></svg></button>
</div>
<div class="min-h-0 overflow-y-auto">
<div class="space-y-3">
<div class="w-full">
<div class="flex items-baseline justify-between mb-1.5">
<label for="input_6a7e9b5c6c565" class="block text-[length:var(--text-field-sm)] font-medium text-base-content">First name</label>
</div>
<div class="flex items-stretch transition-colors rounded-[var(--radius-field)] bg-base-100 tune-border border-base-300 focus-within:border-primary focus-within:ring-1 focus-within:ring-primary h-[var(--h-field-md)]">
<div class="relative flex-1 min-w-0 flex items-stretch">
<input type="text" id="input_6a7e9b5c6c565" class="flex-1 min-w-0 w-full bg-transparent border-0 outline-none placeholder:text-base-content/40 peer text-[length:var(--text-field-md)] px-[var(--px-input-md)]" placeholder="Ada">
</div>
</div>
</div>
<div class="w-full">
<div class="flex items-baseline justify-between mb-1.5">
<label for="input_6a7e9b5c6c5d8" class="block text-[length:var(--text-field-sm)] font-medium text-base-content">Last name</label>
</div>
<div class="flex items-stretch transition-colors rounded-[var(--radius-field)] bg-base-100 tune-border border-base-300 focus-within:border-primary focus-within:ring-1 focus-within:ring-primary h-[var(--h-field-md)]">
<div class="relative flex-1 min-w-0 flex items-stretch">
<input type="text" id="input_6a7e9b5c6c5d8" class="flex-1 min-w-0 w-full bg-transparent border-0 outline-none placeholder:text-base-content/40 peer text-[length:var(--text-field-md)] px-[var(--px-input-md)]" placeholder="Lovelace">
</div>
</div>
</div>
<div class="w-full">
<div class="flex items-baseline justify-between mb-1.5">
<label for="input_6a7e9b5c6c63a" class="block text-[length:var(--text-field-sm)] font-medium text-base-content">Email</label>
</div>
<div class="flex items-stretch transition-colors rounded-[var(--radius-field)] bg-base-100 tune-border border-base-300 focus-within:border-primary focus-within:ring-1 focus-within:ring-primary h-[var(--h-field-md)]">
<div class="relative flex-1 min-w-0 flex items-stretch">
<input type="email" id="input_6a7e9b5c6c63a" class="flex-1 min-w-0 w-full bg-transparent border-0 outline-none placeholder:text-base-content/40 peer text-[length:var(--text-field-md)] px-[var(--px-input-md)]" placeholder="ada@example.com">
</div>
</div>
</div>
<div class="w-full">
<div class="flex items-baseline justify-between mb-1.5">
<label for="input_6a7e9b5c6c697" class="block text-[length:var(--text-field-sm)] font-medium text-base-content">Phone</label>
</div>
<div class="flex items-stretch transition-colors rounded-[var(--radius-field)] bg-base-100 tune-border border-base-300 focus-within:border-primary focus-within:ring-1 focus-within:ring-primary h-[var(--h-field-md)]">
<div class="relative flex-1 min-w-0 flex items-stretch">
<input type="tel" id="input_6a7e9b5c6c697" class="flex-1 min-w-0 w-full bg-transparent border-0 outline-none placeholder:text-base-content/40 peer text-[length:var(--text-field-md)] px-[var(--px-input-md)]" placeholder="+1 555 0100">
</div>
</div>
</div>
<div class="w-full">
<div class="flex items-baseline justify-between mb-1.5">
<label for="input_6a7e9b5c6c6f6" class="block text-[length:var(--text-field-sm)] font-medium text-base-content">Company</label>
</div>
<div class="flex items-stretch transition-colors rounded-[var(--radius-field)] bg-base-100 tune-border border-base-300 focus-within:border-primary focus-within:ring-1 focus-within:ring-primary h-[var(--h-field-md)]">
<div class="relative flex-1 min-w-0 flex items-stretch">
<input type="text" id="input_6a7e9b5c6c6f6" class="flex-1 min-w-0 w-full bg-transparent border-0 outline-none placeholder:text-base-content/40 peer text-[length:var(--text-field-md)] px-[var(--px-input-md)]" placeholder="Analytical Engines Ltd.">
</div>
</div>
</div>
<div class="w-full">
<div class="flex items-baseline justify-between mb-1.5">
<label for="input_6a7e9b5c6c752" class="block text-[length:var(--text-field-sm)] font-medium text-base-content">Job title</label>
</div>
<div class="flex items-stretch transition-colors rounded-[var(--radius-field)] bg-base-100 tune-border border-base-300 focus-within:border-primary focus-within:ring-1 focus-within:ring-primary h-[var(--h-field-md)]">
<div class="relative flex-1 min-w-0 flex items-stretch">
<input type="text" id="input_6a7e9b5c6c752" class="flex-1 min-w-0 w-full bg-transparent border-0 outline-none placeholder:text-base-content/40 peer text-[length:var(--text-field-md)] px-[var(--px-input-md)]" placeholder="Chief Engineer">
</div>
</div>
</div>
<div class="w-full">
<div class="flex items-baseline justify-between mb-1.5">
<label for="input_6a7e9b5c6c7b0" class="block text-[length:var(--text-field-sm)] font-medium text-base-content">Street address</label>
</div>
<div class="flex items-stretch transition-colors rounded-[var(--radius-field)] bg-base-100 tune-border border-base-300 focus-within:border-primary focus-within:ring-1 focus-within:ring-primary h-[var(--h-field-md)]">
<div class="relative flex-1 min-w-0 flex items-stretch">
<input type="text" id="input_6a7e9b5c6c7b0" class="flex-1 min-w-0 w-full bg-transparent border-0 outline-none placeholder:text-base-content/40 peer text-[length:var(--text-field-md)] px-[var(--px-input-md)]" placeholder="12 Byron St.">
</div>
</div>
</div>
<div class="w-full">
<div class="flex items-baseline justify-between mb-1.5">
<label for="input_6a7e9b5c6c807" class="block text-[length:var(--text-field-sm)] font-medium text-base-content">City</label>
</div>
<div class="flex items-stretch transition-colors rounded-[var(--radius-field)] bg-base-100 tune-border border-base-300 focus-within:border-primary focus-within:ring-1 focus-within:ring-primary h-[var(--h-field-md)]">
<div class="relative flex-1 min-w-0 flex items-stretch">
<input type="text" id="input_6a7e9b5c6c807" class="flex-1 min-w-0 w-full bg-transparent border-0 outline-none placeholder:text-base-content/40 peer text-[length:var(--text-field-md)] px-[var(--px-input-md)]" placeholder="London">
</div>
</div>
</div>
<div class="w-full">
<div class="flex items-baseline justify-between mb-1.5">
<label for="input_6a7e9b5c6c85e" class="block text-[length:var(--text-field-sm)] font-medium text-base-content">Postal code</label>
</div>
<div class="flex items-stretch transition-colors rounded-[var(--radius-field)] bg-base-100 tune-border border-base-300 focus-within:border-primary focus-within:ring-1 focus-within:ring-primary h-[var(--h-field-md)]">
<div class="relative flex-1 min-w-0 flex items-stretch">
<input type="text" id="input_6a7e9b5c6c85e" class="flex-1 min-w-0 w-full bg-transparent border-0 outline-none placeholder:text-base-content/40 peer text-[length:var(--text-field-md)] px-[var(--px-input-md)]" placeholder="W1K 1AA">
</div>
</div>
</div>
<div class="w-full">
<div class="flex items-baseline justify-between mb-1.5">
<label for="input_6a7e9b5c6c8b5" class="block text-[length:var(--text-field-sm)] font-medium text-base-content">Country</label>
</div>
<div class="flex items-stretch transition-colors rounded-[var(--radius-field)] bg-base-100 tune-border border-base-300 focus-within:border-primary focus-within:ring-1 focus-within:ring-primary h-[var(--h-field-md)]">
<div class="relative flex-1 min-w-0 flex items-stretch">
<input type="text" id="input_6a7e9b5c6c8b5" class="flex-1 min-w-0 w-full bg-transparent border-0 outline-none placeholder:text-base-content/40 peer text-[length:var(--text-field-md)] px-[var(--px-input-md)]" placeholder="United Kingdom">
</div>
</div>
</div>
<div class="w-full">
<div class="flex items-baseline justify-between mb-1.5">
<label for="input_6a7e9b5c6c90f" class="block text-[length:var(--text-field-sm)] font-medium text-base-content">Website</label>
</div>
<div class="flex items-stretch transition-colors rounded-[var(--radius-field)] bg-base-100 tune-border border-base-300 focus-within:border-primary focus-within:ring-1 focus-within:ring-primary h-[var(--h-field-md)]">
<div class="relative flex-1 min-w-0 flex items-stretch">
<input type="url" id="input_6a7e9b5c6c90f" class="flex-1 min-w-0 w-full bg-transparent border-0 outline-none placeholder:text-base-content/40 peer text-[length:var(--text-field-md)] px-[var(--px-input-md)]" placeholder="https://example.com">
</div>
</div>
</div>
<div class="w-full">
<div class="flex items-baseline justify-between mb-1.5">
<label for="textarea_6a7e9b5c6c968" class="block text-[length:var(--text-field-sm)] font-medium text-base-content">Bio</label>
</div>
<div class="block transition-colors rounded-[var(--radius-field)] bg-base-100 tune-border border-base-300 focus-within:border-primary focus-within:ring-1 focus-within:ring-primary">
<textarea id="textarea_6a7e9b5c6c968" rows="4" class="block w-full bg-transparent border-0 outline-none placeholder:text-base-content/40 tune-textarea-md resize-y" placeholder="A short introduction…"></textarea>
</div>
</div>
</div>
</div>
<div class="flex shrink-0 items-center justify-end gap-xs mt-lg">
<button class="inline-flex items-center justify-center whitespace-nowrap font-medium tracking-wide transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 rounded-[var(--radius-field)] border-[length:var(--border)] h-[var(--h-field-sm)] px-[var(--px-field-sm)] text-[length:var(--text-field-sm)] gap-1.5 bg-transparent text-base-content border-transparent hover:bg-base-200 focus-visible:ring-base-300 cursor-pointer" @click="open = false">Cancel</button>
<button class="inline-flex items-center justify-center whitespace-nowrap font-medium tracking-wide transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 rounded-[var(--radius-field)] border-[length:var(--border)] h-[var(--h-field-sm)] px-[var(--px-field-sm)] text-[length:var(--text-field-sm)] gap-1.5 bg-primary text-primary-content border-primary hover:bg-primary/90 focus-visible:ring-primary cursor-pointer" @click="open = false">Save</button>
</div>
</div>
</div>
</template>
</div>

4. Pass an id and open it via dispatch from any button elsewhere (size: sm/md(default)/lg/xl/full, closed via backdrop click/Escape/×/an actions button's @click='open = false', focus trap via x-trap, rendered under body via x-teleport)

<x-button color="primary" size="sm" x-on:click="$dispatch('open-modal-welcome')">Open the welcome modal</x-button>
<x-button color="info" size="sm" x-on:click="$dispatch('open-modal-confirm-reset')">Open the reset modal</x-button>

<x-modal id="welcome" title="Welcome" size="md">
    <p class="text-sm text-base-content/80">Declared without a trigger slot: it is opened purely by dispatching <code class="text-xs">open-modal-welcome</code>.</p>
    <x-slot:actions>
        <x-button size="sm" @click="open = false">Close</x-button>
    </x-slot:actions>
</x-modal>

<x-modal id="confirm-reset" title="Reset settings" size="sm" :closeOnBackdrop="false">
    <p class="text-sm text-base-content/80">All settings return to their defaults.</p>
    <x-slot:actions>
        <x-button appearance="ghost" size="sm" @click="open = false">Cancel</x-button>
        <x-button color="warning" size="sm" @click="open = false">Reset</x-button>
    </x-slot:actions>
</x-modal>
<button class="inline-flex items-center justify-center whitespace-nowrap font-medium tracking-wide transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 rounded-[var(--radius-field)] border-[length:var(--border)] h-[var(--h-field-sm)] px-[var(--px-field-sm)] text-[length:var(--text-field-sm)] gap-1.5 bg-primary text-primary-content border-primary hover:bg-primary/90 focus-visible:ring-primary cursor-pointer" x-on:click="$dispatch('open-modal-welcome')">Open the welcome modal</button>
<button class="inline-flex items-center justify-center whitespace-nowrap font-medium tracking-wide transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 rounded-[var(--radius-field)] border-[length:var(--border)] h-[var(--h-field-sm)] px-[var(--px-field-sm)] text-[length:var(--text-field-sm)] gap-1.5 bg-info text-info-content border-info hover:bg-info/90 focus-visible:ring-info cursor-pointer" x-on:click="$dispatch('open-modal-confirm-reset')">Open the reset modal</button>
<div x-data="{ open: false }" x-on:open-modal-welcome.window="open = true" x-on:close-modal-welcome.window="open = false">
<template x-teleport="body">
<div x-show="open" x-transition:enter="transition ease-out duration-200" x-transition:enter-start="opacity-0" x-transition:enter-end="opacity-100" x-transition:leave="transition ease-in duration-150" x-transition:leave-start="opacity-100" x-transition:leave-end="opacity-0" class="fixed inset-0 z-50 flex items-center justify-center p-4" x-cloak="">
<div class="absolute inset-0 bg-black/50" @click="open = false"></div>
<div x-show="open" x-transition:enter="transition ease-out duration-200" x-transition:enter-start="opacity-0 scale-95" x-transition:enter-end="opacity-100 scale-100" x-transition:leave="transition ease-in duration-150" x-transition:leave-start="opacity-100 scale-100" x-transition:leave-end="opacity-0 scale-95" x-trap.inert.noscroll="open" @keydown.escape.window="open = false" class="relative w-full max-w-lg flex flex-col max-h-[calc(100dvh-2rem)] bg-base-100 text-base-content text-[length:var(--text-field-md)] rounded-[var(--radius-box)] border-[length:var(--border)] border-base-300 shadow-[0_10px_30px_-8px_rgb(0_0_0_/_0.18),var(--shadow-box)] p-lg" role="dialog" aria-modal="true" aria-labelledby="welcome_title">
<div class="flex shrink-0 items-center justify-between mb-sm">
<h3 id="welcome_title" class="text-[length:var(--text-field-lg)] font-semibold text-base-content">
                        Welcome
                    </h3><button type="button" @click="open = false" class="text-base-content/50 hover:text-base-content transition-colors rounded-[var(--radius-field)] p-1 hover:bg-base-200" aria-label="Close"><svg class="w-5 h-5" fill="none" viewbox="0 0 24 24" stroke="currentcolor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12"></path></svg></button>
</div>
<div class="min-h-0 overflow-y-auto">
<p class="text-sm text-base-content/80">
                        Declared without a trigger slot: it is opened purely by dispatching <code class="text-xs">open-modal-welcome</code>.
                    </p>
</div>
<div class="flex shrink-0 items-center justify-end gap-xs mt-lg">
<button class="inline-flex items-center justify-center whitespace-nowrap font-medium tracking-wide transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 rounded-[var(--radius-field)] border-[length:var(--border)] h-[var(--h-field-sm)] px-[var(--px-field-sm)] text-[length:var(--text-field-sm)] gap-1.5 bg-primary text-primary-content border-primary hover:bg-primary/90 focus-visible:ring-primary cursor-pointer" @click="open = false">Close</button>
</div>
</div>
</div>
</template>
</div>
<div x-data="{ open: false }" x-on:open-modal-confirm-reset.window="open = true" x-on:close-modal-confirm-reset.window="open = false">
<template x-teleport="body">
<div x-show="open" x-transition:enter="transition ease-out duration-200" x-transition:enter-start="opacity-0" x-transition:enter-end="opacity-100" x-transition:leave="transition ease-in duration-150" x-transition:leave-start="opacity-100" x-transition:leave-end="opacity-0" class="fixed inset-0 z-50 flex items-center justify-center p-4" x-cloak="">
<div class="absolute inset-0 bg-black/50"></div>
<div x-show="open" x-transition:enter="transition ease-out duration-200" x-transition:enter-start="opacity-0 scale-95" x-transition:enter-end="opacity-100 scale-100" x-transition:leave="transition ease-in duration-150" x-transition:leave-start="opacity-100 scale-100" x-transition:leave-end="opacity-0 scale-95" x-trap.inert.noscroll="open" @keydown.escape.window="open = false" class="relative w-full max-w-sm flex flex-col max-h-[calc(100dvh-2rem)] bg-base-100 text-base-content text-[length:var(--text-field-md)] rounded-[var(--radius-box)] border-[length:var(--border)] border-base-300 shadow-[0_10px_30px_-8px_rgb(0_0_0_/_0.18),var(--shadow-box)] p-lg" role="dialog" aria-modal="true" aria-labelledby="confirm-reset_title">
<div class="flex shrink-0 items-center justify-between mb-sm">
<h3 id="confirm-reset_title" class="text-[length:var(--text-field-lg)] font-semibold text-base-content">
                        Reset settings
                    </h3><button type="button" @click="open = false" class="text-base-content/50 hover:text-base-content transition-colors rounded-[var(--radius-field)] p-1 hover:bg-base-200" aria-label="Close"><svg class="w-5 h-5" fill="none" viewbox="0 0 24 24" stroke="currentcolor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12"></path></svg></button>
</div>
<div class="min-h-0 overflow-y-auto">
<p class="text-sm text-base-content/80">
                        All settings return to their defaults.
                    </p>
</div>
<div class="flex shrink-0 items-center justify-end gap-xs mt-lg">
<button class="inline-flex items-center justify-center whitespace-nowrap font-medium tracking-wide transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 rounded-[var(--radius-field)] border-[length:var(--border)] h-[var(--h-field-sm)] px-[var(--px-field-sm)] text-[length:var(--text-field-sm)] gap-1.5 bg-transparent text-base-content border-transparent hover:bg-base-200 focus-visible:ring-base-300 cursor-pointer" @click="open = false">Cancel</button>
<button class="inline-flex items-center justify-center whitespace-nowrap font-medium tracking-wide transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 rounded-[var(--radius-field)] border-[length:var(--border)] h-[var(--h-field-sm)] px-[var(--px-field-sm)] text-[length:var(--text-field-sm)] gap-1.5 bg-warning text-warning-content border-warning hover:bg-warning/90 focus-visible:ring-warning cursor-pointer" @click="open = false">Reset</button>
</div>
</div>
</div>
</template>
</div>