A React-based markdown editor with live preview functionality, implemented with TypeScript.
—
The command system provides extensible toolbar actions and text formatting capabilities through a comprehensive set of built-in commands and support for custom commands.
Core interface for defining toolbar commands and text formatting actions.
/**
* Base interface for command definitions used in toolbar and text formatting
*/
interface ICommandBase<T = string> {
/** Parent command reference */
parent?: ICommand<any>;
/** Internal command key */
keyCommand?: string;
/** Command name identifier */
name?: string;
/** Keyboard shortcuts */
shortcuts?: string;
/** Group name for command organization */
groupName?: string;
/** Command icon React element */
icon?: React.ReactElement;
/** Command value */
value?: string;
/** Text prefix for formatting commands */
prefix?: string;
/** Text suffix for formatting commands */
suffix?: string;
/** Toolbar position */
position?: 'right';
/** List item HTML attributes */
liProps?: React.LiHTMLAttributes<HTMLLIElement>;
/** Button props (null disables button rendering) */
buttonProps?: React.ButtonHTMLAttributes<HTMLButtonElement> | null;
/** Custom render function for command UI */
render?: (
command: ICommand<T>,
disabled: boolean,
executeCommand: (command: ICommand<T>, name?: string) => void,
index: number
) => void | undefined | null | React.ReactElement;
/** Command execution function */
execute?: (
state: ExecuteState,
api: TextAreaTextApi,
dispatch?: React.Dispatch<ContextStore>,
executeCommandState?: ExecuteCommandState,
shortcuts?: string[]
) => void;
}
/**
* Command with array of child commands
*/
interface ICommandChildCommands<T = string> extends ICommandBase<T> {
children?: Array<ICommand<T>>;
}
/**
* Command with render function for child components
*/
interface ICommandChildHandle<T = string> extends ICommandBase<T> {
children?: (handle: {
close: () => void;
execute: () => void;
getState?: TextAreaCommandOrchestrator['getState'];
textApi?: TextAreaTextApi;
dispatch?: React.Dispatch<ContextStore>;
}) => React.ReactElement;
}
/**
* Union type for all command variations
*/
type ICommand<T = string> = ICommandChildCommands<T> | ICommandChildHandle<T>;
interface ExecuteState extends TextState {
command: ICommand;
}
interface ExecuteCommandState {
fullscreen?: boolean;
preview?: PreviewType;
highlightEnable?: boolean;
}Comprehensive set of pre-built commands for common markdown formatting and editor controls.
/**
* Built-in commands namespace containing all available commands
*/
declare const commands: {
// Text formatting commands
bold: ICommand;
italic: ICommand;
strikethrough: ICommand;
// Heading commands
title: ICommand; // Alias for title1
heading: ICommand; // Alias for title1
title1: ICommand; // H1 heading
heading1: ICommand; // H1 heading
title2: ICommand; // H2 heading
heading2: ICommand; // H2 heading
title3: ICommand; // H3 heading
heading3: ICommand; // H3 heading
title4: ICommand; // H4 heading
heading4: ICommand; // H4 heading
title5: ICommand; // H5 heading
heading5: ICommand; // H5 heading
title6: ICommand; // H6 heading
heading6: ICommand; // H6 heading
// Content commands
link: ICommand; // Link insertion [text](url)
quote: ICommand; // Quote block >
code: ICommand; // Inline code `code`
codeBlock: ICommand; // Code block ```
comment: ICommand; // HTML comment <!-- -->
image: ICommand; // Image insertion 
table: ICommand; // Table insertion
hr: ICommand; // Horizontal rule ---
// List commands
unorderedListCommand: ICommand; // Unordered list -
orderedListCommand: ICommand; // Ordered list 1.
checkedListCommand: ICommand; // Checklist - [ ]
// UI commands
divider: ICommand; // Visual separator in toolbar
group: ICommand; // Command grouping utility
help: ICommand; // Help command
issue: ICommand; // Issue link command
// Preview mode commands
codeEdit: ICommand; // Edit mode only
codeLive: ICommand; // Split edit/preview mode
codePreview: ICommand; // Preview mode only
fullscreen: ICommand; // Toggle fullscreen mode
};Usage Examples:
import MDEditor, { commands } from "@uiw/react-md-editor";
// Basic command selection
function EditorWithBasicCommands() {
const [value, setValue] = useState("");
return (
<MDEditor
value={value}
onChange={setValue}
commands={[
commands.bold,
commands.italic,
commands.strikethrough,
commands.hr,
commands.divider,
commands.link,
commands.quote,
commands.code,
commands.image
]}
/>
);
}
// Full command set
function EditorWithAllCommands() {
return (
<MDEditor
value={value}
onChange={setValue}
commands={[
commands.bold, commands.italic, commands.strikethrough,
commands.title1, commands.title2, commands.title3,
commands.title4, commands.title5, commands.title6,
commands.link, commands.quote, commands.code, commands.codeBlock,
commands.comment, commands.image, commands.table, commands.hr,
commands.unorderedListCommand, commands.orderedListCommand,
commands.checkedListCommand
]}
extraCommands={[
commands.codeEdit, commands.codeLive, commands.codePreview,
commands.divider, commands.fullscreen
]}
/>
);
}Utility functions for working with commands and getting default command sets.
/**
* Get the default commands array
* @returns Array of default commands for the toolbar
*/
declare function getCommands(): ICommand[];
/**
* Get the default extra commands array (preview modes, fullscreen)
* @returns Array of extra commands for the toolbar
*/
declare function getExtraCommands(): ICommand[];
/**
* Execute heading command with specified level
* @param state - Current execution state
* @param api - Text API for manipulation
* @param dispatch - State dispatcher
* @param executeCommandState - Execute command state
* @param shortcuts - Keyboard shortcuts array
* @param level - Heading level (1-6)
*/
declare function headingExecute(
state: ExecuteState,
api: TextAreaTextApi,
dispatch?: React.Dispatch<ContextStore>,
executeCommandState?: ExecuteCommandState,
shortcuts?: string[],
level?: number
): void;Create custom commands for specialized functionality.
/**
* Example custom command implementation
*/
const customCommand: ICommand = {
name: 'custom',
keyCommand: 'custom',
shortcuts: 'ctrl+k',
prefix: '**CUSTOM:** ',
suffix: '',
icon: <CustomIcon />,
execute: (state: ExecuteState) => {
const { textApi, dispatch } = state;
const selectedText = textApi.getState()?.selectedText || 'default text';
textApi.replaceSelection(`**CUSTOM:** ${selectedText}`);
dispatch?.({ type: 'custom_action' });
}
};
/**
* Group options for organizing commands
*/
type GroupOptions = Omit<ICommand<string>, 'children'> & {
children?: ICommandChildHandle['children'];
};
/**
* Create a grouped command containing multiple child commands
* @param arr - Array of child commands to group together
* @param options - Configuration options for the group
* @returns Group command with dropdown behavior
*/
declare function group(arr: ICommandChildCommands['children'], options?: GroupOptions): ICommand<string>;Usage Examples:
// Command filtering
function EditorWithFilteredCommands() {
const commandsFilter = (command: ICommand, isExtra: boolean) => {
// Remove certain commands
if (command.keyCommand === 'image') return false;
return command;
};
return (
<MDEditor
value={value}
onChange={setValue}
commandsFilter={commandsFilter}
/>
);
}
// Using the group function
import { group, commands } from "@uiw/react-md-editor";
const titleGroup = group([
commands.title1,
commands.title2,
commands.title3,
commands.title4,
commands.title5,
commands.title6
], {
name: 'title',
groupName: 'title',
buttonProps: { 'aria-label': 'Insert title', title: 'Insert title' }
});
// Custom commands with children
const customGroup: ICommand = {
name: 'customGroup',
groupName: 'Custom',
icon: <GroupIcon />,
children: [
commands.bold,
commands.italic,
{
name: 'customAction',
keyCommand: 'customAction',
icon: <ActionIcon />,
execute: (state) => {
// Custom action logic
}
}
]
};Classes for managing command execution and textarea manipulation.
/**
* Command orchestrator for managing command execution on textarea elements
*/
declare class TextAreaCommandOrchestrator {
constructor(textArea: HTMLTextAreaElement);
/**
* Get current textarea state
* @returns Current text state or false if unavailable
*/
getState(): false | TextState;
/**
* Execute a command on the textarea
* @param command - Command to execute
* @param dispatch - Optional state dispatcher
* @param state - Optional context state
* @param shortcuts - Optional keyboard shortcuts
*/
executeCommand(
command: ICommand,
dispatch?: React.Dispatch<ContextStore>,
state?: ContextStore,
shortcuts?: string
): void;
}
/**
* Generic command orchestrator interface
*/
interface CommandOrchestrator {
executeCommand(command: ICommand): void;
}Localized commands for Chinese language support with Chinese labels and tooltips.
/**
* Chinese localized commands with same API as standard commands
* Import from '@uiw/react-md-editor/commands-cn'
*/
declare const commands: {
bold: ICommand; // 粗体
italic: ICommand; // 斜体
strikethrough: ICommand; // 删除线
title: ICommand; // 标题
title1: ICommand; // 一级标题
title2: ICommand; // 二级标题
title3: ICommand; // 三级标题
title4: ICommand; // 四级标题
title5: ICommand; // 五级标题
title6: ICommand; // 六级标题
link: ICommand; // 链接
quote: ICommand; // 引用
code: ICommand; // 代码
codeBlock: ICommand; // 代码块
comment: ICommand; // 注释
image: ICommand; // 图片
table: ICommand; // 表格
hr: ICommand; // 分割线
unorderedListCommand: ICommand; // 无序列表
orderedListCommand: ICommand; // 有序列表
checkedListCommand: ICommand; // 任务列表
// ... all other commands with Chinese localization
};Usage Example:
import { commands } from "@uiw/react-md-editor/commands-cn";
function ChineseEditor() {
return (
<MDEditor
value={value}
onChange={setValue}
commands={[
commands.bold, // 显示为 "粗体"
commands.italic, // 显示为 "斜体"
commands.title1, // 显示为 "一级标题"
commands.link, // 显示为 "链接"
commands.image, // 显示为 "图片"
commands.table // 显示为 "表格"
]}
extraCommands={[
commands.codeEdit, // 显示为 "编辑模式"
commands.codeLive, // 显示为 "实时预览"
commands.codePreview, // 显示为 "预览模式"
commands.fullscreen // 显示为 "全屏"
]}
/>
);
}Install with Tessl CLI
npx tessl i tessl/npm-uiw--react-md-editor