AI Toolkit Demo
Runs in built-in demo mode - no API key required. Click a quick action below, or use the Ask AI toolbar button in the editor. Every suggestion is previewed before it commits.
Try every AI surface below
Pick a sample document, then click a quick action. Watch the editor react in real time.
Each sample exercises different AI behaviors. The editor updates immediately.
Launch-ready product update
RichTextEditor now supports in-editor AI actions that stay close to the document instead of opening a disconnected utility panel.
Use Ask AI to proofread, rewrite, justify an edit, add a paragraph, or open AI Chat for a multi-turn workflow. Suggestions stay reviewable before they are applied.
- Inline AI preview with accept and reject
- Docked AI Chat for multi-turn editing help
- AI Review drawer for pending, accepted, and rejected suggestions
What to try
Select the first paragraph and run Proofread, or open AI Chat and ask it to summarize the content and suggest a stronger heading.
Demo code
Everything between the BEGIN-DEMO-CODE / END-DEMO-CODE markers is the live code running on this page.
<link rel="stylesheet" href="/richtexteditor/rte_theme_default.css" />
<link rel="stylesheet" href="/richtexteditor/plugins/aitoolkit.css" />
<script type="text/javascript" src="/richtexteditor/rte-config.js"></script>
<script type="text/javascript" src="/richtexteditor/rte.js"></script>
<script type="text/javascript" src="/richtexteditor/plugins/all_plugins.js"></script>
<script type="text/javascript" src="/richtexteditor/plugins/aitoolkit.js"></script>
<!-- Dark launch panel -->
<div class="ai-demo-hero">
<div class="flex items-center justify-between gap-3 flex-wrap">
<div>
<span class="ai-demo-chip">Live · Demo resolver</span>
<h2 class="mt-2 text-[clamp(1.3rem,1.8vw,1.7rem)] font-extrabold">Try every AI surface below</h2>
<p class="mt-1 text-sm text-sky-100/80">Pick a sample document, then click a quick action. Watch the editor react in real time.</p>
</div>
<div class="ai-demo-status" id="ai-demo-status">
<span class="ai-demo-status__led" id="ai-demo-status-led"></span>
<span id="ai-demo-status-text">Ready</span>
<span class="ai-demo-status__meta" id="ai-demo-status-meta">0 actions</span>
</div>
</div>
<div class="ai-quickbar">
<button type="button" class="ai-quickbtn" onclick="aiDemo.openDialog(); return false;">
<span class="ai-quickbtn__icon">
<svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><path d="M12 2.5v2.6"/><rect x="5.5" y="7.1" width="13" height="10.7" rx="3.2"/><circle cx="10" cy="12" r="1"/><circle cx="14" cy="12" r="1"/></svg>
</span>
<span class="ai-quickbtn__label"><strong>Ask AI</strong><span>Open the dialog</span></span>
</button>
<button type="button" class="ai-quickbtn" onclick="aiDemo.proofread(); return false;">
<span class="ai-quickbtn__icon">
<svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><circle cx="10.5" cy="10.5" r="4.5"/><path d="M14 14l5 5"/><path d="M8.8 10.5l1.2 1.3 2.3-2.5"/></svg>
</span>
<span class="ai-quickbtn__label"><strong>Proofread</strong><span>First paragraph</span></span>
</button>
<button type="button" class="ai-quickbtn" onclick="aiDemo.rewrite(); return false;">
<span class="ai-quickbtn__icon">
<svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><path d="M4 7h11"/><path d="M4 12h8"/><path d="M4 17h11"/><path d="M16 5l4 4-6.5 6.5H9.5v-4z"/></svg>
</span>
<span class="ai-quickbtn__label"><strong>Rewrite</strong><span>Tighten selection</span></span>
</button>
<button type="button" class="ai-quickbtn" onclick="aiDemo.summarize(); return false;">
<span class="ai-quickbtn__icon">
<svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><path d="M5 7h14"/><path d="M5 11.5h10"/><path d="M5 16h7"/></svg>
</span>
<span class="ai-quickbtn__label"><strong>Summarize</strong><span>Whole document</span></span>
</button>
<button type="button" class="ai-quickbtn" onclick="aiDemo.chat(); return false;">
<span class="ai-quickbtn__icon">
<svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><path d="M12 3.2a3 3 0 013 3v.9h1.3a3.2 3.2 0 013.2 3.2v4.8a3.2 3.2 0 01-3.2 3.2H9.9l-3.8 2.8v-2.8H6a3.2 3.2 0 01-3.2-3.2v-4.8A3.2 3.2 0 016 7.1h1V6.2a3 3 0 013-3"/><circle cx="10" cy="12" r="1"/><circle cx="14" cy="12" r="1"/></svg>
</span>
<span class="ai-quickbtn__label"><strong>AI Chat</strong><span>Docked panel</span></span>
</button>
<button type="button" class="ai-quickbtn" onclick="aiDemo.review(); return false;">
<span class="ai-quickbtn__icon">
<svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><path d="M5.5 6.5h13"/><path d="M5.5 11.5h8"/><path d="M5.5 16.5h6"/><path d="M16.5 14.2l1.8 1.8 3.2-4.2"/></svg>
</span>
<span class="ai-quickbtn__label"><strong>Review queue</strong><span>Pending decisions</span></span>
</button>
</div>
</div>
<!-- Sample switcher -->
<div class="mt-5 rounded-[1.3rem] border border-slate-200 bg-white p-4 shadow-sm">
<div class="flex items-center justify-between gap-3 flex-wrap mb-3">
<div>
<div class="text-xs font-bold uppercase tracking-[0.14em] text-sky-700">Start from a sample</div>
<p class="mt-1 text-sm text-slate-600">Each sample exercises different AI behaviors. The editor updates immediately.</p>
</div>
<div class="text-xs text-slate-500">
Tip: select text first, then press <span class="ai-kbd">Ask AI</span> in the toolbar.
</div>
</div>
<div class="ai-sample-grid">
<button type="button" class="ai-sample" onclick="aiDemo.loadSample('release'); return false;">
<span class="ai-sample__kicker">Product</span>
<span class="ai-sample__title">Release note</span>
<span class="ai-sample__desc">Short paragraph ready for a proofread or rewrite pass.</span>
</button>
<button type="button" class="ai-sample" onclick="aiDemo.loadSample('messy'); return false;">
<span class="ai-sample__kicker">Editing</span>
<span class="ai-sample__title">Messy draft</span>
<span class="ai-sample__desc">Bad spacing, filler words, stray capitalization - great for proofread.</span>
</button>
<button type="button" class="ai-sample" onclick="aiDemo.loadSample('long'); return false;">
<span class="ai-sample__kicker">Length</span>
<span class="ai-sample__title">Long article</span>
<span class="ai-sample__desc">Multi-paragraph piece for summarize, shorten, or section-level chat.</span>
</button>
<button type="button" class="ai-sample" onclick="aiDemo.loadSample('translate'); return false;">
<span class="ai-sample__kicker">Language</span>
<span class="ai-sample__title">Translate me</span>
<span class="ai-sample__desc">A short paragraph you can pass through the translate flow.</span>
</button>
</div>
</div>
<div class="mt-5" id="div_ai_editor">
<h2>Launch-ready product update</h2>
<p>RichTextEditor now supports in-editor AI actions that stay close to the document instead of opening a disconnected utility panel.</p>
<p>Use Ask AI to proofread, rewrite, justify an edit, add a paragraph, or open AI Chat for a multi-turn workflow. Suggestions stay reviewable before they are applied.</p>
<ul>
<li>Inline AI preview with accept and reject</li>
<li>Docked AI Chat for multi-turn editing help</li>
<li>AI Review drawer for pending, accepted, and rejected suggestions</li>
</ul>
<h3>What to try</h3>
<p>Select the first paragraph and run <strong>Proofread</strong>, or open <strong>AI Chat</strong> and ask it to summarize the content and suggest a stronger heading.</p>
</div>
<script>
var aiEditorConfig = {
toolbar: "full",
height: "560px",
showFloatTextToolBar: true,
showFloatParagraph: true,
showStatistics: true,
aiToolkitPersistenceKey: "tailwind-ai-toolkit-demo"
};
var aiEditor = new RichTextEditor("#div_ai_editor", aiEditorConfig);
var aiDemoSamples = {
release: "<h2>Launch-ready product update</h2>" +
"<p>RichTextEditor now supports in-editor AI actions that stay close to the document instead of opening a disconnected utility panel.</p>" +
"<p>Use Ask AI to proofread, rewrite, justify an edit, add a paragraph, or open AI Chat for a multi-turn workflow. Suggestions stay reviewable before they are applied.</p>" +
"<ul><li>Inline AI preview with accept and reject</li><li>Docked AI Chat for multi-turn editing help</li><li>AI Review drawer for pending, accepted, and rejected suggestions</li></ul>",
messy: "<h2>draft: content update</h2>" +
"<p>hello world ,this is really very important and in order to ship it we just need to fix a few things .bad spacing is common here</p>" +
"<p>also , due to the fact that we are on a tight schedule,the team will just push harder this week</p>",
long: "<h2>Quarterly engineering update</h2>" +
"<p>This quarter, the editor team focused on three broad themes: AI integration, structured content, and accessibility. The goal was to keep the editor useful for long-form authoring while adding the AI primitives users expect in modern tools.</p>" +
"<p>On the AI front, we shipped Ask AI, a docked chat panel, and a persistent review drawer. Each surface uses the same structured operation contract, so a suggestion previewed in one place can be applied, rejected, or escalated elsewhere.</p>" +
"<p>For structured content, we extended the JSON bridge with better Markdown round-trips and a static HTML renderer for downstream consumers. Validation is now built into the default save path.</p>" +
"<p>Accessibility work included ARIA refinements across dialogs, better focus management when panels open, and an audit of keyboard shortcuts. We also added a prefers-reduced-motion path that disables the decorative transitions.</p>" +
"<p>Next quarter we will focus on offline persistence, richer collaborative review, and tighter integration with content-management backends.</p>",
translate: "<h2>About the product</h2>" +
"<p>RichTextEditor is a rich text editing component for web applications. It supports structured content, accessibility features, and an AI Toolkit for in-editor suggestions.</p>" +
"<p>Select this paragraph, click Ask AI, switch mode to Translate, and pick a target language to try the flow.</p>"
};
var aiDemoActionCount = 0;
var aiDemoStatusLed = document.getElementById("ai-demo-status-led");
var aiDemoStatusText = document.getElementById("ai-demo-status-text");
var aiDemoStatusMeta = document.getElementById("ai-demo-status-meta");
function setAiDemoStatus(text, state) {
aiDemoStatusText.textContent = text;
aiDemoStatusLed.className = "ai-demo-status__led" + (state ? " is-" + state : "");
}
function bumpAiDemoActions() {
aiDemoActionCount += 1;
aiDemoStatusMeta.textContent = aiDemoActionCount + " action" + (aiDemoActionCount === 1 ? "" : "s");
}
function getAiEditorSelectionDocument() {
if (aiEditor.getDocument) return aiEditor.getDocument();
if (aiEditor.getEditable && aiEditor.getEditable()) return aiEditor.getEditable().ownerDocument;
return document;
}
function selectAiIntroParagraph() {
var doc = getAiEditorSelectionDocument();
var firstParagraph = doc.querySelector("p");
if (!firstParagraph || !firstParagraph.firstChild) {
aiEditor.focus();
return false;
}
var selection = doc.getSelection ? doc.getSelection() : window.getSelection();
var range = doc.createRange();
range.setStart(firstParagraph.firstChild, 0);
range.setEnd(firstParagraph.firstChild, firstParagraph.textContent.length);
selection.removeAllRanges();
selection.addRange(range);
aiEditor.focus();
return true;
}
var aiDemo = {
openDialog: function () {
aiEditor.aiToolkit.openDialog({ presetMode: "rewrite", useDocument: false, autoRun: false });
setAiDemoStatus("Ask AI dialog open", "busy");
bumpAiDemoActions();
},
proofread: function () {
selectAiIntroParagraph();
aiEditor.aiToolkit.runQuickAction("proofread");
setAiDemoStatus("Proofread - first paragraph", "busy");
bumpAiDemoActions();
},
rewrite: function () {
selectAiIntroParagraph();
aiEditor.aiToolkit.runQuickAction("rewrite");
setAiDemoStatus("Rewrite - selection", "busy");
bumpAiDemoActions();
},
summarize: function () {
aiEditor.aiToolkit.runQuickAction("summarize");
setAiDemoStatus("Summarize - whole document", "busy");
bumpAiDemoActions();
},
chat: function () {
aiEditor.aiToolkit.openChatPanel({ focusComposer: true });
setAiDemoStatus("Chat panel open", "busy");
bumpAiDemoActions();
},
review: function () {
aiEditor.aiToolkit.openReviewPanel({ focusPanel: true });
setAiDemoStatus("Review panel open", "busy");
bumpAiDemoActions();
},
loadSample: function (name) {
if (!aiDemoSamples[name]) return;
aiEditor.setHTMLCode(aiDemoSamples[name]);
setAiDemoStatus("Loaded sample: " + name, "ok");
bumpAiDemoActions();
},
clearState: function () {
try { localStorage.removeItem("RTE.AIToolkit.tailwind-ai-toolkit-demo"); } catch (e) {}
if (aiEditor.aiToolkit && aiEditor.aiToolkit.clearSuggestions) {
aiEditor.aiToolkit.clearSuggestions();
}
setAiDemoStatus("Local state cleared", "ok");
}
};
</script>