Skip to content

Commit

Permalink
Merge pull request #3 from x0k/editor-panel
Browse files Browse the repository at this point in the history
Editor panel
  • Loading branch information
x0k authored Jun 6, 2024
2 parents 4cf247b + 16460ce commit f798982
Show file tree
Hide file tree
Showing 29 changed files with 880 additions and 253 deletions.
Binary file modified bun.lockb
Binary file not shown.
11 changes: 7 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,24 @@
"@astrojs/svelte": "^5.4.0",
"@astrojs/tailwind": "^5.1.0",
"@php-wasm/web": "^0.7.20",
"astro": "^4.9.2",
"@xterm/addon-fit": "^0.10.0",
"@xterm/xterm": "^5.5.0",
"astro": "^4.9.3",
"astro-icon": "^1.1.0",
"fast-deep-equal": "^3.1.3",
"monaco-editor": "^0.49.0",
"monaco-vim": "^0.4.1",
"pyodide": "^0.26.0",
"tailwindcss": "^3.4.3",
"tailwindcss": "^3.4.4",
"typescript": "^5.4.5"
},
"devDependencies": {
"@iconify-json/lucide": "^1.1.189",
"@iconify-json/lucide": "^1.1.190",
"@iconify/svelte": "^4.0.2",
"@tailwindcss/typography": "^0.5.13",
"@types/color": "^3.0.6",
"color": "^4.2.3",
"daisyui": "^4.11.1",
"daisyui": "^4.12.2",
"svelte": "5.0.0-next.133",
"vite-plugin-static-copy": "^1.0.5"
}
Expand Down
18 changes: 18 additions & 0 deletions src/adapters/storage.svelte.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import type { SyncStorage } from "@/shared";

export interface StorageState<T> {
value: T;
}

export function reactive<T>(storage: SyncStorage<T>): StorageState<T> {
let value = $state(storage.load());
return {
get value() {
return value;
},
set value(newValue) {
value = newValue;
storage.save(newValue);
},
};
}
57 changes: 0 additions & 57 deletions src/components/editor-testing-panel.svelte

This file was deleted.

107 changes: 0 additions & 107 deletions src/components/editor.svelte

This file was deleted.

147 changes: 147 additions & 0 deletions src/components/editor/editor-surface.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
<script lang="ts">
import { untrack, type Snippet } from 'svelte';
import { editor } from "monaco-editor";
import type { SyncStorage } from "@/shared";
import { type SurfaceApi } from './model'
import Resizer, { Orientation } from './resizer.svelte';
interface Props {
model: editor.IModel;
widthStorage: SyncStorage<number>;
panel: Snippet<[{ resizer: Snippet, api: SurfaceApi }]>;
}
const { model, widthStorage, panel }: Props = $props();
function normalizeWidth(width: number) {
return Math.min(Math.max(width, 480), window.innerWidth);
}
const PANEL_BORDER_HEIGHT = 1
const MIN_PANEL_HEIGHT = 32 + PANEL_BORDER_HEIGHT
function normalizeHeight(height: number) {
return Math.min(Math.max(height, 0), window.innerHeight - MIN_PANEL_HEIGHT);
}
let width = $state(normalizeWidth(widthStorage.load()));
let height = $state(window.innerHeight - MIN_PANEL_HEIGHT);
let start: { x: number, y: number };
function onWindowResize() {
if (window.innerWidth < width) {
width = normalizeWidth(window.innerWidth)
}
if (window.innerHeight < height) {
height = normalizeHeight(window.innerHeight)
}
}
$effect(() => {
window.addEventListener("resize", onWindowResize);
return () => {
window.removeEventListener("resize", onWindowResize);
};
});
let ed = $state<editor.IStandaloneCodeEditor>()
let editorElement: HTMLDivElement;
$effect(() => {
model;
ed = editor.create(editorElement, {
model,
theme: "vs-dark",
fixedOverflowWidgets: true,
lineNumbers: "on",
tabSize: 2,
insertSpaces: true,
fontSize: 16,
minimap: {
enabled: false,
},
});
untrack(() => {
ed?.layout({ width, height });
})
return () => {
ed?.dispose();
}
});
let panelHeight = $derived(window.innerHeight - height);
let isCollapsed = $derived(panelHeight <= MIN_PANEL_HEIGHT)
const api: SurfaceApi = {
get editor() {
return ed
},
get width() {
return width
},
get panelHeight() {
return panelHeight
},
get isPanelCollapsed () {
return isCollapsed
},
togglePanel(newHeight) {
if (isCollapsed) {
return api.showPanel(newHeight)
}
return api.hidePanel()
},
showPanel(newHeight) {
const panelHeight = window.innerHeight - height
if (panelHeight > MIN_PANEL_HEIGHT * 2) {
return false
}
height = normalizeHeight(window.innerHeight - newHeight - PANEL_BORDER_HEIGHT)
ed?.layout({ width, height }, true)
return true
},
hidePanel() {
if (isCollapsed) {
return false
}
height = normalizeHeight(window.innerHeight)
ed?.layout({ width, height }, true)
return true
},
}
</script>

<div class="h-full flex flex-col relative bg-base-300" style="width: {width}px">
<Resizer
onMoveStart={(e) => {
start = { x: e.clientX, y: $state.snapshot(width) }
}}
onMove={(e) => {
width = normalizeWidth(start.x - e.clientX + start.y)
ed?.layout({ width, height }, true)
}}
onMoveEnd={() => {
widthStorage.save(width)
}}
/>
<div bind:this={editorElement} class="relative" style="height: {height}px" ></div>
{#snippet resizer()}
<Resizer
orientation={Orientation.Horizontal}
onMoveStart={(e) => {
start = { x: $state.snapshot(height), y: e.clientY }
}}
onMove={(e) => {
height = normalizeHeight(start.x - (start.y - e.clientY))
ed?.layout({ width, height }, true)
}}
/>
{/snippet}
{@render panel({
resizer,
api
})}
</div>
Loading

0 comments on commit f798982

Please sign in to comment.