Fix the about page image display
This commit is contained in:
@ -5,6 +5,7 @@ import { saveAboutMeAction } from "@/actions/about/saveAbout";
|
||||
import { BasicBlocksKit } from "@/components/editor/plugins/basic-blocks-kit";
|
||||
import { BasicMarksKit } from "@/components/editor/plugins/basic-marks-kit";
|
||||
import { CodeBlockKit } from "@/components/editor/plugins/code-block-kit";
|
||||
import { ImageKit } from "@/components/editor/plugins/image-kit";
|
||||
import { ListKit } from "@/components/editor/plugins/list-kit";
|
||||
import { MarkdownKit } from "@/components/editor/plugins/markdown-kit";
|
||||
import { Button } from "@/components/ui/button";
|
||||
@ -43,6 +44,7 @@ export default function AboutEditor({ markdown }: { markdown: string | null }) {
|
||||
plugins: [
|
||||
...BasicBlocksKit,
|
||||
...CodeBlockKit,
|
||||
...ImageKit,
|
||||
...ListKit,
|
||||
...BasicMarksKit,
|
||||
...MarkdownKit,
|
||||
|
||||
15
src/components/editor/plugins/image-kit.tsx
Normal file
15
src/components/editor/plugins/image-kit.tsx
Normal file
@ -0,0 +1,15 @@
|
||||
'use client';
|
||||
|
||||
import { createPlatePlugin } from 'platejs/react';
|
||||
|
||||
import { ImageElement } from '@/components/ui/image-node';
|
||||
|
||||
// Minimal image plugin to render markdown images.
|
||||
export const ImageKit = [
|
||||
createPlatePlugin({
|
||||
key: 'img',
|
||||
node: {
|
||||
isElement: true,
|
||||
},
|
||||
}).withComponent(ImageElement),
|
||||
];
|
||||
76
src/components/ui/image-node.tsx
Normal file
76
src/components/ui/image-node.tsx
Normal file
@ -0,0 +1,76 @@
|
||||
'use client';
|
||||
|
||||
import * as React from 'react';
|
||||
|
||||
import type { PlateElementProps } from 'platejs/react';
|
||||
|
||||
import { PlateElement, useEditorRef, useFocused, useReadOnly, useSelected, useElement } from 'platejs/react';
|
||||
|
||||
import { cn } from '@/lib/utils';
|
||||
|
||||
type ImageElementData = {
|
||||
url?: string;
|
||||
src?: string;
|
||||
alt?: string;
|
||||
altText?: string;
|
||||
caption?: { text: string }[];
|
||||
};
|
||||
|
||||
export function ImageElement(props: PlateElementProps) {
|
||||
const editor = useEditorRef();
|
||||
const element = useElement<ImageElementData>();
|
||||
const readOnly = useReadOnly();
|
||||
const selected = useSelected();
|
||||
const focused = useFocused();
|
||||
const data = element ?? (props.element as ImageElementData);
|
||||
const src = data.url ?? data.src;
|
||||
const captionText =
|
||||
data.caption?.map((c) => c.text).join('') ?? data.alt ?? data.altText ?? '';
|
||||
const showCaptionEditor = !readOnly;
|
||||
const path = showCaptionEditor ? editor.api.findPath(element) : null;
|
||||
|
||||
return (
|
||||
<PlateElement {...props} className={cn('my-4')}>
|
||||
<figure className="w-full">
|
||||
{src ? (
|
||||
<img
|
||||
src={src}
|
||||
alt={captionText}
|
||||
className="max-w-full rounded-md border border-border"
|
||||
loading="lazy"
|
||||
contentEditable={false}
|
||||
/>
|
||||
) : (
|
||||
<div className="text-sm text-muted-foreground">Missing image source</div>
|
||||
)}
|
||||
<figcaption
|
||||
className="mt-2"
|
||||
contentEditable={false}
|
||||
onMouseDown={(e) => e.stopPropagation()}
|
||||
>
|
||||
{showCaptionEditor ? (
|
||||
<input
|
||||
type="text"
|
||||
value={captionText}
|
||||
onChange={(e) => {
|
||||
if (!path) return;
|
||||
editor.tf.setNodes<ImageElementData>(
|
||||
{ caption: [{ text: e.target.value }] },
|
||||
{ at: path }
|
||||
);
|
||||
}}
|
||||
placeholder="Add caption / alt text"
|
||||
className="w-full rounded-md border border-border bg-background px-3 py-2 text-sm text-foreground"
|
||||
onMouseDown={(e) => e.stopPropagation()}
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
onFocus={(e) => e.stopPropagation()}
|
||||
/>
|
||||
) : captionText ? (
|
||||
<div className="text-xs text-muted-foreground">{captionText}</div>
|
||||
) : null}
|
||||
</figcaption>
|
||||
</figure>
|
||||
{props.children}
|
||||
</PlateElement>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user