wraith/frontend/components/terminal/SplitPane.vue
Vantz Stockwell c8868258d5 feat: Phase 2 — SSH terminal + SFTP sidebar in browser
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-12 17:21:11 -04:00

75 lines
2.2 KiB
Vue

<script setup lang="ts">
import { ref } from 'vue'
const direction = ref<'horizontal' | 'vertical'>('horizontal')
const splitRatio = ref(50) // percentage for first pane
const isDragging = ref(false)
function toggleDirection() {
direction.value = direction.value === 'horizontal' ? 'vertical' : 'horizontal'
}
function startDrag(event: MouseEvent) {
isDragging.value = true
const container = (event.target as HTMLElement).closest('.split-pane-container') as HTMLElement
if (!container) return
const onMove = (e: MouseEvent) => {
if (!isDragging.value) return
const rect = container.getBoundingClientRect()
if (direction.value === 'horizontal') {
splitRatio.value = Math.min(80, Math.max(20, ((e.clientX - rect.left) / rect.width) * 100))
} else {
splitRatio.value = Math.min(80, Math.max(20, ((e.clientY - rect.top) / rect.height) * 100))
}
}
const onUp = () => {
isDragging.value = false
window.removeEventListener('mousemove', onMove)
window.removeEventListener('mouseup', onUp)
}
window.addEventListener('mousemove', onMove)
window.addEventListener('mouseup', onUp)
}
</script>
<template>
<div
class="split-pane-container w-full h-full flex"
:class="direction === 'horizontal' ? 'flex-row' : 'flex-col'"
>
<!-- First pane -->
<div
class="overflow-hidden"
:style="direction === 'horizontal'
? `width: ${splitRatio}%; flex-shrink: 0`
: `height: ${splitRatio}%; flex-shrink: 0`"
>
<slot name="first" />
</div>
<!-- Divider -->
<div
class="bg-gray-700 hover:bg-wraith-500 transition-colors cursor-col-resize shrink-0"
:class="direction === 'horizontal' ? 'w-1 cursor-col-resize' : 'h-1 cursor-row-resize'"
@mousedown="startDrag"
/>
<!-- Second pane -->
<div class="flex-1 overflow-hidden">
<slot name="second" />
</div>
<!-- Direction toggle button (slot for external control) -->
<slot name="controls">
<button
@click="toggleDirection"
class="absolute top-2 right-2 text-xs text-gray-600 hover:text-gray-400 z-10"
title="Toggle split direction"
>{{ direction === 'horizontal' ? '⇅' : '⇄' }}</button>
</slot>
</div>
</template>