import {Dialog} from '@primer/react/drafts'
The dialog component the Primer implementation of the ARIA design pattern Dialog. A dialog is a type of overlay that can be used for confirming actions, asking for disambiguation, and presenting small forms. They generally allow the user to focus on a quick task without having to navigate to a different page.
Dialogs appear in the page after a direct user interaction. Don't show dialogs on page load or as system alerts.
Dialogs appear centered in the page, with a visible backdrop that dims the rest of the window for focus.
All dialogs should have a title and a close button. Use the title
prop to set the title. The close button is created automatically, but must be handled with an onClose
prop.
Dialogs are modal. Dialogs can be dismissed by clicking on the close button, or by interacting with another button in the overlay. To avoid losing information and missing important messages, clicking outside of the dialog will not close it.
(Coming soon) Make sure larger dialogs remain mobile-friendly. Even large dialogs need to be responsive. A dialog's width and height will be readjusted depending on the screen size and should never exceed the available space. Use responsive solutions to adjust the UI so they behave well on smaller screens.
(Coming soon) Simple and small dialogs can remain as-is on mobile. As more elements are added to it, mobile-specific style variations such as Bottom sheet and Full-screen should be considered.
The dialog component is completely stateless. The parent component must conditionally render a dialog based on the necessary criteria. The parent component can be notified by a gesture to close the dialog (e.g. by clicking the "X" button or by pressing the Escape key) by passing in the onClose
prop.
The dialog component is fully accessible out-of-the-box. The dialog's title is used for aria-labelledby
, and the dialog's description is used for aria-describedby
. The aria-modal="true"
attribute is used to inform screen readers that the rest of the content on the page is inert.
The default keyboard API for a dialog employs three mechanisms:
autoFocus: true
.Note: using custom rendering allows breaking out of the defined design, UX, and accessibility patterns of the dialog. Use only as a last resort.
By default, the Dialog component implements the design and interactions defined by the Primer design system. If necessary, you can provide custom renderers for the header, body, or footer using the renderHeader
, renderBody
, and renderFooter
props, respectively. The JSX produced by these render props will render full-bleed into their respective areas of the dialog. If you are using the custom renderers, you should use the provided sub-components Dialog.Header
, Dialog.Title
, Dialog.Subtitle
, Dialog.CloseButton
, Dialog.Body
, Dialog.Footer
, and Dialog.Buttons
to the extent possible.
<State default={false}>{([isOpen, setIsOpen]) => {const openDialog = React.useCallback(() => setIsOpen(true), [setIsOpen])const closeDialog = React.useCallback(() => setIsOpen(false), [setIsOpen])return (<><Button onClick={openDialog}>Open</Button>{isOpen && (<Dialogtitle="Dialog example"subtitle={<>This is a <b>description</b> of the dialog.</>}footerButtons={[{content: 'Ok', onClick: closeDialog}]}onClose={closeDialog}><Text fontFamily="sans-serif">Some content</Text></Dialog>)}</>)}}</State>
Prop name | Type | Default | Description |
---|---|---|---|
title | React.ReactNode | "Dialog" | Sets the title of the dialog, which by default is also used as the aria-labelledby attribute. |
subtitle | React.ReactNode | Optional. Sets the subtitle of the dialog, which by default is also used as the aria-describedby attribute. | |
renderHeader | (props: DialogHeaderProps) => JSX.Element | Optional. Custom render the dialog header. See "Custom rendering" above for more info. | |
renderBody | (props: DialogProps) => JSX.Element | Optional. Custom render the dialog body. See "Custom rendering" above for more info. | |
renderFooter | (props: DialogProps) => JSX.Element | Optional. Custom render the dialog footer. See "Custom rendering" above for more info. | |
footerButtons | DialogButtonProps[] | Optional. Specify buttons that will be rendered in the footer of the dialog. | |
onClose | (gesture: 'close-button' │ 'escape') => void | Required. This method is invoked when a gesture to close the dialog is used (either an Escape key press or clicking the "X" in the top-right corner). The gesture argument indicates the gesture that was used to close the dialog (either 'close-button' or 'escape'). | |
role | "dialog" │ "alertdialog" | "dialog" | The ARIA role given to the dialog element. More info: dialog, alertdialog |
width | "small" │ "medium" │ "large" │ "xlarge" | "xlarge" | The fixed width of the dialog. |
height | "small" │ "large" │ "auto" | "auto" | The fixed height of the dialog, or, auto to adjust the height based on its contents. |
sx | SystemStyleObject | {} | Style to be applied to the component |
The DialogHeaderProps
interface extends DialogProps
and adds these additional properties:
Prop name | Type | Description |
---|---|---|
dialogLabelId | string | ID of the element that will be used as the aria-labelledby attribute on the dialog. This ID should be set to the element that renders the dialog's title. |
dialogDescriptionId | string | ID of the element that will be used as the aria-describedby attribute on the dialog. This ID should be set to the element that renders the dialog's subtitle. |
The DialogButtonProps
interface extends ButtonProps
(see Button) and adds these additional properties:
Prop name | Type | Default | Description |
---|---|---|---|
buttonType | "normal" │ "primary" │ "danger" | Button | The type of button to render |
content | React.ReactNode | Required. The button's inner content. | |
autoFocus | boolean | false | If true, this button will be automatically focused when the dialog is first rendered. If autoFocus is true on subsequent button definitions, it will be ignored. |
A ConfirmationDialog
is a special kind of dialog with more rigid behavior. It is used to confirm a user action. ConfirmationDialog
s always have exactly two buttons: one to cancel the action and one to confirm it. No custom rendering capabilities are provided for ConfirmationDialog.
An alternate way to use ConfirmationDialog
is with the useConfirm()
hook. It takes no parameters and returns an async
function, confirm
. When confirm
is called (see ConfirmOptions below for its argument), it shows the confirmation dialog. When the dialog is dismissed, a promise is resolved with true
or false
depending on whether or not the confirm button was used.
useConfirm
hook)function ShorthandExample2() {const confirm = useConfirm()const buttonClick = React.useCallback(async function (e) {if (await confirm({title: 'Are you sure?', content: 'You must confirm this action to continue.'})) {e.target.textContent = 'Confirmed!'}},[confirm])return (<><Button onClick={buttonClick}>Confirmable action</Button></>)}render(<ShorthandExample2 />)
ConfirmationDialog
component)<State default={false}>{([isOpen, setIsOpen]) => {const openDialog = React.useCallback(() => setIsOpen(true), [setIsOpen])const closeDialog = React.useCallback(() => setIsOpen(false), [setIsOpen])return (<><Button onClick={openDialog}>Open</Button>{isOpen && (<ConfirmationDialog title="Confirm action?" onClose={closeDialog}>Are you sure you want to confirm this action?</ConfirmationDialog>)}</>)}}</State>
Prop name | Type | Default | Description |
---|---|---|---|
title | React.ReactNode | Required. Sets the title of the dialog, which by default is also used as the aria-labelledby attribute. | |
onClose | (gesture: 'confirm' │ 'cancel' │ 'close-button' │ 'escape') => void | Required. This callback is invoked when a gesture to close the dialog is performed. The first argument indicates the gesture. | |
cancelButtonContent | React.ReactNode | "Cancel" | The content to use for the cancel button. |
confirmButtonContent | React.ReactNode | "OK" | The content to use for the confirm button. |
confirmButtonType | "normal" │ "primary" │ "danger" | Button | The type of button to use for the confirm button. |
Prop name | Type | Default | Description |
---|---|---|---|
title | React.ReactNode | Required. Sets the title of the dialog, which by default is also used as the aria-labelledby attribute. | |
content | React.ReactNode | Required. Used as the body of the ConfirmationDialog that is displayed. | |
cancelButtonContent | React.ReactNode | "Cancel" | The content to use for the cancel button. |
confirmButtonContent | React.ReactNode | "OK" | The content to use for the confirm button. |
confirmButtonType | "normal" │ "primary" │ "danger" | Button | The type of button to use for the confirm button. |