Files
oldboy/src/lib/components/editor/EditorWithLogs.svelte

132 lines
3.0 KiB
Svelte

<script lang="ts">
import { onMount } from 'svelte';
import Editor from './Editor.svelte';
import LogPanel from './LogPanel.svelte';
import type { EditorSettingsStore } from '../../stores/editorSettings';
interface Props {
value: string;
onChange?: (value: string) => void;
onExecute?: (code: string, source: 'selection' | 'block' | 'document') => void;
logs?: string[];
editorSettings: EditorSettingsStore;
mode: 'composition' | 'livecoding';
}
let {
value = '',
onChange,
onExecute,
logs = [],
editorSettings,
mode = 'composition'
}: Props = $props();
let logPanelRef: LogPanel;
let editorHeight = $state(70);
let isResizing = $state(false);
let startY = $state(0);
let startHeight = $state(0);
let previousHeight = $state(70);
let isCollapsed = $state(false);
function handleResizeStart(e: MouseEvent) {
isResizing = true;
startY = e.clientY;
startHeight = editorHeight;
e.preventDefault();
}
function handleResizeMove(e: MouseEvent) {
if (!isResizing) return;
const container = document.querySelector('.editor-with-logs');
if (!container) return;
const containerHeight = container.clientHeight;
const deltaY = e.clientY - startY;
const deltaPercent = (deltaY / containerHeight) * 100;
const newHeight = Math.max(20, Math.min(80, startHeight + deltaPercent));
editorHeight = newHeight;
}
function handleResizeEnd() {
isResizing = false;
}
function toggleCollapse() {
if (isCollapsed) {
editorHeight = previousHeight;
isCollapsed = false;
} else {
previousHeight = editorHeight;
editorHeight = 96;
isCollapsed = true;
}
}
onMount(() => {
document.addEventListener('mousemove', handleResizeMove);
document.addEventListener('mouseup', handleResizeEnd);
return () => {
document.removeEventListener('mousemove', handleResizeMove);
document.removeEventListener('mouseup', handleResizeEnd);
};
});
</script>
<div class="editor-with-logs">
<div class="editor-section" style="height: {editorHeight}%;">
<Editor
{value}
{onChange}
{onExecute}
{editorSettings}
{mode}
/>
</div>
<div class="resize-divider" onmousedown={handleResizeStart}></div>
<div class="logs-section" style="height: {100 - editorHeight}%;">
<LogPanel bind:this={logPanelRef} {logs} onHeaderClick={toggleCollapse} collapsed={isCollapsed} />
</div>
</div>
<style>
.editor-with-logs {
display: flex;
flex-direction: column;
height: 100%;
width: 100%;
overflow: hidden;
}
.editor-section {
position: relative;
overflow: hidden;
}
.resize-divider {
height: 4px;
background-color: var(--surface-color);
cursor: ns-resize;
transition: background-color var(--transition-base);
z-index: 10;
}
.resize-divider:hover,
.resize-divider:active {
background-color: var(--accent-color);
}
.logs-section {
position: relative;
overflow: hidden;
}
</style>