or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

auto-scrolling.mdcomponent-utilities.mddrag-drop-hooks.mdeditor-transforms.mdindex.mdplugin-configuration.mdutility-functions.md

editor-transforms.mddocs/

0

# Editor Transforms

1

2

Functions for manipulating editor state during drag-and-drop operations. These transforms handle block selection, movement, focus management, and the core logic for processing drop operations within the Plate editor.

3

4

## Capabilities

5

6

### Block Selection Functions

7

8

Functions for selecting and focusing specific blocks within the editor during drag-and-drop operations.

9

10

### selectBlocksBySelectionOrId

11

12

Intelligently selects blocks based on current selection or by specific ID, providing contextual selection behavior.

13

14

```typescript { .api }

15

/**

16

* Select blocks by selection or by id

17

* If the block with id is not selected, select the block with id

18

* Else, select the blocks above the selection

19

* @param editor - The Plate editor instance

20

* @param id - The ID of the block to select

21

*/

22

export function selectBlocksBySelectionOrId(

23

editor: PlateEditor,

24

id: string

25

): void;

26

```

27

28

**Usage Examples:**

29

30

```typescript

31

import { selectBlocksBySelectionOrId } from "@udecode/plate-dnd";

32

33

// In a drag operation handler

34

function handleDragStart(editor: PlateEditor, blockId: string) {

35

// Select the dragged block or maintain current selection

36

selectBlocksBySelectionOrId(editor, blockId);

37

}

38

39

// In a drop handler

40

function handleBlockDrop(editor: PlateEditor, droppedBlockId: string) {

41

// Ensure proper selection after drop

42

selectBlocksBySelectionOrId(editor, droppedBlockId);

43

}

44

```

45

46

### selectBlockById

47

48

Selects a specific block by its ID and focuses the editor.

49

50

```typescript { .api }

51

/**

52

* Select the block above the selection by id and focus the editor

53

* @param editor - The editor instance

54

* @param id - The ID of the block to select

55

*/

56

export function selectBlockById(editor: Editor, id: string): void;

57

```

58

59

**Usage Examples:**

60

61

```typescript

62

import { selectBlockById } from "@udecode/plate-dnd";

63

64

// Select a specific block

65

function selectSpecificBlock(editor: Editor, blockId: string) {

66

selectBlockById(editor, blockId);

67

}

68

69

// In a component that needs to highlight a block

70

function HighlightableBlock({ blockId, children }) {

71

const editor = useEditorRef();

72

73

const handleClick = () => {

74

selectBlockById(editor, blockId);

75

};

76

77

return (

78

<div onClick={handleClick}>

79

{children}

80

</div>

81

);

82

}

83

```

84

85

### focusBlockStartById

86

87

Focuses the start of a specific block by its ID.

88

89

```typescript { .api }

90

/**

91

* Select the start of a block by id and focus the editor

92

* @param editor - The editor instance

93

* @param id - The ID of the block to focus

94

*/

95

export function focusBlockStartById(editor: Editor, id: string): void;

96

```

97

98

**Usage Examples:**

99

100

```typescript

101

import { focusBlockStartById } from "@udecode/plate-dnd";

102

103

// Focus at the beginning of a block after operation

104

function focusBlock(editor: Editor, blockId: string) {

105

focusBlockStartById(editor, blockId);

106

}

107

108

// In a navigation function

109

function navigateToBlock(editor: Editor, targetBlockId: string) {

110

focusBlockStartById(editor, targetBlockId);

111

}

112

```

113

114

### Block Removal Functions

115

116

Functions for removing blocks while maintaining proper editor focus and state.

117

118

### removeBlocksAndFocus

119

120

Removes blocks with specific IDs and maintains editor focus.

121

122

```typescript { .api }

123

/**

124

* Remove blocks with an id and focus the editor

125

* @param editor - The editor instance

126

* @param options - Options for finding blocks to remove

127

*/

128

export function removeBlocksAndFocus<E extends Editor = Editor>(

129

editor: E,

130

options: EditorNodesOptions<ValueOf<E>>

131

): void;

132

```

133

134

**Usage Examples:**

135

136

```typescript

137

import { removeBlocksAndFocus } from "@udecode/plate-dnd";

138

139

// Remove selected blocks

140

function removeSelectedBlocks(editor: Editor) {

141

if (!editor.selection) return;

142

143

removeBlocksAndFocus(editor, {

144

at: editor.selection

145

});

146

}

147

148

// Remove blocks of a specific type

149

function removeBlocksByType(editor: Editor, blockType: string) {

150

removeBlocksAndFocus(editor, {

151

match: n => n.type === blockType

152

});

153

}

154

155

// In a delete handler

156

function handleDeleteBlocks(editor: Editor, blockIds: string[]) {

157

removeBlocksAndFocus(editor, {

158

match: n => blockIds.includes(n.id as string)

159

});

160

}

161

```

162

163

### Drop Operation Functions

164

165

Core functions that handle the drag-and-drop logic, including path calculation and node movement.

166

167

### onDropNode

168

169

Handles the actual drop operation when a dragged node is dropped onto a target.

170

171

```typescript { .api }

172

/**

173

* Handles drop operations for dragged nodes

174

* Calculates drop paths and moves nodes to new positions

175

* @param editor - The Plate editor instance

176

* @param options - Drop operation configuration

177

*/

178

export function onDropNode(

179

editor: PlateEditor,

180

options: OnDropNodeOptions

181

): void;

182

183

export interface OnDropNodeOptions {

184

/** Function to validate if drop is allowed */

185

canDropNode?: CanDropCallback;

186

/** The dragged item data */

187

dragItem: ElementDragItemNode;

188

/** The target element */

189

element: TElement;

190

/** React DnD monitor for drop state */

191

monitor: DropTargetMonitor<DragItemNode, unknown>;

192

/** Reference to the DOM node */

193

nodeRef: any;

194

/** Orientation of the drop operation */

195

orientation?: 'horizontal' | 'vertical';

196

}

197

```

198

199

**Usage Examples:**

200

201

```typescript

202

import { onDropNode } from "@udecode/plate-dnd";

203

204

// In a custom drop handler

205

function customDropHandler(

206

editor: PlateEditor,

207

dragItem: ElementDragItemNode,

208

targetElement: TElement,

209

monitor: DropTargetMonitor,

210

nodeRef: React.RefObject<HTMLElement>

211

) {

212

onDropNode(editor, {

213

dragItem,

214

element: targetElement,

215

monitor,

216

nodeRef,

217

orientation: 'vertical',

218

canDropNode: ({ dragEntry, dropEntry }) => {

219

// Custom validation: prevent dropping on itself

220

return dragEntry[0].id !== dropEntry[0].id;

221

}

222

});

223

}

224

225

// With custom validation

226

function restrictedDropHandler(editor: PlateEditor, options: OnDropNodeOptions) {

227

const restrictedTypes = ['heading', 'code-block'];

228

229

onDropNode(editor, {

230

...options,

231

canDropNode: ({ dragEntry, dropEntry }) => {

232

// Prevent moving restricted types

233

return !restrictedTypes.includes(dragEntry[0].type as string);

234

}

235

});

236

}

237

```

238

239

### getDropPath

240

241

Calculates the appropriate drop path for a drag operation, determining where the dragged item should be placed.

242

243

```typescript { .api }

244

/**

245

* Calculates drop paths for drag operations

246

* Determines source and target paths for node movement

247

* @param editor - The Plate editor instance

248

* @param options - Path calculation options

249

* @returns Drop operation result with paths or null if invalid

250

*/

251

export function getDropPath(

252

editor: PlateEditor,

253

options: GetDropPathOptions

254

): DropPathResult | null;

255

256

export interface GetDropPathOptions {

257

canDropNode?: CanDropCallback;

258

dragItem: DragItemNode;

259

element: TElement;

260

monitor: DropTargetMonitor<DragItemNode, unknown>;

261

nodeRef: any;

262

orientation?: 'horizontal' | 'vertical';

263

}

264

265

export interface DropPathResult {

266

/** Source path of the dragged item */

267

from: Path;

268

/** Target path for the drop */

269

to: Path;

270

}

271

```

272

273

**Usage Examples:**

274

275

```typescript

276

import { getDropPath } from "@udecode/plate-dnd";

277

278

// Calculate drop path before performing operation

279

function calculateAndExecuteDrop(

280

editor: PlateEditor,

281

dragItem: DragItemNode,

282

targetElement: TElement,

283

monitor: DropTargetMonitor,

284

nodeRef: React.RefObject<HTMLElement>

285

) {

286

const result = getDropPath(editor, {

287

dragItem,

288

element: targetElement,

289

monitor,

290

nodeRef,

291

orientation: 'vertical'

292

});

293

294

if (result) {

295

// Perform custom operations before/after move

296

console.log('Moving from', result.from, 'to', result.to);

297

298

// Move the node

299

editor.tf.moveNodes({

300

at: result.from,

301

to: result.to

302

});

303

}

304

}

305

306

// Validation before drop

307

function validateDrop(

308

editor: PlateEditor,

309

dragItem: DragItemNode,

310

targetElement: TElement,

311

monitor: DropTargetMonitor,

312

nodeRef: React.RefObject<HTMLElement>

313

): boolean {

314

const result = getDropPath(editor, {

315

dragItem,

316

element: targetElement,

317

monitor,

318

nodeRef,

319

canDropNode: ({ dragEntry, dropEntry }) => {

320

// Custom validation logic

321

return dragEntry[0].type === dropEntry[0].type;

322

}

323

});

324

325

return result !== null;

326

}

327

```

328

329

### onHoverNode

330

331

Handles hover events during drag operations, managing visual feedback and drop target state.

332

333

```typescript { .api }

334

/**

335

* Handles hover events during drag operations

336

* Manages drop target state and visual feedback

337

* @param editor - The Plate editor instance

338

* @param options - Hover handling options

339

*/

340

export function onHoverNode(

341

editor: PlateEditor,

342

options: OnHoverNodeOptions

343

): void;

344

345

export interface OnHoverNodeOptions {

346

canDropNode?: CanDropCallback;

347

dragItem: DragItemNode;

348

element: TElement;

349

monitor: DropTargetMonitor<DragItemNode, unknown>;

350

nodeRef: any;

351

orientation?: 'horizontal' | 'vertical';

352

}

353

```

354

355

**Usage Examples:**

356

357

```typescript

358

import { onHoverNode } from "@udecode/plate-dnd";

359

360

// In a custom hover handler

361

function customHoverHandler(

362

editor: PlateEditor,

363

dragItem: DragItemNode,

364

targetElement: TElement,

365

monitor: DropTargetMonitor,

366

nodeRef: React.RefObject<HTMLElement>

367

) {

368

onHoverNode(editor, {

369

dragItem,

370

element: targetElement,

371

monitor,

372

nodeRef,

373

orientation: 'vertical'

374

});

375

376

// Additional custom hover logic

377

if (monitor.isOver({ shallow: true })) {

378

console.log('Hovering over target element');

379

}

380

}

381

```

382

383

## Types

384

385

```typescript { .api }

386

export type CanDropCallback = (args: {

387

dragEntry: NodeEntry<TElement>;

388

dragItem: DragItemNode;

389

dropEntry: NodeEntry<TElement>;

390

editor: PlateEditor;

391

}) => boolean;

392

393

export interface ElementDragItemNode {

394

id: string;

395

element: TElement;

396

[key: string]: unknown;

397

}

398

399

export type EditorNodesOptions<T> = {

400

at?: Location;

401

match?: (node: T) => boolean;

402

mode?: 'all' | 'highest' | 'lowest';

403

universal?: boolean;

404

reverse?: boolean;

405

voids?: boolean;

406

};

407

```