@notectl/core 1.0.6 → 1.0.8
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 +78 -56
- package/custom-elements.json +344 -0
- package/dist/chunks/{AttrRegistry-DTsHyDVA.mjs → AttrRegistry-D-przlzb.mjs} +4 -4
- package/dist/chunks/{AttrRegistry-DTsHyDVA.mjs.map → AttrRegistry-D-przlzb.mjs.map} +1 -1
- package/dist/chunks/ColorNames-iaWsSZx1.mjs +35 -0
- package/dist/chunks/ColorNames-iaWsSZx1.mjs.map +1 -0
- package/dist/chunks/ColorValidation-Dyy4Bye8.mjs +140 -0
- package/dist/chunks/ColorValidation-Dyy4Bye8.mjs.map +1 -0
- package/dist/chunks/{Commands-DLP85Mp5.mjs → Commands-CSpSwGXv.mjs} +13 -13
- package/dist/chunks/{Commands-DLP85Mp5.mjs.map → Commands-CSpSwGXv.mjs.map} +1 -1
- package/dist/chunks/ToolbarKeyboardNav-B32OMv8r.mjs +46 -0
- package/dist/chunks/ToolbarKeyboardNav-B32OMv8r.mjs.map +1 -0
- package/dist/chunks/{ToolbarPlugin-sJTiZr-S.mjs → ToolbarPlugin-DY2xaJiu.mjs} +63 -93
- package/dist/chunks/ToolbarPlugin-DY2xaJiu.mjs.map +1 -0
- package/dist/chunks/index-BAk1EG1x.mjs +541 -0
- package/dist/chunks/index-BAk1EG1x.mjs.map +1 -0
- package/dist/chunks/index-BRYzYOYC.mjs +63 -0
- package/dist/chunks/index-BRYzYOYC.mjs.map +1 -0
- package/dist/chunks/index-BSFLNveF.mjs +953 -0
- package/dist/chunks/index-BSFLNveF.mjs.map +1 -0
- package/dist/chunks/index-BYgspns5.mjs +209 -0
- package/dist/chunks/index-BYgspns5.mjs.map +1 -0
- package/dist/chunks/index-B_3qDrUN.mjs +64 -0
- package/dist/chunks/index-B_3qDrUN.mjs.map +1 -0
- package/dist/chunks/index-Bsp4LC5t.mjs +130 -0
- package/dist/chunks/index-Bsp4LC5t.mjs.map +1 -0
- package/dist/chunks/index-C-YWHOcC.mjs +100 -0
- package/dist/chunks/index-C-YWHOcC.mjs.map +1 -0
- package/dist/chunks/index-C2GQoHot.mjs +92 -0
- package/dist/chunks/index-C2GQoHot.mjs.map +1 -0
- package/dist/chunks/index-CT3HGdQt.mjs +39 -0
- package/dist/chunks/index-CT3HGdQt.mjs.map +1 -0
- package/dist/chunks/index-Ct0ivLhO.mjs +407 -0
- package/dist/chunks/index-Ct0ivLhO.mjs.map +1 -0
- package/dist/chunks/index-CxiWyUho.mjs +191 -0
- package/dist/chunks/index-CxiWyUho.mjs.map +1 -0
- package/dist/chunks/index-D3CQWJiw.mjs +200 -0
- package/dist/chunks/index-D3CQWJiw.mjs.map +1 -0
- package/dist/chunks/index-DC1EK22F.mjs +41 -0
- package/dist/chunks/index-DC1EK22F.mjs.map +1 -0
- package/dist/chunks/index-Dh76rR13.mjs +196 -0
- package/dist/chunks/index-Dh76rR13.mjs.map +1 -0
- package/dist/chunks/index-o6hDR07y.mjs +41 -0
- package/dist/chunks/index-o6hDR07y.mjs.map +1 -0
- package/dist/chunks/index-uTnc9y7M.mjs +62 -0
- package/dist/chunks/index-uTnc9y7M.mjs.map +1 -0
- package/dist/chunks/resolvePluginLocale-B4w1OkPy.mjs +34 -0
- package/dist/chunks/resolvePluginLocale-B4w1OkPy.mjs.map +1 -0
- package/dist/editor/NotectlEditor.d.ts +10 -0
- package/dist/editor/NotectlEditor.d.ts.map +1 -1
- package/dist/editor/PaperLayoutController.d.ts +27 -0
- package/dist/editor/PaperLayoutController.d.ts.map +1 -0
- package/dist/editor/PaperSize.d.ts +35 -0
- package/dist/editor/PaperSize.d.ts.map +1 -0
- package/dist/editor/styles/color-picker.d.ts +1 -1
- package/dist/editor/styles/color-picker.d.ts.map +1 -1
- package/dist/editor/styles/paper.d.ts +3 -0
- package/dist/editor/styles/paper.d.ts.map +1 -0
- package/dist/editor/styles/table.d.ts +1 -1
- package/dist/editor/styles/table.d.ts.map +1 -1
- package/dist/editor/styles/toolbar.d.ts +1 -1
- package/dist/editor/styles/toolbar.d.ts.map +1 -1
- package/dist/editor/styles.d.ts.map +1 -1
- package/dist/i18n/Locale.d.ts +17 -0
- package/dist/i18n/Locale.d.ts.map +1 -0
- package/dist/i18n/LocaleService.d.ts +8 -0
- package/dist/i18n/LocaleService.d.ts.map +1 -0
- package/dist/i18n/index.d.ts +4 -0
- package/dist/i18n/index.d.ts.map +1 -0
- package/dist/i18n/resolvePluginLocale.d.ts +3 -0
- package/dist/i18n/resolvePluginLocale.d.ts.map +1 -0
- package/dist/index.d.ts +42 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/input/ClipboardHandler.d.ts.map +1 -1
- package/dist/input/InputHandler.d.ts.map +1 -1
- package/dist/input/KeyboardHandler.d.ts.map +1 -1
- package/dist/input/PasteHandler.d.ts.map +1 -1
- package/dist/notectl-core.mjs +2126 -1952
- package/dist/notectl-core.mjs.map +1 -1
- package/dist/notectl-core.umd.js +2002 -1544
- package/dist/notectl-core.umd.js.map +1 -1
- package/dist/plugins/PluginManager.d.ts +5 -0
- package/dist/plugins/PluginManager.d.ts.map +1 -1
- package/dist/plugins/alignment/AlignmentLocale.d.ts +19 -0
- package/dist/plugins/alignment/AlignmentLocale.d.ts.map +1 -0
- package/dist/plugins/alignment/AlignmentPlugin.d.ts +4 -0
- package/dist/plugins/alignment/AlignmentPlugin.d.ts.map +1 -1
- package/dist/plugins/alignment.mjs +3 -89
- package/dist/plugins/alignment.mjs.map +1 -1
- package/dist/plugins/blockquote/BlockquoteLocale.d.ts +17 -0
- package/dist/plugins/blockquote/BlockquoteLocale.d.ts.map +1 -0
- package/dist/plugins/blockquote/BlockquotePlugin.d.ts +3 -0
- package/dist/plugins/blockquote/BlockquotePlugin.d.ts.map +1 -1
- package/dist/plugins/blockquote.mjs +2 -55
- package/dist/plugins/blockquote.mjs.map +1 -1
- package/dist/plugins/code-block/CodeBlockLocale.d.ts +17 -0
- package/dist/plugins/code-block/CodeBlockLocale.d.ts.map +1 -0
- package/dist/plugins/code-block/CodeBlockPlugin.d.ts +1 -0
- package/dist/plugins/code-block/CodeBlockPlugin.d.ts.map +1 -1
- package/dist/plugins/code-block/CodeBlockTypes.d.ts +2 -0
- package/dist/plugins/code-block/CodeBlockTypes.d.ts.map +1 -1
- package/dist/plugins/code-block.mjs +3 -3
- package/dist/plugins/font/FontLocale.d.ts +15 -0
- package/dist/plugins/font/FontLocale.d.ts.map +1 -0
- package/dist/plugins/font/FontPlugin.d.ts +3 -0
- package/dist/plugins/font/FontPlugin.d.ts.map +1 -1
- package/dist/plugins/font-size/FontSizeLocale.d.ts +17 -0
- package/dist/plugins/font-size/FontSizeLocale.d.ts.map +1 -0
- package/dist/plugins/font-size/FontSizePlugin.d.ts +3 -0
- package/dist/plugins/font-size/FontSizePlugin.d.ts.map +1 -1
- package/dist/plugins/font-size/FontSizePopup.d.ts +2 -0
- package/dist/plugins/font-size/FontSizePopup.d.ts.map +1 -1
- package/dist/plugins/font-size.mjs +2 -201
- package/dist/plugins/font-size.mjs.map +1 -1
- package/dist/plugins/font.mjs +2 -183
- package/dist/plugins/font.mjs.map +1 -1
- package/dist/plugins/hard-break.mjs +1 -1
- package/dist/plugins/heading/HeadingLocale.d.ts +26 -0
- package/dist/plugins/heading/HeadingLocale.d.ts.map +1 -0
- package/dist/plugins/heading/HeadingPlugin.d.ts +4 -0
- package/dist/plugins/heading/HeadingPlugin.d.ts.map +1 -1
- package/dist/plugins/heading.mjs +1 -184
- package/dist/plugins/heading.mjs.map +1 -1
- package/dist/plugins/highlight/HighlightLocale.d.ts +17 -0
- package/dist/plugins/highlight/HighlightLocale.d.ts.map +1 -0
- package/dist/plugins/highlight/HighlightPlugin.d.ts +3 -5
- package/dist/plugins/highlight/HighlightPlugin.d.ts.map +1 -1
- package/dist/plugins/highlight.mjs +2 -123
- package/dist/plugins/highlight.mjs.map +1 -1
- package/dist/plugins/horizontal-rule/HorizontalRuleLocale.d.ts +15 -0
- package/dist/plugins/horizontal-rule/HorizontalRuleLocale.d.ts.map +1 -0
- package/dist/plugins/horizontal-rule/HorizontalRulePlugin.d.ts +4 -0
- package/dist/plugins/horizontal-rule/HorizontalRulePlugin.d.ts.map +1 -1
- package/dist/plugins/horizontal-rule.mjs +2 -56
- package/dist/plugins/horizontal-rule.mjs.map +1 -1
- package/dist/plugins/image/ImageLocale.d.ts +25 -0
- package/dist/plugins/image/ImageLocale.d.ts.map +1 -0
- package/dist/plugins/image/ImagePlugin.d.ts +1 -0
- package/dist/plugins/image/ImagePlugin.d.ts.map +1 -1
- package/dist/plugins/image/ImageUpload.d.ts +3 -0
- package/dist/plugins/image/ImageUpload.d.ts.map +1 -1
- package/dist/plugins/image.mjs +4 -378
- package/dist/plugins/image.mjs.map +1 -1
- package/dist/plugins/link/LinkLocale.d.ts +23 -0
- package/dist/plugins/link/LinkLocale.d.ts.map +1 -0
- package/dist/plugins/link/LinkPlugin.d.ts +3 -0
- package/dist/plugins/link/LinkPlugin.d.ts.map +1 -1
- package/dist/plugins/link.mjs +2 -124
- package/dist/plugins/link.mjs.map +1 -1
- package/dist/plugins/list/ListLocale.d.ts +18 -0
- package/dist/plugins/list/ListLocale.d.ts.map +1 -0
- package/dist/plugins/list/ListPlugin.d.ts +4 -0
- package/dist/plugins/list/ListPlugin.d.ts.map +1 -1
- package/dist/plugins/list.mjs +2 -190
- package/dist/plugins/list.mjs.map +1 -1
- package/dist/plugins/print/PrintLocale.d.ts +16 -0
- package/dist/plugins/print/PrintLocale.d.ts.map +1 -0
- package/dist/plugins/print/PrintPlugin.d.ts +1 -0
- package/dist/plugins/print/PrintPlugin.d.ts.map +1 -1
- package/dist/plugins/print/PrintStyleCollector.d.ts +7 -0
- package/dist/plugins/print/PrintStyleCollector.d.ts.map +1 -1
- package/dist/plugins/print/PrintTypes.d.ts +5 -0
- package/dist/plugins/print/PrintTypes.d.ts.map +1 -1
- package/dist/plugins/shared/ColorMarkOperations.d.ts +28 -0
- package/dist/plugins/shared/ColorMarkOperations.d.ts.map +1 -0
- package/dist/plugins/shared/ColorNames.d.ts +22 -0
- package/dist/plugins/shared/ColorNames.d.ts.map +1 -0
- package/dist/plugins/shared/ColorPickerPopup.d.ts +31 -0
- package/dist/plugins/shared/ColorPickerPopup.d.ts.map +1 -0
- package/dist/plugins/shared/ColorValidation.d.ts +14 -0
- package/dist/plugins/shared/ColorValidation.d.ts.map +1 -0
- package/dist/plugins/strikethrough/StrikethroughLocale.d.ts +17 -0
- package/dist/plugins/strikethrough/StrikethroughLocale.d.ts.map +1 -0
- package/dist/plugins/strikethrough/StrikethroughPlugin.d.ts +3 -0
- package/dist/plugins/strikethrough/StrikethroughPlugin.d.ts.map +1 -1
- package/dist/plugins/strikethrough.mjs +2 -32
- package/dist/plugins/strikethrough.mjs.map +1 -1
- package/dist/plugins/super-sub/SuperSubLocale.d.ts +19 -0
- package/dist/plugins/super-sub/SuperSubLocale.d.ts.map +1 -0
- package/dist/plugins/super-sub/SuperSubPlugin.d.ts +3 -0
- package/dist/plugins/super-sub/SuperSubPlugin.d.ts.map +1 -1
- package/dist/plugins/super-sub.mjs +2 -78
- package/dist/plugins/super-sub.mjs.map +1 -1
- package/dist/plugins/table/TableBorderColor.d.ts +24 -0
- package/dist/plugins/table/TableBorderColor.d.ts.map +1 -0
- package/dist/plugins/table/TableCommands.d.ts +9 -8
- package/dist/plugins/table/TableCommands.d.ts.map +1 -1
- package/dist/plugins/table/TableContextMenu.d.ts +14 -0
- package/dist/plugins/table/TableContextMenu.d.ts.map +1 -0
- package/dist/plugins/table/TableControls.d.ts +3 -1
- package/dist/plugins/table/TableControls.d.ts.map +1 -1
- package/dist/plugins/table/TableControlsDOM.d.ts +13 -1
- package/dist/plugins/table/TableControlsDOM.d.ts.map +1 -1
- package/dist/plugins/table/TableLocale.d.ts +48 -0
- package/dist/plugins/table/TableLocale.d.ts.map +1 -0
- package/dist/plugins/table/TableNavigation.d.ts +2 -1
- package/dist/plugins/table/TableNavigation.d.ts.map +1 -1
- package/dist/plugins/table/TableNodeViews.d.ts +3 -1
- package/dist/plugins/table/TableNodeViews.d.ts.map +1 -1
- package/dist/plugins/table/TablePlugin.d.ts +7 -1
- package/dist/plugins/table/TablePlugin.d.ts.map +1 -1
- package/dist/plugins/table/index.d.ts +3 -0
- package/dist/plugins/table/index.d.ts.map +1 -1
- package/dist/plugins/table.mjs +18 -660
- package/dist/plugins/table.mjs.map +1 -1
- package/dist/plugins/text-color/TextColorLocale.d.ts +17 -0
- package/dist/plugins/text-color/TextColorLocale.d.ts.map +1 -0
- package/dist/plugins/text-color/TextColorPlugin.d.ts +3 -5
- package/dist/plugins/text-color/TextColorPlugin.d.ts.map +1 -1
- package/dist/plugins/text-color.mjs +2 -123
- package/dist/plugins/text-color.mjs.map +1 -1
- package/dist/plugins/text-formatting/TextFormattingLocale.d.ts +18 -0
- package/dist/plugins/text-formatting/TextFormattingLocale.d.ts.map +1 -0
- package/dist/plugins/text-formatting/TextFormattingPlugin.d.ts +4 -0
- package/dist/plugins/text-formatting/TextFormattingPlugin.d.ts.map +1 -1
- package/dist/plugins/text-formatting.mjs +2 -49
- package/dist/plugins/text-formatting.mjs.map +1 -1
- package/dist/plugins/toolbar/ToolbarLocale.d.ts +14 -0
- package/dist/plugins/toolbar/ToolbarLocale.d.ts.map +1 -0
- package/dist/plugins/toolbar/ToolbarPlugin.d.ts +1 -0
- package/dist/plugins/toolbar/ToolbarPlugin.d.ts.map +1 -1
- package/dist/plugins/toolbar.mjs +1 -1
- package/dist/state/EditorState.d.ts +4 -1
- package/dist/state/EditorState.d.ts.map +1 -1
- package/dist/view/EditorView.d.ts.map +1 -1
- package/package.json +3 -2
- package/dist/chunks/Plugin-B9OZ6Y4c.mjs +0 -15
- package/dist/chunks/Plugin-B9OZ6Y4c.mjs.map +0 -1
- package/dist/chunks/ToolbarPlugin-sJTiZr-S.mjs.map +0 -1
- package/dist/chunks/color-picker-Csf0wx5a.mjs +0 -5
- package/dist/chunks/color-picker-Csf0wx5a.mjs.map +0 -1
- package/dist/chunks/index-QvKiO9_4.mjs +0 -538
- package/dist/chunks/index-QvKiO9_4.mjs.map +0 -1
package/README.md
CHANGED
|
@@ -1,44 +1,35 @@
|
|
|
1
1
|
<div align="center">
|
|
2
2
|
|
|
3
|
+
<br />
|
|
4
|
+
|
|
3
5
|
# notectl
|
|
4
6
|
|
|
5
|
-
###
|
|
7
|
+
### Drop one tag. Get a full editor.
|
|
8
|
+
|
|
9
|
+
`<notectl-editor>` — the rich text editor that works everywhere.<br />
|
|
10
|
+
React, Vue, Angular, Svelte, or plain HTML. Zero config, full power.
|
|
6
11
|
|
|
7
|
-
|
|
8
|
-
Use what you need, nothing more.
|
|
12
|
+
<br />
|
|
9
13
|
|
|
10
14
|
[](https://www.typescriptlang.org/)
|
|
11
15
|
[](https://developer.mozilla.org/en-US/docs/Web/API/Web_components)
|
|
12
16
|
[](LICENSE)
|
|
13
17
|
[](https://www.npmjs.com/package/@notectl/core)
|
|
18
|
+
[](https://www.npmjs.com/package/@notectl/core)
|
|
14
19
|
|
|
15
20
|
<br />
|
|
16
21
|
|
|
17
|
-
<img src="
|
|
18
|
-
|
|
19
|
-
[Documentation](https://samyssmile.github.io/notectl/) • [Playground](https://samyssmile.github.io/notectl/playground/) • [npm](https://www.npmjs.com/package/@notectl/core)
|
|
20
|
-
|
|
21
|
-
</div>
|
|
22
|
+
<img src="e2e/demo.gif" alt="notectl editor demo" width="720" />
|
|
22
23
|
|
|
23
24
|
<br />
|
|
24
25
|
|
|
25
|
-
**Try
|
|
26
|
-
|
|
27
|
-
<br />
|
|
26
|
+
[**Try the Playground**](https://samyssmile.github.io/notectl/playground/) · [Documentation](https://samyssmile.github.io/notectl/) · [npm](https://www.npmjs.com/package/@notectl/core)
|
|
28
27
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
- **Web Component** — drop `<notectl-editor>` into React, Vue, Svelte, Angular, or plain HTML
|
|
32
|
-
- **Plugin architecture** — every feature is a plugin; add only what you need
|
|
33
|
-
- **Accessible by default** — full keyboard navigation, ARIA roles and labels, screen reader support
|
|
34
|
-
- **Immutable state** — predictable updates, time-travel undo/redo, zero mutation bugs
|
|
35
|
-
- **Native Angular integration** — available as [`@notectl/angular`](https://www.npmjs.com/package/@notectl/angular)
|
|
36
|
-
- **Lightweight** — bundle size of notectl core is 29kb
|
|
37
|
-
- **Single dependency** — only DOMPurify at runtime
|
|
28
|
+
</div>
|
|
38
29
|
|
|
39
30
|
<br />
|
|
40
31
|
|
|
41
|
-
##
|
|
32
|
+
## 30 seconds to a full editor
|
|
42
33
|
|
|
43
34
|
```bash
|
|
44
35
|
npm install @notectl/core
|
|
@@ -70,36 +61,63 @@ const editor = await createEditor({
|
|
|
70
61
|
document.body.appendChild(editor);
|
|
71
62
|
```
|
|
72
63
|
|
|
73
|
-
A
|
|
64
|
+
That's it. A production-ready editor in 16 lines. No build step required.
|
|
74
65
|
|
|
75
66
|
<br />
|
|
76
67
|
|
|
77
|
-
##
|
|
68
|
+
## Why teams choose notectl
|
|
69
|
+
|
|
70
|
+
<table>
|
|
71
|
+
<tr>
|
|
72
|
+
<td width="50%">
|
|
73
|
+
|
|
74
|
+
**Ship faster**
|
|
75
|
+
|
|
76
|
+
One `<notectl-editor>` tag works in every framework. No wrapper libraries, no adapter boilerplate, no version lock-in.
|
|
77
|
+
|
|
78
|
+
</td>
|
|
79
|
+
<td width="50%">
|
|
80
|
+
|
|
81
|
+
**Stay lean**
|
|
82
|
+
|
|
83
|
+
34 KB core. One runtime dependency (DOMPurify). Every feature is a plugin — bundle only what you use.
|
|
84
|
+
|
|
85
|
+
</td>
|
|
86
|
+
</tr>
|
|
87
|
+
<tr>
|
|
88
|
+
<td>
|
|
89
|
+
|
|
90
|
+
**Accessible out of the box**
|
|
91
|
+
|
|
92
|
+
Full keyboard navigation, ARIA roles, screen reader announcements, focus management, high-contrast themes. Not an afterthought — it's the foundation.
|
|
93
|
+
|
|
94
|
+
</td>
|
|
95
|
+
<td>
|
|
78
96
|
|
|
79
|
-
|
|
97
|
+
**Built for control**
|
|
80
98
|
|
|
81
|
-
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
99
|
+
Immutable state, step-based transactions, time-travel undo/redo. Every change is traceable, testable, and invertible.
|
|
100
|
+
|
|
101
|
+
</td>
|
|
102
|
+
</tr>
|
|
103
|
+
</table>
|
|
86
104
|
|
|
87
105
|
<br />
|
|
88
106
|
|
|
89
|
-
##
|
|
107
|
+
## Plugin ecosystem
|
|
90
108
|
|
|
91
|
-
Every capability is a plugin. Compose exactly the editor you need.
|
|
92
|
-
See the [plugin documentation](https://samyssmile.github.io/notectl/plugins/overview/) for configuration details and examples.
|
|
109
|
+
Every capability is a plugin. Compose exactly the editor you need — nothing more, nothing less.
|
|
93
110
|
|
|
94
|
-
| Plugin | What
|
|
111
|
+
| Plugin | What you get |
|
|
95
112
|
|---|---|
|
|
96
113
|
| **TextFormattingPlugin** | Bold, italic, underline |
|
|
97
114
|
| **StrikethroughPlugin** | ~~Strikethrough~~ text |
|
|
98
115
|
| **HeadingPlugin** | H1 – H6 headings |
|
|
99
116
|
| **BlockquotePlugin** | Block quotes |
|
|
100
|
-
| **ListPlugin** | Bullet and
|
|
117
|
+
| **ListPlugin** | Bullet, ordered, and checklists |
|
|
101
118
|
| **LinkPlugin** | Hyperlink insertion and editing |
|
|
102
119
|
| **TablePlugin** | Full table support with row/column controls |
|
|
120
|
+
| **CodeBlockPlugin** | Code blocks with syntax highlighting |
|
|
103
121
|
| **TextColorPlugin** | Text color picker |
|
|
104
122
|
| **HighlightPlugin** | Text highlighting / background color |
|
|
105
123
|
| **AlignmentPlugin** | Left, center, right, justify |
|
|
@@ -107,39 +125,39 @@ See the [plugin documentation](https://samyssmile.github.io/notectl/plugins/over
|
|
|
107
125
|
| **FontSizePlugin** | Configurable font sizes |
|
|
108
126
|
| **HorizontalRulePlugin** | Horizontal dividers |
|
|
109
127
|
| **SuperSubPlugin** | Superscript and subscript |
|
|
110
|
-
| **PrintPlugin** |
|
|
111
|
-
|
|
112
|
-
<br />
|
|
128
|
+
| **PrintPlugin** | Print editor content with configurable options |
|
|
113
129
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
See notectl in action with every plugin, custom fonts, and the complete API:
|
|
117
|
-
|
|
118
|
-
- [`examples/vanillajs`](examples/vanillajs) — Vanilla JavaScript
|
|
119
|
-
- [`examples/angular`](examples/angular) — Angular with `@notectl/angular`
|
|
120
|
-
|
|
121
|
-
```bash
|
|
122
|
-
git clone https://github.com/Samyssmile/notectl.git
|
|
123
|
-
cd notectl && pnpm install && pnpm dev
|
|
124
|
-
```
|
|
130
|
+
See the [plugin documentation](https://samyssmile.github.io/notectl/plugins/overview/) for configuration and examples.
|
|
125
131
|
|
|
126
132
|
<br />
|
|
127
133
|
|
|
128
134
|
## Content API
|
|
129
135
|
|
|
136
|
+
Read and write content in any format:
|
|
137
|
+
|
|
130
138
|
```ts
|
|
131
|
-
editor.getHTML(); //
|
|
132
|
-
editor.setHTML('<p>Hello <strong>world</strong></p>'); //
|
|
133
|
-
editor.getJSON(); //
|
|
134
|
-
editor.getText(); //
|
|
139
|
+
editor.getHTML(); // export as HTML
|
|
140
|
+
editor.setHTML('<p>Hello <strong>world</strong></p>'); // import HTML
|
|
141
|
+
editor.getJSON(); // structured JSON
|
|
142
|
+
editor.getText(); // plain text
|
|
135
143
|
editor.isEmpty(); // check if empty
|
|
136
144
|
```
|
|
137
145
|
|
|
138
146
|
<br />
|
|
139
147
|
|
|
140
|
-
##
|
|
148
|
+
## Works with your stack
|
|
141
149
|
|
|
142
|
-
|
|
150
|
+
| | Framework | How |
|
|
151
|
+
|---|---|---|
|
|
152
|
+
| **Any** | Vanilla JS, React, Vue, Svelte | `<notectl-editor>` Web Component |
|
|
153
|
+
| **Angular** | Angular 17+ | [`@notectl/angular`](https://www.npmjs.com/package/@notectl/angular) native integration |
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
git clone https://github.com/Samyssmile/notectl.git
|
|
157
|
+
cd notectl && pnpm install && pnpm dev
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
See [`examples/vanillajs`](examples/vanillajs) and [`examples/angular`](examples/angular) for full working demos.
|
|
143
161
|
|
|
144
162
|
<br />
|
|
145
163
|
|
|
@@ -155,6 +173,10 @@ pnpm lint # lint
|
|
|
155
173
|
|
|
156
174
|
<br />
|
|
157
175
|
|
|
158
|
-
|
|
176
|
+
<div align="center">
|
|
177
|
+
|
|
178
|
+
**[Get started](https://samyssmile.github.io/notectl/)** · **[Open the playground](https://samyssmile.github.io/notectl/playground/)** · **[View on npm](https://www.npmjs.com/package/@notectl/core)**
|
|
159
179
|
|
|
160
|
-
|
|
180
|
+
MIT License
|
|
181
|
+
|
|
182
|
+
</div>
|
|
@@ -0,0 +1,344 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": "1.0.0",
|
|
3
|
+
"readme": "",
|
|
4
|
+
"modules": [
|
|
5
|
+
{
|
|
6
|
+
"kind": "javascript-module",
|
|
7
|
+
"path": "dist/notectl-core.mjs",
|
|
8
|
+
"declarations": [
|
|
9
|
+
{
|
|
10
|
+
"kind": "class",
|
|
11
|
+
"name": "NotectlEditor",
|
|
12
|
+
"superclass": {
|
|
13
|
+
"name": "HTMLElement"
|
|
14
|
+
},
|
|
15
|
+
"tagName": "notectl-editor",
|
|
16
|
+
"description": "A modern, accessible rich text editor shipped as a single Web Component. Features immutable state, transaction-based architecture, and a plugin system that powers every feature.",
|
|
17
|
+
"members": [
|
|
18
|
+
{
|
|
19
|
+
"kind": "field",
|
|
20
|
+
"name": "commands",
|
|
21
|
+
"type": {
|
|
22
|
+
"text": "{ toggleBold(): boolean | undefined; toggleItalic(): boolean | undefined; toggleUnderline(): boolean | undefined; undo(): void; redo(): void; selectAll(): void; }"
|
|
23
|
+
},
|
|
24
|
+
"description": "Convenience accessors for common formatting commands.",
|
|
25
|
+
"readonly": true
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"kind": "method",
|
|
29
|
+
"name": "getHTML",
|
|
30
|
+
"return": {
|
|
31
|
+
"type": {
|
|
32
|
+
"text": "string"
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
"description": "Returns sanitized HTML representation of the document."
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"kind": "method",
|
|
39
|
+
"name": "setHTML",
|
|
40
|
+
"return": {
|
|
41
|
+
"type": {
|
|
42
|
+
"text": "void"
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
"parameters": [
|
|
46
|
+
{
|
|
47
|
+
"name": "html",
|
|
48
|
+
"type": {
|
|
49
|
+
"text": "string"
|
|
50
|
+
},
|
|
51
|
+
"description": "HTML string to set as content."
|
|
52
|
+
}
|
|
53
|
+
],
|
|
54
|
+
"description": "Sets the editor content from an HTML string (sanitized via DOMPurify)."
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
"kind": "method",
|
|
58
|
+
"name": "getJSON",
|
|
59
|
+
"return": {
|
|
60
|
+
"type": {
|
|
61
|
+
"text": "Document"
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
"description": "Returns the document as an immutable JSON-serializable Document object."
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
"kind": "method",
|
|
68
|
+
"name": "setJSON",
|
|
69
|
+
"return": {
|
|
70
|
+
"type": {
|
|
71
|
+
"text": "void"
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
"parameters": [
|
|
75
|
+
{
|
|
76
|
+
"name": "doc",
|
|
77
|
+
"type": {
|
|
78
|
+
"text": "Document"
|
|
79
|
+
},
|
|
80
|
+
"description": "A Document object to set as editor content."
|
|
81
|
+
}
|
|
82
|
+
],
|
|
83
|
+
"description": "Replaces the editor content with the given Document object."
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
"kind": "method",
|
|
87
|
+
"name": "getText",
|
|
88
|
+
"return": {
|
|
89
|
+
"type": {
|
|
90
|
+
"text": "string"
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
"description": "Returns the plain text content of the editor."
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
"kind": "method",
|
|
97
|
+
"name": "isEmpty",
|
|
98
|
+
"return": {
|
|
99
|
+
"type": {
|
|
100
|
+
"text": "boolean"
|
|
101
|
+
}
|
|
102
|
+
},
|
|
103
|
+
"description": "Returns true if the editor contains only a single empty paragraph."
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
"kind": "method",
|
|
107
|
+
"name": "executeCommand",
|
|
108
|
+
"return": {
|
|
109
|
+
"type": {
|
|
110
|
+
"text": "boolean"
|
|
111
|
+
}
|
|
112
|
+
},
|
|
113
|
+
"parameters": [
|
|
114
|
+
{
|
|
115
|
+
"name": "name",
|
|
116
|
+
"type": {
|
|
117
|
+
"text": "string"
|
|
118
|
+
},
|
|
119
|
+
"description": "The name of a registered command."
|
|
120
|
+
}
|
|
121
|
+
],
|
|
122
|
+
"description": "Executes a named command registered by a plugin."
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
"kind": "method",
|
|
126
|
+
"name": "setTheme",
|
|
127
|
+
"return": {
|
|
128
|
+
"type": {
|
|
129
|
+
"text": "void"
|
|
130
|
+
}
|
|
131
|
+
},
|
|
132
|
+
"parameters": [
|
|
133
|
+
{
|
|
134
|
+
"name": "theme",
|
|
135
|
+
"type": {
|
|
136
|
+
"text": "ThemePreset | Theme"
|
|
137
|
+
},
|
|
138
|
+
"description": "A built-in preset ('light' | 'dark' | 'system') or a custom Theme object."
|
|
139
|
+
}
|
|
140
|
+
],
|
|
141
|
+
"description": "Changes the editor theme at runtime."
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
"kind": "method",
|
|
145
|
+
"name": "getTheme",
|
|
146
|
+
"return": {
|
|
147
|
+
"type": {
|
|
148
|
+
"text": "ThemePreset | Theme"
|
|
149
|
+
}
|
|
150
|
+
},
|
|
151
|
+
"description": "Returns the current theme setting."
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
"kind": "method",
|
|
155
|
+
"name": "destroy",
|
|
156
|
+
"return": {
|
|
157
|
+
"type": {
|
|
158
|
+
"text": "Promise<void>"
|
|
159
|
+
}
|
|
160
|
+
},
|
|
161
|
+
"description": "Tears down the editor, disconnects plugins, and cleans up DOM resources."
|
|
162
|
+
}
|
|
163
|
+
],
|
|
164
|
+
"attributes": [
|
|
165
|
+
{
|
|
166
|
+
"name": "placeholder",
|
|
167
|
+
"type": {
|
|
168
|
+
"text": "string"
|
|
169
|
+
},
|
|
170
|
+
"description": "Placeholder text shown when the editor is empty."
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
"name": "readonly",
|
|
174
|
+
"type": {
|
|
175
|
+
"text": "string"
|
|
176
|
+
},
|
|
177
|
+
"description": "When present, puts the editor into read-only mode."
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
"name": "theme",
|
|
181
|
+
"type": {
|
|
182
|
+
"text": "'light' | 'dark' | 'system'"
|
|
183
|
+
},
|
|
184
|
+
"description": "Sets the built-in theme preset. Defaults to 'light'."
|
|
185
|
+
}
|
|
186
|
+
],
|
|
187
|
+
"events": [
|
|
188
|
+
{
|
|
189
|
+
"name": "ready",
|
|
190
|
+
"type": {
|
|
191
|
+
"text": "CustomEvent<undefined>"
|
|
192
|
+
},
|
|
193
|
+
"description": "Fired when the editor has been fully initialized and is ready for interaction."
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
"name": "focus",
|
|
197
|
+
"type": {
|
|
198
|
+
"text": "CustomEvent<undefined>"
|
|
199
|
+
},
|
|
200
|
+
"description": "Fired when the editor content area receives focus."
|
|
201
|
+
},
|
|
202
|
+
{
|
|
203
|
+
"name": "blur",
|
|
204
|
+
"type": {
|
|
205
|
+
"text": "CustomEvent<undefined>"
|
|
206
|
+
},
|
|
207
|
+
"description": "Fired when the editor content area loses focus."
|
|
208
|
+
},
|
|
209
|
+
{
|
|
210
|
+
"name": "stateChange",
|
|
211
|
+
"type": {
|
|
212
|
+
"text": "CustomEvent<{ oldState: EditorState; newState: EditorState; transaction: Transaction }>"
|
|
213
|
+
},
|
|
214
|
+
"description": "Fired after every state transition, providing the old state, new state, and the applied transaction."
|
|
215
|
+
},
|
|
216
|
+
{
|
|
217
|
+
"name": "selectionChange",
|
|
218
|
+
"type": {
|
|
219
|
+
"text": "CustomEvent<{ selection: EditorSelection }>"
|
|
220
|
+
},
|
|
221
|
+
"description": "Fired when the cursor or selection changes."
|
|
222
|
+
}
|
|
223
|
+
],
|
|
224
|
+
"cssProperties": [
|
|
225
|
+
{
|
|
226
|
+
"name": "--notectl-bg",
|
|
227
|
+
"description": "Editor background color."
|
|
228
|
+
},
|
|
229
|
+
{
|
|
230
|
+
"name": "--notectl-fg",
|
|
231
|
+
"description": "Editor foreground (text) color."
|
|
232
|
+
},
|
|
233
|
+
{
|
|
234
|
+
"name": "--notectl-fg-muted",
|
|
235
|
+
"description": "Muted foreground color for secondary text."
|
|
236
|
+
},
|
|
237
|
+
{
|
|
238
|
+
"name": "--notectl-border",
|
|
239
|
+
"description": "Default border color."
|
|
240
|
+
},
|
|
241
|
+
{
|
|
242
|
+
"name": "--notectl-border-focus",
|
|
243
|
+
"description": "Border color when the editor is focused."
|
|
244
|
+
},
|
|
245
|
+
{
|
|
246
|
+
"name": "--notectl-primary",
|
|
247
|
+
"description": "Primary accent color (buttons, links)."
|
|
248
|
+
},
|
|
249
|
+
{
|
|
250
|
+
"name": "--notectl-primary-fg",
|
|
251
|
+
"description": "Foreground color on primary backgrounds."
|
|
252
|
+
},
|
|
253
|
+
{
|
|
254
|
+
"name": "--notectl-primary-muted",
|
|
255
|
+
"description": "Muted variant of the primary color."
|
|
256
|
+
},
|
|
257
|
+
{
|
|
258
|
+
"name": "--notectl-surface-raised",
|
|
259
|
+
"description": "Background for raised surfaces (toolbar, popups)."
|
|
260
|
+
},
|
|
261
|
+
{
|
|
262
|
+
"name": "--notectl-surface-overlay",
|
|
263
|
+
"description": "Background for overlay surfaces (modals, dropdowns)."
|
|
264
|
+
},
|
|
265
|
+
{
|
|
266
|
+
"name": "--notectl-hover-bg",
|
|
267
|
+
"description": "Background color on hover."
|
|
268
|
+
},
|
|
269
|
+
{
|
|
270
|
+
"name": "--notectl-active-bg",
|
|
271
|
+
"description": "Background color on active/pressed state."
|
|
272
|
+
},
|
|
273
|
+
{
|
|
274
|
+
"name": "--notectl-danger",
|
|
275
|
+
"description": "Danger/error accent color."
|
|
276
|
+
},
|
|
277
|
+
{
|
|
278
|
+
"name": "--notectl-danger-muted",
|
|
279
|
+
"description": "Muted variant of the danger color."
|
|
280
|
+
},
|
|
281
|
+
{
|
|
282
|
+
"name": "--notectl-success",
|
|
283
|
+
"description": "Success accent color."
|
|
284
|
+
},
|
|
285
|
+
{
|
|
286
|
+
"name": "--notectl-shadow",
|
|
287
|
+
"description": "Box shadow color for elevated surfaces."
|
|
288
|
+
},
|
|
289
|
+
{
|
|
290
|
+
"name": "--notectl-focus-ring",
|
|
291
|
+
"description": "Focus ring color for keyboard navigation."
|
|
292
|
+
}
|
|
293
|
+
]
|
|
294
|
+
},
|
|
295
|
+
{
|
|
296
|
+
"kind": "function",
|
|
297
|
+
"name": "createEditor",
|
|
298
|
+
"return": {
|
|
299
|
+
"type": {
|
|
300
|
+
"text": "Promise<NotectlEditor>"
|
|
301
|
+
}
|
|
302
|
+
},
|
|
303
|
+
"parameters": [
|
|
304
|
+
{
|
|
305
|
+
"name": "config",
|
|
306
|
+
"optional": true,
|
|
307
|
+
"type": {
|
|
308
|
+
"text": "NotectlEditorConfig"
|
|
309
|
+
},
|
|
310
|
+
"description": "Optional editor configuration (plugins, theme, placeholder, etc.)."
|
|
311
|
+
}
|
|
312
|
+
],
|
|
313
|
+
"description": "Factory function that creates and initializes a <notectl-editor> element."
|
|
314
|
+
}
|
|
315
|
+
],
|
|
316
|
+
"exports": [
|
|
317
|
+
{
|
|
318
|
+
"kind": "js",
|
|
319
|
+
"name": "NotectlEditor",
|
|
320
|
+
"declaration": {
|
|
321
|
+
"name": "NotectlEditor",
|
|
322
|
+
"module": "dist/notectl-core.mjs"
|
|
323
|
+
}
|
|
324
|
+
},
|
|
325
|
+
{
|
|
326
|
+
"kind": "js",
|
|
327
|
+
"name": "createEditor",
|
|
328
|
+
"declaration": {
|
|
329
|
+
"name": "createEditor",
|
|
330
|
+
"module": "dist/notectl-core.mjs"
|
|
331
|
+
}
|
|
332
|
+
},
|
|
333
|
+
{
|
|
334
|
+
"kind": "custom-element-definition",
|
|
335
|
+
"name": "notectl-editor",
|
|
336
|
+
"declaration": {
|
|
337
|
+
"name": "NotectlEditor",
|
|
338
|
+
"module": "dist/notectl-core.mjs"
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
]
|
|
342
|
+
}
|
|
343
|
+
]
|
|
344
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AttrRegistry-
|
|
1
|
+
{"version":3,"file":"AttrRegistry-D-przlzb.mjs","sources":["../../src/model/AttrRegistry.ts"],"sourcesContent":["/**\n * Module-augmentable attribute registries for type-safe node/mark attributes.\n *\n * Plugins extend these interfaces via `declare module`:\n * @example\n * declare module '../../model/AttrRegistry.js' {\n * interface NodeAttrRegistry {\n * heading: { level: HeadingLevel; align?: BlockAlignment };\n * }\n * }\n */\n\nimport type { BlockAlignment } from '../plugins/alignment/AlignmentPlugin.js';\nimport type { BlockNode, InlineNode, Mark } from './Document.js';\nimport { isInlineNode } from './Document.js';\n\n/** Plugins augment this interface to register typed node attributes. */\nexport interface NodeAttrRegistry {\n\tparagraph: { align?: BlockAlignment };\n}\n\n/** Plugins augment this interface to register typed mark attributes. */\nexport interface MarkAttrRegistry {\n\tbold: Record<string, never>;\n\titalic: Record<string, never>;\n\tunderline: Record<string, never>;\n}\n\n/** Resolves typed attributes for known node types, falls back for unknown. */\nexport type NodeAttrsFor<T extends string> = T extends keyof NodeAttrRegistry\n\t? NodeAttrRegistry[T]\n\t: Record<string, string | number | boolean>;\n\n/** Resolves typed attributes for known mark types, falls back for unknown. */\nexport type MarkAttrsFor<T extends string> = T extends keyof MarkAttrRegistry\n\t? MarkAttrRegistry[T]\n\t: Record<string, string | number | boolean>;\n\n/** Narrows a BlockNode to a typed variant with known attributes. */\nexport function isNodeOfType<T extends keyof NodeAttrRegistry>(\n\tnode: BlockNode,\n\ttype: T,\n): node is BlockNode & { readonly type: T; readonly attrs: NodeAttrRegistry[T] } {\n\treturn (node.type as string) === type;\n}\n\n/** Narrows a Mark to a typed variant with known attributes. */\nexport function isMarkOfType<T extends keyof MarkAttrRegistry>(\n\tmark: Mark,\n\ttype: T,\n): mark is Mark & { readonly type: T; readonly attrs: MarkAttrRegistry[T] } {\n\treturn (mark.type as string) === type;\n}\n\n// --- InlineNode Attribute Registry ---\n\n/** Plugins augment this interface to register typed inline node attributes. */\n// biome-ignore lint/suspicious/noEmptyInterface: module augmentation requires interface\nexport interface InlineNodeAttrRegistry {}\n\n/** Resolves typed attributes for known inline node types, falls back for unknown. */\nexport type InlineNodeAttrsFor<T extends string> = T extends keyof InlineNodeAttrRegistry\n\t? InlineNodeAttrRegistry[T]\n\t: Record<string, string | number | boolean>;\n\n/** Narrows an InlineNode to a typed variant with known attributes. */\nexport function isInlineNodeOfType<T extends keyof InlineNodeAttrRegistry>(\n\tnode: InlineNode,\n\tinlineNodeType: T,\n): node is InlineNode & {\n\treadonly inlineType: T;\n\treadonly attrs: InlineNodeAttrRegistry[T];\n} {\n\treturn isInlineNode(node) && (node.inlineType as string) === inlineNodeType;\n}\n"],"names":["isNodeOfType","node","type","isMarkOfType","mark","isInlineNodeOfType","inlineNodeType","isInlineNode","inlineType"],"mappings":";AAuCO,SAASA,EACfC,IACAC,IAAAA;AAEA,SAAQD,GAAKC,SAAoBA;AAClC;AAGO,SAASC,EACfC,IACAF,IAAAA;AAEA,SAAQE,GAAKF,SAAoBA;AAClC;AAcO,SAASG,EACfJ,IACAK,IAAAA;AAKA,SAAOC,EAAaN,EAAAA,KAAUA,GAAKO,eAA0BF;AAC9D;"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
const e = /* @__PURE__ */ new Map([["#000000", "Black"], ["#434343", "Dark Gray 4"], ["#666666", "Dark Gray 3"], ["#999999", "Dark Gray 2"], ["#b7b7b7", "Dark Gray 1"], ["#cccccc", "Light Gray 3"], ["#d9d9d9", "Light Gray 2"], ["#efefef", "Light Gray 1"], ["#f3f3f3", "Near White"], ["#ffffff", "White"], ["#980000", "Dark Red Berry"], ["#ff0000", "Red"], ["#ff9900", "Orange"], ["#ffff00", "Yellow"], ["#00ff00", "Green"], ["#00ffff", "Cyan"], ["#4a86e8", "Cornflower Blue"], ["#0000ff", "Blue"], ["#9900ff", "Purple"], ["#ff00ff", "Magenta"], ["#e6b8af", "Light Red Berry 3"], ["#f4cccc", "Light Red 3"], ["#fce5cd", "Light Orange 3"], ["#fff2cc", "Light Yellow 3"], ["#d9ead3", "Light Green 3"], ["#d0e0e3", "Light Cyan 3"], ["#c9daf8", "Light Cornflower Blue 3"], ["#cfe2f3", "Light Blue 3"], ["#d9d2e9", "Light Purple 3"], ["#ead1dc", "Light Magenta 3"], ["#dd7e6b", "Light Red Berry 2"], ["#ea9999", "Light Red 2"], ["#f9cb9c", "Light Orange 2"], ["#ffe599", "Light Yellow 2"], ["#b6d7a8", "Light Green 2"], ["#a2c4c9", "Light Cyan 2"], ["#a4c2f4", "Light Cornflower Blue 2"], ["#9fc5e8", "Light Blue 2"], ["#b4a7d6", "Light Purple 2"], ["#d5a6bd", "Light Magenta 2"], ["#cc4125", "Light Red Berry 1"], ["#e06666", "Light Red 1"], ["#f6b26b", "Light Orange 1"], ["#ffd966", "Light Yellow 1"], ["#93c47d", "Light Green 1"], ["#76a5af", "Light Cyan 1"], ["#6d9eeb", "Light Cornflower Blue 1"], ["#6fa8dc", "Light Blue 1"], ["#8e7cc3", "Light Purple 1"], ["#c27ba0", "Light Magenta 1"], ["#a61c00", "Dark Red Berry 1"], ["#cc0000", "Dark Red 1"], ["#e69138", "Dark Orange 1"], ["#f1c232", "Dark Yellow 1"], ["#6aa84f", "Dark Green 1"], ["#45818e", "Dark Cyan 1"], ["#3c78d8", "Dark Cornflower Blue 1"], ["#3d85c6", "Dark Blue 1"], ["#674ea7", "Dark Purple 1"], ["#a64d79", "Dark Magenta 1"], ["#85200c", "Dark Red Berry 2"], ["#990000", "Dark Red 2"], ["#b45f06", "Dark Orange 2"], ["#bf9000", "Dark Yellow 2"], ["#38761d", "Dark Green 2"], ["#134f5c", "Dark Cyan 2"], ["#1155cc", "Dark Cornflower Blue 2"], ["#0b5394", "Dark Blue 2"], ["#351c75", "Dark Purple 2"], ["#741b47", "Dark Magenta 2"], ["#fff176", "Bright Yellow"], ["#aed581", "Light Green"], ["#4dd0e1", "Bright Cyan"], ["#64b5f6", "Sky Blue"], ["#ce93d8", "Lavender"], ["#f48fb1", "Pink"], ["#ffab91", "Peach"], ["#ff8a65", "Coral"], ["#e6ee9c", "Lime"], ["#80cbc4", "Teal"], ["#fff9c4", "Pale Yellow"], ["#dcedc8", "Pale Green"], ["#e0f7fa", "Pale Cyan"], ["#e3f2fd", "Pale Blue"], ["#f3e5f5", "Pale Purple"], ["#fce4ec", "Pale Pink"], ["#fff3e0", "Pale Orange"], ["#fbe9e7", "Pale Red"], ["#f9fbe7", "Pale Lime"], ["#e0f2f1", "Pale Teal"], ["#fff59d", "Soft Yellow"], ["#c5e1a5", "Soft Green"], ["#80deea", "Soft Cyan"], ["#90caf9", "Soft Blue"], ["#e1bee7", "Soft Purple"], ["#f8bbd0", "Soft Pink"], ["#ffcc80", "Soft Orange"], ["#a5d6a7", "Mint"], ["#ffee58", "Vivid Yellow"], ["#9ccc65", "Vivid Green"], ["#26c6da", "Vivid Cyan"], ["#42a5f5", "Vivid Blue"], ["#ab47bc", "Vivid Purple"], ["#ec407a", "Vivid Pink"], ["#ffa726", "Vivid Orange"], ["#ff7043", "Red Orange"], ["#d4e157", "Vivid Lime"], ["#66bb6a", "Emerald"], ["#fafafa", "Almost White"], ["#f5f5f5", "Lightest Gray"], ["#eeeeee", "Very Light Gray"], ["#e0e0e0", "Silver"], ["#bdbdbd", "Medium Gray"], ["#e8eaf6", "Lavender Gray"], ["#efebe9", "Warm Gray"], ["#eceff1", "Cool Gray"]]);
|
|
2
|
+
function a(a2) {
|
|
3
|
+
return e.get(a2.toLowerCase()) || (function(e2) {
|
|
4
|
+
const a3 = f(e2), r2 = Number.parseInt(a3.slice(1, 3), 16) / 255, t2 = Number.parseInt(a3.slice(3, 5), 16) / 255, n = Number.parseInt(a3.slice(5, 7), 16) / 255, c = Math.max(r2, t2, n), l = Math.min(r2, t2, n), d = (c + l) / 2, g = c - l;
|
|
5
|
+
if (g < 0.05) return d < 0.15 ? "Black" : d < 0.35 ? "Dark Gray" : d < 0.65 ? "Gray" : d < 0.85 ? "Light Gray" : "Near White";
|
|
6
|
+
let o = 0;
|
|
7
|
+
o = c === r2 ? 60 * ((t2 - n) / g + (t2 < n ? 6 : 0)) : c === t2 ? 60 * ((n - r2) / g + 2) : 60 * ((r2 - t2) / g + 4);
|
|
8
|
+
let h = "Red";
|
|
9
|
+
for (const [e3, a4] of i) if (o < e3) {
|
|
10
|
+
h = a4;
|
|
11
|
+
break;
|
|
12
|
+
}
|
|
13
|
+
return d < 0.25 ? `Very Dark ${h}` : d < 0.4 ? `Dark ${h}` : d > 0.8 ? `Very Light ${h}` : d > 0.65 ? `Light ${h}` : h;
|
|
14
|
+
})(a2);
|
|
15
|
+
}
|
|
16
|
+
function r(e2) {
|
|
17
|
+
const a2 = (function(e3) {
|
|
18
|
+
const a3 = f(e3);
|
|
19
|
+
return 0.2126 * t(Number.parseInt(a3.slice(1, 3), 16) / 255) + 0.7152 * t(Number.parseInt(a3.slice(3, 5), 16) / 255) + 0.0722 * t(Number.parseInt(a3.slice(5, 7), 16) / 255);
|
|
20
|
+
})(e2);
|
|
21
|
+
return a2 > 0.3;
|
|
22
|
+
}
|
|
23
|
+
function f(e2) {
|
|
24
|
+
const a2 = e2.toLowerCase();
|
|
25
|
+
return 4 === a2.length ? `#${a2[1]}${a2[1]}${a2[2]}${a2[2]}${a2[3]}${a2[3]}` : a2;
|
|
26
|
+
}
|
|
27
|
+
function t(e2) {
|
|
28
|
+
return e2 <= 0.03928 ? e2 / 12.92 : ((e2 + 0.055) / 1.055) ** 2.4;
|
|
29
|
+
}
|
|
30
|
+
const i = [[15, "Red"], [45, "Orange"], [65, "Yellow"], [150, "Green"], [190, "Cyan"], [250, "Blue"], [290, "Purple"], [330, "Pink"], [361, "Red"]];
|
|
31
|
+
export {
|
|
32
|
+
a as g,
|
|
33
|
+
r as i
|
|
34
|
+
};
|
|
35
|
+
//# sourceMappingURL=ColorNames-iaWsSZx1.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ColorNames-iaWsSZx1.mjs","sources":["../../src/plugins/shared/ColorNames.ts"],"sourcesContent":["/**\n * Human-readable color name lookup for accessibility.\n *\n * Provides descriptive names for color swatches so screen readers\n * announce \"Red\" instead of \"#ff0000\". Covers all default palette\n * colors with a fallback algorithm for custom hex values.\n */\n\n// ---------------------------------------------------------------------------\n// Static name map — covers every default palette color\n// ---------------------------------------------------------------------------\n\nconst COLOR_NAME_MAP: ReadonlyMap<string, string> = new Map([\n\t// ── TextColor palette (70 colors) ──────────────────────────────────────\n\n\t// Row 1 — Grays\n\t['#000000', 'Black'],\n\t['#434343', 'Dark Gray 4'],\n\t['#666666', 'Dark Gray 3'],\n\t['#999999', 'Dark Gray 2'],\n\t['#b7b7b7', 'Dark Gray 1'],\n\t['#cccccc', 'Light Gray 3'],\n\t['#d9d9d9', 'Light Gray 2'],\n\t['#efefef', 'Light Gray 1'],\n\t['#f3f3f3', 'Near White'],\n\t['#ffffff', 'White'],\n\n\t// Row 2 — Vivid\n\t['#980000', 'Dark Red Berry'],\n\t['#ff0000', 'Red'],\n\t['#ff9900', 'Orange'],\n\t['#ffff00', 'Yellow'],\n\t['#00ff00', 'Green'],\n\t['#00ffff', 'Cyan'],\n\t['#4a86e8', 'Cornflower Blue'],\n\t['#0000ff', 'Blue'],\n\t['#9900ff', 'Purple'],\n\t['#ff00ff', 'Magenta'],\n\n\t// Row 3 — Light 3 (lightest tint)\n\t['#e6b8af', 'Light Red Berry 3'],\n\t['#f4cccc', 'Light Red 3'],\n\t['#fce5cd', 'Light Orange 3'],\n\t['#fff2cc', 'Light Yellow 3'],\n\t['#d9ead3', 'Light Green 3'],\n\t['#d0e0e3', 'Light Cyan 3'],\n\t['#c9daf8', 'Light Cornflower Blue 3'],\n\t['#cfe2f3', 'Light Blue 3'],\n\t['#d9d2e9', 'Light Purple 3'],\n\t['#ead1dc', 'Light Magenta 3'],\n\n\t// Row 4 — Light 2\n\t['#dd7e6b', 'Light Red Berry 2'],\n\t['#ea9999', 'Light Red 2'],\n\t['#f9cb9c', 'Light Orange 2'],\n\t['#ffe599', 'Light Yellow 2'],\n\t['#b6d7a8', 'Light Green 2'],\n\t['#a2c4c9', 'Light Cyan 2'],\n\t['#a4c2f4', 'Light Cornflower Blue 2'],\n\t['#9fc5e8', 'Light Blue 2'],\n\t['#b4a7d6', 'Light Purple 2'],\n\t['#d5a6bd', 'Light Magenta 2'],\n\n\t// Row 5 — Light 1\n\t['#cc4125', 'Light Red Berry 1'],\n\t['#e06666', 'Light Red 1'],\n\t['#f6b26b', 'Light Orange 1'],\n\t['#ffd966', 'Light Yellow 1'],\n\t['#93c47d', 'Light Green 1'],\n\t['#76a5af', 'Light Cyan 1'],\n\t['#6d9eeb', 'Light Cornflower Blue 1'],\n\t['#6fa8dc', 'Light Blue 1'],\n\t['#8e7cc3', 'Light Purple 1'],\n\t['#c27ba0', 'Light Magenta 1'],\n\n\t// Row 6 — Dark 1\n\t['#a61c00', 'Dark Red Berry 1'],\n\t['#cc0000', 'Dark Red 1'],\n\t['#e69138', 'Dark Orange 1'],\n\t['#f1c232', 'Dark Yellow 1'],\n\t['#6aa84f', 'Dark Green 1'],\n\t['#45818e', 'Dark Cyan 1'],\n\t['#3c78d8', 'Dark Cornflower Blue 1'],\n\t['#3d85c6', 'Dark Blue 1'],\n\t['#674ea7', 'Dark Purple 1'],\n\t['#a64d79', 'Dark Magenta 1'],\n\n\t// Row 7 — Dark 2\n\t['#85200c', 'Dark Red Berry 2'],\n\t['#990000', 'Dark Red 2'],\n\t['#b45f06', 'Dark Orange 2'],\n\t['#bf9000', 'Dark Yellow 2'],\n\t['#38761d', 'Dark Green 2'],\n\t['#134f5c', 'Dark Cyan 2'],\n\t['#1155cc', 'Dark Cornflower Blue 2'],\n\t['#0b5394', 'Dark Blue 2'],\n\t['#351c75', 'Dark Purple 2'],\n\t['#741b47', 'Dark Magenta 2'],\n\n\t// ── Highlight palette (50 colors, minus duplicates) ────────────────────\n\n\t// Row 1 — Classic highlighter (bright, vivid)\n\t['#fff176', 'Bright Yellow'],\n\t['#aed581', 'Light Green'],\n\t['#4dd0e1', 'Bright Cyan'],\n\t['#64b5f6', 'Sky Blue'],\n\t['#ce93d8', 'Lavender'],\n\t['#f48fb1', 'Pink'],\n\t['#ffab91', 'Peach'],\n\t['#ff8a65', 'Coral'],\n\t['#e6ee9c', 'Lime'],\n\t['#80cbc4', 'Teal'],\n\n\t// Row 2 — Light pastels\n\t['#fff9c4', 'Pale Yellow'],\n\t['#dcedc8', 'Pale Green'],\n\t['#e0f7fa', 'Pale Cyan'],\n\t['#e3f2fd', 'Pale Blue'],\n\t['#f3e5f5', 'Pale Purple'],\n\t['#fce4ec', 'Pale Pink'],\n\t['#fff3e0', 'Pale Orange'],\n\t['#fbe9e7', 'Pale Red'],\n\t['#f9fbe7', 'Pale Lime'],\n\t['#e0f2f1', 'Pale Teal'],\n\n\t// Row 3 — Medium pastels\n\t['#fff59d', 'Soft Yellow'],\n\t['#c5e1a5', 'Soft Green'],\n\t['#80deea', 'Soft Cyan'],\n\t['#90caf9', 'Soft Blue'],\n\t['#e1bee7', 'Soft Purple'],\n\t['#f8bbd0', 'Soft Pink'],\n\t['#ffcc80', 'Soft Orange'],\n\t// #ffab91 duplicate → Peach (already mapped)\n\t// #e6ee9c duplicate → Lime (already mapped)\n\t['#a5d6a7', 'Mint'],\n\n\t// Row 4 — Bold pastels\n\t['#ffee58', 'Vivid Yellow'],\n\t['#9ccc65', 'Vivid Green'],\n\t['#26c6da', 'Vivid Cyan'],\n\t['#42a5f5', 'Vivid Blue'],\n\t['#ab47bc', 'Vivid Purple'],\n\t['#ec407a', 'Vivid Pink'],\n\t['#ffa726', 'Vivid Orange'],\n\t['#ff7043', 'Red Orange'],\n\t['#d4e157', 'Vivid Lime'],\n\t['#66bb6a', 'Emerald'],\n\n\t// Row 5 — Grays and neutral highlights\n\t// #ffffff duplicate → White (already mapped)\n\t['#fafafa', 'Almost White'],\n\t['#f5f5f5', 'Lightest Gray'],\n\t['#eeeeee', 'Very Light Gray'],\n\t['#e0e0e0', 'Silver'],\n\t['#bdbdbd', 'Medium Gray'],\n\t['#e8eaf6', 'Lavender Gray'],\n\t['#efebe9', 'Warm Gray'],\n\t['#eceff1', 'Cool Gray'],\n\t// #fafafa duplicate → Almost White (already mapped)\n]);\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Returns a human-readable name for a hex color.\n *\n * Checks the static map first, then falls back to a computed\n * description based on hue, saturation, and lightness.\n */\nexport function getColorName(hex: string): string {\n\tconst name: string | undefined = COLOR_NAME_MAP.get(hex.toLowerCase());\n\tif (name) return name;\n\treturn describeColor(hex);\n}\n\n/**\n * Determines whether a color is light enough to need a visible\n * border when rendered on a white background (WCAG 1.4.11).\n *\n * Uses a contrast-ratio threshold of 3:1 against white.\n */\nexport function isLightColor(hex: string): boolean {\n\tconst luminance: number = relativeLuminance(hex);\n\t// Contrast ratio against white: (1.05) / (L + 0.05) < 3\n\t// ⟹ L > 1.05/3 − 0.05 = 0.3\n\tconst LIGHT_THRESHOLD = 0.3;\n\treturn luminance > LIGHT_THRESHOLD;\n}\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\n/** Expands `#RGB` to `#RRGGBB` and lowercases. */\nfunction normalizeHex(hex: string): string {\n\tconst h: string = hex.toLowerCase();\n\tif (h.length === 4) {\n\t\treturn `#${h[1]}${h[1]}${h[2]}${h[2]}${h[3]}${h[3]}`;\n\t}\n\treturn h;\n}\n\n/** Applies sRGB linearization to a single channel value (0–1). */\nfunction linearize(channel: number): number {\n\treturn channel <= 0.03928 ? channel / 12.92 : ((channel + 0.055) / 1.055) ** 2.4;\n}\n\n/** Computes WCAG relative luminance from a hex color. */\nfunction relativeLuminance(hex: string): number {\n\tconst normalized: string = normalizeHex(hex);\n\tconst r: number = linearize(Number.parseInt(normalized.slice(1, 3), 16) / 255);\n\tconst g: number = linearize(Number.parseInt(normalized.slice(3, 5), 16) / 255);\n\tconst b: number = linearize(Number.parseInt(normalized.slice(5, 7), 16) / 255);\n\treturn 0.2126 * r + 0.7152 * g + 0.0722 * b;\n}\n\n/** Hue boundary table: upper bound (degrees) → name. */\nconst HUE_NAMES: readonly (readonly [number, string])[] = [\n\t[15, 'Red'],\n\t[45, 'Orange'],\n\t[65, 'Yellow'],\n\t[150, 'Green'],\n\t[190, 'Cyan'],\n\t[250, 'Blue'],\n\t[290, 'Purple'],\n\t[330, 'Pink'],\n\t[361, 'Red'],\n];\n\n/**\n * Generates a descriptive name from a hex color using HSL analysis.\n * Produces names like \"Dark Blue\", \"Light Green\", or \"Gray\".\n */\nfunction describeColor(hex: string): string {\n\tconst normalized: string = normalizeHex(hex);\n\tconst rRaw: number = Number.parseInt(normalized.slice(1, 3), 16) / 255;\n\tconst gRaw: number = Number.parseInt(normalized.slice(3, 5), 16) / 255;\n\tconst bRaw: number = Number.parseInt(normalized.slice(5, 7), 16) / 255;\n\n\tconst max: number = Math.max(rRaw, gRaw, bRaw);\n\tconst min: number = Math.min(rRaw, gRaw, bRaw);\n\tconst lightness: number = (max + min) / 2;\n\tconst delta: number = max - min;\n\n\t// Achromatic\n\tif (delta < 0.05) {\n\t\tif (lightness < 0.15) return 'Black';\n\t\tif (lightness < 0.35) return 'Dark Gray';\n\t\tif (lightness < 0.65) return 'Gray';\n\t\tif (lightness < 0.85) return 'Light Gray';\n\t\treturn 'Near White';\n\t}\n\n\t// Compute hue in degrees\n\tlet hue = 0;\n\tif (max === rRaw) {\n\t\thue = ((gRaw - bRaw) / delta + (gRaw < bRaw ? 6 : 0)) * 60;\n\t} else if (max === gRaw) {\n\t\thue = ((bRaw - rRaw) / delta + 2) * 60;\n\t} else {\n\t\thue = ((rRaw - gRaw) / delta + 4) * 60;\n\t}\n\n\t// Look up hue name\n\tlet hueName = 'Red';\n\tfor (const [threshold, name] of HUE_NAMES) {\n\t\tif (hue < threshold) {\n\t\t\thueName = name;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t// Lightness modifier\n\tif (lightness < 0.25) return `Very Dark ${hueName}`;\n\tif (lightness < 0.4) return `Dark ${hueName}`;\n\tif (lightness > 0.8) return `Very Light ${hueName}`;\n\tif (lightness > 0.65) return `Light ${hueName}`;\n\treturn hueName;\n}\n"],"names":["COLOR_NAME_MAP","Map","getColorName","hex","get","toLowerCase","normalized","normalizeHex","rRaw","Number","parseInt","slice","gRaw","bRaw","max","Math","min","lightness","delta","hue","hueName","threshold","name","HUE_NAMES","isLightColor","luminance","linearize","h","length","channel"],"mappings":"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"}
|