Dialog
Modal interruptions on the native <dialog>: focus stays inside, Escape closes it and the page behind is inert.
Other components
Examples
Confirming a decision
You keep open in state. Escape, a click outside and the Cancel button all close it.
function Confirm() {
const [asking, setAsking] = useState(false);
const deleteProject = () => setAsking(false);
return (
<>
<Action intent="action.delete" onClick={() => setAsking(true)}>Delete project</Action>
<Dialog intent="dialog.confirm" open={asking} onClose={() => setAsking(false)} label="Delete this project?">
<Layout intent="layout.section">
<Text intent="heading.item" as="h2">Delete this project?</Text>
<Text intent="text.body">The project and all its data will be gone for good.</Text>
<Layout intent="layout.actions">
<Action intent="action.cancel" onClick={() => setAsking(false)}>Cancel</Action>
<Action intent="action.delete" onClick={deleteProject}>Delete</Action>
</Layout>
</Layout>
</Dialog>
</>
);
}Intents it renders
One domain, with its own page of neighbours and examples. The intent decides the element; these are the starter intents.
Dialog dialog.*
5 intentsdialog.taskA focused task that blocks the page until done or dismissed: edit settings, compose
<dialog>dialog.confirmAsks the user to confirm or cancel one decision
<dialog>dialog.mediaShows one photo or video large over the dimmed page, with its details beside it: who posted it, the caption, comments. A click outside closes it. On small screens it fills the screen, the photo between its title and its details
<dialog>dialog.readerShows one piece of content over the whole screen: reading an article
<dialog>dialog.drawerA full-height panel that slides in from the side over the dimmed page: site navigation on a small screen. A click outside closes it
<dialog>
Props
Plus its element’s usual attributes (id, onClick, aria-*, data-*). No className or style.
intentrequireddialog.task,dialog.confirmordialog.reader.DialogIntentopenrequiredWhether it is showing. You keep it in state.
booleanonCloserequiredCalled on Escape, a click outside, or when it closes itself.
() => voidlabelrequiredThe accessible name: usually the heading text.
stringchildrenrequiredThe content. It renders only while the dialog is open.
ReactNodeunsafeClassNameBypasses the intent. Needs a
// prongs-unsafe: <reason>comment on the line above, andprongs checkcounts it.string
Rules
Put a heading, the content and a
layout.actionsrow inside.Keep
openin state and set it to false inonClose.