or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

editor-enhancements.mdhooks-state.mdindex.mdplugin-configuration.mdreact-components.mdtransforms-utilities.mdtypes-interfaces.md

hooks-state.mddocs/

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

```