@powerduck/md-editor 0.11.1 → 0.11.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +126 -267
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,17 +1,24 @@
|
|
|
1
1
|
# @powerduck/md-editor
|
|
2
2
|
|
|
3
|
-
High-performance embeddable Markdown editor with syntax highlighting, math formulas, mindmaps, @mentions, document link cards, and incremental rendering. Built on CodeMirror 6 with a React wrapper.
|
|
4
|
-
|
|
5
3
|
[](https://www.npmjs.com/package/@powerduck/md-editor)
|
|
6
4
|
[](https://github.com/PowerDuckie/md-editor/blob/main/LICENSE)
|
|
5
|
+
[](https://www.npmjs.com/package/@powerduck/md-editor)
|
|
7
6
|
|
|
8
|
-
|
|
7
|
+
High-performance embeddable Markdown editor with syntax highlighting, math formulas, mindmaps, @mentions, document link cards, and incremental rendering. Built on CodeMirror 6 with a React wrapper.
|
|
9
8
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
-
|
|
13
|
-
|
|
14
|
-
-
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
Powerduck is an open-source developer tooling platform for teams building modern API workflows.
|
|
12
|
+
|
|
13
|
+
- **CodeMirror 6 Core** — Incremental rendering, virtual scrolling, and 60fps editing for large documents
|
|
14
|
+
- **KaTeX Math** — Render LaTeX math formulas inline and in display blocks
|
|
15
|
+
- **Markmap Mindmaps** — Visualize markdown outlines as interactive mindmaps
|
|
16
|
+
- **highlight.js Code Blocks** — Syntax highlighting for 190+ programming languages
|
|
17
|
+
- **@mentions** — Type `@` to search and mention users with avatars and descriptions
|
|
18
|
+
- **Document Link Cards** — Type `/` to insert rich doc-link preview cards with thumbnails
|
|
19
|
+
- **Admonition Blocks** — `:::tip`, `:::warning`, `:::note`, and more
|
|
20
|
+
- **Simple & Complex Modes** — Lightweight mode for comments, full-featured mode for docs
|
|
21
|
+
- **Light & Dark Themes** — Built-in themes with CSS variable customization
|
|
15
22
|
|
|
16
23
|
---
|
|
17
24
|
|
|
@@ -27,7 +34,10 @@ npm install @powerduck/md-editor
|
|
|
27
34
|
|
|
28
35
|
```tsx
|
|
29
36
|
import { useRef, useState } from "react";
|
|
30
|
-
import {
|
|
37
|
+
import {
|
|
38
|
+
MarkdownEditorReact,
|
|
39
|
+
type MarkdownEditorHandle,
|
|
40
|
+
} from "@powerduck/md-editor/react";
|
|
31
41
|
import "@powerduck/md-editor/dist/style.css";
|
|
32
42
|
|
|
33
43
|
function App() {
|
|
@@ -64,21 +74,50 @@ const editor = new MarkdownEditor("#editor", {
|
|
|
64
74
|
onChange: (value) => console.log(value.length, "chars"),
|
|
65
75
|
});
|
|
66
76
|
|
|
67
|
-
// Read and write content
|
|
68
|
-
const markdown = editor.getValue();
|
|
69
|
-
editor.setValue("# Updated content");
|
|
70
|
-
|
|
71
|
-
// Render to HTML
|
|
72
77
|
const html = editor.getHtml();
|
|
73
78
|
```
|
|
74
79
|
|
|
75
|
-
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## Links
|
|
83
|
+
|
|
84
|
+
- [Official Website](https://www.powerduck.com/opensource/md-editor.html)
|
|
85
|
+
- [Documentation](https://www.powerduck.com/docs/md-editor/introduction)
|
|
86
|
+
- [Live Demo](https://www.powerduck.com/demo/md-editor)
|
|
87
|
+
- [GitHub](https://github.com/PowerDuckie/md-editor)
|
|
88
|
+
- [npm](https://www.npmjs.com/package/@powerduck/md-editor)
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## Features
|
|
93
|
+
|
|
94
|
+
- **CodeMirror 6 core** — incremental rendering, virtual scrolling, and 60fps editing for large documents
|
|
95
|
+
- **KaTeX math** — render LaTeX math formulas inline and in display blocks
|
|
96
|
+
- **Markmap mindmaps** — visualize markdown outlines as interactive mindmaps
|
|
97
|
+
- **highlight.js code blocks** — syntax highlighting for 190+ programming languages
|
|
98
|
+
- **@mentions** — type `@` to search and mention users with avatars and descriptions
|
|
99
|
+
- **Document link cards** — type `/` to insert rich doc-link preview cards with thumbnails
|
|
100
|
+
- **Admonition blocks** — `:::tip`, `:::warning`, `:::note`, and more
|
|
101
|
+
- **Simple & complex modes** — lightweight mode for comments, full-featured mode for docs
|
|
102
|
+
- **Light & dark themes** — built-in themes with CSS variable customization
|
|
103
|
+
- **Image upload hooks** — custom upload handlers with paste and drag-and-drop support
|
|
104
|
+
- **Toolbar & slash commands** — rich formatting toolbar and `/` command palette
|
|
105
|
+
- **Dual ESM/CJS builds** — works with `import` and `require`, with bundled TypeScript declarations
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## @mention Integration
|
|
76
110
|
|
|
77
111
|
```typescript
|
|
78
112
|
import { MarkdownEditor, type MentionItem } from "@powerduck/md-editor";
|
|
79
113
|
|
|
80
114
|
const USERS: MentionItem[] = [
|
|
81
|
-
{
|
|
115
|
+
{
|
|
116
|
+
id: "1",
|
|
117
|
+
label: "Alice",
|
|
118
|
+
avatar: "https://example.com/a.png",
|
|
119
|
+
description: "alice@example.com",
|
|
120
|
+
},
|
|
82
121
|
{ id: "2", label: "Bob", description: "bob@example.com" },
|
|
83
122
|
];
|
|
84
123
|
|
|
@@ -94,14 +133,21 @@ new MarkdownEditor("#editor", {
|
|
|
94
133
|
});
|
|
95
134
|
```
|
|
96
135
|
|
|
97
|
-
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
## Document Link Card
|
|
98
139
|
|
|
99
140
|
```typescript
|
|
100
141
|
import { MarkdownEditor, type DocItem } from "@powerduck/md-editor";
|
|
101
142
|
|
|
102
143
|
const DOCS: DocItem[] = [
|
|
103
|
-
{
|
|
104
|
-
|
|
144
|
+
{
|
|
145
|
+
id: "1",
|
|
146
|
+
title: "Getting Started",
|
|
147
|
+
url: "https://docs.example.com/getting-started",
|
|
148
|
+
thumbnail: "https://example.com/thumb.jpg",
|
|
149
|
+
description: "Quick start tutorial",
|
|
150
|
+
},
|
|
105
151
|
];
|
|
106
152
|
|
|
107
153
|
new MarkdownEditor("#editor", {
|
|
@@ -109,288 +155,101 @@ new MarkdownEditor("#editor", {
|
|
|
109
155
|
docLink: {
|
|
110
156
|
onDocSearch: async (query) =>
|
|
111
157
|
DOCS.filter((d) => d.title.toLowerCase().includes(query.toLowerCase())),
|
|
112
|
-
|
|
113
|
-
const res = await fetch(`/api/og?url=${encodeURIComponent(url)}`);
|
|
114
|
-
return res.json();
|
|
115
|
-
},
|
|
116
|
-
insertStyle: "auto", // "auto" | "card" | "link"
|
|
158
|
+
insertStyle: "card",
|
|
117
159
|
minChars: 0,
|
|
118
|
-
maxItems:
|
|
160
|
+
maxItems: 6,
|
|
119
161
|
},
|
|
120
162
|
});
|
|
121
163
|
```
|
|
122
164
|
|
|
123
165
|
---
|
|
124
166
|
|
|
125
|
-
##
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
167
|
+
## API Reference
|
|
168
|
+
|
|
169
|
+
### React Props
|
|
170
|
+
|
|
171
|
+
| Prop | Type | Default | Description |
|
|
172
|
+
| ---------------- | ------------------------- | ----------- | --------------------------------------- |
|
|
173
|
+
| `value` | `string` | - | Markdown content (controlled) |
|
|
174
|
+
| `defaultValue` | `string` | - | Initial markdown content (uncontrolled) |
|
|
175
|
+
| `onChange` | `(value: string) => void` | - | Content change callback |
|
|
176
|
+
| `mode` | `"simple" \| "complex"` | `"complex"` | Editor mode |
|
|
177
|
+
| `theme` | `"light" \| "dark"` | `"light"` | Color theme |
|
|
178
|
+
| `math` | `boolean` | `true` | Enable KaTeX math rendering |
|
|
179
|
+
| `mindmap` | `boolean` | `true` | Enable Markmap mindmaps |
|
|
180
|
+
| `codeHighlight` | `boolean` | `true` | Enable highlight.js code blocks |
|
|
181
|
+
| `tips` | `boolean` | `true` | Enable admonition blocks |
|
|
182
|
+
| `preview` | `boolean` | `true` | Show preview pane |
|
|
183
|
+
| `autoPreview` | `boolean` | `true` | Auto-update preview |
|
|
184
|
+
| `renderDebounce` | `number` | `200` | Preview render debounce in ms |
|
|
185
|
+
| `mention` | `MentionConfig` | - | @mention configuration |
|
|
186
|
+
| `docLink` | `DocLinkConfig` | - | Document link card configuration |
|
|
187
|
+
|
|
188
|
+
### Imperative Handle (React)
|
|
146
189
|
|
|
147
190
|
```typescript
|
|
148
|
-
interface
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
tips?: boolean; // default: true
|
|
156
|
-
preview?: boolean; // default: true
|
|
157
|
-
onChange?: (value: string) => void;
|
|
158
|
-
toolbar?: ToolbarConfig;
|
|
159
|
-
onImageUpload?: (file: File) => Promise<string>;
|
|
160
|
-
mention?: MentionOptions;
|
|
161
|
-
docLink?: DocLinkOptions;
|
|
162
|
-
renderDebounce?: number | false; // adaptive by default
|
|
163
|
-
autoPreview?: boolean; // default: true
|
|
191
|
+
interface MarkdownEditorHandle {
|
|
192
|
+
getValue(): string;
|
|
193
|
+
setValue(value: string): void;
|
|
194
|
+
getHtml(): string;
|
|
195
|
+
focus(): void;
|
|
196
|
+
blur(): void;
|
|
197
|
+
clear(): void;
|
|
164
198
|
}
|
|
165
199
|
```
|
|
166
200
|
|
|
167
|
-
###
|
|
201
|
+
### MentionConfig
|
|
168
202
|
|
|
169
203
|
```typescript
|
|
170
|
-
interface
|
|
171
|
-
onMentionSearch
|
|
172
|
-
onMentionSelect?: (item: MentionItem) => string;
|
|
173
|
-
minChars?: number;
|
|
174
|
-
maxItems?: number;
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
interface MentionItem {
|
|
178
|
-
id: string;
|
|
179
|
-
label: string;
|
|
180
|
-
avatar?: string;
|
|
181
|
-
description?: string;
|
|
182
|
-
[key: string]: unknown;
|
|
204
|
+
interface MentionConfig {
|
|
205
|
+
onMentionSearch: (query: string) => MentionItem[] | Promise<MentionItem[]>;
|
|
206
|
+
onMentionSelect?: (item: MentionItem) => string;
|
|
207
|
+
minChars?: number;
|
|
208
|
+
maxItems?: number;
|
|
209
|
+
triggerChar?: string;
|
|
183
210
|
}
|
|
184
211
|
```
|
|
185
212
|
|
|
186
|
-
###
|
|
213
|
+
### DocLinkConfig
|
|
187
214
|
|
|
188
215
|
```typescript
|
|
189
|
-
interface
|
|
190
|
-
onDocSearch
|
|
216
|
+
interface DocLinkConfig {
|
|
217
|
+
onDocSearch: (query: string) => DocItem[] | Promise<DocItem[]>;
|
|
191
218
|
onFetchDocMeta?: (url: string) => Promise<DocMeta>;
|
|
192
|
-
insertStyle?: "card" | "link" | "auto";
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
interface DocItem {
|
|
199
|
-
id: string;
|
|
200
|
-
title: string;
|
|
201
|
-
url: string;
|
|
202
|
-
thumbnail?: string;
|
|
203
|
-
description?: string;
|
|
204
|
-
[key: string]: unknown;
|
|
219
|
+
insertStyle?: "card" | "link" | "auto";
|
|
220
|
+
minChars?: number;
|
|
221
|
+
maxItems?: number;
|
|
222
|
+
triggerChar?: string;
|
|
205
223
|
}
|
|
206
224
|
```
|
|
207
225
|
|
|
208
226
|
---
|
|
209
227
|
|
|
210
|
-
##
|
|
211
|
-
|
|
212
|
-
```typescript
|
|
213
|
-
interface MarkdownEditorProps extends Omit<MarkdownEditorOptions, "value" | "onChange"> {
|
|
214
|
-
value?: string; // controlled value
|
|
215
|
-
defaultValue?: string; // uncontrolled initial value (mount only)
|
|
216
|
-
onChange?: (value: string) => void;
|
|
217
|
-
className?: string;
|
|
218
|
-
style?: CSSProperties;
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
interface MarkdownEditorHandle {
|
|
222
|
-
getValue: () => string;
|
|
223
|
-
setValue: (value: string) => void;
|
|
224
|
-
getHtml: () => string;
|
|
225
|
-
focus: () => void;
|
|
226
|
-
setMode: (mode: "simple" | "complex") => void;
|
|
227
|
-
setTheme: (theme: "light" | "dark") => void;
|
|
228
|
-
renderNow: () => void;
|
|
229
|
-
}
|
|
230
|
-
```
|
|
231
|
-
|
|
232
|
-
> **Performance note:** Structural options (`mode`, `math`, `mindmap`, `preview`, `autoPreview`, `renderDebounce`) recreate the underlying instance when they change. `value`, `onChange`, and `theme` use lightweight sync paths and never recreate the instance, so controlled usage stays responsive on large documents.
|
|
233
|
-
|
|
234
|
-
---
|
|
235
|
-
|
|
236
|
-
## Toolbar Actions
|
|
237
|
-
|
|
238
|
-
22 built-in toolbar actions in default order:
|
|
239
|
-
|
|
240
|
-
`heading`, `bold`, `italic`, `link`, `image`, `video`, `youtube`, `quote`, `ul`, `ol`, `tasklist`, `mention`, `doclink`, `code`, `table`, `math`, `mindmap`, `hr`, `tips`, `preview`, `help`, `theme`
|
|
241
|
-
|
|
242
|
-
### Configure Toolbar
|
|
243
|
-
|
|
244
|
-
```typescript
|
|
245
|
-
// Array form: include-list (only these actions show, in this order)
|
|
246
|
-
new MarkdownEditor("#editor", {
|
|
247
|
-
mode: "complex",
|
|
248
|
-
toolbar: ["bold", "italic", "link", "code", "math"],
|
|
249
|
-
});
|
|
250
|
-
|
|
251
|
-
// Record form: per-item overrides (everything not listed stays visible)
|
|
252
|
-
new MarkdownEditor("#editor", {
|
|
253
|
-
mode: "complex",
|
|
254
|
-
toolbar: {
|
|
255
|
-
bold: { label: "Make bold" },
|
|
256
|
-
image: { show: false },
|
|
257
|
-
youtube: { show: false },
|
|
258
|
-
},
|
|
259
|
-
});
|
|
260
|
-
```
|
|
261
|
-
|
|
262
|
-
---
|
|
263
|
-
|
|
264
|
-
## Standalone Rendering
|
|
265
|
-
|
|
266
|
-
```typescript
|
|
267
|
-
import { renderMarkdown } from "@powerduck/md-editor";
|
|
268
|
-
import "@powerduck/md-editor/dist/style.css";
|
|
269
|
-
|
|
270
|
-
const html = renderMarkdown("# Hello\n\n$E=mc^2$", { math: true });
|
|
271
|
-
document.getElementById("output")!.innerHTML = html;
|
|
272
|
-
```
|
|
273
|
-
|
|
274
|
-
> `renderMarkdown` returns a string and does not mount an editor. Mindmap placeholders are emitted as inert `<div>`s; call `Renderer.hydrate` yourself if you need live diagrams outside the editor.
|
|
275
|
-
|
|
276
|
-
---
|
|
277
|
-
|
|
278
|
-
## Public API (Vanilla JS)
|
|
228
|
+
## TypeScript Types
|
|
279
229
|
|
|
280
230
|
```typescript
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
setTheme(theme: "light" | "dark"): void;
|
|
291
|
-
focus(): void;
|
|
292
|
-
destroy(): void;
|
|
293
|
-
}
|
|
294
|
-
```
|
|
295
|
-
|
|
296
|
-
---
|
|
297
|
-
|
|
298
|
-
## Keyboard Shortcuts
|
|
299
|
-
|
|
300
|
-
| Shortcut | Action |
|
|
301
|
-
|---|---|
|
|
302
|
-
| `Ctrl/Cmd + B` | Bold |
|
|
303
|
-
| `Ctrl/Cmd + I` | Italic |
|
|
304
|
-
| `Ctrl/Cmd + K` | Link |
|
|
305
|
-
| `Ctrl/Cmd + S` | (custom via onChange) |
|
|
306
|
-
|
|
307
|
-
---
|
|
308
|
-
|
|
309
|
-
## Mindmap Syntax
|
|
310
|
-
|
|
311
|
-
````markdown
|
|
312
|
-
```mindmap
|
|
313
|
-
# Root topic
|
|
314
|
-
## Branch one
|
|
315
|
-
- Child A
|
|
316
|
-
- Child B
|
|
317
|
-
## Branch two
|
|
318
|
-
- Child C
|
|
319
|
-
```
|
|
320
|
-
````
|
|
321
|
-
|
|
322
|
-
Renders as an interactive markmap SVG diagram in the preview pane.
|
|
323
|
-
|
|
324
|
-
---
|
|
325
|
-
|
|
326
|
-
## Math Syntax
|
|
327
|
-
|
|
328
|
-
```markdown
|
|
329
|
-
Inline: $E = mc^2$
|
|
330
|
-
|
|
331
|
-
Block:
|
|
332
|
-
$$
|
|
333
|
-
\int_{a}^{b} f(x)\,dx
|
|
334
|
-
$$
|
|
335
|
-
```
|
|
336
|
-
|
|
337
|
-
Powered by KaTeX.
|
|
338
|
-
|
|
339
|
-
---
|
|
340
|
-
|
|
341
|
-
## Callout Syntax
|
|
342
|
-
|
|
343
|
-
```markdown
|
|
344
|
-
:::notice Title
|
|
345
|
-
Notice content.
|
|
346
|
-
:::
|
|
347
|
-
|
|
348
|
-
:::warning Warning
|
|
349
|
-
Warning content.
|
|
350
|
-
:::
|
|
351
|
-
|
|
352
|
-
:::danger Danger
|
|
353
|
-
Danger content.
|
|
354
|
-
:::
|
|
355
|
-
|
|
356
|
-
:::tip Tip
|
|
357
|
-
Tip content.
|
|
358
|
-
:::
|
|
359
|
-
```
|
|
360
|
-
|
|
361
|
-
Available types: `notice`, `info`, `tip`, `success`, `warning`, `danger`.
|
|
362
|
-
|
|
363
|
-
---
|
|
364
|
-
|
|
365
|
-
## Development
|
|
366
|
-
|
|
367
|
-
```bash
|
|
368
|
-
# Install dependencies
|
|
369
|
-
npm install
|
|
370
|
-
|
|
371
|
-
# Type check
|
|
372
|
-
npm run typecheck
|
|
373
|
-
|
|
374
|
-
# Build (ESM + CJS + type declarations + CSS)
|
|
375
|
-
npm run build
|
|
376
|
-
|
|
377
|
-
# Run tests
|
|
378
|
-
npm test
|
|
379
|
-
|
|
380
|
-
# Dev server
|
|
381
|
-
npm run dev
|
|
231
|
+
import type {
|
|
232
|
+
MentionItem,
|
|
233
|
+
DocItem,
|
|
234
|
+
DocMeta,
|
|
235
|
+
MentionConfig,
|
|
236
|
+
DocLinkConfig,
|
|
237
|
+
MarkdownEditorHandle,
|
|
238
|
+
MarkdownEditorProps,
|
|
239
|
+
} from "@powerduck/md-editor";
|
|
382
240
|
```
|
|
383
241
|
|
|
384
242
|
---
|
|
385
243
|
|
|
386
|
-
##
|
|
244
|
+
## Browser Support
|
|
387
245
|
|
|
388
|
-
-
|
|
389
|
-
-
|
|
390
|
-
-
|
|
246
|
+
- Chrome 90+
|
|
247
|
+
- Firefox 88+
|
|
248
|
+
- Safari 14+
|
|
249
|
+
- Edge 90+
|
|
391
250
|
|
|
392
251
|
---
|
|
393
252
|
|
|
394
253
|
## License
|
|
395
254
|
|
|
396
|
-
MIT
|
|
255
|
+
MIT © [POWERDUCK LIMITED](https://www.powerduck.com)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@powerduck/md-editor",
|
|
3
|
-
"version": "0.11.
|
|
3
|
+
"version": "0.11.2",
|
|
4
4
|
"description": "High-performance embeddable Markdown editor: KaTeX math, Markmap mindmaps, highlight.js code blocks with copy button, github-markdown-css preview, admonition blocks, rich toolbar with image/video/YouTube/table popups, keyboard shortcuts, configurable toolbar, image upload hook, standalone renderMarkdown API, React component, block-level incremental rendering. Simple and complex modes, light/dark themes.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.cjs",
|