React components and hooks for building customizable rich text editors using the Slate framework.
—
Essential React components for building rich text editors. These components form the foundation of any Slate React implementation.
The Slate component is a React provider that wraps the editor and manages its state. It provides the editor context to all child components and handles editor state changes.
/**
* Provider component that wraps the editor and manages state
* @param props - Slate component props
* @returns JSX element providing editor context
*/
function Slate(props: {
editor: ReactEditor;
initialValue: Descendant[];
children: React.ReactNode;
onChange?: (value: Descendant[]) => void;
onSelectionChange?: (selection: Selection) => void;
onValueChange?: (value: Descendant[]) => void;
}): JSX.Element;Usage Example:
import React, { useMemo, useState } from 'react';
import { createEditor, Descendant } from 'slate';
import { Slate, withReact } from 'slate-react';
const MyEditor = () => {
const editor = useMemo(() => withReact(createEditor()), []);
const [value, setValue] = useState<Descendant[]>([
{ type: 'paragraph', children: [{ text: 'Hello world!' }] }
]);
return (
<Slate
editor={editor}
initialValue={value}
onChange={setValue}
onSelectionChange={(selection) => console.log('Selection changed:', selection)}
>
{/* Editor components go here */}
</Slate>
);
};The Editable component renders the main editor interface where users can input and edit text. It handles DOM events, keyboard interactions, and content rendering.
/**
* Main editable component that renders the editor content area
* @param props - Editable component props
* @returns JSX element for the editable area
*/
function Editable(props: EditableProps): JSX.Element;
interface EditableProps extends React.TextareaHTMLAttributes<HTMLDivElement> {
/** Function to add decorations to text ranges */
decorate?: (entry: NodeEntry) => DecoratedRange[];
/** Handler for DOM beforeinput events */
onDOMBeforeInput?: (event: InputEvent) => void;
/** Placeholder text when editor is empty */
placeholder?: string;
/** Whether the editor is read-only */
readOnly?: boolean;
/** ARIA role for accessibility */
role?: string;
/** CSS styles for the editor */
style?: React.CSSProperties;
/** Custom element renderer */
renderElement?: (props: RenderElementProps) => JSX.Element;
/** Custom chunk renderer for performance optimization */
renderChunk?: (props: RenderChunkProps) => JSX.Element;
/** Custom leaf renderer */
renderLeaf?: (props: RenderLeafProps) => JSX.Element;
/** Custom text renderer */
renderText?: (props: RenderTextProps) => JSX.Element;
/** Custom placeholder renderer */
renderPlaceholder?: (props: RenderPlaceholderProps) => JSX.Element;
/** Custom scroll behavior for selection */
scrollSelectionIntoView?: (editor: ReactEditor, domRange: DOMRange) => void;
/** HTML element type to render (default: div) */
as?: React.ElementType;
/** Disable default Slate CSS styles */
disableDefaultStyles?: boolean;
}Usage Example:
import React from 'react';
import { Editable, RenderElementProps, RenderLeafProps } from 'slate-react';
const renderElement = ({ attributes, children, element }: RenderElementProps) => {
switch (element.type) {
case 'paragraph':
return <p {...attributes}>{children}</p>;
case 'heading':
return <h1 {...attributes}>{children}</h1>;
default:
return <div {...attributes}>{children}</div>;
}
};
const renderLeaf = ({ attributes, children, leaf }: RenderLeafProps) => {
if (leaf.bold) {
children = <strong>{children}</strong>;
}
if (leaf.italic) {
children = <em>{children}</em>;
}
return <span {...attributes}>{children}</span>;
};
const MyEditable = () => (
<Editable
placeholder="Type something..."
renderElement={renderElement}
renderLeaf={renderLeaf}
onDOMBeforeInput={(event) => {
// Handle input events
console.log('Input event:', event);
}}
/>
);Slate React provides default components for common rendering scenarios. These can be used as-is or as references for custom implementations.
/**
* Default element renderer component
* @param props - Element render props
* @returns Default element rendering (span for inline, div for block)
*/
function DefaultElement(props: RenderElementProps): JSX.Element;
/**
* Default leaf renderer component
* @param props - Leaf render props
* @returns Default leaf rendering (span)
*/
function DefaultLeaf(props: RenderLeafProps): JSX.Element;
/**
* Default text renderer component
* @param props - Text render props
* @returns Default text rendering (span)
*/
function DefaultText(props: RenderTextProps): JSX.Element;
/**
* Default placeholder renderer component
* @param props - Placeholder render props
* @returns Default placeholder rendering
*/
function DefaultPlaceholder(props: RenderPlaceholderProps): JSX.Element;Usage Example:
import { Editable, DefaultElement, DefaultLeaf } from 'slate-react';
// Use default components when you don't need custom rendering
const SimpleEditor = () => (
<Editable
renderElement={DefaultElement}
renderLeaf={DefaultLeaf}
placeholder="Start typing..."
/>
);/**
* Default implementation to scroll DOM range into view
* @param editor - The ReactEditor instance
* @param domRange - DOM range to scroll into view
*/
function defaultScrollSelectionIntoView(
editor: ReactEditor,
domRange: DOMRange
): void;Usage Example:
import { Editable, defaultScrollSelectionIntoView } from 'slate-react';
const CustomEditor = () => (
<Editable
scrollSelectionIntoView={defaultScrollSelectionIntoView}
// or provide custom scroll behavior
// scrollSelectionIntoView={(editor, domRange) => {
// // Custom scroll logic
// }}
/>
);The core components work together to create a complete editing experience:
// Complete basic editor setup
import React, { useMemo, useState } from 'react';
import { createEditor, Descendant } from 'slate';
import { Slate, Editable, withReact } from 'slate-react';
const BasicEditor = () => {
const editor = useMemo(() => withReact(createEditor()), []);
const [value, setValue] = useState<Descendant[]>([
{ type: 'paragraph', children: [{ text: 'Hello world!' }] }
]);
return (
<Slate editor={editor} initialValue={value} onChange={setValue}>
<Editable
placeholder="Enter text here..."
renderElement={({ attributes, children }) => (
<p {...attributes}>{children}</p>
)}
renderLeaf={({ attributes, children }) => (
<span {...attributes}>{children}</span>
)}
/>
</Slate>
);
};Install with Tessl CLI
npx tessl i tessl/npm-slate-react