Skip to content

prosekit/meowdown

Repository files navigation

@meowdown/react

React components for Meowdown, a hybrid (live-preview) Markdown editor.

Live demo

Quick start

Install the package and its peer dependencies:

npm install @meowdown/react @meowdown/core react react-dom

Import both stylesheets and render the editor:

import '@meowdown/core/style.css'
import '@meowdown/react/style.css'
import { MeowdownEditor } from '@meowdown/react'

export function App() {
  return <MeowdownEditor initialMarkdown="# Hello" />
}

Usage

import '@meowdown/core/style.css'
import '@meowdown/react/style.css'

import { MeowdownEditor, type EditorHandle } from '@meowdown/react'
import { useRef, useCallback } from 'react'

export function App() {
  const ref = useRef<EditorHandle>(null)
  const handleDocChange = useCallback(() => {
    console.log(ref.current?.getMarkdown())
  }, [])

  return (
    <MeowdownEditor
      handleRef={ref}
      mode="focus"
      initialMarkdown="# Hello"
      onDocChange={handleDocChange}
    />
  )
}

API

See the full API reference here.

Slash menu host items can include keywords to match hidden terms without changing the displayed label.

The caret glides between positions by default; pass caretGlide={false} to move it instantly (hosts can also tune the duration via the --meowdown-caret-glide CSS variable).

Wiki embeds

Obsidian-style wiki embeds (![[path]], with optional |width or |widthxheight) stay literal and editable unless the host classifies them. resolveWikiEmbed is a pure, creation-time resolver: return an image, file, or note result to reuse the corresponding Meowdown atom and its existing click hook; return undefined for missing or ambiguous targets.

<MeowdownEditor
  initialMarkdown="![[assets/photo.png|320]]"
  resolveWikiEmbed={({ target }) => (target.endsWith('.png') ? { kind: 'image' } : undefined)}
  resolveImageUrl={resolveLocalImageUrl}
  onImageClick={openLightbox}
/>

Use EditorHandle.revealHeading('#Section%20name') to move the selection to a matching heading and scroll it into view after following a heading link.

Both MeowdownEditor and the read-only MarkdownView accept resolveFileLink. Return true to render a standard [label](path) Markdown link with the same file pill, metadata resolver, and click hook used by wiki file embeds; return false to keep it as a normal link.

<MarkdownView
  markdown="[Quarterly report](docs/report.pdf)"
  resolveFileLink={({ href }) => href.startsWith('docs/')}
  resolveFileInfo={resolveLocalFileInfo}
  onFileClick={openLocalFile}
/>

Wiki-link hover cards

Mount WikilinkHoverCard inside MeowdownEditor and render host-owned preview content from the hovered wiki link's target. Returning null renders no card. The render function may also return a promise: the card stays closed until it resolves, resolving to null (or rejecting) renders no card, and a result that lands after the pointer moved on is discarded, so a host can look up local content without ever flashing an empty card.

<MeowdownEditor initialMarkdown="See [[Project plan]]">
  <WikilinkHoverCard>
    {async (hit) => {
      const note = await readLocalNote(hit.target)
      return note == null ? null : <LocalNotePreview note={note} />
    }}
  </WikilinkHoverCard>
</MeowdownEditor>

For local-only passive preview content, render Markdown with interaction disabled: the tree contains no anchors or focusable controls, and recognized tweet and YouTube embeds are omitted before any image resolver runs. Supply a resolver that accepts only trusted local image sources.

<MarkdownView markdown={markdown} interactive={false} resolveImageUrl={resolveLocalImageUrl} />

Mermaid code blocks

Fenced mermaid code blocks render as diagrams in both MeowdownEditor and MarkdownView. The editor shows only the preview while the caret is outside the block, then shows source and a live preview while editing it.

Rendering uses beautiful-mermaid, which currently supports Flowchart, State, Sequence, Class, ER, and XY Chart diagrams. Unsupported syntax renders an error instead of an empty preview. Override --meowdown-mermaid-bg, --meowdown-mermaid-fg, --meowdown-mermaid-line, --meowdown-mermaid-accent, --meowdown-mermaid-muted, --meowdown-mermaid-surface, --meowdown-mermaid-border, or --meowdown-mermaid-error to customize the diagram palette.

Styling

Import both stylesheets: @meowdown/core/style.css (the editor theme and variables) and @meowdown/react/style.css (the component layout). The core theme is documented in @meowdown/core.

License

MIT

About

Resources

License

Stars

8 stars

Watchers

1 watching

Forks

Sponsor this project

 

Packages

 
 
 

Contributors