useDialog
@volvo-cars/react-headless v0.25.1
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.