Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,6 @@ export default antfu({
'no-console': 'off',
},
})
.removeRules(
'vue/no-template-shadow',
)
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
"@types/ws": "catalog:types",
"@typescript-eslint/utils": "catalog:devtools",
"@unocss/eslint-config": "catalog:devtools",
"@vueuse/core": "catalog:frontend",
"ansis": "catalog:deps",
"bumpp": "catalog:devtools",
"esbuild": "catalog:build",
Expand Down
4 changes: 3 additions & 1 deletion packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,17 +62,19 @@
"debug": "catalog:deps",
"launch-editor": "catalog:deps",
"mlly": "catalog:deps",
"nanoevents": "catalog:deps",
"open": "catalog:deps",
"pathe": "catalog:deps",
"perfect-debounce": "catalog:deps",
"sirv": "catalog:deps",
"tinyexec": "catalog:deps",
"ws": "catalog:deps"
},
"devDependencies": {
"@vitejs/devtools": "workspace:*",
"@vitejs/devtools-vite": "workspace:*",
"@vitejs/plugin-vue": "catalog:build",
"@xterm/addon-fit": "catalog:frontend",
"@xterm/xterm": "catalog:frontend",
"tsdown": "catalog:build",
"typescript": "catalog:devtools",
"unplugin-vue": "catalog:build",
Expand Down
8 changes: 8 additions & 0 deletions packages/core/playground/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,14 @@ export default defineConfig({
launcher: {
title: 'Launcher My Cool App',
onLaunch: async () => {
await ctx.terminals.startChildProcess({
command: 'vite',
args: ['dev'],
cwd: process.cwd(),
}, {
id: 'vite-run',
title: 'Vite Run',
})
await new Promise(resolve => setTimeout(resolve, 1000))

ctx.docks.update({
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/client/inject/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import type { DockPanelStorage } from '@vitejs/devtools-kit/client'
import { getDevToolsRpcClient } from '@vitejs/devtools-kit/client'
import { useLocalStorage } from '@vueuse/core'
import { createDocksContext } from '../webcomponents'
import { createDocksContext } from '../webcomponents/state/context'

export async function init(): Promise<void> {
// eslint-disable-next-line no-console
Expand All @@ -16,7 +16,7 @@ export async function init(): Promise<void> {
// eslint-disable-next-line no-console
console.log('[VITE DEVTOOLS] RPC', rpc)

const rpcFunctions = await rpc.$call('vite:core:list-rpc-functions')
const rpcFunctions = await rpc.$call('vite:internal:rpc:server:list')
// eslint-disable-next-line no-console
console.log('[VITE DEVTOOLS] RPC Functions', rpcFunctions)

Expand Down
7 changes: 2 additions & 5 deletions packages/core/src/client/standalone/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ import { markRaw, useTemplateRef } from 'vue'
import DockEntries from '../webcomponents/components/DockEntries.vue'
import VitePlus from '../webcomponents/components/icons/VitePlus.vue'
import ViewEntry from '../webcomponents/components/ViewEntry.vue'
import { createDocksContext } from '../webcomponents/state/dock'
import { useStateHandlers } from '../webcomponents/state/state'
import { createDocksContext } from '../webcomponents/state/context'
import { PresistedDomViewsManager } from '../webcomponents/utils/PresistedDomViewsManager'
const rpcReturn = await getDevToolsRpcClient()
Expand All @@ -24,8 +23,6 @@ const context: DocksContext = await createDocksContext(
)
context.docks.selectedId ||= context.docks.entries[0]?.id ?? null
const { selectDockEntry } = useStateHandlers(context)
</script>

<template>
Expand All @@ -39,7 +36,7 @@ const { selectDockEntry } = useStateHandlers(context)
class="transition duration-200 p2"
:is-vertical="false"
:selected="context.docks.selected"
@select="selectDockEntry"
@select="(e) => context.docks.switchEntry(e?.id)"
/>
</div>
<div>
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/client/webcomponents/.generated/css.ts

Large diffs are not rendered by default.

7 changes: 2 additions & 5 deletions packages/core/src/client/webcomponents/components/Dock.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import type { DocksContext } from '@vitejs/devtools-kit/client'
import { useEventListener, useScreenSafeArea } from '@vueuse/core'
import { computed, onMounted, reactive, ref, useTemplateRef, watchEffect } from 'vue'
import { useStateHandlers } from '../state/state'
import DockEntries from './DockEntries.vue'
import BracketLeft from './icons/BracketLeft.vue'
import BracketRight from './icons/BracketRight.vue'
Expand All @@ -17,7 +16,7 @@ const context = props.context
const isSafari = navigator.userAgent.includes('Safari') && !navigator.userAgent.includes('Chrome')
const PANEL_MARGIN = 5
const PANEL_MARGIN = 2
const panelMargins = reactive({
left: PANEL_MARGIN,
top: PANEL_MARGIN,
Expand Down Expand Up @@ -220,8 +219,6 @@ const panelStyle = computed(() => {
return style
})
const { selectDockEntry } = useStateHandlers(context)
onMounted(() => {
bringUp()
recalculateCounter.value++
Expand Down Expand Up @@ -277,7 +274,7 @@ onMounted(() => {
:class="isMinimized ? 'opacity-0 pointer-events-none' : 'opacity-100'"
:is-vertical="context.panel.isVertical"
:selected="context.docks.selected"
@select="selectDockEntry"
@select="(e) => context.docks.switchEntry(e?.id)"
/>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
<script setup lang="ts">
import type { DevToolsDockEntry } from '@vitejs/devtools-kit'
import type { DevToolsDockEntryBase } from '@vitejs/devtools-kit'
import { useEventListener } from '@vueuse/core'
import { useTemplateRef } from 'vue'
import { setFloatingTooltip } from '../state/floating-tooltip'
import DockIcon from './DockIcon.vue'

const props = defineProps<{
dock: DevToolsDockEntry
dock: DevToolsDockEntryBase
isSelected?: boolean
isDimmed?: boolean
isVertical?: boolean
Expand Down
124 changes: 60 additions & 64 deletions packages/core/src/client/webcomponents/components/DockPanelResizer.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<script setup lang="ts">
import type { DocksPanelContext } from '@vitejs/devtools-kit/client'
import { useEventListener } from '@vueuse/core'
import { ref, watch } from 'vue'
import { computed, ref, useTemplateRef, watch } from 'vue'

const props = defineProps<{
panel: DocksPanelContext
Expand All @@ -10,7 +10,8 @@ const props = defineProps<{
const PANEL_MIN = 20
const PANEL_MAX = 100

const container = ref<HTMLElement>()
const topHandle = useTemplateRef<HTMLDivElement>('topHandle')
const container = computed(() => topHandle.value?.parentElement)
const resizingState = ref<false | { top?: boolean, left?: boolean, right?: boolean, bottom?: boolean }>(false)

// Close panel on outside click (when enabled)
Expand Down Expand Up @@ -79,67 +80,62 @@ watch(
</script>

<template>
<!-- Handlers -->
<div
id="vite-devtools-resize-container"
ref="container"
class="w-full h-full absolute left-0 right-0 bottom-0 top-0 antialiased pointer-events-auto"
>
<!-- Handlers -->
<div
v-show="panel.store.position !== 'top'"
class="vite-devtools-resize-handle vite-devtools-resize-handle-horizontal"
:style="{ top: 0 }"
@mousedown.prevent="resizingState = { top: true }"
@touchstart.passive="() => resizingState = { top: true }"
/>
<div
v-show="panel.store.position !== 'bottom'"
class="vite-devtools-resize-handle vite-devtools-resize-handle-horizontal"
:style="{ bottom: 0 }"
@mousedown.prevent="() => resizingState = { bottom: true }"
@touchstart.passive="() => resizingState = { bottom: true }"
/>
<div
v-show="panel.store.position !== 'left'"
class="vite-devtools-resize-handle vite-devtools-resize-handle-vertical"
:style="{ left: 0 }"
@mousedown.prevent="() => resizingState = { left: true }"
@touchstart.passive="() => resizingState = { left: true }"
/>
<div
v-show="panel.store.position !== 'right'"
class="vite-devtools-resize-handle vite-devtools-resize-handle-vertical"
:style="{ right: 0 }"
@mousedown.prevent="() => resizingState = { right: true }"
@touchstart.passive="() => resizingState = { right: true }"
/>
<div
v-show="panel.store.position !== 'top' && panel.store.position !== 'left'"
class="vite-devtools-resize-handle vite-devtools-resize-handle-corner"
:style="{ top: 0, left: 0, cursor: 'nwse-resize' }"
@mousedown.prevent="() => resizingState = { top: true, left: true }"
@touchstart.passive="() => resizingState = { top: true, left: true }"
/>
<div
v-show="panel.store.position !== 'top' && panel.store.position !== 'right'"
class="vite-devtools-resize-handle vite-devtools-resize-handle-corner"
:style="{ top: 0, right: 0, cursor: 'nesw-resize' }"
@mousedown.prevent="() => resizingState = { top: true, right: true }"
@touchstart.passive="() => resizingState = { top: true, right: true }"
/>
<div
v-show="panel.store.position !== 'bottom' && panel.store.position !== 'left'"
class="vite-devtools-resize-handle vite-devtools-resize-handle-corner"
:style="{ bottom: 0, left: 0, cursor: 'nesw-resize' }"
@mousedown.prevent="() => resizingState = { bottom: true, left: true }"
@touchstart.passive="() => resizingState = { bottom: true, left: true }"
/>
<div
v-show="panel.store.position !== 'bottom' && panel.store.position !== 'right'"
class="vite-devtools-resize-handle vite-devtools-resize-handle-corner"
:style="{ bottom: 0, right: 0, cursor: 'nwse-resize' }"
@mousedown.prevent="() => resizingState = { bottom: true, right: true }"
@touchstart.passive="() => resizingState = { bottom: true, right: true }"
/>
</div>
v-show="panel.store.position !== 'top'"
ref="topHandle"
class="vite-devtools-resize-handle vite-devtools-resize-handle-horizontal"
:style="{ top: 0 }"
@mousedown.prevent="resizingState = { top: true }"
@touchstart.passive="() => resizingState = { top: true }"
/>
<div
v-show="panel.store.position !== 'bottom'"
class="vite-devtools-resize-handle vite-devtools-resize-handle-horizontal"
:style="{ bottom: 0 }"
@mousedown.prevent="() => resizingState = { bottom: true }"
@touchstart.passive="() => resizingState = { bottom: true }"
/>
<div
v-show="panel.store.position !== 'left'"
class="vite-devtools-resize-handle vite-devtools-resize-handle-vertical"
:style="{ left: 0 }"
@mousedown.prevent="() => resizingState = { left: true }"
@touchstart.passive="() => resizingState = { left: true }"
/>
<div
v-show="panel.store.position !== 'right'"
class="vite-devtools-resize-handle vite-devtools-resize-handle-vertical"
:style="{ right: 0 }"
@mousedown.prevent="() => resizingState = { right: true }"
@touchstart.passive="() => resizingState = { right: true }"
/>
<div
v-show="panel.store.position !== 'top' && panel.store.position !== 'left'"
class="vite-devtools-resize-handle vite-devtools-resize-handle-corner"
:style="{ top: 0, left: 0, cursor: 'nwse-resize' }"
@mousedown.prevent="() => resizingState = { top: true, left: true }"
@touchstart.passive="() => resizingState = { top: true, left: true }"
/>
<div
v-show="panel.store.position !== 'top' && panel.store.position !== 'right'"
class="vite-devtools-resize-handle vite-devtools-resize-handle-corner"
:style="{ top: 0, right: 0, cursor: 'nesw-resize' }"
@mousedown.prevent="() => resizingState = { top: true, right: true }"
@touchstart.passive="() => resizingState = { top: true, right: true }"
/>
<div
v-show="panel.store.position !== 'bottom' && panel.store.position !== 'left'"
class="vite-devtools-resize-handle vite-devtools-resize-handle-corner"
:style="{ bottom: 0, left: 0, cursor: 'nesw-resize' }"
@mousedown.prevent="() => resizingState = { bottom: true, left: true }"
@touchstart.passive="() => resizingState = { bottom: true, left: true }"
/>
<div
v-show="panel.store.position !== 'bottom' && panel.store.position !== 'right'"
class="vite-devtools-resize-handle vite-devtools-resize-handle-corner"
:style="{ bottom: 0, right: 0, cursor: 'nwse-resize' }"
@mousedown.prevent="() => resizingState = { bottom: true, right: true }"
@touchstart.passive="() => resizingState = { bottom: true, right: true }"
/>
</template>
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<!-- eslint-disable vue/no-mutating-props -->
<script setup lang="ts">
import type { DocksContext } from '@vitejs/devtools-kit/client'
import type { TerminalState } from '../state/terminals'
import { useEventListener } from '@vueuse/core'
import { FitAddon } from '@xterm/addon-fit'
import { Terminal } from '@xterm/xterm'
import { markRaw, onMounted, ref } from 'vue'

const props = defineProps<{
context: DocksContext
terminal: TerminalState
}>()

const container = ref<HTMLElement>()
let term: Terminal

onMounted(async () => {
term = markRaw(new Terminal({
convertEol: true,
cols: 80,
screenReaderMode: true,
}))
const fitAddon = new FitAddon()
term.loadAddon(fitAddon)
term.open(container.value!)
fitAddon.fit()

useEventListener(window, 'resize', () => {
fitAddon.fit()
})

if (props.terminal.buffer == null) {
const { buffer } = await props.context.rpc.$call('vite:internal:terminals:read', props.terminal.info.id)
props.terminal.buffer = markRaw(buffer)
for (const chunk of buffer)
term.writeln(chunk)
}

props.terminal.terminal = term
})

// async function clear() {
// rpc.runTerminalAction(await ensureDevAuthToken(), props.id, 'clear')
// term?.clear()
// }

// async function restart() {
// rpc.runTerminalAction(await ensureDevAuthToken(), props.id, 'restart')
// }

// async function terminate() {
// rpc.runTerminalAction(await ensureDevAuthToken(), props.id, 'terminate')
// }
</script>

<template>
<div ref="container" class="h-full w-full of-auto bg-black" />
<!-- <div border="t base" flex="~ gap-2" items-center p2>
<NButton title="Clear" icon="i-carbon-clean" :border="false" @click="clear()" />
<NButton v-if="info?.restartable" title="Restart" icon="carbon-renew" :border="false" @click="restart()" />
<NButton v-if="info?.terminatable" title="Terminate" icon="carbon-delete" :border="false" @click="terminate()" />
<span text-sm op50>{{ info?.description }}</span>
</div> -->
</template>
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<script setup lang="ts">
import type { DocksContext } from '@vitejs/devtools-kit/client'
import type { TerminalState } from '../state/terminals'
import { shallowRef } from 'vue'
import { useTerminals } from '../state/terminals'
import ViewBuiltinTerminalPanel from './ViewBuiltinTerminalPanel.vue'

const props = defineProps<{
context: DocksContext
}>()

const terminals = useTerminals(props.context)
const selectedTerminal = shallowRef<TerminalState | null>(null)
</script>

<template>
<div class="w-full h-full grid-cols-[max-content_1fr]">
<div class="border-base border-b">
<button
v-for="terminal of terminals.values()"
:key="terminal.info.id"
class="px3 py2 border-r border-base hover:bg-active"
@click="selectedTerminal = terminal"
>
{{ terminal.info.title }}
</button>
</div>
<div class="h-full flex relative">
<ViewBuiltinTerminalPanel
v-if="selectedTerminal"
:context
:terminal="selectedTerminal"
/>
<div v-else class="flex items-center justify-center h-full text-center">
Select a terminal tab to start
</div>
</div>
</div>
</template>
Loading
Loading