Prodular UI

Rich text editor

AIPro

A Tiptap editor with headings, lists, quotes, code, links and tables, a toolbar, a slash menu, a selection menu, and AI editing that streams a rewrite as a diff before it replaces anything.

npx prodular-ui add rich-text-editor

Part of Prodular UI Pro. Preview and read the docs freely, install with a license. See pricing

Document

Toolbar formatting, a table with its own controls when the cursor is inside, and / for blocks.

AI editing

Select the first paragraph and press Ask AI. The rewrite streams in as a diff: Replace, Discard or Try again. On an empty line, / then Ask AI to write.

Compact

No toolbar for comments and replies. The selection menu and / still work.

Select text for formatting.

Anatomy

<RichTextEditor  value={html}  onChange={setHtml}  aria-label="Policy"  ai={{    onRun: async function* (request, signal) {      const res = await fetch("/api/edit", { method: "POST", body: JSON.stringify(request), signal })      const reader = res.body!.pipeThrough(new TextDecoderStream()).getReader()      for (;;) { const { value, done } = await reader.read(); if (done) return; yield value }    },  }}/>

Guidance

Use it when

  • Long form text people format: notes, descriptions, policies, emails, comments.
  • ai when the product has a model and people edit prose: rewrite, shorten, change tone, translate, or draft at the cursor.

Avoid

  • Short plain fields like a title or a name. Use Input.
  • Code. Use a code editor; the code block here is for snippets inside prose.

Rules for AI agents

Published in llms-full.txt, the registry and the MCP server, so coding agents follow them when they build with this component.

  • Store the HTML from onChange, and sanitize it on the server before rendering it anywhere else.
  • Give it aria-label describing the document (Month end notes, Reply).
  • For ai, implement onRun as an async generator that reads your model route's text stream and yields chunks. Pass the AbortSignal to fetch. With the AI SDK, return result.toTextStreamResponse() from the route.
  • Never apply AI output without the review step: the editor shows a diff and only changes the document on Replace or Insert.
  • Use toolbar={false} for comments and replies; keep the toolbar for documents.

API

RichTextEditor

PropTypeDefaultDescription
value / defaultValue / onChangestring (HTML)Controlled or uncontrolled content.
placeholderstring"Write, or press / for blocks"Shown in an empty document.
toolbarbooleantrueHide the toolbar for compact uses.
editablebooleantrueRead only when false.
minHeightnumber180Minimum height of the writing area in px.
ai.onRun(request, signal) => AsyncIterable<string> | Promise<string>request has action (improve, fix, shorter, longer, tone, translate, custom, write), option, prompt, text and context.
ai.tones / ai.languagesstring[]Choices under Change tone and Translate.

Installation

The Prodular UI CLI adds the source to components/ui with everything it depends on. In a project that already uses shadcn/ui, the shadcn CLI installs it from the Prodular registry too. See Installation for the first setup.

npx prodular-ui add rich-text-editor# or, with the registry in components.jsonnpx shadcn@latest add @prodular/rich-text-editor