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.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144<script lang="ts"> import type { Snippet } from 'svelte'; import { dismissal, fitted } from './popover';
// A title-bar icon that lists things: the session's background jobs, the // artifacts it made, the agents it started. The list closes on a pick, a click elsewhere or Escape; // `up` opens it above the icon, for the phone's composer; `inline` renders the list // straight into the body of an undocked chip window. let { label, count = 0, live = false, up = false, inline = false, open = $bindable(false), icon, children, }: { label: string; count?: number; live?: boolean; up?: boolean; inline?: boolean; open?: boolean; icon: Snippet; children: Snippet } = $props(); let element = $state<HTMLElement>();
$effect(() => (open && !inline ? dismissal((target) => !!element?.contains(target), () => (open = false)) : undefined));</script>
{#if inline} <ul class="list inline nowheel holds-wheel"> {@render children()} </ul>{:else} <span class="menu nodrag" class:open bind:this={element}> <button class="icon" class:live aria-haspopup="true" aria-expanded={open} aria-label={label} title={label} onclick={() => (open = !open)}> {@render icon()} {#if count}<span class="count">{count}</span>{/if} </button> {#if open} <ul class="list nowheel holds-wheel" class:up {@attach fitted(up)} > {@render children()} </ul> {/if} </span>{/if}
<style> .menu { position: relative; display: inline-flex; } .menu.open { z-index: 30; } .icon { display: inline-flex; align-items: center; gap: 4px; height: 26px; padding: 0 7px; color: var(--muted); font: inherit; font-size: calc(11.5px * var(--ui-scale)); background: var(--well); border: 0; border-radius: 8px; cursor: pointer; transition: background-color 120ms ease, color 120ms ease; } .icon:hover, .icon[aria-expanded='true'] { color: var(--text); background: var(--field); } .icon.live { color: var(--accent); } .count { font-variant-numeric: tabular-nums; } .list { position: absolute; top: calc(100% + 6px); right: 0; z-index: 20; width: min(340px, 80vw); max-height: 260px; margin: 0; padding: 4px; overflow-y: auto; overscroll-behavior: contain; list-style: none; background: var(--surface); border-radius: 12px; box-shadow: var(--shadow-raised); } /* Alone on a canvas the list is as tall as itself, up to a cap; in a tile or a group it fills its place. */ :global(.window-slot[data-place='canvas']) .list.inline { max-height: 280px; } .list.up { top: auto; bottom: calc(100% + 6px); right: auto; left: 0; } .list.inline { position: static; z-index: auto; flex: 1 1 auto; width: 100%; max-height: none; min-height: 0; padding: 4px 6px 8px; background: none; border-radius: 0 0 14px 14px; box-shadow: none; } .list :global(li > button) { display: grid; grid-template-columns: minmax(0, 1fr) auto auto; align-items: baseline; gap: 10px; width: 100%; padding: 7px 10px; color: var(--text); font: inherit; font-size: calc(12.5px * var(--ui-scale)); text-align: left; background: none; border: 0; border-radius: 8px; cursor: pointer; } .list :global(li > button:hover) { background: var(--hover); } .list :global(.when) { color: var(--muted); font-size: calc(11.5px * var(--ui-scale)); font-variant-numeric: tabular-nums; white-space: nowrap; }</style>