@elabs-ai/components-editor 4.0.0

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 (207) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +149 -0
  3. package/dist/chunk-LBC5VJBD.js +3748 -0
  4. package/dist/chunk-LBC5VJBD.js.map +1 -0
  5. package/dist/index.css +233 -0
  6. package/dist/index.css.map +1 -0
  7. package/dist/index.d.ts +199 -0
  8. package/dist/index.js +362 -0
  9. package/dist/index.js.map +1 -0
  10. package/dist/lib/monaco-environment.d.ts +2 -0
  11. package/dist/lib/monaco-environment.js +44 -0
  12. package/dist/lib/monaco-environment.js.map +1 -0
  13. package/dist/markdown/frontmatter.d.ts +11 -0
  14. package/dist/markdown/frontmatter.js +33 -0
  15. package/dist/markdown/frontmatter.js.map +1 -0
  16. package/dist/markdown/index.css +233 -0
  17. package/dist/markdown/index.css.map +1 -0
  18. package/dist/markdown/index.d.ts +1486 -0
  19. package/dist/markdown/index.js +4882 -0
  20. package/dist/markdown/index.js.map +1 -0
  21. package/dist/markdown/parse.d.ts +25 -0
  22. package/dist/markdown/parse.js +14 -0
  23. package/dist/markdown/parse.js.map +1 -0
  24. package/dist/markdown-editor-DfBZibAn.d.ts +702 -0
  25. package/package.json +101 -0
  26. package/src/ai-objects/ai-objects-integration.test.tsx +128 -0
  27. package/src/ai-objects/ai-objects.stories.tsx +233 -0
  28. package/src/ai-objects/ai-objects.test.tsx +205 -0
  29. package/src/ai-objects/decision-card.tsx +178 -0
  30. package/src/ai-objects/directives.ts +136 -0
  31. package/src/ai-objects/entity.tsx +181 -0
  32. package/src/ai-objects/index.ts +34 -0
  33. package/src/ai-objects/knowledge-card.tsx +143 -0
  34. package/src/calc-block/calc-block.stories.tsx +297 -0
  35. package/src/calc-block/calc-block.test.tsx +164 -0
  36. package/src/calc-block/calc-block.tsx +398 -0
  37. package/src/calc-block/calc-editor-monaco.ts +214 -0
  38. package/src/calc-block/calc-editor-prose.ts +128 -0
  39. package/src/calc-block/calc-editor.css +80 -0
  40. package/src/calc-block/calc-editor.stories.tsx +272 -0
  41. package/src/calc-block/calc-editor.test.ts +228 -0
  42. package/src/calc-block/calc-editor.ts +270 -0
  43. package/src/calc-block/calc-inline.stories.tsx +44 -0
  44. package/src/calc-block/calc-inline.test.tsx +44 -0
  45. package/src/calc-block/calc-inline.tsx +75 -0
  46. package/src/calc-block/index.ts +20 -0
  47. package/src/calc-block/types.ts +164 -0
  48. package/src/code-editor/code-editor.stories.tsx +218 -0
  49. package/src/code-editor/code-editor.test.tsx +134 -0
  50. package/src/code-editor/code-editor.tsx +250 -0
  51. package/src/code-editor/index.ts +6 -0
  52. package/src/code-workspace/code-workspace.stories.tsx +51 -0
  53. package/src/code-workspace/code-workspace.test.tsx +146 -0
  54. package/src/code-workspace/code-workspace.tsx +253 -0
  55. package/src/code-workspace/index.ts +6 -0
  56. package/src/copy-button/copy-button.tsx +51 -0
  57. package/src/copy-button/index.ts +1 -0
  58. package/src/css.d.ts +3 -0
  59. package/src/diff-editor/diff-editor.stories.tsx +44 -0
  60. package/src/diff-editor/diff-editor.test.tsx +68 -0
  61. package/src/diff-editor/diff-editor.tsx +151 -0
  62. package/src/diff-editor/index.ts +1 -0
  63. package/src/editor-context-menu/editor-context-menu.tsx +120 -0
  64. package/src/editor-context-menu/index.ts +1 -0
  65. package/src/editor-toolbar/editor-toolbar.tsx +83 -0
  66. package/src/editor-toolbar/index.ts +1 -0
  67. package/src/index.ts +48 -0
  68. package/src/lib/editor-completions-monaco.test.ts +206 -0
  69. package/src/lib/editor-completions-monaco.ts +127 -0
  70. package/src/lib/editor-completions.test.ts +156 -0
  71. package/src/lib/editor-completions.ts +153 -0
  72. package/src/lib/editor-content-access-prose.test.ts +411 -0
  73. package/src/lib/editor-content-access-prose.ts +172 -0
  74. package/src/lib/editor-content-access.test.ts +182 -0
  75. package/src/lib/editor-content-access.ts +109 -0
  76. package/src/lib/languages.ts +32 -0
  77. package/src/lib/markdown/diff.test.ts +80 -0
  78. package/src/lib/markdown/diff.ts +194 -0
  79. package/src/lib/markdown/directives.ts +342 -0
  80. package/src/lib/markdown/frontmatter.ts +50 -0
  81. package/src/lib/markdown/markdown-scale.test.ts +65 -0
  82. package/src/lib/markdown/markdown-scale.ts +62 -0
  83. package/src/lib/markdown/merge.test.ts +64 -0
  84. package/src/lib/markdown/merge.ts +158 -0
  85. package/src/lib/markdown/slugify.test.ts +156 -0
  86. package/src/lib/markdown/slugify.ts +47 -0
  87. package/src/lib/monaco-environment.ts +103 -0
  88. package/src/lib/monaco-theme-bridge.ts +293 -0
  89. package/src/lib/use-data-theme.ts +61 -0
  90. package/src/markdown/frontmatter.ts +14 -0
  91. package/src/markdown/index.ts +323 -0
  92. package/src/markdown/parse.test.ts +60 -0
  93. package/src/markdown/parse.ts +38 -0
  94. package/src/markdown-academic/citations.test.ts +77 -0
  95. package/src/markdown-academic/citations.tsx +442 -0
  96. package/src/markdown-academic/footnotes.tsx +235 -0
  97. package/src/markdown-academic/index.ts +32 -0
  98. package/src/markdown-academic/math.tsx +163 -0
  99. package/src/markdown-academic/toc.tsx +88 -0
  100. package/src/markdown-editor/completions/completions-menu.tsx +96 -0
  101. package/src/markdown-editor/completions/completions-prose.test.ts +356 -0
  102. package/src/markdown-editor/completions/completions-prose.ts +313 -0
  103. package/src/markdown-editor/completions/completions-widget.tsx +75 -0
  104. package/src/markdown-editor/completions/index.ts +37 -0
  105. package/src/markdown-editor/directive-nodes.ts +151 -0
  106. package/src/markdown-editor/directive-views.test.tsx +189 -0
  107. package/src/markdown-editor/directive-views.tsx +795 -0
  108. package/src/markdown-editor/exit-keymap.test.ts +88 -0
  109. package/src/markdown-editor/exit-keymap.ts +87 -0
  110. package/src/markdown-editor/index.ts +6 -0
  111. package/src/markdown-editor/markdown-editor.css +250 -0
  112. package/src/markdown-editor/markdown-editor.directives.test.tsx +105 -0
  113. package/src/markdown-editor/markdown-editor.fill.test.ts +34 -0
  114. package/src/markdown-editor/markdown-editor.paste-embed.test.tsx +297 -0
  115. package/src/markdown-editor/markdown-editor.stories.tsx +560 -0
  116. package/src/markdown-editor/markdown-editor.strictmode.test.tsx +38 -0
  117. package/src/markdown-editor/markdown-editor.table.test.tsx +287 -0
  118. package/src/markdown-editor/markdown-editor.tsx +560 -0
  119. package/src/markdown-editor/milkdown-react/editor.tsx +33 -0
  120. package/src/markdown-editor/milkdown-react/index.ts +8 -0
  121. package/src/markdown-editor/milkdown-react/types.ts +27 -0
  122. package/src/markdown-editor/milkdown-react/use-editor.ts +27 -0
  123. package/src/markdown-editor/milkdown-react/use-get-editor.ts +56 -0
  124. package/src/markdown-editor/milkdown-react/use-instance.ts +23 -0
  125. package/src/markdown-editor/paste-embed.ts +355 -0
  126. package/src/markdown-editor/slash/brand-slash-commands.test.ts +194 -0
  127. package/src/markdown-editor/slash/brand-slash-commands.ts +324 -0
  128. package/src/markdown-editor/slash/brand-slash-plugin.test.ts +254 -0
  129. package/src/markdown-editor/slash/brand-slash-plugin.ts +385 -0
  130. package/src/markdown-editor/slash/index.ts +107 -0
  131. package/src/markdown-editor/slash/insert-directive.test.ts +263 -0
  132. package/src/markdown-editor/slash/insert-directive.ts +345 -0
  133. package/src/markdown-editor/slash/monaco-slash-menu.test.tsx +198 -0
  134. package/src/markdown-editor/slash/monaco-slash-menu.tsx +356 -0
  135. package/src/markdown-editor/slash/shortcut-monaco.ts +69 -0
  136. package/src/markdown-editor/slash/shortcut.test.ts +157 -0
  137. package/src/markdown-editor/slash/shortcut.ts +57 -0
  138. package/src/markdown-editor/slash/slash-menu.stories.tsx +139 -0
  139. package/src/markdown-editor/slash/slash-menu.tsx +115 -0
  140. package/src/markdown-editor/slash/slash-scroll.test.tsx +52 -0
  141. package/src/markdown-editor/slash/slash-widget.tsx +97 -0
  142. package/src/markdown-editor/slash/source-slash-trigger.test.ts +42 -0
  143. package/src/markdown-editor/slash/source-slash-trigger.ts +46 -0
  144. package/src/markdown-editor/table-view.tsx +249 -0
  145. package/src/markdown-iteration/directive.tsx +92 -0
  146. package/src/markdown-iteration/edit-context.ts +56 -0
  147. package/src/markdown-iteration/index.ts +24 -0
  148. package/src/markdown-iteration/iteration-block.test.tsx +138 -0
  149. package/src/markdown-iteration/iteration-builder-dialog.stories.tsx +293 -0
  150. package/src/markdown-iteration/iteration-builder-dialog.tsx +312 -0
  151. package/src/markdown-iteration/iteration-builder.test.ts +252 -0
  152. package/src/markdown-iteration/iteration-builder.ts +303 -0
  153. package/src/markdown-iteration/iteration.test.ts +56 -0
  154. package/src/markdown-iteration/iteration.tsx +333 -0
  155. package/src/markdown-iteration/template-dialog.stories.tsx +63 -0
  156. package/src/markdown-iteration/template-dialog.test.tsx +104 -0
  157. package/src/markdown-iteration/template-dialog.tsx +116 -0
  158. package/src/markdown-outline/document-outline.stories.tsx +76 -0
  159. package/src/markdown-outline/document-outline.tsx +83 -0
  160. package/src/markdown-outline/index.ts +2 -0
  161. package/src/markdown-outline/markdown-outline.test.ts +49 -0
  162. package/src/markdown-outline/markdown-outline.ts +60 -0
  163. package/src/markdown-preview/code-fence.tsx +193 -0
  164. package/src/markdown-preview/index.ts +8 -0
  165. package/src/markdown-preview/markdown-preview-academic.stories.tsx +203 -0
  166. package/src/markdown-preview/markdown-preview-academic.test.tsx +257 -0
  167. package/src/markdown-preview/markdown-preview-iteration-calc.test.tsx +71 -0
  168. package/src/markdown-preview/markdown-preview-iteration-nested.test.tsx +58 -0
  169. package/src/markdown-preview/markdown-preview-iteration.stories.tsx +187 -0
  170. package/src/markdown-preview/markdown-preview-iteration.test.tsx +90 -0
  171. package/src/markdown-preview/markdown-preview-linking.test.tsx +61 -0
  172. package/src/markdown-preview/markdown-preview-transclusion.test.tsx +33 -0
  173. package/src/markdown-preview/markdown-preview.stories.tsx +108 -0
  174. package/src/markdown-preview/markdown-preview.test.tsx +411 -0
  175. package/src/markdown-preview/markdown-preview.tsx +1541 -0
  176. package/src/markdown-toolbar/index.ts +8 -0
  177. package/src/markdown-toolbar/markdown-commands.test.ts +84 -0
  178. package/src/markdown-toolbar/markdown-commands.ts +104 -0
  179. package/src/markdown-toolbar/markdown-toolbar.stories.tsx +56 -0
  180. package/src/markdown-toolbar/markdown-toolbar.tsx +263 -0
  181. package/src/markdown-workspace/focus-writing.test.ts +52 -0
  182. package/src/markdown-workspace/focus-writing.ts +38 -0
  183. package/src/markdown-workspace/index.ts +6 -0
  184. package/src/markdown-workspace/markdown-workspace.stories.tsx +688 -0
  185. package/src/markdown-workspace/markdown-workspace.test.tsx +326 -0
  186. package/src/markdown-workspace/markdown-workspace.tsx +787 -0
  187. package/src/mermaid-diagram/index.ts +1 -0
  188. package/src/mermaid-diagram/mermaid-diagram.stories.tsx +42 -0
  189. package/src/mermaid-diagram/mermaid-diagram.test.tsx +86 -0
  190. package/src/mermaid-diagram/mermaid-diagram.tsx +318 -0
  191. package/src/mermaid-diagram/mermaid-viewer.test.tsx +89 -0
  192. package/src/mermaid-diagram/mermaid-viewer.tsx +367 -0
  193. package/src/mermaid-diagram/real-parse.test.ts +42 -0
  194. package/src/mermaid-diagram/remediate.test.ts +60 -0
  195. package/src/mermaid-diagram/remediate.ts +124 -0
  196. package/src/mermaid-workspace/index.ts +1 -0
  197. package/src/mermaid-workspace/mermaid-workspace.stories.tsx +28 -0
  198. package/src/mermaid-workspace/mermaid-workspace.tsx +71 -0
  199. package/src/metric-block/index.ts +1 -0
  200. package/src/metric-block/metric-block.stories.tsx +40 -0
  201. package/src/metric-block/metric-block.tsx +14 -0
  202. package/src/monaco-workers.d.ts +10 -0
  203. package/src/prose/index.ts +14 -0
  204. package/src/prose/prose.stories.tsx +44 -0
  205. package/src/prose/prose.test.tsx +44 -0
  206. package/src/prose/prose.tsx +21 -0
  207. package/src/timeline/index.ts +18 -0
@@ -0,0 +1,702 @@
1
+ import * as react from 'react';
2
+ import { HTMLAttributes, ReactNode } from 'react';
3
+ import * as monaco from 'monaco-editor';
4
+ import { IRange } from 'monaco-editor';
5
+ import { Ctx } from '@milkdown/kit/ctx';
6
+ import { Schema, NodeType } from '@milkdown/kit/prose/model';
7
+ import { Command } from '@milkdown/kit/prose/state';
8
+
9
+ type MonacoCodeEditor = monaco.editor.IStandaloneCodeEditor;
10
+ /** A Monaco editor action (system command + optional hotkey + palette/menu entry). */
11
+ type EditorAction = monaco.editor.IActionDescriptor;
12
+ interface CodeEditorProps extends Omit<HTMLAttributes<HTMLDivElement>, "onChange" | "defaultValue"> {
13
+ /** Controlled content. Pair with `onChange`. */
14
+ value?: string;
15
+ /** Initial content for uncontrolled use. */
16
+ defaultValue?: string;
17
+ /** Fires on every edit with the full document text. */
18
+ onChange?: (value: string) => void;
19
+ /** Monaco language id (e.g. "typescript", "json"). Defaults to "typescript". */
20
+ language?: string;
21
+ /** Model path/URI — drives per-file language services + diagnostics. */
22
+ path?: string;
23
+ /** Render the editor read-only. */
24
+ readOnly?: boolean;
25
+ /** Editor height. Number → px. Defaults to "100%" (size via the parent). */
26
+ height?: number | string;
27
+ /** Passthrough Monaco construction options (merged over the defaults). */
28
+ options?: monaco.editor.IStandaloneEditorConstructionOptions;
29
+ /**
30
+ * Accessible name for the editor. Maps onto Monaco's `ariaLabel` construction
31
+ * option AND the inner screen-reader `<textarea>` (`aria-label`), so assistive
32
+ * tech announces a name. Spreading `aria-label` via `...props` only lands on the
33
+ * wrapper div and never reaches Monaco's focusable textarea — use this instead.
34
+ */
35
+ ariaLabel?: string;
36
+ /** Sets `aria-invalid` on Monaco's inner `<textarea>` to convey validity. */
37
+ ariaInvalid?: boolean;
38
+ /** Sets `aria-describedby` on Monaco's inner `<textarea>` (e.g. an error id). */
39
+ ariaDescribedBy?: string;
40
+ /**
41
+ * Right-click menu. `"brand"` (default) replaces Monaco's built-in menu with
42
+ * brand-ui's `ContextMenu`; `"monaco"` keeps Monaco's themed menu; `"none"`
43
+ * disables it.
44
+ */
45
+ contextMenu?: "brand" | "monaco" | "none";
46
+ /** Called once the editor instance + monaco namespace are ready. */
47
+ onMount?: (editor: MonacoCodeEditor, monacoApi: typeof monaco) => void;
48
+ /**
49
+ * Declarative Monaco editor actions — each registers a command (run on its
50
+ * `keybindings`, in the command palette, and optionally the context menu via
51
+ * `contextMenuGroupId`). Wraps `editor.addAction`; re-registered when the array
52
+ * identity changes, disposed on unmount. Build keybindings with the re-exported
53
+ * `monaco` namespace, e.g. `keybindings: [monaco.KeyMod.CtrlCmd | monaco.KeyCode.Slash]`.
54
+ *
55
+ * Note: a context-menu entry only shows when `contextMenu="monaco"`, but the
56
+ * keybinding and command palette work regardless. Memoize `actions` to avoid
57
+ * re-registering on every render.
58
+ */
59
+ actions?: EditorAction[];
60
+ }
61
+ /**
62
+ * A token-themed Monaco editor wrapped as a brand-ui React component. Monaco
63
+ * renders its own editing surface + widgets; this wrapper owns lifecycle,
64
+ * controlled/uncontrolled value, and applies the brand theme bridge so the
65
+ * editor matches the active `data-theme` (all three themes).
66
+ *
67
+ * Workers (for completions/diagnostics) are wired by importing
68
+ * `@elabs-ai/components-editor/monaco-environment` once at the app entry.
69
+ */
70
+ declare const CodeEditor: react.ForwardRefExoticComponent<CodeEditorProps & react.RefAttributes<monaco.editor.IStandaloneCodeEditor | null>>;
71
+
72
+ /**
73
+ * CalcBlock contracts — the shape the consumer's `evaluate` hook returns.
74
+ *
75
+ * The library RENDERS; the consumer EVALUATES. The math engine is app/domain
76
+ * logic and must NOT live in the design system — so these are pure types and the
77
+ * library never bundles a calculator (mirrors how `resolveUrl` keeps URL
78
+ * resolution in the consumer). A consumer produces a `CalcSheet` from a ```calc
79
+ * source; CalcBlock paints it.
80
+ */
81
+ type CalcValueKind = "number" | "quantity" | "currency" | "date" | "duration" | "percent" | "text" | "error";
82
+ /** A typed result value; `display` is the locale-formatted, tabular-ready string. */
83
+ interface CalcValue {
84
+ kind: CalcValueKind;
85
+ raw: number | string;
86
+ unit?: string;
87
+ display: string;
88
+ }
89
+ type CalcTokenKind = "number" | "unit" | "currency" | "operator" | "function" | "constant" | "comment" | "var-def" | "var-ref" | "line-ref" | "unknown";
90
+ /** One highlighted span within a source line — 0-based columns, `end` exclusive. */
91
+ interface CalcToken {
92
+ start: number;
93
+ end: number;
94
+ kind: CalcTokenKind;
95
+ /** `false` → a non-fatal warning style (unknown identifier / dangling ref). */
96
+ resolved: boolean;
97
+ }
98
+ /**
99
+ * Presentation hint: a rule (horizontal divider) drawn below a row — a `"dotted"`
100
+ * hairline, a `"single"` solid line, or a `"double"` line (e.g. above a subtotal).
101
+ * Pure presentation: the library renders it; the evaluator decides which rows get one.
102
+ */
103
+ type CalcRule = "dotted" | "single" | "double";
104
+ /**
105
+ * Presentation hint: tint a row's background with a semantic status wash
106
+ * (theme-safe `bg-<token>/10`, matching the house status vocabulary). `"muted"`
107
+ * is a neutral, non-status tint. The evaluator decides; the library paints.
108
+ */
109
+ type CalcTint = "primary" | "success" | "warning" | "destructive" | "info" | "muted";
110
+ /** One evaluated source line: its highlight tokens, and a value OR an error. */
111
+ interface CalcLineResult {
112
+ /** 1-based line within the calc source. */
113
+ line: number;
114
+ tokens: CalcToken[];
115
+ value?: CalcValue;
116
+ /** A per-line error rendered inline; never thrown. */
117
+ error?: {
118
+ message: string;
119
+ };
120
+ /** Presentation hint: draw a rule (divider) below this row. */
121
+ rule?: CalcRule;
122
+ /** Presentation hint: tint this row's background with a semantic wash. */
123
+ tint?: CalcTint;
124
+ }
125
+ interface CalcSheet {
126
+ results: CalcLineResult[];
127
+ /** Running total for the block. */
128
+ total?: CalcValue;
129
+ }
130
+ interface CalcContext {
131
+ docPath?: string;
132
+ }
133
+ /** The consumer-supplied evaluator (sync, like `resolveUrl`). */
134
+ type EvaluateCalc = (source: string, ctx?: CalcContext) => CalcSheet;
135
+ /**
136
+ * Tokenize ONE calc source line into highlight spans (the columns the library
137
+ * paints). Called per line, so the returned {@link CalcToken} `start`/`end`
138
+ * columns are relative to `line` — the same shape `evaluate` already returns on
139
+ * each `CalcLineResult.tokens`. Sync, like `resolveUrl`.
140
+ */
141
+ type CalcTokenize = (line: string, ctx?: CalcContext) => CalcToken[];
142
+ /** A completion category — drives the icon (Monaco) / glyph + label (WYSIWYG). */
143
+ type CalcCompletionKind = "variable" | "function" | "unit" | "currency" | "constant" | "reference" | "keyword" | "snippet";
144
+ /** One autocomplete suggestion offered inside a ```calc fence. */
145
+ interface CalcCompletion {
146
+ /** Text shown in the completion list. */
147
+ label: string;
148
+ /** Text inserted when the item is chosen (replaces the typed `prefix`). */
149
+ insert: string;
150
+ /** Secondary detail shown muted beside the label (e.g. a type or preview). */
151
+ detail?: string;
152
+ /** Category; selects the suggestion icon. Defaults to `"variable"`. */
153
+ kind?: CalcCompletionKind;
154
+ }
155
+ /** What the editor knows at the caret when it asks the consumer for completions. */
156
+ interface CalcCompletionContext extends CalcContext {
157
+ /** The full calc fence body (all lines). */
158
+ source: string;
159
+ /** The current line's text (the line the caret is on). */
160
+ line: string;
161
+ /** 1-based line of the caret within the fence body. */
162
+ lineNumber: number;
163
+ /** 0-based caret column within `line`. */
164
+ column: number;
165
+ /** The identifier characters immediately before the caret (the word typed). */
166
+ prefix: string;
167
+ }
168
+ /** Suggest completions at the caret inside a ```calc fence (sync). */
169
+ type CalcComplete = (ctx: CalcCompletionContext) => CalcCompletion[];
170
+ /**
171
+ * The opt-in authoring hooks threaded onto `MarkdownEditor` / `MarkdownWorkspace`
172
+ * via the `calc` prop (off by default). Each capability is independent:
173
+ * - `tokenize` → syntax highlighting (falls back to `evaluate`'s per-line
174
+ * `tokens` when omitted, so a consumer who already wrote `evaluate` gets
175
+ * highlighting for free).
176
+ * - `evaluate` → per-line result inlays (the computed answer, shown after the
177
+ * line). Reuses the existing {@link EvaluateCalc} contract.
178
+ * - `complete` → autocomplete inside the fence (Monaco surface).
179
+ */
180
+ interface CalcEditorHooks {
181
+ tokenize?: CalcTokenize;
182
+ complete?: CalcComplete;
183
+ evaluate?: EvaluateCalc;
184
+ }
185
+
186
+ /**
187
+ * Engine-agnostic completion-provider contract (#283) — the `completions` prop
188
+ * on `MarkdownWorkspace` (and, via it, the WYSIWYG `MarkdownEditor`).
189
+ *
190
+ * ISOLATION INVARIANT (mirrors `editor-content-access.ts`): this file imports
191
+ * NOTHING engine-specific — no `monaco-editor`, no `@milkdown`. It is the
192
+ * dependency-light leaf both engine adapters (`editor-completions-monaco.ts` for
193
+ * Monaco, `markdown-editor/completions/` for Milkdown/ProseMirror) build on, so a
194
+ * consumer can import the TYPES with zero engine imports (#283 acceptance: "zero
195
+ * `monaco-editor` imports in app code").
196
+ *
197
+ * D5 / the calc `complete` hook precedent: the library only REGISTERS the
198
+ * provider and RENDERS its suggestions — candidate list, filtering/ranking, and
199
+ * insert text are entirely consumer-owned. Nothing here fetches anything; a
200
+ * throwing/rejecting `provide()` degrades to "no suggestions" (never blanks or
201
+ * throws), the same degrade-safely contract as `resolveResults`/`CalcBlock`.
202
+ */
203
+ /** One completion candidate a provider offers at the caret. */
204
+ interface EditorCompletionItem {
205
+ /** Text shown in the suggestion list. */
206
+ label: string;
207
+ /** Text inserted when the item is chosen. */
208
+ insertText: string;
209
+ /** Secondary detail shown muted beside the label. */
210
+ detail?: string;
211
+ /**
212
+ * Start column (1-based, Monaco convention) of the already-typed token to
213
+ * replace. Defaults to the start of the "trigger query" — the run of text
214
+ * typed since the provider's trigger character (see {@link triggerQueryStart}).
215
+ */
216
+ replaceFrom?: number;
217
+ }
218
+ /** What a provider knows at the caret when it is asked for completions. */
219
+ interface EditorCompletionContext {
220
+ /** The full document text. */
221
+ source: string;
222
+ /** 1-based line number. */
223
+ line: number;
224
+ /** 1-based column. */
225
+ column: number;
226
+ /** The full text of the current line. */
227
+ lineText: string;
228
+ }
229
+ /**
230
+ * A declarative completion source. Registered ONCE per `MarkdownWorkspace` (or
231
+ * `MarkdownEditor`) tree via the `completions` prop — the library owns the
232
+ * engine registration lifecycle (Monaco's `registerCompletionItemProvider` is
233
+ * global-per-language, refcounted here; see `editor-completions-monaco.ts`).
234
+ */
235
+ interface EditorCompletionProvider {
236
+ /** Stable id — surfaced for consumer bookkeeping (not currently rendered). */
237
+ id: string;
238
+ /** Characters that (re)open the suggestion list, e.g. `["["]`. */
239
+ triggerCharacters?: string[];
240
+ /** Return the candidates for the caret described by `ctx`. May be async. */
241
+ provide(ctx: EditorCompletionContext): EditorCompletionItem[] | Promise<EditorCompletionItem[]>;
242
+ }
243
+ /**
244
+ * Find the 1-based column right after the LAST occurrence, before `column`, of
245
+ * any of `triggerCharacters` in `lineText` — the start of the "trigger query"
246
+ * (the text typed since the trigger character). `null` when no trigger
247
+ * character precedes the caret on this line (falls back to inserting at the
248
+ * bare caret — see {@link resolveReplaceRange}).
249
+ *
250
+ * Deliberately the LAST occurrence, not the first: `[[note` (triggerCharacters
251
+ * `["["]`) resolves the query start to right after the SECOND `[`, so the
252
+ * inserted text replaces only `note`, preserving the `[[` the user typed.
253
+ */
254
+ declare function triggerQueryStart(lineText: string, column: number, triggerCharacters: string[] | undefined): number | null;
255
+ /** A 1-based, Monaco-`IRange`-shaped span (structural — no monaco import). */
256
+ interface CompletionReplaceRange {
257
+ startLineNumber: number;
258
+ startColumn: number;
259
+ endLineNumber: number;
260
+ endColumn: number;
261
+ }
262
+ /**
263
+ * Resolve the range an item's `insertText` replaces: `item.replaceFrom` when
264
+ * given, else the trigger-query start (see {@link triggerQueryStart}), else the
265
+ * bare caret (a pure insert, nothing replaced). Always ends at the caret, on
266
+ * the caret's line — a completion never spans multiple lines.
267
+ */
268
+ declare function resolveReplaceRange(item: EditorCompletionItem, position: {
269
+ lineNumber: number;
270
+ column: number;
271
+ }, lineText: string, triggerCharacters: string[] | undefined): CompletionReplaceRange;
272
+ /** One resolved completion item, paired with the provider that produced it. */
273
+ interface CompletionMatch {
274
+ provider: EditorCompletionProvider;
275
+ item: EditorCompletionItem;
276
+ }
277
+ /**
278
+ * Call every provider's `provide(ctx)`, collect the results, and pair each item
279
+ * back with its provider (so a caller can resolve a per-provider replace range
280
+ * via that provider's `triggerCharacters`). Never throws: a provider whose
281
+ * `provide()` throws or whose returned promise rejects contributes zero items
282
+ * (mirrors `resolveResults`'s calc-hook degrade-safely contract) — one bad
283
+ * provider never blanks another's suggestions.
284
+ */
285
+ declare function collectCompletions(providers: EditorCompletionProvider[], ctx: EditorCompletionContext): Promise<CompletionMatch[]>;
286
+
287
+ /**
288
+ * Engine-agnostic editor content-access interface + Monaco adapter.
289
+ *
290
+ * ISOLATION INVARIANT: this file imports ONLY `monaco-editor` and the
291
+ * `MonacoCodeEditor` type from `../code-editor`. It MUST NOT import
292
+ * `editor-content-access-prose.ts` or anything from `@milkdown`, or the
293
+ * `@milkdown` graph leaks into the `.` barrel (#271-inverse).
294
+ */
295
+
296
+ /** A snapshot of the editor's current selection. Text, not engine positions —
297
+ * that is what an AI assistant needs and it keeps the interface engine-agnostic. */
298
+ interface EditorSelection {
299
+ /**
300
+ * The selected text. Plain text for Monaco. For the Milkdown WYSIWYG it is the
301
+ * selection SERIALIZED TO MARKDOWN by default (so `**bold**`, links, lists round-trip);
302
+ * pass `{ fidelity: "plainText" }` to the adapter to get `doc.textBetween` instead.
303
+ */
304
+ text: string;
305
+ /** `true` when the selection is collapsed (a bare caret, nothing highlighted). */
306
+ empty: boolean;
307
+ }
308
+ /**
309
+ * Engine-agnostic, text-oriented access to an editor's content + selection — the
310
+ * uniform surface an external AI assistant drives across the Monaco code editors
311
+ * AND the Milkdown WYSIWYG markdown editor.
312
+ *
313
+ * D5: this manipulates EDITOR CONTENT only. It performs no model calls, no transport,
314
+ * no fetch. The app owns the AI call and APPLIES the result via these methods.
315
+ *
316
+ * `replaceSelection` and `insertAtCursor` are equivalent primitives (both replace the
317
+ * active range; an empty range is the caret) — two names for two reader intents.
318
+ */
319
+ interface EditorContentAccess {
320
+ /** The full document text (Monaco: source; Milkdown: serialized markdown). */
321
+ getText(): string;
322
+ /** A snapshot of the current selection (selected text + whether collapsed). */
323
+ getSelection(): EditorSelection;
324
+ /** Replace the current selection; a collapsed selection inserts at the caret. */
325
+ replaceSelection(text: string): void;
326
+ /**
327
+ * Insert at the caret; a non-empty selection is replaced (platform "typing" semantics).
328
+ * Equivalent to `replaceSelection` — two names for two reader intents (agent-legibility).
329
+ */
330
+ insertAtCursor(text: string): void;
331
+ /** Move focus to the editing surface (so the user can keep typing after an apply). */
332
+ focus(): void;
333
+ /**
334
+ * Subscribe to selection changes. Fires with a fresh `EditorSelection` whenever the
335
+ * selection or caret moves. Returns an unsubscribe function — the caller MUST call it
336
+ * (e.g. in a React effect cleanup) to dispose the underlying engine listener.
337
+ */
338
+ onSelectionChange(listener: (selection: EditorSelection) => void): () => void;
339
+ }
340
+ /**
341
+ * Wrap a live Monaco `IStandaloneCodeEditor` as the engine-agnostic
342
+ * {@link EditorContentAccess}. The `CodeEditor` / `DiffEditor` / `CodeWorkspace`
343
+ * `ref` already exposes the raw Monaco instance — pass it here to get the
344
+ * uniform shape used by the markdown surfaces.
345
+ *
346
+ * For a `DiffEditor`, pass the modified (editable) side:
347
+ * `monacoContentAccess(diffRef.current!.getModifiedEditor())`.
348
+ *
349
+ * @example
350
+ * const editorRef = useRef<MonacoCodeEditor>(null);
351
+ * // ...later
352
+ * const access = monacoContentAccess(editorRef.current!);
353
+ * access.insertAtCursor(aiText);
354
+ */
355
+ declare function monacoContentAccess(editor: MonacoCodeEditor): EditorContentAccess;
356
+
357
+ /**
358
+ * paste-embed — ProseMirror plugin + helper for image paste/drop embedding.
359
+ *
360
+ * When `onEmbedAsset` is provided by the host:
361
+ * 1. Intercepts paste (from clipboard) or drop events carrying image files.
362
+ * 2. Inserts an inline "uploading…" widget Decoration at the caret/drop position.
363
+ * 3. Calls `onEmbedAsset(file)` and on resolve inserts a real image node, removing
364
+ * the placeholder.
365
+ * 4. On reject removes the placeholder and renders a transient inline error
366
+ * decoration (role="alert", auto-dismissed after 4 s) + toast.error().
367
+ *
368
+ * The plugin is a raw `$prose` ProseMirror plugin (same pattern as the slash menu),
369
+ * so it pulls zero new dependencies beyond what Milkdown already provides.
370
+ *
371
+ * A11y:
372
+ * - Upload placeholder: role="status" aria-live="polite"
373
+ * - Error decoration: role="alert" (assertive; fires once and auto-dismisses)
374
+ *
375
+ * Motion: gated via `duration-normal ease-standard motion-reduce:transition-none`
376
+ * token utilities (defined in @elabs-ai/components-tokens).
377
+ */
378
+
379
+ /** The host-provided hook: receives a File, resolves to a URL/path string. */
380
+ type EmbedAssetFn = (file: File) => Promise<string>;
381
+
382
+ interface IterationEditRequest {
383
+ /** Which directive asked to be edited. */
384
+ kind: "iterate" | "pivot";
385
+ /** The current template markdown (the node body, serialized). */
386
+ template: string;
387
+ /** Apply the edited template back to the node. */
388
+ onSave: (template: string) => void;
389
+ /**
390
+ * The directive's current attributes (value lists, bind name, layout) — present
391
+ * when the node-view supports GUIDED re-editing (A5). The
392
+ * `IterationBuilderProvider` reads these to reopen the builder with its data;
393
+ * the template-only `IterationTemplateProvider` ignores them.
394
+ */
395
+ attributes?: Record<string, string>;
396
+ /**
397
+ * Write back BOTH the attributes and the template (the guided builder path). When
398
+ * present it is preferred over {@link onSave} (which only rewrites the body).
399
+ */
400
+ onSaveData?: (next: {
401
+ attributes: Record<string, string>;
402
+ template: string;
403
+ }) => void;
404
+ /**
405
+ * Directly rewrite the node's attributes (e.g. the node-menu's "Change layout" /
406
+ * "Transpose" actions) without touching the template body. Additive (#223) —
407
+ * present alongside {@link onSave}/{@link onSaveData} for back-compat; a
408
+ * consumer-side surface (a future dialog action) can reach the same write the
409
+ * node-view's own menu uses.
410
+ */
411
+ onSetAttributes?: (attributes: Record<string, string>) => void;
412
+ /**
413
+ * Replace the ENTIRE directive node with plain markdown — e.g. the node-menu's
414
+ * "Convert to static" action (the evaluated, populated result). After this the
415
+ * node stops being a `:::iterate`/`:::pivot` directive. Additive (#223).
416
+ */
417
+ onReplaceWithMarkdown?: (markdown: string) => void;
418
+ }
419
+ /** A consumer handler that opens the template editor for a request. */
420
+ type IterationEditHandler = (request: IterationEditRequest) => void;
421
+ /** Provide a handler to enable the node-view `⋯` re-edit affordance. */
422
+ declare const IterationEditContext: react.Context<IterationEditHandler | null>;
423
+
424
+ /**
425
+ * Pure ProseMirror insertion commands for the slash menu.
426
+ *
427
+ * The load-bearing logic of the slash menu lives here, deliberately decoupled
428
+ * from Milkdown's context and from React: an `insertBrandDirective` factory that
429
+ * builds the right `brand_container_directive` / `brand_leaf_directive` node (from
430
+ * the schemas in `directive-nodes.ts`) with sensible default attrs + a placeholder
431
+ * body, replaces the active slash range (or inserts at the cursor), and drops the
432
+ * caret into the first editable field. Because it takes the NodeTypes/Schema as
433
+ * arguments (not a Milkdown `Ctx`), it is unit-testable against a hand-built
434
+ * ProseMirror state and its output round-trips losslessly through the editor's
435
+ * existing `toMarkdown` runners (asserted in insert-directive.test.ts).
436
+ *
437
+ * `resolveBrandInsert` is the thin Milkdown-aware adapter: it reads the NodeTypes
438
+ * from the editor `Ctx` and returns the same pure command — so the slash plugin
439
+ * and any direct caller share one implementation.
440
+ */
441
+
442
+ /** A `[from, to)` document range to replace (the typed `/query`), or `null`. */
443
+ interface SlashRange {
444
+ from: number;
445
+ to: number;
446
+ }
447
+ /** The directive names the slash menu can insert as brand blocks. */
448
+ type InsertableDirective = "card" | "callout" | "timeline" | "metric" | "iterate" | "pivot";
449
+ /**
450
+ * The pure insertion command. Builds the directive node from the given
451
+ * NodeTypes + schema and replaces `range` (or the current selection when
452
+ * `range` is null), then positions the caret in the first editable field
453
+ * (the body's start for containers; just after the atomic leaf for metric).
454
+ *
455
+ * Returns a ProseMirror `Command` `(state, dispatch?) => boolean`.
456
+ */
457
+ declare function insertBrandDirective(name: InsertableDirective, containerType: NodeType, leafType: NodeType, schema: Schema, range: SlashRange | null): Command;
458
+ /** Map a basic-block id to a ProseMirror command that inserts the native node. */
459
+ declare function insertBasicBlock(id: BasicBlockId, schema: Schema, range: SlashRange | null): Command;
460
+ /** Seed body for a fresh ```calc fence — a tiny ledger so highlight + inlays show at once. */
461
+ declare const CALC_FENCE_SEED: string;
462
+ /**
463
+ * Insert a ```calc fence (a `code_block` with `language: "calc"`) seeded with a
464
+ * short example, then drop the caret into the body. The editor's calc layer
465
+ * (`calc-editor-prose`) highlights + adds result inlays once `calc` hooks are wired;
466
+ * with none it is just a fenced code block (and renders as a `CalcBlock` in preview
467
+ * when `evaluate` is supplied) — so inserting one is always safe.
468
+ */
469
+ declare function insertCalcFence(schema: Schema, range: SlashRange | null, seed?: string): Command;
470
+ /** Milkdown-aware adapter for {@link insertCalcFence}. */
471
+ declare function resolveCalcInsert(ctx: Ctx, range: SlashRange | null): boolean;
472
+
473
+ /**
474
+ * The brand slash-command registry — pure, typed, tree-shakeable data.
475
+ *
476
+ * Each command is a label + group + match keywords + an icon + a `run` that
477
+ * inserts the corresponding block at the caret. `run` is given a
478
+ * {@link SlashInsertContext} (the Milkdown `Ctx` + the active `/query` range);
479
+ * brand directives delegate to `resolveBrandInsert`, basic blocks to
480
+ * `resolveBasicInsert` — so the SAME registry drives the menu and any
481
+ * programmatic insert, and the load-bearing insertion logic stays in
482
+ * `insert-directive.ts` (unit-tested there).
483
+ *
484
+ * Defaults: card · callout · metric · timeline ("Brand blocks") +
485
+ * heading · bullet-list · ordered-list · quote · code · divider ("Basic").
486
+ * Consumers can extend or replace the list via the `slashMenu` prop.
487
+ *
488
+ * `runInSource` (#299) is an OPTIONAL, ADDITIVE second handler for the Monaco
489
+ * source pane — `run` (Milkdown) stays untouched, so the 12 default commands
490
+ * need zero migration. `MonacoCodeEditor` / `IRange` / `EditorContentAccess`
491
+ * below are TYPE-ONLY imports (erased at build) — this file stays free of any
492
+ * `monaco-editor` RUNTIME import, so the Milkdown-facing `slash/index.ts`
493
+ * barrel this file feeds still pulls zero Monaco code.
494
+ */
495
+
496
+ /** The native (non-directive) blocks the slash menu can insert. */
497
+ type BasicBlockId = "heading" | "bullet-list" | "ordered-list" | "quote" | "code" | "divider";
498
+ /**
499
+ * Context handed to a {@link SlashCommand.run}. `ctx` is the live Milkdown editor
500
+ * context; `range` is the `[from, to)` document range of the typed trigger +
501
+ * query (so the command replaces it), or `null` to insert at the caret.
502
+ */
503
+ interface SlashInsertContext {
504
+ ctx: Ctx;
505
+ range: SlashRange | null;
506
+ }
507
+ /**
508
+ * Context handed to a {@link SlashCommand.runInSource} (#299) — the Monaco
509
+ * SOURCE-pane counterpart to {@link SlashInsertContext}. By the time this runs,
510
+ * the typed `/query` trigger has already been stripped from the document (the
511
+ * same edit `cancel` uses), so the handler starts from a clean doc.
512
+ */
513
+ interface SourceSlashContext {
514
+ /** The raw Monaco editor instance — full imperative access when needed. */
515
+ editor: MonacoCodeEditor;
516
+ /**
517
+ * Model range the typed `/query` trigger occupied (already removed by the
518
+ * time this fires) — `null` on the hotkey path, where no `/` was ever typed.
519
+ */
520
+ range: IRange | null;
521
+ /** Engine-agnostic content access (get/replace-selection/insert-at-cursor). */
522
+ content: EditorContentAccess;
523
+ }
524
+ /** One entry in the slash menu. Pure data + an insertion `run`. */
525
+ interface SlashCommand {
526
+ /** Stable id (used as the React key + `aria-activedescendant` target). */
527
+ id: string;
528
+ /** Visible label, e.g. "Card". */
529
+ label: string;
530
+ /** Grouping header, e.g. "Brand blocks" | "Basic". */
531
+ group?: string;
532
+ /** A short description shown under the label. */
533
+ description?: string;
534
+ /** Extra fuzzy-match aids beyond the label (matched case-insensitively). */
535
+ keywords?: string[];
536
+ /** Leading icon (a Lucide glyph or any node). */
537
+ icon?: ReactNode;
538
+ /**
539
+ * Markdown SNIPPET the source / split toolbar's Insert menu inserts (text mode).
540
+ * Optional: commands without one — the basic blocks, which already have their
541
+ * own toolbar buttons — don't appear in that menu. Brand blocks set this so the
542
+ * source toolbar inserts the SAME directive / fence the WYSIWYG `run` builds, so
543
+ * the two surfaces stay at parity. (A4)
544
+ */
545
+ snippet?: string;
546
+ /** Insert the block at the caret. WYSIWYG (Milkdown) — UNCHANGED (#299). */
547
+ run: (ctx: SlashInsertContext) => void;
548
+ /**
549
+ * OPTIONAL source-pane (Monaco) handler (#299) — for a RUN-ONLY command (no
550
+ * `snippet`, e.g. an "Ask AI" entry) that can't express itself as a markdown
551
+ * insert. When present, selecting the command in the Monaco source-pane menu
552
+ * (`MonacoSlashMenu`) strips the typed `/query` first, then calls this with
553
+ * the live editor + the (now-stripped) trigger range + engine-agnostic
554
+ * content access — instead of the `snippet`-only `commitSnippet` fallback. A
555
+ * command needs only ONE of `snippet` / `runInSource` to appear in source (both
556
+ * is fine too — `runInSource` wins there since it's the more capable handler).
557
+ */
558
+ runInSource?: (ctx: SourceSlashContext) => void;
559
+ /**
560
+ * OPTIONAL guided variant (#223, WYSIWYG only). When present AND the
561
+ * consumer has wired an `IterationEditContext` handler (an
562
+ * `IterationBuilderProvider` / `IterationTemplateProvider` above the
563
+ * editor), this REPLACES `run` — it opens the guided modal seeded blank
564
+ * instead of inserting a bare directive. Falls back to `run` when no
565
+ * handler is available, so the 12 non-guided default commands need zero
566
+ * changes. Set on the `iterate` / `pivot` commands only.
567
+ */
568
+ guided?: (insert: SlashInsertContext, handler: IterationEditHandler) => void;
569
+ }
570
+ /**
571
+ * The default command list. Brand blocks first (the wedge), then the basics.
572
+ * The brand-block icons reuse the `data-brand-directive` chrome look via Lucide
573
+ * stand-ins (the editor renders the real component once inserted).
574
+ */
575
+ declare const BRAND_SLASH_COMMANDS: SlashCommand[];
576
+ /**
577
+ * Filter a command list by a query (case-insensitive substring over label +
578
+ * keywords). An empty query returns the full list (in registry order).
579
+ */
580
+ declare function filterSlashCommands(commands: SlashCommand[], query: string): SlashCommand[];
581
+ /** Preserve registry order while grouping; used by the menu to render headers. */
582
+ declare function groupSlashCommands(commands: SlashCommand[]): {
583
+ group: string;
584
+ commands: SlashCommand[];
585
+ }[];
586
+
587
+ /**
588
+ * Imperative handle exposed via `ref`.
589
+ *
590
+ * Extends {@link EditorContentAccess} so any consumer of a `MarkdownEditor`
591
+ * ref can drive AI editing operations (insert, replace, subscribe to selection)
592
+ * through the engine-agnostic interface, alongside the markdown-specific helpers.
593
+ *
594
+ * `getText()` is an alias for `getMarkdown()` (same output; both return the full
595
+ * document serialized to markdown). The duplication is intentional: `getText`
596
+ * satisfies the `EditorContentAccess` interface contract; `getMarkdown` is the
597
+ * historically-named markdown-specific method. JSDoc notes the equivalence.
598
+ */
599
+ interface MarkdownEditorHandle extends EditorContentAccess {
600
+ /**
601
+ * Serialize the current document to a markdown string.
602
+ * Equivalent to `getText()` — both return the full document as markdown.
603
+ */
604
+ getMarkdown: () => string;
605
+ /**
606
+ * Serialize the current document, or `null` while the engine is still
607
+ * booting. Used to capture the pre-edit normalization BASELINE for the
608
+ * lossless-edit merge (WI-1) — unlike `getMarkdown` it never falls back to
609
+ * the raw input, so a non-null result is always the editor's own output.
610
+ */
611
+ serialized: () => string | null;
612
+ /**
613
+ * Best-effort: scroll the heading whose outline slug matches into view (#273).
614
+ * Walks the ProseMirror doc for `heading` nodes, slugifies their text with the
615
+ * same algorithm as `parseMarkdownOutline`, and scrolls the first match into
616
+ * view. No-op (never throws) while the engine is booting or if no match.
617
+ */
618
+ scrollToHeading: (slug: string) => void;
619
+ /**
620
+ * Best-effort: scroll toward FULL-SOURCE 1-based `line` by resolving the
621
+ * nearest preceding heading in the ProseMirror doc (no exact source map in
622
+ * WYSIWYG — Milkdown keeps no `data-sourcepos`). No-op when no preceding
623
+ * heading is found or while booting. (#273)
624
+ *
625
+ * For precise navigation, prefer `scrollToHeading(slug)` — the workspace
626
+ * resolves the slug from the line via `parseMarkdownOutline` + `fmOffset`
627
+ * before forwarding here.
628
+ */
629
+ revealLine: (line: number, opts?: {
630
+ center?: boolean;
631
+ }) => void;
632
+ }
633
+ interface MarkdownEditorProps extends Omit<HTMLAttributes<HTMLDivElement>, "onChange" | "defaultValue"> {
634
+ /** Controlled markdown value. Pair with `onChange`. */
635
+ value?: string;
636
+ /** Initial markdown for uncontrolled use. */
637
+ defaultValue?: string;
638
+ /** Fires on every edit with the full markdown document. */
639
+ onChange?: (markdown: string) => void;
640
+ /** Render the editor read-only (still selectable, not editable). */
641
+ readOnly?: boolean;
642
+ /**
643
+ * Accessible name for the editable surface. Milkdown/ProseMirror renders an ARIA
644
+ * `textbox` (`contenteditable`); without a name, screen readers announce an
645
+ * unlabeled field. Set onto the ProseMirror view's `attributes`. Default
646
+ * `"Markdown editor"`.
647
+ */
648
+ ariaLabel?: string;
649
+ /**
650
+ * Enable the `/` command menu (insert brand `:::` directives + basic blocks
651
+ * live at the caret). `true` (default) uses the built-in
652
+ * {@link BRAND_SLASH_COMMANDS}; pass a `commands` array to extend/replace them,
653
+ * or `false` to disable. The `trigger` defaults to `"/"`.
654
+ *
655
+ * Pass `shortcut` (default `"Mod-Shift-O"`) to control the keyboard shortcut that
656
+ * opens the menu at the caret without typing the trigger character — works in
657
+ * BOTH the WYSIWYG pane and the Monaco source pane (#271).
658
+ */
659
+ slashMenu?: boolean | {
660
+ commands?: SlashCommand[];
661
+ trigger?: string;
662
+ shortcut?: string;
663
+ };
664
+ /**
665
+ * Opt-in calc authoring inside ```calc fences (off by default). Supply the
666
+ * consumer's hooks — `tokenize` (highlight), `evaluate` (result inlays), and/or
667
+ * `complete` (autocomplete; Monaco surface). The library DECORATES, the consumer
668
+ * COMPUTES — no calc engine is bundled. Mirrors `MarkdownPreview`'s `evaluate`.
669
+ */
670
+ calc?: CalcEditorHooks;
671
+ /**
672
+ * Declarative completion providers (#283) — e.g. `[[wikilink]]` autocomplete.
673
+ * Off by default; mirrors the `slashMenu`/`calc` opt-in pattern. Each provider
674
+ * registers a `triggerCharacters` set + a `provide(ctx)` that returns
675
+ * candidates; the library owns detecting the trigger and rendering/inserting.
676
+ *
677
+ * This is a DELIBERATELY MINIMAL, best-effort mirror of the Monaco source-pane
678
+ * behavior (see `markdown-editor/completions/completions-prose.ts` for the
679
+ * exact gaps — no real cross-block line/column, a plain listbox instead of a
680
+ * native suggest widget). Forwarded from `MarkdownWorkspace`'s `completions`
681
+ * prop, which also wires the FULL Monaco/source-pane path.
682
+ */
683
+ completions?: EditorCompletionProvider[];
684
+ /**
685
+ * Host-provided callback for image paste/drop embedding.
686
+ *
687
+ * When set, the editor intercepts paste and drop events that contain image
688
+ * files, shows an inline "uploading…" placeholder, calls this function with
689
+ * the `File`, and on resolve inserts `![filename](returnedPath)` in the
690
+ * document. On reject the placeholder is removed and an inline error chip
691
+ * (+ toast) is shown — the document never contains a broken image.
692
+ *
693
+ * If not set, the editor's default paste/drop behavior is unchanged.
694
+ *
695
+ * The library NEVER stores assets — all persistence is the host's responsibility.
696
+ */
697
+ onEmbedAsset?: EmbedAssetFn;
698
+ }
699
+
700
+ declare const MarkdownEditor: react.ForwardRefExoticComponent<MarkdownEditorProps & react.RefAttributes<MarkdownEditorHandle>>;
701
+
702
+ export { type CalcValueKind as A, BRAND_SLASH_COMMANDS as B, CodeEditor as C, type CompletionMatch as D, type EditorContentAccess as E, type CompletionReplaceRange as F, type EditorCompletionContext as G, type EditorCompletionItem as H, type IterationEditHandler as I, type InsertableDirective as J, IterationEditContext as K, type IterationEditRequest as L, type MonacoCodeEditor as M, type SlashInsertContext as N, type SlashRange as O, type SourceSlashContext as P, collectCompletions as Q, filterSlashCommands as R, type SlashCommand as S, groupSlashCommands as T, insertBasicBlock as U, insertBrandDirective as V, insertCalcFence as W, resolveCalcInsert as X, resolveReplaceRange as Y, triggerQueryStart as Z, type CodeEditorProps as a, type EditorAction as b, type EditorSelection as c, type EmbedAssetFn as d, MarkdownEditor as e, type MarkdownEditorHandle as f, type MarkdownEditorProps as g, type EditorCompletionProvider as h, type CalcEditorHooks as i, type EvaluateCalc as j, type CalcValue as k, type CalcTokenKind as l, monacoContentAccess as m, type BasicBlockId as n, CALC_FENCE_SEED as o, type CalcComplete as p, type CalcCompletion as q, type CalcCompletionContext as r, type CalcCompletionKind as s, type CalcContext as t, type CalcLineResult as u, type CalcRule as v, type CalcSheet as w, type CalcTint as x, type CalcToken as y, type CalcTokenize as z };