From d57bb002159c17051a07ad4c4e92de3264ce41fa Mon Sep 17 00:00:00 2001 From: ManishMadan2882 Date: Thu, 24 Sep 2026 20:34:03 +0530 Subject: [PATCH] (fix:widget: Keep a back-button entry while any panel is open --- .../react-widget/src/hooks/useBackDismiss.ts | 32 +++++++++++++++---- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/extensions/react-widget/src/hooks/useBackDismiss.ts b/extensions/react-widget/src/hooks/useBackDismiss.ts index 70eeeaea..272780e1 100644 --- a/extensions/react-widget/src/hooks/useBackDismiss.ts +++ b/extensions/react-widget/src/hooks/useBackDismiss.ts @@ -6,15 +6,33 @@ const HISTORY_MARKER = 'dgptOverlay'; const layers: Array<() => void> = []; let entryPushed = false; let releaseTimer: ReturnType | 0 = 0; +let releasing = false; const ours = () => (window.history.state as Record | null)?.[HISTORY_MARKER] === true; +const arm = () => { + if (entryPushed) return; + entryPushed = true; + if (!ours()) window.history.pushState({ [HISTORY_MARKER]: true }, ''); + window.addEventListener('popstate', handlePopState); +}; + const handlePopState = () => { + if (releasing) { + releasing = false; + entryPushed = ours(); + if (layers.length > 0) arm(); + else if (!entryPushed) + window.removeEventListener('popstate', handlePopState); + return; + } // A host entry stacked above ours pops first, leaving ours in place. entryPushed = ours(); + const remaining = layers.length > 1; layers[layers.length - 1]?.(); + if (remaining) arm(); }; const register = (dismiss: () => void) => { @@ -23,10 +41,7 @@ const register = (dismiss: () => void) => { clearTimeout(releaseTimer); releaseTimer = 0; } - if (entryPushed) return; - entryPushed = true; - window.history.pushState({ [HISTORY_MARKER]: true }, ''); - window.addEventListener('popstate', handlePopState); + arm(); }; const unregister = (dismiss: () => void) => { @@ -38,11 +53,14 @@ const unregister = (dismiss: () => void) => { releaseTimer = setTimeout(() => { releaseTimer = 0; if (layers.length > 0) return; - window.removeEventListener('popstate', handlePopState); - if (!entryPushed) return; entryPushed = false; // Closing by button or overlay would otherwise leave the entry behind. - if (ours()) window.history.back(); + if (ours()) { + releasing = true; + window.history.back(); + return; + } + window.removeEventListener('popstate', handlePopState); }); };