diff --git a/src/uix/eidos/components/words/words-drawer.svelte b/src/uix/eidos/components/words/words-drawer.svelte index e91f19b1f..593e71aa2 100644 --- a/src/uix/eidos/components/words/words-drawer.svelte +++ b/src/uix/eidos/components/words/words-drawer.svelte @@ -13,6 +13,7 @@ * just paints them. */ import { ChevronRight, ChevronLeft, ChevronDown, ChevronUp } from '$uix/eidos/components/icon'; + import { Editable } from '$uix/eidos/components/editable'; import * as Words from '$soma/components/words'; import type { DrawerSnippetProps, @@ -65,10 +66,13 @@ function imageBlockAtCaret(s: ProviderSnippetProps): | { - readonly src: string; - readonly alt?: string; - readonly caption?: string; - readonly status?: 'pending' | 'error'; + readonly index: number; + readonly block: { + readonly src: string; + readonly alt?: string; + readonly caption?: string; + readonly status?: 'pending' | 'error'; + }; } | undefined { // Atomic block selection wins (image is contenteditable=false so @@ -81,7 +85,7 @@ if (blockIndex === undefined) return undefined; const block = s.document.children[blockIndex]; if (!block || block.type !== 'image') return undefined; - return block; + return { index: blockIndex, block }; } const CODE_LANGUAGES = [ @@ -545,18 +549,64 @@ {/snippet} {#snippet imagePanel(s: ProviderSnippetProps)} - {@const block = imageBlockAtCaret(s)} - {#if block} + {@const entry = imageBlockAtCaret(s)} + {#if entry} + {@const block = entry.block} + {@const blockIndex = entry.index}
Source

{block.src}

Alt
-

- {block.alt || '(missing)'} -

- {#if block.caption} -
Caption
-

{block.caption}

- {/if} + + s.applyCommand({ + type: 'updateBlock', + blockIndex, + patch: { alt: next } + })} + > + + + + + + Edit + Save + Cancel + + +
Caption
+ + s.applyCommand({ + type: 'updateBlock', + blockIndex, + patch: { caption: next || undefined } + })} + > + + + + + + Edit + Save + Cancel + + {#if block.status}
Status

diff --git a/src/uix/soma/components/words/types.ts b/src/uix/soma/components/words/types.ts index 617bcca56..6f9781e96 100644 --- a/src/uix/soma/components/words/types.ts +++ b/src/uix/soma/components/words/types.ts @@ -100,6 +100,14 @@ export type WordsCommandName = export type WordsProviderSnippetProps = { readonly document: WordsDocument; readonly selection: WordsSelection | null; + /** + * Index of an atomic block currently selected via `selectAtomicBlock` + * (e.g. click on an image). Coexists with `selection` but takes + * priority for block-scoped UIs (drawer image panel, float bar) + * because atomic blocks are `contenteditable=false` and the text + * selection rarely points at them. + */ + readonly selectedBlockIndex: number | undefined; readonly plainText: string; readonly isEmpty: boolean; readonly isFocused: boolean;