or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

core-plugin.mdfloating-interface.mdindex.mdreact-components.mdreact-integration.mdtransforms.mdurl-utils.md

floating-interface.mddocs/

0

# Floating Link Interface

1

2

Complete floating UI system for inserting and editing links with keyboard shortcuts, positioning, and form management. Provides modal-style interfaces that appear contextually based on user interactions.

3

4

## Capabilities

5

6

### Floating Link Triggers

7

8

#### triggerFloatingLink

9

10

Main entry point for showing floating link interface based on current mode and state.

11

12

```typescript { .api }

13

/**

14

* Trigger floating link interface based on current mode

15

* @param editor - Slate editor instance

16

* @param options - Optional focus behavior

17

*/

18

function triggerFloatingLink(

19

editor: SlateEditor,

20

options?: { focused?: boolean }

21

): void;

22

```

23

24

**Usage Examples:**

25

26

```typescript

27

import { triggerFloatingLink } from "@udecode/plate-link/react";

28

29

// Trigger from keyboard shortcut

30

function handleKeyboardShortcut(editor: SlateEditor) {

31

triggerFloatingLink(editor, { focused: true });

32

}

33

34

// Trigger from toolbar button

35

function handleToolbarClick(editor: SlateEditor) {

36

triggerFloatingLink(editor);

37

}

38

```

39

40

#### triggerFloatingLinkInsert

41

42

Specifically triggers the floating interface in insert mode for creating new links.

43

44

```typescript { .api }

45

/**

46

* Trigger floating link interface in insert mode

47

* @param editor - Slate editor instance

48

* @param options - Optional focus behavior

49

* @returns Whether the trigger was successful

50

*/

51

function triggerFloatingLinkInsert(

52

editor: SlateEditor,

53

options?: { focused?: boolean }

54

): boolean | undefined;

55

```

56

57

**Usage Examples:**

58

59

```typescript

60

import { triggerFloatingLinkInsert } from "@udecode/plate-link/react";

61

62

// Trigger insert mode

63

function handleAddLink(editor: SlateEditor) {

64

const success = triggerFloatingLinkInsert(editor, { focused: true });

65

if (!success) {

66

console.log("Cannot insert link in current context");

67

}

68

}

69

70

// Check selection before triggering

71

function handleToolbarInsert(editor: SlateEditor) {

72

if (editor.selection) {

73

triggerFloatingLinkInsert(editor);

74

} else {

75

alert("Please select text to create a link");

76

}

77

}

78

```

79

80

#### triggerFloatingLinkEdit

81

82

Triggers the floating interface in edit mode for modifying existing links.

83

84

```typescript { .api }

85

/**

86

* Trigger floating link interface in edit mode for existing links

87

* @param editor - Slate editor instance

88

* @returns Whether edit mode was successfully triggered

89

*/

90

function triggerFloatingLinkEdit(

91

editor: SlateEditor

92

): boolean | undefined;

93

```

94

95

**Usage Examples:**

96

97

```typescript

98

import { triggerFloatingLinkEdit } from "@udecode/plate-link/react";

99

100

// Trigger edit mode

101

function handleEditLink(editor: SlateEditor) {

102

const success = triggerFloatingLinkEdit(editor);

103

if (!success) {

104

console.log("No link found at current selection");

105

}

106

}

107

108

// Context menu integration

109

function handleLinkContextMenu(editor: SlateEditor, event: MouseEvent) {

110

event.preventDefault();

111

triggerFloatingLinkEdit(editor);

112

}

113

```

114

115

### Floating Insert Interface

116

117

#### useFloatingLinkInsert

118

119

Complete hook system for managing floating link insertion UI with positioning and form handling.

120

121

```typescript { .api }

122

/**

123

* Get state for floating link insert interface

124

* @param options - Optional floating toolbar configuration

125

* @returns State object with floating UI data

126

*/

127

function useFloatingLinkInsertState(options?: LinkFloatingToolbarState): {

128

floating: ReturnType<typeof useVirtualFloating>;

129

focused: boolean;

130

isOpen: boolean;

131

readOnly: boolean;

132

triggerFloatingLinkHotkeys: string;

133

};

134

135

/**

136

* Get props and behavior for floating link insert interface

137

* @param state - State from useFloatingLinkInsertState

138

* @returns Interface props, refs, and input handling

139

*/

140

function useFloatingLinkInsert(

141

state: ReturnType<typeof useFloatingLinkInsertState>

142

): {

143

hidden: boolean;

144

props: object;

145

ref: RefObject<HTMLElement>;

146

textInputProps: object;

147

};

148

149

interface LinkFloatingToolbarState {

150

floatingOptions?: UseVirtualFloatingOptions;

151

}

152

```

153

154

**Usage Examples:**

155

156

```typescript

157

import React from 'react';

158

import {

159

useFloatingLinkInsertState,

160

useFloatingLinkInsert,

161

FloatingLinkUrlInput

162

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

163

164

function FloatingLinkInsertPopover() {

165

const state = useFloatingLinkInsertState({

166

floatingOptions: {

167

placement: 'bottom-start',

168

offset: 4

169

}

170

});

171

172

const { hidden, props, ref, textInputProps } = useFloatingLinkInsert(state);

173

174

if (hidden) return null;

175

176

return (

177

<div

178

{...props}

179

ref={ref}

180

className="floating-link-popover"

181

>

182

<div className="popover-content">

183

<FloatingLinkUrlInput />

184

<div className="popover-actions">

185

<button type="submit">Add Link</button>

186

<button type="button" onClick={() => /* close */}>

187

Cancel

188

</button>

189

</div>

190

</div>

191

</div>

192

);

193

}

194

```

195

196

### Floating Edit Interface

197

198

#### useFloatingLinkEdit

199

200

Complete hook system for managing floating link editing UI with existing link data population.

201

202

```typescript { .api }

203

/**

204

* Get state for floating link edit interface

205

* @param options - Optional floating toolbar configuration

206

* @returns Comprehensive state with editor and floating data

207

*/

208

function useFloatingLinkEditState(options?: LinkFloatingToolbarState): {

209

editor: SlateEditor;

210

floating: ReturnType<typeof useVirtualFloating>;

211

isEditing: boolean;

212

isOpen: boolean;

213

readOnly: boolean;

214

triggerFloatingLinkHotkeys: string;

215

versionEditor: number;

216

};

217

218

/**

219

* Get props and behavior for floating link edit interface

220

* @param state - State from useFloatingLinkEditState

221

* @returns Edit interface props and button handlers

222

*/

223

function useFloatingLinkEdit(

224

state: ReturnType<typeof useFloatingLinkEditState>

225

): {

226

editButtonProps: object;

227

props: object;

228

ref: RefObject<HTMLElement>;

229

unlinkButtonProps: object;

230

};

231

```

232

233

**Usage Examples:**

234

235

```typescript

236

import React from 'react';

237

import {

238

useFloatingLinkEditState,

239

useFloatingLinkEdit,

240

FloatingLinkUrlInput,

241

FloatingLinkNewTabInput

242

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

243

244

function FloatingLinkEditPopover() {

245

const state = useFloatingLinkEditState();

246

const {

247

editButtonProps,

248

props,

249

ref,

250

unlinkButtonProps

251

} = useFloatingLinkEdit(state);

252

253

if (!state.isOpen) return null;

254

255

return (

256

<div

257

{...props}

258

ref={ref}

259

className="floating-link-edit-popover"

260

>

261

<div className="popover-content">

262

<FloatingLinkUrlInput />

263

<FloatingLinkNewTabInput />

264

265

<div className="popover-actions">

266

<button {...editButtonProps}>

267

Save Changes

268

</button>

269

<button {...unlinkButtonProps} className="btn-danger">

270

Remove Link

271

</button>

272

</div>

273

</div>

274

</div>

275

);

276

}

277

```

278

279

### Virtual Floating Positioning

280

281

#### useVirtualFloatingLink

282

283

Manages virtual floating positioning for link UI elements relative to editor selection.

284

285

```typescript { .api }

286

/**

287

* Manage virtual floating positioning for link UI

288

* @param config - Editor ID and floating options

289

* @returns Virtual floating positioning data

290

*/

291

function useVirtualFloatingLink({

292

editorId,

293

...floatingOptions

294

}: {

295

editorId: string;

296

} & UseVirtualFloatingOptions): ReturnType<typeof useVirtualFloating>;

297

```

298

299

**Usage Examples:**

300

301

```typescript

302

import React from 'react';

303

import { useVirtualFloatingLink } from "@udecode/plate-link/react";

304

import { useEditorPlugin } from '@udecode/plate/react';

305

import { LinkPlugin } from '@udecode/plate-link/react';

306

307

function CustomFloatingLink() {

308

const { editor } = useEditorPlugin(LinkPlugin);

309

310

const floating = useVirtualFloatingLink({

311

editorId: editor.id,

312

placement: 'bottom',

313

offset: 8,

314

autoUpdate: true

315

});

316

317

return (

318

<div

319

ref={floating.refs.setFloating}

320

style={{

321

position: floating.strategy,

322

top: floating.y ?? 0,

323

left: floating.x ?? 0,

324

zIndex: 1000

325

}}

326

className="custom-floating-link"

327

>

328

{/* Floating UI content */}

329

</div>

330

);

331

}

332

```

333

334

### Keyboard Handling

335

336

#### useFloatingLinkEscape

337

338

Handles escape key behavior for closing floating link interfaces.

339

340

```typescript { .api }

341

/**

342

* Handle escape key behavior for floating link UI

343

*/

344

function useFloatingLinkEscape(): void;

345

```

346

347

#### useFloatingLinkEnter

348

349

Handles enter key submission for floating link forms.

350

351

```typescript { .api }

352

/**

353

* Handle enter key submission for floating link forms

354

*/

355

function useFloatingLinkEnter(): void;

356

```

357

358

**Usage Examples:**

359

360

```typescript

361

import React from 'react';

362

import {

363

useFloatingLinkEscape,

364

useFloatingLinkEnter

365

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

366

367

function FloatingLinkForm() {

368

// Enable keyboard handling

369

useFloatingLinkEscape();

370

useFloatingLinkEnter();

371

372

return (

373

<form className="floating-link-form">

374

{/* Form fields */}

375

<input placeholder="Enter URL..." />

376

<div className="form-hint">

377

Press Enter to save, Escape to cancel

378

</div>

379

</form>

380

);

381

}

382

```

383

384

### Advanced Floating Patterns

385

386

#### Custom Floating UI with Full Control

387

388

```typescript

389

import React from 'react';

390

import {

391

useFloatingLinkInsertState,

392

useFloatingLinkInsert,

393

useFloatingLinkEscape,

394

useFloatingLinkEnter,

395

submitFloatingLink

396

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

397

import { useEditorPlugin } from '@udecode/plate/react';

398

import { LinkPlugin } from '@udecode/plate-link/react';

399

400

function AdvancedFloatingLink() {

401

const { editor } = useEditorPlugin(LinkPlugin);

402

403

const state = useFloatingLinkInsertState({

404

floatingOptions: {

405

placement: 'bottom-start',

406

middleware: [

407

{ name: 'offset', options: { mainAxis: 8 } },

408

{ name: 'flip' },

409

{ name: 'shift', options: { padding: 8 } }

410

]

411

}

412

});

413

414

const { hidden, props, ref } = useFloatingLinkInsert(state);

415

416

// Enable keyboard shortcuts

417

useFloatingLinkEscape();

418

useFloatingLinkEnter();

419

420

const handleSubmit = () => {

421

const success = submitFloatingLink(editor);

422

if (success) {

423

editor.api.floatingLink.hide();

424

}

425

};

426

427

if (hidden) return null;

428

429

return (

430

<div

431

{...props}

432

ref={ref}

433

className="advanced-floating-link"

434

>

435

<div className="floating-header">

436

<h3>Add Link</h3>

437

<button

438

onClick={() => editor.api.floatingLink.hide()}

439

className="close-button"

440

>

441

×

442

</button>

443

</div>

444

445

<form onSubmit={handleSubmit}>

446

<div className="form-fields">

447

<input placeholder="https://example.com" />

448

<label>

449

<input type="checkbox" />

450

Open in new tab

451

</label>

452

</div>

453

454

<div className="form-actions">

455

<button type="submit">Add Link</button>

456

<button type="button" onClick={() => editor.api.floatingLink.hide()}>

457

Cancel

458

</button>

459

</div>

460

</form>

461

</div>

462

);

463

}

464

```

465

466

#### Contextual Floating Behavior

467

468

```typescript

469

import {

470

triggerFloatingLinkInsert,

471

triggerFloatingLinkEdit

472

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

473

474

function handleFloatingLinkTrigger(editor: SlateEditor) {

475

// Check if cursor is in existing link

476

const linkEntry = editor.api.above({

477

match: { type: 'a' }

478

});

479

480

if (linkEntry) {

481

// Edit existing link

482

triggerFloatingLinkEdit(editor);

483

} else {

484

// Insert new link

485

triggerFloatingLinkInsert(editor, { focused: true });

486

}

487

}

488

489

// Keyboard shortcut handler

490

function setupFloatingLinkShortcut(editor: SlateEditor) {

491

const handleKeyDown = (event: KeyboardEvent) => {

492

if ((event.ctrlKey || event.metaKey) && event.key === 'k') {

493

event.preventDefault();

494

handleFloatingLinkTrigger(editor);

495

}

496

};

497

498

document.addEventListener('keydown', handleKeyDown);

499

return () => document.removeEventListener('keydown', handleKeyDown);

500

}

501

```