Markdown Editor
Markdown textarea with formatting toolbar, edit/preview toggle, keyboard shortcuts, and optional character count.
Default
Toolbar formatting, preview toggle, and sample markdown.
default-example.tsx
1import { MarkdownEditor } from "@/registry/ui/markdown-editor";23const SAMPLE_MARKDOWN = `# Release notes45Ship faster with **bold claims** and _italic nuance_.67## Highlights89- Formatting toolbar inserts Markdown at the cursor10- Toggle **Preview** to render lists, headings, and code11- Keyboard shortcuts: \`⌘B\` / \`⌘I\`1213\`\`\`ts14const greeting = "Hello, Markdown";15console.log(greeting);16\`\`\`1718~~Deprecated API~~ - use the new endpoint instead.19`;2021export function MarkdownEditorDefaultExample() {22 return (23 <div className="mx-auto w-full max-w-2xl p-4">24 <MarkdownEditor defaultValue={SAMPLE_MARKDOWN} />25 </div>26 );27}
With limits
Placeholder, max length, and character count.
0 / 500
with-limits-example.tsx
1import { MarkdownEditor } from "@/registry/ui/markdown-editor";23export function MarkdownEditorWithLimitsExample() {4 return (5 <div className="mx-auto w-full max-w-2xl p-4">6 <MarkdownEditor7 placeholder="Describe your feature in Markdown…"8 maxLength={500}9 showCharacterCount10 />11 </div>12 );13}
Controlled
Parent owns value state for forms and persistence.
Parent state: 37 characters
controlled-example.tsx
1"use client";23import { useState } from "react";4import { MarkdownEditor } from "@/registry/ui/markdown-editor";56export function MarkdownEditorControlledExample() {7 const [value, setValue] = useState("**Controlled** value from the parent.");89 return (10 <div className="mx-auto flex w-full max-w-2xl flex-col gap-3 p-4">11 <MarkdownEditor value={value} onChange={setValue} />12 <p className="text-xs text-muted-foreground">13 Parent state: {value.length} characters14 </p>15 </div>16 );17}
Installation & source
Install via the shadcn CLI or copy the registry files manually.
bash
npx shadcn@latest add @tt-ui/markdown-editor
Props
| Name | Type | Default | Description |
|---|---|---|---|
| value | string | undefined | Controlled markdown string (pair with onChange). |
| defaultValue | string | "" | Initial value when uncontrolled. |
| onChange | (value: string) => void | undefined | Called when markdown content changes. |
| maxLength | number | undefined | Optional character limit. |
| showCharacterCount | boolean | false | Show character count footer. |
| defaultMode | "edit" | "preview" | "edit" | Initial edit or preview mode. |