0
# React Components
1
2
Pre-built React components and hooks for creating link editing interfaces, toolbar buttons, and form inputs with full integration into the Plate editor ecosystem.
3
4
## Capabilities
5
6
### Link Element Hook
7
8
#### useLink
9
10
React hook for rendering link elements with proper event handling and attributes.
11
12
```typescript { .api }
13
/**
14
* React hook for link element rendering with event handling
15
* @param props - Hook configuration with link element
16
* @returns Props object for anchor element
17
*/
18
function useLink({ element }: { element: TLinkElement }): {
19
props: React.AnchorHTMLAttributes<HTMLAnchorElement>;
20
};
21
```
22
23
**Usage Examples:**
24
25
```typescript
26
import React from 'react';
27
import { useLink } from "@udecode/plate-link/react";
28
29
function LinkElement({ element, children }) {
30
const { props } = useLink({ element });
31
32
return (
33
<a {...props}>
34
{children}
35
</a>
36
);
37
}
38
39
// Usage in PlateContent rendering
40
function CustomLinkElement({ element, children, ...props }) {
41
const { props: linkProps } = useLink({ element });
42
43
return (
44
<a
45
{...linkProps}
46
className="custom-link-style"
47
onContextMenu={(e) => {
48
// Custom context menu logic
49
console.log('Right-clicked link:', element.url);
50
}}
51
>
52
{children}
53
</a>
54
);
55
}
56
```
57
58
**Generated Props:**
59
60
- `href`: Processed URL with encoding
61
- `target`: Target attribute (if specified)
62
- `rel`: Security attributes for external links
63
- `onClick`: Click handler for editor integration
64
- `onMouseDown`: Mouse event handling
65
66
### Toolbar Integration
67
68
#### useLinkToolbarButton
69
70
Hook pair providing state and behavior for link toolbar buttons.
71
72
```typescript { .api }
73
/**
74
* Get toolbar button state based on current selection
75
* @returns State object with pressed status
76
*/
77
function useLinkToolbarButtonState(): { pressed: boolean };
78
79
/**
80
* Get toolbar button behavior and event handlers
81
* @param state - State from useLinkToolbarButtonState
82
* @returns Props object with click handlers
83
*/
84
function useLinkToolbarButton(
85
state: ReturnType<typeof useLinkToolbarButtonState>
86
): {
87
props: {
88
pressed: boolean;
89
onClick: () => void;
90
onMouseDown: (e: React.MouseEvent) => void;
91
};
92
};
93
```
94
95
**Usage Examples:**
96
97
```typescript
98
import React from 'react';
99
import {
100
useLinkToolbarButtonState,
101
useLinkToolbarButton
102
} from "@udecode/plate-link/react";
103
104
function LinkToolbarButton() {
105
const state = useLinkToolbarButtonState();
106
const { props } = useLinkToolbarButton(state);
107
108
return (
109
<button
110
{...props}
111
className={`toolbar-button ${props.pressed ? 'active' : ''}`}
112
title="Add Link (Ctrl+K)"
113
>
114
๐
115
</button>
116
);
117
}
118
119
// With custom styling and icons
120
function CustomLinkButton() {
121
const state = useLinkToolbarButtonState();
122
const { props } = useLinkToolbarButton(state);
123
124
return (
125
<button
126
{...props}
127
className={`btn ${props.pressed ? 'btn-active' : 'btn-default'}`}
128
>
129
<LinkIcon />
130
{props.pressed ? 'Edit Link' : 'Add Link'}
131
</button>
132
);
133
}
134
```
135
136
### Pre-built Form Components
137
138
#### FloatingLinkUrlInput
139
140
Pre-configured input component for URL entry with validation and state management.
141
142
```typescript { .api }
143
/**
144
* Get state for URL input component
145
* @returns State object with input ref
146
*/
147
function useFloatingLinkUrlInputState(): {
148
ref: RefObject<HTMLInputElement>
149
};
150
151
/**
152
* Get props and behavior for URL input
153
* @param state - State from useFloatingLinkUrlInputState
154
* @returns Input props and ref
155
*/
156
function useFloatingLinkUrlInput(state: ReturnType<typeof useFloatingLinkUrlInputState>): {
157
props: {
158
defaultValue: string;
159
onChange: ChangeEventHandler<HTMLInputElement>;
160
};
161
ref: RefObject<HTMLInputElement>;
162
};
163
164
/**
165
* Pre-built URL input component
166
*/
167
const FloatingLinkUrlInput: React.FC;
168
```
169
170
**Usage Examples:**
171
172
```typescript
173
import React from 'react';
174
import {
175
FloatingLinkUrlInput,
176
useFloatingLinkUrlInputState,
177
useFloatingLinkUrlInput
178
} from "@udecode/plate-link/react";
179
180
// Using pre-built component
181
function SimpleFloatingForm() {
182
return (
183
<div className="floating-link-form">
184
<FloatingLinkUrlInput />
185
<button type="submit">Save</button>
186
</div>
187
);
188
}
189
190
// Using hooks for custom component
191
function CustomUrlInput() {
192
const state = useFloatingLinkUrlInputState();
193
const { props, ref } = useFloatingLinkUrlInput(state);
194
195
return (
196
<div className="url-input-wrapper">
197
<label htmlFor="url-input">URL:</label>
198
<input
199
{...props}
200
ref={ref}
201
id="url-input"
202
className="url-input"
203
placeholder="https://example.com"
204
autoFocus
205
/>
206
</div>
207
);
208
}
209
```
210
211
#### FloatingLinkNewTabInput
212
213
Pre-configured checkbox component for new tab option.
214
215
```typescript { .api }
216
/**
217
* Get state for new tab checkbox component
218
* @returns State object with checkbox state and ref
219
*/
220
function useFloatingLinkNewTabInputState(): {
221
checked: boolean;
222
ref: RefObject<HTMLInputElement>;
223
setChecked: Dispatch<SetStateAction<boolean>>;
224
};
225
226
/**
227
* Get props and behavior for new tab checkbox
228
* @param state - State from useFloatingLinkNewTabInputState
229
* @returns Checkbox props and ref
230
*/
231
function useFloatingLinkNewTabInput(
232
state: ReturnType<typeof useFloatingLinkNewTabInputState>
233
): {
234
props: {
235
checked: boolean;
236
type: 'checkbox';
237
onChange: ChangeEventHandler<HTMLInputElement>;
238
};
239
ref: RefObject<HTMLInputElement>;
240
};
241
242
/**
243
* Pre-built new tab checkbox component
244
*/
245
const FloatingLinkNewTabInput: React.FC;
246
```
247
248
**Usage Examples:**
249
250
```typescript
251
import React from 'react';
252
import {
253
FloatingLinkNewTabInput,
254
useFloatingLinkNewTabInputState,
255
useFloatingLinkNewTabInput
256
} from "@udecode/plate-link/react";
257
258
// Using pre-built component
259
function FloatingFormWithNewTab() {
260
return (
261
<div className="floating-link-form">
262
<FloatingLinkUrlInput />
263
<label>
264
<FloatingLinkNewTabInput />
265
Open in new tab
266
</label>
267
<button type="submit">Save</button>
268
</div>
269
);
270
}
271
272
// Using hooks for custom component
273
function CustomNewTabCheckbox() {
274
const state = useFloatingLinkNewTabInputState();
275
const { props, ref } = useFloatingLinkNewTabInput(state);
276
277
return (
278
<div className="checkbox-wrapper">
279
<input
280
{...props}
281
ref={ref}
282
id="new-tab-checkbox"
283
className="new-tab-checkbox"
284
/>
285
<label htmlFor="new-tab-checkbox">
286
Open link in new tab
287
</label>
288
</div>
289
);
290
}
291
```
292
293
### Deprecated Components
294
295
#### LinkOpenButton
296
297
Legacy component for opening links (deprecated in favor of direct link interaction).
298
299
```typescript { .api }
300
/**
301
* @deprecated Use direct link interaction instead
302
* Get state for link open button
303
*/
304
function useLinkOpenButtonState(): { element?: TLinkElement };
305
306
/**
307
* @deprecated Use direct link interaction instead
308
* Get props for link open button
309
*/
310
function useLinkOpenButton({ element }: { element?: TLinkElement }): {
311
props: React.AnchorHTMLAttributes<HTMLAnchorElement>;
312
};
313
314
/**
315
* @deprecated Use direct link interaction instead
316
* Pre-built link open button component
317
*/
318
const LinkOpenButton: React.FC;
319
```
320
321
### Advanced Component Patterns
322
323
#### Custom Form Components
324
325
```typescript
326
import React from 'react';
327
import {
328
useFloatingLinkUrlInputState,
329
useFloatingLinkUrlInput,
330
useFloatingLinkNewTabInputState,
331
useFloatingLinkNewTabInput,
332
submitFloatingLink
333
} from "@udecode/plate-link/react";
334
import { useEditorPlugin } from '@udecode/plate/react';
335
import { LinkPlugin } from '@udecode/plate-link/react';
336
337
function CustomFloatingLinkForm() {
338
const { editor } = useEditorPlugin(LinkPlugin);
339
340
const urlState = useFloatingLinkUrlInputState();
341
const { props: urlProps, ref: urlRef } = useFloatingLinkUrlInput(urlState);
342
343
const newTabState = useFloatingLinkNewTabInputState();
344
const { props: newTabProps, ref: newTabRef } = useFloatingLinkNewTabInput(newTabState);
345
346
const handleSubmit = (e: React.FormEvent) => {
347
e.preventDefault();
348
const success = submitFloatingLink(editor);
349
if (success) {
350
console.log('Link submitted successfully');
351
}
352
};
353
354
return (
355
<form onSubmit={handleSubmit} className="floating-link-form">
356
<div className="form-group">
357
<label htmlFor="url">URL</label>
358
<input
359
{...urlProps}
360
ref={urlRef}
361
id="url"
362
className="form-control"
363
placeholder="Enter URL..."
364
/>
365
</div>
366
367
<div className="form-group">
368
<label className="checkbox-label">
369
<input
370
{...newTabProps}
371
ref={newTabRef}
372
className="checkbox"
373
/>
374
Open in new tab
375
</label>
376
</div>
377
378
<div className="form-actions">
379
<button type="submit" className="btn-primary">
380
Save Link
381
</button>
382
<button
383
type="button"
384
onClick={() => editor.api.floatingLink.hide()}
385
className="btn-secondary"
386
>
387
Cancel
388
</button>
389
</div>
390
</form>
391
);
392
}
393
```
394
395
#### Toolbar Integration
396
397
```typescript
398
import React from 'react';
399
import {
400
useLinkToolbarButtonState,
401
useLinkToolbarButton
402
} from "@udecode/plate-link/react";
403
404
function LinkToolbar() {
405
const linkState = useLinkToolbarButtonState();
406
const { props: linkProps } = useLinkToolbarButton(linkState);
407
408
return (
409
<div className="toolbar">
410
<button
411
{...linkProps}
412
className={`toolbar-btn ${linkProps.pressed ? 'active' : ''}`}
413
title="Link (Ctrl+K)"
414
>
415
<LinkIcon />
416
</button>
417
</div>
418
);
419
}
420
```