121 lines
2.6 KiB
Svelte
121 lines
2.6 KiB
Svelte
<script lang="ts">
|
|
import { onMount } from 'svelte';
|
|
import Editor from './Editor.svelte';
|
|
import LogPanel from './LogPanel.svelte';
|
|
|
|
interface Props {
|
|
initialValue?: string;
|
|
language?: 'javascript' | 'html' | 'css';
|
|
onChange?: (value: string) => void;
|
|
logs?: string[];
|
|
}
|
|
|
|
let {
|
|
initialValue = '',
|
|
language = 'javascript',
|
|
onChange,
|
|
logs = []
|
|
}: Props = $props();
|
|
|
|
let editorRef: Editor;
|
|
let logPanelRef: LogPanel;
|
|
|
|
let editorHeight = $state(70);
|
|
let isResizing = $state(false);
|
|
let startY = $state(0);
|
|
let startHeight = $state(0);
|
|
|
|
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;
|
|
}
|
|
|
|
onMount(() => {
|
|
document.addEventListener('mousemove', handleResizeMove);
|
|
document.addEventListener('mouseup', handleResizeEnd);
|
|
|
|
return () => {
|
|
document.removeEventListener('mousemove', handleResizeMove);
|
|
document.removeEventListener('mouseup', handleResizeEnd);
|
|
};
|
|
});
|
|
|
|
export function getValue(): string {
|
|
return editorRef?.getValue() || '';
|
|
}
|
|
|
|
export function setValue(value: string): void {
|
|
editorRef?.setValue(value);
|
|
}
|
|
</script>
|
|
|
|
<div class="editor-with-logs">
|
|
<div class="editor-section" style="height: {editorHeight}%;">
|
|
<Editor
|
|
bind:this={editorRef}
|
|
{initialValue}
|
|
{language}
|
|
{onChange}
|
|
/>
|
|
</div>
|
|
|
|
<div class="resize-divider" onmousedown={handleResizeStart}></div>
|
|
|
|
<div class="logs-section" style="height: {100 - editorHeight}%;">
|
|
<LogPanel bind:this={logPanelRef} {logs} />
|
|
</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: #2a2a2a;
|
|
cursor: ns-resize;
|
|
transition: background-color 0.2s;
|
|
z-index: 10;
|
|
}
|
|
|
|
.resize-divider:hover,
|
|
.resize-divider:active {
|
|
background-color: #646cff;
|
|
}
|
|
|
|
.logs-section {
|
|
position: relative;
|
|
overflow: hidden;
|
|
}
|
|
</style>
|