@notectl/core 1.0.6 → 1.0.9

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 (268) hide show
  1. package/README.md +78 -56
  2. package/custom-elements.json +344 -0
  3. package/dist/chunks/{AttrRegistry-DTsHyDVA.mjs → AttrRegistry-D-przlzb.mjs} +4 -4
  4. package/dist/chunks/{AttrRegistry-DTsHyDVA.mjs.map → AttrRegistry-D-przlzb.mjs.map} +1 -1
  5. package/dist/chunks/ColorNames-iaWsSZx1.mjs +35 -0
  6. package/dist/chunks/ColorNames-iaWsSZx1.mjs.map +1 -0
  7. package/dist/chunks/ColorValidation-Dyy4Bye8.mjs +140 -0
  8. package/dist/chunks/ColorValidation-Dyy4Bye8.mjs.map +1 -0
  9. package/dist/chunks/{Commands-DLP85Mp5.mjs → Commands-CSpSwGXv.mjs} +13 -13
  10. package/dist/chunks/{Commands-DLP85Mp5.mjs.map → Commands-CSpSwGXv.mjs.map} +1 -1
  11. package/dist/chunks/ToolbarKeyboardNav-B32OMv8r.mjs +46 -0
  12. package/dist/chunks/ToolbarKeyboardNav-B32OMv8r.mjs.map +1 -0
  13. package/dist/chunks/ToolbarPlugin-DFkl1uYO.mjs +818 -0
  14. package/dist/chunks/ToolbarPlugin-DFkl1uYO.mjs.map +1 -0
  15. package/dist/chunks/index-BCvuDpVr.mjs +191 -0
  16. package/dist/chunks/index-BCvuDpVr.mjs.map +1 -0
  17. package/dist/chunks/index-BFsYGsBR.mjs +92 -0
  18. package/dist/chunks/index-BFsYGsBR.mjs.map +1 -0
  19. package/dist/chunks/index-BIL37LSL.mjs +73 -0
  20. package/dist/chunks/index-BIL37LSL.mjs.map +1 -0
  21. package/dist/chunks/index-BL56fbXt.mjs +402 -0
  22. package/dist/chunks/index-BL56fbXt.mjs.map +1 -0
  23. package/dist/chunks/index-BQ8iIYLn.mjs +209 -0
  24. package/dist/chunks/index-BQ8iIYLn.mjs.map +1 -0
  25. package/dist/chunks/index-BRYzYOYC.mjs +63 -0
  26. package/dist/chunks/index-BRYzYOYC.mjs.map +1 -0
  27. package/dist/chunks/index-BSFLNveF.mjs +953 -0
  28. package/dist/chunks/index-BSFLNveF.mjs.map +1 -0
  29. package/dist/chunks/index-BTJfyJlJ.mjs +187 -0
  30. package/dist/chunks/index-BTJfyJlJ.mjs.map +1 -0
  31. package/dist/chunks/index-Bsp4LC5t.mjs +130 -0
  32. package/dist/chunks/index-Bsp4LC5t.mjs.map +1 -0
  33. package/dist/chunks/index-DA8TG2S8.mjs +220 -0
  34. package/dist/chunks/index-DA8TG2S8.mjs.map +1 -0
  35. package/dist/chunks/index-DAFCISBN.mjs +100 -0
  36. package/dist/chunks/index-DAFCISBN.mjs.map +1 -0
  37. package/dist/chunks/index-DC1EK22F.mjs +41 -0
  38. package/dist/chunks/index-DC1EK22F.mjs.map +1 -0
  39. package/dist/chunks/index-DGrRWMlW.mjs +541 -0
  40. package/dist/chunks/index-DGrRWMlW.mjs.map +1 -0
  41. package/dist/chunks/index-DfO_fKw6.mjs +39 -0
  42. package/dist/chunks/index-DfO_fKw6.mjs.map +1 -0
  43. package/dist/chunks/index-o6hDR07y.mjs +41 -0
  44. package/dist/chunks/index-o6hDR07y.mjs.map +1 -0
  45. package/dist/chunks/index-uTnc9y7M.mjs +62 -0
  46. package/dist/chunks/index-uTnc9y7M.mjs.map +1 -0
  47. package/dist/chunks/resolvePluginLocale-B4w1OkPy.mjs +34 -0
  48. package/dist/chunks/resolvePluginLocale-B4w1OkPy.mjs.map +1 -0
  49. package/dist/editor/DocumentSerializer.d.ts.map +1 -1
  50. package/dist/editor/NotectlEditor.d.ts +37 -5
  51. package/dist/editor/NotectlEditor.d.ts.map +1 -1
  52. package/dist/editor/PaperLayoutController.d.ts +27 -0
  53. package/dist/editor/PaperLayoutController.d.ts.map +1 -0
  54. package/dist/editor/PaperSize.d.ts +35 -0
  55. package/dist/editor/PaperSize.d.ts.map +1 -0
  56. package/dist/editor/styles/color-picker.d.ts +1 -1
  57. package/dist/editor/styles/color-picker.d.ts.map +1 -1
  58. package/dist/editor/styles/list.d.ts +2 -0
  59. package/dist/editor/styles/list.d.ts.map +1 -1
  60. package/dist/editor/styles/paper.d.ts +3 -0
  61. package/dist/editor/styles/paper.d.ts.map +1 -0
  62. package/dist/editor/styles/table.d.ts +1 -1
  63. package/dist/editor/styles/table.d.ts.map +1 -1
  64. package/dist/editor/styles/toolbar.d.ts +1 -1
  65. package/dist/editor/styles/toolbar.d.ts.map +1 -1
  66. package/dist/editor/styles.d.ts.map +1 -1
  67. package/dist/i18n/Locale.d.ts +17 -0
  68. package/dist/i18n/Locale.d.ts.map +1 -0
  69. package/dist/i18n/LocaleService.d.ts +8 -0
  70. package/dist/i18n/LocaleService.d.ts.map +1 -0
  71. package/dist/i18n/index.d.ts +4 -0
  72. package/dist/i18n/index.d.ts.map +1 -0
  73. package/dist/i18n/resolvePluginLocale.d.ts +3 -0
  74. package/dist/i18n/resolvePluginLocale.d.ts.map +1 -0
  75. package/dist/index.d.ts +48 -3
  76. package/dist/index.d.ts.map +1 -1
  77. package/dist/input/ClipboardHandler.d.ts +2 -0
  78. package/dist/input/ClipboardHandler.d.ts.map +1 -1
  79. package/dist/input/InputHandler.d.ts +2 -0
  80. package/dist/input/InputHandler.d.ts.map +1 -1
  81. package/dist/input/KeyboardHandler.d.ts +2 -0
  82. package/dist/input/KeyboardHandler.d.ts.map +1 -1
  83. package/dist/input/LegacyHTMLNormalizer.d.ts +18 -0
  84. package/dist/input/LegacyHTMLNormalizer.d.ts.map +1 -0
  85. package/dist/input/PasteHandler.d.ts +4 -0
  86. package/dist/input/PasteHandler.d.ts.map +1 -1
  87. package/dist/model/HTMLParser.d.ts +13 -0
  88. package/dist/model/HTMLParser.d.ts.map +1 -1
  89. package/dist/model/SchemaRegistry.d.ts +2 -2
  90. package/dist/model/SchemaRegistry.d.ts.map +1 -1
  91. package/dist/notectl-core.mjs +2297 -1971
  92. package/dist/notectl-core.mjs.map +1 -1
  93. package/dist/notectl-core.umd.js +2894 -1825
  94. package/dist/notectl-core.umd.js.map +1 -1
  95. package/dist/plugins/Plugin.d.ts +17 -2
  96. package/dist/plugins/Plugin.d.ts.map +1 -1
  97. package/dist/plugins/PluginManager.d.ts +22 -1
  98. package/dist/plugins/PluginManager.d.ts.map +1 -1
  99. package/dist/plugins/alignment/AlignmentLocale.d.ts +19 -0
  100. package/dist/plugins/alignment/AlignmentLocale.d.ts.map +1 -0
  101. package/dist/plugins/alignment/AlignmentPlugin.d.ts +4 -0
  102. package/dist/plugins/alignment/AlignmentPlugin.d.ts.map +1 -1
  103. package/dist/plugins/alignment.mjs +3 -89
  104. package/dist/plugins/alignment.mjs.map +1 -1
  105. package/dist/plugins/blockquote/BlockquoteLocale.d.ts +17 -0
  106. package/dist/plugins/blockquote/BlockquoteLocale.d.ts.map +1 -0
  107. package/dist/plugins/blockquote/BlockquotePlugin.d.ts +3 -0
  108. package/dist/plugins/blockquote/BlockquotePlugin.d.ts.map +1 -1
  109. package/dist/plugins/blockquote.mjs +2 -55
  110. package/dist/plugins/blockquote.mjs.map +1 -1
  111. package/dist/plugins/code-block/CodeBlockLocale.d.ts +17 -0
  112. package/dist/plugins/code-block/CodeBlockLocale.d.ts.map +1 -0
  113. package/dist/plugins/code-block/CodeBlockPlugin.d.ts +1 -0
  114. package/dist/plugins/code-block/CodeBlockPlugin.d.ts.map +1 -1
  115. package/dist/plugins/code-block/CodeBlockTypes.d.ts +2 -0
  116. package/dist/plugins/code-block/CodeBlockTypes.d.ts.map +1 -1
  117. package/dist/plugins/code-block.mjs +3 -3
  118. package/dist/plugins/font/FontLocale.d.ts +15 -0
  119. package/dist/plugins/font/FontLocale.d.ts.map +1 -0
  120. package/dist/plugins/font/FontPlugin.d.ts +3 -0
  121. package/dist/plugins/font/FontPlugin.d.ts.map +1 -1
  122. package/dist/plugins/font-size/FontSizeLocale.d.ts +17 -0
  123. package/dist/plugins/font-size/FontSizeLocale.d.ts.map +1 -0
  124. package/dist/plugins/font-size/FontSizePlugin.d.ts +3 -0
  125. package/dist/plugins/font-size/FontSizePlugin.d.ts.map +1 -1
  126. package/dist/plugins/font-size/FontSizePopup.d.ts +2 -0
  127. package/dist/plugins/font-size/FontSizePopup.d.ts.map +1 -1
  128. package/dist/plugins/font-size.mjs +2 -201
  129. package/dist/plugins/font-size.mjs.map +1 -1
  130. package/dist/plugins/font.mjs +2 -183
  131. package/dist/plugins/font.mjs.map +1 -1
  132. package/dist/plugins/hard-break.mjs +1 -1
  133. package/dist/plugins/heading/HeadingBlockTypePicker.d.ts +14 -0
  134. package/dist/plugins/heading/HeadingBlockTypePicker.d.ts.map +1 -0
  135. package/dist/plugins/heading/HeadingCommands.d.ts +5 -0
  136. package/dist/plugins/heading/HeadingCommands.d.ts.map +1 -0
  137. package/dist/plugins/heading/HeadingInputRules.d.ts +5 -0
  138. package/dist/plugins/heading/HeadingInputRules.d.ts.map +1 -0
  139. package/dist/plugins/heading/HeadingKeyboardHandlers.d.ts +5 -0
  140. package/dist/plugins/heading/HeadingKeyboardHandlers.d.ts.map +1 -0
  141. package/dist/plugins/heading/HeadingLocale.d.ts +26 -0
  142. package/dist/plugins/heading/HeadingLocale.d.ts.map +1 -0
  143. package/dist/plugins/heading/HeadingPlugin.d.ts +4 -40
  144. package/dist/plugins/heading/HeadingPlugin.d.ts.map +1 -1
  145. package/dist/plugins/heading.mjs +1 -184
  146. package/dist/plugins/heading.mjs.map +1 -1
  147. package/dist/plugins/highlight/HighlightLocale.d.ts +17 -0
  148. package/dist/plugins/highlight/HighlightLocale.d.ts.map +1 -0
  149. package/dist/plugins/highlight/HighlightPlugin.d.ts +3 -5
  150. package/dist/plugins/highlight/HighlightPlugin.d.ts.map +1 -1
  151. package/dist/plugins/highlight.mjs +2 -123
  152. package/dist/plugins/highlight.mjs.map +1 -1
  153. package/dist/plugins/horizontal-rule/HorizontalRuleLocale.d.ts +15 -0
  154. package/dist/plugins/horizontal-rule/HorizontalRuleLocale.d.ts.map +1 -0
  155. package/dist/plugins/horizontal-rule/HorizontalRulePlugin.d.ts +4 -0
  156. package/dist/plugins/horizontal-rule/HorizontalRulePlugin.d.ts.map +1 -1
  157. package/dist/plugins/horizontal-rule.mjs +2 -56
  158. package/dist/plugins/horizontal-rule.mjs.map +1 -1
  159. package/dist/plugins/image/ImageLocale.d.ts +25 -0
  160. package/dist/plugins/image/ImageLocale.d.ts.map +1 -0
  161. package/dist/plugins/image/ImagePlugin.d.ts +1 -0
  162. package/dist/plugins/image/ImagePlugin.d.ts.map +1 -1
  163. package/dist/plugins/image/ImageUpload.d.ts +3 -0
  164. package/dist/plugins/image/ImageUpload.d.ts.map +1 -1
  165. package/dist/plugins/image.mjs +4 -378
  166. package/dist/plugins/image.mjs.map +1 -1
  167. package/dist/plugins/link/LinkLocale.d.ts +23 -0
  168. package/dist/plugins/link/LinkLocale.d.ts.map +1 -0
  169. package/dist/plugins/link/LinkPlugin.d.ts +3 -0
  170. package/dist/plugins/link/LinkPlugin.d.ts.map +1 -1
  171. package/dist/plugins/link.mjs +2 -124
  172. package/dist/plugins/link.mjs.map +1 -1
  173. package/dist/plugins/list/ListLocale.d.ts +18 -0
  174. package/dist/plugins/list/ListLocale.d.ts.map +1 -0
  175. package/dist/plugins/list/ListPlugin.d.ts +13 -0
  176. package/dist/plugins/list/ListPlugin.d.ts.map +1 -1
  177. package/dist/plugins/list.mjs +2 -190
  178. package/dist/plugins/list.mjs.map +1 -1
  179. package/dist/plugins/print/PrintLocale.d.ts +16 -0
  180. package/dist/plugins/print/PrintLocale.d.ts.map +1 -0
  181. package/dist/plugins/print/PrintPlugin.d.ts +1 -0
  182. package/dist/plugins/print/PrintPlugin.d.ts.map +1 -1
  183. package/dist/plugins/print/PrintStyleCollector.d.ts +7 -0
  184. package/dist/plugins/print/PrintStyleCollector.d.ts.map +1 -1
  185. package/dist/plugins/print/PrintTypes.d.ts +5 -0
  186. package/dist/plugins/print/PrintTypes.d.ts.map +1 -1
  187. package/dist/plugins/shared/ColorMarkOperations.d.ts +28 -0
  188. package/dist/plugins/shared/ColorMarkOperations.d.ts.map +1 -0
  189. package/dist/plugins/shared/ColorNames.d.ts +22 -0
  190. package/dist/plugins/shared/ColorNames.d.ts.map +1 -0
  191. package/dist/plugins/shared/ColorPickerPopup.d.ts +31 -0
  192. package/dist/plugins/shared/ColorPickerPopup.d.ts.map +1 -0
  193. package/dist/plugins/shared/ColorValidation.d.ts +14 -0
  194. package/dist/plugins/shared/ColorValidation.d.ts.map +1 -0
  195. package/dist/plugins/strikethrough/StrikethroughLocale.d.ts +17 -0
  196. package/dist/plugins/strikethrough/StrikethroughLocale.d.ts.map +1 -0
  197. package/dist/plugins/strikethrough/StrikethroughPlugin.d.ts +3 -0
  198. package/dist/plugins/strikethrough/StrikethroughPlugin.d.ts.map +1 -1
  199. package/dist/plugins/strikethrough.mjs +2 -32
  200. package/dist/plugins/strikethrough.mjs.map +1 -1
  201. package/dist/plugins/super-sub/SuperSubLocale.d.ts +19 -0
  202. package/dist/plugins/super-sub/SuperSubLocale.d.ts.map +1 -0
  203. package/dist/plugins/super-sub/SuperSubPlugin.d.ts +3 -0
  204. package/dist/plugins/super-sub/SuperSubPlugin.d.ts.map +1 -1
  205. package/dist/plugins/super-sub.mjs +2 -78
  206. package/dist/plugins/super-sub.mjs.map +1 -1
  207. package/dist/plugins/table/TableBorderColor.d.ts +24 -0
  208. package/dist/plugins/table/TableBorderColor.d.ts.map +1 -0
  209. package/dist/plugins/table/TableCommands.d.ts +9 -8
  210. package/dist/plugins/table/TableCommands.d.ts.map +1 -1
  211. package/dist/plugins/table/TableContextMenu.d.ts +14 -0
  212. package/dist/plugins/table/TableContextMenu.d.ts.map +1 -0
  213. package/dist/plugins/table/TableControls.d.ts +3 -1
  214. package/dist/plugins/table/TableControls.d.ts.map +1 -1
  215. package/dist/plugins/table/TableControlsDOM.d.ts +13 -1
  216. package/dist/plugins/table/TableControlsDOM.d.ts.map +1 -1
  217. package/dist/plugins/table/TableLocale.d.ts +48 -0
  218. package/dist/plugins/table/TableLocale.d.ts.map +1 -0
  219. package/dist/plugins/table/TableNavigation.d.ts +2 -1
  220. package/dist/plugins/table/TableNavigation.d.ts.map +1 -1
  221. package/dist/plugins/table/TableNodeViews.d.ts +3 -1
  222. package/dist/plugins/table/TableNodeViews.d.ts.map +1 -1
  223. package/dist/plugins/table/TablePlugin.d.ts +7 -1
  224. package/dist/plugins/table/TablePlugin.d.ts.map +1 -1
  225. package/dist/plugins/table/index.d.ts +3 -0
  226. package/dist/plugins/table/index.d.ts.map +1 -1
  227. package/dist/plugins/table.mjs +18 -660
  228. package/dist/plugins/table.mjs.map +1 -1
  229. package/dist/plugins/text-color/TextColorLocale.d.ts +17 -0
  230. package/dist/plugins/text-color/TextColorLocale.d.ts.map +1 -0
  231. package/dist/plugins/text-color/TextColorPlugin.d.ts +3 -5
  232. package/dist/plugins/text-color/TextColorPlugin.d.ts.map +1 -1
  233. package/dist/plugins/text-color.mjs +2 -123
  234. package/dist/plugins/text-color.mjs.map +1 -1
  235. package/dist/plugins/text-formatting/TextFormattingLocale.d.ts +18 -0
  236. package/dist/plugins/text-formatting/TextFormattingLocale.d.ts.map +1 -0
  237. package/dist/plugins/text-formatting/TextFormattingPlugin.d.ts +4 -0
  238. package/dist/plugins/text-formatting/TextFormattingPlugin.d.ts.map +1 -1
  239. package/dist/plugins/text-formatting.mjs +2 -49
  240. package/dist/plugins/text-formatting.mjs.map +1 -1
  241. package/dist/plugins/toolbar/ToolbarLocale.d.ts +15 -0
  242. package/dist/plugins/toolbar/ToolbarLocale.d.ts.map +1 -0
  243. package/dist/plugins/toolbar/ToolbarOverflowBehavior.d.ts +23 -0
  244. package/dist/plugins/toolbar/ToolbarOverflowBehavior.d.ts.map +1 -0
  245. package/dist/plugins/toolbar/ToolbarOverflowController.d.ts +56 -0
  246. package/dist/plugins/toolbar/ToolbarOverflowController.d.ts.map +1 -0
  247. package/dist/plugins/toolbar/ToolbarPlugin.d.ts +18 -0
  248. package/dist/plugins/toolbar/ToolbarPlugin.d.ts.map +1 -1
  249. package/dist/plugins/toolbar.mjs +1 -1
  250. package/dist/state/EditorState.d.ts +4 -1
  251. package/dist/state/EditorState.d.ts.map +1 -1
  252. package/dist/state/ReadonlyGuard.d.ts +6 -0
  253. package/dist/state/ReadonlyGuard.d.ts.map +1 -0
  254. package/dist/state/Transaction.d.ts +4 -0
  255. package/dist/state/Transaction.d.ts.map +1 -1
  256. package/dist/view/EditorView.d.ts +2 -0
  257. package/dist/view/EditorView.d.ts.map +1 -1
  258. package/package.json +3 -2
  259. package/dist/chunks/Plugin-B9OZ6Y4c.mjs +0 -15
  260. package/dist/chunks/Plugin-B9OZ6Y4c.mjs.map +0 -1
  261. package/dist/chunks/ToolbarPlugin-sJTiZr-S.mjs +0 -398
  262. package/dist/chunks/ToolbarPlugin-sJTiZr-S.mjs.map +0 -1
  263. package/dist/chunks/color-picker-Csf0wx5a.mjs +0 -5
  264. package/dist/chunks/color-picker-Csf0wx5a.mjs.map +0 -1
  265. package/dist/chunks/index-QvKiO9_4.mjs +0 -538
  266. package/dist/chunks/index-QvKiO9_4.mjs.map +0 -1
  267. package/dist/input/SourceNormalizer.d.ts +0 -7
  268. package/dist/input/SourceNormalizer.d.ts.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
- ### The rich text editor that gets out of your way.
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
- A modular, accessible rich text editor — shipped as a Web Component.
8
- Use what you need, nothing more.
12
+ <br />
9
13
 
10
14
  [![TypeScript](https://img.shields.io/badge/TypeScript-strict-blue?logo=typescript&logoColor=white)](https://www.typescriptlang.org/)
11
15
  [![Web Component](https://img.shields.io/badge/Web_Component-%3Cnotectl--editor%3E-purple)](https://developer.mozilla.org/en-US/docs/Web/API/Web_components)
12
16
  [![License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
13
17
  [![npm](https://img.shields.io/npm/v/@notectl/core)](https://www.npmjs.com/package/@notectl/core)
18
+ [![Bundle Size](https://img.shields.io/badge/core-29kb-orange)](https://www.npmjs.com/package/@notectl/core)
14
19
 
15
20
  <br />
16
21
 
17
- <img src="docs-site/src/assets/screenshots/hero-editor-rich.png" alt="notectl editor with rich content" width="720" />
18
-
19
- [Documentation](https://samyssmile.github.io/notectl/) &bull; [Playground](https://samyssmile.github.io/notectl/playground/) &bull; [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 it live** — [Open the playground](https://samyssmile.github.io/notectl/playground/) (no install required)
26
-
27
- <br />
26
+ [**Try the Playground**](https://samyssmile.github.io/notectl/playground/) &nbsp;&middot;&nbsp; [Documentation](https://samyssmile.github.io/notectl/) &nbsp;&middot;&nbsp; [npm](https://www.npmjs.com/package/@notectl/core)
28
27
 
29
- ## Why notectl?
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
- ## Quick Start
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 full-featured editor in 16 lines.
64
+ That's it. A production-ready editor in 16 lines. No build step required.
74
65
 
75
66
  <br />
76
67
 
77
- ## Accessibility
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
- notectl is built with accessibility as a first-class concern, not an afterthought.
97
+ **Built for control**
80
98
 
81
- - Full **keyboard navigation** every feature reachable without a mouse
82
- - Semantic **ARIA roles and labels** on all interactive elements
83
- - Proper **focus management** across toolbar, dialogs, and editor content
84
- - **Screen reader** friendly — announces formatting changes and editor state
85
- - **High-contrast** compatible with `ThemePreset.Light` and `ThemePreset.Dark`
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
- ## Plugins
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 it does |
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 ordered lists |
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** | Provides an API for printing editor content with configurable options |
111
-
112
- <br />
128
+ | **PrintPlugin** | Print editor content with configurable options |
113
129
 
114
- ## Full Working Examples
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(); // read HTML
132
- editor.setHTML('<p>Hello <strong>world</strong></p>'); // write HTML
133
- editor.getJSON(); // read JSON
134
- editor.getText(); // read plain text
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
- ## Documentation
148
+ ## Works with your stack
141
149
 
142
- Full guides, API reference, and plugin docs are available at **[samyssmile.github.io/notectl](https://samyssmile.github.io/notectl/)**.
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
- ## License
176
+ <div align="center">
177
+
178
+ **[Get started](https://samyssmile.github.io/notectl/)** &nbsp;&middot;&nbsp; **[Open the playground](https://samyssmile.github.io/notectl/playground/)** &nbsp;&middot;&nbsp; **[View on npm](https://www.npmjs.com/package/@notectl/core)**
159
179
 
160
- [MIT](LICENSE)
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
+ }
@@ -9,8 +9,8 @@ function r(t2, e2) {
9
9
  return n(t2) && t2.inlineType === e2;
10
10
  }
11
11
  export {
12
- r as a,
13
- e as b,
14
- t as i
12
+ t as a,
13
+ r as b,
14
+ e as i
15
15
  };
16
- //# sourceMappingURL=AttrRegistry-DTsHyDVA.mjs.map
16
+ //# sourceMappingURL=AttrRegistry-D-przlzb.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"AttrRegistry-DTsHyDVA.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;"}
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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"}