@nightlybuildgroup/markdown-editor
v0.1.0
Published
A compact, GitHub-style markdown editor and renderer for React. Toggle toolbar, smart list continuation, write/preview tabs, Tailwind-styled.
Readme
@nightlybuildgroup/markdown-editor
A compact, GitHub style markdown editor and renderer for React.
- Toggle toolbar. Bold, italic, underline, strikethrough, inline code, link, quote, and ordered / unordered lists. Buttons toggle: apply again to remove the formatting instead of stacking it.
- Smart editing. Pressing Enter inside a list continues the list (or exits it on an empty item), GitHub style. Inline toggles are run aware, so toggling code never peels a backtick off a fenced block.
- Write / Preview tabs. Live preview rendered with
react-markdownplus GFM, sanitized HTML, and<u>support. - Form friendly. Optional hidden textarea so the value submits with native
FormData. - Pure, tested core. All cursor and selection logic lives in framework free functions with a full unit test suite.
Styling is Tailwind based and theme driven, so the editor inherits your app's colors and dark mode automatically.
Installation
pnpm add @nightlybuildgroup/markdown-editorreact and react-dom (v18 or v19) are peer dependencies. The markdown rendering stack (react-markdown, remark-gfm, remark-breaks, rehype-raw, rehype-sanitize) and clsx / tailwind-merge ship as dependencies.
Tailwind setup
The components are styled with utility classes that reference shadcn/ui style theme tokens. If your app already uses shadcn/ui, everything is in place. Otherwise, define these CSS variables (the editor reads them through Tailwind):
--background, --foreground, --card, --muted, --muted-foreground, --border, --input, --ring, --destructive.
The preview uses Tailwind Typography (prose), so install and enable the plugin:
pnpm add -D @tailwindcss/typographyMake sure the package is included in your Tailwind content scan so its classes are generated:
// tailwind.config (Tailwind v3) or @source (Tailwind v4)
content: ["./node_modules/@nightlybuildgroup/markdown-editor/dist/**/*.js"]Usage
"use client";
import { useState } from "react";
import { MarkdownEditor } from "@nightlybuildgroup/markdown-editor";
export function CommentBox() {
const [value, setValue] = useState("");
return (
<MarkdownEditor
value={value}
onChange={setValue}
placeholder="Leave a comment"
rows={3}
/>
);
}Rendering markdown on its own:
import { MarkdownContent } from "@nightlybuildgroup/markdown-editor";
<MarkdownContent>{post.body}</MarkdownContent>;MarkdownEditor props
| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| value | string | required | Current markdown source. |
| onChange | (v: string) => void | required | Called with the new value. Use a synchronous setter (useState); deferred schedulers can misplace the cursor after a toolbar action. |
| placeholder | string | | Textarea placeholder. |
| rows | number | 4 | Initial textarea rows. |
| disabled | boolean | false | Disable input and toolbar. |
| name | string | | When set, renders a hidden <textarea name> for native FormData submission and uses name as the field id. |
| autoFocus | boolean | false | Focus the textarea on mount. |
| toolbarPosition | "top" \| "bottom" | "bottom" | Where the tabs and toolbar sit. |
| onBlur | () => void | | Fires when the write textarea loses focus. |
| labels | Partial<MarkdownEditorLabels> | English | Override accessible labels and visible copy for localization (see below). |
Localization
All visible and accessible strings default to English and can be overridden:
<MarkdownEditor
value={value}
onChange={setValue}
labels={{
preview: "Vorschau",
edit: "Bearbeiten",
emptyPreview: "Nichts anzuzeigen.",
toolbar: { bold: "Fett", italic: "Kursiv", link: "Link" },
}}
/>Actions API
The toolbar logic is exported as pure functions if you want to build your own UI on top of it. Each takes the textarea value plus selectionStart / selectionEnd and returns { value, ss, se } (the new value and the selection to restore):
import {
toggleWrap,
insertLink,
toggleLinePrefix,
continueListOnEnter,
type ActionResult,
type LinePrefixKind,
} from "@nightlybuildgroup/markdown-editor";License
MIT
