Skip to content

Commit 11a4aa0

Browse files
committed
feat(core): refactor vue internals data structure
1 parent d84e3c3 commit 11a4aa0

File tree

18 files changed

+285
-178
lines changed

18 files changed

+285
-178
lines changed

packages/core/playground/vite.config.ts

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,14 +47,38 @@ export default defineConfig({
4747

4848
ctx.docks.register({
4949
type: 'action',
50-
action: ctx.utils.clientEntryFromSimpleFunction(() => {
50+
action: ctx.utils.createSimpleClientScript(() => {
5151
// eslint-disable-next-line no-alert
5252
alert('Hello, world!')
5353
}),
5454
id: 'local2',
5555
title: 'Local2',
5656
icon: 'ph:bell-simple-ringing-duotone',
5757
})
58+
59+
ctx.docks.register({
60+
type: 'custom-render',
61+
renderer: ctx.utils.createSimpleClientScript((ctx) => {
62+
if (!ctx.current.elPanel) {
63+
// eslint-disable-next-line no-alert
64+
alert('No panel element found!')
65+
}
66+
const el = document.createElement('div')
67+
el.textContent = 'Hello from custom render dock!'
68+
69+
const btn = document.createElement('button')
70+
btn.textContent = 'Click me'
71+
btn.onclick = () => {
72+
// eslint-disable-next-line no-alert
73+
alert('Button clicked in custom render dock!')
74+
}
75+
el.appendChild(btn)
76+
ctx.current.elPanel?.appendChild(el)
77+
}),
78+
id: 'custom-render',
79+
title: 'Custom',
80+
icon: 'ph:newspaper-clipping-duotone',
81+
})
5882
},
5983
},
6084
},

packages/core/src/client/inject/index.ts

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
/// <reference types="vite/client" />
22
/// <reference lib="dom" />
33

4+
import type { DockPanelState } from '../webcomponents'
45
import { getDevToolsRpcClient } from '@vitejs/devtools-kit/client'
56
import { useLocalStorage } from '@vueuse/core'
7+
import { createDockContext } from '../webcomponents'
68

79
export async function init(): Promise<void> {
810
// eslint-disable-next-line no-console
@@ -13,15 +15,11 @@ export async function init(): Promise<void> {
1315
// eslint-disable-next-line no-console
1416
console.log('[VITE DEVTOOLS] RPC', rpc)
1517

16-
const docks = await rpc['vite:core:list-dock-entries']()
17-
// eslint-disable-next-line no-console
18-
console.log('[VITE DEVTOOLS] Docks', docks)
19-
2018
const rpcFunctions = await rpc['vite:core:list-rpc-functions']()
2119
// eslint-disable-next-line no-console
2220
console.log('[VITE DEVTOOLS] RPC Functions', rpcFunctions)
2321

24-
const state = useLocalStorage(
22+
const state = useLocalStorage<DockPanelState>(
2523
'vite-devtools-dock-state',
2624
{
2725
width: 80,
@@ -35,15 +33,17 @@ export async function init(): Promise<void> {
3533
{ mergeDefaults: true },
3634
)
3735

36+
const context = await createDockContext(
37+
'embedded',
38+
rpc,
39+
state,
40+
)
41+
3842
const { DockEmbedded } = import.meta.env.VITE_DEVTOOLS_LOCAL_DEV
3943
? await import('../webcomponents')
4044
: await import('@vitejs/devtools/client/webcomponents')
4145

42-
const dockEl = new DockEmbedded({
43-
state,
44-
docks,
45-
rpc,
46-
})
46+
const dockEl = new DockEmbedded({ context })
4747
document.body.appendChild(dockEl)
4848
}
4949

packages/core/src/client/standalone/App.vue

Lines changed: 16 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
<script setup lang="ts">
2-
import type { DevToolsDockState } from '../webcomponents/types/DockProps'
2+
import type { DockContext } from '../webcomponents/state/dock'
33
import { getDevToolsRpcClient } from '@vitejs/devtools-kit/client'
4-
import { useLocalStorage } from '@vueuse/core'
5-
import { computed, markRaw, ref, shallowRef, useTemplateRef } from 'vue'
4+
import { markRaw, useTemplateRef } from 'vue'
65
import DockEntries from '../webcomponents/components/DockEntries.vue'
76
import VitePlus from '../webcomponents/components/icons/VitePlus.vue'
87
import ViewEntry from '../webcomponents/components/ViewEntry.vue'
8+
import { createDockContext } from '../webcomponents/state/dock'
99
import { useStateHandlers } from '../webcomponents/state/state'
1010
import { PresistedDomViewsManager } from '../webcomponents/utils/PresistedDomViewsManager'
1111
@@ -14,31 +14,17 @@ const { rpc } = await getDevToolsRpcClient()
1414
// eslint-disable-next-line no-console
1515
console.log('[VITE DEVTOOLS] RPC', rpc)
1616
17-
const docks = shallowRef(await rpc['vite:core:list-dock-entries']())
18-
// eslint-disable-next-line no-console
19-
console.log('[VITE DEVTOOLS] Docks', docks)
20-
21-
const state = useLocalStorage<DevToolsDockState>(
22-
'vite-devtools-dock-state',
23-
{
24-
width: 80,
25-
height: 80,
26-
top: 0,
27-
left: 0,
28-
position: 'left',
29-
open: false,
30-
minimizePanelInactive: 3_000,
31-
},
32-
{ mergeDefaults: true },
33-
)
34-
3517
const viewsContainer = useTemplateRef<HTMLElement>('viewsContainer')
3618
const presistedDoms = markRaw(new PresistedDomViewsManager(viewsContainer))
3719
38-
const isDragging = ref(false)
39-
const entry = computed(() => state.value.dockEntry || docks.value[0])
20+
const context: DockContext = await createDockContext(
21+
'standalone',
22+
rpc,
23+
)
24+
25+
context.selected ||= context.dockEntries[0] || null
4026
41-
const { selectDockEntry } = useStateHandlers(state, docks, rpc, 'standalone')
27+
const { selectDockEntry } = useStateHandlers(context)
4228
</script>
4329

4430
<template>
@@ -48,22 +34,20 @@ const { selectDockEntry } = useStateHandlers(state, docks, rpc, 'standalone')
4834
<VitePlus class="w-7 h-7 ma" />
4935
</div>
5036
<DockEntries
51-
:entries="docks"
37+
:entries="context.dockEntries"
5238
class="transition duration-200 p2"
5339
:is-vertical="false"
54-
:selected="state.dockEntry"
40+
:selected="context.selected"
5541
@select="selectDockEntry"
5642
/>
5743
</div>
5844
<div>
5945
<div id="vite-devtools-views-container" ref="viewsContainer" />
6046
<ViewEntry
61-
v-if="entry && viewsContainer"
62-
:key="entry.id"
63-
:state="state"
64-
:entry="entry"
65-
:is-dragging="isDragging"
66-
:is-resizing="false"
47+
v-if="context.selected && viewsContainer"
48+
:key="context.selected.id"
49+
:entry="context.selected"
50+
:context
6751
:presisted-doms="presistedDoms"
6852
/>
6953
</div>

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

Lines changed: 25 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
11
<script setup lang="ts">
2-
import type { DockProps } from '../types/DockProps'
2+
import type { DockContext } from '../state/dock'
33
import { useEventListener, useScreenSafeArea } from '@vueuse/core'
4-
import { computed, onMounted, reactive, ref, toRefs, useTemplateRef, watchEffect } from 'vue'
4+
import { computed, onMounted, reactive, ref, useTemplateRef, watchEffect } from 'vue'
55
import { useStateHandlers } from '../state/state'
66
import DockEntries from './DockEntries.vue'
77
import BracketLeft from './icons/BracketLeft.vue'
88
import BracketRight from './icons/BracketRight.vue'
99
import VitePlusCore from './icons/VitePlusCore.vue'
1010
11-
const props = defineProps<DockProps>()
12-
13-
const { state, docks } = toRefs(props)
11+
// Here we directly destructure is as we don't expect context to be changed
12+
const props = defineProps<{
13+
context: DockContext
14+
}>()
15+
const context = props.context
1416
1517
const isDragging = defineModel<boolean>('isDragging', { default: false })
1618
@@ -94,16 +96,16 @@ onMounted(() => {
9496
const BL = Math.atan2(window.innerHeight - HORIZONTAL_MARGIN - centerY, 0 - centerX)
9597
const BR = Math.atan2(window.innerHeight - HORIZONTAL_MARGIN - centerY, window.innerWidth - centerX)
9698
97-
state.value.position = deg >= TL && deg <= TR
99+
context.state.position = deg >= TL && deg <= TR
98100
? 'top'
99101
: deg >= TR && deg <= BR
100102
? 'right'
101103
: deg >= BR && deg <= BL
102104
? 'bottom'
103105
: 'left'
104106
105-
state.value.left = snapToPoints(x / window.innerWidth * 100)
106-
state.value.top = snapToPoints(y / window.innerHeight * 100)
107+
context.state.left = snapToPoints(x / window.innerWidth * 100)
108+
context.state.top = snapToPoints(y / window.innerHeight * 100)
107109
})
108110
useEventListener(window, 'pointerup', () => {
109111
isDragging.value = false
@@ -129,7 +131,7 @@ function clamp(value: number, min: number, max: number) {
129131
130132
const recalculateCounter = ref(0)
131133
const isHovering = ref(false)
132-
const isVertical = computed(() => state.value.position === 'left' || state.value.position === 'right')
134+
const isVertical = computed(() => context.state.position === 'left' || context.state.position === 'right')
133135
134136
const anchorPos = computed(() => {
135137
// eslint-disable-next-line ts/no-unused-expressions
@@ -138,10 +140,10 @@ const anchorPos = computed(() => {
138140
const halfWidth = (dockEl.value?.clientWidth || 0) / 2
139141
const halfHeight = (dockEl.value?.clientHeight || 0) / 2
140142
141-
const left = state.value.left * windowSize.width / 100
142-
const top = state.value.top * windowSize.height / 100
143+
const left = context.state.left * windowSize.width / 100
144+
const top = context.state.top * windowSize.height / 100
143145
144-
switch (state.value.position) {
146+
switch (context.state.position) {
145147
case 'top':
146148
return {
147149
left: clamp(left, halfWidth + panelMargins.left, windowSize.width - halfWidth - panelMargins.right),
@@ -169,29 +171,29 @@ const anchorPos = computed(() => {
169171
let _timer: ReturnType<typeof setTimeout> | null = null
170172
function bringUp() {
171173
isHovering.value = true
172-
if (state.value.minimizePanelInactive < 0)
174+
if (context.state.minimizePanelInactive < 0)
173175
return
174176
if (_timer)
175177
clearTimeout(_timer)
176178
_timer = setTimeout(() => {
177179
isHovering.value = false
178-
}, +state.value.minimizePanelInactive || 0)
180+
}, +context.state.minimizePanelInactive || 0)
179181
}
180182
181183
const isHidden = computed(() => false)
182184
183185
const isMinimized = computed(() => {
184-
if (state.value.minimizePanelInactive < 0)
186+
if (context.state.minimizePanelInactive < 0)
185187
return false
186-
if (state.value.minimizePanelInactive === 0)
188+
if (context.state.minimizePanelInactive === 0)
187189
return true
188190
// @ts-expect-error compatibility
189191
const isTouchDevice = 'ontouchstart' in window || navigator.maxTouchPoints > 0 || navigator.msMaxTouchPoints > 0
190192
return !isDragging.value
191-
&& !state.value.open
193+
&& !context.state.open
192194
&& !isHovering.value
193195
&& !isTouchDevice
194-
&& state.value.minimizePanelInactive
196+
&& context.state.minimizePanelInactive
195197
})
196198
197199
const anchorStyle = computed(() => {
@@ -217,7 +219,7 @@ const panelStyle = computed(() => {
217219
return style
218220
})
219221
220-
const { selectDockEntry } = useStateHandlers(state, docks, props.rpc, 'embedded')
222+
const { selectDockEntry } = useStateHandlers(context)
221223
222224
onMounted(() => {
223225
bringUp()
@@ -263,21 +265,20 @@ onMounted(() => {
263265
:class="isMinimized ? 'op100' : 'op0'"
264266
/>
265267
<DockEntries
266-
:entries="docks"
268+
:entries="context.dockEntries"
267269
class="transition duration-200 flex items-center w-full h-full justify-center"
268270
:class="isMinimized ? 'opacity-0 pointer-events-none' : 'opacity-100'"
269271
:is-vertical="isVertical"
270-
:selected="state.dockEntry"
272+
:selected="context.selected"
271273
@select="selectDockEntry"
272274
/>
273275
</div>
274276
</div>
275277
<slot
278+
:context="context"
276279
:dock-el="dockEl"
280+
:selected="context.selected"
277281
:panel-margins="panelMargins"
278-
:state="state"
279-
:is-dragging="isDragging"
280-
:entry="state.dockEntry?.type === 'action' ? undefined : state.dockEntry"
281282
/>
282283
</div>
283284
</template>

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type { VueElementConstructor } from 'vue'
2-
import type { DockProps } from '../types/DockProps'
2+
import type { DockContext } from '../state/dock'
33
import { defineCustomElement } from 'vue'
44
import css from '../.generated/css'
55
import Component from './DockEmbedded.vue'
@@ -10,6 +10,8 @@ export const DockEmbedded = defineCustomElement(
1010
shadowRoot: true,
1111
styles: [css],
1212
},
13-
) as VueElementConstructor<DockProps>
13+
) as VueElementConstructor<{
14+
context: DockContext
15+
}>
1416

1517
customElements.define('vite-devtools-dock-embedded', DockEmbedded)

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

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,22 @@
11
<script setup lang="ts">
2-
import type { DevToolsDockEntry } from '@vitejs/devtools-kit'
3-
import type { DevToolsRpcClient } from '@vitejs/devtools-kit/client'
4-
import type { DevToolsDockState } from '../types/DockProps'
2+
import type { DockContext } from '../state/dock'
53
import Dock from './Dock.vue'
64
import DockPanel from './DockPanel.vue'
75
import FloatingTooltip from './FloatingTooltip.vue'
86
97
defineProps<{
10-
state: DevToolsDockState
11-
docks: DevToolsDockEntry[]
12-
rpc: DevToolsRpcClient
8+
context: DockContext
139
}>()
1410
</script>
1511

1612
<template>
17-
<Dock
18-
:state="state"
19-
:docks="docks"
20-
:rpc="rpc"
21-
>
22-
<template #default="{ dockEl, entry, panelMargins, isDragging }">
13+
<Dock :context>
14+
<template #default="{ dockEl, panelMargins, selected }">
2315
<DockPanel
16+
:context
17+
:selected
2418
:dock-el="dockEl!"
25-
:state="state"
26-
:is-dragging="isDragging"
2719
:panel-margins="panelMargins"
28-
:entry="entry"
2920
/>
3021
</template>
3122
</Dock>

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ import { toRefs } from 'vue'
44
import DockEntry from './DockEntry.vue'
55
66
const props = defineProps<{
7-
selected?: DevToolsDockEntry
8-
isVertical: boolean
97
entries: DevToolsDockEntry[]
8+
selected: DevToolsDockEntry | null
9+
isVertical: boolean
1010
}>()
1111
1212
const emit = defineEmits<{
@@ -30,7 +30,7 @@ function toggleDockEntry(dock: DevToolsDockEntry) {
3030
:key="dock.id"
3131
:dock
3232
:is-selected="selected?.id === dock.id"
33-
:is-dimmed="selected && (selected.id !== dock.id)"
33+
:is-dimmed="selected ? (selected.id !== dock.id) : false"
3434
:is-vertical="isVertical"
3535
@click="toggleDockEntry(dock)"
3636
/>

0 commit comments

Comments
 (0)