fix: route clipboard image pastes to the attachment strip #295

Merged
talksik merged 5 commits from claude/markdown-image-upload-fix-t9ggfa into main 2026-06-21 16:15:21 +00:00
2 changed files with 12 additions and 31 deletions
Showing only changes of commit 3a7d9a7c31 - Show all commits
@@ -110,26 +110,12 @@
margin-top: 0;
}
/* Images come from URLs only (no stable public upload URL), so hide the
* file uploader — the placeholder then just prompts for a link. */
.llink-crepe
.milkdown
:is(.milkdown-image-block, .milkdown-image-inline)
.placeholder
.uploader {
display: none;
}
/* Read-only renders the image node view with inert editing chrome — hide it. */
.llink-crepe:not(.llink-crepe--fill) .milkdown .milkdown-image-block .operation,
.llink-crepe:not(.llink-crepe--fill)
.milkdown
.milkdown-image-block
.image-resize-handle {
display: none;
}
.llink-crepe .milkdown .milkdown-image-block img {
/* Image *links* render through the base commonmark schema (the ImageBlock
* feature is off — see markdown-editor.tsx). Keep them within the content
* column and softly rounded. */
.llink-crepe .milkdown .ProseMirror img {
max-width: 100%;
max-height: 420px;
border-radius: 8px;
}
@@ -57,23 +57,18 @@ export function MarkdownEditor({
[Crepe.Feature.BlockEdit]: !readOnly,
[Crepe.Feature.Toolbar]: !readOnly,
[Crepe.Feature.Placeholder]: !readOnly,
[Crepe.Feature.ImageBlock]: true,
// Off on purpose: file uploads aren't supported, so this feature's
// paste/drop handler would only strand an "upload in progress" node in
// the editor. Image *links* still render through the base commonmark
// schema, and pasted image files are routed to the compose attachment
// strip (see use-file-input).
[Crepe.Feature.ImageBlock]: false,
[Crepe.Feature.Latex]: false,
[Crepe.Feature.TopBar]: false,
[Crepe.Feature.AI]: false,
},
featureConfigs: {
[Crepe.Feature.Placeholder]: { text: placeholder ?? '' },
// Images come from URLs only (e.g. pasted markdown) — there is no
// stable public upload URL, so the file uploader is hidden in CSS and
// onUpload rejects in case a file ever reaches it anyway (the default
// would serialize an ephemeral blob: URL into the message).
[Crepe.Feature.ImageBlock]: {
blockUploadPlaceholderText: 'Paste an image link…',
inlineUploadPlaceholderText: 'paste an image link',
maxHeight: 420,
onUpload: () => Promise.reject(new Error('Image uploads disabled')),
},
},
});