Something went wrong. Try again.
small gleam coding and persistent agent daemon with a detachable cli and a canvas ui forked from okami.mom/albedo
Something went wrong. Try again.
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485<script lang="ts"> import { Handle, NodeResizer, Position, type NodeProps } from '@xyflow/svelte'; import { limits, type SlotNode } from '../board.svelte'; import SectionHead from '../tiles/SectionHead.svelte'; import { getContext, setContext } from 'svelte'; import TileView, { DEPTH } from '../tiles/TileView.svelte'; import WindowSlot from '../tiles/WindowSlot.svelte';
// Whatever sits on a canvas, a window or a tile of them: edges and corners // that resize it, the ends the lines between windows meet, and the slot // the window itself is carried into. Notes size and tie themselves. Tiled // windows sit in a group with a header of its own: it moves them together, // carries their name and lets them go again. A canvas sits in one the same // way, its header closing it instead. Filling the board, either is drawn // there (tiles/BoardView.svelte) and its place here stays empty. let { id, data }: NodeProps<SlotNode> = $props(); const type = $derived(data.tile.kind === 'leaf' ? data.board.windows[data.tile.window]?.type : undefined); const limit = $derived(limits(type)); const away = $derived(data.board.expandedOver && data.board.expanded === data.tile.id); const selected = $derived(data.board.selected === data.tile.id); const naming = { get: () => data.board.naming === data.tile.id, set: (on: boolean) => (data.board.naming = on ? data.tile.id : null) }; // A group or a canvas is a section: the ones inside it sit a step deeper. const outer = getContext<(() => number) | undefined>(DEPTH) ?? (() => 0); setContext(DEPTH, () => outer() + 1);</script>
{#if type !== 'note'} <NodeResizer minWidth={limit.minWidth} minHeight={limit.minHeight} lineClass="window-edge" handleClass="window-corner" onResizeStart={() => (data.board.resizing = true)} onResizeEnd={() => (data.board.resizing = false)} /> <!-- Where the lines between a window and the views it opened meet it, on whichever side faces the other (board.edgesOf); nothing to grab. --> {#each [Position.Left, Position.Right, Position.Top, Position.Bottom] as position (position)} <Handle id={position} type="target" {position} isConnectable={false} class="tether-end" /> <Handle id={position} type="source" {position} isConnectable={false} class="tether-end" /> {/each}{/if}{#if data.tile.kind === 'leaf'} <WindowSlot board={data.board} window={data.tile.window} />{:else if data.tile.kind === 'canvas'} <div class="group tray" class:nested={outer() > 0} class:selected style:--depth={outer()}> <SectionHead class="canvas-handle" data-pane={data.tile.id} name={data.tile.name ?? ''} placeholder="canvas" bind:renaming={naming.get, naming.set} onrename={(name) => data.board.rename(data.tile.id, name)} onungroup={() => data.board.ungroupCanvas(data.tile.id)} onclose={() => data.board.closeTile(data.tile.id)} expanded={away} onexpand={() => data.board.toggleExpanded(data.tile.id)} /> <div class="tiled"> {#if !away}<TileView board={data.board} tile={data.tile} />{/if} </div> </div>{:else} <div class="group tray" class:selected data-section={data.tile.id}> <SectionHead class="group-handle" data-pane={data.tile.id} name={data.tile.name ?? ''} placeholder="group" bind:renaming={naming.get, naming.set} onrename={(name) => data.board.rename(data.tile.id, name)} onungroup={() => data.board.ungroup(id)} expanded={away} onexpand={() => data.board.toggleExpanded(data.tile.id)} /> <div class="tiled"> {#if !away}<TileView board={data.board} tile={data.tile} headed={false} />{/if} </div> </div>{/if}
<style> .group { position: relative; display: flex; flex-direction: column; width: 100%; height: 100%; } /* Selected, as a window is (tiles/WindowSlot.svelte): its name in the accent and a faint ring. */ .selected > :global(.section-head) { color: var(--accent); } .selected::after { position: absolute; inset: 0; border-radius: inherit; box-shadow: 0 0 0 1px color-mix(in oklab, var(--accent) 35%, transparent); content: ''; pointer-events: none; } :global([data-theme='dark']) .selected::after { box-shadow: 0 0 0 1px color-mix(in oklab, var(--accent) 55%, transparent); } /* A flex parent, as the board view is: a split or tabs grows to fill it. */ .tiled { position: relative; display: flex; flex: 1; min-height: 0; padding: 0 6px 6px; }</style>