Skip to content
weftGitHub

MarkdownEditor

Write Markdown beside a live preview.

SourcePackage @weft-js/warp

Preview

tsx
import { MarkdownEditor } from '@weft-js/warp'export function Basic() {  return (    <MarkdownEditor label="README" defaultValue={README} />  )}const README = `# storefrontThe public shop, served from the **edge**.## Run it- \`npm install\`- \`npm run dev\`See [the deploy guide](https://weft.dev/docs) for more.`

Installation

npm install @weft-js/warp

Usage

tsx
import { MarkdownEditor } from '@weft-js/warp'<MarkdownEditor label="README" defaultValue={README} />

A short entry

Use rows to set how tall the editor is, here five lines.

tsx
import { MarkdownEditor } from '@weft-js/warp'export function Short() {  return (    <MarkdownEditor label="Changelog entry" rows={5} defaultValue={'**Fixed:** retries on timed out calls.'} hint="⌘B and ⌘I wrap the selection." />  )}

States

A Markdown editor can show a hint or an error, and can be disabled or readonly.

tsx
import { MarkdownEditor, Stack, Text } from '@weft-js/warp'export function States() {  return (    <Stack gap="group">      <Cell name="Empty"><MarkdownEditor label="Changelog entry" rows={3} /></Cell>      <Cell name="Filled"><MarkdownEditor label="Changelog entry" rows={3} defaultValue="**Fixed:** retries." /></Cell>      <Cell name="Hint"><MarkdownEditor label="Changelog entry" rows={3} hint="⌘B and ⌘I wrap the selection." /></Cell>      <Cell name="Invalid"><MarkdownEditor label="Changelog entry" rows={3} defaultValue="tbd" error="Say what changed." /></Cell>      <Cell name="Disabled"><MarkdownEditor label="Changelog entry" rows={3} defaultValue="**Fixed:** retries." disabled /></Cell>      <Cell name="Read-only"><MarkdownEditor label="Changelog entry" rows={3} defaultValue="**Fixed:** retries." readonly /></Cell>    </Stack>  )}const Cell = (p: { name: string; children?: unknown }) => (  <Stack gap="tight">    <Text role="caption" subtle>{p.name}</Text>    {p.children}  </Stack>)

When to use

Use it for

  • READMEs, changelogs, docs: people who like seeing the source

Reach for something else

Accessibility

⌘B
Wraps the selection in bold
⌘I
Wraps it in italics
⌘K
Wraps it in a link
←→
Moves between Write and Preview on the tabs

API Reference

PropTypeDefaultDescription
labelstring—The visible name, and what screen readers announce.
hintunknown—A short line of help under the field.
errorunknown—Replaces the hint and marks the field invalid.
iconIconRef—Leading icon: it sweeps with the border.
prefixunknown—Text or an element inside the field before the value, such as $.
suffixunknown—Text or an element inside the field after the value, such as kg.
variant"floating" | "classic"—floating (default, or the app's warp({ fields })) · classic: the label above.
appearance"line"—line: only a bottom line under the value, no box or fill. The boxed field otherwise.
size"sm" | "md" | "lg"'md'Control size. md by default.
clearablebooleanfalseA clear button (shown once there is a value).
counternumber—Maximum length, shown as a counter.
idstring—The element id. One is made for you if you leave it out.
disabledbooleanfalseCan't be focused or changed.
readonlybooleanfalseShows the value and lets it be selected and copied, but not changed.
valuestring | State<string>—The Markdown, or a State to bind.
defaultValuestring—The starting value, when the component owns the state.
rowsnumber12The height in lines.
EventTypeDefaultDescription
onInput((e: InputEvent & { currentTarget: HTMLInputElement & HTMLTextAreaElemen…—Called on each keystroke.
onValueChange((v: string, reason: ChangeReason) => void)—Called with each new value, and whether a pointer, a key or code made the change.

Parts

Every element carries a stable name, so you can style it from your own CSS: [data-scope="md-editor"] [data-part="tabs"]

tabssource

RelatedRich text editorMarkdownTextarea