fix(ui): reopen a popout clicked while it is closing (#3318)

This commit is contained in:
Hampus authored and GitHub committed 2026-10-08 20:33:04 +02:00
1 parent a6a9789091
commit acc1392a53
4 files changed
+19 -6

No files matched your search

@@ -309,7 +309,7 @@ export const Popout = React.forwardRef<HTMLElement, PopoutProps>((props, ref) =>
);
const toggle = useCallback(
(clickPos?: number) => {
if (PopoutState.isOpen(state.id)) {
if (PopoutState.isOpen(state.id) && !PopoutState.isClosing(state.id)) {
if (props.hoverDelay != null && openModeRef.current === 'hover') {
clearTimers();
open(clickPos, 'click');
@@ -240,11 +240,21 @@ const PopoutItem: React.FC<PopoutItemProps> = observer(
setTargetInDOM(true);
}
}, [target, ownerDocument, keepOpenOnTargetUnmount, beginClose]);
const wasClosingRequestedRef = useRef(isClosingRequested);
useEffect(() => {
const wasClosingRequested = wasClosingRequestedRef.current;
wasClosingRequestedRef.current = isClosingRequested;
if (isClosingRequested) {
beginClose();
return;
}
}, [isClosingRequested, beginClose]);
if (!wasClosingRequested) return;
if (closeTimerRef.current != null && ownerWindow != null) {
ownerWindow.clearTimeout(closeTimerRef.current);
closeTimerRef.current = null;
}
setIsVisible(true);
}, [isClosingRequested, beginClose, ownerWindow]);
useEffect(() => {
return () => {
if (closeTimerRef.current != null && ownerWindow != null) {
@@ -460,7 +470,7 @@ export const Popouts: React.FC<PopoutsProps> = observer(({ownerDocument}) => {
const portalHost = scopePortalHostToDocument(activePortalHost, scopeDocument);
const popouts = PopoutState.getPopouts(scopeDocument);
const topPopout = popouts.length ? popouts[popouts.length - 1] : null;
const needsBackdrop = Boolean(topPopout && !topPopout.disableBackdrop);
const needsBackdrop = PopoutState.requiresBackdrop(scopeDocument);
useEffect(() => {
const currentKeys = new Set(popouts.map((popout) => popout.key.toString()));
const prevKeys = prevPopoutKeysRef.current;
@@ -218,6 +218,11 @@ class Popout {
);
}
requiresBackdrop(ownerDocument: Document = document): boolean {
const owner = this.getPopouts(ownerDocument).findLast((popout) => !this.isClosing(popout.key));
return owner != null && !owner.disableBackdrop;
}
private getParentPopoutChain(dependsOnKey: string): Record<string, PopoutDefinition> {
const result: Record<string, PopoutDefinition> = {};
let currentKey: string | undefined = dependsOnKey;