@clepit/core 0.2.0-beta.322

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 (188) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/LICENSE +21 -0
  3. package/README.md +79 -0
  4. package/dist/core/editor/action-bar/css.d.ts +3 -0
  5. package/dist/core/editor/action-bar/index.d.ts +18 -0
  6. package/dist/core/editor/css.d.ts +3 -0
  7. package/dist/core/editor/index.d.ts +18 -0
  8. package/dist/core/editor/views/edit.d.ts +4 -0
  9. package/dist/core/editor/views/index.d.ts +4 -0
  10. package/dist/core/editor/views/json.d.ts +9 -0
  11. package/dist/core/editor/views/preview.d.ts +4 -0
  12. package/dist/core/element/index.d.ts +101 -0
  13. package/dist/core/i18n/index.d.ts +43 -0
  14. package/dist/core/managers/block/css.d.ts +3 -0
  15. package/dist/core/managers/block/index.d.ts +40 -0
  16. package/dist/core/managers/event.d.ts +13 -0
  17. package/dist/core/managers/style.d.ts +181 -0
  18. package/dist/core/renderer/draw.d.ts +27 -0
  19. package/dist/core/renderer/index.d.ts +15 -0
  20. package/dist/core/renderer/invalid-data.d.ts +4 -0
  21. package/dist/core/renderer/page.d.ts +37 -0
  22. package/dist/core/store.d.ts +42 -0
  23. package/dist/core/theme/css.d.ts +4 -0
  24. package/dist/core/theme/index.d.ts +42 -0
  25. package/dist/core/toolbars/block/css.d.ts +3 -0
  26. package/dist/core/toolbars/block/index.d.ts +38 -0
  27. package/dist/core/toolbars/inline/css.d.ts +6 -0
  28. package/dist/core/toolbars/inline/index.d.ts +43 -0
  29. package/dist/index.d.ts +12 -0
  30. package/dist/index.js +2 -0
  31. package/dist/index.mjs +2 -0
  32. package/dist/tools/block/alert/css.d.ts +5 -0
  33. package/dist/tools/block/alert/index.d.ts +13 -0
  34. package/dist/tools/block/alert/input.d.ts +13 -0
  35. package/dist/tools/block/alert/output.d.ts +9 -0
  36. package/dist/tools/block/audio/css.d.ts +5 -0
  37. package/dist/tools/block/audio/index.d.ts +13 -0
  38. package/dist/tools/block/audio/input.d.ts +22 -0
  39. package/dist/tools/block/audio/output.d.ts +9 -0
  40. package/dist/tools/block/checklist/css.d.ts +5 -0
  41. package/dist/tools/block/checklist/index.d.ts +13 -0
  42. package/dist/tools/block/checklist/input.d.ts +14 -0
  43. package/dist/tools/block/checklist/output.d.ts +9 -0
  44. package/dist/tools/block/code/css.d.ts +5 -0
  45. package/dist/tools/block/code/grammar/engine.d.ts +52 -0
  46. package/dist/tools/block/code/grammar/languages.d.ts +6 -0
  47. package/dist/tools/block/code/highlight.d.ts +22 -0
  48. package/dist/tools/block/code/index.d.ts +13 -0
  49. package/dist/tools/block/code/input.d.ts +57 -0
  50. package/dist/tools/block/code/loaders/language.d.ts +17 -0
  51. package/dist/tools/block/code/loaders/theme.d.ts +21 -0
  52. package/dist/tools/block/code/output.d.ts +32 -0
  53. package/dist/tools/block/code/theme-css.d.ts +14 -0
  54. package/dist/tools/block/code/theme-generator.d.ts +27 -0
  55. package/dist/tools/block/code/variants.d.ts +14 -0
  56. package/dist/tools/block/collapsible/css.d.ts +6 -0
  57. package/dist/tools/block/collapsible/index.d.ts +13 -0
  58. package/dist/tools/block/collapsible/input.d.ts +13 -0
  59. package/dist/tools/block/collapsible/output.d.ts +16 -0
  60. package/dist/tools/block/collection/css.d.ts +6 -0
  61. package/dist/tools/block/collection/index.d.ts +13 -0
  62. package/dist/tools/block/collection/input.d.ts +11 -0
  63. package/dist/tools/block/collection/output.d.ts +12 -0
  64. package/dist/tools/block/columns/css.d.ts +6 -0
  65. package/dist/tools/block/columns/index.d.ts +13 -0
  66. package/dist/tools/block/columns/input.d.ts +12 -0
  67. package/dist/tools/block/columns/output.d.ts +11 -0
  68. package/dist/tools/block/date/css.d.ts +6 -0
  69. package/dist/tools/block/date/index.d.ts +13 -0
  70. package/dist/tools/block/date/input.d.ts +12 -0
  71. package/dist/tools/block/date/output.d.ts +10 -0
  72. package/dist/tools/block/delimiter/css.d.ts +5 -0
  73. package/dist/tools/block/delimiter/index.d.ts +13 -0
  74. package/dist/tools/block/delimiter/input.d.ts +12 -0
  75. package/dist/tools/block/delimiter/output.d.ts +9 -0
  76. package/dist/tools/block/doc-card/css.d.ts +6 -0
  77. package/dist/tools/block/doc-card/index.d.ts +13 -0
  78. package/dist/tools/block/doc-card/input.d.ts +11 -0
  79. package/dist/tools/block/doc-card/output.d.ts +11 -0
  80. package/dist/tools/block/embed/css.d.ts +6 -0
  81. package/dist/tools/block/embed/index.d.ts +13 -0
  82. package/dist/tools/block/embed/input.d.ts +11 -0
  83. package/dist/tools/block/embed/output.d.ts +23 -0
  84. package/dist/tools/block/embed/providers.d.ts +5 -0
  85. package/dist/tools/block/file/css.d.ts +6 -0
  86. package/dist/tools/block/file/index.d.ts +13 -0
  87. package/dist/tools/block/file/input.d.ts +14 -0
  88. package/dist/tools/block/file/output.d.ts +10 -0
  89. package/dist/tools/block/glance/css.d.ts +5 -0
  90. package/dist/tools/block/glance/index.d.ts +13 -0
  91. package/dist/tools/block/glance/input.d.ts +11 -0
  92. package/dist/tools/block/glance/output.d.ts +18 -0
  93. package/dist/tools/block/header/css.d.ts +5 -0
  94. package/dist/tools/block/header/index.d.ts +13 -0
  95. package/dist/tools/block/header/input.d.ts +13 -0
  96. package/dist/tools/block/header/output.d.ts +9 -0
  97. package/dist/tools/block/image/css.d.ts +5 -0
  98. package/dist/tools/block/image/index.d.ts +13 -0
  99. package/dist/tools/block/image/input.d.ts +22 -0
  100. package/dist/tools/block/image/output.d.ts +9 -0
  101. package/dist/tools/block/list/css.d.ts +5 -0
  102. package/dist/tools/block/list/index.d.ts +13 -0
  103. package/dist/tools/block/list/input.d.ts +16 -0
  104. package/dist/tools/block/list/output.d.ts +9 -0
  105. package/dist/tools/block/openapi/css.d.ts +5 -0
  106. package/dist/tools/block/openapi/index.d.ts +13 -0
  107. package/dist/tools/block/openapi/input.d.ts +11 -0
  108. package/dist/tools/block/openapi/output.d.ts +24 -0
  109. package/dist/tools/block/openapi/schema.d.ts +17 -0
  110. package/dist/tools/block/openapi/snippets.d.ts +5 -0
  111. package/dist/tools/block/openapi/spec.d.ts +46 -0
  112. package/dist/tools/block/paragraph/css.d.ts +5 -0
  113. package/dist/tools/block/paragraph/index.d.ts +13 -0
  114. package/dist/tools/block/paragraph/input.d.ts +12 -0
  115. package/dist/tools/block/paragraph/output.d.ts +13 -0
  116. package/dist/tools/block/quote/css.d.ts +5 -0
  117. package/dist/tools/block/quote/index.d.ts +13 -0
  118. package/dist/tools/block/quote/input.d.ts +15 -0
  119. package/dist/tools/block/quote/output.d.ts +14 -0
  120. package/dist/tools/block/sketch/css.d.ts +6 -0
  121. package/dist/tools/block/sketch/index.d.ts +13 -0
  122. package/dist/tools/block/sketch/input.d.ts +14 -0
  123. package/dist/tools/block/sketch/output.d.ts +16 -0
  124. package/dist/tools/block/table/css.d.ts +5 -0
  125. package/dist/tools/block/table/index.d.ts +13 -0
  126. package/dist/tools/block/table/input.d.ts +28 -0
  127. package/dist/tools/block/table/output.d.ts +28 -0
  128. package/dist/tools/block/toc/css.d.ts +6 -0
  129. package/dist/tools/block/toc/index.d.ts +13 -0
  130. package/dist/tools/block/toc/input.d.ts +11 -0
  131. package/dist/tools/block/toc/output.d.ts +18 -0
  132. package/dist/tools/block/typeset/css.d.ts +6 -0
  133. package/dist/tools/block/typeset/index.d.ts +22 -0
  134. package/dist/tools/block/typeset/input.d.ts +18 -0
  135. package/dist/tools/block/typeset/latex/layout.d.ts +32 -0
  136. package/dist/tools/block/typeset/latex/model.d.ts +64 -0
  137. package/dist/tools/block/typeset/latex/parse.d.ts +3 -0
  138. package/dist/tools/block/typeset/latex/render.d.ts +7 -0
  139. package/dist/tools/block/typeset/latex/symbols.d.ts +26 -0
  140. package/dist/tools/block/typeset/mermaid/layout.d.ts +71 -0
  141. package/dist/tools/block/typeset/mermaid/model.d.ts +78 -0
  142. package/dist/tools/block/typeset/mermaid/parse.d.ts +3 -0
  143. package/dist/tools/block/typeset/mermaid/render.d.ts +7 -0
  144. package/dist/tools/block/typeset/output.d.ts +46 -0
  145. package/dist/tools/block/updates/css.d.ts +6 -0
  146. package/dist/tools/block/updates/index.d.ts +13 -0
  147. package/dist/tools/block/updates/input.d.ts +14 -0
  148. package/dist/tools/block/updates/output.d.ts +19 -0
  149. package/dist/tools/block/video/css.d.ts +5 -0
  150. package/dist/tools/block/video/index.d.ts +13 -0
  151. package/dist/tools/block/video/input.d.ts +22 -0
  152. package/dist/tools/block/video/output.d.ts +9 -0
  153. package/dist/tools/index.d.ts +3 -0
  154. package/dist/tools/inline/bold/css.d.ts +3 -0
  155. package/dist/tools/inline/bold/index.d.ts +10 -0
  156. package/dist/tools/inline/code/css.d.ts +3 -0
  157. package/dist/tools/inline/code/index.d.ts +12 -0
  158. package/dist/tools/inline/italic/css.d.ts +3 -0
  159. package/dist/tools/inline/italic/index.d.ts +10 -0
  160. package/dist/tools/inline/link/css.d.ts +3 -0
  161. package/dist/tools/inline/link/dialog.d.ts +31 -0
  162. package/dist/tools/inline/link/index.d.ts +11 -0
  163. package/dist/tools/inline/marker/css.d.ts +3 -0
  164. package/dist/tools/inline/marker/index.d.ts +16 -0
  165. package/dist/tools/inline/mention/css.d.ts +3 -0
  166. package/dist/tools/inline/mention/index.d.ts +10 -0
  167. package/dist/tools/inline/status/css.d.ts +3 -0
  168. package/dist/tools/inline/status/dialog.d.ts +30 -0
  169. package/dist/tools/inline/status/index.d.ts +12 -0
  170. package/dist/tools/inline/strikethrough/css.d.ts +3 -0
  171. package/dist/tools/inline/strikethrough/index.d.ts +10 -0
  172. package/dist/tools/inline/tooltip/css.d.ts +3 -0
  173. package/dist/tools/inline/tooltip/dialog.d.ts +52 -0
  174. package/dist/tools/inline/tooltip/index.d.ts +21 -0
  175. package/dist/tools/inline/underline/css.d.ts +3 -0
  176. package/dist/tools/inline/underline/index.d.ts +10 -0
  177. package/dist/types.d.ts +947 -0
  178. package/dist/utils/dialogs/css.d.ts +3 -0
  179. package/dist/utils/dom.d.ts +20 -0
  180. package/dist/utils/icons.d.ts +7 -0
  181. package/dist/utils/platform.d.ts +82 -0
  182. package/dist/utils/sanitize-html-nodom.d.ts +2 -0
  183. package/dist/utils/switch/css.d.ts +3 -0
  184. package/dist/utils/switch/index.d.ts +30 -0
  185. package/dist/utils/tooltip/css.d.ts +3 -0
  186. package/dist/utils/tooltip/index.d.ts +4 -0
  187. package/dist/utils/url.d.ts +52 -0
  188. package/package.json +66 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,23 @@
1
+ # Changelog
2
+
3
+ All notable changes to `@clepit/core` are documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ## [0.2.0] — 2026-04-21
11
+
12
+ ### Added
13
+ - First publicly-supported release.
14
+ - Public `README.md`, `LICENSE` (MIT), and `CHANGELOG.md` for npm consumers.
15
+ - 12 block types: `header`, `paragraph`, `list`, `checklist`, `quote`, `code`, `alert`, `table`, `image`, `video`, `delimiter`, `json`.
16
+ - 8 inline tools: link, marker, tooltip, bold, italic, underline, strikethrough, inline-code.
17
+ - Themes: `'auto' | 'light' | 'dark'` plus `themeOverrides` for custom tokens.
18
+ - `StyleManager.subscribe` for reacting to theme token changes at runtime.
19
+
20
+ ## [0.1.0] — 2026-04-01
21
+
22
+ ### Added
23
+ - Initial internal release of the editor library.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Adombang Mbomndih Munang
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,79 @@
1
+ # @clepit/core
2
+
3
+ A framework-agnostic block-style editor with clean JSON output and a batteries-included renderer. Ships with 12 block types, 8 inline tools, and first-class theming.
4
+
5
+ **Homepage:** [clepit.com](https://clepit.com) · **Docs:** [clepit.com/docs](https://clepit.com/docs) · **Live demo:** [clepit.com/demo](https://clepit.com/demo)
6
+
7
+ ## Install
8
+
9
+ ```sh
10
+ bun add @clepit/core
11
+ # or
12
+ npm install @clepit/core
13
+ ```
14
+
15
+ ## Quick start
16
+
17
+ ```html
18
+ <div id="editor"></div>
19
+ ```
20
+
21
+ ```ts
22
+ import { Editor } from '@clepit/core';
23
+
24
+ const editor = Editor.create({
25
+ containerId: 'editor',
26
+ theme: 'auto', // 'auto' | 'light' | 'dark'
27
+ });
28
+
29
+ const data = editor.data.extract();
30
+ console.log(data.blocks);
31
+ ```
32
+
33
+ ## Features
34
+
35
+ - **12 built-in block types** — header, paragraph, list, checklist, quote, code, alert, table, image, video, delimiter, json.
36
+ - **8 inline tools** — link, marker, tooltip, bold, italic, underline, strikethrough, inline-code.
37
+ - **Framework-agnostic** — no React, Vue, or Svelte dependency. Drop into any app that can mount a DOM node.
38
+ - **TypeScript-first** — every public API is typed. No `any`.
39
+ - **Theme-aware** — pass `theme: 'auto'` and the editor follows the OS color scheme. Override any token with `themeOverrides`.
40
+ - **Clean JSON output** — persist, sync, and render wherever you like.
41
+
42
+ ## Theming
43
+
44
+ ```ts
45
+ Editor.create({
46
+ containerId: 'editor',
47
+ theme: 'auto',
48
+ themeOverrides: {
49
+ accentPrimary: '#5b5bff',
50
+ bgDefault: '#ffffff',
51
+ textPrimary: '#0a0a0a',
52
+ },
53
+ });
54
+ ```
55
+
56
+ Subscribe to runtime token changes:
57
+
58
+ ```ts
59
+ import { StyleManager } from '@clepit/core';
60
+
61
+ const unsub = StyleManager.subscribe(tokens => {
62
+ // sync surrounding UI with editor theme
63
+ });
64
+ ```
65
+
66
+ ## Rendering saved content
67
+
68
+ ```ts
69
+ import { Renderer } from '@clepit/core';
70
+
71
+ Renderer.render({
72
+ containerId: 'view',
73
+ data, // block JSON from editor.data.extract()
74
+ });
75
+ ```
76
+
77
+ ## License
78
+
79
+ MIT. See [LICENSE](./LICENSE).
@@ -0,0 +1,3 @@
1
+ export declare const stylesKey = "clepit-action-bar-styles";
2
+ export declare const style = "\n/* View Toggle */\n.clepit-action-bar {\n position: relative;\n z-index: 1000;\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: -14px; /* Position buttons so exactly half is inside and half outside */\n pointer-events: none;\n padding: 0 100px;\n}\n\n.clepit-action-bar-group {\n display: flex;\n background: var(--clepit-bg);\n border: 1px solid var(--clepit-border);\n border-radius: 6px;\n overflow: hidden;\n padding: 4px;\n gap: 4px;\n}\n\n.clepit-action-bar-button {\n width: 24px;\n height: 24px;\n border: none;\n border-radius: 4px;\n background: transparent;\n color: var(--clepit-text-muted);\n font-size: 14px;\n font-weight: bold;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all 0.2s ease;\n pointer-events: auto;\n}\n\n.clepit-action-bar-button:first-child {\n border-radius: 4px;\n}\n\n.clepit-action-bar-button:last-child {\n border-radius: 4px;\n}\n\n.clepit-action-bar-button:not(:first-child):not(:last-child) {\n border-radius: 4px;\n}\n\n.clepit-action-bar-button:hover {\n background: var(--clepit-toolbar-button-hover-bg, var(--clepit-selection-bg));\n color: var(--clepit-toolbar-button-hover-color, var(--clepit-primary));\n transform: scale(1.05);\n}\n\n.clepit-action-bar-button:active {\n transform: scale(0.95);\n}\n\n.clepit-action-bar-button.active {\n background-color: var(--clepit-primary-bg);\n color: var(--clepit-primary);\n font-weight: bold;\n}\n\n/* Action Buttons */\n.clepit-view-actions {\n display: flex;\n background: var(--clepit-bg);\n border: 1px solid var(--clepit-border);\n border-radius: 6px;\n overflow: hidden;\n padding: 4px;\n gap: 4px;\n}\n\n.clepit-view-action-button {\n width: 24px;\n height: 24px;\n border: none;\n border-radius: 4px;\n background: transparent;\n color: var(--clepit-text-muted);\n font-size: 14px;\n font-weight: bold;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all 0.2s ease;\n pointer-events: auto;\n}\n\n.clepit-view-action-button:first-child {\n border-radius: 4px;\n}\n\n.clepit-view-action-button:last-child {\n border-radius: 4px;\n}\n\n.clepit-view-action-button:not(:first-child):not(:last-child) {\n border-radius: 4px;\n}\n\n.clepit-view-action-button:hover {\n background: var(--clepit-toolbar-button-hover-bg, var(--clepit-selection-bg));\n color: var(--clepit-toolbar-button-hover-color, var(--clepit-primary));\n transform: scale(1.05);\n}\n\n.clepit-view-action-button:active {\n transform: scale(0.95);\n}\n\n/* Copy button feedback animation */\n.clepit-view-action-button--copy-feedback {\n transform: scale(0.95) !important;\n background-color: var(--clepit-success) !important;\n color: var(--clepit-bg) !important;\n}\n";
3
+ //# sourceMappingURL=css.d.ts.map
@@ -0,0 +1,18 @@
1
+ import { EditorView } from '../../../types';
2
+ /*****************************************************************************************************************************************************
3
+ * Class for the action bar
4
+ *****************************************************************************************************************************************************/
5
+ export declare class ActionBar {
6
+ private static eventListenersMap;
7
+ private static addEventListener;
8
+ static create(containerId: string): void;
9
+ private static createButtonGroup;
10
+ static getCurrentView(containerId: string): EditorView | null;
11
+ private static updateButtonStates;
12
+ private static handleViewChange;
13
+ private static handleCopyJson;
14
+ private static handleClearEditor;
15
+ private static handleDownloadJson;
16
+ static destroy(containerId: string): void;
17
+ }
18
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,3 @@
1
+ export declare const stylesKey = "clepit-editor-container-styles";
2
+ export declare const style: string;
3
+ //# sourceMappingURL=css.d.ts.map
@@ -0,0 +1,18 @@
1
+ import { EditorAPI, EditorConfig } from '../../types';
2
+ export declare class Editor {
3
+ static create(config: EditorConfig): EditorAPI;
4
+ private static initialize;
5
+ /**
6
+ * Flatten every block to the locale being edited before the editor sees it.
7
+ *
8
+ * Returns the data untouched when no locale is configured, so an editor that
9
+ * never heard of multilingual content behaves exactly as it always did.
10
+ * Reports each block that had to fall back, so the host can say which language
11
+ * is on screen rather than leaving an author wondering why their text did not
12
+ * change when they switched.
13
+ */
14
+ private static localizeData;
15
+ private static render;
16
+ static destroy(containerId: string): void;
17
+ }
18
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,4 @@
1
+ export declare class EditView {
2
+ static render(containerId: string): void;
3
+ }
4
+ //# sourceMappingURL=edit.d.ts.map
@@ -0,0 +1,4 @@
1
+ export * from './edit';
2
+ export * from './json';
3
+ export * from './preview';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,9 @@
1
+ export declare class JsonView {
2
+ static render(containerId: string): void;
3
+ private static addEventListeners;
4
+ private static removeEventListeners;
5
+ private static handleJsonInput;
6
+ private static validateAndUpdateJson;
7
+ static destroy(containerId: string): void;
8
+ }
9
+ //# sourceMappingURL=json.d.ts.map
@@ -0,0 +1,4 @@
1
+ export declare class PreviewView {
2
+ static render(containerId: string): void;
3
+ }
4
+ //# sourceMappingURL=preview.d.ts.map
@@ -0,0 +1,101 @@
1
+ import { Block } from '../../types';
2
+ /**
3
+ * The construction surface a block's render path is allowed to use.
4
+ *
5
+ * Two backings implement it: the real DOM in a browser, a string builder
6
+ * outside one. That is what lets `@clepit/core` draw a document in a
7
+ * consumer's own process with no browser and no network — which it must, being
8
+ * a published package.
9
+ *
10
+ * Interaction and measurement are deliberately absent. `addEventListener`,
11
+ * `getSelection`, `getComputedStyle` and `getBoundingClientRect` have no meaning
12
+ * without a live page: there is no cursor to read, nothing to measure and no
13
+ * user to listen to. They stay in a separate attach step that only runs under
14
+ * the DOM backing.
15
+ */
16
+ export type ClepitElement = {
17
+ readonly tag: string;
18
+ setAttribute(name: string, value: string): void;
19
+ addClass(...names: string[]): void;
20
+ setText(text: string): void;
21
+ /**
22
+ * Assign markup.
23
+ *
24
+ * The DOM backing hands this to the browser's parser. The string backing has
25
+ * no parser, so it runs the value through the sanitiser it was constructed
26
+ * with — without that, stored document content would emit arbitrary markup
27
+ * into a server-rendered page.
28
+ */
29
+ setHtml(html: string): void;
30
+ append(child: ClepitElement): void;
31
+ appendText(text: string): void;
32
+ };
33
+ /**
34
+ * What a block needs to draw itself beyond its own data.
35
+ *
36
+ * Most blocks need nothing here. The few that do needed it as an extra
37
+ * positional argument of their own shape, which meant there was no single way
38
+ * to call "whichever drawer this block type uses" and the compiler could not
39
+ * check the call. One optional context, shared by every drawer, is what makes
40
+ * the registry in `core/renderer/draw` type-safe rather than checked at run
41
+ * time.
42
+ */
43
+ export type DrawContext = {
44
+ /** A toc derives from its siblings, which no block-local data carries. */
45
+ documentBlocks?: readonly Block[];
46
+ /** Which variant a code block opens on. */
47
+ activeVariant?: number;
48
+ /** Google Maps embeds need a key to build a provider URL. */
49
+ mapsEmbedKey?: string;
50
+ /** How a doc card turns a page id into a link, which only the host knows. */
51
+ docHref?: (pageId: string) => string;
52
+ };
53
+ export type Backing = {
54
+ create(tag: string): ClepitElement;
55
+ /**
56
+ * Create an element in a namespace — in practice SVG, which a sketch and a
57
+ * typeset diagram are both drawn in.
58
+ *
59
+ * The namespace is not serialised. Inline SVG inside an HTML document carries
60
+ * no `xmlns`, and the DOM's own HTML serialiser omits it, so emitting one
61
+ * would put the two backings out of parity.
62
+ */
63
+ createNS(namespace: string, tag: string): ClepitElement;
64
+ };
65
+ export declare const domBacking: Backing;
66
+ /**
67
+ * Escape for a text node, exactly as the DOM's own serialiser does.
68
+ *
69
+ * Three characters, not five. A quote cannot terminate a text node, and
70
+ * escaping one anyway emits a different document from the browser for the same
71
+ * input — which the parity tests read as the two backings having drifted.
72
+ */
73
+ export declare const escapeText: (value: string) => string;
74
+ /**
75
+ * Escape for a double-quoted attribute value, exactly as the DOM's own
76
+ * serialiser does. Angle brackets are literal inside a quoted value; the double
77
+ * quote is the only thing that can end it early.
78
+ */
79
+ export declare const escapeAttribute: (value: string) => string;
80
+ /**
81
+ * A backing that draws to a string.
82
+ *
83
+ * `sanitize` is REQUIRED and has no default on purpose. The package's existing
84
+ * `sanitizeHtml` builds a DOM to parse with, so it cannot run here, and quietly
85
+ * escaping instead would strip every document's inline formatting without
86
+ * saying so. Making it an argument keeps that gap visible at the call site
87
+ * rather than hidden in a default.
88
+ */
89
+ export declare const stringBacking: (sanitize: (html: string) => string) => Backing;
90
+ export declare const renderToString: (element: ClepitElement) => string;
91
+ /**
92
+ * The real node behind a DOM-backed element.
93
+ *
94
+ * A block whose drawing is shared between `render` and `draw` builds it once
95
+ * through the layer, and the DOM path needs the node back at the end to hand to
96
+ * `appendChild`. Throws rather than returning anything for a string-backed
97
+ * element: there is no node, and a caller that got this far has passed the
98
+ * wrong backing.
99
+ */
100
+ export declare const toDomElement: (element: ClepitElement) => Element;
101
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,43 @@
1
+ export declare const isTranslatableField: (blockType: string, field: string) => boolean;
2
+ export declare const translatableFieldsOf: (blockType: string) => string[];
3
+ export declare const isCollectionField: (blockType: string, field: string) => boolean;
4
+ /**
5
+ * Flatten a block's translatable top-level fields to one reader's locale.
6
+ *
7
+ * Called once at the render boundary so that every block tool keeps receiving
8
+ * plain scalars and needs no change. A block whose fields are all scalars comes
9
+ * back untouched, which is what makes this invisible for a single-language
10
+ * document.
11
+ *
12
+ * Collection fields pass through unchanged: their text is at the leaf and
13
+ * walking into them is a separate concern.
14
+ */
15
+ export declare const resolveBlockData: (blockType: string, data: Record<string, unknown>, requested: string, documentDefault: string) => Record<string, unknown>;
16
+ export type Localized<T> = T | Record<string, T>;
17
+ export type Resolution<T> = {
18
+ locale: string;
19
+ isFallback: boolean;
20
+ value: T;
21
+ };
22
+ export declare const isTranslated: <T>(value: Localized<T>) => boolean;
23
+ export declare const localesOf: <T>(value: Localized<T>, documentDefault: string) => string[];
24
+ /**
25
+ * Resolve a possibly-translated field for a reader.
26
+ *
27
+ * A bare scalar is the document's default locale, which is what lets every
28
+ * block written before this slice read correctly with no backfill.
29
+ *
30
+ * Order is requested, then the document default, then any present locale in a
31
+ * deterministic order. It returns null only when a locale map is genuinely
32
+ * empty: a reader must never get a blank block because their language is
33
+ * missing, so `isFallback` reports when they are reading something other than
34
+ * what they asked for.
35
+ */
36
+ export declare const resolveLocalized: <T>(value: Localized<T> | undefined, requested: string, documentDefault: string) => Resolution<T> | null;
37
+ /**
38
+ * Write a value for one locale, keeping the field scalar while it holds only the
39
+ * document default. A single-language tenant's stored data therefore never
40
+ * changes shape.
41
+ */
42
+ export declare const withLocale: <T>(value: Localized<T> | undefined, locale: string, next: T, documentDefault: string) => Localized<T>;
43
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,3 @@
1
+ export declare const stylesKey = "clepit-block-manager-styles";
2
+ export declare const style = "\n/* Blocks */\n.clepit-block {\n position: relative;\n margin: var(--block-margin-top, 8px) 0 var(--block-margin-bottom, 16px) 0;\n padding: 8px 0;\n padding-left: 54px;\n border-radius: 4px;\n transition: background-color 0.2s ease;\n display: flex;\n align-items: flex-start;\n gap: 6px;\n}\n\n.clepit-block:hover {\n background-color: var(--clepit-block-highlight-bg);\n}\n\n.clepit-block--active {\n background-color: var(--clepit-block-highlight-bg);\n}\n\n.clepit-block-content {\n outline: none;\n min-height: 1.2em;\n flex: 1;\n min-width: 0; /* Allow content to shrink */\n}\n\n/* Remove focus outline from editable elements */\n.clepit-block-content [contenteditable=\"true\"] {\n outline: none;\n}\n\n/* Placeholder styles for all text elements */\n.clepit-block-content:empty::before {\n content: attr(data-placeholder);\n color: var(--clepit-text-subtle);\n pointer-events: none;\n font-style: italic;\n}\n\n/* Menu animation classes */\n.clepit-block-type-selector--visible {\n display: block;\n transform: translateY(0);\n}\n\n.clepit-block-type-selector--hidden {\n display: none;\n}\n\n/* Block Operations Menu */\n.clepit-block-operations-menu {\n position: absolute;\n top: 100%;\n left: 0;\n z-index: 1001;\n background: var(--clepit-bg);\n border: 1px solid var(--clepit-border);\n border-radius: 6px;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);\n padding: 8px;\n min-width: 200px;\n margin-top: 4px;\n display: none;\n transition: transform 0.2s ease;\n}\n\n.clepit-block-operations-menu--visible {\n display: block;\n transform: translateY(0);\n}\n\n.clepit-block-operations-menu--hidden {\n display: none;\n}\n\n/* Block Type Selector */\n.clepit-block-type-selector {\n position: absolute;\n top: 100%;\n left: 0;\n z-index: 1001;\n background: var(--clepit-bg);\n border: 1px solid var(--clepit-border);\n border-radius: 6px;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);\n padding: 8px;\n min-width: 150px;\n margin-top: 4px;\n display: none;\n transition: transform 0.2s ease;\n}\n\n.clepit-block-type-selector--visible {\n display: block;\n transform: translateY(0);\n}\n\n.clepit-block-type-selector--hidden {\n display: none;\n}\n\n/* Default menu item styles - package doesn't care about theme */\n.clepit-menu-item {\n padding: 8px 12px;\n cursor: pointer;\n border-radius: 4px;\n transition: background-color 0.2s;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.clepit-menu-item .clepit-menu-icon {\n width: 16px;\n height: 16px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n font-size: 14px;\n}\n\n.clepit-menu-item:hover {\n background-color: var(--clepit-selection-bg);\n}\n\n.clepit-menu-item.active {\n background-color: var(--clepit-primary-bg);\n color: var(--clepit-primary);\n font-weight: bold;\n}\n\n.clepit-menu-item--danger {\n color: var(--clepit-error);\n}\n\n/* Block type menu items - match font size with operations menu */\n.clepit-block-type-item {\n font-size: 14px;\n}\n\n/* Default menu divider styles */\n.clepit-menu-divider {\n height: 1px;\n background: linear-gradient(to right, transparent, var(--clepit-border), transparent);\n margin: 8px 0;\n}\n\n/* Default menu arrow styles */\n.clepit-menu-arrow {\n margin-left: auto;\n font-size: 12px;\n color: var(--clepit-text-muted);\n}\n\n/* Input styles for block type selector */\n.clepit-block-type-selector input {\n width: 100%;\n padding: 8px 12px;\n border: 1px solid var(--clepit-input-border, var(--clepit-border));\n border-radius: 4px;\n font-size: 14px;\n margin-bottom: 8px;\n outline: none;\n transition: border-color 0.2s;\n background-color: var(--input-bg, var(--clepit-bg));\n color: var(--input-color, var(--clepit-text));\n}\n\n.clepit-block-type-selector input:focus {\n border-color: var(--clepit-primary);\n box-shadow: 0 0 0 2px var(--clepit-primary-bg);\n}\n\n.clepit-block-type-selector input::placeholder {\n color: var(--placeholder-color, var(--clepit-text-subtle));\n}\n\n.clepit-block-type-selector-items {\n max-height: 200px;\n overflow-y: auto;\n}\n\n.clepit-menu-icon {\n font-size: 14px;\n min-width: 20px;\n text-align: center;\n font-weight: bold;\n}\n\n.clepit-menu-shortcut {\n margin-left: auto;\n font-size: 9px;\n color: var(--clepit-text-muted);\n opacity: 0.7;\n}\n\n.clepit-menu-positioned {\n position: absolute;\n z-index: 1001;\n top: var(--menu-top, 0);\n left: var(--menu-left, 0);\n}\n\n/* The block menus are popovers in the top layer. Anchor positioning puts them\n * under the block toolbar without JavaScript measuring anything.\n *\n * Guarded: anchor positioning is Baseline 2026 (Chrome 125+, Firefox 132+,\n * Safari 18.2+), roughly 91% of traffic. Browsers without it get the popover's\n * default centred placement rather than a second JS positioning path \u2014 the menu\n * stays usable, just not adjacent to its button. */\n.clepit-block-type-selector:popover-open,\n.clepit-block-operations-menu:popover-open {\n margin: 0;\n border: 1px solid var(--clepit-border);\n border-radius: 6px;\n background: var(--clepit-bg);\n padding: 8px;\n overflow: visible;\n}\n\n@supports (anchor-name: --a) {\n .clepit-block-type-selector:popover-open,\n .clepit-block-operations-menu:popover-open {\n position-anchor: --clepit-block-toolbar;\n position-area: bottom span-inline-end;\n margin-block-start: 5px;\n }\n}\n\n@supports (position-try-fallbacks: flip-block) {\n .clepit-block-type-selector:popover-open,\n .clepit-block-operations-menu:popover-open {\n position-try-fallbacks: flip-block;\n }\n}\n\n/* Convert Submenu */\n@supports (anchor-name: --a) {\n .clepit-convert-submenu:popover-open {\n position: fixed;\n position-area: inline-end span-block-end;\n margin: 0 0 0 4px;\n inset: auto;\n }\n\n .clepit-convert-submenu:popover-open {\n position-try-fallbacks: flip-inline;\n }\n}\n\n.clepit-convert-submenu {\n position: absolute;\n top: var(--submenu-top, 0);\n left: var(--submenu-left, 100%);\n z-index: var(--submenu-z-index, 1002);\n background: var(--clepit-bg);\n border: 1px solid var(--clepit-border);\n border-radius: 6px;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);\n padding: 8px;\n min-width: 140px;\n margin-left: 4px;\n display: none;\n transition: transform 0.2s ease;\n}\n\n.clepit-convert-submenu--visible {\n display: block;\n opacity: 1;\n transform: translateX(0);\n}\n\n.clepit-convert-submenu--hidden {\n display: none;\n opacity: 0;\n transform: translateX(-10px);\n}\n\n/* Input styles for convert submenu */\n.clepit-convert-submenu input {\n width: 100%;\n padding: 6px 8px;\n border: 1px solid var(--clepit-input-border, var(--clepit-border));\n border-radius: 4px;\n font-size: 12px;\n outline: none;\n background-color: var(--input-bg, var(--clepit-bg));\n color: var(--input-color, var(--clepit-text));\n}\n\n.clepit-convert-submenu input:focus {\n border-color: var(--clepit-input-focus-border, var(--clepit-primary));\n box-shadow: 0 0 0 2px var(--clepit-input-focus-shadow, var(--clepit-primary-bg));\n}\n\n.clepit-convert-submenu input::placeholder {\n color: var(--clepit-input-placeholder, var(--clepit-text-subtle));\n}\n\n.clepit-convert-submenu-items {\n max-height: 200px;\n overflow-y: auto;\n}\n\n.clepit-block-operation-item {\n padding: 8px 12px;\n cursor: pointer;\n border-radius: 4px;\n transition: background-color 0.2s;\n font-size: 14px;\n}\n\n.clepit-block-operation-item:hover {\n background-color: var(--clepit-hover-bg, var(--clepit-selection-bg));\n}\n\n/* Input styles for operations menu */\n.clepit-block-operations-menu input {\n width: 100%;\n padding: 8px 12px;\n border: 1px solid var(--clepit-input-border, var(--clepit-border));\n border-radius: 4px;\n font-size: 14px;\n margin-bottom: 8px;\n outline: none;\n transition: border-color 0.2s;\n background-color: var(--input-bg, var(--clepit-bg));\n color: var(--input-color, var(--clepit-text));\n}\n\n.clepit-block-operations-menu input:focus {\n border-color: var(--clepit-primary);\n box-shadow: 0 0 0 2px var(--clepit-primary-bg);\n}\n\n.clepit-block-operations-menu input::placeholder {\n color: var(--placeholder-color, var(--clepit-text-subtle));\n}\n\n.clepit-block-operations-menu-items {\n max-height: 200px;\n overflow-y: auto;\n}\n\n.clepit-block-operation-item[data-operation=\"delete\"] {\n color: var(--clepit-error);\n}\n\n/* Convert submenu items */\n.clepit-convert-option-item {\n padding: 8px 12px;\n cursor: pointer;\n border-radius: 4px;\n transition: background-color 0.2s;\n font-size: 14px;\n}\n\n.clepit-convert-option-item:hover {\n background-color: var(--clepit-hover-bg, var(--clepit-selection-bg));\n}\n\n/* Indentation */\n.clepit-block[data-indent=\"1\"] .clepit-block-content {\n margin-left: 20px;\n}\n\n.clepit-block[data-indent=\"2\"] .clepit-block-content {\n margin-left: 40px;\n}\n\n.clepit-block[data-indent=\"3\"] .clepit-block-content {\n margin-left: 60px;\n}\n\n/* Responsive */\n@media (max-width: 768px) {\n /* The 54px gutter exists to hold the block toolbar, which is only ever\n * displayed on the active block. On a phone that reserved a seventh of the\n * editor's width on every idle block at once, pushing the text into a narrow\n * column with empty space either side. Give the width back and let the\n * gutter open only under the block whose toolbar is actually showing. */\n /* No transition on padding-left. The block element is re-created as you\n * interact with it, so an animated gutter restarts from 0 every time and\n * never reaches its end value \u2014 the toolbar would sit on top of the text. */\n .clepit-block {\n padding-left: 0;\n }\n\n .clepit-block--active,\n .clepit-block:focus-within,\n .clepit-block:has(.clepit-block-toolbar--visible) {\n padding-left: 54px;\n }\n}\n";
3
+ //# sourceMappingURL=css.d.ts.map
@@ -0,0 +1,40 @@
1
+ import { Block, BlockToolType, EditorData, Tool } from '../../../types';
2
+ /*****************************************************************************************************************************************************
3
+ * Class for the block manager
4
+ *****************************************************************************************************************************************************/
5
+ export declare class BlockManager {
6
+ private static eventListenersMap;
7
+ private static addEventListener;
8
+ private static createBlockElement;
9
+ static insertBlock(block: Block, containerId: string, index: number): HTMLElement | null;
10
+ static removeBlock(containerId: string, index: number): null | undefined;
11
+ static replaceBlock(containerId: string, index: number, block: Block<BlockToolType>): void;
12
+ static moveBlock(containerId: string, fromIndex: number, toIndex: number): void;
13
+ static getBlock(blockId: string): HTMLElement | null;
14
+ static getBlocks(containerId: string): HTMLElement[];
15
+ static getActiveBlocks(containerId: string): HTMLElement[];
16
+ static getBlockIndex(containerId: string, blockId: string): number;
17
+ static getTool(type: BlockToolType): Tool | null;
18
+ static getBlockData<T extends BlockToolType>(blockId: string): Block<T>;
19
+ static extractData(containerId: string): EditorData;
20
+ static renderTool(type: BlockToolType, data: Block<BlockToolType>['data'], containerId: string): HTMLElement | null;
21
+ static focusBlock(block: HTMLElement): void;
22
+ static setActiveBlock(block: HTMLElement): void;
23
+ static getActiveBlock(containerId: string): HTMLElement | null;
24
+ static convertBlock(blockId: string, newType: BlockToolType, containerId: string): void;
25
+ private static getBlockTunes;
26
+ static updateStateFromRange(range: Range): void;
27
+ static renderBlock(block: HTMLElement, containerId: string, index: number): void;
28
+ static setBlocks(blocks: Block[], containerId: string): void;
29
+ static renderBlocks(blocks: Block[], containerId: string): void;
30
+ private static removeAllBlocks;
31
+ static resetBlocks(containerId: string): void;
32
+ static getEditorId(element: HTMLElement): string | null;
33
+ static handleKeydown(event: Event): void;
34
+ static handleInput(event: Event): void;
35
+ static ensureActiveBlock(containerId: string): void;
36
+ static saveBlockData(element: HTMLElement): void;
37
+ static updateBlockData(blockId: string, data: Block['data'], containerId: string): void;
38
+ static destroy(containerId: string): void;
39
+ }
40
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,13 @@
1
+ import { EditorInstance } from '../../types';
2
+ export declare class EventManager {
3
+ static addListeners(containerId: string): void;
4
+ static removeListeners(containerId: string): void;
5
+ static getInstanceAndTargetFromRange(range: Range): {
6
+ target: HTMLElement;
7
+ instance: EditorInstance;
8
+ } | null;
9
+ private static handleClick;
10
+ private static handleSelectionChange;
11
+ static handlePaste(event: ClipboardEvent): void;
12
+ }
13
+ //# sourceMappingURL=event.d.ts.map
@@ -0,0 +1,181 @@
1
+ import { ThemeTokens } from '../theme';
2
+ import { BlockClassNames, CSSProperties } from '../../types';
3
+ /**
4
+ * Centralized styling manager that ensures consistent styling across all components
5
+ *
6
+ * Styling hierarchy:
7
+ * 1. Default styles via CSS classes (lowest priority)
8
+ * 2. User styles as inline styles (highest priority)
9
+ * 3. User classnames last (can override default styles but not user styles)
10
+ */
11
+ export declare class StyleManager {
12
+ static idSuffixes: {
13
+ actionBar: {
14
+ clearButton: string;
15
+ copyButton: string;
16
+ downloadButton: string;
17
+ editButton: string;
18
+ jsonButton: string;
19
+ previewButton: string;
20
+ };
21
+ editorContent: string;
22
+ };
23
+ static classNames: {
24
+ actionBar: {
25
+ action: string;
26
+ actionButton: string;
27
+ button: string;
28
+ container: string;
29
+ copyFeedback: string;
30
+ group: string;
31
+ };
32
+ block: {
33
+ active: string;
34
+ alert: string;
35
+ audio: {
36
+ captionEditable: string;
37
+ container: string;
38
+ dropArea: string;
39
+ wrapper: string;
40
+ };
41
+ audioDeleteBtn: string;
42
+ checklist: {
43
+ checkbox: string;
44
+ container: string;
45
+ item: string;
46
+ text: string;
47
+ };
48
+ code: {
49
+ container: string;
50
+ editor: string;
51
+ header: string;
52
+ headerWrapper: string;
53
+ };
54
+ container: string;
55
+ content: string;
56
+ header: string;
57
+ image: {
58
+ captionEditable: string;
59
+ container: string;
60
+ dropArea: string;
61
+ wrapper: string;
62
+ };
63
+ imageDeleteBtn: string;
64
+ indent1: string;
65
+ indent2: string;
66
+ indent3: string;
67
+ link: string;
68
+ list: {
69
+ container: string;
70
+ item: string;
71
+ };
72
+ output: string;
73
+ paragraph: string;
74
+ quote: {
75
+ author: string;
76
+ container: string;
77
+ divider: string;
78
+ text: string;
79
+ };
80
+ table: {
81
+ caption: string;
82
+ cell: string;
83
+ downloadSwitch: string;
84
+ headerCell: string;
85
+ headerRow: string;
86
+ row: string;
87
+ };
88
+ tooltip: string;
89
+ video: {
90
+ captionEditable: string;
91
+ container: string;
92
+ dropArea: string;
93
+ iframe: string;
94
+ video: string;
95
+ wrapper: string;
96
+ };
97
+ videoDeleteBtn: string;
98
+ };
99
+ editor: {
100
+ container: string;
101
+ content: string;
102
+ jsonEditable: string;
103
+ jsonEmpty: string;
104
+ jsonError: string;
105
+ jsonOutput: string;
106
+ };
107
+ renderer: {
108
+ content: string;
109
+ };
110
+ switch: {
111
+ container: string;
112
+ };
113
+ };
114
+ /**
115
+ * Apply styles to an element following the proper hierarchy
116
+ */
117
+ static applyStyles(element: HTMLElement, styles?: CSSProperties): void;
118
+ /**
119
+ * Apply class names to an element
120
+ */
121
+ static applyClassNames(element: HTMLElement, classNames?: BlockClassNames | Record<string, string | undefined> | string): void;
122
+ /**
123
+ * Apply styling to an element following the proper hierarchy:
124
+ * 1. Default styles via CSS classes (already applied via className)
125
+ * 2. User styles as inline styles (highest priority)
126
+ * 3. User classnames last (can override default styles but not user styles)
127
+ */
128
+ static applyStyling(element: HTMLElement, options: {
129
+ styles?: CSSProperties;
130
+ classNames?: BlockClassNames | string;
131
+ }): void;
132
+ /**
133
+ * Create a styled element with proper styling hierarchy
134
+ */
135
+ static createStyledElement(tag: keyof HTMLElementTagNameMap, className: string, options?: {
136
+ styles?: CSSProperties;
137
+ classNames?: BlockClassNames | string;
138
+ }): HTMLElement;
139
+ /**
140
+ * Reusable function to inject styles into the document head
141
+ * @param styleId - Unique ID for the style element
142
+ * @param styles - CSS styles as a string
143
+ * @returns boolean - true if styles were injected, false if already existed
144
+ */
145
+ static injectStyles(styleId: string, styles: string): boolean;
146
+ private static themeRegistry;
147
+ private static themeSubscribers;
148
+ private static themeMediaQuery?;
149
+ private static themeMediaQueryListener?;
150
+ /**
151
+ * Register an editor instance with the theme system. Sets data attributes on
152
+ * the container, injects per-instance token overrides if provided, and
153
+ * lazily attaches the prefers-color-scheme listener if needed.
154
+ */
155
+ static registerEditor(containerId: string, mode: 'auto' | 'light' | 'dark', overrides?: {
156
+ light?: ThemeTokens;
157
+ dark?: ThemeTokens;
158
+ }): void;
159
+ /**
160
+ * Unregister an editor instance. Removes the per-instance override block,
161
+ * clears data attributes, and detaches the matchMedia listener if no
162
+ * auto-mode editors and no subscribers remain.
163
+ */
164
+ static unregisterEditor(containerId: string): void;
165
+ /**
166
+ * Mirrors the active editor's theme mode onto `document.body` so that
167
+ * portaled overlays (dialogs, menus, tooltips appended to body) inherit
168
+ * the same CSS variables defined in the built-in theme stylesheet.
169
+ * If multiple editors are registered, the first registered mode wins.
170
+ */
171
+ private static syncBodyThemeAttribute;
172
+ /** Returns the current OS-resolved theme. Defaults to 'light' when matchMedia is unavailable. */
173
+ static getResolvedTheme(): 'light' | 'dark';
174
+ /** Subscribe to OS-level theme changes. Returns unsubscribe function. */
175
+ static subscribe(cb: (theme: 'light' | 'dark') => void): () => void;
176
+ /** Test-only helper to reset registry between tests. */
177
+ static unregisterAllEditorsForTest(): void;
178
+ private static ensureThemeListener;
179
+ private static maybeDetachThemeListener;
180
+ }
181
+ //# sourceMappingURL=style.d.ts.map
@@ -0,0 +1,27 @@
1
+ import { Backing, ClepitElement, DrawContext } from '../element';
2
+ import { Block, BlockToolType } from '../../types';
3
+ /**
4
+ * How any block type draws itself, in one shape.
5
+ *
6
+ * Four blocks used to take a fourth argument of their own: the toc wanted the
7
+ * document's other blocks, code an active variant, embed a maps key, and a doc
8
+ * card a link builder. One shared optional context replaces all four, which is
9
+ * what lets a single call site draw any block at all.
10
+ */
11
+ export type BlockDrawer<T extends BlockToolType> = (data: Block<T>['data'], backing: Backing, context?: DrawContext) => ClepitElement | null;
12
+ /**
13
+ * Draw one block, whatever type it is.
14
+ *
15
+ * A switch rather than a lookup table, and deliberately so. Indexing a table by
16
+ * `block.type` gives the compiler a union of every drawer, and it then demands
17
+ * an argument acceptable to all of them at once, which no block's data is. That
18
+ * is the point where a cast usually gets written, and a cast here would let a
19
+ * paragraph's data reach the table drawer with nothing complaining.
20
+ *
21
+ * Each `case` narrows `block` to one type, so `block.data` is checked against
22
+ * that block's drawer and nothing else. The `never` at the end is what makes it
23
+ * total: add a block tool without a case and this file stops compiling, rather
24
+ * than a child quietly vanishing from a published page.
25
+ */
26
+ export declare const drawBlock: (block: Block, backing: Backing, context?: DrawContext) => ClepitElement | null;
27
+ //# sourceMappingURL=draw.d.ts.map
@@ -0,0 +1,15 @@
1
+ import { RendererConfig } from '../../types';
2
+ export declare class Renderer {
3
+ static render(config: RendererConfig): HTMLElement;
4
+ /**
5
+ * Flatten a block's translated fields to the reader's locale before any tool
6
+ * sees it, so every tool keeps receiving plain scalars.
7
+ *
8
+ * Returns the block itself when no locale is configured or nothing is
9
+ * translated, which is what keeps a single-language document byte-identical
10
+ * through this path.
11
+ */
12
+ private static localize;
13
+ private static renderBlock;
14
+ }
15
+ //# sourceMappingURL=index.d.ts.map