React components and hooks for building customizable rich text editors using the Slate framework.
npx @tessl/cli install tessl/npm-slate-react@0.117.0Slate React provides React-specific integration components, hooks, and utilities for building completely customizable rich text editors using the Slate framework. It enables developers to create sophisticated rich text editing experiences similar to Medium, Google Docs, or Dropbox Paper while maintaining full control over styling, behavior, and functionality through React's component model.
npm install slate-react react react-dom slate slate-domimport {
Slate,
Editable,
withReact,
useSlate,
useSlateStatic,
ReactEditor,
RenderElementProps,
RenderLeafProps,
RenderTextProps,
RenderPlaceholderProps,
RenderChunkProps
} from "slate-react";For CommonJS:
const {
Slate,
Editable,
withReact,
useSlate,
useSlateStatic,
ReactEditor
} = require("slate-react");import React, { useMemo, useState } from 'react';
import { createEditor, Descendant } from 'slate';
import { Slate, Editable, withReact } from 'slate-react';
const MyEditor = () => {
const editor = useMemo(() => withReact(createEditor()), []);
const [value, setValue] = useState<Descendant[]>([
{
type: 'paragraph',
children: [{ text: 'A line of text in a paragraph.' }],
},
]);
return (
<Slate
editor={editor}
initialValue={value}
onChange={setValue}
>
<Editable
placeholder="Enter some rich text…"
renderElement={({ attributes, children, element }) => (
<div {...attributes}>{children}</div>
)}
renderLeaf={({ attributes, children, leaf }) => (
<span {...attributes}>{children}</span>
)}
/>
</Slate>
);
};Slate React is built around several key components:
Slate component manages editor state and provides contextEditable handles DOM rendering, events, and user interactionswithReact() enhances editors with React-specific behaviorsEssential React components for building rich text editors. The foundation for any Slate React implementation.
function Slate(props: {
editor: ReactEditor;
initialValue: Descendant[];
children: React.ReactNode;
onChange?: (value: Descendant[]) => void;
onSelectionChange?: (selection: Selection) => void;
onValueChange?: (value: Descendant[]) => void;
}): JSX.Element;
function Editable(props: EditableProps): JSX.Element;React hooks for accessing editor state, selection, focus, and other editor properties. Essential for building interactive editor features.
function useSlate(): Editor;
function useSlateStatic(): Editor;
function useFocused(): boolean;
function useSelected(): boolean;
function useReadOnly(): boolean;
function useComposing(): boolean;
function useSlateSelection(): BaseSelection;React-specific plugin functionality that integrates Slate with React's lifecycle and event system.
function withReact<T extends BaseEditor>(
editor: T,
clipboardFormatKey?: string
): T & ReactEditor;
interface ReactEditor extends DOMEditor {
getChunkSize(node: Ancestor): number | null;
}Customizable render functions for controlling how editor content is displayed. Essential for creating custom editor UI.
interface RenderElementProps {
children: any;
element: Element;
attributes: {
'data-slate-node': 'element';
'data-slate-inline'?: true;
'data-slate-void'?: true;
dir?: 'rtl';
ref: any;
};
}
interface RenderLeafProps {
children: any;
leaf: Text;
text: Text;
attributes: {
'data-slate-leaf': true;
ref: any;
};
leafPosition?: LeafPosition;
}Advanced hooks and utilities for optimizing editor performance, especially important for large documents.
function useSlateSelector<T>(
selector: (editor: Editor) => T,
equalityFn?: (a: T | null, b: T) => boolean,
options?: SlateSelectorOptions
): T;
interface SlateSelectorOptions {
deferred?: boolean;
}Additional utility functions and re-exported constants from slate-dom.
function defaultScrollSelectionIntoView(
editor: ReactEditor,
domRange: DOMRange
): void;
// Re-exported from slate-dom
const NODE_TO_INDEX: WeakMap<Node, number>;
const NODE_TO_PARENT: WeakMap<Node, Node>;Core type definitions used throughout the API:
interface EditableProps extends React.TextareaHTMLAttributes<HTMLDivElement> {
decorate?: (entry: NodeEntry) => DecoratedRange[];
onDOMBeforeInput?: (event: InputEvent) => void;
placeholder?: string;
readOnly?: boolean;
renderElement?: (props: RenderElementProps) => JSX.Element;
renderChunk?: (props: RenderChunkProps) => JSX.Element;
renderLeaf?: (props: RenderLeafProps) => JSX.Element;
renderText?: (props: RenderTextProps) => JSX.Element;
renderPlaceholder?: (props: RenderPlaceholderProps) => JSX.Element;
scrollSelectionIntoView?: (editor: ReactEditor, domRange: DOMRange) => void;
as?: React.ElementType;
disableDefaultStyles?: boolean;
}
interface RenderChunkProps {
highest: boolean;
lowest: boolean;
children: any;
attributes: {
'data-slate-chunk': true;
ref: any;
};
}
interface RenderTextProps {
text: Text;
children: any;
attributes: {
'data-slate-node': 'text';
ref: any;
};
}
interface RenderPlaceholderProps {
children: any;
attributes: {
'data-slate-placeholder': boolean;
dir?: 'rtl';
contentEditable: boolean;
ref: React.RefCallback<any>;
style: React.CSSProperties;
};
}