diff --git a/.changeset/giant-rats-kneel.md b/.changeset/giant-rats-kneel.md new file mode 100644 index 0000000000..6dd13b612f --- /dev/null +++ b/.changeset/giant-rats-kneel.md @@ -0,0 +1,5 @@ +--- +"@digdir/designsystemet-react": patch +--- + +**Dialog**: If the browser supports `closedBy` on ``, we let the browser handle it diff --git a/packages/react/src/components/dialog/dialog.tsx b/packages/react/src/components/dialog/dialog.tsx index 39e0144204..0f6895af2a 100644 --- a/packages/react/src/components/dialog/dialog.tsx +++ b/packages/react/src/components/dialog/dialog.tsx @@ -19,6 +19,8 @@ export type DialogProps = MergeRight< /** * Light dismiss behavior, allowing to close on backdrop click by setting `closedby="any"`. * + * @see https://developer.mozilla.org/en-US/docs/Web/API/HTMLDialogElement/closedBy + * * @default 'closerequest' */ closedby?: 'none' | 'closerequest' | 'any'; @@ -99,6 +101,15 @@ export const Dialog = forwardRef( const handleClosedby = (event: Event) => { if (event.defaultPrevented) return; // Skip if default action is prevented const { clientY: y, clientX: x, target } = event as MouseEvent; + /* Check if clicked element or its closest parent has data-command='close' */ + if (target instanceof Element && event.type === 'click') { + const closeElement = target.closest('[data-command="close"]'); + if (closeElement) return dialog?.close(); + } + + // if the browser supports closedBy, we let the browser handle it + // see https://developer.mozilla.org/en-US/docs/Web/API/HTMLDialogElement/closedBy + if (dialog && 'closedBy' in dialog) return; if (event instanceof KeyboardEvent) return ( @@ -107,12 +118,6 @@ export const Dialog = forwardRef( event.preventDefault() ); // Skip ESC-key if closedby="none" - /* Check if clicked element or its closest parent has data-command='close' */ - if (target instanceof Element) { - const closeElement = target.closest('[data-command="close"]'); - if (closeElement) return dialog?.close(); - } - if (window.getSelection()?.toString()) return; // Fix bug where if you select text spanning two divs it thinks you clicked outside if (dialog && target === dialog && closedby === 'any') { const { top, left, right, bottom } = dialog.getBoundingClientRect(); @@ -151,6 +156,7 @@ export const Dialog = forwardRef( className={cl('ds-dialog', className)} ref={mergedRefs} data-modal={modal} + closedby={closedby} {...rest} > {closeButton !== false && (