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

editor-enhancements.mddocs/

0

# Editor Enhancements

1

2

Higher-order functions that enhance the Plate editor with image-specific functionality including upload handling and URL embedding.

3

4

## Capabilities

5

6

### Main Image Enhancement

7

8

Combines upload and embed functionality to provide comprehensive image handling capabilities.

9

10

```typescript { .api }

11

/**

12

* Enhances editor with complete image functionality

13

* Combines withImageUpload and withImageEmbed based on plugin configuration

14

* @param editor - Plate editor instance to enhance

15

* @param plugin - Plugin configuration with ImagePlugin options

16

* @returns Enhanced editor with image capabilities

17

*/

18

function withImage<

19

V extends Value = Value,

20

E extends PlateEditor<V> = PlateEditor<V>

21

>(

22

editor: E,

23

plugin: WithPlatePlugin<ImagePlugin, V, E>

24

): E;

25

```

26

27

**Usage Examples:**

28

29

```typescript

30

import { withImage, ImagePlugin } from "@udecode/plate-image";

31

import { createPlateEditor } from "@udecode/plate-core";

32

33

// Automatically applied through createImagePlugin

34

const editor = createPlateEditor({

35

plugins: [

36

createImagePlugin({

37

options: {

38

uploadImage: async (dataUrl) => uploadToServer(dataUrl),

39

disableUploadInsert: false,

40

disableEmbedInsert: false,

41

}

42

})

43

]

44

});

45

46

// Manual application (advanced usage)

47

let enhancedEditor = createPlateEditor();

48

enhancedEditor = withImage(enhancedEditor, {

49

options: {

50

uploadImage: async (dataUrl) => await customUpload(dataUrl)

51

}

52

});

53

```

54

55

### Image Upload Enhancement

56

57

Enables clipboard and drag-and-drop image upload functionality with optional custom upload handling.

58

59

```typescript { .api }

60

/**

61

* Enhances editor with image upload capabilities from clipboard and drag-and-drop

62

* Intercepts insertData to handle image files and process them through upload pipeline

63

* @param editor - Plate editor instance to enhance

64

* @param plugin - Plugin configuration with upload options

65

* @returns Enhanced editor with upload capabilities

66

*/

67

function withImageUpload<

68

V extends Value = Value,

69

E extends PlateEditor<V> = PlateEditor<V>

70

>(

71

editor: E,

72

plugin: WithPlatePlugin<ImagePlugin, V, E>

73

): E;

74

```

75

76

**Upload Process:**

77

78

1. **File Detection**: Monitors `insertData` calls for image file types

79

2. **MIME Type Validation**: Checks file MIME type starts with 'image/'

80

3. **File Reading**: Uses FileReader to convert files to data URLs

81

4. **Custom Upload**: Calls `uploadImage` function if provided

82

5. **Image Insertion**: Inserts processed image into editor

83

84

**Usage Examples:**

85

86

```typescript

87

import { withImageUpload } from "@udecode/plate-image";

88

89

// Basic upload enhancement

90

const editor = withImageUpload(baseEditor, {

91

options: {

92

uploadImage: async (dataUrl) => {

93

// Upload to your preferred service

94

const formData = new FormData();

95

formData.append('image', dataUrlToBlob(dataUrl));

96

97

const response = await fetch('/api/upload', {

98

method: 'POST',

99

body: formData

100

});

101

102

const result = await response.json();

103

return result.imageUrl;

104

}

105

}

106

});

107

108

// Multiple file handling

109

const multiUploadEditor = withImageUpload(baseEditor, {

110

options: {

111

uploadImage: async (dataUrl) => {

112

try {

113

return await uploadImageWithProgress(dataUrl, {

114

onProgress: (percent) => console.log(`Upload: ${percent}%`)

115

});

116

} catch (error) {

117

console.error('Upload failed, using data URL fallback');

118

return dataUrl; // Fallback to data URL

119

}

120

}

121

}

122

});

123

```

124

125

### Image URL Embedding Enhancement

126

127

Enables automatic conversion of pasted image URLs into image elements.

128

129

```typescript { .api }

130

/**

131

* Enhances editor with automatic image URL embedding

132

* Intercepts insertData to detect image URLs and convert them to image elements

133

* @param editor - Plate editor instance to enhance

134

* @param plugin - Plugin configuration (options not currently used)

135

* @returns Enhanced editor with URL embedding capabilities

136

*/

137

function withImageEmbed<

138

V extends Value = Value,

139

E extends PlateEditor<V> = PlateEditor<V>

140

>(

141

editor: E,

142

plugin: WithPlatePlugin<ImagePlugin, V, E>

143

): E;

144

```

145

146

**Embedding Process:**

147

148

1. **URL Detection**: Monitors pasted text for valid URLs

149

2. **Image URL Validation**: Uses `isImageUrl` to check if URL points to an image

150

3. **Element Creation**: Converts valid image URLs to image elements

151

4. **Insertion**: Inserts image element at current cursor position

152

153

**Usage Examples:**

154

155

```typescript

156

import { withImageEmbed } from "@udecode/plate-image";

157

158

// Basic embed enhancement

159

const editor = withImageEmbed(baseEditor, { options: {} });

160

161

// Combined with upload functionality

162

let fullEditor = createPlateEditor();

163

fullEditor = withImageUpload(fullEditor, {

164

options: {

165

uploadImage: customUploadFunction

166

}

167

});

168

fullEditor = withImageEmbed(fullEditor, { options: {} });

169

170

// Disable embed selectively

171

const noEmbedEditor = withImage(baseEditor, {

172

options: {

173

disableEmbedInsert: true, // URLs won't be auto-embedded

174

disableUploadInsert: false // File uploads still work

175

}

176

});

177

```

178

179

## Enhanced Editor Behavior

180

181

### Data Transfer Handling

182

183

The enhancements intercept the editor's `insertData` method to provide custom handling:

184

185

```typescript

186

// Original insertData behavior is preserved as fallback

187

const originalInsertData = editor.insertData;

188

189

editor.insertData = (dataTransfer: DataTransfer) => {

190

// Custom image handling logic

191

const text = dataTransfer.getData('text/plain');

192

const files = dataTransfer.files;

193

194

// Handle files (withImageUpload)

195

if (files && files.length > 0) {

196

// Process image files...

197

return;

198

}

199

200

// Handle URLs (withImageEmbed)

201

if (isImageUrl(text)) {

202

insertImage(editor, text);

203

return;

204

}

205

206

// Fallback to original behavior

207

originalInsertData(dataTransfer);

208

};

209

```

210

211

### Error Handling Patterns

212

213

```typescript

214

// Robust upload configuration with error handling

215

const robustUploadConfig = {

216

uploadImage: async (dataUrl: string | ArrayBuffer) => {

217

try {

218

// Attempt cloud upload

219

const cloudUrl = await uploadToCloud(dataUrl);

220

return cloudUrl;

221

} catch (cloudError) {

222

console.warn('Cloud upload failed, trying fallback:', cloudError);

223

224

try {

225

// Attempt fallback service

226

const fallbackUrl = await uploadToFallback(dataUrl);

227

return fallbackUrl;

228

} catch (fallbackError) {

229

console.error('All uploads failed, using data URL:', fallbackError);

230

// Use data URL as last resort

231

return dataUrl;

232

}

233

}

234

}

235

};

236

```

237

238

### Configuration Patterns

239

240

```typescript

241

// Environment-specific configuration

242

function createImageEnhancements(environment: 'development' | 'production') {

243

const baseConfig = {

244

disableUploadInsert: false,

245

disableEmbedInsert: false,

246

};

247

248

if (environment === 'development') {

249

return {

250

...baseConfig,

251

uploadImage: (dataUrl: string | ArrayBuffer) => {

252

// Development: just use data URLs

253

console.log('Dev mode: using data URL');

254

return Promise.resolve(dataUrl);

255

}

256

};

257

}

258

259

return {

260

...baseConfig,

261

uploadImage: async (dataUrl: string | ArrayBuffer) => {

262

// Production: upload to CDN

263

return await uploadToCDN(dataUrl);

264

}

265

};

266

}

267

```