rst-rich-text-editor
v2.1.1
Published
React rich text editor with toolbar, tables, images, and react-hook-form support
Downloads
470
Maintainers
Readme
rst-rich-text-editor
React rich text editor with toolbar controls, image/table tools, personalization tokens, email preview helpers, and react-hook-form compatibility.
Package exports (v2)
From v2.0.0 onward this library is named-export only. There is no default export on the package entry (rst-rich-text-editor). That avoids mixed default/named CommonJS output and the build warnings that come with it.
Update your imports:
// Before (v1 — default export; no longer supported)
import CustomRichTextEditor from "rst-rich-text-editor";
// After (v2 — use the named export)
import { CustomRichTextEditor } from "rst-rich-text-editor";All public APIs (CustomRichTextEditor, email helpers, types) stay available as named exports from the same entry. Subpath rst-rich-text-editor/styles.css is unchanged.
Installation
npm install rst-rich-text-editorPeer dependencies
reactreact-domdompurify(required — HTML sanitization)react-hook-form(optional — only when usingcontrol/nameprops)lucide-react(optional — toolbar icons; required for default UI)
Basic usage
import "rst-rich-text-editor/styles.css";
import { CustomRichTextEditor } from "rst-rich-text-editor";
export function Example() {
return (
<CustomRichTextEditor
label="Content"
value="<p>Hello</p>"
onChange={(nextHtml) => console.log(nextHtml)}
height={320}
enablePreview
enableImageInsert
enableTableInsert
enablePersonalize
/>
);
}styles.css is scoped under .rte-scope, so importing globally does not restyle unrelated pages.
With react-hook-form
import "rst-rich-text-editor/styles.css";
import { useForm } from "react-hook-form";
import { CustomRichTextEditor } from "rst-rich-text-editor";
type FormValues = { body: string };
export function FormExample() {
const { control, handleSubmit } = useForm<FormValues>({
defaultValues: { body: "" },
});
return (
<form onSubmit={handleSubmit(console.log)}>
<CustomRichTextEditor<FormValues>
control={control}
name="body"
label="Email Body"
enablePreview
/>
<button type="submit">Save</button>
</form>
);
}Email output helpers
For save/send/preview pipelines, use the built-in helper:
import { prepareEmailPreviewHtml } from "rst-rich-text-editor";
const finalHtml = prepareEmailPreviewHtml(editorHtml);Available exports:
CustomRichTextEditor(named export only; see Package exports (v2))prepareEmailPreviewHtmlapplyEmailRichTextOutputStylesunwrapEscapedHtmlsanitizeEmailHtmlsanitizeFullDocumentWithStyleswrapFragmentInDocumentisFullDocument
Theme tokens
Override editor colors by redefining --rte-* tokens:
.rte-scope {
--rte-background: 255 255 255;
--rte-foreground: 15 23 42;
--rte-border: 226 232 240;
--rte-default: 41 37 99;
--rte-muted: 243 244 246;
--rte-destructive: 220 38 38;
}
.dark .rte-scope,
[data-theme="dark"] .rte-scope {
--rte-background: 15 23 42;
--rte-foreground: 248 250 252;
--rte-border: 51 65 85;
--rte-default: 129 140 248;
--rte-muted: 30 41 59;
--rte-destructive: 239 68 68;
}Contributing / source layout
New to the codebase? Start with src/README.md for a folder map, dependency rules, and where to change toolbar vs DOM vs email logic. Deeper notes live in src/components/README.md, src/lib/editor/README.md, and src/email/README.md.
Notes
- Includes an in-editor Help panel (More menu) with quick usage guidance.
Build
npm run buildDevelopment
npm run typecheck
npm run test # runs tests in tests/
npm run test:watch
npm run ci # typecheck + build + test + publintTests live in tests/ (not published to npm; committed to git). Run npm run ci locally before publish.
Email helpers subpath
Tree-shake email utilities without the React editor UI:
import { prepareEmailPreviewHtml, sanitizeEmailHtml } from "rst-rich-text-editor/email";i18n / custom labels
<CustomRichTextEditor
labels={{
toolbar: { bold: "Gras", preview: "Aperçu" },
placeholders: { default: "Commencez à écrire…" },
}}
/>Export DEFAULT_EDITOR_LABELS, mergeEditorLabels, and EditorLabels from the package entry for apps that build label maps programmatically.
Headless engine (advanced)
For custom UIs or tests without React:
import { createRichTextEngine, parseDocumentCommand } from "rst-rich-text-editor";
const engine = createRichTextEngine(editorElement);
engine.run({ type: "bold" });
engine.runLegacy("formatBlock", "<h2>");