Markdown area

A chrome-less writing surface whose formatting toolbar floats in only when text is selected.

Installation
$Terminal
npx shadcn@latest add https://sdk-components.thesqd.com/r/markdown-area.json
Usage
Import the master file and drop it in — the toolbar and invisible textarea are self-contained.
TSImport
import { MarkdownArea } from "@/components/ui/markdown-area";
TSExample
import { MarkdownArea } from "@/components/ui/markdown-area";

export function Example() {
  return (
    <MarkdownArea
      defaultValue={"## Hello\n\nWrite **markdown** here."}
      aria-label="Notes"
    />
  );
}
Composition
Anatomy of the MarkdownArea component.
MarkdownArea (props)
├── value? / defaultValue?: string        // controlled / uncontrolled markdown
├── onValueChange?: (value) => void
├── placeholder?: string
├── showTitle?: boolean                    // renders an InvisibleInput title above the toolbar
├── title? / defaultTitle?: string
├── onTitleChange?: (title) => void
├── titlePlaceholder?: string
├── actions?: MarkdownActionId[]           // allow-list, in order — any of:
│                                          //   "bold" | "italic" | "strike" | "code" | "codeBlock"
│                                          //   | "h1" | "h2" | "h3" | "link" | "bulletList"
│                                          //   | "orderedList" | "quote"
├── minHeight?: number                     // min body height in px
├── collapsible?: boolean                  // clamp when unfocused + "Show more"
├── collapsedLines?: number                // collapse after N rows of text
├── collapsedHeight?: number               // collapsed height in px (default 160)
├── disabled?: boolean                     // read-only
├── richBlocks?: boolean                   // page editor: doc blocks, tables, tasks, "/" menu
└── aria-label?: string

Anatomy
└── MarkdownArea                 // Tiptap editor, markdown in/out — no chrome
    ├── InvisibleInput          // optional title (when showTitle)
    ├── EditorContent           // live-rendered markdown body
    └── BubbleMenu > Toolbar    // floating formatting bar, shown on selection
Default
Type markdown and it renders live. Highlight any text and the shared Toolbar floats in above it to format the selection. No border, background, ring, or resize handle around the field.
With title
Pass `showTitle` to render an `InvisibleInput` heading above the body — it reads like a document title but edits inline.
All actions
Pass an `actions` allow-list to control which tools appear, in order. This one enables the full vocabulary: `bold`, `italic`, `strike`, `code`, `codeBlock`, `h1`, `h2`, `h3`, `link`, `bulletList`, `orderedList`, `quote`.
Collapsible
Pass `collapsible` to clamp the field to `collapsedHeight` while it isn't focused, with a bottom fade and a “Show more” button. Focusing expands it; blurring collapses it again — good for long descriptions in dense layouts.
Page editor
Pass `richBlocks` for documentation pages: type `/` to insert a callout, steps, tabs, an accordion, cards, a file tree, a table or a to-do list. Each block edits in a light frame with fields for its title or link, and saves as plain markdown (`:::steps`, `:::tab {title="npm"}`, ```` ```ts title="a.ts" ````) that `RichMarkdown variant="page"` renders.
API Reference
Props for MarkdownArea.
PropTypeDefaultDescription
valuestring—Controlled markdown value. Pair with `onValueChange`.
defaultValuestring""Uncontrolled initial markdown value.
onValueChange(value: string) => void—Fires with the full markdown string on every edit.
placeholderstring"Write in markdown…"Empty-state placeholder for the body.
showTitlebooleanfalseRenders an `InvisibleInput` title field above the toolbar.
title / defaultTitlestring—Controlled / uncontrolled title value (with `onTitleChange`).
titlePlaceholderstring"Untitled"Placeholder for the title field.
actionsArray<"bold" | "italic" | "strike" | "code" | "codeBlock" | "h1" | "h2" | "h3" | "link" | "bulletList" | "orderedList" | "quote">["bold","italic","h1","h2","h3","link","bulletList","orderedList","quote","code"]Allow-list of formatting tools shown in the floating toolbar, in order.
minHeightnumber120Minimum body height in px; the field grows with content.
collapsiblebooleanfalseClamp the field to `collapsedHeight` when unfocused and reveal a “Show more” control. Focus expands it; blur collapses it again.
collapsedLinesnumber—Collapse after N rows of text. Takes precedence over `collapsedHeight`.
collapsedHeightnumber160Collapsed height in px when `collapsible` and the content overflows.
disabledboolean—Makes the editor read-only.
richBlocksbooleanfalseA page editor: rich markdown (callouts, highlight, colour, buttons), documentation blocks (steps, tabs, accordions, cards, file trees), tables, task lists, and a `/` menu to insert any of them. What it writes is what `RichMarkdown variant="page"` draws. Read once, at mount.
aria-labelstring"Markdown editor"Accessibility label for the editor body.