or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

diff-editor.mdindex.mdmonaco-editor.md

diff-editor.mddocs/

0

# Monaco Diff Editor

1

2

The MonacoDiffEditor component provides side-by-side code comparison functionality with change highlighting, useful for showing differences between code versions, reviewing changes, or implementing merge interfaces.

3

4

## Capabilities

5

6

### Monaco Diff Editor Component

7

8

React component wrapper for Monaco Diff Editor with full TypeScript support and lifecycle management.

9

10

```typescript { .api }

11

/**

12

* Monaco Diff Editor React component for side-by-side code comparison

13

* @param props - MonacoDiffEditorProps configuration

14

* @param ref - Forward ref to access diff editor instance

15

* @returns React element containing Monaco Diff Editor

16

*/

17

declare const MonacoDiffEditor: React.ForwardRefExoticComponent<

18

MonacoDiffEditorProps & React.RefAttributes<MonacoDiffEditorHandle>

19

>;

20

```

21

22

**Usage Examples:**

23

24

```typescript

25

import React, { useState } from "react";

26

import { MonacoDiffEditor } from "react-monaco-editor";

27

28

// Basic diff editor showing changes

29

function BasicDiffEditor() {

30

const originalCode = `function greet(name) {

31

console.log("Hello " + name);

32

}`;

33

34

const modifiedCode = `function greet(name) {

35

console.log(\`Hello \${name}!\`);

36

return \`Hello \${name}!\`;

37

}`;

38

39

return (

40

<MonacoDiffEditor

41

width="800"

42

height="400"

43

language="javascript"

44

original={originalCode}

45

value={modifiedCode}

46

options={{

47

renderSideBySide: true,

48

enableSplitViewResizing: true,

49

readOnly: false,

50

}}

51

/>

52

);

53

}

54

55

// Interactive diff editor with state management

56

function InteractiveDiffEditor() {

57

const [original, setOriginal] = useState('const a = "Hello World";');

58

const [modified, setModified] = useState('const a = "Hello Monaco";');

59

60

return (

61

<div>

62

<div>

63

<button onClick={() => setOriginal('const b = "Updated Original";')}>

64

Update Original

65

</button>

66

<button onClick={() => setModified('const b = "Updated Modified";')}>

67

Update Modified

68

</button>

69

</div>

70

<MonacoDiffEditor

71

width="800"

72

height="300"

73

language="javascript"

74

original={original}

75

value={modified}

76

onChange={(newValue) => setModified(newValue)}

77

editorDidMount={(editor, monaco) => {

78

console.log('Diff editor mounted');

79

}}

80

/>

81

</div>

82

);

83

}

84

```

85

86

### Component Props

87

88

Full configuration interface for the Monaco Diff Editor component.

89

90

```typescript { .api }

91

interface MonacoDiffEditorProps extends MonacoEditorBaseProps {

92

/** The original value to compare against. */

93

original?: string;

94

95

/** Value of the auto created model in the editor.

96

* If you specify value property, the component behaves in controlled mode.

97

* Otherwise, it behaves in uncontrolled mode. */

98

value?: string;

99

100

/** Refer to Monaco interface {monaco.editor.IDiffEditorConstructionOptions}. */

101

options?: monaco.editor.IDiffEditorConstructionOptions;

102

103

/** Refer to Monaco interface {monaco.editor.IEditorOverrideServices}. */

104

overrideServices?: monaco.editor.IEditorOverrideServices;

105

106

/** An event emitted before the editor mounted (similar to componentWillMount of React). */

107

editorWillMount?: DiffEditorWillMount;

108

109

/** An event emitted when the editor has been mounted (similar to componentDidMount of React). */

110

editorDidMount?: DiffEditorDidMount;

111

112

/** An event emitted before the editor unmount (similar to componentWillUnmount of React). */

113

editorWillUnmount?: DiffEditorWillUnmount;

114

115

/** An event emitted when the content of the current model has changed. */

116

onChange?: DiffChangeHandler;

117

118

/** Let the language be inferred from the uri */

119

originalUri?: (monaco: typeof monaco) => monaco.Uri;

120

121

/** Let the language be inferred from the uri */

122

modifiedUri?: (monaco: typeof monaco) => monaco.Uri;

123

}

124

```

125

126

### Diff Editor Handle

127

128

Interface for accessing the Monaco Diff Editor instance via React ref.

129

130

```typescript { .api }

131

interface MonacoDiffEditorHandle {

132

/** Direct access to Monaco diff editor instance */

133

editor: monaco.editor.IStandaloneDiffEditor;

134

}

135

```

136

137

**Usage Example:**

138

139

```typescript

140

import React, { useRef } from "react";

141

import { MonacoDiffEditor } from "react-monaco-editor";

142

143

function DiffEditorWithRef() {

144

const diffEditorRef = useRef<MonacoDiffEditorHandle>(null);

145

146

const getChanges = () => {

147

if (diffEditorRef.current) {

148

const diffEditor = diffEditorRef.current.editor;

149

const changes = diffEditor.getLineChanges();

150

console.log('Line changes:', changes);

151

152

// Access individual editors

153

const originalEditor = diffEditor.getOriginalEditor();

154

const modifiedEditor = diffEditor.getModifiedEditor();

155

156

console.log('Original content:', originalEditor.getValue());

157

console.log('Modified content:', modifiedEditor.getValue());

158

}

159

};

160

161

return (

162

<div>

163

<button onClick={getChanges}>Get Changes</button>

164

<MonacoDiffEditor

165

ref={diffEditorRef}

166

width="800"

167

height="400"

168

language="javascript"

169

original="const original = true;"

170

value="const modified = true;"

171

/>

172

</div>

173

);

174

}

175

```

176

177

### Lifecycle Callbacks

178

179

Callback functions for handling diff editor lifecycle events.

180

181

```typescript { .api }

182

/**

183

* Callback invoked before the diff editor is mounted

184

* @param monaco - Monaco Editor API instance

185

* @returns Optional editor construction options to merge with props.options

186

*/

187

type DiffEditorWillMount = (

188

monaco: typeof monaco

189

) => void | monaco.editor.IStandaloneEditorConstructionOptions;

190

191

/**

192

* Callback invoked after the diff editor has been mounted

193

* @param editor - The mounted Monaco diff editor instance

194

* @param monaco - Monaco Editor API instance

195

*/

196

type DiffEditorDidMount = (

197

editor: monaco.editor.IStandaloneDiffEditor,

198

monaco: typeof monaco

199

) => void;

200

201

/**

202

* Callback invoked before the diff editor is unmounted

203

* @param editor - The Monaco diff editor instance being unmounted

204

* @param monaco - Monaco Editor API instance

205

*/

206

type DiffEditorWillUnmount = (

207

editor: monaco.editor.IStandaloneDiffEditor,

208

monaco: typeof monaco

209

) => void;

210

211

/**

212

* Callback invoked when the modified editor content changes

213

* Note: Only changes to the modified (right-side) editor trigger this callback

214

*/

215

type DiffChangeHandler = ChangeHandler;

216

```

217

218

**Usage Example:**

219

220

```typescript

221

function DiffEditorWithLifecycle() {

222

const diffEditorWillMount = (monaco) => {

223

console.log('Diff editor will mount');

224

// Return options to merge with props.options

225

return {

226

renderSideBySide: true,

227

ignoreTrimWhitespace: false,

228

};

229

};

230

231

const diffEditorDidMount = (diffEditor, monaco) => {

232

console.log('Diff editor mounted');

233

234

// Access both editors

235

const originalEditor = diffEditor.getOriginalEditor();

236

const modifiedEditor = diffEditor.getModifiedEditor();

237

238

// Add commands to both editors

239

const commandId = 'my.custom.command';

240

originalEditor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyK, () => {

241

console.log('Custom command in original editor');

242

});

243

244

modifiedEditor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyK, () => {

245

console.log('Custom command in modified editor');

246

});

247

};

248

249

const diffEditorWillUnmount = (diffEditor, monaco) => {

250

console.log('Diff editor will unmount');

251

// Cleanup if needed

252

};

253

254

const onChange = (newValue, event) => {

255

console.log('Modified editor content changed:', newValue);

256

};

257

258

return (

259

<MonacoDiffEditor

260

width="800"

261

height="400"

262

language="typescript"

263

original="interface User { name: string; }"

264

value="interface User { name: string; age: number; }"

265

editorWillMount={diffEditorWillMount}

266

editorDidMount={diffEditorDidMount}

267

editorWillUnmount={diffEditorWillUnmount}

268

onChange={onChange}

269

/>

270

);

271

}

272

```

273

274

### URI Support

275

276

Custom URI creation for both original and modified models, useful for language services and proper file identification.

277

278

```typescript { .api }

279

/**

280

* Function to create a Monaco URI for the original model

281

* @param monaco - Monaco Editor API instance

282

* @returns Monaco URI for the original model

283

*/

284

originalUri?: (monaco: typeof monaco) => monaco.Uri;

285

286

/**

287

* Function to create a Monaco URI for the modified model

288

* @param monaco - Monaco Editor API instance

289

* @returns Monaco URI for the modified model

290

*/

291

modifiedUri?: (monaco: typeof monaco) => monaco.Uri;

292

```

293

294

**Usage Example:**

295

296

```typescript

297

function DiffEditorWithURIs() {

298

return (

299

<MonacoDiffEditor

300

width="800"

301

height="400"

302

language="typescript"

303

original="// Original version"

304

value="// Modified version"

305

originalUri={(monaco) => monaco.Uri.parse("file:///original.ts")}

306

modifiedUri={(monaco) => monaco.Uri.parse("file:///modified.ts")}

307

/>

308

);

309

}

310

```

311

312

### Common Diff Options

313

314

Frequently used Monaco Diff Editor configuration options:

315

316

```typescript

317

const commonDiffOptions = {

318

// Layout

319

renderSideBySide: true, // Side-by-side view (true) vs inline view (false)

320

enableSplitViewResizing: true, // Allow resizing the split view

321

322

// Whitespace handling

323

ignoreTrimWhitespace: true, // Ignore leading/trailing whitespace changes

324

325

// Line changes

326

renderIndicators: true, // Show change indicators in overview ruler

327

328

// Readonly behavior

329

readOnly: false, // Allow editing the modified version

330

originalEditable: false, // Prevent editing the original version

331

332

// Diff computation

333

maxComputationTime: 5000, // Max time in ms for diff computation

334

335

// Word-level diffing

336

diffWordWrap: 'off' as const, // Word wrap for diff algorithm

337

338

// Colors and styling

339

renderOverviewRuler: true, // Show overview ruler with change markers

340

};

341

```

342

343

### Accessing Individual Editors

344

345

The diff editor provides access to both the original and modified editors:

346

347

```typescript

348

function AccessIndividualEditors() {

349

const diffEditorRef = useRef<MonacoDiffEditorHandle>(null);

350

351

const workWithEditors = () => {

352

if (diffEditorRef.current) {

353

const diffEditor = diffEditorRef.current.editor;

354

355

// Get individual editors

356

const originalEditor = diffEditor.getOriginalEditor();

357

const modifiedEditor = diffEditor.getModifiedEditor();

358

359

// Work with original editor

360

const originalContent = originalEditor.getValue();

361

originalEditor.setSelection(new monaco.Selection(1, 1, 1, 10));

362

363

// Work with modified editor

364

const modifiedContent = modifiedEditor.getValue();

365

modifiedEditor.focus();

366

367

// Get diff information

368

const lineChanges = diffEditor.getLineChanges();

369

console.log('Changes:', lineChanges);

370

}

371

};

372

373

return (

374

<div>

375

<button onClick={workWithEditors}>Work with Editors</button>

376

<MonacoDiffEditor

377

ref={diffEditorRef}

378

width="800"

379

height="400"

380

language="javascript"

381

original="const a = 1;"

382

value="const b = 2;"

383

/>

384

</div>

385

);

386

}

387

```