Skip to content

Commit b30faf0

Browse files
authored
feat(core): close on click outside (#189)
1 parent 98f9207 commit b30faf0

File tree

4 files changed

+44
-1
lines changed

4 files changed

+44
-1
lines changed

packages/core/src/client/webcomponents/components/DockEmbedded.vue

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,39 @@
11
<script setup lang="ts">
22
import type { DocksContext } from '@vitejs/devtools-kit/client'
3+
import { useEventListener } from '@vueuse/core'
34
import { onUnmounted } from 'vue'
5+
import { sharedStateToRef } from '../state/docks'
46
import { closeDockPopup, useIsDockPopupOpen } from '../state/popup'
57
import Dock from './Dock.vue'
68
import DockPanel from './DockPanel.vue'
79
import FloatingElements from './FloatingElements.vue'
810
9-
defineProps<{
11+
const props = defineProps<{
1012
context: DocksContext
1113
}>()
1214
1315
const isDockPopupOpen = useIsDockPopupOpen()
16+
const settings = sharedStateToRef(props.context.docks.settings)
17+
18+
// Close the dock when clicking outside of it
19+
useEventListener(window, 'mousedown', (e: MouseEvent) => {
20+
if (!settings.value.closeOnOutsideClick)
21+
return
22+
if (isDockPopupOpen.value)
23+
return
24+
if (!props.context.panel.store.open || props.context.panel.isDragging || props.context.panel.isResizing)
25+
return
26+
27+
const matched = e.composedPath().find((_el) => {
28+
const el = _el as HTMLElement
29+
return [...(el.classList || [])].some(c => c.startsWith('vite-devtools-'))
30+
|| el.id?.startsWith('vite-devtools-')
31+
|| el.tagName?.toLowerCase() === 'iframe'
32+
})
33+
34+
if (!matched)
35+
props.context.docks.switchEntry(null)
36+
})
1437
1538
onUnmounted(() => {
1639
closeDockPopup()

packages/core/src/client/webcomponents/components/ViewBuiltinSettings.vue

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,24 @@ function resetSettings() {
284284
<span class="text-xs op50">Display navigation controls and URL bar for iframe views</span>
285285
</div>
286286
</label>
287+
288+
<!-- Close on outside click toggle -->
289+
<label class="flex items-center gap-3 cursor-pointer group">
290+
<button
291+
class="w-10 h-6 rounded-full transition-colors relative shrink-0"
292+
:class="settings.closeOnOutsideClick ? 'bg-lime' : 'bg-gray/30'"
293+
@click="settingsStore.mutate((s) => { s.closeOnOutsideClick = !s.closeOnOutsideClick })"
294+
>
295+
<div
296+
class="absolute top-1 w-4 h-4 rounded-full bg-white shadow transition-transform"
297+
:class="settings.closeOnOutsideClick ? 'translate-x-5' : 'translate-x-1'"
298+
/>
299+
</button>
300+
<div class="flex flex-col">
301+
<span class="text-sm">Close panel on outside click</span>
302+
<span class="text-xs op50">Close the DevTools panel when clicking outside of it (embedded mode only)</span>
303+
</div>
304+
</label>
287305
</div>
288306
</section>
289307

packages/kit/src/constants.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,5 @@ export const DEFAULT_STATE_USER_SETTINGS: () => DevToolsDocksUserSettings = () =
2727
docksPinned: [],
2828
docksCustomOrder: {},
2929
showIframeAddressBar: false,
30+
closeOnOutsideClick: false,
3031
})

packages/kit/src/types/settings.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,5 @@ export interface DevToolsDocksUserSettings {
44
docksPinned: string[]
55
docksCustomOrder: Record<string, number>
66
showIframeAddressBar: boolean
7+
closeOnOutsideClick: boolean
78
}

0 commit comments

Comments
 (0)