draftly 0.1.0-alpha.0 → 1.0.0-alpha.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 +346 -0
- package/dist/chunk-2B3A3VSQ.cjs +3382 -0
- package/dist/chunk-2B3A3VSQ.cjs.map +1 -0
- package/dist/chunk-72ZYRGRT.cjs +399 -0
- package/dist/chunk-72ZYRGRT.cjs.map +1 -0
- package/dist/chunk-CG4M4TC7.js +392 -0
- package/dist/chunk-CG4M4TC7.js.map +1 -0
- package/dist/chunk-DFQYXFOP.js +86 -0
- package/dist/chunk-DFQYXFOP.js.map +1 -0
- package/dist/chunk-HPSMS2WB.js +182 -0
- package/dist/chunk-HPSMS2WB.js.map +1 -0
- package/dist/chunk-KBQDZ5IW.cjs +192 -0
- package/dist/chunk-KBQDZ5IW.cjs.map +1 -0
- package/dist/chunk-KDEDLC3D.cjs +93 -0
- package/dist/chunk-KDEDLC3D.cjs.map +1 -0
- package/dist/chunk-N3WL3XPB.js +3360 -0
- package/dist/chunk-N3WL3XPB.js.map +1 -0
- package/dist/draftly-BLnx3uGX.d.cts +293 -0
- package/dist/draftly-BLnx3uGX.d.ts +293 -0
- package/dist/editor/index.cjs +57 -0
- package/dist/editor/index.cjs.map +1 -0
- package/dist/editor/index.d.cts +15 -0
- package/dist/editor/index.d.ts +15 -0
- package/dist/editor/index.js +4 -0
- package/dist/editor/index.js.map +1 -0
- package/dist/index.cjs +120 -1129
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +9 -257
- package/dist/index.d.ts +9 -257
- package/dist/index.js +4 -1126
- package/dist/index.js.map +1 -1
- package/dist/plugins/index.cjs +66 -0
- package/dist/plugins/index.cjs.map +1 -0
- package/dist/plugins/index.d.cts +515 -0
- package/dist/plugins/index.d.ts +515 -0
- package/dist/plugins/index.js +5 -0
- package/dist/plugins/index.js.map +1 -0
- package/dist/preview/index.cjs +29 -0
- package/dist/preview/index.cjs.map +1 -0
- package/dist/preview/index.d.cts +143 -0
- package/dist/preview/index.d.ts +143 -0
- package/dist/preview/index.js +4 -0
- package/dist/preview/index.js.map +1 -0
- package/package.json +22 -1
- package/src/{draftly.ts → editor/draftly.ts} +28 -27
- package/src/editor/index.ts +5 -0
- package/src/{plugin.ts → editor/plugin.ts} +62 -34
- package/src/editor/theme.ts +62 -0
- package/src/editor/utils.ts +143 -0
- package/src/{view-plugin.ts → editor/view-plugin.ts} +25 -140
- package/src/index.ts +4 -7
- package/src/plugins/code-plugin.ts +1119 -0
- package/src/plugins/heading-plugin.ts +108 -74
- package/src/plugins/hr-plugin.ts +102 -0
- package/src/plugins/html-plugin.ts +59 -53
- package/src/plugins/image-plugin.ts +447 -0
- package/src/plugins/index.ts +57 -0
- package/src/plugins/inline-plugin.ts +178 -39
- package/src/plugins/link-plugin.ts +509 -0
- package/src/plugins/list-plugin.ts +492 -211
- package/src/plugins/math-plugin.ts +514 -0
- package/src/plugins/mermaid-plugin.ts +500 -0
- package/src/plugins/paragraph-plugin.ts +38 -0
- package/src/plugins/quote-plugin.ts +146 -0
- package/src/preview/context.ts +38 -0
- package/src/preview/css-generator.ts +51 -0
- package/src/preview/default-renderers.ts +29 -0
- package/src/preview/index.ts +20 -0
- package/src/preview/preview.ts +40 -0
- package/src/preview/renderer.ts +157 -0
- package/src/preview/types.ts +72 -0
- package/src/plugins/plugins.ts +0 -9
- package/src/theme.ts +0 -86
- package/src/utils.ts +0 -21
package/README.md
ADDED
|
@@ -0,0 +1,346 @@
|
|
|
1
|
+
<h1 align="center">Draftly</h1>
|
|
2
|
+
|
|
3
|
+
<p align="center">
|
|
4
|
+
<strong>A modern, extensible markdown editor and previewer for the web.</strong>
|
|
5
|
+
</p>
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
<a href="https://www.npmjs.com/package/draftly"><img src="https://img.shields.io/npm/v/draftly?style=flat-square&color=blue" alt="npm version" /></a>
|
|
9
|
+
<a href="https://www.npmjs.com/package/draftly"><img src="https://img.shields.io/npm/dm/draftly?style=flat-square" alt="npm downloads" /></a>
|
|
10
|
+
<a href="https://github.com/NeuroNexul/draftly/blob/main/LICENSE"><img src="https://img.shields.io/npm/l/draftly?style=flat-square" alt="license" /></a>
|
|
11
|
+
<a href="https://github.com/NeuroNexul/draftly"><img src="https://img.shields.io/github/stars/NeuroNexul/draftly?style=flat-square" alt="GitHub stars" /></a>
|
|
12
|
+
<img src="https://img.shields.io/badge/TypeScript-Ready-blue?style=flat-square&logo=typescript&logoColor=white" alt="TypeScript" />
|
|
13
|
+
<img src="https://img.shields.io/badge/CodeMirror-6-orange?style=flat-square" alt="CodeMirror 6" />
|
|
14
|
+
</p>
|
|
15
|
+
|
|
16
|
+
<p align="center">
|
|
17
|
+
<a href="#installation">Installation</a> •
|
|
18
|
+
<a href="#quick-start">Quick Start</a> •
|
|
19
|
+
<a href="#usage">Usage</a> •
|
|
20
|
+
<a href="#features">Features</a> •
|
|
21
|
+
<a href="#api-reference">API</a> •
|
|
22
|
+
<a href="#license">License</a>
|
|
23
|
+
</p>
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Overview
|
|
28
|
+
|
|
29
|
+
**Draftly** is a powerful, pluggable markdown editor and preview toolkit built on top of **CodeMirror 6**. It provides a seamless "rich text" editing experience while preserving standard markdown syntax. Draftly also includes a static HTML renderer that produces output visually identical to the editor, making it perfect for blogs, documentation sites, and content management systems.
|
|
30
|
+
|
|
31
|
+
### Why Draftly?
|
|
32
|
+
|
|
33
|
+
- 🚀 **Modern Architecture**: Built on CodeMirror 6 with incremental Lezer parsing.
|
|
34
|
+
- 🎨 **Rich Editing**: WYSIWYG-like experience with full markdown control.
|
|
35
|
+
- 🔌 **Extensible Plugin System**: Add custom rendering, keymaps, and syntax.
|
|
36
|
+
- 🖼️ **Static Preview**: Render markdown to semantic HTML with visual parity.
|
|
37
|
+
- 🌗 **Theming**: First-class support for light and dark modes.
|
|
38
|
+
- 📦 **Modular Exports**: Import only what you need (`draftly/editor`, `draftly/preview`, `draftly/plugins`).
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## Installation
|
|
43
|
+
|
|
44
|
+
Install the package via your preferred package manager:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
# npm
|
|
48
|
+
npm install draftly
|
|
49
|
+
|
|
50
|
+
# yarn
|
|
51
|
+
yarn add draftly
|
|
52
|
+
|
|
53
|
+
# pnpm
|
|
54
|
+
pnpm add draftly
|
|
55
|
+
|
|
56
|
+
# bun
|
|
57
|
+
bun add draftly
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Peer Dependencies
|
|
61
|
+
|
|
62
|
+
Draftly requires the following CodeMirror packages as peer dependencies. Make sure they are installed in your project:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
npm install @codemirror/commands @codemirror/lang-markdown @codemirror/language @codemirror/language-data @codemirror/state @codemirror/view
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## Quick Start
|
|
71
|
+
|
|
72
|
+
Get up and running in seconds.
|
|
73
|
+
|
|
74
|
+
```tsx
|
|
75
|
+
import { EditorView } from "@codemirror/view";
|
|
76
|
+
import { EditorState } from "@codemirror/state";
|
|
77
|
+
import { draftly } from "draftly";
|
|
78
|
+
|
|
79
|
+
const view = new EditorView({
|
|
80
|
+
state: EditorState.create({
|
|
81
|
+
doc: "# Hello, Draftly!",
|
|
82
|
+
extensions: [draftly()],
|
|
83
|
+
}),
|
|
84
|
+
parent: document.getElementById("editor")!,
|
|
85
|
+
});
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## Usage
|
|
91
|
+
|
|
92
|
+
Draftly is designed for flexibility. Use it as a CodeMirror extension for interactive editing or as a standalone renderer for static previews.
|
|
93
|
+
|
|
94
|
+
### Editor Integration
|
|
95
|
+
|
|
96
|
+
Here's a complete example using `@uiw/react-codemirror`:
|
|
97
|
+
|
|
98
|
+
```tsx
|
|
99
|
+
import CodeMirror from "@uiw/react-codemirror";
|
|
100
|
+
import { draftly, allPlugins, ThemeEnum } from "draftly";
|
|
101
|
+
import { githubDark } from "@uiw/codemirror-theme-github";
|
|
102
|
+
|
|
103
|
+
function MarkdownEditor() {
|
|
104
|
+
return (
|
|
105
|
+
<CodeMirror
|
|
106
|
+
value="# Welcome to Draftly\n\nStart writing..."
|
|
107
|
+
height="500px"
|
|
108
|
+
extensions={[
|
|
109
|
+
draftly({
|
|
110
|
+
theme: ThemeEnum.DARK,
|
|
111
|
+
themeStyle: githubDark,
|
|
112
|
+
plugins: allPlugins,
|
|
113
|
+
lineWrapping: true,
|
|
114
|
+
history: true,
|
|
115
|
+
indentWithTab: true,
|
|
116
|
+
onNodesChange: (nodes) => console.log("AST:", nodes),
|
|
117
|
+
}),
|
|
118
|
+
]}
|
|
119
|
+
/>
|
|
120
|
+
);
|
|
121
|
+
}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
#### Editor Configuration (`DraftlyConfig`)
|
|
125
|
+
|
|
126
|
+
| Option | Type | Default | Description |
|
|
127
|
+
| --------------------- | -------------------------------- | ---------------- | -------------------------------------------------------- |
|
|
128
|
+
| `theme` | `ThemeEnum` | `ThemeEnum.AUTO` | Theme mode: `LIGHT`, `DARK`, or `AUTO`. |
|
|
129
|
+
| `themeStyle` | `Extension` | `undefined` | CodeMirror theme extension (e.g., `githubDark`). |
|
|
130
|
+
| `plugins` | `DraftlyPlugin[]` | `[]` | Plugins to enable for rendering and parsing. |
|
|
131
|
+
| `baseStyles` | `boolean` | `true` | Load default base styles. |
|
|
132
|
+
| `disableViewPlugin` | `boolean` | `false` | Disable rich rendering (raw markdown mode). |
|
|
133
|
+
| `defaultKeybindings` | `boolean` | `true` | Enable default CodeMirror keybindings. |
|
|
134
|
+
| `history` | `boolean` | `true` | Enable undo/redo history. |
|
|
135
|
+
| `indentWithTab` | `boolean` | `true` | Use Tab for indentation. |
|
|
136
|
+
| `highlightActiveLine` | `boolean` | `true` | Highlight the current line (in raw mode). |
|
|
137
|
+
| `lineWrapping` | `boolean` | `true` | Enable line wrapping. |
|
|
138
|
+
| `onNodesChange` | `(nodes: DraftlyNode[]) => void` | `undefined` | Callback fired on every document update with parsed AST. |
|
|
139
|
+
| `markdown` | `MarkdownConfig[]` | `[]` | Additional Lezer markdown parser extensions. |
|
|
140
|
+
| `extensions` | `Extension[]` | `[]` | Additional CodeMirror extensions. |
|
|
141
|
+
| `keymap` | `KeyBinding[]` | `[]` | Additional keybindings. |
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
### Static Preview
|
|
146
|
+
|
|
147
|
+
Render markdown to semantic HTML for server-side rendering, static site generation, or read-only views.
|
|
148
|
+
|
|
149
|
+
```tsx
|
|
150
|
+
import { preview, generateCSS, allPlugins, ThemeEnum } from "draftly";
|
|
151
|
+
|
|
152
|
+
const markdown = `
|
|
153
|
+
# Hello World
|
|
154
|
+
|
|
155
|
+
This is a **bold** statement with some \`inline code\`.
|
|
156
|
+
|
|
157
|
+
- Item 1
|
|
158
|
+
- Item 2
|
|
159
|
+
- Item 3
|
|
160
|
+
`;
|
|
161
|
+
|
|
162
|
+
// Generate HTML
|
|
163
|
+
const html = preview(markdown, {
|
|
164
|
+
theme: ThemeEnum.LIGHT,
|
|
165
|
+
plugins: allPlugins,
|
|
166
|
+
sanitize: true,
|
|
167
|
+
wrapperClass: "prose",
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
// Generate matching CSS
|
|
171
|
+
const css = generateCSS({
|
|
172
|
+
theme: ThemeEnum.LIGHT,
|
|
173
|
+
plugins: allPlugins,
|
|
174
|
+
wrapperClass: "prose",
|
|
175
|
+
includeBase: true,
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
// Use in your app
|
|
179
|
+
function ArticlePreview() {
|
|
180
|
+
return (
|
|
181
|
+
<>
|
|
182
|
+
<style>{css}</style>
|
|
183
|
+
<article dangerouslySetInnerHTML={{ __html: html }} />
|
|
184
|
+
</>
|
|
185
|
+
);
|
|
186
|
+
}
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
#### Preview Configuration (`PreviewConfig`)
|
|
190
|
+
|
|
191
|
+
| Option | Type | Default | Description |
|
|
192
|
+
| -------------- | ------------------ | ------------------- | ------------------------------------- |
|
|
193
|
+
| `plugins` | `DraftlyPlugin[]` | `[]` | Plugins for rendering. |
|
|
194
|
+
| `theme` | `ThemeEnum` | `ThemeEnum.AUTO` | Theme mode. |
|
|
195
|
+
| `sanitize` | `boolean` | `true` | Sanitize HTML output (via DOMPurify). |
|
|
196
|
+
| `wrapperClass` | `string` | `"draftly-preview"` | CSS class for the wrapper element. |
|
|
197
|
+
| `wrapperTag` | `string` | `"article"` | HTML tag for the wrapper element. |
|
|
198
|
+
| `markdown` | `MarkdownConfig[]` | `[]` | Additional parser extensions. |
|
|
199
|
+
|
|
200
|
+
---
|
|
201
|
+
|
|
202
|
+
## Features
|
|
203
|
+
|
|
204
|
+
### 🎯 Rich Text Editing
|
|
205
|
+
|
|
206
|
+
Draftly's `ViewPlugin` decorates the editor to hide markdown syntax and render styled content inline. This provides a WYSIWYG-like experience while keeping the source as plain markdown.
|
|
207
|
+
|
|
208
|
+
- **Inline Formatting**: Bold, italic, strikethrough, and code are styled in-place.
|
|
209
|
+
- **Headings**: Rendered with proper sizes and weights.
|
|
210
|
+
- **Lists**: Ordered and unordered lists with custom bullets.
|
|
211
|
+
- **Images**: Displayed inline with alt text and captions.
|
|
212
|
+
- **Links**: Clickable with visual distinction.
|
|
213
|
+
- **Code Blocks**: Syntax highlighted with language detection.
|
|
214
|
+
|
|
215
|
+
### 🔌 Plugin Architecture
|
|
216
|
+
|
|
217
|
+
Every feature in Draftly is a plugin. Plugins can provide:
|
|
218
|
+
|
|
219
|
+
- **CodeMirror Extensions**: Custom decorations, widgets, and behaviors.
|
|
220
|
+
- **Markdown Parser Extensions**: Extend the Lezer parser for custom syntax.
|
|
221
|
+
- **Keymaps**: Add keyboard shortcuts.
|
|
222
|
+
- **Themes**: Inject custom styles based on the current theme.
|
|
223
|
+
- **Preview Renderers**: Define how elements are rendered to static HTML.
|
|
224
|
+
|
|
225
|
+
```typescript
|
|
226
|
+
import { DraftlyPlugin } from "draftly/editor";
|
|
227
|
+
|
|
228
|
+
class MyCustomPlugin extends DraftlyPlugin {
|
|
229
|
+
name = "my-custom-plugin";
|
|
230
|
+
|
|
231
|
+
onRegister(context) {
|
|
232
|
+
console.log("Plugin registered!", context.config);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
getExtensions() {
|
|
236
|
+
return [
|
|
237
|
+
/* CodeMirror extensions */
|
|
238
|
+
];
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
getKeymap() {
|
|
242
|
+
return [
|
|
243
|
+
/* KeyBinding[] */
|
|
244
|
+
];
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
getMarkdownConfig() {
|
|
248
|
+
return {
|
|
249
|
+
/* MarkdownConfig */
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
theme(mode) {
|
|
254
|
+
return {
|
|
255
|
+
/* Theme spec */
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
### 🌲 AST Access
|
|
262
|
+
|
|
263
|
+
Access the parsed document structure via the `onNodesChange` callback. Perfect for building:
|
|
264
|
+
|
|
265
|
+
- **Table of Contents**
|
|
266
|
+
- **Document Outlines**
|
|
267
|
+
- **Navigation Breadcrumbs**
|
|
268
|
+
- **Word/Line Counters**
|
|
269
|
+
|
|
270
|
+
```typescript
|
|
271
|
+
type DraftlyNode = {
|
|
272
|
+
from: number; // Start position
|
|
273
|
+
to: number; // End position
|
|
274
|
+
name: string; // Node type (e.g., "Heading", "Paragraph")
|
|
275
|
+
children: DraftlyNode[];
|
|
276
|
+
isSelected: boolean; // True if cursor is within this node
|
|
277
|
+
};
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
### 🌗 Theming
|
|
281
|
+
|
|
282
|
+
Draftly provides seamless theming with automatic light/dark mode support:
|
|
283
|
+
|
|
284
|
+
- **Auto Detection**: Follows system preference with `ThemeEnum.AUTO`.
|
|
285
|
+
- **Manual Control**: Force `ThemeEnum.LIGHT` or `ThemeEnum.DARK`.
|
|
286
|
+
- **Custom Themes**: Pass any CodeMirror theme via `themeStyle`.
|
|
287
|
+
- **Preview Parity**: CSS generation ensures preview matches editor styling.
|
|
288
|
+
|
|
289
|
+
### 📦 Modular Imports
|
|
290
|
+
|
|
291
|
+
Import only what you need to minimize bundle size:
|
|
292
|
+
|
|
293
|
+
```typescript
|
|
294
|
+
// Full package
|
|
295
|
+
import { draftly, preview, allPlugins } from "draftly";
|
|
296
|
+
|
|
297
|
+
// Editor only
|
|
298
|
+
import { draftly, DraftlyPlugin } from "draftly/editor";
|
|
299
|
+
|
|
300
|
+
// Preview only
|
|
301
|
+
import { preview, generateCSS } from "draftly/preview";
|
|
302
|
+
|
|
303
|
+
// Individual plugins
|
|
304
|
+
import { HeadingPlugin, ListPlugin } from "draftly/plugins";
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
---
|
|
308
|
+
|
|
309
|
+
## API Reference
|
|
310
|
+
|
|
311
|
+
### Exports
|
|
312
|
+
|
|
313
|
+
| Export | Path | Description |
|
|
314
|
+
| --------------- | ----------------- | ----------------------------------------------- |
|
|
315
|
+
| `draftly` | `draftly/editor` | Main editor extension factory. |
|
|
316
|
+
| `DraftlyPlugin` | `draftly/editor` | Base class for creating plugins. |
|
|
317
|
+
| `ThemeEnum` | `draftly/editor` | Enum for theme modes (`AUTO`, `LIGHT`, `DARK`). |
|
|
318
|
+
| `DraftlyNode` | `draftly/editor` | Type for AST nodes. |
|
|
319
|
+
| `preview` | `draftly/preview` | Function to render markdown to HTML. |
|
|
320
|
+
| `generateCSS` | `draftly/preview` | Function to generate CSS for preview styling. |
|
|
321
|
+
| `allPlugins` | `draftly/plugins` | Array of all built-in plugins. |
|
|
322
|
+
|
|
323
|
+
---
|
|
324
|
+
|
|
325
|
+
## Browser Support
|
|
326
|
+
|
|
327
|
+
Draftly supports all modern browsers:
|
|
328
|
+
|
|
329
|
+
| Browser | Version |
|
|
330
|
+
| ------- | ------- |
|
|
331
|
+
| Chrome | 88+ |
|
|
332
|
+
| Firefox | 78+ |
|
|
333
|
+
| Safari | 14+ |
|
|
334
|
+
| Edge | 88+ |
|
|
335
|
+
|
|
336
|
+
---
|
|
337
|
+
|
|
338
|
+
## Contributing
|
|
339
|
+
|
|
340
|
+
Contributions are welcome! Please read our [Contributing Guide](CONTRIBUTING.md) before submitting a pull request.
|
|
341
|
+
|
|
342
|
+
---
|
|
343
|
+
|
|
344
|
+
## License
|
|
345
|
+
|
|
346
|
+
[MIT](LICENSE) © [NeuroNexul](https://github.com/NeuroNexul)
|