feat: update sidebar to svelte-5
All checks were successful
Deploy to GitHub Pages / build_site (push) Successful in 2m1s

This commit is contained in:
Max Richter
2026-01-18 18:39:02 +01:00
parent 8a540522dd
commit 80d3e117b4
8 changed files with 123 additions and 120 deletions

View File

@@ -1,12 +1,16 @@
<script lang="ts">
import { getContext } from "svelte";
import { getContext, type Snippet } from "svelte";
let index = -1;
let index = $state(-1);
let wrapper: HTMLDivElement;
$: if (index === -1) {
const { children } = $props<{ children?: Snippet }>();
$effect(() => {
if (index === -1) {
index = getContext<() => number>("registerCell")();
}
});
const sizes = getContext<{ value: string[] }>("sizes");
@@ -31,8 +35,8 @@
</script>
<svelte:window
on:mouseup={() => (mouseDown = false)}
on:mousemove={handleMouseMove}
onmouseup={() => (mouseDown = false)}
onmousemove={handleMouseMove}
/>
{#if index > 0}
@@ -40,12 +44,12 @@
class="seperator"
role="button"
tabindex="0"
on:mousedown={handleMouseDown}
onmousedown={handleMouseDown}
></div>
{/if}
<div class="cell" bind:this={wrapper}>
<slot />
{@render children?.()}
</div>
<style>

View File

@@ -1,9 +1,9 @@
<script lang="ts">
import { setContext } from "svelte";
import { setContext, type Snippet } from "svelte";
export let id = "grid-0";
const { children, id } = $props<{ children?: Snippet; id?: string }>();
setContext("grid-id", id);
</script>
<slot {id} />
{@render children({ id })}

View File

@@ -1,36 +1,39 @@
<script lang="ts">
import { getContext } from "svelte";
import type { Readable } from "svelte/store";
import { getContext, type Snippet } from "svelte";
import type { PanelState } from "./PanelState.svelte";
export let id: string;
export let icon: string = "";
export let title = "";
export let classes = "";
export let hidden: boolean | undefined = undefined;
const {
id,
icon = "",
title = "",
classes = "",
hidden,
children,
} = $props<{
id: string;
icon?: string;
title?: string;
classes?: string;
hidden?: boolean;
children?: Snippet;
}>();
const setVisibility =
getContext<(id: string, visible: boolean) => void>("setVisibility");
const panelState = getContext<PanelState>("panel-state");
$: if (typeof hidden === "boolean") {
setVisibility(id, !hidden);
}
const registerPanel =
getContext<
(id: string, icon: string, classes: string) => Readable<boolean>
>("registerPanel");
let visible = registerPanel(id, icon, classes);
const panel = panelState.registerPanel(id, icon, classes, hidden);
$effect(() => {
panel.hidden = hidden;
});
</script>
{#if $visible}
{#if panelState.activePanel.value === id}
<div class="wrapper" class:hidden>
{#if title}
<header>
<h3>{title}</h3>
</header>
{/if}
<slot />
{@render children?.()}
</div>
{/if}

View File

@@ -0,0 +1,35 @@
import { localState } from "$lib/helpers/localState.svelte";
type Panel = {
icon: string;
classes: string;
hidden?: boolean;
}
export class PanelState {
panels = $state<Record<string, Panel>>({});
activePanel = localState<string | boolean>("node.activePanel", "")
get keys() {
return Object.keys(this.panels);
}
public registerPanel(id: string, icon: string, classes: string, hidden: boolean): Panel {
const state = $state({
icon: icon,
classes: classes,
hidden: hidden,
});
this.panels[id] = state;
return state;
}
public toggleOpen() {
if (this.activePanel.value) {
this.activePanel.value = false;
} else {
this.activePanel.value = this.keys[0]
}
}
}

View File

@@ -1,78 +1,35 @@
<script lang="ts">
import localStore from "$lib/helpers/localStore";
import { setContext } from "svelte";
import { derived } from "svelte/store";
import { setContext, type Snippet } from "svelte";
import { PanelState } from "./PanelState.svelte";
let panels: Record<
string,
{
icon: string;
id: string;
classes: string;
visible?: boolean;
}
> = {};
const state = new PanelState();
setContext("panel-state", state);
const activePanel = localStore<keyof typeof panels | false>(
"nodes.settings.activePanel",
false,
);
$: keys = panels
? (Object.keys(panels) as unknown as (keyof typeof panels)[]).filter(
(key) => !!panels[key]?.id,
)
: [];
setContext("setVisibility", (id: string, visible: boolean) => {
panels[id].visible = visible;
panels = { ...panels };
});
setContext("registerPanel", (id: string, icon: string, classes: string) => {
panels[id] = { id, icon, classes };
return derived(activePanel, ($activePanel) => {
return $activePanel === id;
});
});
function setActivePanel(panel: keyof typeof panels | false) {
if (panel === $activePanel) {
$activePanel = false;
} else if (panel) {
$activePanel = panel;
} else {
$activePanel = false;
}
}
const { children } = $props<{ children?: Snippet }>();
</script>
<div class="wrapper" class:visible={$activePanel}>
<div class="wrapper" class:visible={state.activePanel.value}>
<div class="tabs">
<button
aria-label="Close"
on:click={() => {
setActivePanel($activePanel ? false : keys[0]);
}}
>
<button aria-label="Close" onclick={() => state.toggleOpen()}>
<span class="icon-[tabler--settings]"></span>
<span class="absolute i-[tabler--chevron-left] w-6 h-6 block"></span>
</button>
{#each keys as panel (panels[panel].id)}
{#if panels[panel].visible !== false}
{#each state.keys as panelId (panelId)}
{#if !state.panels[panelId].hidden}
<button
aria-label={panel}
class="tab {panels[panel].classes}"
class:active={panel === $activePanel}
on:click={() => setActivePanel(panel)}
aria-label={panelId}
class="tab {state.panels[panelId].classes}"
class:active={panelId === state.activePanel.value}
onclick={() => (state.activePanel.value = panelId)}
>
<span class={`block w-6 h-6 iconify ${panels[panel].icon}`}></span>
<span class={`block w-6 h-6 iconify ${state.panels[panelId].icon}`}
></span>
</button>
{/if}
{/each}
</div>
<div class="content">
<slot />
{@render children?.()}
</div>
</div>

View File

@@ -15,7 +15,7 @@
FileSaver.saveAs(blob, name + "." + extension);
};
export let scene: Group;
const { scene } = $props<{ scene: Group }>();
let gltfExporter: GLTFExporter;
async function exportGltf() {
@@ -53,7 +53,7 @@
}
</script>
<div class="p-2">
<button on:click={exportObj}> export obj </button>
<button on:click={exportGltf}> export gltf </button>
<div class="p-4">
<button onclick={exportObj}> export obj </button>
<button onclick={exportGltf}> export gltf </button>
</div>

View File

@@ -13,7 +13,8 @@
let { keymaps }: Props = $props();
</script>
<table class="wrapper">
<div class="p-4">
<table class="wrapper">
<tbody>
{#each keymaps as keymap}
<tr>
@@ -38,7 +39,8 @@
{/each}
{/each}
</tbody>
</table>
</table>
</div>
<style>
.wrapper {

View File

@@ -1,6 +1,8 @@
<script lang="ts">
import "@nodarium/ui/app.css";
import "../app.css";
import type { Snippet } from "svelte";
const { children } = $props<{ children?: Snippet }>();
</script>
<slot />
{@render children?.()}