You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
svelte-kit-vice/src/uix/eidos/components/command/command-dialog.svelte

88 lines
2.4 KiB

<script lang="ts">
/**
* Eidos `<Command.Dialog>` — modal palette built on top of the eidos
* `<Dialog>` wrapper (so panel chrome + overlay + sizing stay
* consistent with the rest of the system). Mirrors soma's
* CommandDialog API but routes through the eidos layer.
*
* <Command.Dialog bind:open shortcut="mod+k">
* <Command.Input placeholder="Search…" />
* <Command.List>…</Command.List>
* </Command.Dialog>
*
* Default `shortcut='mod+k'` opens the dialog on the canonical
* keyboard binding. Set `shortcut={null}` to disable.
*/
import { ActiveEidos } from '$uix/eidos';
import { Dialog } from '$uix/eidos/components/dialog';
import CommandRoot from './command.svelte';
import type { CommandDialogProps } from './types';
import { bindCommandShortcut } from './command-shortcut.svelte';
let {
open = $bindable(false),
onOpenChange,
modal = true,
shortcut = 'mod+k',
size = 'md',
dialogSize = 'md',
// Command pass-through
label,
value = $bindable(''),
onValueChange,
search = $bindable(''),
onSearchChange,
shouldFilter = true,
filter,
loop = false,
vimBindings = true,
columns = 1,
disablePointerSelection = false,
overlay,
// Rename to avoid shadowing the inner snippet
children: bodyContent
}: CommandDialogProps = $props();
const eidos = ActiveEidos.require();
// Uses `$effect` (see command.svelte — visual layer can't import
// Svelte 4 lifecycle hooks). DOM binding via `eidos.dom.listen(...)`
// inside `bindCommandShortcut` so the ActiveDom layer owns cleanup.
$effect(() => {
if (!shortcut) return undefined;
return bindCommandShortcut(eidos.dom, shortcut, () => {
const next = !open;
open = next;
onOpenChange?.(next);
});
});
</script>
<Dialog bind:open {modal} onOpenChange={(v) => onOpenChange?.(v)}>
<Dialog.Portal>
{#if overlay}{@render overlay()}{:else}<Dialog.Overlay />{/if}
<Dialog.Content size={dialogSize}>
<Dialog.Close position="top-right" variant="ghost" color="neutral" />
<CommandRoot
{label}
onSelect={() => (open = false)}
bind:value
onValueChange={(v) => onValueChange?.(v)}
bind:search
onSearchChange={(v) => onSearchChange?.(v)}
{shouldFilter}
{filter}
{loop}
{vimBindings}
{columns}
{disablePointerSelection}
{size}
>
{#snippet children(snippetProps)}
{@render bodyContent?.(snippetProps)}
{/snippet}
</CommandRoot>
</Dialog.Content>
</Dialog.Portal>
</Dialog>

Powered by TurnKey Linux.