Installing basic UI

This commit is contained in:
2025-10-14 21:58:12 +02:00
parent 8bceae2396
commit ece02406bd
12 changed files with 1320 additions and 78 deletions

View File

@ -1,47 +1,209 @@
<script lang="ts">
import svelteLogo from './assets/svelte.svg'
import viteLogo from '/vite.svg'
import Counter from './lib/Counter.svelte'
import TopBar from './lib/TopBar.svelte';
import EditorWithLogs from './lib/EditorWithLogs.svelte';
import EditorSettings from './lib/EditorSettings.svelte';
import SidePanel from './lib/SidePanel.svelte';
import Popup from './lib/Popup.svelte';
import {
PanelLeftClose,
PanelLeftOpen,
PanelRightClose,
PanelRightOpen,
PanelBottomClose,
PanelBottomOpen,
LayoutGrid
} from 'lucide-svelte';
let sidePanelVisible = $state(true);
let sidePanelPosition = $state<'left' | 'right' | 'bottom'>('right');
let popupVisible = $state(false);
let editorValue = $state('// Start coding here...\n');
let interpreterLogs = $state<string[]>([]);
let sidePanelRef: SidePanel;
let editorRef: EditorWithLogs;
function toggleSidePanel() {
sidePanelVisible = !sidePanelVisible;
}
function showPopup() {
popupVisible = true;
}
function handleEditorChange(value: string) {
editorValue = value;
}
function cyclePanelPosition() {
if (sidePanelPosition === 'right') {
sidePanelPosition = 'left';
} else if (sidePanelPosition === 'left') {
sidePanelPosition = 'bottom';
} else {
sidePanelPosition = 'right';
}
}
const panelTabs = [
{
id: 'editor',
label: 'Editor',
content: editorTabContent
},
{
id: 'files',
label: 'Files',
content: filesTabContent
}
];
</script>
<main>
<div>
<a href="https://vite.dev" target="_blank" rel="noreferrer">
<img src={viteLogo} class="logo" alt="Vite Logo" />
</a>
<a href="https://svelte.dev" target="_blank" rel="noreferrer">
<img src={svelteLogo} class="logo svelte" alt="Svelte Logo" />
</a>
</div>
<h1>Vite + Svelte</h1>
{#snippet editorTabContent()}
<EditorSettings />
{/snippet}
<div class="card">
<Counter />
{#snippet filesTabContent()}
<h3>File Browser</h3>
<p>Your project files will be listed here.</p>
<ul>
<li>src/</li>
<li>├── App.svelte</li>
<li>├── main.ts</li>
<li>└── lib/</li>
</ul>
{/snippet}
<div class="app-container">
<TopBar title="oldboy">
<button onclick={toggleSidePanel} class="icon-button">
{#if sidePanelVisible}
{#if sidePanelPosition === 'left'}
<PanelLeftClose size={18} />
{:else if sidePanelPosition === 'right'}
<PanelRightClose size={18} />
{:else}
<PanelBottomClose size={18} />
{/if}
{:else}
{#if sidePanelPosition === 'left'}
<PanelLeftOpen size={18} />
{:else if sidePanelPosition === 'right'}
<PanelRightOpen size={18} />
{:else}
<PanelBottomOpen size={18} />
{/if}
{/if}
</button>
<button onclick={cyclePanelPosition} class="icon-button" title="Change panel position">
<LayoutGrid size={18} />
</button>
</TopBar>
<div class="main-content" class:panel-bottom={sidePanelPosition === 'bottom'}>
{#if sidePanelPosition === 'left'}
<SidePanel
bind:this={sidePanelRef}
bind:visible={sidePanelVisible}
bind:position={sidePanelPosition}
tabs={panelTabs}
/>
{/if}
<div class="editor-area">
<EditorWithLogs
bind:this={editorRef}
initialValue={editorValue}
language="javascript"
onChange={handleEditorChange}
logs={interpreterLogs}
/>
</div>
{#if sidePanelPosition === 'right'}
<SidePanel
bind:this={sidePanelRef}
bind:visible={sidePanelVisible}
bind:position={sidePanelPosition}
tabs={panelTabs}
/>
{/if}
{#if sidePanelPosition === 'bottom'}
<SidePanel
bind:this={sidePanelRef}
bind:visible={sidePanelVisible}
bind:position={sidePanelPosition}
initialWidth={200}
minWidth={100}
maxWidth={400}
tabs={panelTabs}
/>
{/if}
</div>
<p>
Check out <a href="https://github.com/sveltejs/kit#readme" target="_blank" rel="noreferrer">SvelteKit</a>, the official Svelte app framework powered by Vite!
</p>
<p class="read-the-docs">
Click on the Vite and Svelte logos to learn more
</p>
</main>
<Popup
bind:visible={popupVisible}
title="Example Popup"
x={200}
y={150}
width={500}
height={400}
>
<h3>This is a popup!</h3>
<p>You can drag it around by the header.</p>
<p>It stays on top of everything else.</p>
</Popup>
</div>
<style>
.logo {
height: 6em;
padding: 1.5em;
will-change: filter;
transition: filter 300ms;
.app-container {
display: flex;
flex-direction: column;
height: 100vh;
width: 100vw;
overflow: hidden;
}
.logo:hover {
filter: drop-shadow(0 0 2em #646cffaa);
.main-content {
display: flex;
flex: 1;
overflow: hidden;
}
.logo.svelte:hover {
filter: drop-shadow(0 0 2em #ff3e00aa);
.main-content.panel-bottom {
flex-direction: column;
}
.read-the-docs {
color: #888;
.editor-area {
flex: 1;
overflow: hidden;
}
.icon-button {
padding: 0.5rem;
background-color: #333;
color: rgba(255, 255, 255, 0.87);
border: 1px solid #555;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
transition: background-color 0.2s;
}
.icon-button:hover {
background-color: #444;
border-color: #646cff;
}
h3 {
margin-top: 0;
color: rgba(255, 255, 255, 0.87);
}
p {
color: rgba(255, 255, 255, 0.7);
line-height: 1.6;
}
</style>