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

Commit

Permalink
feat: minimize panel on inactive (#186)
Browse files Browse the repository at this point in the history

Co-authored-by: webfansplz <308241863@qq.com>
  • Loading branch information
OneGIl and webfansplz authored Aug 7, 2023
1 parent a075e8a commit 28815b1
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 14 deletions.
2 changes: 2 additions & 0 deletions packages/client/composables/state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export interface DevToolsFrameState {
position: string
isFirstVisit: boolean
closeOnOutsideClick: boolean
minimizePanelInactive: number
}

const frameState = useLocalStorage<DevToolsFrameState>(FRAME_STATE_STORAGE_KEY, {
Expand All @@ -23,6 +24,7 @@ const frameState = useLocalStorage<DevToolsFrameState>(FRAME_STATE_STORAGE_KEY,
position: 'bottom',
isFirstVisit: true,
closeOnOutsideClick: false,
minimizePanelInactive: 5000,
}, { mergeDefaults: true })

const frameStateRefs = toRefs(frameState)
Expand Down
24 changes: 22 additions & 2 deletions packages/client/pages/settings.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const {
hiddenTabGroups,
} = useDevToolsSettings()
const { closeOnOutsideClick } = useFrameState()
const { closeOnOutsideClick, minimizePanelInactive } = useFrameState()
const scaleOptions = [
['Tiny', 12 / 15],
Expand All @@ -17,6 +17,15 @@ const scaleOptions = [
['Huge', 18 / 15],
]
const minimizeInactiveOptions = [
['Always', 0],
['1s', 1000],
['2s', 2000],
['5s', 5000],
['10s', 10000],
['Never', -1],
]
const groupedTabs = useGroupedTabs(false)
function toggleTab(name: string, v: boolean) {
Expand Down Expand Up @@ -104,11 +113,22 @@ const showTabGroup = ref(false)
<div>
<VDDarkToggle v-slot="{ toggle, isDark }">
<VDButton n="primary" @click="toggle">
<div carbon-sun translate-y--1px dark:carbon-moon /> {{ isDark.value ? 'Dark' : 'Light' }}
<div carbon-sun dark:carbon-moon translate-y--1px /> {{ isDark.value ? 'Dark' : 'Light' }}
</VDButton>
</VDDarkToggle>
</div>
</div>
<div py3 flex="~ col gap-1">
<h3 mb1 text-lg>
Floating Panel
</h3>
<p>Minimize panel on inactive</p>
<VDSelect v-model="minimizePanelInactive" n="primary">
<option v-for="i of minimizeInactiveOptions" :key="i[0]" :value="i[1]">
{{ i[0] }}
</option>
</VDSelect>
</div>
<div py3 flex="~ col gap-1">
<h3 mb1 text-lg>
UI Scale
Expand Down
50 changes: 39 additions & 11 deletions packages/node/src/views/Main.vue
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ const panelState = ref<{
const { togglePanelVisible, closePanel, panelVisible } = usePanelVisible()
const panelEl = ref<HTMLDivElement>()
const { onPointerDown, anchorStyle, iframeStyle, isDragging, isVertical } = usePosition(panelEl)
const { onPointerDown, bringUp, anchorStyle, iframeStyle, isDragging, isVertical, isHidden, panelStyle } = usePosition(panelEl)
const vars = computed(() => {
const colorScheme = useColorScheme()
const dark = colorScheme.value === 'auto'
Expand Down Expand Up @@ -239,11 +239,15 @@ collectHookBuffer()
<div
id="vue-devtools-anchor"
:style="[anchorStyle, vars]"
:class="{ 'vue-devtools-vertical': isVertical }"
:class="{
'vue-devtools-vertical': isVertical,
'vue-devtools-hide': isHidden,
}"
@mousemove="bringUp"
>
<!-- toggle button -->
<div v-if="!checkIsSafari()" class="vue-devtools-glowing" :style="isDragging ? 'opacity: 0.6 !important' : ''" />
<div ref="panelEl" class="vue-devtools-button-panel" @pointerdown="onPointerDown">
<div ref="panelEl" class="vue-devtools-panel" :style="panelStyle" @pointerdown="onPointerDown">
<div
class="vue-devtools-icon-button vue-devtools-vue-button"
title="Toggle Vue DevTools" aria-label="Toggle devtools panel"
Expand All @@ -256,9 +260,9 @@ collectHookBuffer()
<path fill="#35495E" d="M50.56 0L128 133.12L204.8 0h-47.36L128 51.2L97.92 0H50.56Z" />
</svg>
</div>
<div style="border-left: 1px solid #8883;width:1px;height:10px;" />
<div style="border-left: 1px solid #8883;width:1px;height:10px;" class="vue-devtools-panel-content" />
<div
class="vue-devtools-icon-button vue-devtools-inspector-button"
class="vue-devtools-icon-button vue-devtools-panel-content vue-devtools-inspector-button"
:class="{ disabled: !inspectorLoaded }"
:disabled="!inspectorLoaded"
title="Toggle Component Inspector" @click="toggleInspector"
Expand Down Expand Up @@ -310,6 +314,19 @@ collectHookBuffer()
color: inherit;
}
#vue-devtools-anchor.vue-devtools-hide .vue-devtools-panel {
max-width: 32px;
padding: 2px 0;
}
#vue-devtools-anchor .vue-devtools-panel-content {
transition: opacity 0.4s ease;
}
#vue-devtools-anchor .vue-devtools-hide .vue-devtools-panel-content {
opacity: 0;
}
#vue-devtools-anchor .vue-devtools-glowing {
position: absolute;
left: 0;
Expand All @@ -318,7 +335,7 @@ collectHookBuffer()
width: 160px;
height: 160px;
opacity: 0;
transition: all 0.8s ease;
transition: all 1s ease;
pointer-events: none;
z-index: -1;
border-radius: 9999px;
Expand Down Expand Up @@ -350,13 +367,14 @@ collectHookBuffer()
opacity: 0.6;
}
#vue-devtools-anchor .vue-devtools-button-panel {
#vue-devtools-anchor .vue-devtools-panel {
position: absolute;
left: 0;
top: 0;
transform: translate(-50%, -50%);
display: flex;
justify-content: center;
justify-content: flex-start;
overflow: hidden;
align-items: center;
gap: 2px;
height: 30px;
Expand All @@ -368,17 +386,27 @@ collectHookBuffer()
backdrop-filter: blur(10px);
color: var(--vue-devtools-widget-fg);
box-shadow: 2px 2px 8px var(--vue-devtools-widget-shadow);
transition: background 0.2s ease;
user-select: none;
max-width: 150px;
transition: max-width 0.4s ease, padding 0.5s ease, transform 0.3s ease, all 0.4s ease;
}
#vue-devtools-anchor .vue-devtools-vue-button {
flex: none;
}
#vue-devtools-anchor.vue-devtools-vertical .vue-devtools-vue-button {
transform: rotate(-90deg);
}
#vue-devtools-anchor.vue-devtools-vertical .vue-devtools-button-panel {
#vue-devtools-anchor.vue-devtools-hide .vue-devtools-panel {
max-width: 32px;
padding: 2px 0;
}
#vue-devtools-anchor.vue-devtools-vertical .vue-devtools-panel {
transform: translate(-50%, -50%) rotate(90deg);
box-shadow: 2px -2px 8px var(--nuxt-devtools-widget-shadow);
box-shadow: 2px -2px 8px var(--vue-devtools-widget-shadow);
}
#vue-devtools-anchor .vue-devtools-inspector-button.disabled {
Expand Down
60 changes: 59 additions & 1 deletion packages/node/src/views/composables.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ interface DevToolsFrameState {
position: string
isFirstVisit: boolean
closeOnOutsideClick: boolean
minimizePanelInactive: number
}

interface ComponentInspectorBounds {
Expand All @@ -38,6 +39,7 @@ export const state = useObjectStorage<DevToolsFrameState>('__vue-devtools-frame-
position: 'bottom',
isFirstVisit: true,
closeOnOutsideClick: false,
minimizePanelInactive: 50000,
})

// ---- useIframe ----
Expand Down Expand Up @@ -245,6 +247,7 @@ function snapToPoints(value: number) {
}

export function usePosition(panelEl: Ref<HTMLElement | undefined>) {
const isHovering = ref(false)
const isDragging = ref(false)
const draggingOffset = reactive({ x: 0, y: 0 })
const windowSize = reactive({ width: 0, height: 0 })
Expand All @@ -255,6 +258,7 @@ export function usePosition(panelEl: Ref<HTMLElement | undefined>) {
right: 10,
bottom: 10,
})
let _timer: ReturnType<typeof setTimeout> | null = null

const safeArea = useScreenSafeArea()

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

const bringUp = () => {
isHovering.value = true
if (state.value.minimizePanelInactive < 0)
return
if (_timer)
clearTimeout(_timer)
_timer = setTimeout(() => {
isHovering.value = false
}, +state.value.minimizePanelInactive || 0)
}

onMounted(() => {
setWindowSize()

bringUp()

useWindowEventListener('resize', () => {
setWindowSize()
})
Expand Down Expand Up @@ -325,6 +342,19 @@ export function usePosition(panelEl: Ref<HTMLElement | undefined>) {
})

const isVertical = computed(() => state.value.position === 'left' || state.value.position === 'right')
const isHidden = computed(() => {
if (state.value.minimizePanelInactive < 0)
return false
if (state.value.minimizePanelInactive === 0)
return true
// @ts-expect-error compatibility
const isTouchDevice = 'ontouchstart' in window || navigator.maxTouchPoints > 0 || navigator.msMaxTouchPoints > 0
return !isDragging.value
&& !state.value.open
&& !isHovering.value
&& !isTouchDevice
&& state.value.minimizePanelInactive
})

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

const panelStyle = computed(() => {
const style: any = {
transform: isVertical.value
? `translate(${isHidden.value ? `calc(-50% ${state.value.position === 'right' ? '+' : '-'} 15px)` : '-50%'}, -50%) rotate(90deg)`
: `translate(-50%, ${isHidden.value ? `calc(-50% ${state.value.position === 'top' ? '-' : '+'} 15px)` : '-50%'})`,
}
if (isHidden.value) {
switch (state.value.position) {
case 'top':
case 'right':
style.borderTopLeftRadius = '0'
style.borderTopRightRadius = '0'
break
case 'bottom':
case 'left':
style.borderBottomLeftRadius = '0'
style.borderBottomRightRadius = '0'
break
}
}
if (isDragging.value)
style.transition = 'none !important'
return style
})

return {
isHidden,
isDragging,
onPointerDown,
isVertical,
anchorStyle,
iframeStyle,
panelStyle,
onPointerDown,
bringUp,
}
}

Expand Down

0 comments on commit 28815b1

Please sign in to comment.