0
# React Components
1
2
Complete set of React components for rendering images with captions, resizing handles, and interactive features.
3
4
## Capabilities
5
6
### Image Component Namespace
7
8
Main component namespace containing all image-related React components.
9
10
```typescript { .api }
11
/**
12
* Image component namespace containing all image-related components
13
* Provides a structured way to access different image rendering components
14
*/
15
const Image: {
16
/** Root image element component */
17
Root: React.ComponentType<any>;
18
/** Image caption component */
19
Caption: React.ComponentType<ImageCaptionProps>;
20
/** Image display component */
21
Img: React.ComponentType<any>;
22
/** Resizable image wrapper component */
23
Resizable: React.ComponentType<ImageResizableProps>;
24
/** Caption textarea component */
25
CaptionTextarea: React.ComponentType<ImageCaptionTextareaProps>;
26
};
27
```
28
29
**Usage Examples:**
30
31
```typescript
32
import { Image } from "@udecode/plate-image";
33
34
// Complete image component with all features
35
function MyImageRenderer() {
36
return (
37
<Image.Root>
38
<Image.Resizable align="center">
39
<Image.Img />
40
</Image.Resizable>
41
<Image.Caption>
42
<Image.CaptionTextarea />
43
</Image.Caption>
44
</Image.Root>
45
);
46
}
47
48
// Minimal image component
49
function SimpleImageRenderer() {
50
return (
51
<Image.Root>
52
<Image.Img />
53
</Image.Root>
54
);
55
}
56
```
57
58
### Image Root Component
59
60
Base root component for image elements created using Plate's element component factory.
61
62
```typescript { .api }
63
/**
64
* Root image element component created via createPlateElementComponent
65
* Serves as the container for all image-related content and components
66
*/
67
const ImageRoot: React.ComponentType<any>;
68
```
69
70
### Image Caption Component
71
72
Conditionally rendered caption component that displays when caption content exists or when the image is selected in edit mode.
73
74
```typescript { .api }
75
/**
76
* Image caption component that conditionally renders based on content and editor state
77
* Automatically hides when no caption exists and image is not selected in read-only mode
78
*/
79
const ImageCaption: React.ComponentType<ImageCaptionProps>;
80
81
interface ImageCaptionProps extends HTMLPropsAs<'figcaption'> {
82
/** Override read-only state (inherits from editor if not specified) */
83
readOnly?: boolean;
84
}
85
```
86
87
**Caption Display Logic:**
88
- Shows when caption has content
89
- Shows when image is selected in edit mode (even without content)
90
- Hides when no content and in read-only mode or image not selected
91
92
**Usage Examples:**
93
94
```typescript
95
import { Image, ImageCaptionProps } from "@udecode/plate-image";
96
97
// Basic caption
98
function BasicCaption() {
99
return <Image.Caption />;
100
}
101
102
// Caption with custom styling
103
function StyledCaption() {
104
return (
105
<Image.Caption
106
className="custom-caption"
107
style={{ fontStyle: 'italic', textAlign: 'center' }}
108
/>
109
);
110
}
111
112
// Read-only caption
113
function ReadOnlyCaption() {
114
return <Image.Caption readOnly={true} />;
115
}
116
```
117
118
### Image Display Component
119
120
Component that renders the actual image element with proper source and accessibility attributes.
121
122
```typescript { .api }
123
/**
124
* Image display component that renders the actual img element
125
* Automatically sets src from element URL and alt from caption
126
*/
127
const ImageImg: React.ComponentType<any>;
128
```
129
130
**Automatic Behavior:**
131
- Sets `src` attribute from image element's `url` property
132
- Sets `alt` attribute from caption text content
133
- Enables dragging with `draggable={true}`
134
- Accepts additional HTML img attributes as props
135
136
**Usage Examples:**
137
138
```typescript
139
import { Image } from "@udecode/plate-image";
140
141
// Basic image
142
function BasicImage() {
143
return <Image.Img />;
144
}
145
146
// Image with custom attributes
147
function CustomImage() {
148
return (
149
<Image.Img
150
className="custom-image"
151
loading="lazy"
152
onLoad={() => console.log('Image loaded')}
153
/>
154
);
155
}
156
```
157
158
### Resizable Image Component
159
160
Wrapper component providing image resizing functionality using the re-resizable library.
161
162
```typescript { .api }
163
/**
164
* Resizable image wrapper component with alignment and interaction controls
165
* Provides drag handles for resizing images while maintaining aspect ratio
166
*/
167
const ImageResizable: React.ComponentType<ImageResizableProps>;
168
169
interface ImageResizableProps extends Omit<ResizableProps, 'as'>, AsProps<'div'> {
170
/** Image alignment affecting resize handle placement */
171
align?: 'left' | 'center' | 'right';
172
/** Override read-only state (disables resizing when true) */
173
readOnly?: boolean;
174
}
175
```
176
177
**Resizing Behavior:**
178
- **Left alignment**: Resize handle on right side only
179
- **Center alignment**: Resize handles on both sides (default)
180
- **Right alignment**: Resize handle on left side only
181
- **Aspect ratio**: Automatically maintained during resize
182
- **Minimum width**: 92 pixels
183
- **Maximum width**: 100% of container
184
185
**Usage Examples:**
186
187
```typescript
188
import { Image, ImageResizableProps } from "@udecode/plate-image";
189
190
// Center-aligned resizable image (default)
191
function CenterResizableImage() {
192
return (
193
<Image.Resizable>
194
<Image.Img />
195
</Image.Resizable>
196
);
197
}
198
199
// Left-aligned resizable image
200
function LeftResizableImage() {
201
return (
202
<Image.Resizable align="left">
203
<Image.Img />
204
</Image.Resizable>
205
);
206
}
207
208
// Read-only image (no resize handles)
209
function ReadOnlyImage() {
210
return (
211
<Image.Resizable readOnly={true}>
212
<Image.Img />
213
</Image.Resizable>
214
);
215
}
216
217
// Custom resize constraints
218
function CustomResizableImage() {
219
return (
220
<Image.Resizable
221
minWidth={200}
222
maxWidth={800}
223
onResize={(e, direction, ref) => {
224
console.log('Resizing to:', ref.offsetWidth);
225
}}
226
>
227
<Image.Img />
228
</Image.Resizable>
229
);
230
}
231
```
232
233
### Caption Textarea Component
234
235
Auto-resizing textarea component for editing image captions with keyboard navigation support.
236
237
```typescript { .api }
238
/**
239
* Auto-resizing textarea component for caption editing
240
* Handles keyboard navigation and integrates with image focus management
241
*/
242
const ImageCaptionTextarea: React.ComponentType<ImageCaptionTextareaProps>;
243
244
interface ImageCaptionTextareaProps
245
extends TextareaAutosizeProps,
246
RefAttributes<HTMLTextAreaElement>,
247
AsProps<'textarea'> {}
248
```
249
250
**Features:**
251
- Auto-resizes height based on content
252
- Keyboard navigation (up/down arrows)
253
- Focus management integration
254
- Real-time caption updates
255
- Read-only state inheritance
256
257
**Keyboard Behavior:**
258
- **Up arrow**: Focus the image element above
259
- **Down arrow**: Move to next block after image
260
261
**Usage Examples:**
262
263
```typescript
264
import { Image, ImageCaptionTextareaProps } from "@udecode/plate-image";
265
266
// Basic caption textarea
267
function BasicCaptionTextarea() {
268
return <Image.CaptionTextarea />;
269
}
270
271
// Styled caption textarea
272
function StyledCaptionTextarea() {
273
return (
274
<Image.CaptionTextarea
275
placeholder="Enter image caption..."
276
className="caption-input"
277
style={{
278
fontFamily: 'serif',
279
fontSize: '14px',
280
textAlign: 'center'
281
}}
282
/>
283
);
284
}
285
286
// Caption with event handlers
287
function InteractiveCaptionTextarea() {
288
return (
289
<Image.CaptionTextarea
290
onFocus={() => console.log('Caption focused')}
291
onBlur={() => console.log('Caption blurred')}
292
onChange={(e) => console.log('Caption changed:', e.target.value)}
293
/>
294
);
295
}
296
```
297
298
### Auto-resize Textarea Base Component
299
300
Base textarea component with auto-resize functionality, used internally by the caption textarea.
301
302
```typescript { .api }
303
/**
304
* Auto-sizing textarea component wrapper around react-textarea-autosize
305
* Handles re-rendering issues and provides consistent auto-resize behavior
306
*/
307
const TextareaAutosize: React.ComponentType<TextareaAutosizeProps>;
308
```
309
310
**Internal Implementation Note:**
311
- Addresses re-rendering issues with react-textarea-autosize
312
- Uses `useLayoutEffect` to ensure proper rendering timing
313
- Can be used independently for other auto-resize textarea needs
314
315
### Component Hook Functions
316
317
Advanced hook functions for customizing component behavior and accessing internal component state.
318
319
```typescript { .api }
320
/**
321
* Image caption hook providing style properties and behavior configuration
322
* @param props - ImageCaptionProps configuration
323
* @returns HTMLPropsAs<'figcaption'> with computed properties including width styling
324
*/
325
function useImageCaption(props?: ImageCaptionProps): HTMLPropsAs<'figcaption'>;
326
327
/**
328
* Image caption state hook providing caption content and interaction state
329
* @param props - ImageCaptionProps configuration
330
* @returns Object containing captionString, selected state, and readOnly state
331
*/
332
function useImageCaptionState(props: ImageCaptionProps): {
333
captionString: string;
334
selected: boolean;
335
readOnly: boolean;
336
};
337
338
/**
339
* Image resizable hook providing resizable configuration and behavior
340
* @param props - ImageResizableProps with alignment and resizing options
341
* @returns ResizableProps configured for the image element with proper constraints
342
*/
343
function useImageResizable(props?: ImageResizableProps): ResizableProps;
344
```
345
346
**Hook Usage Examples:**
347
348
```typescript
349
import {
350
useImageCaption,
351
useImageCaptionState,
352
useImageResizable,
353
ImageCaptionProps,
354
ImageResizableProps
355
} from "@udecode/plate-image";
356
357
// Custom caption component using hooks
358
function CustomImageCaption(props: ImageCaptionProps) {
359
const htmlProps = useImageCaption(props);
360
const { captionString, selected, readOnly } = useImageCaptionState(props);
361
362
// Custom rendering logic
363
if (!captionString.length && (readOnly || !selected)) {
364
return null;
365
}
366
367
return <figcaption {...htmlProps}>Custom caption: {captionString}</figcaption>;
368
}
369
370
// Custom resizable component using hooks
371
function CustomImageResizable(props: ImageResizableProps) {
372
const resizableProps = useImageResizable({
373
align: 'center',
374
minWidth: 150,
375
...props
376
});
377
378
return <Resizable {...resizableProps} />;
379
}
380
```
381
382
## Component Composition Patterns
383
384
### Complete Image with All Features
385
386
```typescript
387
function FullFeaturedImage() {
388
return (
389
<Image.Root>
390
<Image.Resizable align="center">
391
<Image.Img />
392
</Image.Resizable>
393
<Image.Caption>
394
<Image.CaptionTextarea placeholder="Add a caption..." />
395
</Image.Caption>
396
</Image.Root>
397
);
398
}
399
```
400
401
### Read-Only Image Display
402
403
```typescript
404
function ReadOnlyImageDisplay() {
405
return (
406
<Image.Root>
407
<Image.Resizable readOnly={true}>
408
<Image.Img />
409
</Image.Resizable>
410
<Image.Caption readOnly={true} />
411
</Image.Root>
412
);
413
}
414
```
415
416
### Minimal Image Component
417
418
```typescript
419
function MinimalImage() {
420
return (
421
<Image.Root>
422
<Image.Img />
423
</Image.Root>
424
);
425
}
426
```
427
428
## Integration with Plate Editor
429
430
These components are designed to be used with Plate's rendering system:
431
432
```typescript
433
import { createPlateEditor } from "@udecode/plate-core";
434
import { createImagePlugin, Image, ELEMENT_IMAGE } from "@udecode/plate-image";
435
436
const editor = createPlateEditor({
437
plugins: [
438
createImagePlugin()
439
],
440
components: {
441
[ELEMENT_IMAGE]: FullFeaturedImage, // Use your composed component
442
}
443
});
444
```