Library · Foundations
Modal
Accessible modal dialog (native <dialog>) with focus trapping, Escape/backdrop dismissal, and view-transition-safe trigger binding; expose window.closeModal() to close programmatically. Requires a trigger element with a matching id to exist in the DOM before render or the component throws.
Figma: Primitives / Modal ↗---
import Modal from "../components/primitives/modal/Modal.astro";
import Button from "../components/primitives/button/Button.astro";
---
<Button id="modal-story-trigger" type="primary">Open modal</Button>
<Modal triggerId="modal-story-trigger" title="Example modal">
<p>
This is example modal content. Press <kbd>Escape</kbd> or click the
backdrop outside this dialog to close it.
</p>
</Modal> Props
| Name | Type | Required | Description |
|---|---|---|---|
class | string | — | Additional classes to apply to the modal |
title | string | Yes | Modal title |
triggerId | string | Yes | ID of the trigger element |
closeText | string | — | Close button text (default: "Close") |
closeIcon | boolean | — | Whether to show close icon (default: true) |
headingSize | 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | — | Visual size of the heading (can differ from semantic level) (default: "h2" (maintains previous 1.5rem visual size)) |
[key: string] | string | number | boolean | undefined | — | HTML attributes to spread on the modal |
Example with all props
<Button id="signup-modal-trigger" type="primary">Register interest</Button>
<Modal
class="signup-modal"
triggerId="signup-modal-trigger"
title="Register your interest"
closeText="Dismiss"
closeIcon={false}
headingSize="h3"
data-analytics="signup-modal"
>
<p>Modal body content goes in the default slot.</p>
<!-- Close programmatically with window.closeModal() -->
</Modal>