Skip to content

Dialog (Compound Component)

The dialog component informs users about a task and can contain critical information, require decisions, or involve multiple tasks. The Dialog component can be used to create a modal, alert, or other custom dialog and can be fully customized to fit your needs.

No content has been provided for this dialog.
<Dialog.Root>
<Dialog.Content />
<Dialog.Trigger />
</Dialog.Root>

Anatomy

This component is comprised of several elements that work together to create a dialog. The following are the elements that make up the Dialog component.

---
import Dialog from '@/components/elements/dialog/compound-component/Dialog'
---
<Dialog.Root>
<Dialog.Content />
<Dialog.Trigger />
</Dialog.Root>

API Reference

Root

The root element of the Dialog component. This element wraps the content and trigger elements and provides the scripting logic to open and close the dialog.

Content

The content of the Dialog component. This component is based on the <dialog> element and can take in any additional HTML attributes. The following are the custom props that can be passed to the component.

Prop Type Default
hideClose
boolean false

Trigger

The trigger that opens the Dialog component. This element inherits from the Button component.

Prop Type Default
variant
"contained" | "outlined" | "subtle" | "text" "contained"
size
"sm" | "md" | "lg" "md"
title
string
icon
boolean false
href
string
disabled
boolean false

Accessibility

The <Dialog> component leverages the <dialog> element which is natively accessible. The following are some additional accessibility features that are built into the component:

  • Clicking off from the dialog will close it. This is done by listening for a click event on the dialog element and checking if the target is the dialog itself.
  • When the dialog element is opened, the body element will receive the overflow-hidden class to prevent scrolling.
  • When the dialog includes a form, we suggest passing autofocus to the first input field to ensure that the user can start interacting with the form immediately.
  • Ensure forms are validated before submitting. This can be done by adding the required attribute to the input fields and setting the formnovalidate attribute on the cancel button.

Examples

Hide Close Button

You can hide the default close button by passing the hideClose prop to the <Dialog.Content> component.

No content has been provided for this dialog.
<Dialog.Root>
<Dialog.Content hideClose />
<Dialog.Trigger />
</Dialog.Root>

Form Dialog

You can use a dialog to handle form data. The following example demonstrates how to create a custom form dialog using the <Dialog> component.

---
import Button from '@/components/Button.astro'
import TextInput from '@/components/forms/TextInput.astro'
---
<Dialog.Root>
<Dialog.Content>
<form method="dialog" class="grid gap-24">
<div class="flex gap-16 p-2">
<TextInput
label="First Name"
name="first-name"
placeholder="John"
required
inputProps={{ autofocus: true }}
/>
<TextInput
label="Last Name"
name="last-name"
placeholder="Smith"
required
/>
</div>
<footer class="flex items-center justify-end gap-16">
<Button
type="submit"
variant="outlined"
data-dialog="close"
formnovalidate
>Cancel</Button>
<Button type="submit">Submit</Button>
</footer>
</form>
</Dialog.Content>
<Dialog.Trigger />
</Dialog.Root>

Custom Trigger & Dialog

The dialog element can be customized to fit whatever context it is being used in. The following example demonstrates how to create a custom trigger and dialog.

Culpa proident non exercitation eu consequat Lorem ipsum.

<Dialog.Root>
<Dialog.Content class="rounded-lg border-2 border-white bg-gradient-to-r from-indigo-500 from-10% via-sky-500 via-30% to-emerald-500 to-90% p-24">
<div class="flex items-center">
Culpa proident non exercitation eu consequat Lorem ipsum.
</div>
</Dialog.Content>
<Dialog.Trigger class="rounded bg-gradient-to-r from-indigo-500 via-purple-500 to-pink-500 p-8 font-bold !text-white transition hover:bg-gradient-to-tr hover:opacity-85 active:opacity-75">
Open Custom Dialog
</Dialog.Trigger>
</Dialog.Root>

Astro Component

It’s recommended that an element like this is made as a reusable component. In this case, we have put together the following Astro compound component to serve as a blueprint for how you could possibly set up a Dialog component, and what properties to consider.

Dialog.ts
import Root from './Root.astro'
import Content from './Content.astro'
import Trigger from './Trigger.astro'
export default Object.assign({ Root, Content, Trigger })