Modal
overlayAn accessible dialog overlay rendered via Solid'sPortal. Manages focus trap, scroll lock, and restore-on-close automatically. Opt into persistent mode to require an explicit action to dismiss.
Preview
Usage
import { Modal, Button } from 'PRIVATE_BETA_PACKAGE_COORDINATE_REDACTED';
const [open, setOpen] = createSignal(false);
<Button onClick={() => setOpen(true)}>Open</Button>
<Modal
open={open()}
onClose={() => setOpen(false)}
title="Confirm action"
footer={<Button onClick={() => setOpen(false)}>OK</Button>}
>
Are you sure?
</Modal>Props
| Prop | Type | Default | Description |
|---|---|---|---|
open | boolean | false | Whether the modal is visible |
onClose | () => void | -- | Called when the modal requests to close |
title | string | -- | Dialog title, sets aria-labelledby |
descriptionId | string | -- | ID for aria-describedby (caller manages element) |
persistent | boolean | false | Prevents backdrop click from closing |
footer | JSX.Element | -- | Optional footer slot for action buttons |
children | JSX.Element | -- | Dialog body content |
Accessibility
- Focus trap: Tab and Shift+Tab cycle within the dialog while open.
- Focus management: First focusable element receives focus on open; focus returns to the trigger on close.
- Keyboard: Esc closes the dialog (including persistent mode).
- ARIA:
role="dialog",aria-modal="true",aria-labelledbylinked to the title. - Scroll lock: Body scroll is locked while the modal is open.
- Motion: Animations honor
prefers-reduced-motionvia CSS.
Do / Don't
Do
Use modals for confirmations, short forms, or actions that require focused attention. Provide a clear title and at least one dismissal path.
Don't
Don't nest modals or use them for long-form content that would be better served by a dedicated page. Avoid removing all close mechanisms.