返回 presentation-ai
media-image-node.tsx
根目录 / src / components / plate / ui / media-image-node.tsx
1 "use client";
2
3 import { useDraggable } from "@platejs/dnd";
4 import { Image, ImagePlugin, useMediaState } from "@platejs/media/react";
5 import { ResizableProvider, useResizableValue } from "@platejs/resizable";
6 import { type TImageElement } from "platejs";
7 import { PlateElement, withHOC, type PlateElementProps } from "platejs/react";
8
9 import { cn } from "@/lib/utils";
10 import { Caption, CaptionTextarea } from "./caption";
11 import { MediaToolbar } from "./media-toolbar";
12 import { Resizable, ResizeHandle } from "./resize-handle";
13 import { mediaResizeHandleVariants } from "./resize-handle";
14
15 export const ImageElement = withHOC(
16 ResizableProvider,
17 function ImageElement(props: PlateElementProps<TImageElement>) {
18 const { align = "center", focused, readOnly, selected } = useMediaState();
19 const width = useResizableValue("width");
20
21 const { isDragging, handleRef } = useDraggable({
22 element: props.element,
23 });
24
25 return (
26 <MediaToolbar plugin={ImagePlugin}>
27 <PlateElement {...props} className="py-2.5">
28 <figure className="group relative m-0" contentEditable={false}>
29 <Resizable
30 align={align}
31 options={{
32 align,
33 readOnly,
34 }}
35 className={cn(!width && "w-full")}
36 >
37 <ResizeHandle
38 className={mediaResizeHandleVariants({ direction: "left" })}
39 options={{ direction: "left" }}
40 />
41 <Image
42 ref={handleRef}
43 className={cn(
44 "block w-full max-w-full cursor-pointer object-cover px-0",
45 "rounded-sm",
46 focused && selected && "ring-2 ring-ring ring-offset-2",
47 isDragging && "opacity-50",
48 )}
49 alt={(props.attributes as { alt?: string }).alt}
50 />
51 <ResizeHandle
52 className={mediaResizeHandleVariants({
53 direction: "right",
54 })}
55 options={{ direction: "right" }}
56 />
57 </Resizable>
58
59 <Caption style={{ width }} align={align}>
60 <CaptionTextarea
61 readOnly={readOnly}
62 onFocus={(e) => {
63 e.preventDefault();
64 }}
65 placeholder="Write a caption..."
66 />
67 </Caption>
68 </figure>
69
70 {props.children}
71 </PlateElement>
72 </MediaToolbar>
73 );
74 },
75 );
76
76 lines Plain Text