useDialog
@volvo-cars/react-headless v0.24.7
Manages native HTML dialog elements in React (MDN dialog docs).
import { useDialog } from '@volvo-cars/react-headless';
const MyComponent = () => { const { dialogProps, showDialog, closeDialog } = useDialog();
return ( <> <button onClick={showDialog}>Open dialog</button> <dialog className="dialog-large" {...dialogProps}> <article slot="main"> <h2>Dialog title</h2> <p>Dialog content</p> </article> <footer slot="footer"> <button onClick={closeDialog}>Close</button> </footer> </dialog> </> );};Controlled dialog
Section titled “Controlled dialog”The state of the dialog can be controlled by passing open and onToggle:
import { useState } from 'react';import { useDialog } from '@volvo-cars/react-headless';
function ControlledDialog() { const [open, setOpen] = useState(false);
const { dialogProps, showDialog, closeDialog } = useDialog({ open, onToggle: ({ open, reason }) => { setOpen(open); console.log('Dialog closed with reason:', reason); }, });
return ( <> <button onClick={showDialog}>Open dialog</button> <dialog className="dialog-large" {...dialogProps}> <article slot="main"> <p>Controlled dialog content</p> </article> <footer slot="footer"> <button onClick={() => closeDialog('confirm')}>Confirm</button> <button onClick={() => closeDialog('cancel')}>Cancel</button> </footer> </dialog> </> );}Non-dismissible dialog
Section titled “Non-dismissible dialog”Prevent the dialog from being dismissed by backdrop click or Escape key:
import { useDialog } from '@volvo-cars/react-headless';
function NonDismissibleDialog() { const { dialogProps, showDialog, closeDialog } = useDialog({ dismissible: false, });
return ( <> <button onClick={showDialog}>Open dialog</button> <dialog className="dialog-large" {...dialogProps}> <article slot="main"> <p>You must click a button to close this dialog.</p> </article> <footer slot="footer"> <button onClick={closeDialog}>Close</button> </footer> </dialog> </> );}Intercept dismiss
Section titled “Intercept dismiss”Use onBeforeDismiss to intercept and optionally prevent dismissal:
import { useDialog } from '@volvo-cars/react-headless';
function ConfirmBeforeClose() { const { dialogProps, showDialog } = useDialog({ onBeforeDismiss: (e) => { if (!confirm('Are you sure you want to close?')) { e.preventDefault(); } }, });
return ( <> <button onClick={showDialog}>Open dialog</button> <dialog className="dialog-large" {...dialogProps}> <article slot="main"> <p>Try to close by clicking the backdrop or pressing Escape.</p> </article> </dialog> </> );}Options
Section titled “Options”useDialog accepts an optional options object:
open— controlled open state. Makes the dialog a controlled component.onToggle— callback called when the dialog is opened or closed. Receives{ target, open, reason }.dismissible— whether the dialog can be dismissed by clicking the backdrop or pressing Escape (default:true)resetScroll— whether to reset scroll position of all scrollable children when opening (default:true)ref— optional existing ref to the dialog element. If not provided, one will be created.onBeforeDismiss— callback that runs before the dialog is dismissed. Calle.preventDefault()to block dismissal.
Returns
Section titled “Returns”The hook returns an object with:
dialogProps— props to spread on the<dialog>elementshowDialog()— opens the dialog as a modal. Returns a promise that resolves when animations finish.closeDialog(returnValue?)— closes the dialog, optionally setting the return value. Returns a promise that resolves when animations finish.