The dialog component is used for all modals. It renders on top of the rest of the app with an overlay.
You'll need to manage the isOpen
state in a wrapper component of your own and pass in a function to be used to close the Dialog. For documentation purposes only we've created a mock State
to handle this, but you should handle the state in the component you consume Dialog
in or in a wrapper component.
A few considerations must be made to ensure your use of the Dialog
component is accessible:
Always be sure to provide either aria-labelledby
or aria-label
to your Dialog
component. In most cases you should use aria-labelledby
and pass it the id
of your Dialog.Header
. If there is no text in your header, or you chose not to use a header, you can use aria-label
to describe the purpose of the Dialog
.
Be sure to pass a ref to return the focus back to once the Dialog
closes via the returnFocusRef
prop. In most cases this should be the element that opened the Dialog. If you decide to manage focus within your application and want to bypass Primer React Components from doing so when the Dialog
closes, you can omit the returnFocusProp
.
If you're running into z-index issues or are rendering the component inside of an absolutely positioned element, you can wrap your Dialog
in a React Portal.
<State default={false}>{([isOpen, setIsOpen]) => {const returnFocusRef = React.useRef(null)return (<><Button ref={returnFocusRef} onClick={() => setIsOpen(true)}>Open</Button><DialogreturnFocusRef={returnFocusRef}isOpen={isOpen}onDismiss={() => setIsOpen(false)}aria-labelledby="header-id"><Dialog.Header id="header-id">Title</Dialog.Header><Box p={3}><Text fontFamily="sans-serif">Some content</Text></Box></Dialog></>)}}</State>
You can also pass any non-text content into the header:
<State default={false}>{([isOpen, setIsOpen]) => {const returnFocusRef = React.useRef(null)return (<><Button ref={returnFocusRef} onClick={() => setIsOpen(true)}>Open</Button><DialogisOpen={isOpen}returnFocusRef={returnFocusRef}onDismiss={() => setIsOpen(false)}aria-labelledby="label"><Dialog.Header><ZapIcon /></Dialog.Header><Box p={3}><Text id="label" fontFamily="sans-serif">Are you sure you'd like to delete this issue?</Text><Box display="flex" mt={3} justifyContent="flex-end"><Button sx={{mr: 1}}>Cancel</Button><Button variant="danger">Delete</Button></Box></Box></Dialog></>)}}</State>
Name | Type | Default | Description |
---|---|---|---|
isOpen | boolean | Whether or not the dialog is open | |
onDismiss | () => void | Function that will be called when the dialog is closed | |
returnFocusRef | React.RefObject<HTMLElement> | The element to restore focus back to after the `Dialog` is closed | |
initialFocusRef | React.RefObject<HTMLElement> | Element inside of the `Dialog` you'd like to be focused when the Dialog is opened. If nothing is passed to `initialFocusRef` the close button is focused. | |
aria-labelledby | string | Pass an id to use for the aria-label. Use either a `aria-label` or an `aria-labelledby` but not both. | |
aria-label | string | Pass a label to be used to describe the Dialog. Use either a `aria-label` or an `aria-labelledby` but not both. | |
sx | SystemStyleObject | Style overrides to apply to the component. See also overriding styles. |
Name | Type | Default | Description |
---|---|---|---|
sx | SystemStyleObject | Style overrides to apply to the component. See also overriding styles. |