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