@notectl/core 0.0.6 → 0.0.7

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.
Files changed (2) hide show
  1. package/README.md +246 -0
  2. package/package.json +24 -2
package/README.md ADDED
@@ -0,0 +1,246 @@
1
+ <div align="center">
2
+
3
+ # notectl
4
+
5
+ **A modern rich text editor, shipped as a single Web Component.**
6
+
7
+ Built on immutable state, a transaction-based architecture, and a plugin system that powers every feature — from bold text to full table editing.
8
+
9
+ [![TypeScript](https://img.shields.io/badge/TypeScript-strict-blue?logo=typescript&logoColor=white)](https://www.typescriptlang.org/)
10
+ [![Web Component](https://img.shields.io/badge/Web_Component-%3Cnotectl--editor%3E-purple)](https://developer.mozilla.org/en-US/docs/Web/API/Web_components)
11
+ [![License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
12
+ [![npm](https://img.shields.io/npm/v/@notectl/core)](https://www.npmjs.com/package/@notectl/core)
13
+
14
+ <br />
15
+
16
+ <img src="docs-site/src/assets/screenshots/hero-editor-rich.png" alt="notectl editor with rich content" width="720" />
17
+
18
+ </div>
19
+
20
+ <br />
21
+
22
+ ## Why notectl?
23
+
24
+ Most editors bolt formatting on top of `contenteditable` and hope for the best. notectl takes a different approach: every keystroke produces an immutable transaction, every feature is a plugin, and the DOM is a projection of state — never the source of truth.
25
+
26
+ - **Web Component** — drop `<notectl-editor>` into any framework or vanilla HTML
27
+ - **Plugin architecture** — every feature (bold, tables, lists, ...) is a plugin; add only what you need
28
+ - **Immutable state** — predictable updates, time-travel undo/redo, zero mutation bugs
29
+ - **Transaction system** — atomic, invertible steps with middleware support
30
+ - **Zero framework lock-in** — works with React, Vue, Svelte, Angular, or plain JS
31
+ - **Tiny dependency footprint** — single runtime dependency (DOMPurify)
32
+
33
+ <br />
34
+
35
+ ## Quick Start
36
+
37
+ ### Install
38
+
39
+ ```bash
40
+ npm install @notectl/core
41
+ ```
42
+
43
+ ### Use
44
+
45
+ ```ts
46
+ import {
47
+ createEditor,
48
+ TextFormattingPlugin,
49
+ HeadingPlugin,
50
+ ListPlugin,
51
+ LinkPlugin,
52
+ TablePlugin,
53
+ ToolbarPlugin,
54
+ } from '@notectl/core';
55
+
56
+ const editor = await createEditor({
57
+ toolbar: [
58
+ [new TextFormattingPlugin({ bold: true, italic: true, underline: true })],
59
+ [new HeadingPlugin()],
60
+ [new ListPlugin()],
61
+ [new LinkPlugin(), new TablePlugin()],
62
+ ],
63
+ placeholder: 'Start typing...',
64
+ autofocus: true,
65
+ });
66
+
67
+ document.body.appendChild(editor);
68
+ ```
69
+
70
+ That's it. A full-featured editor in 15 lines.
71
+
72
+ <br />
73
+
74
+ ## Plugins
75
+
76
+ Every capability is a plugin. Compose exactly the editor you need.
77
+
78
+ | Plugin | What it does |
79
+ |---|---|
80
+ | **TextFormattingPlugin** | Bold, italic, underline — individually toggleable |
81
+ | **StrikethroughPlugin** | ~~Strikethrough~~ text |
82
+ | **HeadingPlugin** | H1 – H6 headings |
83
+ | **BlockquotePlugin** | Block quotes |
84
+ | **ListPlugin** | Bullet and ordered lists |
85
+ | **LinkPlugin** | Hyperlink insertion and editing |
86
+ | **TablePlugin** | Full table support with row/column controls |
87
+ | **TextColorPlugin** | Text color picker |
88
+ | **TextAlignmentPlugin** | Left, center, right, justify |
89
+ | **FontPlugin** | Font family selection with custom font support |
90
+ | **FontSizePlugin** | Configurable font sizes |
91
+ | **HorizontalRulePlugin** | Horizontal dividers |
92
+ | **SuperSubPlugin** | Superscript and subscript |
93
+ | **HighlightPlugin** | Text highlighting / background color |
94
+ | **ToolbarPlugin** | Visual toolbar with grouped items |
95
+
96
+ ### Tables
97
+
98
+ Full table editing — add/remove rows and columns, navigate with Tab, resize, and select.
99
+
100
+ <div align="center">
101
+ <img src="docs-site/src/assets/screenshots/editor-table-showcase.png" alt="Table editing in notectl" width="720" />
102
+ </div>
103
+
104
+ <br />
105
+
106
+ ## Content API
107
+
108
+ Read and write content in multiple formats:
109
+
110
+ ```ts
111
+ // JSON (immutable Document)
112
+ const doc = editor.getJSON();
113
+ editor.setJSON(doc);
114
+
115
+ // HTML (sanitized via DOMPurify)
116
+ const html = editor.getHTML();
117
+ editor.setHTML('<p>Hello <strong>world</strong></p>');
118
+
119
+ // Plain text
120
+ const text = editor.getText();
121
+
122
+ // State
123
+ editor.isEmpty(); // true | false
124
+ ```
125
+
126
+ ## Command API
127
+
128
+ ```ts
129
+ editor.commands.toggleBold();
130
+ editor.commands.toggleItalic();
131
+ editor.commands.toggleUnderline();
132
+ editor.commands.undo();
133
+ editor.commands.redo();
134
+ editor.commands.selectAll();
135
+ ```
136
+
137
+ ## Events
138
+
139
+ ```ts
140
+ editor.on('stateChange', ({ oldState, newState, transaction }) => { /* ... */ });
141
+ editor.on('selectionChange', ({ selection }) => { /* ... */ });
142
+ editor.on('ready', () => { /* ... */ });
143
+ editor.on('focus', () => { /* ... */ });
144
+ editor.on('blur', () => { /* ... */ });
145
+ ```
146
+
147
+ <br />
148
+
149
+ ## Custom Fonts
150
+
151
+ Bring your own fonts — notectl handles `@font-face` injection automatically.
152
+
153
+ ```ts
154
+ import { FontPlugin, STARTER_FONTS } from '@notectl/core';
155
+
156
+ const Inter = {
157
+ name: 'Inter',
158
+ family: "'Inter', sans-serif",
159
+ category: 'sans-serif',
160
+ fontFaces: [
161
+ {
162
+ src: "url('/fonts/Inter-Variable.ttf') format('truetype')",
163
+ weight: '100 900',
164
+ style: 'normal',
165
+ },
166
+ ],
167
+ };
168
+
169
+ new FontPlugin({ fonts: [...STARTER_FONTS, Inter] });
170
+ ```
171
+
172
+ <br />
173
+
174
+ ## Toolbar Configuration
175
+
176
+ Group plugins into toolbar sections for a clean UI:
177
+
178
+ ```ts
179
+ const editor = await createEditor({
180
+ toolbar: [
181
+ [new FontPlugin(), new FontSizePlugin()],
182
+ [new TextFormattingPlugin(), new StrikethroughPlugin(), new TextColorPlugin()],
183
+ [new HeadingPlugin(), new BlockquotePlugin()],
184
+ [new TextAlignmentPlugin()],
185
+ [new ListPlugin()],
186
+ [new LinkPlugin(), new TablePlugin(), new HorizontalRulePlugin()],
187
+ ],
188
+ });
189
+ ```
190
+
191
+ Each inner array becomes a visually separated group in the toolbar.
192
+
193
+ <br />
194
+
195
+ ## Examples
196
+
197
+ Check out the full working example in [`examples/vanillajs`](examples/vanillajs) — it demonstrates every plugin, custom font loading, toolbar grouping, and the complete content API.
198
+
199
+ ```bash
200
+ git clone https://github.com/Samyssmile/notectl.git
201
+ cd notectl
202
+ pnpm install
203
+ pnpm dev
204
+ ```
205
+
206
+ <br />
207
+
208
+ ## Architecture
209
+
210
+ ```
211
+ Input Event → InputHandler / KeyboardHandler
212
+ → Transaction with atomic Steps
213
+ → Middleware chain (priority-ordered)
214
+ → EditorState.apply(tr) → new immutable EditorState
215
+ → Reconciler patches DOM (block-level diffing)
216
+ → Plugins notified via onStateChange()
217
+ ```
218
+
219
+ | Layer | Responsibility |
220
+ |---|---|
221
+ | `model/` | Immutable data — Document, BlockNode, TextNode, Mark, Selection |
222
+ | `state/` | EditorState, Transaction, StepApplication, History |
223
+ | `view/` | DOM rendering, Reconciler, SelectionSync |
224
+ | `input/` | Keyboard/input handling, paste, input rules |
225
+ | `commands/` | High-level operations (toggleMark, splitBlock, ...) |
226
+ | `plugins/` | All features — every capability is a plugin |
227
+ | `editor/` | `<notectl-editor>` Web Component public API |
228
+
229
+ <br />
230
+
231
+ ## Development
232
+
233
+ ```bash
234
+ pnpm install # install dependencies
235
+ pnpm build # build all packages
236
+ pnpm test # run unit tests (vitest + happy-dom)
237
+ pnpm test:e2e # run e2e tests (playwright)
238
+ pnpm lint # lint (biome)
239
+ pnpm typecheck # type check
240
+ ```
241
+
242
+ <br />
243
+
244
+ ## License
245
+
246
+ [MIT](LICENSE)
package/package.json CHANGED
@@ -1,6 +1,8 @@
1
1
  {
2
2
  "name": "@notectl/core",
3
- "version": "0.0.6",
3
+ "version": "0.0.7",
4
+ "description": "A modern rich text editor shipped as a single Web Component. Immutable state, transaction-based architecture, and a plugin system that powers every feature.",
5
+ "license": "MIT",
4
6
  "type": "module",
5
7
  "main": "./dist/notectl-core.js",
6
8
  "module": "./dist/notectl-core.mjs",
@@ -12,7 +14,27 @@
12
14
  "require": "./dist/notectl-core.js"
13
15
  }
14
16
  },
15
- "files": ["dist"],
17
+ "files": ["dist", "README.md"],
18
+ "keywords": [
19
+ "rich-text-editor",
20
+ "web-component",
21
+ "contenteditable",
22
+ "editor",
23
+ "wysiwyg",
24
+ "typescript",
25
+ "plugin-system",
26
+ "immutable-state",
27
+ "notectl"
28
+ ],
29
+ "repository": {
30
+ "type": "git",
31
+ "url": "https://github.com/Samyssmile/notectl.git",
32
+ "directory": "packages/core"
33
+ },
34
+ "homepage": "https://github.com/Samyssmile/notectl",
35
+ "bugs": {
36
+ "url": "https://github.com/Samyssmile/notectl/issues"
37
+ },
16
38
  "scripts": {
17
39
  "build": "vite build",
18
40
  "test": "vitest run",