React wrapper component for CodeMirror 6 editor with TypeScript support and extensible theming system
—
Utility functions for extracting editor statistics and managing editor state information. These utilities provide detailed insights into the editor's current state and user interactions.
Function to extract comprehensive statistics from the editor's current state.
/**
* Extract comprehensive statistics from a ViewUpdate
* @param view - ViewUpdate object from CodeMirror
* @returns Statistics object with editor state information
*/
function getStatistics(view: ViewUpdate): Statistics;Usage Examples:
import React from "react";
import CodeMirror from "@uiw/react-codemirror";
import { getStatistics } from "@uiw/react-codemirror";
function StatisticsDisplay() {
const [stats, setStats] = React.useState(null);
const handleUpdate = (viewUpdate) => {
const currentStats = getStatistics(viewUpdate);
setStats(currentStats);
};
return (
<div>
<CodeMirror
value="console.log('Hello World');\nconst x = 42;"
onUpdate={handleUpdate}
height="200px"
/>
{stats && (
<div style={{ marginTop: 10, fontSize: 12 }}>
<div>Lines: {stats.lineCount}</div>
<div>Characters: {stats.length}</div>
<div>Selected: {stats.selectedText ? 'Yes' : 'No'}</div>
<div>Selection: {stats.selectionCode}</div>
<div>Read-only: {stats.readOnly ? 'Yes' : 'No'}</div>
<div>Tab size: {stats.tabSize}</div>
</div>
)}
</div>
);
}Comprehensive interface containing all available editor statistics.
interface Statistics {
/** Total length of the document in characters */
length: number;
/** Total number of lines in the editor */
lineCount: number;
/** Line object at current cursor position */
line: Line;
/** Line break string used by the editor (\\n, \\r\\n, etc.) */
lineBreak: string;
/** Whether the editor is in read-only mode */
readOnly: boolean;
/** Size of tab character in columns */
tabSize: number;
/** Current selection object with all ranges */
selection: EditorSelection;
/** Primary selection range as single range */
selectionAsSingle: SelectionRange;
/** Array of all selection ranges */
ranges: readonly SelectionRange[];
/** Text content of current selection */
selectionCode: string;
/** Array of selected text for each selection range */
selections: string[];
/** Whether any text is currently selected */
selectedText: boolean;
}Usage Examples:
import React from "react";
import CodeMirror from "@uiw/react-codemirror";
import { getStatistics } from "@uiw/react-codemirror";
// Detailed statistics usage
function DetailedStatistics() {
const [stats, setStats] = React.useState(null);
const handleStatistics = (statistics) => {
setStats(statistics);
// Access specific properties
console.log('Document info:', {
totalChars: statistics.length,
lines: statistics.lineCount,
lineBreak: statistics.lineBreak === '\n' ? 'LF' : 'CRLF',
});
// Current line information
console.log('Current line:', {
number: statistics.line.number,
text: statistics.line.text,
from: statistics.line.from,
to: statistics.line.to,
});
// Selection information
if (statistics.selectedText) {
console.log('Selection:', {
text: statistics.selectionCode,
ranges: statistics.ranges.length,
multipleSelections: statistics.ranges.length > 1,
});
}
};
return (
<CodeMirror
value={`Line 1
Line 2
Line 3 with more content`}
onStatistics={handleStatistics}
height="150px"
/>
);
}
// Selection tracking
function SelectionTracker() {
const [selectionInfo, setSelectionInfo] = React.useState({
hasSelection: false,
selectedText: '',
ranges: 0,
});
const handleStatistics = (stats) => {
setSelectionInfo({
hasSelection: stats.selectedText,
selectedText: stats.selectionCode,
ranges: stats.ranges.length,
});
};
return (
<div>
<CodeMirror
value="Select some text in this editor to see selection details."
onStatistics={handleStatistics}
height="100px"
/>
<div style={{ marginTop: 10 }}>
<div>Has selection: {selectionInfo.hasSelection ? 'Yes' : 'No'}</div>
{selectionInfo.hasSelection && (
<>
<div>Selected text: "{selectionInfo.selectedText}"</div>
<div>Selection ranges: {selectionInfo.ranges}</div>
</>
)}
</div>
</div>
);
}Details about line objects and their properties.
// Line interface (from @codemirror/state)
interface Line {
/** Line number (1-based) */
readonly number: number;
/** Start position of line in document */
readonly from: number;
/** End position of line in document (excluding line break) */
readonly to: number;
/** Text content of the line */
readonly text: string;
/** Length of the line */
readonly length: number;
}Usage Examples:
import React from "react";
import CodeMirror from "@uiw/react-codemirror";
import { getStatistics } from "@uiw/react-codemirror";
function LineInformation() {
const [lineInfo, setLineInfo] = React.useState(null);
const handleStatistics = (stats) => {
const { line } = stats;
setLineInfo({
number: line.number,
text: line.text,
length: line.length,
isEmpty: line.length === 0,
position: {
from: line.from,
to: line.to,
},
});
};
return (
<div>
<CodeMirror
value={`First line
Second line with more text
Fourth line (third was empty)`}
onStatistics={handleStatistics}
height="120px"
/>
{lineInfo && (
<div style={{ marginTop: 10, fontSize: 12, fontFamily: 'monospace' }}>
<div>Current line: {lineInfo.number}</div>
<div>Line text: "{lineInfo.text}"</div>
<div>Line length: {lineInfo.length}</div>
<div>Empty line: {lineInfo.isEmpty ? 'Yes' : 'No'}</div>
<div>Position: {lineInfo.position.from}-{lineInfo.position.to}</div>
</div>
)}
</div>
);
}Details about selection ranges and their properties.
// Selection interfaces (from @codemirror/state)
interface EditorSelection {
/** All selection ranges */
readonly ranges: readonly SelectionRange[];
/** Primary selection range */
readonly main: SelectionRange;
/** Convert to single range selection */
asSingle(): EditorSelection;
}
interface SelectionRange {
/** Start position of selection */
readonly from: number;
/** End position of selection */
readonly to: number;
/** Whether the selection is empty (cursor) */
readonly empty: boolean;
/** Anchor position (where selection started) */
readonly anchor: number;
/** Head position (where selection ends) */
readonly head: number;
}Usage Examples:
import React from "react";
import CodeMirror from "@uiw/react-codemirror";
function SelectionDetails() {
const [selectionDetails, setSelectionDetails] = React.useState(null);
const handleStatistics = (stats) => {
const { selection, ranges, selectionCode, selections } = stats;
setSelectionDetails({
mainRange: {
from: selection.main.from,
to: selection.main.to,
empty: selection.main.empty,
anchor: selection.main.anchor,
head: selection.main.head,
},
totalRanges: ranges.length,
allSelections: selections,
combinedText: selectionCode,
});
};
return (
<div>
<CodeMirror
value="Try selecting text with mouse or keyboard. Use Ctrl+Click for multiple selections."
onStatistics={handleStatistics}
height="100px"
/>
{selectionDetails && (
<div style={{ marginTop: 10, fontSize: 12 }}>
<div><strong>Main Selection:</strong></div>
<div> From: {selectionDetails.mainRange.from}, To: {selectionDetails.mainRange.to}</div>
<div> Empty: {selectionDetails.mainRange.empty ? 'Yes' : 'No'}</div>
<div> Anchor: {selectionDetails.mainRange.anchor}, Head: {selectionDetails.mainRange.head}</div>
<div style={{ marginTop: 8 }}><strong>All Selections:</strong></div>
<div> Total ranges: {selectionDetails.totalRanges}</div>
{selectionDetails.allSelections.map((text, index) => (
<div key={index}> Range {index + 1}: "{text}"</div>
))}
{selectionDetails.combinedText && (
<div style={{ marginTop: 8 }}>
<strong>Combined selection:</strong> "{selectionDetails.combinedText}"
</div>
)}
</div>
)}
</div>
);
}The package also exports internal utility classes for timeout management, primarily used for debouncing editor updates.
/**
* Timeout management class for debounced callbacks
* Used internally by the editor for optimizing update performance
*/
class TimeoutLatch {
constructor(callback: Function, timeoutMS: number);
/** Manually trigger the timeout tick */
tick(): void;
/** Cancel the timeout */
cancel(): void;
/** Reset the timeout to its original duration */
reset(): void;
/** Check if the timeout is done (cancelled or expired) */
readonly isDone: boolean;
}
/**
* Get the global scheduler instance for timeout management
* Returns singleton for browser environments, new instance for server
*/
function getScheduler(): Scheduler;Note: These utilities are primarily for internal use and advanced customization scenarios.
Install with Tessl CLI
npx tessl i tessl/npm-uiw--react-codemirror