feat: Improved placeholder and upload handling for images

This commit is contained in:
Arek Nawo
2026-01-19 16:54:24 +01:00
parent 5510434221
commit 5bda5623f2
8 changed files with 137 additions and 126 deletions
@@ -43,7 +43,7 @@ export function ImageMenu({ editor }: EditorMenuProps) {
return false;
}
return editor.isActive("image");
return editor.isActive("image") && editor.getAttributes("image").src;
},
[editor],
);
@@ -0,0 +1,10 @@
.imagePlaceholder {
border-radius: 8px;
@mixin light {
background-color: var(--mantine-color-gray-0);
}
@mixin dark {
background-color: var(--mantine-color-dark-7);
}
}
@@ -3,11 +3,11 @@ import { useMemo } from "react";
import { Image } from "@mantine/core";
import { getFileUrl } from "@/lib/config.ts";
import clsx from "clsx";
import classes from "./image-view.module.css";
export default function ImageView(props: NodeViewProps) {
const { node, selected } = props;
const { src, width, align, title } = node.attrs;
const { src, width, align, title, aspectRatio } = node.attrs;
const alignClass = useMemo(() => {
if (align === "left") return "alignLeft";
if (align === "right") return "alignRight";
@@ -17,14 +17,21 @@ export default function ImageView(props: NodeViewProps) {
return (
<NodeViewWrapper data-drag-handle>
<Image
radius="md"
fit="contain"
w={width}
src={getFileUrl(src)}
alt={title}
className={clsx(selected ? "ProseMirror-selectednode" : "", alignClass)}
/>
<div
className={clsx(
selected ? "ProseMirror-selectednode" : "",
classes.imagePlaceholder,
alignClass,
)}
style={{
aspectRatio: aspectRatio ? aspectRatio : src ? undefined : "16 / 9",
width,
}}
>
{src && (
<Image radius="md" fit="contain" src={getFileUrl(src)} alt={title} />
)}
</div>
</NodeViewWrapper>
);
}
@@ -174,9 +174,13 @@ const CommandGroups: SlashMenuGroupedItemsType = {
if (input.files?.length) {
for (const file of input.files) {
const pos = editor.view.state.selection.from;
uploadImageAction(file, editor.view, pos, pageId);
}
}
// Reset the input value to allow uploading the same file again if needed
input.value = "";
};
input.click();
},