A React component for Ace Editor providing comprehensive code editing capabilities with syntax highlighting, themes, and customization options
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
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.
Split screen editor component that renders multiple synchronized or independent editor panes.
/**
* Split screen editor component for side-by-side editing
* Supports multiple panes with individual content and shared configuration
*/
declare class SplitComponent extends React.Component<ISplitEditorProps> {}
interface ISplitEditorProps {
/** Unique identifier for the split editor instance */
name?: string;
/** CSS styles for the split editor container */
style?: object;
/** Syntax highlighting mode for all splits */
mode?: string;
/** Editor theme for all splits */
theme?: string;
/** Total height of the split editor */
height?: string;
/** Total width of the split editor */
width?: string;
/** CSS class name for the split editor container */
className?: string;
/** Font size for all editor splits */
fontSize?: number | string;
/** Show line numbers in all splits */
showGutter?: boolean;
/** Show print margin in all splits */
showPrintMargin?: boolean;
/** Highlight active line in all splits */
highlightActiveLine?: boolean;
/** Auto-focus the first split on mount */
focus?: boolean;
/** Number of editor splits (required) */
splits: number;
/** Debounce period for onChange events */
debounceChangePeriod?: number;
/** Starting cursor position for all splits */
cursorStart?: number;
/** Enable line wrapping in all splits */
wrapEnabled?: boolean;
/** Make all splits read-only */
readOnly?: boolean;
/** Minimum lines for all splits */
minLines?: number;
/** Maximum lines for all splits */
maxLines?: number;
/** Enable basic autocompletion in all splits */
enableBasicAutocompletion?: boolean | string[];
/** Enable live autocompletion in all splits */
enableLiveAutocompletion?: boolean | string[];
/** Tab size for all splits */
tabSize?: number;
/** Content for each split (array) */
value?: string[];
/** Default content for each split */
defaultValue?: string[];
/** Scroll margin for all splits */
scrollMargin?: number[];
/** Split orientation ("beside" or "below") */
orientation?: string;
/** Called when text selection changes in any split */
onSelectionChange?: (value: any, event?: any) => void;
/** Called when cursor position changes in any split */
onCursorChange?: (value: any, event?: any) => void;
/** Called on text input in any split */
onInput?: (event?: any) => void;
/** Called when split editor is fully loaded */
onLoad?: (editor: IEditorProps) => void;
/** Called before ace is loaded (for configuration) */
onBeforeLoad?: (ace: any) => void;
/** Called when content changes in any split */
onChange?: (value: string[], event?: any) => void;
/** Called when text is selected in any split */
onSelection?: (selectedText: string, event?: any) => void;
/** Called when text is copied from any split */
onCopy?: (value: string) => void;
/** Called when text is pasted into any split */
onPaste?: (value: string) => void;
/** Called when any split gains focus */
onFocus?: (value: Event) => void;
/** Called when any split loses focus */
onBlur?: (value: Event) => void;
/** Called when any split is scrolled */
onScroll?: (editor: IEditorProps) => void;
/** Additional editor properties for all splits */
editorProps?: IEditorProps;
/** Ace editor configuration options for all splits */
setOptions?: IAceOptions;
/** Keyboard handler mode for all splits */
keyboardHandler?: string;
/** Custom commands for all splits */
commands?: ICommand[];
/** Annotations for each split (2D array) */
annotations?: IAnnotation[][];
/** Markers for each split (2D array) */
markers?: IMarker[][];
}Basic Split Editor:
import React, { useState } from "react";
import { split } from "react-ace";
import "ace-builds/src-noconflict/mode-javascript";
import "ace-builds/src-noconflict/theme-github";
const SplitEditor = split;
function CompareFiles() {
const [values, setValues] = useState([
'// Original code\nfunction original() {\n return "old";\n}',
'// Modified code\nfunction modified() {\n return "new";\n}'
]);
return (
<SplitEditor
mode="javascript"
theme="github"
splits={2}
orientation="beside"
value={values}
onChange={setValues}
name="file-comparison"
width="100%"
height="400px"
fontSize={14}
showGutter={true}
highlightActiveLine={true}
/>
);
}Multi-Split Editor with Individual Configuration:
import React, { useState } from "react";
import { split, IAnnotation, IMarker } from "react-ace";
import "ace-builds/src-noconflict/mode-typescript";
import "ace-builds/src-noconflict/theme-monokai";
const SplitEditor = split;
function MultiSplitEditor() {
const [values, setValues] = useState([
'// Component code',
'// Test code',
'// Documentation'
]);
const annotations: IAnnotation[][] = [
[{ row: 0, column: 0, text: "Component ready", type: "info" }],
[{ row: 1, column: 0, text: "Test failing", type: "error" }],
[]
];
const markers: IMarker[][] = [
[{
startRow: 0,
startCol: 0,
endRow: 0,
endCol: 10,
className: 'component-highlight',
type: 'text'
}],
[],
[]
];
return (
<SplitEditor
mode="typescript"
theme="monokai"
splits={3}
orientation="beside"
value={values}
onChange={setValues}
name="multi-split-editor"
width="100%"
height="600px"
fontSize={14}
annotations={annotations}
markers={markers}
setOptions={{
enableBasicAutocompletion: true,
enableLiveAutocompletion: true,
tabSize: 2
}}
/>
);
}Vertical Split Layout:
import React, { useState } from "react";
import { split } from "react-ace";
import "ace-builds/src-noconflict/mode-html";
import "ace-builds/src-noconflict/mode-css";
import "ace-builds/src-noconflict/theme-github";
const SplitEditor = split;
function WebDevEditor() {
const [htmlCode, setHtmlCode] = useState('<div>Hello World</div>');
const [cssCode, setCssCode] = useState('div { color: blue; }');
const handleChange = (values) => {
setHtmlCode(values[0]);
setCssCode(values[1]);
};
return (
<div>
<SplitEditor
mode="html"
theme="github"
splits={2}
orientation="below"
value={[htmlCode, cssCode]}
onChange={handleChange}
name="web-dev-editor"
width="100%"
height="500px"
fontSize={14}
showGutter={true}
highlightActiveLine={true}
/>
</div>
);
}Split Editor with Event Handling:
import React, { useState, useCallback } from "react";
import { split } from "react-ace";
const SplitEditor = split;
function EventHandlingSplitEditor() {
const [values, setValues] = useState(['', '']);
const [activePane, setActivePane] = useState(0);
const handleFocus = useCallback((event) => {
// Determine which pane is focused
console.log('Pane focused:', event);
}, []);
const handleSelectionChange = useCallback((selection, event) => {
console.log('Selection changed:', selection);
}, []);
const handleCursorChange = useCallback((cursor, event) => {
console.log('Cursor moved:', cursor);
}, []);
return (
<SplitEditor
mode="text"
theme="github"
splits={2}
orientation="beside"
value={values}
onChange={setValues}
onFocus={handleFocus}
onSelectionChange={handleSelectionChange}
onCursorChange={handleCursorChange}
name="event-split-editor"
width="100%"
height="400px"
fontSize={14}
/>
);
}Orientation Options:
"beside": Side-by-side horizontal layout (default)"below": Vertical stack layoutSplit Management:
The splits prop determines the number of editor panes. Each pane shares the same configuration but can have individual content, annotations, and markers.
interface SplitConfiguration {
/** Number of editor panes */
splits: number;
/** Layout orientation */
orientation?: "beside" | "below";
/** Content for each pane */
value?: string[];
/** Default content for each pane */
defaultValue?: string[];
/** Annotations per pane */
annotations?: IAnnotation[][];
/** Markers per pane */
markers?: IMarker[][];
}Split editor events provide information about which pane triggered the event:
/** Called when content changes in any split */
onChange?: (values: string[], event?: {
splitIndex?: number;
start: { row: number; column: number };
end: { row: number; column: number };
action: "insert" | "remove";
lines: string[];
}) => void;
/** Called when selection changes in any split */
onSelectionChange?: (selection: {
start: { row: number; column: number };
end: { row: number; column: number };
splitIndex?: number;
}, event?: any) => void;Synchronized Scrolling:
By default, split panes scroll independently. For synchronized scrolling, you can implement custom scroll handlers.
Individual Pane Access:
Each split pane can be accessed through the editor instance provided in the onLoad callback.
Performance Considerations:
Install with Tessl CLI
npx tessl i tessl/npm-react-ace