0
# Hooks and State Management
1
2
React hooks for accessing image element data, managing captions, and integrating with the image store system.
3
4
## Capabilities
5
6
### Image Element Hook
7
8
Hook to access the current image element data within image component contexts.
9
10
```typescript { .api }
11
/**
12
* Hook to get the current image element data
13
* Must be used within an image element component context
14
* @returns Current TImageElement with url, width, and caption properties
15
*/
16
function useImageElement(): TImageElement;
17
```
18
19
**Usage Examples:**
20
21
```typescript
22
import { useImageElement, TImageElement } from "@udecode/plate-image";
23
24
// Access image properties in component
25
function MyImageComponent() {
26
const element = useImageElement();
27
28
return (
29
<div>
30
<img src={element.url} style={{ width: element.width }} />
31
{element.caption && (
32
<figcaption>
33
Caption has {element.caption.length} nodes
34
</figcaption>
35
)}
36
</div>
37
);
38
}
39
40
// Conditional rendering based on image properties
41
function ConditionalImageRenderer() {
42
const element = useImageElement();
43
44
const hasCaption = element.caption && element.caption.length > 0;
45
const hasWidth = element.width && element.width > 0;
46
47
return (
48
<figure className={`image ${hasCaption ? 'with-caption' : ''}`}>
49
<img
50
src={element.url}
51
style={{
52
width: hasWidth ? `${element.width}px` : '100%',
53
maxWidth: '100%'
54
}}
55
draggable={true}
56
/>
57
{hasCaption && (
58
<figcaption>Image has caption content</figcaption>
59
)}
60
</figure>
61
);
62
}
63
```
64
65
### Image Caption String Hook
66
67
Hook to extract and memoize the caption text as a plain string from the image element.
68
69
```typescript { .api }
70
/**
71
* Hook to get image caption as a plain string
72
* Extracts text content from caption descendant nodes and memoizes the result
73
* @returns String representation of the caption content (empty string if no caption)
74
*/
75
function useImageCaptionString(): string;
76
```
77
78
**Usage Examples:**
79
80
```typescript
81
import { useImageCaptionString } from "@udecode/plate-image";
82
83
// Use caption string for alt text
84
function AccessibleImage() {
85
const captionString = useImageCaptionString();
86
const element = useImageElement();
87
88
return (
89
<img
90
src={element.url}
91
alt={captionString || 'Image'}
92
title={captionString}
93
/>
94
);
95
}
96
97
// Conditional rendering based on caption content
98
function CaptionDisplay() {
99
const captionString = useImageCaptionString();
100
101
if (!captionString.length) {
102
return <div className="no-caption">No caption available</div>;
103
}
104
105
return (
106
<figcaption className="image-caption">
107
{captionString}
108
<span className="caption-length">({captionString.length} characters)</span>
109
</figcaption>
110
);
111
}
112
113
// Search and filtering based on caption content
114
function SearchableImageList({ searchTerm }: { searchTerm: string }) {
115
const captionString = useImageCaptionString();
116
117
const matchesSearch = captionString.toLowerCase().includes(
118
searchTerm.toLowerCase()
119
);
120
121
if (!matchesSearch) return null;
122
123
return (
124
<div className="search-result">
125
<Image.Img />
126
<div className="caption-match">
127
Caption: "{captionString}"
128
</div>
129
</div>
130
);
131
}
132
```
133
134
## Store Management System
135
136
### Image Store
137
138
Atom store for managing image-specific state like width during resize operations.
139
140
```typescript { .api }
141
/**
142
* Atom store for image-specific state management
143
* Manages width property for individual image elements
144
*/
145
const imageStore: {
146
get: {
147
width(): CSSProperties['width'];
148
};
149
set: {
150
width(value: CSSProperties['width']): void;
151
};
152
};
153
154
/**
155
* Hook to access imageStore state
156
* Provides reactive access to image store properties
157
*/
158
function useImageStore(): {
159
get: {
160
width(): CSSProperties['width'];
161
};
162
set: {
163
width(value: CSSProperties['width']): void;
164
};
165
use: {
166
width(): [CSSProperties['width'], (value: CSSProperties['width']) => void];
167
};
168
};
169
```
170
171
**Usage Examples:**
172
173
```typescript
174
import { useImageStore } from "@udecode/plate-image";
175
176
// Access current width in resize component
177
function ResizeDisplayComponent() {
178
const imageStore = useImageStore();
179
const [width, setWidth] = imageStore.use.width();
180
181
return (
182
<div>
183
<div>Current width: {width}</div>
184
<button onClick={() => setWidth(300)}>
185
Set width to 300px
186
</button>
187
</div>
188
);
189
}
190
191
// Monitor width changes during resize
192
function ResizeMonitor() {
193
const imageStore = useImageStore();
194
const width = imageStore.get.width();
195
196
React.useEffect(() => {
197
console.log('Image width changed:', width);
198
}, [width]);
199
200
return <div>Width: {width}</div>;
201
}
202
```
203
204
### Global Image Store
205
206
Global store for managing cross-image state like caption focus coordination.
207
208
```typescript { .api }
209
/**
210
* Global store for cross-image state management
211
* Coordinates focus states across different image elements
212
*/
213
const imageGlobalStore: {
214
get: {
215
focusEndCaptionPath(): TPath | null;
216
focusStartCaptionPath(): TPath | null;
217
};
218
set: {
219
focusEndCaptionPath(path: TPath | null): void;
220
focusStartCaptionPath(path: TPath | null): void;
221
};
222
use: {
223
focusEndCaptionPath(): TPath | null;
224
focusStartCaptionPath(): TPath | null;
225
};
226
};
227
```
228
229
**Focus Management:**
230
- `focusEndCaptionPath`: Triggers focus to end of caption textarea for specified image path
231
- `focusStartCaptionPath`: Triggers focus to start of caption textarea for specified image path
232
- Paths are automatically cleared after focusing to prevent repeated focus events
233
234
**Usage Examples:**
235
236
```typescript
237
import { imageGlobalStore } from "@udecode/plate-image";
238
import { findNodePath } from "@udecode/plate-core";
239
240
// Programmatically focus image caption
241
function FocusImageCaption() {
242
const element = useImageElement();
243
const editor = useEditorRef();
244
245
const focusCaption = () => {
246
const path = findNodePath(editor, element);
247
if (path) {
248
imageGlobalStore.set.focusEndCaptionPath(path);
249
}
250
};
251
252
return (
253
<button onClick={focusCaption}>
254
Focus Image Caption
255
</button>
256
);
257
}
258
259
// Monitor focus state changes
260
function FocusStateMonitor() {
261
const focusPath = imageGlobalStore.use.focusEndCaptionPath();
262
263
return (
264
<div>
265
{focusPath ? (
266
<div>Caption focus requested for path: {focusPath.join('.')}</div>
267
) : (
268
<div>No caption focus pending</div>
269
)}
270
</div>
271
);
272
}
273
```
274
275
## Component Hook Integration Patterns
276
277
### Custom Image Component with Hooks
278
279
```typescript
280
import {
281
useImageElement,
282
useImageCaptionString,
283
useImageStore
284
} from "@udecode/plate-image";
285
286
function CustomImageComponent() {
287
// Access image data
288
const element = useImageElement();
289
const captionString = useImageCaptionString();
290
const imageStore = useImageStore();
291
292
// Local state for interaction
293
const [isHovered, setIsHovered] = React.useState(false);
294
const [width] = imageStore.use.width();
295
296
return (
297
<figure
298
className="custom-image"
299
onMouseEnter={() => setIsHovered(true)}
300
onMouseLeave={() => setIsHovered(false)}
301
>
302
<img
303
src={element.url}
304
alt={captionString}
305
style={{
306
width: width || element.width || '100%',
307
opacity: isHovered ? 0.9 : 1,
308
transition: 'opacity 0.2s'
309
}}
310
/>
311
312
{captionString && (
313
<figcaption style={{ fontStyle: 'italic' }}>
314
{captionString}
315
</figcaption>
316
)}
317
318
{isHovered && (
319
<div className="image-info">
320
Dimensions: {width || element.width || 'auto'}
321
</div>
322
)}
323
</figure>
324
);
325
}
326
```
327
328
### Hook Usage in Context
329
330
```typescript
331
// Custom hook combining multiple image hooks
332
function useImageInfo() {
333
const element = useImageElement();
334
const captionString = useImageCaptionString();
335
const imageStore = useImageStore();
336
337
return {
338
url: element.url,
339
width: element.width,
340
hasCaption: captionString.length > 0,
341
captionText: captionString,
342
storeWidth: imageStore.get.width(),
343
updateWidth: imageStore.set.width,
344
};
345
}
346
347
// Usage of custom hook
348
function ImageInfoDisplay() {
349
const info = useImageInfo();
350
351
return (
352
<div className="image-info">
353
<div>URL: {info.url}</div>
354
<div>Width: {info.width || 'auto'}</div>
355
<div>Store Width: {info.storeWidth}</div>
356
<div>Has Caption: {info.hasCaption ? 'Yes' : 'No'}</div>
357
{info.hasCaption && (
358
<div>Caption: "{info.captionText}"</div>
359
)}
360
</div>
361
);
362
}
363
```