A React-based markdown editor with live preview functionality, implemented with TypeScript.
—
The MDEditor component is the main React component providing a complete markdown editing experience with toolbar, textarea, and live preview functionality.
The primary markdown editor component with full TypeScript support and customizable interface.
/**
* Main markdown editor component with live preview functionality
* @param props - Component props including value, onChange, and customization options
* @returns React component with forward ref support
*/
declare const MDEditor: React.ForwardedRefComponent<RefMDEditor, MDEditorProps>;
interface MDEditorProps {
/** The markdown content value */
value?: string;
/** Change event handler called when content is modified */
onChange?: (value?: string, event?: React.ChangeEvent<HTMLTextAreaElement>, state?: ContextStore) => void;
/** Height change event handler */
onHeightChange?: (value?: CSSProperties['height'], oldValue?: CSSProperties['height'], state?: ContextStore) => void;
/** Statistics callback for editor metrics */
onStatistics?: (data: Statistics) => void;
/** Editor height (default: 200) */
height?: CSSProperties['height'];
/** Minimum drag height (default: 100) */
minHeight?: number;
/** Maximum drag height (default: 1200) */
maxHeight?: number;
/** Show drag and drop tool (default: true) */
visibleDragbar?: boolean;
/** Hide the toolbar */
hideToolbar?: boolean;
/** Position toolbar at bottom */
toolbarBottom?: boolean;
/** Text direction ('ltr' | 'rtl') */
direction?: CSSProperties['direction'];
/** Preview mode ('live' | 'edit' | 'preview', default: 'live') */
preview?: PreviewType;
/** Full screen mode (default: false) */
fullscreen?: boolean;
/** Disable fullscreen body styles (default: true) */
overflow?: boolean;
/** React-markdown settings */
previewOptions?: Omit<MarkdownPreviewProps, 'source'>;
/** Auto focus on initialization */
autoFocus?: boolean;
/** Focus on end of text on initialization */
autoFocusEnd?: boolean;
/** Enable code highlighting (default: true) */
highlightEnable?: boolean;
/** Tab character count (default: 2) */
tabSize?: number;
/** Enable default tab behavior */
defaultTabEnable?: boolean;
/** Enable scrolling (default: true) */
enableScroll?: boolean;
/** Custom commands array */
commands?: ICommand[];
/** Additional commands array */
extraCommands?: ICommand[];
/** Command filter function */
commandsFilter?: (command: ICommand, isExtra: boolean) => false | ICommand;
/** Textarea-specific props */
textareaProps?: ITextAreaProps;
/** Custom component renderers */
components?: {
textarea?: (props: any) => React.ReactElement;
toolbar?: (command: ICommand, disabled: boolean, executeCommand: Function, index: number) => React.ReactElement;
preview?: (props: any) => React.ReactElement;
};
/** Theme configuration */
'data-color-mode'?: 'light' | 'dark';
}
interface RefMDEditor extends ContextStore {
textarea?: HTMLTextAreaElement;
container?: HTMLDivElement;
}
type PreviewType = 'live' | 'edit' | 'preview';Usage Examples:
import React, { useState } from "react";
import MDEditor from "@uiw/react-md-editor";
// Basic usage
function BasicEditor() {
const [value, setValue] = useState("# Hello World");
return (
<MDEditor
value={value}
onChange={setValue}
/>
);
}
// Advanced configuration
function AdvancedEditor() {
const [value, setValue] = useState("");
return (
<MDEditor
value={value}
onChange={setValue}
height={400}
preview="live"
hideToolbar={false}
visibleDragbar={true}
highlightEnable={true}
autoFocus={true}
data-color-mode="dark"
textareaProps={{
placeholder: "Enter your markdown here...",
style: { fontSize: '14px' }
}}
onHeightChange={(height, oldHeight) => {
console.log('Height changed:', height);
}}
onStatistics={(stats) => {
console.log('Editor stats:', stats);
}}
/>
);
}
// Custom preview options
function EditorWithCustomPreview() {
const [value, setValue] = useState("");
return (
<MDEditor
value={value}
onChange={setValue}
previewOptions={{
rehypePlugins: [[rehypeHighlight]],
components: {
code: ({ children, ...props }) => (
<code {...props} style={{ background: '#f0f0f0' }}>
{children}
</code>
)
}
}}
/>
);
}React context providing editor state throughout the component tree.
/**
* React context for editor state management
*/
declare const EditorContext: React.Context<ContextStore>;
interface ContextStore {
/** Component renderers */
components?: MDEditorProps['components'];
/** Current commands */
commands?: ICommand<string>[];
/** Current extra commands */
extraCommands?: ICommand<string>[];
/** Current markdown content */
markdown?: string;
/** Current preview mode */
preview?: PreviewType;
/** Editor height */
height?: CSSProperties['height'];
/** Fullscreen state */
fullscreen?: boolean;
/** Syntax highlighting state */
highlightEnable?: boolean;
/** Auto focus state */
autoFocus?: boolean;
/** Auto focus end state */
autoFocusEnd?: boolean;
/** Textarea element reference */
textarea?: HTMLTextAreaElement;
/** Command orchestrator instance */
commandOrchestrator?: TextAreaCommandOrchestrator;
/** Textarea wrapper element */
textareaWarp?: HTMLDivElement;
/** Textarea pre element for highlighting */
textareaPre?: HTMLPreElement;
/** Container element reference */
container?: HTMLDivElement | null;
/** State dispatcher */
dispatch?: React.Dispatch<ContextStore>;
/** Bar popup states */
barPopup?: Record<string, boolean>;
/** Scroll position */
scrollTop?: number;
/** Preview scroll position */
scrollTopPreview?: number;
/** Tab size setting */
tabSize?: number;
/** Default tab enable setting */
defaultTabEnable?: boolean;
/** Additional properties */
[key: string]: any;
}Editor statistics and metrics data structure.
/**
* Editor statistics and metrics extending TextState
*/
interface Statistics extends TextState {
/** Total length of the document */
length: number;
/** Get the number of lines in the editor */
lineCount: number;
}Core interfaces for component styling and textarea customization.
/**
* Base props interface for styling components
*/
interface IProps {
/** CSS prefix class */
prefixCls?: string;
/** Additional CSS class name */
className?: string;
}
/**
* Textarea component props interface
*/
interface ITextAreaProps extends Omit<React.TextareaHTMLAttributes<HTMLTextAreaElement>, 'value' | 'onScroll'>, IProps {
/** Textarea value */
value?: string;
/** Scroll event handler for wrapper div */
onScroll?: (e: React.UIEvent<HTMLDivElement>) => void;
/** Custom textarea renderer */
renderTextarea?: (
props: React.TextareaHTMLAttributes<HTMLTextAreaElement> | React.HTMLAttributes<HTMLDivElement>,
opts: RenderTextareaHandle
) => JSX.Element;
}
/**
* Render handle for custom textarea implementations
*/
type RenderTextareaHandle = {
dispatch: ContextStore['dispatch'];
onChange?: (event: React.ChangeEvent<HTMLTextAreaElement>) => void;
useContext?: {
commands: ContextStore['commands'];
extraCommands: ContextStore['extraCommands'];
commandOrchestrator?: TextAreaCommandOrchestrator;
};
shortcuts?: (
e: KeyboardEvent | React.KeyboardEvent<HTMLTextAreaElement>,
commands: ICommand[],
commandOrchestrator?: TextAreaCommandOrchestrator,
dispatch?: React.Dispatch<ContextStore>,
state?: ExecuteCommandState
) => void;
};
/**
* Textarea element references
*/
type TextAreaRef = {
/** Textarea element reference */
text?: HTMLTextAreaElement;
/** Wrapper div element reference */
warp?: HTMLDivElement;
};
/**
* Subset of context store for command execution
*/
type ExecuteCommandState = Pick<ContextStore, 'fullscreen' | 'preview' | 'highlightEnable'>;Access to the underlying markdown preview component.
/**
* Standalone markdown preview component
* Available as MDEditor.Markdown
*/
interface MarkdownPreviewProps {
source: string;
style?: React.CSSProperties;
className?: string;
rehypePlugins?: any[];
remarkPlugins?: any[];
components?: Record<string, React.ComponentType>;
}Usage Example:
import MDEditor from "@uiw/react-md-editor";
function PreviewOnly() {
const markdown = "# Hello\n\nThis is **bold** text.";
return (
<MDEditor.Markdown
source={markdown}
style={{ whiteSpace: 'pre-wrap' }}
/>
);
}Performance-optimized version without syntax highlighting.
/**
* Performance-optimized editor without syntax highlighting
* Import from '@uiw/react-md-editor/nohighlight'
*/
declare const MDEditor: React.ForwardedRefComponent<RefMDEditor, MDEditorProps>;Usage Example:
import MDEditor from "@uiw/react-md-editor/nohighlight";
import "@uiw/react-md-editor/markdown-editor.css";
function FastEditor() {
const [value, setValue] = useState("");
return (
<MDEditor
value={value}
onChange={setValue}
highlightEnable={false} // No syntax highlighting for better performance
/>
);
}Install with Tessl CLI
npx tessl i tessl/npm-uiw--react-md-editor