CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-react-ace

A React component for Ace Editor providing comprehensive code editing capabilities with syntax highlighting, themes, and customization options

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

split-editor.mddocs/

Split Editor

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.

Capabilities

SplitComponent

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[][];
}

Usage Examples

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}
    />
  );
}

Split Configuration

Orientation Options:

  • "beside": Side-by-side horizontal layout (default)
  • "below": Vertical stack layout

Split 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[][];
}

Event Handling

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;

Advanced Features

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:

  • Use debounceChangePeriod to control update frequency
  • Consider virtualization for large numbers of splits
  • Minimize re-renders by using useCallback for event handlers

Install with Tessl CLI

npx tessl i tessl/npm-react-ace

docs

ace-editor.md

diff-editor.md

index.md

split-editor.md

tile.json