diff --git a/src/uix/eidos/components/words/words-block-gutter.svelte b/src/uix/eidos/components/words/words-block-gutter.svelte index 84dcd4180..536b86ddb 100644 --- a/src/uix/eidos/components/words/words-block-gutter.svelte +++ b/src/uix/eidos/components/words/words-block-gutter.svelte @@ -26,6 +26,7 @@ type ProviderSnippetProps, type WordsBlockMenuEntry } from '$soma/components/words'; + import { pickImageFile } from './words-image-file'; let { api, @@ -206,32 +207,13 @@ // until the user picks a file or types a URL). The gutter inserter // opens a file picker → FileReader → data URL when an image entry // is selected, then inserts the block with a valid `src`. URLs from - // real backends would replace this with a fetch + upload. + // real backends would replace this with a fetch + upload. The picker + // flow is shared with the inspector's image panel (`pickImageFile`). function insertImageInteractive() { const doc = - (typeof document !== 'undefined' ? document : null) ?? - content?.ownerDocument ?? - null; + (typeof document !== 'undefined' ? document : null) ?? content?.ownerDocument ?? null; if (!doc) return; - const input = doc.createElement('input'); - input.type = 'file'; - input.accept = 'image/*'; - input.style.display = 'none'; - input.addEventListener('change', () => { - const file = input.files?.[0]; - input.remove(); - if (!file) return; - const reader = new FileReader(); - reader.onload = () => { - const src = typeof reader.result === 'string' ? reader.result : ''; - if (!src) return; - const alt = file.name.replace(/\.[^/.]+$/, '') || undefined; - insert({ type: 'image', src, alt }); - }; - reader.readAsDataURL(file); - }); - doc.body.appendChild(input); - input.click(); + pickImageFile(doc, (src, alt) => insert({ type: 'image', src, alt })); } function handleInsert(entry: WordsBlockMenuEntry) { @@ -303,7 +285,8 @@ {#if inGutter || menuOpen}
{/if}