or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

ace-editor.mddiff-editor.mdindex.mdsplit-editor.md

split-editor.mddocs/

0

# Split Editor

1

2

The Split Editor component provides side-by-side editing capabilities with multiple panes that can be synchronized or operate independently. This is ideal for comparing files, editing multiple documents simultaneously, or creating before/after views.

3

4

## Capabilities

5

6

### SplitComponent

7

8

Split screen editor component that renders multiple synchronized or independent editor panes.

9

10

```typescript { .api }

11

/**

12

* Split screen editor component for side-by-side editing

13

* Supports multiple panes with individual content and shared configuration

14

*/

15

declare class SplitComponent extends React.Component<ISplitEditorProps> {}

16

17

interface ISplitEditorProps {

18

/** Unique identifier for the split editor instance */

19

name?: string;

20

/** CSS styles for the split editor container */

21

style?: object;

22

/** Syntax highlighting mode for all splits */

23

mode?: string;

24

/** Editor theme for all splits */

25

theme?: string;

26

/** Total height of the split editor */

27

height?: string;

28

/** Total width of the split editor */

29

width?: string;

30

/** CSS class name for the split editor container */

31

className?: string;

32

/** Font size for all editor splits */

33

fontSize?: number | string;

34

/** Show line numbers in all splits */

35

showGutter?: boolean;

36

/** Show print margin in all splits */

37

showPrintMargin?: boolean;

38

/** Highlight active line in all splits */

39

highlightActiveLine?: boolean;

40

/** Auto-focus the first split on mount */

41

focus?: boolean;

42

/** Number of editor splits (required) */

43

splits: number;

44

/** Debounce period for onChange events */

45

debounceChangePeriod?: number;

46

/** Starting cursor position for all splits */

47

cursorStart?: number;

48

/** Enable line wrapping in all splits */

49

wrapEnabled?: boolean;

50

/** Make all splits read-only */

51

readOnly?: boolean;

52

/** Minimum lines for all splits */

53

minLines?: number;

54

/** Maximum lines for all splits */

55

maxLines?: number;

56

/** Enable basic autocompletion in all splits */

57

enableBasicAutocompletion?: boolean | string[];

58

/** Enable live autocompletion in all splits */

59

enableLiveAutocompletion?: boolean | string[];

60

/** Tab size for all splits */

61

tabSize?: number;

62

/** Content for each split (array) */

63

value?: string[];

64

/** Default content for each split */

65

defaultValue?: string[];

66

/** Scroll margin for all splits */

67

scrollMargin?: number[];

68

/** Split orientation ("beside" or "below") */

69

orientation?: string;

70

/** Called when text selection changes in any split */

71

onSelectionChange?: (value: any, event?: any) => void;

72

/** Called when cursor position changes in any split */

73

onCursorChange?: (value: any, event?: any) => void;

74

/** Called on text input in any split */

75

onInput?: (event?: any) => void;

76

/** Called when split editor is fully loaded */

77

onLoad?: (editor: IEditorProps) => void;

78

/** Called before ace is loaded (for configuration) */

79

onBeforeLoad?: (ace: any) => void;

80

/** Called when content changes in any split */

81

onChange?: (value: string[], event?: any) => void;

82

/** Called when text is selected in any split */

83

onSelection?: (selectedText: string, event?: any) => void;

84

/** Called when text is copied from any split */

85

onCopy?: (value: string) => void;

86

/** Called when text is pasted into any split */

87

onPaste?: (value: string) => void;

88

/** Called when any split gains focus */

89

onFocus?: (value: Event) => void;

90

/** Called when any split loses focus */

91

onBlur?: (value: Event) => void;

92

/** Called when any split is scrolled */

93

onScroll?: (editor: IEditorProps) => void;

94

/** Additional editor properties for all splits */

95

editorProps?: IEditorProps;

96

/** Ace editor configuration options for all splits */

97

setOptions?: IAceOptions;

98

/** Keyboard handler mode for all splits */

99

keyboardHandler?: string;

100

/** Custom commands for all splits */

101

commands?: ICommand[];

102

/** Annotations for each split (2D array) */

103

annotations?: IAnnotation[][];

104

/** Markers for each split (2D array) */

105

markers?: IMarker[][];

106

}

107

```

108

109

### Usage Examples

110

111

**Basic Split Editor:**

112

113

```typescript

114

import React, { useState } from "react";

115

import { split } from "react-ace";

116

117

import "ace-builds/src-noconflict/mode-javascript";

118

import "ace-builds/src-noconflict/theme-github";

119

120

const SplitEditor = split;

121

122

function CompareFiles() {

123

const [values, setValues] = useState([

124

'// Original code\nfunction original() {\n return "old";\n}',

125

'// Modified code\nfunction modified() {\n return "new";\n}'

126

]);

127

128

return (

129

<SplitEditor

130

mode="javascript"

131

theme="github"

132

splits={2}

133

orientation="beside"

134

value={values}

135

onChange={setValues}

136

name="file-comparison"

137

width="100%"

138

height="400px"

139

fontSize={14}

140

showGutter={true}

141

highlightActiveLine={true}

142

/>

143

);

144

}

145

```

146

147

**Multi-Split Editor with Individual Configuration:**

148

149

```typescript

150

import React, { useState } from "react";

151

import { split, IAnnotation, IMarker } from "react-ace";

152

153

import "ace-builds/src-noconflict/mode-typescript";

154

import "ace-builds/src-noconflict/theme-monokai";

155

156

const SplitEditor = split;

157

158

function MultiSplitEditor() {

159

const [values, setValues] = useState([

160

'// Component code',

161

'// Test code',

162

'// Documentation'

163

]);

164

165

const annotations: IAnnotation[][] = [

166

[{ row: 0, column: 0, text: "Component ready", type: "info" }],

167

[{ row: 1, column: 0, text: "Test failing", type: "error" }],

168

[]

169

];

170

171

const markers: IMarker[][] = [

172

[{

173

startRow: 0,

174

startCol: 0,

175

endRow: 0,

176

endCol: 10,

177

className: 'component-highlight',

178

type: 'text'

179

}],

180

[],

181

[]

182

];

183

184

return (

185

<SplitEditor

186

mode="typescript"

187

theme="monokai"

188

splits={3}

189

orientation="beside"

190

value={values}

191

onChange={setValues}

192

name="multi-split-editor"

193

width="100%"

194

height="600px"

195

fontSize={14}

196

annotations={annotations}

197

markers={markers}

198

setOptions={{

199

enableBasicAutocompletion: true,

200

enableLiveAutocompletion: true,

201

tabSize: 2

202

}}

203

/>

204

);

205

}

206

```

207

208

**Vertical Split Layout:**

209

210

```typescript

211

import React, { useState } from "react";

212

import { split } from "react-ace";

213

214

import "ace-builds/src-noconflict/mode-html";

215

import "ace-builds/src-noconflict/mode-css";

216

import "ace-builds/src-noconflict/theme-github";

217

218

const SplitEditor = split;

219

220

function WebDevEditor() {

221

const [htmlCode, setHtmlCode] = useState('<div>Hello World</div>');

222

const [cssCode, setCssCode] = useState('div { color: blue; }');

223

224

const handleChange = (values) => {

225

setHtmlCode(values[0]);

226

setCssCode(values[1]);

227

};

228

229

return (

230

<div>

231

<SplitEditor

232

mode="html"

233

theme="github"

234

splits={2}

235

orientation="below"

236

value={[htmlCode, cssCode]}

237

onChange={handleChange}

238

name="web-dev-editor"

239

width="100%"

240

height="500px"

241

fontSize={14}

242

showGutter={true}

243

highlightActiveLine={true}

244

/>

245

</div>

246

);

247

}

248

```

249

250

**Split Editor with Event Handling:**

251

252

```typescript

253

import React, { useState, useCallback } from "react";

254

import { split } from "react-ace";

255

256

const SplitEditor = split;

257

258

function EventHandlingSplitEditor() {

259

const [values, setValues] = useState(['', '']);

260

const [activePane, setActivePane] = useState(0);

261

262

const handleFocus = useCallback((event) => {

263

// Determine which pane is focused

264

console.log('Pane focused:', event);

265

}, []);

266

267

const handleSelectionChange = useCallback((selection, event) => {

268

console.log('Selection changed:', selection);

269

}, []);

270

271

const handleCursorChange = useCallback((cursor, event) => {

272

console.log('Cursor moved:', cursor);

273

}, []);

274

275

return (

276

<SplitEditor

277

mode="text"

278

theme="github"

279

splits={2}

280

orientation="beside"

281

value={values}

282

onChange={setValues}

283

onFocus={handleFocus}

284

onSelectionChange={handleSelectionChange}

285

onCursorChange={handleCursorChange}

286

name="event-split-editor"

287

width="100%"

288

height="400px"

289

fontSize={14}

290

/>

291

);

292

}

293

```

294

295

### Split Configuration

296

297

**Orientation Options:**

298

299

- `"beside"`: Side-by-side horizontal layout (default)

300

- `"below"`: Vertical stack layout

301

302

**Split Management:**

303

304

The `splits` prop determines the number of editor panes. Each pane shares the same configuration but can have individual content, annotations, and markers.

305

306

```typescript { .api }

307

interface SplitConfiguration {

308

/** Number of editor panes */

309

splits: number;

310

/** Layout orientation */

311

orientation?: "beside" | "below";

312

/** Content for each pane */

313

value?: string[];

314

/** Default content for each pane */

315

defaultValue?: string[];

316

/** Annotations per pane */

317

annotations?: IAnnotation[][];

318

/** Markers per pane */

319

markers?: IMarker[][];

320

}

321

```

322

323

### Event Handling

324

325

Split editor events provide information about which pane triggered the event:

326

327

```typescript { .api }

328

/** Called when content changes in any split */

329

onChange?: (values: string[], event?: {

330

splitIndex?: number;

331

start: { row: number; column: number };

332

end: { row: number; column: number };

333

action: "insert" | "remove";

334

lines: string[];

335

}) => void;

336

337

/** Called when selection changes in any split */

338

onSelectionChange?: (selection: {

339

start: { row: number; column: number };

340

end: { row: number; column: number };

341

splitIndex?: number;

342

}, event?: any) => void;

343

```

344

345

### Advanced Features

346

347

**Synchronized Scrolling:**

348

349

By default, split panes scroll independently. For synchronized scrolling, you can implement custom scroll handlers.

350

351

**Individual Pane Access:**

352

353

Each split pane can be accessed through the editor instance provided in the `onLoad` callback.

354

355

**Performance Considerations:**

356

357

- Use debounceChangePeriod to control update frequency

358

- Consider virtualization for large numbers of splits

359

- Minimize re-renders by using useCallback for event handlers