Skip to content

RichTextEditor

A rich text editor with a formatting toolbar built on TipTap and Chakra UI.

An editor that lets users format text with bold, italic, headings, lists, and links. Content is stored and emitted as a TipTap JSONContent object.

Use useRichTextEditor to create an editor instance, then compose the UI from RichTextEditor.* primitives and RichTextEditor.Control.* components.

import { RichTextEditor, useRichTextEditor } from "@caspeco/casper-ui-library";
export default function Demo() {
const editor = useRichTextEditor({ onChange: (content) => console.log(content) });
return (
<RichTextEditor.Root editor={editor}>
<RichTextEditor.Toolbar>
<RichTextEditor.ControlGroup>
<RichTextEditor.Control.Bold />
<RichTextEditor.Control.Italic />
<RichTextEditor.Control.Underline />
</RichTextEditor.ControlGroup>
<RichTextEditor.ControlGroup>
<RichTextEditor.Control.Heading1 />
<RichTextEditor.Control.Heading2 />
<RichTextEditor.Control.Heading3 />
<RichTextEditor.Control.Heading4 />
</RichTextEditor.ControlGroup>
<RichTextEditor.ControlGroup>
<RichTextEditor.Control.BulletList />
<RichTextEditor.Control.OrderedList />
</RichTextEditor.ControlGroup>
<RichTextEditor.ControlGroup>
<RichTextEditor.Control.Link />
</RichTextEditor.ControlGroup>
</RichTextEditor.Toolbar>
<RichTextEditor.Content />
</RichTextEditor.Root>
);
}

Place any combination of RichTextEditor.Control.* components inside a RichTextEditor.ControlGroup. Separate groups with additional RichTextEditor.ControlGroup elements — the toolbar renders a visual divider between them.

Control Description
RichTextEditor.Control.Bold Toggles bold
RichTextEditor.Control.Italic Toggles italic
RichTextEditor.Control.Underline Toggles underline
RichTextEditor.Control.Heading1 Toggles heading level 1
RichTextEditor.Control.Heading2 Toggles heading level 2
RichTextEditor.Control.Heading3 Toggles heading level 3
RichTextEditor.Control.Heading4 Toggles heading level 4
RichTextEditor.Control.BulletList Toggles an unordered list
RichTextEditor.Control.OrderedList Toggles an ordered list
RichTextEditor.Control.Link Opens a popover to insert or edit a link

Use RichTextRenderer to display stored JSONContent without an editor instance. It applies the same typography styles as the editor so content looks identical whether it is being edited or read.

import { RichTextRenderer } from "@caspeco/casper-ui-library";
<RichTextRenderer content={savedContent} />;

RichTextRenderer is a pure rendering component — it does not mount a TipTap editor, has no toolbar, and is safe to use in server-side rendering contexts.

import type { JSONContent } from "@caspeco/casper-ui-library";
import { RichTextRenderer } from "@caspeco/casper-ui-library";
const content: JSONContent = {
type: "doc",
content: [
{ type: "heading", attrs: { level: 2 }, content: [{ type: "text", text: "Meeting notes" }] },
{
type: "paragraph",
content: [
{ type: "text", text: "We agreed on the following " },
{ type: "text", marks: [{ type: "bold" }], text: "action items" },
{ type: "text", text: " for next sprint:" },
],
},
{
type: "bulletList",
content: [
{
type: "listItem",
content: [{ type: "paragraph", content: [{ type: "text", text: "Finalise the design handoff" }] }],
},
{
type: "listItem",
content: [{ type: "paragraph", content: [{ type: "text", text: "Write migration guide" }] }],
},
{
type: "listItem",
content: [
{
type: "paragraph",
content: [
{ type: "text", text: "Review " },
{
type: "text",
marks: [{ type: "link", attrs: { href: "https://example.com" } }],
text: "open PRs",
},
],
},
],
},
],
},
],
};
export default function Demo() {
return <RichTextRenderer content={content} />;
}