@mieweb/ui 0.11.0-dev.45 → 0.11.0-dev.46
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{EncounterMdyEditor-L7RBLE7B.js → EncounterMdyEditor-ATNWXQ72.js} +3 -3
- package/dist/{EncounterMdyEditor-L7RBLE7B.js.map → EncounterMdyEditor-ATNWXQ72.js.map} +1 -1
- package/dist/{EncounterMdyEditor-46WMYRFI.cjs → EncounterMdyEditor-XA7HLLVD.cjs} +6 -6
- package/dist/{EncounterMdyEditor-46WMYRFI.cjs.map → EncounterMdyEditor-XA7HLLVD.cjs.map} +1 -1
- package/dist/{chunk-UQAWXY6R.js → chunk-2D6TFO2Y.js} +3 -3
- package/dist/{chunk-UQAWXY6R.js.map → chunk-2D6TFO2Y.js.map} +1 -1
- package/dist/{chunk-NCG7NJAW.cjs → chunk-5O54NWAL.cjs} +83 -9
- package/dist/chunk-5O54NWAL.cjs.map +1 -0
- package/dist/{chunk-XX6PNPF2.cjs → chunk-5UKGOBCZ.cjs} +16 -2
- package/dist/chunk-5UKGOBCZ.cjs.map +1 -0
- package/dist/{chunk-HOE2U27V.cjs → chunk-6I2G26AX.cjs} +11 -7
- package/dist/chunk-6I2G26AX.cjs.map +1 -0
- package/dist/{chunk-OJ2NCQ2R.cjs → chunk-BUM72SAI.cjs} +28 -10
- package/dist/chunk-BUM72SAI.cjs.map +1 -0
- package/dist/{chunk-TNRANQVI.cjs → chunk-CFT3P5KP.cjs} +2 -2
- package/dist/{chunk-TNRANQVI.cjs.map → chunk-CFT3P5KP.cjs.map} +1 -1
- package/dist/{chunk-IKHK4GTF.cjs → chunk-F6ZTKNAL.cjs} +4 -4
- package/dist/{chunk-IKHK4GTF.cjs.map → chunk-F6ZTKNAL.cjs.map} +1 -1
- package/dist/{chunk-AQBZEN43.js → chunk-IYXZ25E6.js} +26 -8
- package/dist/chunk-IYXZ25E6.js.map +1 -0
- package/dist/{chunk-X6THHGTZ.cjs → chunk-LE3HZ7MM.cjs} +11 -11
- package/dist/{chunk-X6THHGTZ.cjs.map → chunk-LE3HZ7MM.cjs.map} +1 -1
- package/dist/{chunk-XZ65FX6T.js → chunk-N6STVVB6.js} +2 -2
- package/dist/{chunk-XZ65FX6T.js.map → chunk-N6STVVB6.js.map} +1 -1
- package/dist/{chunk-5WA6IYZD.js → chunk-NB2C6FSI.js} +16 -2
- package/dist/chunk-NB2C6FSI.js.map +1 -0
- package/dist/{chunk-VOPRL4RF.js → chunk-QJ75ZMCG.js} +3 -3
- package/dist/{chunk-VOPRL4RF.js.map → chunk-QJ75ZMCG.js.map} +1 -1
- package/dist/{chunk-NIE3WBJH.js → chunk-ULKDK6W6.js} +83 -9
- package/dist/chunk-ULKDK6W6.js.map +1 -0
- package/dist/{chunk-MQSGJB2B.js → chunk-WI35L5TR.js} +8 -4
- package/dist/chunk-WI35L5TR.js.map +1 -0
- package/dist/components/EmailEditor/index.cjs +14 -14
- package/dist/components/EmailEditor/index.js +5 -5
- package/dist/components/RichTextEditor/index.cjs +4 -4
- package/dist/components/RichTextEditor/index.js +1 -1
- package/dist/components/Textarea/index.cjs +7 -7
- package/dist/components/Textarea/index.js +4 -4
- package/dist/esheet.cjs +19 -19
- package/dist/esheet.js +6 -6
- package/dist/index.cjs +62 -62
- package/dist/index.js +10 -10
- package/dist/kerebron.cjs +6 -6
- package/dist/kerebron.d.cts +27 -2
- package/dist/kerebron.d.ts +27 -2
- package/dist/kerebron.js +3 -3
- package/dist/styles.css +1 -1
- package/dist/tailwind-preset.cjs +4 -4
- package/dist/tailwind-preset.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-5WA6IYZD.js.map +0 -1
- package/dist/chunk-AQBZEN43.js.map +0 -1
- package/dist/chunk-HOE2U27V.cjs.map +0 -1
- package/dist/chunk-MQSGJB2B.js.map +0 -1
- package/dist/chunk-NCG7NJAW.cjs.map +0 -1
- package/dist/chunk-NIE3WBJH.js.map +0 -1
- package/dist/chunk-OJ2NCQ2R.cjs.map +0 -1
- package/dist/chunk-XX6PNPF2.cjs.map +0 -1
|
@@ -10,37 +10,97 @@ import { jsxs, jsx } from 'react/jsx-runtime';
|
|
|
10
10
|
// src/components/RichEditor/mdyTransaction.ts
|
|
11
11
|
var MDY_PROJECTION_META = "mdyProjectionRefresh";
|
|
12
12
|
var unsafeExtensions = ["autocomplete", "hover"];
|
|
13
|
+
function fixShortcodeRoundTrip(extensions) {
|
|
14
|
+
for (const item of extensions) {
|
|
15
|
+
if (!item || typeof item !== "object") continue;
|
|
16
|
+
const extension = item;
|
|
17
|
+
if (extension.name === "shortcode_inline" && typeof extension.getNodeSpec === "function") {
|
|
18
|
+
const stockSpec = extension.getNodeSpec.bind(extension);
|
|
19
|
+
extension.getNodeSpec = () => ({
|
|
20
|
+
...stockSpec(),
|
|
21
|
+
parseDOM: [
|
|
22
|
+
{
|
|
23
|
+
tag: "span.kb-shortcode-inline",
|
|
24
|
+
getAttrs: (dom) => {
|
|
25
|
+
const text = dom.textContent ?? "";
|
|
26
|
+
const match = /^\{\{([^}]+)\}\}$/.exec(text);
|
|
27
|
+
return { content: match ? match[1] : text || null };
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
],
|
|
31
|
+
toDOM: (node) => [
|
|
32
|
+
"span",
|
|
33
|
+
{ class: "kb-shortcode-inline" },
|
|
34
|
+
node.attrs.content ? `{{${String(node.attrs.content)}}}` : ""
|
|
35
|
+
]
|
|
36
|
+
});
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
if (Array.isArray(extension.requires)) {
|
|
40
|
+
fixShortcodeRoundTrip(extension.requires);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
function dropNamedExtensions(extensions, names) {
|
|
45
|
+
const kept = extensions.filter(
|
|
46
|
+
(item) => !(item && typeof item === "object" && "name" in item && names.includes(item.name))
|
|
47
|
+
);
|
|
48
|
+
for (const item of kept) {
|
|
49
|
+
if (!item || typeof item !== "object") continue;
|
|
50
|
+
const extension = item;
|
|
51
|
+
if (Array.isArray(extension.requires)) {
|
|
52
|
+
extension.requires = dropNamedExtensions(extension.requires, names);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return kept;
|
|
56
|
+
}
|
|
13
57
|
var SafeAdvancedEditorKit = class {
|
|
14
|
-
constructor(forCollab, mediaUpload, modifyMenu) {
|
|
58
|
+
constructor(forCollab, mediaUpload, modifyMenu, omitExtensions) {
|
|
15
59
|
this.forCollab = forCollab;
|
|
16
60
|
this.mediaUpload = mediaUpload;
|
|
17
61
|
this.modifyMenu = modifyMenu;
|
|
62
|
+
this.omitExtensions = omitExtensions;
|
|
18
63
|
}
|
|
19
64
|
forCollab;
|
|
20
65
|
mediaUpload;
|
|
21
66
|
modifyMenu;
|
|
67
|
+
omitExtensions;
|
|
22
68
|
name = "advanced-editor";
|
|
23
69
|
getExtensions() {
|
|
24
70
|
const dropped = [...unsafeExtensions];
|
|
25
71
|
if (this.forCollab) dropped.push("history");
|
|
26
72
|
if (this.mediaUpload) dropped.push("mediaUpload");
|
|
27
73
|
if (this.modifyMenu) dropped.push("customMenu");
|
|
28
|
-
|
|
74
|
+
let extensions = new AdvancedEditorKit().getExtensions().filter(
|
|
29
75
|
(extension) => !("name" in extension && dropped.includes(extension.name))
|
|
30
76
|
);
|
|
77
|
+
if (this.omitExtensions?.length) {
|
|
78
|
+
extensions = dropNamedExtensions(
|
|
79
|
+
extensions,
|
|
80
|
+
this.omitExtensions
|
|
81
|
+
);
|
|
82
|
+
}
|
|
31
83
|
if (this.modifyMenu) {
|
|
32
84
|
extensions.push(new ExtensionCustomMenu({ modifyMenu: this.modifyMenu }));
|
|
33
85
|
}
|
|
34
86
|
if (this.mediaUpload) {
|
|
35
87
|
extensions.push(new ExtensionMediaUpload(this.mediaUpload));
|
|
36
88
|
}
|
|
89
|
+
fixShortcodeRoundTrip(extensions);
|
|
37
90
|
return extensions;
|
|
38
91
|
}
|
|
39
92
|
};
|
|
40
|
-
async function createEditorKits(config, mediaUpload, modifyMenu) {
|
|
93
|
+
async function createEditorKits(config, mediaUpload, modifyMenu, omitExtensions) {
|
|
41
94
|
if (!config) {
|
|
42
95
|
return {
|
|
43
|
-
kits: [
|
|
96
|
+
kits: [
|
|
97
|
+
new SafeAdvancedEditorKit(
|
|
98
|
+
false,
|
|
99
|
+
mediaUpload,
|
|
100
|
+
modifyMenu,
|
|
101
|
+
omitExtensions
|
|
102
|
+
)
|
|
103
|
+
],
|
|
44
104
|
collaborative: false
|
|
45
105
|
};
|
|
46
106
|
}
|
|
@@ -49,7 +109,12 @@ async function createEditorKits(config, mediaUpload, modifyMenu) {
|
|
|
49
109
|
const url = config.wsUrl ?? defaultWsUrl();
|
|
50
110
|
return {
|
|
51
111
|
kits: [
|
|
52
|
-
new SafeAdvancedEditorKit(
|
|
112
|
+
new SafeAdvancedEditorKit(
|
|
113
|
+
true,
|
|
114
|
+
mediaUpload,
|
|
115
|
+
modifyMenu,
|
|
116
|
+
omitExtensions
|
|
117
|
+
),
|
|
53
118
|
new HuddleYjsKit(
|
|
54
119
|
url,
|
|
55
120
|
config.params ?? {},
|
|
@@ -66,7 +131,14 @@ async function createEditorKits(config, mediaUpload, modifyMenu) {
|
|
|
66
131
|
);
|
|
67
132
|
config.onUnavailable?.(error);
|
|
68
133
|
return {
|
|
69
|
-
kits: [
|
|
134
|
+
kits: [
|
|
135
|
+
new SafeAdvancedEditorKit(
|
|
136
|
+
false,
|
|
137
|
+
mediaUpload,
|
|
138
|
+
modifyMenu,
|
|
139
|
+
omitExtensions
|
|
140
|
+
)
|
|
141
|
+
],
|
|
70
142
|
collaborative: false
|
|
71
143
|
};
|
|
72
144
|
}
|
|
@@ -96,6 +168,7 @@ var RichEditor = forwardRef(
|
|
|
96
168
|
mediaUpload,
|
|
97
169
|
editorKits: additionalEditorKits,
|
|
98
170
|
modifyMenu,
|
|
171
|
+
omitExtensions,
|
|
99
172
|
valueType = MARKDOWN_TYPE,
|
|
100
173
|
strictValue = false
|
|
101
174
|
}, ref) {
|
|
@@ -259,7 +332,8 @@ var RichEditor = forwardRef(
|
|
|
259
332
|
const { kits: editorKits, collaborative } = await createEditorKits(
|
|
260
333
|
collab,
|
|
261
334
|
mediaUpload,
|
|
262
|
-
modifyMenu
|
|
335
|
+
modifyMenu,
|
|
336
|
+
omitExtensions
|
|
263
337
|
);
|
|
264
338
|
if (disposed) return;
|
|
265
339
|
editor = CoreEditor.create({
|
|
@@ -398,5 +472,5 @@ var RichEditor = forwardRef(
|
|
|
398
472
|
RichEditor.displayName = "RichEditor";
|
|
399
473
|
|
|
400
474
|
export { MDY_PROJECTION_META, RichEditor };
|
|
401
|
-
//# sourceMappingURL=chunk-
|
|
402
|
-
//# sourceMappingURL=chunk-
|
|
475
|
+
//# sourceMappingURL=chunk-ULKDK6W6.js.map
|
|
476
|
+
//# sourceMappingURL=chunk-ULKDK6W6.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/RichEditor/mdyTransaction.ts","../src/components/RichEditor/editorKits.ts","../src/components/RichEditor/RichEditor.tsx"],"names":["RichEditor","doc"],"mappings":"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","file":"chunk-ULKDK6W6.js","sourcesContent":["/** Shared metadata for host-created MDY projection updates. */\nexport const MDY_PROJECTION_META = 'mdyProjectionRefresh';\n","/**\n * Editor kit assembly for {@link RichEditor}, for both plain and collaborative\n * (Yjs) mode.\n *\n * Both modes start from {@link AdvancedEditorKit} and drop the extensions that\n * are unsafe for our usage — see {@link unsafeExtensions} — then collaborative\n * mode adds the Yjs pieces on top.\n *\n * The Yjs pieces live in `collabKit.ts` behind a dynamic `import()`, so\n * `@kerebron/extension-yjs`, `yjs` and `y-protocols` remain truly optional\n * peers — plain-mode consumers never load them.\n */\nimport type { EditorKit } from '@kerebron/editor';\nimport type { NodeSpec } from 'prosemirror-model';\nimport { AdvancedEditorKit } from '@kerebron/editor-kits/AdvancedEditorKit';\nimport {\n ExtensionMediaUpload,\n type MediaUploadOptions,\n} from '@kerebron/extension-basic-editor/ExtensionMediaUpload';\nimport {\n ExtensionCustomMenu,\n type MenuElement,\n} from '@kerebron/extension-menu';\n\nexport type { MediaUploadOptions };\nexport type { MenuElement };\n\n/**\n * Reshape the toolbar menu before it renders: receives the stock menu's\n * item groups and returns the groups to render. Append custom\n * {@link MenuElement}s (e.g. a Macros toggle) or drop stock groups.\n */\nexport type ModifyMenu = (menus: MenuElement[][]) => MenuElement[][];\n\nexport interface CollabConfig {\n /** Room id — one shared document per room (e.g. a post id). */\n room: string;\n /**\n * WebSocket base URL for the Yjs relay. Defaults to\n * `<ws|wss>://<location.host>/yjs`. The room id is appended by the provider.\n */\n wsUrl?: string;\n /** Extra query params for the socket (e.g. `{ token }` for auth). */\n params?: Record<string, string>;\n /**\n * Who this editor is, published on awareness (`kerebron:user`) so peers see\n * a named, coloured cursor. Without it remote cursors do not render — the\n * position plugin skips awareness states that carry no user — and the\n * `id` is what the cursor colour is derived from (kerebron's `User` shape).\n */\n user?: { id: string; name: string; color?: string };\n /**\n * Custom WebSocket implementation handed to the Yjs provider — e.g. a\n * loopback socket for demos/tests, or a polyfill outside the browser.\n * Defaults to `globalThis.WebSocket`.\n */\n WebSocketPolyfill?: typeof globalThis.WebSocket;\n /**\n * Called when collaborative editing could not be started at all — the Yjs\n * kit failed to load (see {@link createEditorKits}). The editor mounts\n * anyway, as a local one; this is how the host finds out that edits are no\n * longer shared, so it can say so, or tear its own editor down if unshared\n * editing would be unsafe.\n *\n * Not for connection trouble: a room that is reachable but currently\n * disconnected still has the Yjs kit loaded, and the provider retries on its\n * own. This fires once, before the editor is created.\n */\n onUnavailable?: (error: unknown) => void;\n}\n\n/** What {@link createEditorKits} resolves to. */\nexport interface EditorKits {\n kits: EditorKit[];\n /**\n * Whether the returned kits can actually collaborate. False when `config`\n * asked for a room but the Yjs kit could not be loaded, so callers know not\n * to join one.\n */\n collaborative: boolean;\n}\n\n/**\n * Extensions dropped from {@link AdvancedEditorKit}, and why.\n *\n * `autocomplete` and `hover` debounce their DOM handlers (200ms) and then call\n * `dispatchMeta`, which reads `this.editor.state` with no guard that the editor\n * is still alive. Any teardown or document swap inside that debounce window\n * lands the deferred call on a dead view and throws\n * `null.matchesNode()` inside ProseMirror's `EditorView.updateStateInner`,\n * leaving the view permanently broken. Two ways to hit it:\n * - remount (e.g. a `key` change) while the pointer is over the editor, which\n * fires the debounced `onMouseLeave` after the view is destroyed;\n * - a Yjs remote update replacing the document tree under a pending callback.\n * The first applies to *every* editor, so both extensions come out in both\n * modes. No functional cost — autocomplete popups and node-hover tooltips are\n * compositor conveniences, not required for editing.\n *\n * `history` is collab-only: ExtensionYjs supplies its own CRDT-aware undo/redo\n * and the editor throws `Extension conflict: yjs vs history` if both are\n * present. Plain mode keeps it, so undo/redo still works there.\n */\nconst unsafeExtensions = ['autocomplete', 'hover'] as const;\n\n/**\n * Fix the `shortcode_inline` node's DOM round-trip (mieweb/ui#695).\n *\n * The stock node chips `{{merge_tokens}}` into atomic spans but its `toDOM`\n * drops the braces, so serializing a document back to HTML/text silently\n * corrupts every merge token. Patch the spec on the kit's own instance:\n * serialize the braces, strip them again on parse — the `content` attr stays\n * brace-less, which the input rule and the markdown serializer both rely on.\n *\n * Done here, in the kit we ship, so npm consumers on stock\n * `@kerebron/extension-basic-editor` get the fix too — `@kerebron/*` is\n * externalized (`tsup.config.ts`), so a workspace-level package patch would\n * never reach them. Drop once fixed upstream.\n *\n * The node is nested: `AdvancedEditorKit` → `ExtensionBasicEditor`, whose\n * `requires` carries the `BasicEditorKit` extension *instances* (names and\n * instances mix in `requires`), hence the recursive walk.\n */\nfunction fixShortcodeRoundTrip(extensions: unknown[]): void {\n for (const item of extensions) {\n if (!item || typeof item !== 'object') continue; // name-only requires\n const extension = item as {\n name?: unknown;\n requires?: unknown;\n getNodeSpec?: () => NodeSpec;\n };\n if (\n extension.name === 'shortcode_inline' &&\n typeof extension.getNodeSpec === 'function'\n ) {\n const stockSpec = extension.getNodeSpec.bind(extension);\n extension.getNodeSpec = (): NodeSpec => ({\n ...stockSpec(),\n parseDOM: [\n {\n tag: 'span.kb-shortcode-inline',\n getAttrs: (dom) => {\n const text = dom.textContent ?? '';\n const match = /^\\{\\{([^}]+)\\}\\}$/.exec(text);\n return { content: match ? match[1] : text || null };\n },\n },\n ],\n toDOM: (node) => [\n 'span',\n { class: 'kb-shortcode-inline' },\n node.attrs.content ? `{{${String(node.attrs.content)}}}` : '',\n ],\n });\n return;\n }\n if (Array.isArray(extension.requires)) {\n fixShortcodeRoundTrip(extension.requires);\n }\n }\n}\n\n/**\n * Remove extensions by name, wherever they sit: extensions nest (e.g.\n * `ExtensionBasicEditor.requires` carries the BasicEditorKit node instances),\n * so the walk descends `requires` arrays and filters each level in place.\n * Name-only (string) requires entries are left alone — they declare ordering,\n * not instances.\n */\nfunction dropNamedExtensions(\n extensions: unknown[],\n names: readonly string[]\n): unknown[] {\n const kept = extensions.filter(\n (item) =>\n !(\n item &&\n typeof item === 'object' &&\n 'name' in item &&\n names.includes((item as { name: string }).name)\n )\n );\n for (const item of kept) {\n if (!item || typeof item !== 'object') continue;\n const extension = item as { requires?: unknown };\n if (Array.isArray(extension.requires)) {\n extension.requires = dropNamedExtensions(extension.requires, names);\n }\n }\n return kept;\n}\n\n/**\n * {@link AdvancedEditorKit} minus {@link unsafeExtensions} (and, for collab\n * mode, minus `history`), with `mediaUpload` reconfigured when the host asks.\n *\n * `AdvancedEditorKit` constructs `ExtensionMediaUpload` with no options, and an\n * extension's options are fixed at construction — so the only way to configure\n * it is to drop that instance and append one of our own. `modifyMenu` works\n * the same way: the stock `ExtensionCustomMenu` is constructed with no config,\n * so customizing the toolbar means replacing it with a configured instance.\n */\nclass SafeAdvancedEditorKit implements EditorKit {\n name = 'advanced-editor';\n constructor(\n private readonly forCollab: boolean,\n private readonly mediaUpload?: MediaUploadOptions,\n private readonly modifyMenu?: ModifyMenu,\n private readonly omitExtensions?: readonly string[]\n ) {}\n\n getExtensions() {\n const dropped: string[] = [...unsafeExtensions];\n if (this.forCollab) dropped.push('history');\n if (this.mediaUpload) dropped.push('mediaUpload');\n if (this.modifyMenu) dropped.push('customMenu');\n\n let extensions = new AdvancedEditorKit()\n .getExtensions()\n .filter(\n (extension) =>\n !('name' in extension && dropped.includes(extension.name))\n );\n\n if (this.omitExtensions?.length) {\n extensions = dropNamedExtensions(\n extensions,\n this.omitExtensions\n ) as typeof extensions;\n }\n if (this.modifyMenu) {\n extensions.push(new ExtensionCustomMenu({ modifyMenu: this.modifyMenu }));\n }\n if (this.mediaUpload) {\n extensions.push(new ExtensionMediaUpload(this.mediaUpload));\n }\n fixShortcodeRoundTrip(extensions);\n return extensions;\n }\n}\n\n/** MarkYChange + ExtensionYjs live in `collabKit.ts` (lazy-loaded). */\n\n/**\n * Build the editor kits for a session. Pass `config` to join a collaborative\n * room; omit it for a plain local editor. Pass `mediaUpload` to configure how\n * pasted/dropped files are handled — most importantly `uploadHandler`, without\n * which every image is embedded in the document as a base64 `data:` URL.\n * Pass `omitExtensions` to remove schema extensions by name — the toolbar is\n * schema-driven, so dropping a node removes its menu items, input rules and\n * paste handling in one move (e.g. the email surface drops `task_list`).\n *\n * Async because collaborative mode lazy-loads the Yjs kit (and its optional\n * peer deps) on first use; plain mode resolves immediately.\n *\n * That lazy load is allowed to fail. `@kerebron/extension-yjs`, `yjs` and\n * `y-protocols` are optional peers, so the chunk can be absent (peers never\n * installed), stale (a dev server's dependency hash moved under a running\n * page) or simply unreachable (a partial deploy, an offline client). None of\n * that is a reason to leave the caller without an editor: collaboration is an\n * enhancement, editing is the feature. So a failed load degrades to the local\n * kit and reports itself through {@link CollabConfig.onUnavailable} rather\n * than rejecting.\n */\nexport async function createEditorKits(\n config?: CollabConfig,\n mediaUpload?: MediaUploadOptions,\n modifyMenu?: ModifyMenu,\n omitExtensions?: readonly string[]\n): Promise<EditorKits> {\n if (!config) {\n return {\n kits: [\n new SafeAdvancedEditorKit(\n false,\n mediaUpload,\n modifyMenu,\n omitExtensions\n ),\n ],\n collaborative: false,\n };\n }\n\n try {\n const { HuddleYjsKit, defaultWsUrl } = await import('./collabKit');\n const url = config.wsUrl ?? defaultWsUrl();\n return {\n kits: [\n new SafeAdvancedEditorKit(\n true,\n mediaUpload,\n modifyMenu,\n omitExtensions\n ),\n new HuddleYjsKit(\n url,\n config.params ?? {},\n config.WebSocketPolyfill,\n config.user\n ),\n ],\n collaborative: true,\n };\n } catch (error) {\n console.warn(\n '[RichEditor] Collaborative editing unavailable — the Yjs kit failed to load. Continuing as a local editor.',\n error\n );\n config.onUnavailable?.(error);\n // Degrading to a local editor must not also drop `mediaUpload`: without it\n // the stock extension comes back and pasted files are embedded as base64.\n return {\n kits: [\n new SafeAdvancedEditorKit(\n false,\n mediaUpload,\n modifyMenu,\n omitExtensions\n ),\n ],\n collaborative: false,\n };\n }\n}\n","'use client';\n\nimport {\n forwardRef,\n useCallback,\n useEffect,\n useImperativeHandle,\n useReducer,\n useRef,\n useState,\n} from 'react';\n\nimport { CoreEditor, type AssetLoad, type EditorKit } from '@kerebron/editor';\nimport { createAssetLoad } from '@kerebron/wasm/web';\n\nimport { useIsDarkMode } from '../../hooks/useIsDarkMode';\nimport { MDY_PROJECTION_META } from './mdyTransaction';\nimport {\n createEditorKits,\n type CollabConfig,\n type MediaUploadOptions,\n type ModifyMenu,\n} from './editorKits';\n\nexport type {\n CollabConfig,\n MediaUploadOptions,\n MenuElement,\n ModifyMenu,\n} from './editorKits';\n\nconst MARKDOWN_TYPE = 'text/x-markdown';\n\n/**\n * The markdown converter's tree-sitter WASM init is not concurrency-safe, so\n * every editor's *first* load queues behind the previous one. Later loads (a\n * `value` change) are free — by then the grammars are warm.\n */\nlet initialLoadQueue: Promise<unknown> = Promise.resolve();\n\nfunction queueInitialLoad(load: () => Promise<void>): Promise<void> {\n const queued = initialLoadQueue.catch(() => undefined).then(load);\n initialLoadQueue = queued.catch(() => undefined);\n return queued;\n}\n\nexport interface RichEditorProps {\n /** Markdown to load. Changing it reloads the editor unless `collab` is set. */\n value?: string;\n /** Called with the editor's markdown content whenever it changes. */\n onChange?: (value: string) => void;\n /** Called when editor setup or a Markdown load fails. getContent also rejects. */\n onError?: (error: unknown) => void;\n /** Called after the initial Markdown load completes. */\n onReady?: (editor: CoreEditor) => void;\n /** Whether to render the live markdown output preview. Defaults to `false`. */\n showPreview?: boolean;\n /**\n * Enable live collaborative editing (Yjs) for the given room. When set, the\n * editor connects to the `/yjs` websocket relay and every peer in the same\n * `room` co-edits one shared document. Uncontrolled like `value` — remount via\n * `key` to switch rooms.\n *\n * Best-effort: if the Yjs kit cannot be loaded the editor still mounts, as a\n * local one, and `collab.onUnavailable` is called. Pass that callback if\n * unshared editing is something your users need to be told about.\n */\n collab?: CollabConfig;\n /** Read-only surface: no typing, and the content dims. */\n disabled?: boolean;\n /**\n * Lock edits while keeping the surface focusable and selectable, without\n * the dimmed `disabled` styling. Applied from creation, so the document\n * cannot be edited even while the initial load is still in flight.\n */\n readOnly?: boolean;\n /**\n * Id for the editor host element — an `aria-labelledby`/`aria-describedby`\n * anchor. The host is a `div`, not a labelable control, so a\n * `<label htmlFor>` will not associate; name the editor with `aria-label`\n * or `aria-labelledby` instead.\n */\n id?: string;\n /** Extra classes on the editor surface, beside `kb-component`. */\n className?: string;\n 'aria-label'?: string;\n 'aria-labelledby'?: string;\n /**\n * Where the tree-sitter WASM grammars load from. Defaults to\n * `createAssetLoad('/kerebron-wasm')`; supply your own when the host serves\n * `@kerebron/wasm`'s `assets/` somewhere else.\n */\n assetLoad?: AssetLoad;\n /**\n * How files pasted or dropped into the editor are handled.\n *\n * **Set `uploadHandler` if your documents are persisted anywhere.** Without\n * it, a pasted image is embedded in the document as a base64 `data:` URL and\n * a video as a blob object URL: a 4 MB screenshot becomes ~5.8 MB of\n * markdown, which most APIs will refuse, and an object URL is dead as soon as\n * the page reloads. `uploadHandler` receives the file and returns the URL to\n * reference it by, so the document carries a link instead of the bytes.\n *\n * ```tsx\n * <RichEditor\n * mediaUpload={{ uploadHandler: (file) => uploadToMyMediaStore(file) }}\n * />\n * ```\n *\n * Read once, when the editor mounts — like {@link collab}, remount via `key`\n * to change it.\n */\n mediaUpload?: MediaUploadOptions;\n /** Additional editor kits, installed once when the editor mounts. */\n editorKits?: EditorKit[];\n /**\n * Reshape the stock toolbar before it renders: receives the menu's item\n * groups and returns the groups to render — append custom controls (a\n * macros toggle, dictation) or drop stock ones. Read once, when the editor\n * mounts — like {@link collab}, remount via `key` to change it.\n */\n modifyMenu?: ModifyMenu;\n /**\n * Schema extensions to remove by name (e.g. `['task_list', 'task_item']`).\n * The toolbar, input rules and paste handling are all schema-driven, so\n * dropping a node here removes the whole feature in one move. Read once,\n * when the editor mounts — like {@link collab}, remount via `key` to\n * change it.\n */\n omitExtensions?: readonly string[];\n /**\n * MIME type of the `value`/`onChange` contract (`'text/x-markdown'` by\n * default; pass `'text/html'` for an HTML-valued surface). Governs both\n * how `value` is parsed and what `onChange`/`getContent()` emit.\n */\n valueType?: string;\n /**\n * Converge the document to `value` on every render, not only when the\n * prop changes — native controlled-input semantics: when a host's\n * `onChange` does not echo an edit back into `value`, the edit reverts.\n * A rejected edit leaves the prop identity unchanged while the document\n * moved on, which a change-gated reload can never see. Off by default,\n * which tolerates read-once hosts that call `getContent()` on submit.\n */\n strictValue?: boolean;\n}\n\nexport interface RichEditorHandle {\n /**\n * The editor's markdown, awaiting the initial load. `onChange` can lag the\n * last keystroke, so read this on submit rather than trusting mirrored state.\n */\n getContent: () => Promise<string>;\n /** Focus the editor, restoring the caret where the writer left it. */\n focus: () => void;\n}\n\n/**\n * Markdown editor over Kerebron's `CoreEditor`.\n *\n * The editor mounts into a **disposable child div**: `CoreEditor.destroy()`\n * replaces its host element with a clone, which would strand React's ref (and,\n * under StrictMode's double-mount, leave the live editor detached behind a\n * dead clone).\n */\nconst RichEditor = forwardRef<RichEditorHandle, RichEditorProps>(\n function RichEditor(\n {\n value = '',\n onChange,\n onError,\n onReady,\n showPreview = false,\n collab,\n disabled = false,\n readOnly = false,\n id,\n className,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n assetLoad,\n mediaUpload,\n editorKits: additionalEditorKits,\n modifyMenu,\n omitExtensions,\n valueType = MARKDOWN_TYPE,\n strictValue = false,\n },\n ref\n ) {\n const isDark = useIsDarkMode();\n const hostRef = useRef<HTMLDivElement>(null);\n const editorInstance = useRef<CoreEditor | null>(null);\n const onChangeRef = useRef(onChange);\n onChangeRef.current = onChange;\n const onErrorRef = useRef(onError);\n onErrorRef.current = onError;\n const onReadyRef = useRef(onReady);\n onReadyRef.current = onReady;\n // Mirrors what the editor last held, so an echo of our own `onChange`\n // doesn't reload the document out from under the caret.\n const valueRef = useRef(value);\n const readyRef = useRef<Promise<void> | null>(null);\n const loadingRef = useRef(false);\n const loadVersionRef = useRef(0);\n // Return the exact source until a writer changes the loaded document.\n // Running the Markdown converter alone can normalize whitespace or links.\n const loadedDocRef = useRef<unknown>(null);\n const disabledRef = useRef(disabled);\n const readOnlyRef = useRef(readOnly);\n\n const [md, setMd] = useState<string>('');\n // A strict surface reconciles in an after-render effect, but publishing\n // an edit only mutates refs — a host whose `onChange` ignores the edit\n // (rejection) triggers no render, so the stale document would stay\n // visible. Each publication schedules one render; an accepted update\n // from the host batches into the same pass, so the effect compares the\n // freshest prop either way.\n const [, scheduleStrictReconcile] = useReducer(\n (tick: number) => tick + 1,\n 0\n );\n const strictValueRef = useRef(strictValue);\n strictValueRef.current = strictValue;\n // Serializing the document is the expensive part of a transaction, so the\n // last doc that was serialized is kept to recognise the transactions that\n // did not change it. ProseMirror documents are immutable, so identity is an\n // exact test.\n const lastSerializedDoc = useRef<unknown>(null);\n // Read inside effects created once on mount.\n const showPreviewRef = useRef(showPreview);\n showPreviewRef.current = showPreview;\n const valueTypeRef = useRef(valueType);\n valueTypeRef.current = valueType;\n\n // The contenteditable surface has no implicit ARIA role, so labeling\n // attributes are only permitted alongside an explicit textbox role — and\n // `aria-readonly` is only valid on such a role, not on the host div.\n const surfaceAttributes = useCallback(\n () =>\n ariaLabel || ariaLabelledBy\n ? {\n role: 'textbox',\n 'aria-multiline': 'true',\n ...(ariaLabel ? { 'aria-label': ariaLabel } : {}),\n ...(ariaLabelledBy ? { 'aria-labelledby': ariaLabelledBy } : {}),\n ...(readOnlyRef.current ? { 'aria-readonly': 'true' } : {}),\n }\n : null,\n [ariaLabel, ariaLabelledBy]\n );\n\n // Applies the read state everywhere it matters: the view's `editable`\n // prop, the surface's ARIA attributes, and the stock toolbar — whose\n // buttons dispatch commands regardless of `editable`, so disabled and\n // readOnly must neutralize it with `inert` (blocks pointer and keyboard\n // access while the document's text stays selectable).\n // ProseMirror drops natural tabbability once `editable` is false, so a\n // read-only (not disabled) surface restores it with a direct tabindex —\n // tracked by ownership so a host-supplied tabindex (the TextAreaRich\n // adapter sets its own through `setProps`) is never touched.\n const ownsTabindexRef = useRef(false);\n const syncReadState = useCallback(() => {\n const editor = editorInstance.current;\n if (editor) {\n const attributes = surfaceAttributes();\n editor.view.setProps({\n editable: () => !disabledRef.current && !readOnlyRef.current,\n ...(attributes ? { attributes } : {}),\n });\n const dom = editor.view.dom as HTMLElement;\n if (readOnlyRef.current && !disabledRef.current) {\n if (!dom.hasAttribute('tabindex')) {\n dom.setAttribute('tabindex', '0');\n ownsTabindexRef.current = true;\n }\n } else if (ownsTabindexRef.current) {\n if (dom.getAttribute('tabindex') === '0')\n dom.removeAttribute('tabindex');\n ownsTabindexRef.current = false;\n }\n }\n const inert = disabledRef.current || readOnlyRef.current;\n for (const toolbar of hostRef.current?.querySelectorAll<HTMLElement>(\n '.kb-custom-menu, .kb-custom-menu__overflow-menu'\n ) ?? []) {\n toolbar.inert = inert;\n }\n }, [surfaceAttributes]);\n\n useEffect(() => {\n disabledRef.current = disabled;\n readOnlyRef.current = readOnly;\n syncReadState();\n }, [disabled, readOnly, syncReadState]);\n\n // Runs after every render (no dependency array): a `strictValue` surface\n // must converge even when the prop identity never changed — a rejected\n // edit keeps `value` as-is while the document moved on. The\n // `value === valueRef` guard keeps the common case free; non-strict\n // hosts additionally require the prop itself to have changed (tracked\n // manually below), preserving tolerance for read-once hosts.\n const lastValuePropRef = useRef(value);\n useEffect(() => {\n const propChanged = lastValuePropRef.current !== value;\n lastValuePropRef.current = value;\n // In collab mode the CRDT owns the content; reloading would fight it.\n if (collab || value === valueRef.current) return;\n if (!strictValue && !propChanged) return;\n valueRef.current = value;\n const editor = editorInstance.current;\n if (!editor) return;\n\n loadingRef.current = true;\n const loadVersion = ++loadVersionRef.current;\n const previousReady = readyRef.current;\n // Serialize reloads behind setup and one another. Saving while a reload\n // is pending awaits that same promise rather than reading stale prose.\n const pending = (previousReady ?? Promise.resolve())\n .catch(() => undefined)\n .then(async () => {\n if (editorInstance.current !== editor) return;\n // Reloading the document must not cost the writer their caret: a\n // host-composed update (macro pick, finding) lands mid-flow and\n // the next keystroke should keep going into the editable.\n const hadFocus = editor.view.hasFocus();\n await editor.loadDocumentText(valueTypeRef.current, value);\n if (editorInstance.current !== editor) return;\n loadedDocRef.current = editor.view.state.doc;\n lastSerializedDoc.current = editor.view.state.doc;\n if (hadFocus) {\n // The load can take long enough for the writer to move on —\n // only reclaim the caret when no other control has taken it.\n const active = document.activeElement;\n if (\n !active ||\n active === document.body ||\n (editor.view.dom as HTMLElement).contains(active)\n ) {\n editor.view.focus();\n }\n }\n if (showPreviewRef.current) setMd(value);\n })\n .finally(() => {\n if (\n editorInstance.current === editor &&\n loadVersion === loadVersionRef.current\n ) {\n loadingRef.current = false;\n }\n });\n readyRef.current = pending;\n void pending.catch((error) => {\n if (editorInstance.current !== editor) return;\n console.error('Failed to load markdown:', error);\n onErrorRef.current?.(error);\n });\n });\n\n useEffect(() => {\n if (!hostRef.current) return;\n const host = hostRef.current;\n\n // Set on cleanup so async continuations (kit loading and the\n // `loadDocumentText` chain) don't touch the editor after `destroy()`.\n let disposed = false;\n let editor: CoreEditor | null = null;\n\n const mount = document.createElement('div');\n host.appendChild(mount);\n\n // Listen to transactions and update markdown preview\n const onTransaction = async (event?: Event) => {\n const transaction = (\n event as\n | globalThis.CustomEvent<{\n transaction?: {\n getMeta: (key: string) => unknown;\n before: unknown;\n };\n }>\n | undefined\n )?.detail?.transaction;\n if (transaction?.getMeta(MDY_PROJECTION_META) === true) {\n const doc = editorInstance.current?.view.state.doc;\n if (transaction.before === loadedDocRef.current) {\n loadedDocRef.current = doc;\n lastSerializedDoc.current = doc;\n } else {\n lastSerializedDoc.current = null;\n // A host projection can overtake a pending user-edit save. That\n // older result is discarded below, so publish the newest composed\n // document even if the writer does not make another transaction.\n // A microtask coalesces a burst of clinical updates into one save.\n void Promise.resolve().then(() => {\n if (!disposed) return onTransaction();\n });\n }\n return;\n }\n // Programmatic loads are not edits — reporting them would echo the\n // caller's own `value` back through `onChange`.\n if (loadingRef.current || !editorInstance.current) return;\n\n // ProseMirror fires a transaction for every selection change too —\n // arrow keys, clicks, a blur. Serializing the whole document to\n // markdown for those costs a full tree-sitter pass and two React\n // renders for a caret move, so only a changed document is re-read.\n const { doc } = editorInstance.current.view.state;\n if (doc === lastSerializedDoc.current) return;\n lastSerializedDoc.current = doc;\n const loadVersion = loadVersionRef.current;\n\n try {\n const buffer = await editorInstance.current.saveDocument(\n valueTypeRef.current\n );\n const markdown = new globalThis.TextDecoder().decode(buffer);\n if (\n disposed ||\n loadingRef.current ||\n loadVersion !== loadVersionRef.current ||\n doc !== editorInstance.current?.view.state.doc\n ) {\n return;\n }\n valueRef.current = markdown;\n // `md` only feeds the preview pane; setting it with the preview off\n // re-renders the editor on every keystroke for nothing.\n if (showPreviewRef.current) setMd(markdown);\n onChangeRef.current?.(markdown);\n if (strictValueRef.current) scheduleStrictReconcile();\n // This source is now published. Future clinical-only projections\n // preserve it without starting another authored-prose write.\n loadedDocRef.current = doc;\n } catch (err) {\n // The document was marked as serialized before the attempt, to keep\n // selection-only transactions arriving mid-save from re-entering.\n // A failure has to undo that, or this document is never retried.\n lastSerializedDoc.current = null;\n console.error('Failed to save markdown:', err);\n }\n };\n\n // Initialize the editor. Both modes drop the teardown-unsafe extensions;\n // collaborative mode additionally swaps `history` for the Yjs CRDT sync\n // and lazy-loads the Yjs kit (see `editorKits.ts` for why).\n const setup = async () => {\n loadingRef.current = true;\n const loadVersion = ++loadVersionRef.current;\n // `collaborative` is false when a room was asked for but the Yjs kit\n // could not be loaded — the editor is still created, just a local one,\n // so there is no room to join below.\n const { kits: editorKits, collaborative } = await createEditorKits(\n collab,\n mediaUpload,\n modifyMenu,\n omitExtensions\n );\n if (disposed) return;\n\n editor = CoreEditor.create({\n element: mount,\n uri: 'file:///untitled.md',\n assetLoad: assetLoad ?? createAssetLoad('/kerebron-wasm'),\n editorKits: [...editorKits, ...(additionalEditorKits ?? [])],\n readOnly: disabledRef.current || readOnlyRef.current,\n });\n\n editorInstance.current = editor;\n syncReadState();\n editor.addEventListener('transaction', onTransaction);\n\n // Seed initial content, then populate the preview once on mount.\n //\n // In collaborative mode we still load the local markdown first, then\n // join the room: the Yjs binding seeds an *empty* shared document from\n // this content on the first join, and overwrites the editor with the\n // shared content when the room already has edits — so the stored\n // markdown is the starting point without ever double-inserting.\n const joinRoom = () => {\n if (collaborative && collab && editor && !disposed) {\n (\n editor.run as Record<string, (...args: unknown[]) => boolean>\n ).changeRoom?.(collab.room);\n reseedWhenRoomStaysEmpty();\n }\n };\n\n // The Yjs binding is supposed to seed an empty room from the local\n // content, but the sync import can land as an overwrite that blanks\n // the just-loaded seed (observed with extension-yjs 0.8.x). Heal it:\n // once the join settles, an empty document with a non-empty seed\n // means nobody's content won — reload the seed, which the binding\n // then pushes into the room. Joiners pass no value, so exactly one\n // participant ever does this.\n const seed = valueRef.current;\n const reseedWhenRoomStaysEmpty = () => {\n if (!seed) return;\n const check = async (attempt: number) => {\n if (disposed || !editorInstance.current) return;\n try {\n const buffer =\n await editorInstance.current.saveDocument(MARKDOWN_TYPE);\n const current = new globalThis.TextDecoder()\n .decode(buffer)\n .trim();\n if (disposed || !editorInstance.current) return;\n if (current) return; // somebody's content arrived — done\n if (attempt >= 2) {\n await editorInstance.current.loadDocumentText(\n valueTypeRef.current,\n seed\n );\n return;\n }\n setTimeout(() => void check(attempt + 1), 300);\n } catch {\n // A failed probe must not break the editor; the room stays as-is.\n }\n };\n setTimeout(() => void check(0), 300);\n };\n\n if (valueRef.current) {\n await queueInitialLoad(() =>\n editor!.loadDocumentText(valueTypeRef.current, valueRef.current)\n );\n }\n if (disposed) return;\n loadedDocRef.current = editor.view.state.doc;\n lastSerializedDoc.current = editor.view.state.doc;\n if (showPreviewRef.current) setMd(valueRef.current);\n if (loadVersion === loadVersionRef.current) loadingRef.current = false;\n onReadyRef.current?.(editor);\n joinRoom();\n };\n\n const pending = setup();\n readyRef.current = pending;\n // Observe the rejection without replacing the readiness promise: callers\n // must be able to detect a failed load instead of saving stale content.\n void pending.catch((error) => {\n if (disposed) return;\n loadingRef.current = false;\n console.error('Failed to set up editor:', error);\n onErrorRef.current?.(error);\n });\n\n // Cleanup on unmount\n return () => {\n disposed = true;\n editorInstance.current = null; // makes onTransaction's guard effective\n editor?.removeEventListener('transaction', onTransaction);\n editor?.destroy();\n readyRef.current = null;\n host.replaceChildren();\n };\n // Initial `value`/`collab` are intentionally only applied on mount\n // (uncontrolled). Remount via `key` to switch rooms.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n useImperativeHandle(\n ref,\n () => ({\n getContent: async (): Promise<string> => {\n while (true) {\n await readyRef.current;\n const editor = editorInstance.current;\n if (!editor) return valueRef.current;\n const doc = editor.view.state.doc;\n const loadVersion = loadVersionRef.current;\n if (doc === loadedDocRef.current) return valueRef.current;\n const buffer = await editor.saveDocument(valueTypeRef.current);\n if (\n editorInstance.current !== editor ||\n loadVersion !== loadVersionRef.current ||\n doc !== editor.view.state.doc\n )\n continue;\n const markdown = new globalThis.TextDecoder().decode(buffer);\n valueRef.current = markdown;\n loadedDocRef.current = doc;\n lastSerializedDoc.current = doc;\n return markdown;\n }\n },\n focus: (): void => {\n const apply = (): void => {\n const view = editorInstance.current?.view as\n | { focus?: () => void }\n | undefined;\n if (view?.focus) {\n view.focus();\n return;\n }\n hostRef.current\n ?.querySelector<HTMLElement>('[contenteditable=\"true\"], textarea')\n ?.focus();\n };\n // Callers focus on mount; the editor may still be loading its kits.\n if (editorInstance.current) apply();\n else void readyRef.current?.then(apply, () => undefined);\n },\n }),\n []\n );\n\n return (\n <div>\n <div>\n <div\n ref={hostRef}\n id={id}\n className={[\n 'kb-component',\n isDark ? 'kb-component--dark' : '',\n className ?? '',\n ]\n .filter(Boolean)\n .join(' ')}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n aria-disabled={disabled || undefined}\n style={{\n isolation: 'isolate',\n opacity: disabled ? 0.65 : undefined,\n pointerEvents: disabled ? 'none' : undefined,\n }}\n />\n </div>\n\n {showPreview && (\n <div>\n <div>\n <h5>Markdown Output</h5>\n <pre>{md}</pre>\n </div>\n </div>\n )}\n </div>\n );\n }\n);\n\nRichEditor.displayName = 'RichEditor';\n\nexport { RichEditor };\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { RichEditor } from './chunk-
|
|
2
|
-
import { processDictation, MacroLibrary } from './chunk-
|
|
1
|
+
import { RichEditor } from './chunk-ULKDK6W6.js';
|
|
2
|
+
import { processDictation, MacroLibrary } from './chunk-N6STVVB6.js';
|
|
3
3
|
import { useMessages } from './chunk-5YOT4DVH.js';
|
|
4
4
|
import { Dropdown, DropdownItem, DropdownSeparator, DropdownSubmenu, DropdownLabel } from './chunk-GTRYDFMT.js';
|
|
5
5
|
import { useMediaQuery } from './chunk-HTZ27DGZ.js';
|
|
@@ -196,6 +196,8 @@ var TextAreaRichKerebron = React2.forwardRef(
|
|
|
196
196
|
readOnly = false,
|
|
197
197
|
editorClassName,
|
|
198
198
|
editorStyle,
|
|
199
|
+
mediaUpload,
|
|
200
|
+
omitExtensions,
|
|
199
201
|
"aria-label": ariaLabel,
|
|
200
202
|
"aria-labelledby": ariaLabelledBy,
|
|
201
203
|
"aria-describedby": ariaDescribedBy,
|
|
@@ -1073,6 +1075,8 @@ var TextAreaRichKerebron = React2.forwardRef(
|
|
|
1073
1075
|
strictValue: true,
|
|
1074
1076
|
modifyMenu: menuAddon.modifyMenu,
|
|
1075
1077
|
editorKits: menuAddon.kits,
|
|
1078
|
+
mediaUpload,
|
|
1079
|
+
omitExtensions,
|
|
1076
1080
|
onReady: handleReady,
|
|
1077
1081
|
disabled,
|
|
1078
1082
|
readOnly
|
|
@@ -1180,5 +1184,5 @@ var TextAreaRichKerebron = React2.forwardRef(
|
|
|
1180
1184
|
TextAreaRichKerebron.displayName = "TextAreaRichKerebron";
|
|
1181
1185
|
|
|
1182
1186
|
export { CodeEditor, TextAreaRichKerebron };
|
|
1183
|
-
//# sourceMappingURL=chunk-
|
|
1184
|
-
//# sourceMappingURL=chunk-
|
|
1187
|
+
//# sourceMappingURL=chunk-WI35L5TR.js.map
|
|
1188
|
+
//# sourceMappingURL=chunk-WI35L5TR.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/RichEditor/CodeEditor.tsx","../src/components/TextAreaRich/speech.ts","../src/components/TextAreaRich/TextAreaRichKerebron.tsx"],"names":["view","toolbar","value","jsx","Fragment"],"mappings":"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","file":"chunk-WI35L5TR.js","sourcesContent":["import React, { useEffect, useRef } from 'react';\n\nimport { CoreEditor } from '@kerebron/editor';\nimport { CodeEditorKit } from '@kerebron/editor-kits/CodeEditorKit';\nimport { createAssetLoad } from '@kerebron/wasm/web';\n\nexport interface CodeEditorProps {\n /** Initial source code to load into the editor. */\n value?: string;\n /** Called with the editor's contents whenever they change. */\n onChange?: (value: string) => void;\n /** Language/grammar to use for syntax highlighting. Defaults to `typescript`. */\n lang?: string;\n}\n\nconst CodeEditor: React.FC<CodeEditorProps> = ({\n value = '',\n onChange,\n lang = 'typescript',\n}) => {\n const editorRef = useRef<HTMLDivElement>(null);\n const editorInstance = useRef<CoreEditor | null>(null);\n const onChangeRef = useRef(onChange);\n onChangeRef.current = onChange;\n\n useEffect(() => {\n const root = editorRef.current;\n if (!root) return;\n\n const applySelectLabel = () => {\n root.querySelectorAll('select.codejar-select').forEach((element) => {\n if (!element.getAttribute('aria-label')) {\n element.setAttribute('aria-label', 'Code editor language');\n }\n });\n };\n\n applySelectLabel();\n const observer = new MutationObserver(() => applySelectLabel());\n observer.observe(root, { childList: true, subtree: true });\n return () => observer.disconnect();\n }, []);\n\n useEffect(() => {\n if (!editorRef.current) return;\n\n // Initialize the editor\n const editor = CoreEditor.create({\n element: editorRef.current,\n uri: 'file:///untitled.ts',\n assetLoad: createAssetLoad('/kerebron-wasm'),\n editorKits: [new CodeEditorKit(lang)],\n });\n\n editorInstance.current = editor;\n\n // Surface edits to callers.\n const onTransaction = async () => {\n if (!editorInstance.current) return;\n\n try {\n const buffer = await editorInstance.current.saveDocument('text/plain');\n onChangeRef.current?.(new globalThis.TextDecoder().decode(buffer));\n } catch (err) {\n console.error('Failed to read code:', err);\n }\n };\n\n editor.addEventListener('transaction', onTransaction);\n\n // Seed initial content on mount.\n if (value) {\n editor\n .loadDocumentText('text/plain', value)\n .catch((err) => console.error('Failed to load code:', err));\n }\n\n // Cleanup on unmount\n return () => {\n editor.removeEventListener('transaction', onTransaction);\n editor.destroy();\n };\n // Initial `value`/`lang` are intentionally only applied on mount.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n return (\n <div>\n <div>\n <div ref={editorRef} className=\"kb-component\" />\n </div>\n </div>\n );\n};\n\nCodeEditor.displayName = 'CodeEditor';\n\nexport { CodeEditor };\n","/**\n * Minimal Web Speech API surface used for dictation. Mirrors the private\n * typings in `RichTextEditor` (the legacy engine keeps its own copy until it\n * is retired) — lib.dom omits these because browser support is uneven.\n */\nexport interface SpeechRecognitionResultLike {\n isFinal: boolean;\n 0: { transcript: string };\n}\nexport interface SpeechRecognitionEventLike {\n resultIndex: number;\n results: ArrayLike<SpeechRecognitionResultLike>;\n}\nexport interface SpeechRecognitionErrorEventLike {\n error: string;\n}\nexport interface SpeechRecognitionLike {\n continuous: boolean;\n interimResults: boolean;\n lang: string;\n maxAlternatives: number;\n onstart: (() => void) | null;\n onresult: ((event: SpeechRecognitionEventLike) => void) | null;\n onerror: ((event: SpeechRecognitionErrorEventLike) => void) | null;\n onend: (() => void) | null;\n start: () => void;\n stop: () => void;\n}\nexport type SpeechRecognitionCtor = new () => SpeechRecognitionLike;\ninterface SpeechWindow {\n SpeechRecognition?: SpeechRecognitionCtor;\n webkitSpeechRecognition?: SpeechRecognitionCtor;\n}\n\n/** The browser's SpeechRecognition constructor, when dictation is available. */\nexport function getSpeechRecognition(): SpeechRecognitionCtor | undefined {\n if (typeof window === 'undefined') return undefined;\n const w = window as unknown as SpeechWindow;\n return w.SpeechRecognition || w.webkitSpeechRecognition;\n}\n","import * as React from 'react';\nimport { Plugin, TextSelection } from 'prosemirror-state';\nimport type { Transaction } from 'prosemirror-state';\nimport type { Node as PMNode } from 'prosemirror-model';\nimport type { EditorView } from 'prosemirror-view';\nimport { Extension, type CoreEditor, type EditorKit } from '@kerebron/editor';\nimport { MenuItem } from '@kerebron/extension-menu';\nimport { Plus } from 'lucide-react';\n\nimport { cn } from '../../utils/cn';\nimport { useMessages } from '../../utils/messages';\nimport { Button } from '../Button';\nimport {\n Dropdown,\n DropdownItem,\n DropdownLabel,\n DropdownSeparator,\n DropdownSubmenu,\n} from '../Dropdown';\nimport { MacroLibrary, type Macro } from '../MacroLibrary';\nimport { Animated, AnimatedPresence } from '../../motion';\nimport { useDirection } from '../../hooks/useDirection';\nimport { useMediaQuery } from '../../hooks/useMediaQuery';\nimport { usePrefersReducedMotion } from '../../hooks/usePrefersReducedMotion';\nimport {\n RichEditor,\n type RichEditorHandle,\n type MediaUploadOptions,\n type MenuElement,\n type ModifyMenu,\n} from '../RichEditor';\nimport {\n processDictation,\n type RichTextEditorBlockMenuLabels,\n type RichTextVariable,\n} from '../RichTextEditor';\nimport type { TextAreaRichProps } from './TextAreaRich';\nimport { getSpeechRecognition, type SpeechRecognitionLike } from './speech';\n\n/**\n * Kerebron-backed TextAreaRich surface: ProseMirror underneath, the stock\n * Kerebron toolbar (hidden until requested), the block gutter menu, docked\n * macro panel, `.shortcut` expansion and dictation — same `TextAreaRichProps`\n * contract (`value`/`onChange` carry HTML) as the legacy surface, but\n * strictly controlled like a native input: an edit that `onChange` does not\n * echo back into `value` reverts (see {@link RichEditorProps.strictValue}).\n *\n * Exported as `TextAreaRich` from `@mieweb/ui/kerebron`, and the engine\n * behind the main bundle's `Textarea` — which is why the `@kerebron/*`\n * runtime peers are required: hosts install them and load\n * `@mieweb/ui/kerebron.css`. (Only the Yjs collab peers remain optional.)\n */\n\n/** Carries our keydown behaviors (macro shortcuts, Ctrl+/) into the editor. */\nclass TextAreaRichExtension extends Extension {\n name = 'textAreaRichShortcuts';\n constructor(\n private readonly onKeyDown: (\n view: EditorView,\n event: KeyboardEvent\n ) => boolean\n ) {\n super({});\n }\n override getProseMirrorPlugins(): Plugin[] {\n return [new Plugin({ props: { handleKeyDown: this.onKeyDown } })];\n }\n}\n\n/**\n * `CoreEditor.view` is typed `EditorView | DummyEditorView` (the dummy exists\n * only until `create()` returns, which is before `onReady` ever fires), so\n * every ready-time consumer can treat it as the real view.\n */\nconst viewOf = (editor: CoreEditor) => editor.view as EditorView;\n\n/**\n * CSS properties whose numeric values are valid without a `px` unit —\n * React's full unitless list, so `editorStyle` keeps the React.CSSProperties\n * contract (`{ flex: 1 }` must not become `flex: 1px`).\n */\nconst UNITLESS_STYLE_PROPS = new Set([\n 'animationIterationCount',\n 'aspectRatio',\n 'borderImageOutset',\n 'borderImageSlice',\n 'borderImageWidth',\n 'boxFlex',\n 'boxFlexGroup',\n 'boxOrdinalGroup',\n 'columnCount',\n 'columns',\n 'flex',\n 'flexGrow',\n 'flexPositive',\n 'flexShrink',\n 'flexNegative',\n 'flexOrder',\n 'fontWeight',\n 'gridArea',\n 'gridRow',\n 'gridRowEnd',\n 'gridRowSpan',\n 'gridRowStart',\n 'gridColumn',\n 'gridColumnEnd',\n 'gridColumnSpan',\n 'gridColumnStart',\n 'lineClamp',\n 'lineHeight',\n 'opacity',\n 'order',\n 'orphans',\n 'tabSize',\n 'widows',\n 'zIndex',\n 'zoom',\n // SVG-related\n 'fillOpacity',\n 'floodOpacity',\n 'stopOpacity',\n 'strokeDasharray',\n 'strokeDashoffset',\n 'strokeMiterlimit',\n 'strokeOpacity',\n 'strokeWidth',\n]);\n\n/**\n * Replace `[from, to]` (defaults: the current selection) with plain text,\n * mapping `\\n` to hard breaks, and put the caret after the insertion.\n */\nfunction insertPlainText(\n view: EditorView,\n text: string,\n from = view.state.selection.from,\n to = view.state.selection.to\n) {\n const { schema, selection, storedMarks } = view.state;\n // Typing at this caret would inherit the active marks (pending toggles\n // or the formatting at the position); composed insertions — dictation,\n // macros, shortcut phrases — must match instead of stripping them.\n const marks =\n (from === selection.from && to === selection.to ? storedMarks : null) ??\n view.state.doc.resolve(from).marks();\n const br = schema.nodes.br ?? schema.nodes.hard_break;\n const lines = text.replace(/\\r\\n?/g, '\\n').split('\\n');\n const nodes: PMNode[] = [];\n lines.forEach((line, index) => {\n if (index > 0) {\n if (br) nodes.push(br.create(null, null, marks));\n else if (line) nodes.push(schema.text(' ', marks));\n }\n if (line) nodes.push(schema.text(line, marks));\n });\n let tr = view.state.tr.replaceWith(from, to, nodes);\n const end = Math.min(\n from + nodes.reduce((size, node) => size + node.nodeSize, 0),\n tr.doc.content.size\n );\n tr = tr.setSelection(TextSelection.near(tr.doc.resolve(end)));\n view.dispatch(tr.scrollIntoView());\n}\n\n/** One empty textblock — the ProseMirror notion of \"nothing typed yet\". */\nfunction docIsEmpty(view: EditorView) {\n const { doc } = view.state;\n return (\n doc.childCount === 1 &&\n !!doc.firstChild &&\n doc.firstChild.isTextblock &&\n doc.firstChild.content.size === 0\n );\n}\n\n/** Gutter menu rows → Kerebron command names. */\nconst BLOCK_FORMAT_ITEMS: Array<{\n key: keyof RichTextEditorBlockMenuLabels;\n label: string;\n command: string;\n}> = [\n { key: 'text', label: 'Text', command: 'setParagraph' },\n { key: 'heading1', label: 'Heading 1', command: 'setHeading1' },\n { key: 'heading2', label: 'Heading 2', command: 'setHeading2' },\n { key: 'heading3', label: 'Heading 3', command: 'setHeading3' },\n { key: 'bulletList', label: 'Bullet list', command: 'toggleBulletList' },\n { key: 'numberedList', label: 'Numbered list', command: 'toggleOrderedList' },\n { key: 'quote', label: 'Quote', command: 'toggleBlockquote' },\n];\n\nexport interface TextAreaRichKerebronProps extends TextAreaRichProps {\n /**\n * How pasted/dropped media files are handled — most importantly\n * `uploadHandler`, without which every image is embedded in the document\n * as a base64 `data:` URL. Kerebron surface only; the legacy engine has no\n * media pipeline. See {@link RichEditorProps.mediaUpload}.\n */\n mediaUpload?: MediaUploadOptions;\n /**\n * Schema extensions to remove by name. The toolbar, input rules and paste\n * handling are schema-driven, so dropping a node removes the whole feature\n * in one move. Kerebron surface only. See\n * {@link RichEditorProps.omitExtensions}.\n */\n omitExtensions?: readonly string[];\n}\n\nconst TextAreaRichKerebron = React.forwardRef<\n HTMLDivElement,\n TextAreaRichKerebronProps\n>(\n (\n {\n value = '',\n onChange,\n placeholder,\n className,\n enableDictation = true,\n onDictationError,\n disabled = false,\n macros,\n defaultMacrosOpen = false,\n macrosOnFocus = false,\n compactMacros = false,\n onMacroInsert,\n macroLabels,\n onCreateMacro,\n variableGroups,\n toolbar,\n defaultToolbar = 'hidden',\n onToolbarChange,\n blockMenuLabels,\n id,\n readOnly = false,\n editorClassName,\n editorStyle,\n mediaUpload,\n omitExtensions,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n 'aria-describedby': ariaDescribedBy,\n 'aria-invalid': ariaInvalid,\n 'aria-required': ariaRequired,\n },\n ref\n ) => {\n const inert = disabled || readOnly;\n\n const wrapperRef = React.useRef<HTMLDivElement>(null);\n const gutterWrapperRef = React.useRef<HTMLDivElement>(null);\n const editorHandleRef = React.useRef<RichEditorHandle>(null);\n const editorRef = React.useRef<CoreEditor | null>(null);\n const [ready, setReady] = React.useState(false);\n // Hosts reach the editable region through the ref (focus, `dir`,\n // ARIA attributes), as with the legacy surface's contenteditable; the\n // wrapper only stands in until the editor mounts.\n React.useImperativeHandle(\n ref,\n () =>\n ready && editorRef.current\n ? (viewOf(editorRef.current).dom as HTMLDivElement)\n : wrapperRef.current!,\n [ready]\n );\n\n const [macrosOpen, setMacrosOpen] = React.useState(\n defaultMacrosOpen && !macrosOnFocus\n );\n const [uncontrolledToolbar, setUncontrolledToolbar] =\n React.useState(defaultToolbar);\n const toolbarVisible = (toolbar ?? uncontrolledToolbar) === 'visible';\n const [isListening, setIsListening] = React.useState(false);\n const [speechSupported, setSpeechSupported] = React.useState(false);\n const [isEmpty, setIsEmpty] = React.useState(true);\n // Offset of the editable below the (optional) toolbar, inside the wrapper.\n const [editorTop, setEditorTop] = React.useState(0);\n const [blockMenuOpen, setBlockMenuOpen] = React.useState(false);\n const [gutterTop, setGutterTop] = React.useState(4);\n const [variablesOpen, setVariablesOpen] = React.useState(false);\n // The toolbar's Variables button rect (relative to the gutter wrapper):\n // the searchable Dropdown anchors a React trigger exactly over it.\n const [variablesAnchor, setVariablesAnchor] = React.useState<{\n top: number;\n left: number;\n width: number;\n height: number;\n } | null>(null);\n\n const recognitionRef = React.useRef<SpeechRecognitionLike | null>(null);\n const isListeningRef = React.useRef(false);\n const shouldRestartRef = React.useRef(false);\n // Invalidates dictation starts still awaiting microphone permission.\n const dictationSessionRef = React.useRef(0);\n const hoverBlockRef = React.useRef<HTMLElement | null>(null);\n const blockTargetPosRef = React.useRef<number | null>(null);\n const firstBlockItemRef = React.useRef<HTMLButtonElement>(null);\n const macroPanelId = React.useId();\n\n const macroSidePanel = useMediaQuery('(min-width: 768px)');\n const prefersReducedMotion = usePrefersReducedMotion();\n // The field's inherited direction (not the document's): a local\n // dir=\"rtl\" subtree docks the panel at inline-end = left, so the motion\n // preset must slide it in from the same side.\n const direction = useDirection(wrapperRef);\n\n const hasMacros = Boolean(macros);\n const hasMacroEntries = Boolean(\n macros?.some((group) => group.macros.length > 0)\n );\n const hasVariables = Boolean(variableGroups && variableGroups.length > 0);\n // The gutter `+` stays discoverable on hover even while a focus-docked\n // field rests as a one-line input.\n const gutterActive = !inert;\n\n // Mount-time closures (the toolbar and keydown plugin are built once)\n // read the latest props/state through refs.\n const macrosRef = React.useRef(macros);\n macrosRef.current = macros;\n const hasMacrosRef = React.useRef(hasMacros);\n hasMacrosRef.current = hasMacros;\n const hasVariablesRef = React.useRef(hasVariables);\n hasVariablesRef.current = hasVariables;\n const variablesOpenRef = React.useRef(variablesOpen);\n variablesOpenRef.current = variablesOpen;\n const onMacroInsertRef = React.useRef(onMacroInsert);\n onMacroInsertRef.current = onMacroInsert;\n const onChangeRef = React.useRef(onChange);\n onChangeRef.current = onChange;\n const inertRef = React.useRef(inert);\n inertRef.current = inert;\n const macrosOpenRef = React.useRef(macrosOpen);\n macrosOpenRef.current = macrosOpen;\n const toolbarVisibleRef = React.useRef(toolbarVisible);\n toolbarVisibleRef.current = toolbarVisible;\n const dictationAvailableRef = React.useRef(false);\n dictationAvailableRef.current = enableDictation && speechSupported;\n const onDictationErrorRef = React.useRef(onDictationError);\n onDictationErrorRef.current = onDictationError;\n // Dictation labels have no prop route (macro labels do), so the host's\n // MessagesProvider is the translation path — like RichTextEditor's.\n const m = useMessages();\n\n const reportError = (message: string) => {\n if (onDictationErrorRef.current) onDictationErrorRef.current(message);\n else if (typeof console !== 'undefined') console.warn(message);\n };\n\n const setToolbarVisibility = (next: 'visible' | 'hidden') => {\n if (toolbar === undefined) setUncontrolledToolbar(next);\n onToolbarChange?.(next);\n };\n\n const focusEditor = () => editorHandleRef.current?.focus();\n\n /** The live ProseMirror view, once the editor is mounted. */\n const currentView = () =>\n editorRef.current ? viewOf(editorRef.current) : null;\n\n // RichEditor publishes edits asynchronously, but a host that takes over\n // macro insertion (`onMacroInsert` returning true) composes from its last\n // published value — so a token-removal edit must reach `onChange` before\n // the hook runs. These waiters bridge that gap.\n const changeWaitersRef = React.useRef<(() => void)[]>([]);\n // The doc as of the last `onChange` emission — when the live doc is ahead\n // of this, a publish is still in flight.\n const publishedDocRef = React.useRef<unknown>(null);\n const handleChange = (next: string) => {\n publishedDocRef.current = currentView()?.state.doc ?? null;\n onChangeRef.current?.(next);\n const waiters = changeWaitersRef.current;\n changeWaitersRef.current = [];\n for (const resolve of waiters) resolve();\n };\n /** Resolves after the next `onChange` emission (or a short fallback). */\n const afterNextChange = () =>\n new Promise<void>((resolve) => {\n const timer = setTimeout(resolve, 250);\n changeWaitersRef.current.push(() => {\n clearTimeout(timer);\n resolve();\n });\n });\n\n // --- Macro insertion ---\n\n const insertMacro = (macro: Macro) => {\n if (inertRef.current) return;\n if (!onMacroInsertRef.current) {\n const view = currentView();\n if (!view) return;\n view.focus();\n insertPlainText(view, macro.content);\n return;\n }\n // A host hook composes from the last *published* value — let any\n // in-flight publish land first, so a pick right after typing doesn't\n // overwrite the unpublished keystrokes.\n const view = currentView();\n const pending = view && view.state.doc !== publishedDocRef.current;\n const invoke = () => {\n if (inertRef.current) return; // went inert (or unmounted) waiting\n const liveView = currentView();\n if (!liveView) return;\n // Focus before composing: a pick must return the caret to the\n // editable even when a host hook handles the insertion itself\n // (mobile keyboards would otherwise dismiss between picks).\n liveView.focus();\n if (onMacroInsertRef.current?.(macro) === true) return;\n insertPlainText(liveView, macro.content);\n };\n if (pending) void afterNextChange().then(invoke);\n else invoke();\n };\n\n /** Typed `.shortcut` + space → macro expansion (space consumed). */\n const expandTypedShortcut = (view: EditorView): boolean => {\n const groups = macrosRef.current;\n if (!groups) return false;\n const { selection } = view.state;\n if (!selection.empty) return false;\n const { $from } = selection;\n // Leaf nodes (hard breaks) read as a newline: still one character, so\n // the position math below holds, and `\\S+` cannot run across a soft\n // line break — `.c` typed after Shift+Enter still expands.\n const textBefore = $from.parent.textBetween(\n 0,\n $from.parentOffset,\n undefined,\n '\\n'\n );\n const match = /(\\S+)$/.exec(textBefore);\n if (!match) return false;\n const lowered = match[1].toLowerCase();\n const macro = groups\n .flatMap((group) => group.macros)\n .find((candidate) => candidate.shortcut?.toLowerCase() === lowered);\n if (!macro) return false;\n\n const from = $from.pos - match[1].length;\n // Without a host hook the whole expansion is one synchronous\n // transaction (token replaced by content — one undo step, no race).\n if (!onMacroInsertRef.current) {\n insertPlainText(view, macro.content, from, $from.pos);\n return true;\n }\n // A host hook composes from the last *published* value, so the token\n // removal must reach `onChange` first. While that publish is pending,\n // further edits (or a moved caret) must not misplace the insertion:\n // map the deletion point through every transaction and give up if it\n // is deleted out from under us.\n const editor = editorRef.current;\n view.dispatch(view.state.tr.delete(from, $from.pos));\n if (!editor) return true;\n let insertAt = from;\n let targetValid = true;\n const trackInsertionPoint = (event: Event) => {\n const tr = (\n event as globalThis.CustomEvent<{ transaction?: Transaction }>\n ).detail?.transaction;\n if (!tr) return;\n const mapped = tr.mapping.mapResult(insertAt);\n if (mapped.deleted) targetValid = false;\n insertAt = mapped.pos;\n };\n editor.addEventListener('transaction', trackInsertionPoint);\n void afterNextChange().then(() => {\n editor.removeEventListener('transaction', trackInsertionPoint);\n // The field may have gone disabled/readOnly (or remounted) while\n // the token-removal publish was pending — `editable: false` does\n // not block programmatic dispatch, so recheck before composing.\n if (inertRef.current || editorRef.current !== editor) return;\n if (onMacroInsertRef.current?.(macro) === true) return;\n if (!targetValid) return;\n const liveView = viewOf(editor);\n liveView.focus();\n const at = Math.min(insertAt, liveView.state.doc.content.size);\n insertPlainText(liveView, macro.content, at, at);\n });\n return true;\n };\n\n // --- Variables menu ---\n\n /**\n * Insert the variable token at the caret as one ProseMirror transaction\n * (native undo step). The view keeps its selection state while focus\n * sits in the menu, so refocusing restores the caret by itself.\n */\n const insertVariable = (variable: RichTextVariable) => {\n if (inertRef.current) return;\n const view = currentView();\n if (!view) return;\n view.focus();\n insertPlainText(view, variable.insertValue ?? variable.value);\n };\n\n /** Close path: hand focus back to the editor when it sits in the menu. */\n const handleVariablesOpenChange = (open: boolean) => {\n if (\n !open &&\n document.activeElement?.closest('[data-slot=\"dropdown-menu\"]')\n ) {\n currentView()?.focus();\n }\n setVariablesOpen(open);\n };\n\n /** Anchor the menu at the (visible) toolbar Variables button and open. */\n const openVariablesMenu = () => {\n if (inertRef.current) return;\n const root = wrapperRef.current;\n const frame = gutterWrapperRef.current;\n if (!root || !frame) return;\n const visible = (candidate: HTMLElement) =>\n candidate.getBoundingClientRect().width > 0;\n // When the button sits in the overflow popup, the popup has already\n // closed (0×0) by the time its forwarded mousedown lands here — fall\n // back to the overflow toggle (where the user just clicked), then the\n // toolbar itself (unmeasured, e.g. jsdom, included: `run` can only\n // fire from a rendered toolbar).\n const anchor =\n Array.from(\n root.querySelectorAll<HTMLElement>('.tar-menu-variables')\n ).find(visible) ??\n Array.from(\n root.querySelectorAll<HTMLElement>('.kb-custom-menu__overflow-toggle')\n ).find(visible) ??\n root.querySelector<HTMLElement>('.kb-custom-menu');\n if (!anchor) return;\n const rect = anchor.getBoundingClientRect();\n const frameRect = frame.getBoundingClientRect();\n setVariablesAnchor({\n top: rect.top - frameRect.top,\n left: rect.left - frameRect.left,\n width: rect.width,\n height: rect.height,\n });\n setVariablesOpen(true);\n };\n\n const toggleVariablesMenu = () => {\n if (variablesOpenRef.current) handleVariablesOpenChange(false);\n else openVariablesMenu();\n };\n\n // --- Block gutter menu ---\n\n const resetGutter = () => {\n hoverBlockRef.current = null;\n setGutterTop(editorTop + 4);\n };\n\n const handleGutterMouseMove = (event: React.MouseEvent) => {\n if (blockMenuOpen) return;\n const view = currentView();\n const wrapper = gutterWrapperRef.current;\n if (!view || !wrapper) return;\n let target: HTMLElement | null = null;\n let top: number | null = null;\n for (const child of Array.from(view.dom.children)) {\n const rect = child.getBoundingClientRect();\n if (rect.width === 0 && rect.height === 0) continue;\n if (rect.top <= event.clientY) {\n target = child as HTMLElement;\n top = rect.top;\n }\n }\n if (!target || top === null) {\n resetGutter();\n return;\n }\n hoverBlockRef.current = target;\n const wrapperTop = wrapper.getBoundingClientRect().top;\n const next = Math.max(Math.round(top - wrapperTop), editorTop + 4);\n setGutterTop((current) => (current === next ? current : next));\n };\n\n /** Dropdown open/close driven by the gutter trigger (mouse path). */\n const handleBlockMenuOpenChange = (open: boolean) => {\n const view = currentView();\n if (open) {\n const block = hoverBlockRef.current;\n blockTargetPosRef.current =\n view && block && view.dom.contains(block)\n ? view.posAtDOM(block, 0)\n : null;\n } else if (view && document.activeElement?.closest('[role=\"menu\"]')) {\n // Escape: focus sits on a menu item about to unmount — hand it back\n // to the editor so typing resumes.\n view.focus();\n }\n setBlockMenuOpen(open);\n };\n\n /** Ctrl/Cmd+/ — open the menu targeting the caret's block. */\n const openBlockMenuAtCaret = () => {\n const view = currentView();\n const wrapper = gutterWrapperRef.current;\n if (view && wrapper) {\n const { from } = view.state.selection;\n blockTargetPosRef.current = from;\n try {\n const coords = view.coordsAtPos(from);\n const wrapperTop = wrapper.getBoundingClientRect().top;\n setGutterTop(\n Math.max(Math.round(coords.top - wrapperTop), editorTop + 4)\n );\n } catch {\n // Position lookup can fail mid-update; the menu still opens.\n }\n }\n setBlockMenuOpen(true);\n };\n\n /** Put the selection at the menu's captured target block. */\n const applyBlockTarget = (view: EditorView) => {\n const pos = blockTargetPosRef.current;\n if (pos === null) return;\n const clamped = Math.min(pos, view.state.doc.content.size);\n view.dispatch(\n view.state.tr.setSelection(\n TextSelection.near(view.state.doc.resolve(clamped))\n )\n );\n };\n\n const applyBlockFormat = (command: string) => {\n const editor = editorRef.current;\n if (inert || !editor) return;\n setBlockMenuOpen(false);\n const view = viewOf(editor);\n view.focus();\n applyBlockTarget(view);\n (editor.run as Record<string, undefined | (() => boolean)>)[command]?.();\n };\n\n // Menus move focus to their first item on open (WAI-ARIA menu pattern);\n // required for the Ctrl/Cmd+/ path, where focus is still in the editor.\n React.useEffect(() => {\n if (!blockMenuOpen) return;\n const frame = requestAnimationFrame(() =>\n firstBlockItemRef.current?.focus()\n );\n return () => cancelAnimationFrame(frame);\n }, [blockMenuOpen]);\n\n // --- Dictation ---\n\n const toggleDictation = React.useRef(async () => {\n const SpeechRecognition = getSpeechRecognition();\n if (!SpeechRecognition) return;\n\n // Stop anything live — or still pending between `start()` and\n // `onstart`, when nothing is listening yet.\n if (isListeningRef.current || recognitionRef.current) {\n stopDictation();\n return;\n }\n\n const session = ++dictationSessionRef.current;\n try {\n const stream = await navigator.mediaDevices.getUserMedia({\n audio: true,\n });\n stream.getTracks().forEach((track) => track.stop());\n } catch {\n reportError(\n 'Microphone access is required for dictation. Please allow microphone access in your browser settings and try again.'\n );\n return;\n }\n\n // The toolbar (and its Stop control) may have been hidden — or the\n // editor made disabled/readOnly or unmounted — while awaiting\n // microphone permission; do not start an unstoppable, read-only or\n // orphaned session.\n if (session !== dictationSessionRef.current) return;\n if (!toolbarVisibleRef.current || inertRef.current) return;\n\n const recognition = new SpeechRecognition();\n recognition.continuous = true;\n recognition.interimResults = true;\n recognition.lang = 'en-US';\n recognition.maxAlternatives = 1;\n\n recognition.onstart = () => {\n // A stop issued between `start()` and this callback already tore the\n // session down — do not arm an unstoppable restart loop.\n if (session !== dictationSessionRef.current) {\n try {\n recognition.stop();\n } catch {\n // Already stopped.\n }\n return;\n }\n setIsListening(true);\n isListeningRef.current = true;\n shouldRestartRef.current = true;\n };\n\n recognition.onresult = (event) => {\n // Results landing after Stop retired this session (or after a\n // restart swapped recognitions) must not focus the editor or\n // insert text.\n if (\n session !== dictationSessionRef.current ||\n recognitionRef.current !== recognition\n ) {\n return;\n }\n if (inertRef.current) return;\n let finalTranscript = '';\n for (let i = event.resultIndex; i < event.results.length; i++) {\n const result = event.results[i];\n if (result.isFinal) finalTranscript += result[0].transcript;\n }\n const view = currentView();\n if (finalTranscript && view) {\n view.focus();\n insertPlainText(view, processDictation(finalTranscript) + ' ');\n }\n };\n\n recognition.onerror = (event) => {\n // A retired session's failures must not clear the live session's\n // listening state.\n if (\n session !== dictationSessionRef.current ||\n recognitionRef.current !== recognition\n ) {\n return;\n }\n if (event.error === 'no-speech' || event.error === 'aborted') return;\n if (event.error === 'not-allowed') {\n reportError(\n 'Microphone access was denied. Please allow microphone access in your browser settings and try again.'\n );\n shouldRestartRef.current = false;\n isListeningRef.current = false;\n setIsListening(false);\n return;\n }\n if (event.error === 'network') return;\n shouldRestartRef.current = false;\n isListeningRef.current = false;\n setIsListening(false);\n };\n\n recognition.onend = () => {\n // The listening refs are shared across sessions: a stop + restart\n // inside this callback's window would read the NEW session's flags\n // and resurrect this retired recognition beside it. Only the\n // recognition still owning the session may restart — checked both\n // here and again after the delay.\n if (\n session === dictationSessionRef.current &&\n shouldRestartRef.current &&\n isListeningRef.current &&\n !inertRef.current\n ) {\n setTimeout(() => {\n if (\n session === dictationSessionRef.current &&\n shouldRestartRef.current &&\n isListeningRef.current &&\n !inertRef.current\n ) {\n try {\n recognition.start();\n } catch {\n shouldRestartRef.current = false;\n isListeningRef.current = false;\n if (recognitionRef.current === recognition)\n recognitionRef.current = null;\n setIsListening(false);\n }\n }\n }, 100);\n } else {\n // Ended for good — release the ref so the next toggle starts a\n // fresh session instead of \"stopping\" a dead one. A retired\n // session must not touch the live one's listening state.\n if (recognitionRef.current === recognition)\n recognitionRef.current = null;\n if (session === dictationSessionRef.current) setIsListening(false);\n }\n };\n\n recognitionRef.current = recognition;\n try {\n recognition.start();\n } catch {\n recognitionRef.current = null;\n reportError('Failed to start speech recognition. Please try again.');\n }\n }).current;\n\n const stopDictation = React.useCallback(() => {\n // Invalidate any start still awaiting microphone permission — or a\n // recognition whose `onstart` hasn't fired yet — and tear down\n // unconditionally: `isListeningRef` is false in that pending window,\n // so an early-return would leave the recognition to arm itself with\n // no Stop control visible.\n dictationSessionRef.current += 1;\n shouldRestartRef.current = false;\n isListeningRef.current = false;\n const recognition = recognitionRef.current;\n recognitionRef.current = null;\n try {\n recognition?.stop();\n } catch {\n // Stopping before `onstart` can throw; the session bump above\n // already keeps it from arming.\n }\n setIsListening(false);\n }, []);\n\n React.useEffect(() => {\n setSpeechSupported(Boolean(getSpeechRecognition()));\n }, []);\n\n // Hiding the toolbar hides the Stop control; never leave an orphaned\n // session running. Same when the editor turns disabled/readOnly or the\n // dictation feature itself is switched off (which hides the button).\n React.useEffect(() => {\n if (!toolbarVisible || inert || !enableDictation) stopDictation();\n }, [toolbarVisible, inert, enableDictation, stopDictation]);\n\n // Hiding the toolbar hides the Variables anchor button; never leave the\n // menu floating over nothing (same when disabled/readOnly, or when\n // variableGroups empties — otherwise restoring the groups would reopen\n // the menu at its stale anchor without user activation).\n React.useEffect(() => {\n if (!toolbarVisible || inert || !hasVariables) setVariablesOpen(false);\n }, [toolbarVisible, inert, hasVariables]);\n\n // A resize can reflow the toolbar (buttons moving into or out of the\n // overflow popup), leaving the overlay anchored to stale coordinates\n // over some other control. The menu is transient — close it rather\n // than track the moving button. Observe the TOOLBAR, not the whole\n // field: opening the menu moves focus into the portaled panel, which\n // drops the field's :hover/:focus-within gutter padding and can rewrap\n // the text — editable-height churn must not dismiss the menu. Close\n // through the open-change handler so focus returns to the editor when\n // it was sitting inside the menu.\n React.useEffect(() => {\n if (!variablesOpen) return;\n const toolbar =\n wrapperRef.current?.querySelector<HTMLElement>('.kb-custom-menu');\n if (!toolbar || typeof ResizeObserver === 'undefined') return;\n let initial = true; // observe() always fires once immediately\n const observer = new ResizeObserver(() => {\n if (initial) {\n initial = false;\n return;\n }\n handleVariablesOpenChangeRef.current(false);\n });\n observer.observe(toolbar);\n return () => observer.disconnect();\n }, [variablesOpen]);\n\n // End-of-life cleanup.\n React.useEffect(() => stopDictation, [stopDictation]);\n\n // --- Kerebron toolbar additions (built once, read state through refs) ---\n\n const openBlockMenuAtCaretRef = React.useRef(openBlockMenuAtCaret);\n openBlockMenuAtCaretRef.current = openBlockMenuAtCaret;\n const expandTypedShortcutRef = React.useRef(expandTypedShortcut);\n expandTypedShortcutRef.current = expandTypedShortcut;\n const toggleVariablesMenuRef = React.useRef(toggleVariablesMenu);\n toggleVariablesMenuRef.current = toggleVariablesMenu;\n const handleVariablesOpenChangeRef = React.useRef(\n handleVariablesOpenChange\n );\n handleVariablesOpenChangeRef.current = handleVariablesOpenChange;\n\n const [menuAddon] = React.useState(() => {\n // Icon-only (filled Material-style paths, like Kerebron's stock\n // items): text labels clip to an empty square in the 32px overflow\n // grid and force the popup onto extra rows.\n const macrosItem = new MenuItem({\n icon: {\n width: 24,\n height: 24,\n // Material Symbols \"text snippet\" (Apache-2.0)\n path: 'M20.41 8.41l-4.83-4.83c-.37-.37-.88-.58-1.41-.58H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V9.83c0-.53-.21-1.04-.59-1.42zM7 7h7v2H7V7zm10 10H7v-2h10v2zm0-4H7v-2h10v2z',\n },\n title: macroLabels?.showMacros ?? 'Show macros',\n class: 'tar-menu-macros',\n select: () => hasMacrosRef.current,\n enable: () => !inertRef.current,\n active: () => macrosOpenRef.current,\n run: () => {\n setMacrosOpen((open) => !open);\n return true;\n },\n });\n const dictateItem = new MenuItem({\n icon: {\n width: 24,\n height: 24,\n // Material Symbols \"mic\" (Apache-2.0)\n path: 'M12 14c1.66 0 2.99-1.34 2.99-3L15 5c0-1.66-1.34-3-3-3S9 3.34 9 5v6c0 1.66 1.34 3 3 3zm5.3-3c0 3-2.54 5.1-5.3 5.1S6.7 14 6.7 11H5c0 3.41 2.72 6.23 6 6.72V21h2v-3.28c3.28-.48 6-3.3 6-6.72h-1.7z',\n },\n title: m('Start dictation'),\n class: 'tar-menu-dictate',\n select: () => dictationAvailableRef.current,\n enable: () => !inertRef.current,\n active: () => isListeningRef.current,\n run: () => {\n void toggleDictation();\n return true;\n },\n });\n const variablesItem = new MenuItem({\n icon: {\n width: 24,\n height: 24,\n // Material Symbols \"data object\" (Apache-2.0)\n path: 'M4 7v2c0 .55-.45 1-1 1H2v4h1c.55 0 1 .45 1 1v2c0 1.65 1.35 3 3 3h3v-2H7c-.55 0-1-.45-1-1v-2c0-1.3-.84-2.42-2-2.83v-.34C5.16 11.42 6 10.3 6 9V7c0-.55.45-1 1-1h3V4H7C5.35 4 4 5.35 4 7zm17 3c-.55 0-1-.45-1-1V7c0-1.65-1.35-3-3-3h-3v2h3c.55 0 1 .45 1 1v2c0 1.3.84 2.42 2 2.83v.34c-1.16.41-2 1.53-2 2.83v2c0 .55-.45 1-1 1h-3v2h3c1.65 0 3-1.35 3-3v-2c0-.55.45-1 1-1h1v-4h-1z',\n },\n title: m('Insert variable'),\n class: 'tar-menu-variables',\n select: () => hasVariablesRef.current,\n enable: () => !inertRef.current,\n active: () => variablesOpenRef.current,\n run: () => {\n toggleVariablesMenuRef.current();\n return true;\n },\n });\n const modifyMenu: ModifyMenu = (menus: MenuElement[][]) => [\n ...menus,\n // The patched MenuItem types `render().dom` as nullable, which no\n // longer satisfies MenuElement; our items always render a button.\n [variablesItem, macrosItem, dictateItem] as unknown as MenuElement[],\n ];\n const kit: EditorKit = {\n getExtensions: () => [\n new TextAreaRichExtension((view, event) => {\n if (inertRef.current) return false;\n if (\n event.key === '/' &&\n (event.ctrlKey || event.metaKey) &&\n !event.altKey\n ) {\n openBlockMenuAtCaretRef.current();\n return true;\n }\n if (\n event.key !== ' ' ||\n event.isComposing ||\n event.ctrlKey ||\n event.metaKey ||\n event.altKey\n ) {\n return false;\n }\n return expandTypedShortcutRef.current(view);\n }),\n ],\n };\n return { modifyMenu, kits: [kit] };\n });\n\n // The toolbar only repaints items on document/selection changes, so\n // React-side state (panel open, dictation) is synced into our injected\n // buttons directly. Kerebron's overflow popup builds FRESH buttons each\n // time it opens — construction-time labels and no aria-pressed — so a\n // childList observer re-syncs every rendered copy on arrival.\n React.useEffect(() => {\n const root = wrapperRef.current;\n if (!root || !ready) return;\n const sync = () => {\n // Disabled/readOnly must neutralize the stock toolbar too — its\n // buttons dispatch regardless of the view's `editable` prop. `inert`\n // blocks both pointer and keyboard access.\n for (const toolbar of root.querySelectorAll<HTMLElement>(\n '.kb-custom-menu, .kb-custom-menu__overflow-menu'\n )) {\n toolbar.inert = inert;\n }\n // The menu plugin re-runs item `update` callbacks only on document/\n // selection changes, so a button rendered while disabled/readOnly\n // keeps its disabled state when the field becomes editable without a\n // transaction — reconcile it here for every rendered copy.\n for (const macrosButton of root.querySelectorAll<HTMLElement>(\n '.tar-menu-macros'\n )) {\n macrosButton.style.display = hasMacros ? '' : 'none';\n macrosButton.classList.toggle('kb-menu__button--disabled', inert);\n macrosButton.setAttribute('aria-disabled', String(inert));\n macrosButton.classList.toggle('kb-menu__button--active', macrosOpen);\n macrosButton.setAttribute('aria-pressed', String(macrosOpen));\n const title = macrosOpen\n ? (macroLabels?.hideMacros ?? 'Hide macros')\n : (macroLabels?.showMacros ?? 'Show macros');\n macrosButton.setAttribute('title', title);\n macrosButton.setAttribute('aria-label', title);\n }\n for (const dictateButton of root.querySelectorAll<HTMLElement>(\n '.tar-menu-dictate'\n )) {\n dictateButton.style.display =\n enableDictation && speechSupported ? '' : 'none';\n dictateButton.classList.toggle('kb-menu__button--disabled', inert);\n dictateButton.setAttribute('aria-disabled', String(inert));\n dictateButton.classList.toggle(\n 'kb-menu__button--active',\n isListening\n );\n dictateButton.setAttribute('aria-pressed', String(isListening));\n const title = isListening\n ? m('Stop dictation')\n : m('Start dictation');\n dictateButton.setAttribute('title', title);\n dictateButton.setAttribute('aria-label', title);\n }\n for (const variablesButton of root.querySelectorAll<HTMLElement>(\n '.tar-menu-variables'\n )) {\n variablesButton.style.display = hasVariables ? '' : 'none';\n variablesButton.classList.toggle('kb-menu__button--disabled', inert);\n variablesButton.setAttribute('aria-disabled', String(inert));\n variablesButton.classList.toggle(\n 'kb-menu__button--active',\n variablesOpen\n );\n variablesButton.setAttribute('aria-haspopup', 'menu');\n variablesButton.setAttribute('aria-expanded', String(variablesOpen));\n const title = m('Insert variable');\n variablesButton.setAttribute('title', title);\n variablesButton.setAttribute('aria-label', title);\n }\n };\n sync();\n // Attribute writes don't retrigger a childList-only observer, so the\n // re-sync cannot loop.\n const observer = new MutationObserver((mutations) => {\n if (mutations.some((mutation) => mutation.addedNodes.length > 0)) {\n sync();\n }\n });\n observer.observe(root, { childList: true, subtree: true });\n return () => observer.disconnect();\n }, [\n ready,\n inert,\n hasMacros,\n macrosOpen,\n macroLabels,\n hasVariables,\n variablesOpen,\n enableDictation,\n speechSupported,\n isListening,\n toolbarVisible,\n m,\n ]);\n\n // --- Editor wiring ---\n\n const handleReady = (editor: CoreEditor) => {\n editorRef.current = editor;\n // The initial load publishes nothing; the loaded doc is the baseline.\n publishedDocRef.current = viewOf(editor).state.doc;\n setIsEmpty(docIsEmpty(viewOf(editor)));\n editor.addEventListener('transaction', () => {\n if (editorRef.current !== editor) return;\n setIsEmpty(docIsEmpty(viewOf(editor)));\n });\n setReady(true);\n };\n\n // The editable region's identity: ARIA naming, validation state and the\n // host-given id all live on the ProseMirror surface, like the legacy\n // contenteditable. setProps merges, so this never clobbers editability.\n React.useEffect(() => {\n const view = currentView();\n if (!view || !ready) return;\n view.setProps({\n attributes: {\n role: 'textbox',\n 'aria-multiline': 'true',\n ...(id ? { id } : {}),\n ...((ariaLabel ?? placeholder)\n ? { 'aria-label': (ariaLabel ?? placeholder) as string }\n : {}),\n ...(ariaLabelledBy ? { 'aria-labelledby': ariaLabelledBy } : {}),\n ...(ariaDescribedBy ? { 'aria-describedby': ariaDescribedBy } : {}),\n ...(ariaInvalid ? { 'aria-invalid': String(ariaInvalid) } : {}),\n // Booleanish: the string \"false\" must not read as required.\n ...(ariaRequired !== undefined\n ? { 'aria-required': String(ariaRequired) }\n : {}),\n ...(readOnly ? { 'aria-readonly': 'true' } : {}),\n ...(disabled ? { 'aria-disabled': 'true' } : {}),\n // Read-only keeps keyboard focus and text selection available;\n // ProseMirror drops natural tabbability once `editable` is false.\n tabindex: disabled ? '-1' : '0',\n // setProps replaces the create-time attributes, so the base\n // kb-editor class must be restated alongside any custom class.\n class: editorClassName ? `kb-editor ${editorClassName}` : 'kb-editor',\n },\n });\n }, [\n ready,\n id,\n ariaLabel,\n placeholder,\n ariaLabelledBy,\n ariaDescribedBy,\n ariaInvalid,\n ariaRequired,\n readOnly,\n disabled,\n editorClassName,\n ]);\n\n // Read-only keeps the region focusable/selectable but blocks edits —\n // enforced by RichEditor's own `readOnly` prop from creation (so the\n // surface is locked even while the initial document load is in flight).\n\n const appliedEditorStyle = React.useRef<\n Array<[HTMLElement['style'], string]>\n >([]);\n React.useEffect(() => {\n const view = currentView();\n const wrapper = wrapperRef.current;\n if (!view || !wrapper || !ready) return;\n // React style contract: camelCase keys, numbers in px (unless the\n // property is unitless — and custom properties pass through as\n // authored, never gaining a unit), and removed keys actually un-apply.\n const editableStyle = (view.dom as HTMLElement).style;\n for (const [style, property] of appliedEditorStyle.current) {\n style.removeProperty(property);\n }\n appliedEditorStyle.current = [];\n if (!editorStyle) return;\n for (const [key, raw] of Object.entries(editorStyle)) {\n if (raw === null || raw === undefined) continue;\n const isCustomProperty = key.startsWith('--');\n const property = isCustomProperty\n ? key\n : key.replace(/[A-Z]/g, (char) => `-${char.toLowerCase()}`);\n const value =\n typeof raw === 'number' &&\n !isCustomProperty &&\n !UNITLESS_STYLE_PROPS.has(key)\n ? `${raw}px`\n : String(raw);\n // Custom properties land on the wrapper so they inherit to the\n // editable (whose kerebron.css metrics read them) AND the overlaid\n // placeholder; everything else styles the editable directly.\n const style = isCustomProperty ? wrapper.style : editableStyle;\n style.setProperty(property, value);\n appliedEditorStyle.current.push([style, property]);\n }\n }, [ready, editorStyle]);\n\n // The editable sits below the (optional) toolbar inside the gutter\n // wrapper; everything anchored beside it (placeholder, gutter +, docked\n // macro panel) offsets by the toolbar's live height.\n React.useEffect(() => {\n const view = currentView();\n const wrapper = gutterWrapperRef.current;\n if (!view || !wrapper || !ready) return;\n const measure = () => {\n const top = Math.max(\n Math.round(\n view.dom.getBoundingClientRect().top -\n wrapper.getBoundingClientRect().top\n ),\n 0\n );\n setEditorTop((current) => (current === top ? current : top));\n // A hovered block may have been deleted since; a detached node must\n // not pin the gutter button to its old offset. A still-connected one\n // moved with the toolbar's height change, so follow it — leaving the\n // stale offset would park the + button under the new toolbar.\n const hovered = hoverBlockRef.current;\n if (hovered?.isConnected) {\n const next = Math.max(\n Math.round(\n hovered.getBoundingClientRect().top -\n wrapper.getBoundingClientRect().top\n ),\n top + 4\n );\n setGutterTop((current) => (current === next ? current : next));\n } else {\n hoverBlockRef.current = null;\n setGutterTop(top + 4);\n }\n };\n measure();\n // Re-measure when the toolbar wraps to more/fewer rows.\n const observer = new ResizeObserver(measure);\n observer.observe(wrapper);\n return () => observer.disconnect();\n }, [ready, toolbarVisible]);\n\n return (\n <div\n ref={wrapperRef}\n data-slot=\"textarea-rich\"\n data-toolbar={toolbarVisible ? 'visible' : 'hidden'}\n data-inert={inert ? '' : undefined}\n data-macros-open={hasMacros && macrosOpen ? '' : undefined}\n data-compact-macros={compactMacros ? '' : undefined}\n data-gutter={gutterActive ? '' : undefined}\n data-block-menu={blockMenuOpen ? '' : undefined}\n className={cn(\n 'border-input rounded-lg border',\n 'transition-colors duration-200',\n 'focus-within:ring-ring focus-within:border-transparent focus-within:ring-2',\n 'flex flex-col',\n disabled && 'bg-muted/20',\n className\n )}\n onFocus={\n hasMacros && macrosOnFocus ? () => setMacrosOpen(true) : undefined\n }\n onBlur={\n hasMacros && macrosOnFocus\n ? (event) => {\n const related = event.relatedTarget as HTMLElement | null;\n if (related && event.currentTarget.contains(related)) return;\n // The block gutter's dropdown — and its \"Insert macro\"\n // submenu — mount in portals under document.body (outside\n // this frame); focus moving into our own menu tree is an\n // internal move, not leaving the field. Walk each menu back\n // to its trigger (a submenu's trigger sits in the parent\n // menu's portal) until one lands inside this frame.\n let menu = related?.closest<HTMLElement>('[role=\"menu\"]');\n while (menu && menu.id) {\n const trigger = document.querySelector(\n `[aria-controls=\"${globalThis.CSS.escape(menu.id)}\"]`\n );\n if (!trigger) break;\n if (event.currentTarget.contains(trigger)) return;\n menu = trigger.closest<HTMLElement>('[role=\"menu\"]');\n }\n setMacrosOpen(false);\n }\n : undefined\n }\n >\n <div className=\"relative flex min-h-0 flex-1 flex-col\">\n <div\n ref={gutterWrapperRef}\n data-slot=\"textarea-rich-body\"\n className={cn('relative flex-1', 'group/tar-body')}\n onMouseMove={gutterActive ? handleGutterMouseMove : undefined}\n >\n {gutterActive && (\n // eslint-disable-next-line jsx-a11y/no-static-element-interactions -- mousedown here only guards editor focus (preventDefault); the real controls inside are native buttons.\n <div\n data-slot=\"textarea-rich-block-gutter\"\n className=\"absolute start-1 z-10\"\n style={{ top: gutterTop }}\n // Keep the editor focused through gutter interaction (see\n // the legacy surface for the full iOS rationale).\n onMouseDown={(event) => event.preventDefault()}\n >\n <Dropdown\n open={blockMenuOpen}\n onOpenChange={handleBlockMenuOpenChange}\n placement=\"bottom-start\"\n trigger={\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className={cn(\n 'h-6 w-6 p-0',\n 'opacity-0 transition-opacity',\n 'group-hover/tar-body:opacity-100',\n 'focus-visible:opacity-100',\n '[@media(hover:none)]:opacity-100',\n blockMenuOpen && 'opacity-100'\n )}\n aria-label={blockMenuLabels?.blockMenu ?? 'Block menu'}\n title={blockMenuLabels?.blockMenu ?? 'Block menu'}\n >\n <Plus className=\"h-4 w-4\" />\n </Button>\n }\n >\n {BLOCK_FORMAT_ITEMS.map((item, index) => (\n <DropdownItem\n key={item.key}\n ref={index === 0 ? firstBlockItemRef : undefined}\n onClick={() => applyBlockFormat(item.command)}\n >\n {blockMenuLabels?.[item.key] ?? item.label}\n </DropdownItem>\n ))}\n <DropdownSeparator />\n {hasMacros && macros && (\n <>\n <DropdownSubmenu\n label={blockMenuLabels?.insertMacro ?? 'Insert macro'}\n disabled={!hasMacroEntries}\n >\n {blockMenuOpen &&\n macros.flatMap((group) => [\n ...(macros.length > 1\n ? [\n <DropdownLabel key={`h:${group.id}`}>\n {group.label}\n </DropdownLabel>,\n ]\n : []),\n ...group.macros.map((macro) => (\n <DropdownItem\n key={`m:${JSON.stringify([group.id, macro.id])}`}\n className=\"[&>[data-slot=dropdown-item-label]]:min-w-0 [&>[data-slot=dropdown-item-label]]:flex-1\"\n onClick={() => {\n setBlockMenuOpen(false);\n const view = currentView();\n if (view) {\n view.focus();\n // Insertion lands at the menu's target\n // block, mirroring the panel flow.\n applyBlockTarget(view);\n }\n insertMacro(macro);\n }}\n >\n <span className=\"flex min-w-0 items-center gap-2\">\n {macro.shortcut && (\n <span\n dir=\"ltr\"\n className=\"border-border bg-background text-muted-foreground rounded border px-1 font-mono text-[11px]\"\n >\n {macro.shortcut}\n </span>\n )}\n <span className=\"min-w-0 flex-1 truncate\">\n {macro.label}\n </span>\n </span>\n </DropdownItem>\n )),\n ])}\n </DropdownSubmenu>\n <DropdownItem\n onClick={() => {\n setBlockMenuOpen(false);\n setMacrosOpen(true);\n focusEditor();\n }}\n >\n {blockMenuLabels?.showMacroLibrary ??\n 'Show macro library'}\n </DropdownItem>\n <DropdownSeparator />\n </>\n )}\n <DropdownItem\n onClick={() => {\n setBlockMenuOpen(false);\n setToolbarVisibility(\n toolbarVisible ? 'hidden' : 'visible'\n );\n focusEditor();\n }}\n >\n {toolbarVisible\n ? (blockMenuLabels?.hideToolbar ?? 'Hide toolbar')\n : (blockMenuLabels?.showToolbar ?? 'Show toolbar')}\n </DropdownItem>\n </Dropdown>\n </div>\n )}\n {isEmpty && placeholder && (\n <div\n aria-hidden=\"true\"\n className={cn(\n 'text-muted-foreground pointer-events-none absolute start-0 end-0 z-[1]',\n 'truncate px-3 py-[7px]',\n 'transition-[padding] duration-200 motion-reduce:transition-none',\n // Mirrors the editable's sliding gutter indent (permanent\n // on touch devices, where the + trigger is always visible).\n gutterActive &&\n 'group-focus-within/tar-body:ps-10 group-hover/tar-body:ps-10 [@media(hover:none)]:ps-10',\n gutterActive && blockMenuOpen && 'ps-10',\n hasMacros && macrosOpen && 'md:me-72',\n editorClassName\n )}\n style={{\n top: editorTop,\n // Match the editable's metrics by construction: the same\n // variables (inherited from the wrapper) with the same\n // kerebron.css fallbacks that size the .kb-editor rule.\n fontSize: 'var(--textarea-rich-font-size, 1rem)',\n lineHeight: 'var(--textarea-rich-line-height, 1.5rem)',\n }}\n >\n {placeholder}\n </div>\n )}\n <RichEditor\n ref={editorHandleRef}\n value={value}\n onChange={handleChange}\n valueType=\"text/html\"\n strictValue\n modifyMenu={menuAddon.modifyMenu}\n editorKits={menuAddon.kits}\n mediaUpload={mediaUpload}\n omitExtensions={omitExtensions}\n onReady={handleReady}\n disabled={disabled}\n readOnly={readOnly}\n />\n {hasVariables && variablesOpen && variablesAnchor && (\n // Invisible React anchor laid exactly over the toolbar's\n // Variables button: the Dropdown positions off it, and the\n // trigger span swallows a toggle-off click before it can\n // reach the Kerebron button (whose `run` would reopen).\n // eslint-disable-next-line jsx-a11y/no-static-element-interactions -- mousedown here only guards editor focus (preventDefault); the a11y contract lives on the real toolbar button underneath.\n <div\n data-slot=\"textarea-rich-variables-anchor\"\n className=\"absolute z-10\"\n style={variablesAnchor}\n // Keep the editor focused when the anchor itself is pressed\n // (see the block gutter above for the iOS rationale). The\n // portaled menu's React events bubble through here too —\n // those keep their defaults (caret placement and drag\n // selection in the search input need them).\n onMouseDown={(event) => {\n if (event.currentTarget.contains(event.target as Node)) {\n event.preventDefault();\n }\n }}\n >\n <Dropdown\n open={variablesOpen}\n onOpenChange={handleVariablesOpenChange}\n placement=\"bottom-start\"\n width={240}\n searchable\n searchPlaceholder={m('Search variables…')}\n searchAriaLabel={m('Search template variables')}\n searchEmptyState={m('No matching variables')}\n trigger={\n // Explicit size: the Dropdown's inline-flex anchor\n // container sizes to this span, matching the button.\n <span\n aria-hidden=\"true\"\n className=\"block\"\n style={{\n width: variablesAnchor.width,\n height: variablesAnchor.height,\n }}\n />\n }\n >\n {variableGroups!.map((group, groupIndex) => (\n <React.Fragment key={group.label}>\n {groupIndex > 0 && <DropdownSeparator />}\n <DropdownLabel>{group.label}</DropdownLabel>\n {group.variables.map((variable) => (\n <DropdownItem\n key={variable.value}\n onClick={() => {\n handleVariablesOpenChange(false);\n insertVariable(variable);\n }}\n >\n {variable.label}\n </DropdownItem>\n ))}\n </React.Fragment>\n ))}\n </Dropdown>\n </div>\n )}\n </div>\n\n {hasMacros && (\n <AnimatedPresence>\n {macrosOpen && (\n <Animated\n key=\"macro-panel\"\n preset={macroSidePanel ? 'menu' : 'collapse'}\n enabled={macroSidePanel || !prefersReducedMotion}\n mode=\"presence\"\n custom={direction === 'rtl' ? 'left' : 'right'}\n fallbackClassName=\"animate-fade-in\"\n className=\"border-border flex max-h-72 flex-col overflow-hidden border-t md:absolute md:end-0 md:bottom-0 md:max-h-none md:w-72 md:overflow-visible md:border-s md:border-t-0\"\n // Docked below the toolbar (top only applies when the\n // panel goes absolute at md:).\n style={{ top: editorTop }}\n >\n <MacroLibrary\n id={macroPanelId}\n groups={macros!}\n onSelect={insertMacro}\n targetLabel={ariaLabel ?? placeholder}\n onClose={\n macrosOnFocus\n ? undefined\n : () => {\n setMacrosOpen(false);\n focusEditor();\n }\n }\n onCreateMacro={onCreateMacro}\n labels={macroLabels}\n compact={compactMacros}\n className=\"min-h-0 flex-1\"\n />\n </Animated>\n )}\n </AnimatedPresence>\n )}\n </div>\n </div>\n );\n }\n);\n\nTextAreaRichKerebron.displayName = 'TextAreaRichKerebron';\n\nexport { TextAreaRichKerebron };\n"]}
|