Dialog
BetaA modal window that traps focus until it closes.
Create project
Deploy your new project in one click.
---
import Dialog from "@/components/ui/dialog/Dialog.astro";
import DialogTrigger from "@/components/ui/dialog/DialogTrigger.astro";
import DialogContent from "@/components/ui/dialog/DialogContent.astro";
import DialogTitle from "@/components/ui/dialog/DialogTitle.astro";
import DialogDescription from "@/components/ui/dialog/DialogDescription.astro";
import DialogClose from "@/components/ui/dialog/DialogClose.astro";
---
<Dialog id="create-project">
<DialogTrigger variant="primary">Create project</DialogTrigger>
<DialogContent>
<div class="flex flex-col gap-1.5">
<DialogTitle>Create project</DialogTitle>
<DialogDescription>Deploy your new project in one click.</DialogDescription>
</div>
<label class="flex flex-col gap-2 text-[15px] font-medium">
Name
<input
name="name"
placeholder="Name of your project"
class="eris-curve h-11 rounded-field border border-border bg-field px-3.5 font-normal text-foreground placeholder:text-placeholder focus-visible:border-ring focus-visible:outline-none"
/>
</label>
<div class="flex justify-end gap-2">
<DialogClose>Cancel</DialogClose>
<DialogClose variant="primary">Deploy</DialogClose>
</div>
</DialogContent>
</Dialog>Installation
npx eris-ui@latest add dialogpnpm dlx eris-ui@latest add dialogbunx eris-ui@latest add dialogyarn dlx eris-ui@latest add dialogInstalls @zag-js/dialog, @zag-js/vanilla. Also adds button.
Confirmations
For a decision the user must make before going on, use role="alertdialog" and turn off closing on outside click. Escape still closes it.
Delete this project?
This removes every deployment. It cannot be undone.
---
import Dialog from "@/components/ui/dialog/Dialog.astro";
import DialogTrigger from "@/components/ui/dialog/DialogTrigger.astro";
import DialogContent from "@/components/ui/dialog/DialogContent.astro";
import DialogTitle from "@/components/ui/dialog/DialogTitle.astro";
import DialogDescription from "@/components/ui/dialog/DialogDescription.astro";
import DialogClose from "@/components/ui/dialog/DialogClose.astro";
---
<Dialog id="delete-project" role="alertdialog" closeOnInteractOutside={false}>
<DialogTrigger variant="danger">Delete project</DialogTrigger>
<DialogContent>
<div class="flex flex-col gap-1.5">
<DialogTitle>Delete this project?</DialogTitle>
<DialogDescription>This removes every deployment. It cannot be undone.</DialogDescription>
</div>
<div class="flex justify-end gap-2">
<DialogClose variant="secondary">Keep it</DialogClose>
<DialogClose variant="danger">Delete</DialogClose>
</div>
</DialogContent>
</Dialog>Focus on close
Closing the dialog returns focus to the trigger. To send it somewhere else, pass a CSS selector as finalFocus. Use this when the trigger will not be there afterwards, like a delete button in a row that the dialog removes.
<h2 id="projects" tabindex="-1">
Projects
</h2>
<Dialog finalFocus="#projects">
<DialogTrigger variant="danger">Delete project</DialogTrigger>
...
</Dialog>
The target must be focusable, so give a heading or container tabindex="-1".
If the trigger is removed, hidden or disabled when the dialog closes and finalFocus is not set, focus moves to the nearest focusable ancestor of the dialog, or to the page’s <main>. It does not fall to <body>. This only covers changes made before the dialog closes. If you remove the trigger later, after a request finishes for example, set finalFocus.
Keyboard
| Key | Does |
|---|---|
| Enter or Space on the trigger | Opens the dialog and moves focus inside |
| Tab / Shift Tab | Moves between focusable elements, staying inside the dialog |
| Esc | Closes the dialog and returns focus to the trigger |
While the dialog is open, the page behind it does not scroll and screen readers only see the dialog.
Parts
| Component | Renders |
|---|---|
Dialog |
The root. Props: id, default, role, close, final |
Dialog |
The button that opens it. Takes Button’s variant and size |
Dialog |
The backdrop and the dialog panel |
Dialog |
The heading; becomes the dialog’s accessible name |
Dialog |
Supporting text; becomes its accessible description |
Dialog |
A button that closes it. Takes Button’s variant and size |