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
└── 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.
API Reference
Props for MarkdownArea.
PropTypeDefaultDescription
valuestringControlled markdown value. Pair with `onValueChange`.
defaultValuestring""Uncontrolled initial markdown value.
onValueChange(value: string) => voidFires 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 / defaultTitlestringControlled / 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.
collapsedLinesnumberCollapse after N rows of text. Takes precedence over `collapsedHeight`.
collapsedHeightnumber160Collapsed height in px when `collapsible` and the content overflows.
disabledbooleanMakes the editor read-only.
aria-labelstring"Markdown editor"Accessibility label for the editor body.