or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

extensions.mdhook-api.mdindex.mdmain-component.mdthemes.mdutilities.md

hook-api.mddocs/

0

# Hook API

1

2

Hook-based interface for advanced integration scenarios, custom containers, and direct CodeMirror state management. The `useCodeMirror` hook provides lower-level access to CodeMirror functionality for complex use cases.

3

4

## Capabilities

5

6

### useCodeMirror Hook

7

8

Main hook for integrating CodeMirror with custom React components and containers.

9

10

```typescript { .api }

11

/**

12

* Hook for integrating CodeMirror with custom React components

13

* @param props - Configuration options extending ReactCodeMirrorProps

14

* @returns Object containing state, view, container, and their setters

15

*/

16

function useCodeMirror(props: UseCodeMirror): {

17

state: EditorState | undefined;

18

setState: React.Dispatch<React.SetStateAction<EditorState | undefined>>;

19

view: EditorView | undefined;

20

setView: React.Dispatch<React.SetStateAction<EditorView | undefined>>;

21

container: HTMLDivElement | null | undefined;

22

setContainer: React.Dispatch<React.SetStateAction<HTMLDivElement | null | undefined>>;

23

};

24

25

interface UseCodeMirror extends ReactCodeMirrorProps {

26

/** Custom container element for the editor */

27

container?: HTMLDivElement | null;

28

}

29

```

30

31

**Usage Examples:**

32

33

```typescript

34

import React, { useEffect, useRef } from "react";

35

import { useCodeMirror } from "@uiw/react-codemirror";

36

import { javascript } from "@codemirror/lang-javascript";

37

38

// Basic hook usage

39

function CustomEditor() {

40

const editor = useRef<HTMLDivElement>(null);

41

const { setContainer, view, state } = useCodeMirror({

42

container: editor.current,

43

value: "console.log('Hello World');",

44

extensions: [javascript()],

45

onChange: (value, viewUpdate) => {

46

console.log('Value changed:', value);

47

},

48

});

49

50

useEffect(() => {

51

if (editor.current) {

52

setContainer(editor.current);

53

}

54

}, [setContainer]);

55

56

return <div ref={editor} />;

57

}

58

59

// Advanced hook usage with multiple containers

60

function MultiEditorContainer() {

61

const editor1 = useRef<HTMLDivElement>(null);

62

const editor2 = useRef<HTMLDivElement>(null);

63

64

const { setContainer: setContainer1, view: view1 } = useCodeMirror({

65

container: editor1.current,

66

value: "// Editor 1",

67

theme: "light",

68

});

69

70

const { setContainer: setContainer2, view: view2 } = useCodeMirror({

71

container: editor2.current,

72

value: "// Editor 2",

73

theme: "dark",

74

});

75

76

useEffect(() => {

77

if (editor1.current) setContainer1(editor1.current);

78

if (editor2.current) setContainer2(editor2.current);

79

}, [setContainer1, setContainer2]);

80

81

const syncEditors = () => {

82

if (view1 && view2) {

83

const content = view1.state.doc.toString();

84

view2.dispatch({

85

changes: { from: 0, to: view2.state.doc.length, insert: content }

86

});

87

}

88

};

89

90

return (

91

<div>

92

<button onClick={syncEditors}>Sync Editors</button>

93

<div style={{ display: 'flex' }}>

94

<div ref={editor1} style={{ flex: 1 }} />

95

<div ref={editor2} style={{ flex: 1 }} />

96

</div>

97

</div>

98

);

99

}

100

```

101

102

### Hook State Management

103

104

The hook returns state management objects for direct manipulation of the editor.

105

106

```typescript { .api }

107

// Returned state objects

108

interface UseCodeMirrorReturn {

109

/** Current editor state - undefined before initialization */

110

state: EditorState | undefined;

111

/** State setter for programmatic state updates */

112

setState: React.Dispatch<React.SetStateAction<EditorState | undefined>>;

113

/** Current editor view - undefined before initialization */

114

view: EditorView | undefined;

115

/** View setter for programmatic view updates */

116

setView: React.Dispatch<React.SetStateAction<EditorView | undefined>>;

117

/** Current container element */

118

container: HTMLDivElement | null | undefined;

119

/** Container setter for attaching to DOM elements */

120

setContainer: React.Dispatch<React.SetStateAction<HTMLDivElement | null | undefined>>;

121

}

122

```

123

124

**Usage Example:**

125

126

```typescript

127

import React, { useEffect, useRef } from "react";

128

import { useCodeMirror } from "@uiw/react-codemirror";

129

import { EditorState } from "@codemirror/state";

130

import { javascript } from "@codemirror/lang-javascript";

131

132

function StateManagementExample() {

133

const containerRef = useRef<HTMLDivElement>(null);

134

const {

135

state,

136

setState,

137

view,

138

container,

139

setContainer

140

} = useCodeMirror({

141

value: "// Initial code",

142

extensions: [javascript()],

143

});

144

145

useEffect(() => {

146

if (containerRef.current) {

147

setContainer(containerRef.current);

148

}

149

}, [setContainer]);

150

151

const resetEditor = () => {

152

if (view) {

153

const newState = EditorState.create({

154

doc: "// Reset code",

155

extensions: [javascript()],

156

});

157

setState(newState);

158

}

159

};

160

161

const logState = () => {

162

if (state) {

163

console.log('Current state:', {

164

content: state.doc.toString(),

165

selection: state.selection.main,

166

lineCount: state.doc.lines,

167

});

168

}

169

};

170

171

return (

172

<div>

173

<button onClick={resetEditor} disabled={!view}>

174

Reset Editor

175

</button>

176

<button onClick={logState} disabled={!state}>

177

Log State

178

</button>

179

<div ref={containerRef} />

180

</div>

181

);

182

}

183

```

184

185

### External Change Tracking

186

187

The hook includes support for tracking external changes to prevent echo effects.

188

189

```typescript { .api }

190

/**

191

* Annotation for marking transactions as external changes

192

* Used internally to prevent onChange callbacks for programmatic updates

193

*/

194

const ExternalChange: import('@codemirror/state').AnnotationType<boolean>;

195

```

196

197

**Usage Example:**

198

199

```typescript

200

import React, { useRef } from "react";

201

import { useCodeMirror, ExternalChange } from "@uiw/react-codemirror";

202

203

function ExternalChangeExample() {

204

const containerRef = useRef<HTMLDivElement>(null);

205

const { view, setContainer } = useCodeMirror({

206

container: containerRef.current,

207

value: "// Original content",

208

onChange: (value, viewUpdate) => {

209

// This won't trigger for external changes

210

console.log('User changed content to:', value);

211

},

212

});

213

214

React.useEffect(() => {

215

if (containerRef.current) {

216

setContainer(containerRef.current);

217

}

218

}, [setContainer]);

219

220

const updateExternally = () => {

221

if (view) {

222

// This update won't trigger onChange

223

view.dispatch({

224

changes: {

225

from: 0,

226

to: view.state.doc.length,

227

insert: "// Updated externally"

228

},

229

annotations: [ExternalChange.of(true)],

230

});

231

}

232

};

233

234

return (

235

<div>

236

<button onClick={updateExternally}>Update Externally</button>

237

<div ref={containerRef} />

238

</div>

239

);

240

}

241

```

242

243

### Performance Optimization

244

245

The hook includes built-in performance optimizations for handling rapid updates.

246

247

**Usage Example:**

248

249

```typescript

250

import React, { useRef, useMemo } from "react";

251

import { useCodeMirror } from "@uiw/react-codemirror";

252

import { javascript } from "@codemirror/lang-javascript";

253

254

function OptimizedEditor() {

255

const containerRef = useRef<HTMLDivElement>(null);

256

257

// Memoize extensions to prevent unnecessary re-renders

258

const extensions = useMemo(() => [javascript()], []);

259

260

const { setContainer } = useCodeMirror({

261

container: containerRef.current,

262

value: "// Optimized editor",

263

extensions, // Stable reference prevents re-creation

264

onChange: React.useCallback((value) => {

265

// Debounced internally by the hook

266

console.log('Content updated:', value);

267

}, []),

268

});

269

270

React.useEffect(() => {

271

if (containerRef.current) {

272

setContainer(containerRef.current);

273

}

274

}, [setContainer]);

275

276

return <div ref={containerRef} />;

277

}

278

```