Skip to content

Commit 534f562

Browse files
committed
fix(Modal): single overlay close handling and prevent re-open/effect loop
1 parent 055922a commit 534f562

1 file changed

Lines changed: 12 additions & 1 deletion

File tree

src/components/Modal/GlobalModal.tsx

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,19 +24,25 @@ export const GlobalModal = ({
2424
const isOpen = useModalDialogIsOpen();
2525
const innerRef = useRef<HTMLDivElement | null>(null);
2626
const closeButtonRef = useRef<HTMLButtonElement | null>(null);
27+
const closingRef = useRef(false);
2728

2829
const maybeClose = useCallback(
2930
(source: ModalCloseSource, event: ModalCloseEvent) => {
3031
const allow = onCloseAttempt?.(source, event);
3132
if (allow !== false) {
3233
onClose?.(event);
3334
dialog.close();
35+
closingRef.current = true;
3436
}
3537
},
3638
[dialog, onClose, onCloseAttempt],
3739
);
3840

3941
const handleClick = (event: React.MouseEvent<HTMLButtonElement | HTMLDivElement>) => {
42+
// Prevent DialogPortalDestination overlay from handling any click (closeAll).
43+
// Ensures overlay/button close is fully controlled by onCloseAttempt/onClose.
44+
event.stopPropagation();
45+
4046
const target = event.target as HTMLButtonElement | HTMLDivElement;
4147
if (innerRef.current?.contains(target)) return;
4248

@@ -58,8 +64,13 @@ export const GlobalModal = ({
5864
return () => document.removeEventListener('keydown', handleKeyDown);
5965
}, [isOpen, maybeClose, open]);
6066

67+
// Sync open prop → dialog open. Don't close here (dialog ref changes after close → effect loop).
68+
// closingRef blocks re-open when we just closed and parent hasn't set open=false yet.
6169
useEffect(() => {
62-
if (open && !isOpen) {
70+
if (!open) {
71+
closingRef.current = false;
72+
}
73+
if (open && !isOpen && !closingRef.current) {
6374
dialog.open();
6475
}
6576
}, [dialog, isOpen, open]);

0 commit comments

Comments
 (0)