2 changed files with 44 additions and 11 deletions
@ -0,0 +1,37 @@ |
|||||||
|
/** |
||||||
|
* Radix `Dialog` wraps the overlay in `react-remove-scroll`, which adds `block-interactivity-*` on |
||||||
|
* `document.body` so only dialog “shard” nodes receive pointer events. Programmatic overlays that |
||||||
|
* mount on `document.body` (e.g. Bitcoin Connect `bc-modal`) are not shards; if they appear while |
||||||
|
* that class is still present, the UI can paint on top but ignore all clicks (notably after closing |
||||||
|
* our Zap dialog from a secondary pane / sheet). |
||||||
|
*/ |
||||||
|
export function stripReactRemoveScrollBodyLocks(): void { |
||||||
|
if (typeof document === 'undefined') return |
||||||
|
const body = document.body |
||||||
|
const toRemove: string[] = [] |
||||||
|
body.classList.forEach((c) => { |
||||||
|
if (c.startsWith('block-interactivity-')) toRemove.push(c) |
||||||
|
}) |
||||||
|
for (const c of toRemove) { |
||||||
|
body.classList.remove(c) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** Slightly longer than Radix dialog exit animation (`duration-200` in our `DialogContent`). */ |
||||||
|
export const MS_AFTER_RADIX_DIALOG_FOR_EXTERNAL_MODAL = 280 |
||||||
|
|
||||||
|
/** |
||||||
|
* Call `closeOuterModel` (e.g. close Zap `Dialog`), wait for scroll-lock cleanup when applicable, |
||||||
|
* strip any stuck `block-interactivity-*` on `body`, then run `fn` (typically `launchPaymentModal`). |
||||||
|
*/ |
||||||
|
export function runAfterReleasingRadixScrollLock( |
||||||
|
closeOuterModel: (() => void) | undefined, |
||||||
|
fn: () => void |
||||||
|
): void { |
||||||
|
closeOuterModel?.() |
||||||
|
const ms = closeOuterModel != null ? MS_AFTER_RADIX_DIALOG_FOR_EXTERNAL_MODAL : 0 |
||||||
|
window.setTimeout(() => { |
||||||
|
stripReactRemoveScrollBodyLocks() |
||||||
|
fn() |
||||||
|
}, ms) |
||||||
|
} |
||||||
Loading…
Reference in new issue