or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

core-plugin.mdhooks-and-utilities.mdindex.mdreact-components.md

react-components.mddocs/

0

# React Components

1

2

React components provide the UI layer for caption functionality with primitive, unstyled components that can be fully customized and themed.

3

4

## Capabilities

5

6

### CaptionPlugin

7

8

React-compatible version of BaseCaptionPlugin for use in React Plate editors.

9

10

```typescript { .api }

11

/**

12

* React plugin wrapper for caption functionality

13

*/

14

const CaptionPlugin = toPlatePlugin(BaseCaptionPlugin);

15

```

16

17

**Usage Examples:**

18

19

```typescript

20

import { createPlateEditor } from "@udecode/plate/react";

21

import { CaptionPlugin } from "@udecode/plate-caption/react";

22

23

const editor = createPlateEditor({

24

plugins: [

25

CaptionPlugin.configure({

26

options: {

27

query: { allow: ['img', 'media'] }

28

}

29

})

30

]

31

});

32

```

33

34

### Caption Container

35

36

Main caption container component that renders as a `figcaption` element with visibility and state management.

37

38

```typescript { .api }

39

/**

40

* Caption container component

41

* @param props - Standard figcaption props plus caption options

42

* @returns JSX.Element or null if hidden

43

*/

44

function Caption(props: CaptionProps): JSX.Element;

45

46

interface CaptionProps extends React.ComponentPropsWithoutRef<'figcaption'> {

47

options?: CaptionOptions;

48

}

49

50

interface CaptionOptions {

51

readOnly?: boolean;

52

}

53

54

/**

55

* State hook for Caption component

56

* @param options - Caption configuration options

57

* @returns State object with caption data and visibility flags

58

*/

59

function useCaptionState(options?: CaptionOptions): {

60

captionString: string;

61

hidden: boolean;

62

readOnly: boolean;

63

selected: boolean;

64

};

65

66

/**

67

* Props hook for Caption component

68

* @param state - State from useCaptionState

69

* @returns Props object for caption element

70

*/

71

function useCaption(state: ReturnType<typeof useCaptionState>): {

72

hidden: boolean;

73

};

74

```

75

76

**Usage Examples:**

77

78

```typescript

79

import { Caption } from "@udecode/plate-caption/react";

80

81

// Basic usage

82

function ImageWithCaption() {

83

return (

84

<div>

85

<img src="example.jpg" />

86

<Caption className="image-caption">

87

Caption content here

88

</Caption>

89

</div>

90

);

91

}

92

93

// With read-only option

94

function ReadOnlyCaption() {

95

return (

96

<Caption options={{ readOnly: true }}>

97

This caption cannot be edited

98

</Caption>

99

);

100

}

101

102

// Custom styling

103

function StyledCaption() {

104

return (

105

<Caption

106

style={{ fontStyle: 'italic', color: '#666' }}

107

className="custom-caption"

108

>

109

Styled caption content

110

</Caption>

111

);

112

}

113

```

114

115

### CaptionTextarea

116

117

Editable textarea component for caption text with auto-resizing, focus management, and keyboard navigation.

118

119

```typescript { .api }

120

/**

121

* Auto-resizing textarea for caption editing

122

* @param props - TextareaAutosize props

123

* @returns JSX.Element

124

*/

125

function CaptionTextarea(

126

props: React.ComponentProps<typeof TextareaAutosize>

127

): JSX.Element;

128

129

/**

130

* State hook for CaptionTextarea component

131

* @returns State object with handlers and refs

132

*/

133

function useCaptionTextareaState(): {

134

captionValue: string;

135

element: TCaptionElement;

136

readOnly: boolean;

137

textareaRef: React.RefObject<HTMLTextAreaElement>;

138

handleChange: (e: React.ChangeEvent<HTMLTextAreaElement>) => void;

139

handleCompositionEnd: (e: React.CompositionEvent<HTMLTextAreaElement>) => void;

140

handleCompositionStart: () => void;

141

};

142

143

/**

144

* Props hook for CaptionTextarea component

145

* @param state - State from useCaptionTextareaState

146

* @returns Props and ref for textarea element

147

*/

148

function useCaptionTextarea(

149

state: ReturnType<typeof useCaptionTextareaState>

150

): {

151

props: {

152

readOnly: boolean;

153

value: string;

154

onBlur: (e: React.FocusEvent<HTMLTextAreaElement>) => void;

155

onChange: (e: React.ChangeEvent<HTMLTextAreaElement>) => void;

156

onCompositionEnd: (e: React.CompositionEvent<HTMLTextAreaElement>) => void;

157

onCompositionStart: () => void;

158

onKeyDown: (e: React.KeyboardEvent<HTMLTextAreaElement>) => void;

159

};

160

ref: React.RefObject<HTMLTextAreaElement>;

161

};

162

163

/**

164

* Focus management hook for caption textarea

165

* @param textareaRef - Ref to textarea element

166

*/

167

function useCaptionTextareaFocus(

168

textareaRef: React.RefObject<HTMLTextAreaElement | null>

169

): void;

170

```

171

172

**Key Features:**

173

174

- **Auto-resize**: Automatically adjusts height based on content

175

- **Focus Management**: Integrates with plugin focus path system

176

- **Keyboard Navigation**: Up/down arrows move between editor and caption

177

- **Composition Handling**: Proper support for IME input methods

178

- **Auto-save**: Changes are automatically saved to editor state

179

180

**Usage Examples:**

181

182

```typescript

183

import { CaptionTextarea } from "@udecode/plate-caption/react";

184

185

// Basic usage

186

function EditableCaption() {

187

return (

188

<CaptionTextarea

189

placeholder="Enter image caption..."

190

className="caption-input"

191

/>

192

);

193

}

194

195

// With custom props

196

function CustomCaption() {

197

return (

198

<CaptionTextarea

199

placeholder="Describe this image..."

200

maxRows={3}

201

style={{

202

border: '1px solid #ccc',

203

borderRadius: '4px',

204

padding: '8px'

205

}}

206

/>

207

);

208

}

209

210

// In combination with Caption container

211

function CompleteCaption() {

212

return (

213

<Caption>

214

<CaptionTextarea placeholder="Add caption..." />

215

</Caption>

216

);

217

}

218

```

219

220

### TextareaAutosize

221

222

Auto-resizing textarea primitive with SSR compatibility.

223

224

```typescript { .api }

225

/**

226

* Auto-resizing textarea component

227

* @param props - Standard textarea props plus autosize options

228

* @param ref - Ref to textarea element

229

* @returns JSX.Element or null during SSR

230

*/

231

const TextareaAutosize = React.forwardRef<

232

HTMLTextAreaElement,

233

TextareaAutosizeProps

234

>((props, ref) => JSX.Element);

235

236

interface TextareaAutosizeProps {

237

maxRows?: number;

238

minRows?: number;

239

onHeightChange?: (height: number, meta: { rowHeight: number }) => void;

240

cacheMeasurements?: boolean;

241

[key: string]: any; // Standard textarea props

242

}

243

```

244

245

**Usage Examples:**

246

247

```typescript

248

import { TextareaAutosize } from "@udecode/plate-caption/react";

249

250

// Basic auto-resize textarea

251

function AutoTextarea() {

252

return (

253

<TextareaAutosize

254

placeholder="Type here..."

255

minRows={2}

256

maxRows={8}

257

/>

258

);

259

}

260

261

// With height change callback

262

function MonitoredTextarea() {

263

const handleHeightChange = (height: number) => {

264

console.log('Textarea height changed to:', height);

265

};

266

267

return (

268

<TextareaAutosize

269

onHeightChange={handleHeightChange}

270

placeholder="Resizing textarea..."

271

/>

272

);

273

}

274

```

275

276

### Caption Button Components

277

278

Utility components for caption interaction buttons.

279

280

```typescript { .api }

281

/**

282

* State hook for caption button functionality

283

* @returns State with editor and element references

284

*/

285

function useCaptionButtonState(): {

286

editor: SlateEditor;

287

element: TElement;

288

};

289

290

/**

291

* Props hook for caption button

292

* @param state - State from useCaptionButtonState

293

* @returns Props with click handler

294

*/

295

function useCaptionButton(

296

state: ReturnType<typeof useCaptionButtonState>

297

): {

298

props: {

299

onClick: () => void;

300

};

301

};

302

```

303

304

**Usage Examples:**

305

306

```typescript

307

import { useCaptionButton, useCaptionButtonState } from "@udecode/plate-caption/react";

308

309

function CaptionToggleButton() {

310

const state = useCaptionButtonState();

311

const { props } = useCaptionButton(state);

312

313

return (

314

<button {...props} className="caption-toggle">

315

Add Caption

316

</button>

317

);

318

}

319

```

320

321

## Component Composition

322

323

Components are designed to be composed together for complete caption functionality:

324

325

```typescript

326

import {

327

Caption,

328

CaptionTextarea,

329

useCaptionButton,

330

useCaptionButtonState

331

} from "@udecode/plate-caption/react";

332

333

function MediaWithCaption({ src, alt }: { src: string; alt: string }) {

334

const buttonState = useCaptionButtonState();

335

const { props: buttonProps } = useCaptionButton(buttonState);

336

337

return (

338

<figure>

339

<img src={src} alt={alt} />

340

<Caption>

341

<CaptionTextarea placeholder="Add a caption..." />

342

</Caption>

343

<button {...buttonProps} className="add-caption-btn">

344

๐Ÿ“ Add Caption

345

</button>

346

</figure>

347

);

348

}

349

```

350

351

## Styling and Customization

352

353

All components are unstyled primitives that accept standard HTML props and can be fully customized:

354

355

```typescript

356

// CSS-in-JS styling

357

const StyledCaption = styled(Caption)`

358

font-style: italic;

359

color: #666;

360

text-align: center;

361

margin-top: 8px;

362

`;

363

364

// Tailwind classes

365

<Caption className="text-sm text-gray-600 italic text-center">

366

<CaptionTextarea className="w-full border rounded p-2" />

367

</Caption>

368

369

// Inline styles

370

<Caption style={{ fontFamily: 'Georgia, serif' }}>

371

<CaptionTextarea style={{ backgroundColor: '#f9f9f9' }} />

372

</Caption>

373

```