Modal
A dialog that opens on top of the page and blocks it until closed. Use it for focused tasks and confirmations; for supporting content next to the trigger, use Popover.
Code
import {CloseIcon} from '@earendil-works/elanor-icons-react';
import {Button, IconButton, Modal, Stack} from '@earendil-works/elanor-react';
export default function ModalDemo() {
return (
<Modal.Root>
<Modal.Trigger render={<Button hierarchy="secondary" />}>Rename project</Modal.Trigger>
<Modal.Portal>
<Modal.Backdrop />
<Modal.Viewport>
<Modal.Popup>
<Stack direction="row" align="start" gap="auto">
<Modal.Title>Rename project</Modal.Title>
<Modal.Close render={<IconButton aria-label="Close" />}>
<CloseIcon />
</Modal.Close>
</Stack>
<Modal.Description>Members see the new name right away.</Modal.Description>
<Modal.Body>The project URL stays the same, so existing links keep working.</Modal.Body>
<Modal.Actions>
<Modal.Close render={<Button />}>Save</Modal.Close>
<Modal.Close render={<Button hierarchy="secondary" />}>Cancel</Modal.Close>
</Modal.Actions>
</Modal.Popup>
</Modal.Viewport>
</Modal.Portal>
</Modal.Root>
);
} Usage
import {Modal} from '@earendil-works/elanor-react';
<Modal.Root>
<Modal.Trigger />
<Modal.Portal>
<Modal.Backdrop />
<Modal.Viewport>
<Modal.Popup>
<Modal.Title />
<Modal.Description />
<Modal.Body />
<Modal.Actions>
<Modal.Close />
</Modal.Actions>
</Modal.Popup>
</Modal.Viewport>
</Modal.Portal>
</Modal.Root>;
The modal moves focus inside, keeps it there, and returns it to the trigger on close. Escape and clicking the backdrop close it.
Modal.Close closes the modal; render it as a Button or an Icon button. Title and Description name and describe the dialog for screen readers.
Static rendering
On pages rendered on the server without React in the browser, use the static parts. Body and Actions stay the same. Bind the behavior once the page has loaded:
<Modal.StaticRoot>
<Modal.StaticTrigger />
<Modal.StaticPopup>
<Modal.StaticTitle />
<Modal.StaticDescription />
<Modal.Body />
<Modal.Actions>
<Modal.StaticClose />
</Modal.Actions>
</Modal.StaticPopup>
</Modal.StaticRoot>
import {createModal, enhance} from '@earendil-works/elanor-react';
enhance({modal: createModal});
The popup is a native modal dialog: the browser traps focus, makes the page inert, and returns focus when it closes. Its buttons open and close it through invoker commands, also without the behavior. The behavior animates opening and closing like the React parts and closes it on Escape and on a press on the backdrop. To close it from a script, call the dialog’s requestClose(), which closes it the same way as Escape. Give StaticRoot an id to open the dialog from other buttons too, with commandfor and command="show-modal".
API
Modal.Root
Accepts Base UI Dialog.Root props.
Modal.Trigger
Accepts Base UI Dialog.Trigger props.
Modal.Portal
Accepts Base UI Dialog.Portal props.
Modal.Backdrop
Accepts Base UI Dialog.Backdrop props.
Modal.Viewport
Accepts Base UI Dialog.Viewport props.
Modal.Popup
Accepts Base UI Dialog.Popup props.
Modal.Title
Accepts Base UI Dialog.Title props.
Modal.Description
Accepts Base UI Dialog.Description props.
Modal.Body
Renders <div>. Accepts its HTML attributes and ref.
Modal.Actions
Renders <div>. Accepts its HTML attributes and ref.
Modal.Close
Accepts Base UI Dialog.Close props.
Modal.StaticRoot
A modal for pages without React in the browser; createModal makes it work. Renders no element.
| Prop | Type | Default | Description |
|---|---|---|---|
id | string | - | The dialog's id, so other buttons can open it with commandfor. Generated by default. |
children | ReactNode | - |
Also accepts HTML attributes and ref.
Modal.StaticTrigger
Renders <button>. Accepts its HTML attributes and ref.
Modal.StaticPopup
The dialog, centered over the page's backdrop.
| Prop | Type | Default | Description |
|---|---|---|---|
data-elanor | string | - | The page's own behaviors for this element, attached after the component's. |
Renders <dialog>. Also accepts its HTML attributes and ref.
Modal.StaticTitle
Renders <h2>. Accepts its HTML attributes and ref.
Modal.StaticDescription
Renders <p>. Accepts its HTML attributes and ref.
Modal.StaticClose
Renders <button>. Accepts its HTML attributes and ref.