From db25587cdf85d408b1c75e46ff39f09711e7a47a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Zasso?= Date: Wed, 13 Dec 2023 16:36:43 +0100 Subject: [PATCH] fix: make Modal's onRequestClose mandatory and call it on close BREAKING-CHANGE: Modal's and ConfirmModal's `onRequestClose` is now mandatory. Note that a Modal has to always be closed (`isOpen` must be set to `false`) when `onRequestClose` is called. This is driven by a change in the HTML spec that ensures a web page cannot indefinitely keep a dialog open. See https://github.com/whatwg/html/pull/9462 and https://bugs.chromium.org/p/chromium/issues/detail?id=1511166#c1 --- src/components/modal/ConfirmModal.tsx | 2 +- src/components/modal/Modal.tsx | 2 +- src/components/modal/useDialog.ts | 20 ++++++++++---------- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/components/modal/ConfirmModal.tsx b/src/components/modal/ConfirmModal.tsx index 56223a29..9d8598cf 100644 --- a/src/components/modal/ConfirmModal.tsx +++ b/src/components/modal/ConfirmModal.tsx @@ -15,7 +15,7 @@ interface ConfirmModalProps { requestCloseOnBackdrop?: boolean; onConfirm: () => void; onCancel?: () => void; - onRequestClose?: () => void; + onRequestClose: () => void; saveText?: string; cancelText?: string; headerColor: string; diff --git a/src/components/modal/Modal.tsx b/src/components/modal/Modal.tsx index f418592b..fb802c7d 100644 --- a/src/components/modal/Modal.tsx +++ b/src/components/modal/Modal.tsx @@ -14,7 +14,7 @@ export interface ModalProps { requestCloseOnEsc?: boolean; hasCloseButton?: boolean; requestCloseOnBackdrop?: boolean; - onRequestClose?: () => void; + onRequestClose: () => void; maxWidth?: number; width?: number; height?: number; diff --git a/src/components/modal/useDialog.ts b/src/components/modal/useDialog.ts index 9a5bcbf2..92a96a98 100644 --- a/src/components/modal/useDialog.ts +++ b/src/components/modal/useDialog.ts @@ -8,20 +8,21 @@ import { } from 'react'; import { useKbsDisableGlobal } from 'react-kbs'; -import { useOnOff } from '../index'; +import { useOnOff } from '../hooks/useOnOff'; interface UseDialogOptions { dialogRef: RefObject; isOpen: boolean; requestCloseOnEsc: boolean; requestCloseOnBackdrop: boolean; - onRequestClose?: () => void; + onRequestClose: () => void; } interface UseDialogReturn { dialogProps: { onClick: MouseEventHandler; onCancel: ReactEventHandler; + onClose: UseDialogOptions['onRequestClose']; }; isModalShown: boolean; } @@ -50,12 +51,11 @@ export function useDialog({ const onCancel = useCallback>( (event) => { - event.preventDefault(); - if (requestCloseOnEsc && onRequestClose) { - onRequestClose(); + if (!requestCloseOnEsc) { + event.preventDefault(); } }, - [onRequestClose, requestCloseOnEsc], + [requestCloseOnEsc], ); const onClick = useCallback>( @@ -77,15 +77,15 @@ export function useDialog({ // Since the dialog has no size of itself, this condition is only // `true` when we click on the backdrop. if (!isInDialog && requestCloseOnBackdrop) { - onRequestClose?.(); + onRequestClose(); } }, - [dialogRef, requestCloseOnBackdrop, onRequestClose], + [requestCloseOnBackdrop, onRequestClose, dialogRef], ); const dialogProps = useMemo( - () => ({ onClick, onCancel }), - [onClick, onCancel], + () => ({ onClick, onCancel, onClose: onRequestClose }), + [onClick, onCancel, onRequestClose], ); return {