Components
Dialog
A window overlaid on the primary window, rendering the content underneath inert.
Edit profile
Make changes to your profile here. Click save when you're done.
<x-ui.dialog>
<x-ui.dialog-trigger>
<x-ui.button variant="outline">Edit Profile</x-ui.button>
</x-ui.dialog-trigger>
<x-ui.dialog-content class="sm:max-w-[425px]">
<x-ui.dialog-header>
<x-ui.dialog-title>Edit profile</x-ui.dialog-title>
<x-ui.dialog-description>
Make changes to your profile here. Click save when you're done.
</x-ui.dialog-description>
</x-ui.dialog-header>
<div class="grid gap-4 py-2">
<div class="grid gap-2">
<x-ui.label for="name">Name</x-ui.label>
<x-ui.input id="name" value="Pedro Duarte" />
</div>
<div class="grid gap-2">
<x-ui.label for="username">Username</x-ui.label>
<x-ui.input id="username" value="@peduarte" />
</div>
</div>
<x-ui.dialog-footer>
<x-ui.button type="submit">Save changes</x-ui.button>
</x-ui.dialog-footer>
</x-ui.dialog-content>
</x-ui.dialog>
Confirmation
Are you absolutely sure?
This action cannot be undone. This will permanently delete your account and remove your data from our servers.
<x-ui.dialog>
<x-ui.dialog-trigger>
<x-ui.button variant="outline">Delete account</x-ui.button>
</x-ui.dialog-trigger>
<x-ui.dialog-content class="sm:max-w-[425px]">
<x-ui.dialog-header>
<x-ui.dialog-title>Are you absolutely sure?</x-ui.dialog-title>
<x-ui.dialog-description>
This action cannot be undone. This will permanently delete your account and remove your data from our servers.
</x-ui.dialog-description>
</x-ui.dialog-header>
<x-ui.dialog-footer>
<x-ui.dialog-close>
<x-ui.button variant="outline">Cancel</x-ui.button>
</x-ui.dialog-close>
<x-ui.button variant="destructive">Delete account</x-ui.button>
</x-ui.dialog-footer>
</x-ui.dialog-content>
</x-ui.dialog>
Dispatchable
Remove member
Remove from the team? This can't be undone.
{{-- Dispatchable mode (id="..."). The "Remove" trigger lives inside a @foreach, but there
is ONE shared dialog defined once below — no per-row modal markup, no scope coupling.
The trigger opens it from anywhere with $dispatch('open-dialog-{id}'); pass row context
in the event detail and capture it on dialog-content. Close from anywhere with
$dispatch('close-dialog-{id}'). --}}
<div class="w-full max-w-sm space-y-2">
@foreach (['Alice Martin', 'Bob Dupont', 'Carol Nguyen'] as $member)
<div class="flex items-center justify-between rounded-md border px-3 py-2 text-sm">
<span>{{ $member }}</span>
<x-ui.button
variant="outline"
size="sm"
x-data
data-name="{{ $member }}"
x-on:click="$dispatch('open-dialog-member', { name: $el.dataset.name })"
>Remove</x-ui.button>
</div>
@endforeach
{{-- Defined once — shared by every row above. --}}
<x-ui.dialog id="member">
<x-ui.dialog-content x-data="{ name: '' }" @open-dialog-member.window="name = $event.detail?.name || ''">
<x-ui.dialog-header>
<x-ui.dialog-title>Remove member</x-ui.dialog-title>
<x-ui.dialog-description>
Remove <span class="text-foreground font-medium" x-text="name"></span> from the team? This can't be undone.
</x-ui.dialog-description>
</x-ui.dialog-header>
<x-ui.dialog-footer>
<x-ui.button variant="outline" x-on:click="$dispatch('close-dialog-member')">Cancel</x-ui.button>
<x-ui.button variant="destructive" x-on:click="$dispatch('close-dialog-member')">Remove</x-ui.button>
</x-ui.dialog-footer>
</x-ui.dialog-content>
</x-ui.dialog>
</div>
Feedback
Submit feedback
Tell us what's working well or what could be better.
<x-ui.dialog>
<x-ui.dialog-trigger>
<x-ui.button variant="outline"><x-lucide-message-square aria-hidden="true" /> Submit feedback</x-ui.button>
</x-ui.dialog-trigger>
<x-ui.dialog-content class="sm:max-w-[425px]">
<x-ui.dialog-header>
<x-ui.dialog-title>Submit feedback</x-ui.dialog-title>
<x-ui.dialog-description>Tell us what's working well or what could be better.</x-ui.dialog-description>
</x-ui.dialog-header>
<div class="flex flex-col gap-4 py-2">
<x-ui.field>
<x-ui.field-label for="fb-title">Title</x-ui.field-label>
<x-ui.input id="fb-title" placeholder="Short summary" />
</x-ui.field>
<x-ui.field>
<x-ui.field-label for="fb-type">Type</x-ui.field-label>
<x-ui.select>
<x-ui.select-trigger id="fb-type" class="w-full"><x-ui.select-value placeholder="Select a type" /></x-ui.select-trigger>
<x-ui.select-content>
<x-ui.select-item value="bug">Bug report</x-ui.select-item>
<x-ui.select-item value="idea">Idea</x-ui.select-item>
<x-ui.select-item value="question">Question</x-ui.select-item>
<x-ui.select-item value="other">Other</x-ui.select-item>
</x-ui.select-content>
</x-ui.select>
</x-ui.field>
<x-ui.field>
<x-ui.field-label for="fb-desc">Description</x-ui.field-label>
<x-ui.textarea id="fb-desc" placeholder="Describe it in a little more detail…" />
</x-ui.field>
</div>
<x-ui.dialog-footer>
<x-ui.dialog-close>
<x-ui.button variant="outline">Cancel</x-ui.button>
</x-ui.dialog-close>
<x-ui.button>Send feedback</x-ui.button>
</x-ui.dialog-footer>
</x-ui.dialog-content>
</x-ui.dialog>
Fullscreen
Full-screen dialog
An edge-to-edge takeover — ideal on mobile, or for focused editing and media.
{{-- Pass `fullscreen` to dialog-content for an edge-to-edge takeover (mobile, editors, viewers). --}}
<x-ui.dialog>
<x-ui.dialog-trigger>
<x-ui.button variant="outline">Open full-screen</x-ui.button>
</x-ui.dialog-trigger>
<x-ui.dialog-content fullscreen>
<div class="mx-auto flex w-full max-w-2xl flex-1 flex-col gap-6">
<x-ui.dialog-header>
<x-ui.dialog-title>Full-screen dialog</x-ui.dialog-title>
<x-ui.dialog-description>
An edge-to-edge takeover — ideal on mobile, or for focused editing and media.
</x-ui.dialog-description>
</x-ui.dialog-header>
<div class="flex-1 space-y-4">
<div class="grid gap-2">
<x-ui.label for="fs-title">Title</x-ui.label>
<x-ui.input id="fs-title" placeholder="Untitled document" />
</div>
<div class="grid gap-2">
<x-ui.label for="fs-body">Body</x-ui.label>
<x-ui.textarea id="fs-body" rows="6" placeholder="Write something…" />
</div>
</div>
<x-ui.dialog-footer>
<x-ui.button variant="outline" @click="open = false">Cancel</x-ui.button>
<x-ui.button @click="open = false">Save</x-ui.button>
</x-ui.dialog-footer>
</div>
</x-ui.dialog-content>
</x-ui.dialog>
Positioned
Top left
This dialog is anchored to the Top left of the screen.
Top
This dialog is anchored to the Top of the screen.
Top right
This dialog is anchored to the Top right of the screen.
Center
This dialog is anchored to the Center of the screen.
Bottom left
This dialog is anchored to the Bottom left of the screen.
Bottom
This dialog is anchored to the Bottom of the screen.
Bottom right
This dialog is anchored to the Bottom right of the screen.
{{-- Dialogs anchored to different edges/corners via the `position` prop. --}}
<div class="flex flex-wrap items-center gap-2">
@foreach (['top-left' => 'Top left', 'top' => 'Top', 'top-right' => 'Top right', 'center' => 'Center', 'bottom-left' => 'Bottom left', 'bottom' => 'Bottom', 'bottom-right' => 'Bottom right'] as $pos => $label)
<x-ui.dialog>
<x-ui.dialog-trigger>
<x-ui.button variant="outline" size="sm">{{ $label }}</x-ui.button>
</x-ui.dialog-trigger>
<x-ui.dialog-content position="{{ $pos }}" class="sm:max-w-sm">
<x-ui.dialog-header>
<x-ui.dialog-title>{{ $label }}</x-ui.dialog-title>
<x-ui.dialog-description>This dialog is anchored to the <strong>{{ $label }}</strong> of the screen.</x-ui.dialog-description>
</x-ui.dialog-header>
<x-ui.dialog-footer>
<x-ui.button @click="open = false">Got it</x-ui.button>
</x-ui.dialog-footer>
</x-ui.dialog-content>
</x-ui.dialog>
@endforeach
</div>
Scroll
Terms of Service
Please review our terms before continuing.
By accessing this service you agree to be bound by these terms and all applicable laws and regulations.
You may not use the materials for any commercial purpose without prior written consent.
The materials are provided on an "as is" basis without warranties of any kind, either express or implied.
In no event shall we be liable for any damages arising out of the use or inability to use the materials.
We may revise these terms at any time without notice. By using this service you agree to be bound by the current version.
These terms are governed by and construed in accordance with applicable law.
<x-ui.dialog>
<x-ui.dialog-trigger>
<x-ui.button variant="outline">View terms</x-ui.button>
</x-ui.dialog-trigger>
<x-ui.dialog-content class="sm:max-w-[480px]">
<x-ui.dialog-header>
<x-ui.dialog-title>Terms of Service</x-ui.dialog-title>
<x-ui.dialog-description>Please review our terms before continuing.</x-ui.dialog-description>
</x-ui.dialog-header>
<div class="text-muted-foreground flex max-h-[50vh] flex-col gap-3 overflow-y-auto pr-2 text-sm">
<p>By accessing this service you agree to be bound by these terms and all applicable laws and regulations.</p>
<p>You may not use the materials for any commercial purpose without prior written consent.</p>
<p>The materials are provided on an "as is" basis without warranties of any kind, either express or implied.</p>
<p>In no event shall we be liable for any damages arising out of the use or inability to use the materials.</p>
<p>We may revise these terms at any time without notice. By using this service you agree to be bound by the current version.</p>
<p>These terms are governed by and construed in accordance with applicable law.</p>
</div>
<x-ui.dialog-footer>
<x-ui.dialog-close>
<x-ui.button variant="outline">Decline</x-ui.button>
</x-ui.dialog-close>
<x-ui.button>Accept</x-ui.button>
</x-ui.dialog-footer>
</x-ui.dialog-content>
</x-ui.dialog>
API Reference
Props, slots and exposed methods for
<x-ui.dialog>.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
open |
bool
|
false
|
Initial open state of the dialog on first render. |
id |
string
|
— | Enables "dispatchable" mode: the dialog also opens/closes from anywhere via $dispatch('open-dialog-{id}') / $dispatch('close-dialog-{id}'). Lets a trigger inside a loop or partial drive a single shared modal defined elsewhere (pair with <x-ui.dialog-trigger for="{id}">). |
showClose |
bool
|
true
|
Set on <x-ui.dialog-content>. Render the built-in top-right close (X) button. |
fullscreen |
bool
|
false
|
Set on <x-ui.dialog-content>. Render the dialog edge-to-edge (inset-0) instead of a centered box — useful for mobile-style takeovers, editors, and media viewers. |
position |
string
|
'center'
|
Set on <x-ui.dialog-content>. Where the box sits within the viewport.
center
top
bottom
left
right
top-left
top-right
bottom-left
bottom-right
|
for |
string
|
— | Set on <x-ui.dialog-trigger>. Opens a dispatchable dialog defined elsewhere (matching its id) instead of one in the same scope. |
Slots
| Slot | Description |
|---|---|
default |
Holds the <x-ui.dialog-trigger> and <x-ui.dialog-content>. The root only manages open state. |
trigger |
The clickable element that opens the dialog, wrapped in <x-ui.dialog-trigger>. |
content |
The modal panel (<x-ui.dialog-content>), teleported to <body>. Compose it from <x-ui.dialog-header> (with <x-ui.dialog-title> + <x-ui.dialog-description>), your body, and <x-ui.dialog-footer>. |
close |
Wrap any element in <x-ui.dialog-close> to make it dismiss the dialog (in addition to the built-in X, Escape, and overlay click). |