From eaa418ec39e8dec28d276621bc1af7dd12ee478c Mon Sep 17 00:00:00 2001 From: Makito Date: Sat, 29 Nov 2025 15:17:35 +0900 Subject: [PATCH] fix(stage-web): allow interacting with Vue DevTools over backdrops --- apps/stage-web/src/main.ts | 36 ++++++++++++++++++++++++++++++++++++ cspell.config.yaml | 1 + 2 files changed, 37 insertions(+) diff --git a/apps/stage-web/src/main.ts b/apps/stage-web/src/main.ts index c2b974e7b..9331ec109 100644 --- a/apps/stage-web/src/main.ts +++ b/apps/stage-web/src/main.ts @@ -50,3 +50,39 @@ createApp(App) .use(i18n) .use(Tres) .mount('#app') + +if (import.meta.env.DEV && !import.meta.env.SSR) { + function captureEvents(el: HTMLElement) { + // Force `pointer-events: auto` as DismissableLayer in Reka UI adds + // `pointer-events: none` to document body. + el.style.pointerEvents = 'auto' + + // We need to capture events inside elements like devtools to prevent them + // from leaking to other layers (like DismissableLayer in Reka UI). + // + // See: https://github.com/unovue/reka-ui/blob/14866201d179b8bae3c8b4346a1ca8eff1c5eaa4/packages/radix-vue/src/DismissableLayer/DismissableLayer.vue#L186-L188 + el.addEventListener('focus', e => e.stopPropagation(), { capture: true }) + el.addEventListener('blur', e => e.stopPropagation(), { capture: true }) + el.addEventListener('pointerdown', e => e.stopPropagation(), { capture: true }) + } + + const observer = new MutationObserver((mutationsList, observer) => { + for (const mutation of mutationsList) { + if (mutation.type === 'childList') { + const devtoolsContainer = document.getElementById('__vue-devtools-container__') + + if (devtoolsContainer) { + captureEvents(devtoolsContainer) + observer.disconnect() + } + } + } + }) + + observer.observe(document.body, { childList: true, subtree: true }) + + // Disconnect on timeout (in case) + setTimeout(() => { + observer.disconnect() // Safe to call even if already disconnected + }, 60 * 1000) +} diff --git a/cspell.config.yaml b/cspell.config.yaml index 4f45a3e1e..8473b670d 100644 --- a/cspell.config.yaml +++ b/cspell.config.yaml @@ -75,6 +75,7 @@ words: - devlog - devlogs - directml + - Dismissable - dokidoki - dompurify - dotenvx