132 lines
3.0 KiB
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>
|