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.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170<script lang="ts"> import { onMount, type Snippet } from 'svelte';
// Filterable picker card shared by the command palette (⌘K), the model // selector, and the new-session folder picker: a solid `--well` card with a // `--surface` search pill (`❯` prompt and inset focus ring) at the top, a // scrollable list body, and an optional footer slot. let { query = $bindable(''), list = $bindable(), placeholder = '', ariaLabel, ariaControls, ariaActivedescendant, autofocus = false, large = false, onkeydown, head, children, foot, }: { query?: string; list?: HTMLElement; placeholder?: string; ariaLabel?: string; ariaControls?: string; ariaActivedescendant?: string; autofocus?: boolean; /** Slightly taller header & 14px radius for the standalone command palette. */ large?: boolean; onkeydown?: (event: KeyboardEvent) => void; /** Custom header content (e.g. NewSession's directory breadcrumb bar) instead of the search input. */ head?: Snippet; children: Snippet; foot?: Snippet; } = $props();
let input = $state<HTMLInputElement>();
onMount(() => { if (autofocus) { input?.focus(); queueMicrotask(() => input?.focus()); } });</script>
<div class="search-card" class:large> {#if head} <div class="head custom"> {@render head()} </div> {:else} <label class="head"> <span class="prompt" aria-hidden="true">❯</span> <!-- svelte-ignore a11y_autofocus --> <input bind:this={input} bind:value={query} {autofocus} {onkeydown} type="text" {placeholder} spellcheck="false" autocomplete="off" aria-label={ariaLabel || placeholder} aria-controls={ariaControls} aria-activedescendant={ariaActivedescendant} /> </label> {/if}
<div class="list nowheel holds-wheel" id={ariaControls} role="listbox" aria-label={ariaLabel || placeholder} bind:this={list}> {@render children()} </div>
{#if foot} <div class="foot"> {@render foot()} </div> {/if}</div>
<style> .search-card { position: relative; display: flex; flex-direction: column; height: var(--selector-height, 320px); padding-top: 6px; overflow: hidden; background: var(--well); border-radius: 12px; } .search-card.large { height: auto; max-height: 420px; padding-top: 7px; border-radius: 14px; box-shadow: var(--shadow-lg); } .head { position: relative; z-index: 2; display: flex; flex: none; align-items: center; gap: 8px; margin: 0 6px 2px; padding: 7px 11px; background: var(--surface); border-radius: 8px; transition: box-shadow 120ms ease; } .large .head { margin: 0 7px 3px; padding: 9px 13px; border-radius: 9px; } .head:focus-within { box-shadow: inset 0 0 0 1.5px color-mix(in oklab, var(--surface) 45%, var(--accent) 55%); } .prompt { color: var(--accent); font-family: var(--mono); font-size: calc(12.5px * var(--ui-scale)); font-weight: 700; line-height: 1; } .head input { flex: 1; min-width: 0; padding: 0; color: var(--text); font: inherit; font-size: calc(13px * var(--ui-scale)); background: none; border: 0; outline: none; } .large .head input { font-size: calc(13.5px * var(--ui-scale)); } .head input::placeholder { color: var(--faint); } @media (max-width: 760px) { .head input { font-size: max(16px, calc(14px * var(--ui-scale))); } } .list { flex: 1; min-height: 0; padding: 5px 6px; overflow-y: auto; overscroll-behavior: contain; scrollbar-width: thin; } .foot { display: flex; flex: none; align-items: center; justify-content: space-between; gap: 8px; padding: 6px 10px 7px; border-top: 1px solid color-mix(in oklab, var(--text) 6%, transparent); }</style>