Skip to content
This repository was archived by the owner on Jan 6, 2024. It is now read-only.

Commit 28815b1

Browse files
OneGIlwebfansplz
andauthored
feat: minimize panel on inactive (#186)
Co-authored-by: webfansplz <[email protected]>
1 parent a075e8a commit 28815b1

File tree

4 files changed

+122
-14
lines changed

4 files changed

+122
-14
lines changed

Diff for: packages/client/composables/state.ts

+2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export interface DevToolsFrameState {
1111
position: string
1212
isFirstVisit: boolean
1313
closeOnOutsideClick: boolean
14+
minimizePanelInactive: number
1415
}
1516

1617
const frameState = useLocalStorage<DevToolsFrameState>(FRAME_STATE_STORAGE_KEY, {
@@ -23,6 +24,7 @@ const frameState = useLocalStorage<DevToolsFrameState>(FRAME_STATE_STORAGE_KEY,
2324
position: 'bottom',
2425
isFirstVisit: true,
2526
closeOnOutsideClick: false,
27+
minimizePanelInactive: 5000,
2628
}, { mergeDefaults: true })
2729

2830
const frameStateRefs = toRefs(frameState)

Diff for: packages/client/pages/settings.vue

+22-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ const {
77
hiddenTabGroups,
88
} = useDevToolsSettings()
99
10-
const { closeOnOutsideClick } = useFrameState()
10+
const { closeOnOutsideClick, minimizePanelInactive } = useFrameState()
1111
1212
const scaleOptions = [
1313
['Tiny', 12 / 15],
@@ -17,6 +17,15 @@ const scaleOptions = [
1717
['Huge', 18 / 15],
1818
]
1919
20+
const minimizeInactiveOptions = [
21+
['Always', 0],
22+
['1s', 1000],
23+
['2s', 2000],
24+
['5s', 5000],
25+
['10s', 10000],
26+
['Never', -1],
27+
]
28+
2029
const groupedTabs = useGroupedTabs(false)
2130
2231
function toggleTab(name: string, v: boolean) {
@@ -104,11 +113,22 @@ const showTabGroup = ref(false)
104113
<div>
105114
<VDDarkToggle v-slot="{ toggle, isDark }">
106115
<VDButton n="primary" @click="toggle">
107-
<div carbon-sun translate-y--1px dark:carbon-moon /> {{ isDark.value ? 'Dark' : 'Light' }}
116+
<div carbon-sun dark:carbon-moon translate-y--1px /> {{ isDark.value ? 'Dark' : 'Light' }}
108117
</VDButton>
109118
</VDDarkToggle>
110119
</div>
111120
</div>
121+
<div py3 flex="~ col gap-1">
122+
<h3 mb1 text-lg>
123+
Floating Panel
124+
</h3>
125+
<p>Minimize panel on inactive</p>
126+
<VDSelect v-model="minimizePanelInactive" n="primary">
127+
<option v-for="i of minimizeInactiveOptions" :key="i[0]" :value="i[1]">
128+
{{ i[0] }}
129+
</option>
130+
</VDSelect>
131+
</div>
112132
<div py3 flex="~ col gap-1">
113133
<h3 mb1 text-lg>
114134
UI Scale

Diff for: packages/node/src/views/Main.vue

+39-11
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ const panelState = ref<{
3030
3131
const { togglePanelVisible, closePanel, panelVisible } = usePanelVisible()
3232
const panelEl = ref<HTMLDivElement>()
33-
const { onPointerDown, anchorStyle, iframeStyle, isDragging, isVertical } = usePosition(panelEl)
33+
const { onPointerDown, bringUp, anchorStyle, iframeStyle, isDragging, isVertical, isHidden, panelStyle } = usePosition(panelEl)
3434
const vars = computed(() => {
3535
const colorScheme = useColorScheme()
3636
const dark = colorScheme.value === 'auto'
@@ -239,11 +239,15 @@ collectHookBuffer()
239239
<div
240240
id="vue-devtools-anchor"
241241
:style="[anchorStyle, vars]"
242-
:class="{ 'vue-devtools-vertical': isVertical }"
242+
:class="{
243+
'vue-devtools-vertical': isVertical,
244+
'vue-devtools-hide': isHidden,
245+
}"
246+
@mousemove="bringUp"
243247
>
244248
<!-- toggle button -->
245249
<div v-if="!checkIsSafari()" class="vue-devtools-glowing" :style="isDragging ? 'opacity: 0.6 !important' : ''" />
246-
<div ref="panelEl" class="vue-devtools-button-panel" @pointerdown="onPointerDown">
250+
<div ref="panelEl" class="vue-devtools-panel" :style="panelStyle" @pointerdown="onPointerDown">
247251
<div
248252
class="vue-devtools-icon-button vue-devtools-vue-button"
249253
title="Toggle Vue DevTools" aria-label="Toggle devtools panel"
@@ -256,9 +260,9 @@ collectHookBuffer()
256260
<path fill="#35495E" d="M50.56 0L128 133.12L204.8 0h-47.36L128 51.2L97.92 0H50.56Z" />
257261
</svg>
258262
</div>
259-
<div style="border-left: 1px solid #8883;width:1px;height:10px;" />
263+
<div style="border-left: 1px solid #8883;width:1px;height:10px;" class="vue-devtools-panel-content" />
260264
<div
261-
class="vue-devtools-icon-button vue-devtools-inspector-button"
265+
class="vue-devtools-icon-button vue-devtools-panel-content vue-devtools-inspector-button"
262266
:class="{ disabled: !inspectorLoaded }"
263267
:disabled="!inspectorLoaded"
264268
title="Toggle Component Inspector" @click="toggleInspector"
@@ -310,6 +314,19 @@ collectHookBuffer()
310314
color: inherit;
311315
}
312316
317+
#vue-devtools-anchor.vue-devtools-hide .vue-devtools-panel {
318+
max-width: 32px;
319+
padding: 2px 0;
320+
}
321+
322+
#vue-devtools-anchor .vue-devtools-panel-content {
323+
transition: opacity 0.4s ease;
324+
}
325+
326+
#vue-devtools-anchor .vue-devtools-hide .vue-devtools-panel-content {
327+
opacity: 0;
328+
}
329+
313330
#vue-devtools-anchor .vue-devtools-glowing {
314331
position: absolute;
315332
left: 0;
@@ -318,7 +335,7 @@ collectHookBuffer()
318335
width: 160px;
319336
height: 160px;
320337
opacity: 0;
321-
transition: all 0.8s ease;
338+
transition: all 1s ease;
322339
pointer-events: none;
323340
z-index: -1;
324341
border-radius: 9999px;
@@ -350,13 +367,14 @@ collectHookBuffer()
350367
opacity: 0.6;
351368
}
352369
353-
#vue-devtools-anchor .vue-devtools-button-panel {
370+
#vue-devtools-anchor .vue-devtools-panel {
354371
position: absolute;
355372
left: 0;
356373
top: 0;
357374
transform: translate(-50%, -50%);
358375
display: flex;
359-
justify-content: center;
376+
justify-content: flex-start;
377+
overflow: hidden;
360378
align-items: center;
361379
gap: 2px;
362380
height: 30px;
@@ -368,17 +386,27 @@ collectHookBuffer()
368386
backdrop-filter: blur(10px);
369387
color: var(--vue-devtools-widget-fg);
370388
box-shadow: 2px 2px 8px var(--vue-devtools-widget-shadow);
371-
transition: background 0.2s ease;
372389
user-select: none;
390+
max-width: 150px;
391+
transition: max-width 0.4s ease, padding 0.5s ease, transform 0.3s ease, all 0.4s ease;
392+
}
393+
394+
#vue-devtools-anchor .vue-devtools-vue-button {
395+
flex: none;
373396
}
374397
375398
#vue-devtools-anchor.vue-devtools-vertical .vue-devtools-vue-button {
376399
transform: rotate(-90deg);
377400
}
378401
379-
#vue-devtools-anchor.vue-devtools-vertical .vue-devtools-button-panel {
402+
#vue-devtools-anchor.vue-devtools-hide .vue-devtools-panel {
403+
max-width: 32px;
404+
padding: 2px 0;
405+
}
406+
407+
#vue-devtools-anchor.vue-devtools-vertical .vue-devtools-panel {
380408
transform: translate(-50%, -50%) rotate(90deg);
381-
box-shadow: 2px -2px 8px var(--nuxt-devtools-widget-shadow);
409+
box-shadow: 2px -2px 8px var(--vue-devtools-widget-shadow);
382410
}
383411
384412
#vue-devtools-anchor .vue-devtools-inspector-button.disabled {

Diff for: packages/node/src/views/composables.ts

+59-1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ interface DevToolsFrameState {
1212
position: string
1313
isFirstVisit: boolean
1414
closeOnOutsideClick: boolean
15+
minimizePanelInactive: number
1516
}
1617

1718
interface ComponentInspectorBounds {
@@ -38,6 +39,7 @@ export const state = useObjectStorage<DevToolsFrameState>('__vue-devtools-frame-
3839
position: 'bottom',
3940
isFirstVisit: true,
4041
closeOnOutsideClick: false,
42+
minimizePanelInactive: 50000,
4143
})
4244

4345
// ---- useIframe ----
@@ -245,6 +247,7 @@ function snapToPoints(value: number) {
245247
}
246248

247249
export function usePosition(panelEl: Ref<HTMLElement | undefined>) {
250+
const isHovering = ref(false)
248251
const isDragging = ref(false)
249252
const draggingOffset = reactive({ x: 0, y: 0 })
250253
const windowSize = reactive({ width: 0, height: 0 })
@@ -255,6 +258,7 @@ export function usePosition(panelEl: Ref<HTMLElement | undefined>) {
255258
right: 10,
256259
bottom: 10,
257260
})
261+
let _timer: ReturnType<typeof setTimeout> | null = null
258262

259263
const safeArea = useScreenSafeArea()
260264

@@ -277,9 +281,22 @@ export function usePosition(panelEl: Ref<HTMLElement | undefined>) {
277281
windowSize.height = window.innerHeight
278282
}
279283

284+
const bringUp = () => {
285+
isHovering.value = true
286+
if (state.value.minimizePanelInactive < 0)
287+
return
288+
if (_timer)
289+
clearTimeout(_timer)
290+
_timer = setTimeout(() => {
291+
isHovering.value = false
292+
}, +state.value.minimizePanelInactive || 0)
293+
}
294+
280295
onMounted(() => {
281296
setWindowSize()
282297

298+
bringUp()
299+
283300
useWindowEventListener('resize', () => {
284301
setWindowSize()
285302
})
@@ -325,6 +342,19 @@ export function usePosition(panelEl: Ref<HTMLElement | undefined>) {
325342
})
326343

327344
const isVertical = computed(() => state.value.position === 'left' || state.value.position === 'right')
345+
const isHidden = computed(() => {
346+
if (state.value.minimizePanelInactive < 0)
347+
return false
348+
if (state.value.minimizePanelInactive === 0)
349+
return true
350+
// @ts-expect-error compatibility
351+
const isTouchDevice = 'ontouchstart' in window || navigator.maxTouchPoints > 0 || navigator.msMaxTouchPoints > 0
352+
return !isDragging.value
353+
&& !state.value.open
354+
&& !isHovering.value
355+
&& !isTouchDevice
356+
&& state.value.minimizePanelInactive
357+
})
328358

329359
const anchorPos = computed(() => {
330360
const halfWidth = (panelEl.value?.clientWidth || 0) / 2
@@ -433,12 +463,40 @@ export function usePosition(panelEl: Ref<HTMLElement | undefined>) {
433463
return style
434464
})
435465

466+
const panelStyle = computed(() => {
467+
const style: any = {
468+
transform: isVertical.value
469+
? `translate(${isHidden.value ? `calc(-50% ${state.value.position === 'right' ? '+' : '-'} 15px)` : '-50%'}, -50%) rotate(90deg)`
470+
: `translate(-50%, ${isHidden.value ? `calc(-50% ${state.value.position === 'top' ? '-' : '+'} 15px)` : '-50%'})`,
471+
}
472+
if (isHidden.value) {
473+
switch (state.value.position) {
474+
case 'top':
475+
case 'right':
476+
style.borderTopLeftRadius = '0'
477+
style.borderTopRightRadius = '0'
478+
break
479+
case 'bottom':
480+
case 'left':
481+
style.borderBottomLeftRadius = '0'
482+
style.borderBottomRightRadius = '0'
483+
break
484+
}
485+
}
486+
if (isDragging.value)
487+
style.transition = 'none !important'
488+
return style
489+
})
490+
436491
return {
492+
isHidden,
437493
isDragging,
438-
onPointerDown,
439494
isVertical,
440495
anchorStyle,
441496
iframeStyle,
497+
panelStyle,
498+
onPointerDown,
499+
bringUp,
442500
}
443501
}
444502

0 commit comments

Comments
 (0)