@bikdotai/bik-component-library 0.0.817-beta.12 → 0.0.817-beta.13
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/cjs/components/template-preview/RCS/RCSChatPreview.js +1 -1
- package/dist/cjs/components/template-preview/RCS/RCSChatPreview.js.map +1 -1
- package/dist/cjs/components/template-preview/helpers/TemplateCreatorHelper.js +1 -1
- package/dist/cjs/components/template-preview/helpers/TemplateCreatorHelper.js.map +1 -1
- package/dist/cjs/components/template-preview/models/RCSTemplate.js.map +1 -1
- package/dist/cjs/editor/BikEditor.js +1 -1
- package/dist/cjs/editor/BikEditor.js.map +1 -1
- package/dist/cjs/editor/BikEditor.utils.js +2 -2
- package/dist/cjs/editor/BikEditor.utils.js.map +1 -1
- package/dist/esm/components/template-preview/RCS/RCSChatPreview.js +72 -68
- package/dist/esm/components/template-preview/RCS/RCSChatPreview.js.map +1 -1
- package/dist/esm/components/template-preview/helpers/TemplateCreatorHelper.d.ts +0 -8
- package/dist/esm/components/template-preview/helpers/TemplateCreatorHelper.js +61 -79
- package/dist/esm/components/template-preview/helpers/TemplateCreatorHelper.js.map +1 -1
- package/dist/esm/components/template-preview/models/RCSTemplate.d.ts +0 -7
- package/dist/esm/components/template-preview/models/RCSTemplate.js.map +1 -1
- package/dist/esm/editor/BikEditor.js +60 -54
- package/dist/esm/editor/BikEditor.js.map +1 -1
- package/dist/esm/editor/BikEditor.utils.d.ts +5 -2
- package/dist/esm/editor/BikEditor.utils.js +104 -96
- package/dist/esm/editor/BikEditor.utils.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { jsxs as rt, jsx as U } from "react/jsx-runtime";
|
|
2
2
|
import { getMarkRange as st } from "../node_modules/@tiptap/core/dist/index.js";
|
|
3
3
|
import { useEditor as it, EditorContent as ct } from "@tiptap/react";
|
|
4
|
-
import { forwardRef as at, useRef as a, useEffect as lt, useImperativeHandle as
|
|
5
|
-
import { BikEditorShell as
|
|
4
|
+
import { forwardRef as at, useRef as a, useEffect as lt, useImperativeHandle as ut } from "react";
|
|
5
|
+
import { BikEditorShell as dt } from "./BikEditor.styles.js";
|
|
6
6
|
import { DEFAULT_FORMAT_STATE as N } from "./BikEditor.types.js";
|
|
7
|
-
import { buildSectionedContent as j, normalizeHtml as i, extractActiveFormats as
|
|
7
|
+
import { buildSectionedContent as j, normalizeHtml as i, extractActiveFormats as W, extractContent as $, extractBodyContent as mt, extractSectionContent as gt, findSectionEndPos as J, findSectionStartPos as ft, setSectionContentInEditor as S, insertInlineHtml as ht } from "./BikEditor.utils.js";
|
|
8
8
|
import { buildExtensions as pt } from "./extensions/buildExtensions.js";
|
|
9
9
|
import { LinkBubbleMenu as Ct } from "./floating/LinkBubbleMenu.js";
|
|
10
10
|
function St(g) {
|
|
@@ -17,12 +17,12 @@ const kt = (g, h) => {
|
|
|
17
17
|
initialContent: f,
|
|
18
18
|
sections: m,
|
|
19
19
|
features: k,
|
|
20
|
-
disabled:
|
|
20
|
+
disabled: _,
|
|
21
21
|
maxCharacters: y,
|
|
22
|
-
shortcuts:
|
|
23
|
-
sendShortcut:
|
|
22
|
+
shortcuts: Q,
|
|
23
|
+
sendShortcut: V,
|
|
24
24
|
mentions: l,
|
|
25
|
-
slashCommands:
|
|
25
|
+
slashCommands: d,
|
|
26
26
|
link: Z,
|
|
27
27
|
onPaste: G,
|
|
28
28
|
onReady: x,
|
|
@@ -40,24 +40,24 @@ const kt = (g, h) => {
|
|
|
40
40
|
} = g, et = m?.length ? j(
|
|
41
41
|
i(f ?? ""),
|
|
42
42
|
m.map((t) => ({ ...t, content: i(t.content) }))
|
|
43
|
-
) : i(f ?? ""), C = a([]), L = a(!1),
|
|
44
|
-
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
const
|
|
48
|
-
|
|
49
|
-
const
|
|
43
|
+
) : i(f ?? ""), C = a([]), L = a(!1), v = a(x);
|
|
44
|
+
v.current = x;
|
|
45
|
+
const T = a(B);
|
|
46
|
+
T.current = B;
|
|
47
|
+
const F = a(R);
|
|
48
|
+
F.current = R;
|
|
49
|
+
const M = a(N), z = a(A);
|
|
50
50
|
z.current = A;
|
|
51
|
-
const
|
|
52
|
-
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
const
|
|
58
|
-
|
|
59
|
-
const q = a(
|
|
60
|
-
q.current =
|
|
51
|
+
const O = a(b);
|
|
52
|
+
O.current = b;
|
|
53
|
+
const w = a(p);
|
|
54
|
+
w.current = p;
|
|
55
|
+
const H = a(l?.agents ?? []);
|
|
56
|
+
H.current = l?.agents ?? [];
|
|
57
|
+
const P = a(l?.teams ?? []);
|
|
58
|
+
P.current = l?.teams ?? [];
|
|
59
|
+
const q = a(d?.items ?? []);
|
|
60
|
+
q.current = d?.items ?? [];
|
|
61
61
|
const o = it({
|
|
62
62
|
extensions: pt({
|
|
63
63
|
features: k,
|
|
@@ -65,23 +65,23 @@ const kt = (g, h) => {
|
|
|
65
65
|
maxCharacters: y,
|
|
66
66
|
hasSections: (m?.length ?? 0) > 0,
|
|
67
67
|
mentions: {
|
|
68
|
-
agents: l ?
|
|
69
|
-
teams: l ?
|
|
68
|
+
agents: l ? H : void 0,
|
|
69
|
+
teams: l ? P : void 0
|
|
70
70
|
},
|
|
71
|
-
slashCommands:
|
|
71
|
+
slashCommands: d ? q : void 0,
|
|
72
72
|
onPaste: G,
|
|
73
|
-
onSend: p ? (t) =>
|
|
74
|
-
sendShortcut:
|
|
75
|
-
shortcuts:
|
|
73
|
+
onSend: p ? (t) => w.current?.(t) : void 0,
|
|
74
|
+
sendShortcut: V,
|
|
75
|
+
shortcuts: Q,
|
|
76
76
|
onMentionSelected: l?.onSelect,
|
|
77
|
-
onSlashCommandSelected:
|
|
77
|
+
onSlashCommandSelected: d?.onSelect,
|
|
78
78
|
renderMentionItem: l?.renderItem,
|
|
79
79
|
renderMentionDropdown: l?.renderDropdown,
|
|
80
|
-
renderSlashCommandItem:
|
|
81
|
-
renderSlashCommandDropdown:
|
|
80
|
+
renderSlashCommandItem: d?.renderItem,
|
|
81
|
+
renderSlashCommandDropdown: d?.renderDropdown
|
|
82
82
|
}),
|
|
83
83
|
content: et,
|
|
84
|
-
editable: !
|
|
84
|
+
editable: !_,
|
|
85
85
|
immediatelyRender: !1,
|
|
86
86
|
// SSR-safe — NEVER remove this
|
|
87
87
|
editorProps: {
|
|
@@ -91,21 +91,21 @@ const kt = (g, h) => {
|
|
|
91
91
|
}
|
|
92
92
|
},
|
|
93
93
|
onUpdate: ({ editor: t }) => {
|
|
94
|
-
|
|
94
|
+
T.current?.($(t));
|
|
95
95
|
},
|
|
96
96
|
onTransaction: ({ editor: t }) => {
|
|
97
|
-
const e =
|
|
98
|
-
(n.bold !== e.bold || n.italic !== e.italic || n.underline !== e.underline || n.strike !== e.strike || n.bulletList !== e.bulletList || n.orderedList !== e.orderedList || n.blockquote !== e.blockquote || n.codeBlock !== e.codeBlock || n.superscript !== e.superscript || n.subscript !== e.subscript || n.textAlign !== e.textAlign || n.fontFamily !== e.fontFamily || n.fontSize !== e.fontSize || n.color !== e.color || n.highlight !== e.highlight || n.link?.href !== e.link?.href) && (
|
|
97
|
+
const e = W(t), n = M.current;
|
|
98
|
+
(n.bold !== e.bold || n.italic !== e.italic || n.underline !== e.underline || n.strike !== e.strike || n.bulletList !== e.bulletList || n.orderedList !== e.orderedList || n.blockquote !== e.blockquote || n.codeBlock !== e.codeBlock || n.superscript !== e.superscript || n.subscript !== e.subscript || n.textAlign !== e.textAlign || n.fontFamily !== e.fontFamily || n.fontSize !== e.fontSize || n.color !== e.color || n.highlight !== e.highlight || n.link?.href !== e.link?.href) && (M.current = e, F.current?.(e));
|
|
99
99
|
},
|
|
100
100
|
onFocus: () => z.current?.(),
|
|
101
|
-
onBlur: () =>
|
|
101
|
+
onBlur: () => O.current?.()
|
|
102
102
|
});
|
|
103
103
|
function s(t) {
|
|
104
104
|
o ? t(o) : C.current.push(t);
|
|
105
105
|
}
|
|
106
106
|
return lt(() => {
|
|
107
|
-
o && (C.current.length > 0 && C.current.splice(0).forEach((e) => e(o)), L.current || (L.current = !0,
|
|
108
|
-
}, [o]),
|
|
107
|
+
o && (C.current.length > 0 && C.current.splice(0).forEach((e) => e(o)), L.current || (L.current = !0, v.current?.()));
|
|
108
|
+
}, [o]), ut(
|
|
109
109
|
h,
|
|
110
110
|
() => ({
|
|
111
111
|
// ── Focus ────────────────────────────────────────────────────────
|
|
@@ -147,7 +147,7 @@ const kt = (g, h) => {
|
|
|
147
147
|
appendContent(t) {
|
|
148
148
|
this.appendInline(t);
|
|
149
149
|
},
|
|
150
|
-
getContent: () => o ?
|
|
150
|
+
getContent: () => o ? $(o) : { html: "", text: "", isEmpty: !0, characterCount: 0 },
|
|
151
151
|
getJSON: () => o?.getJSON() ?? null,
|
|
152
152
|
getMentions: () => {
|
|
153
153
|
const t = /* @__PURE__ */ new Set(), e = /* @__PURE__ */ new Set();
|
|
@@ -172,9 +172,9 @@ const kt = (g, h) => {
|
|
|
172
172
|
return t.doc.textBetween(e, n, " ");
|
|
173
173
|
const c = t.schema.marks.link;
|
|
174
174
|
if (c) {
|
|
175
|
-
const
|
|
176
|
-
if (
|
|
177
|
-
return t.doc.textBetween(
|
|
175
|
+
const u = st(t.doc.resolve(e), c);
|
|
176
|
+
if (u)
|
|
177
|
+
return t.doc.textBetween(u.from, u.to, " ");
|
|
178
178
|
}
|
|
179
179
|
return "";
|
|
180
180
|
},
|
|
@@ -193,7 +193,7 @@ const kt = (g, h) => {
|
|
|
193
193
|
s((e) => {
|
|
194
194
|
if (t === "body") {
|
|
195
195
|
let r = e.state.doc.content.size - 1;
|
|
196
|
-
e.state.doc.descendants((c,
|
|
196
|
+
e.state.doc.descendants((c, u) => (c.type.name === "sectionDivider" && r === e.state.doc.content.size - 1 && (r = u - 1), r === e.state.doc.content.size - 1)), r < 1 && (r = 1), e.chain().focus().setTextSelection(r).run();
|
|
197
197
|
return;
|
|
198
198
|
}
|
|
199
199
|
let n = -1;
|
|
@@ -225,26 +225,32 @@ const kt = (g, h) => {
|
|
|
225
225
|
appendBodyContent: (t) => {
|
|
226
226
|
const e = i(t);
|
|
227
227
|
s((n) => {
|
|
228
|
-
const r =
|
|
229
|
-
n.commands.insertContentAt(r - 1, e
|
|
228
|
+
const r = J(n, "body");
|
|
229
|
+
n.commands.insertContentAt(r - 1, e, {
|
|
230
|
+
parseOptions: { preserveWhitespace: !0 }
|
|
231
|
+
});
|
|
230
232
|
});
|
|
231
233
|
},
|
|
232
234
|
insertAtSectionStart: (t, e) => {
|
|
233
235
|
const n = i(e);
|
|
234
236
|
s((r) => {
|
|
235
237
|
const c = ft(r, t);
|
|
236
|
-
c !== -1 && r.commands.insertContentAt(c, n
|
|
238
|
+
c !== -1 && r.commands.insertContentAt(c, n, {
|
|
239
|
+
parseOptions: { preserveWhitespace: !0 }
|
|
240
|
+
});
|
|
237
241
|
});
|
|
238
242
|
},
|
|
239
243
|
insertAtSectionEnd: (t, e) => {
|
|
240
244
|
const n = i(e);
|
|
241
245
|
s((r) => {
|
|
242
|
-
const c =
|
|
243
|
-
r.commands.insertContentAt(c, n
|
|
246
|
+
const c = J(r, t);
|
|
247
|
+
r.commands.insertContentAt(c, n, {
|
|
248
|
+
parseOptions: { preserveWhitespace: !0 }
|
|
249
|
+
});
|
|
244
250
|
});
|
|
245
251
|
},
|
|
246
252
|
// ── Formats & actions ─────────────────────────────────────────────
|
|
247
|
-
getActiveFormats: () => o ?
|
|
253
|
+
getActiveFormats: () => o ? W(o) : N,
|
|
248
254
|
actions: {
|
|
249
255
|
toggleBold: () => o?.chain().focus().toggleBold().run(),
|
|
250
256
|
toggleItalic: () => o?.chain().focus().toggleItalic().run(),
|
|
@@ -263,12 +269,12 @@ const kt = (g, h) => {
|
|
|
263
269
|
unsetHighlight: () => o?.chain().focus().unsetHighlight().run(),
|
|
264
270
|
setLink: (t, e) => {
|
|
265
271
|
o && (e !== void 0 ? o.chain().focus().extendMarkRange("link").command(({ tr: n, state: r }) => {
|
|
266
|
-
const { from: c, to:
|
|
272
|
+
const { from: c, to: u } = n.selection, D = r.schema.marks.link;
|
|
267
273
|
if (!D) return !1;
|
|
268
274
|
const nt = r.schema.text(e, [
|
|
269
275
|
D.create({ href: t })
|
|
270
276
|
]), ot = r.schema.text(" ");
|
|
271
|
-
return n.replaceWith(c,
|
|
277
|
+
return n.replaceWith(c, u, [nt, ot]), !0;
|
|
272
278
|
}).run() : o.chain().focus().extendMarkRange("link").setLink({ href: t }).insertContent(" ").run());
|
|
273
279
|
},
|
|
274
280
|
updateLink: (t) => o?.chain().focus().extendMarkRange("link").setLink({ href: t }).run(),
|
|
@@ -288,7 +294,7 @@ const kt = (g, h) => {
|
|
|
288
294
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
289
295
|
[o]
|
|
290
296
|
), o ? /* @__PURE__ */ rt(
|
|
291
|
-
|
|
297
|
+
dt,
|
|
292
298
|
{
|
|
293
299
|
minHeight: K,
|
|
294
300
|
maxHeight: X,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BikEditor.js","sources":["../../../src/editor/BikEditor.tsx"],"sourcesContent":["'use client';\n\n/**\n * IMPLEMENTATION LAYER — TipTap-specific.\n * If the underlying editor is swapped, this file changes; BikEditor.types.ts and\n * src/editor/index.ts (the consumer contract) do NOT change.\n */\nimport { Editor, getMarkRange } from '@tiptap/core';\nimport { EditorContent, useEditor } from '@tiptap/react';\nimport React, {\n\tforwardRef,\n\tuseEffect,\n\tuseImperativeHandle,\n\tuseRef,\n} from 'react';\nimport { BikEditorShell } from './BikEditor.styles';\nimport {\n\tBikEditorProps,\n\tBikEditorRef,\n\tDEFAULT_FORMAT_STATE,\n\tFormatState,\n} from './BikEditor.types';\nimport {\n\tbuildSectionedContent,\n\textractActiveFormats,\n\textractBodyContent,\n\textractContent,\n\textractSectionContent,\n\tfindSectionEndPos,\n\tfindSectionStartPos,\n\tinsertInlineHtml,\n\tnormalizeHtml,\n\tsetSectionContentInEditor,\n} from './BikEditor.utils';\nimport { buildExtensions } from './extensions/buildExtensions';\nimport { LinkBubbleMenu } from './floating/LinkBubbleMenu';\n\n/** Convert React.CSSProperties to an inline CSS string for editorProps.attributes. */\nfunction cssToString(style: React.CSSProperties): string {\n\treturn Object.entries(style)\n\t\t.map(\n\t\t\t([k, v]) => `${k.replace(/([A-Z])/g, (c) => `-${c.toLowerCase()}`)}:${v}`,\n\t\t)\n\t\t.join(';');\n}\n\nconst BikEditorInner = (\n\tprops: BikEditorProps,\n\tref: React.Ref<BikEditorRef>,\n) => {\n\tconst {\n\t\tinitialContent,\n\t\tsections,\n\t\tfeatures,\n\t\tdisabled,\n\t\tmaxCharacters,\n\t\tshortcuts,\n\t\tsendShortcut,\n\t\tmentions,\n\t\tslashCommands,\n\t\tlink,\n\t\tonPaste,\n\t\tonReady,\n\t\tonChange,\n\t\tonSend,\n\t\tonFocus,\n\t\tonBlur,\n\t\tonSelectionChange,\n\t\tminHeight,\n\t\tmaxHeight,\n\t\tstyle,\n\t\tclassName,\n\t\teditorClassName,\n\t\teditorStyle,\n\t} = props;\n\n\tconst initialEditorContent = sections?.length\n\t\t? buildSectionedContent(\n\t\t\t\tnormalizeHtml(initialContent ?? ''),\n\t\t\t\tsections.map((s) => ({ ...s, content: normalizeHtml(s.content) })),\n\t\t )\n\t\t: normalizeHtml(initialContent ?? '');\n\n\t// ── Command queue ─────────────────────────────────────────────────────────\n\t// TipTap's useEditor initializes asynchronously; the editor instance is null\n\t// until the first commit. Any imperative method called before the editor is\n\t// ready is enqueued here and flushed automatically once it becomes non-null.\n\t// Consumers never need setTimeout or readiness guards.\n\tconst pendingQueue = useRef<Array<(e: Editor) => void>>([]);\n\tconst hasCalledOnReady = useRef(false);\n\t// Keep stable refs to all callbacks so useEditor receives the same function\n\t// identity on every render — prevents TipTap from re-registering event\n\t// handlers every time the parent re-renders with new inline function props.\n\tconst onReadyRef = useRef(onReady);\n\tonReadyRef.current = onReady;\n\tconst onChangeRef = useRef(onChange);\n\tonChangeRef.current = onChange;\n\tconst onSelectionChangeRef = useRef(onSelectionChange);\n\tonSelectionChangeRef.current = onSelectionChange;\n\tconst prevFormatsRef = useRef<FormatState>(DEFAULT_FORMAT_STATE);\n\tconst onFocusRef = useRef(onFocus);\n\tonFocusRef.current = onFocus;\n\tconst onBlurRef = useRef(onBlur);\n\tonBlurRef.current = onBlur;\n\tconst onSendRef = useRef(onSend);\n\tonSendRef.current = onSend;\n\tconst agentMentionsRef = useRef(mentions?.agents ?? []);\n\tagentMentionsRef.current = mentions?.agents ?? [];\n\tconst teamMentionsRef = useRef(mentions?.teams ?? []);\n\tteamMentionsRef.current = mentions?.teams ?? [];\n\tconst slashCommandsRef = useRef(slashCommands?.items ?? []);\n\tslashCommandsRef.current = slashCommands?.items ?? [];\n\n\tconst editor = useEditor({\n\t\textensions: buildExtensions({\n\t\t\tfeatures,\n\t\t\tplaceholder: props.placeholder,\n\t\t\tmaxCharacters,\n\t\t\thasSections: (sections?.length ?? 0) > 0,\n\t\t\tmentions: {\n\t\t\t\tagents: mentions ? agentMentionsRef : undefined,\n\t\t\t\tteams: mentions ? teamMentionsRef : undefined,\n\t\t\t},\n\t\t\tslashCommands: slashCommands ? slashCommandsRef : undefined,\n\t\t\tonPaste,\n\t\t\tonSend: onSend ? (snapshot) => onSendRef.current?.(snapshot) : undefined,\n\t\t\tsendShortcut,\n\t\t\tshortcuts,\n\t\t\tonMentionSelected: mentions?.onSelect,\n\t\t\tonSlashCommandSelected: slashCommands?.onSelect,\n\t\t\trenderMentionItem: mentions?.renderItem,\n\t\t\trenderMentionDropdown: mentions?.renderDropdown,\n\t\t\trenderSlashCommandItem: slashCommands?.renderItem,\n\t\t\trenderSlashCommandDropdown: slashCommands?.renderDropdown,\n\t\t}),\n\t\tcontent: initialEditorContent,\n\t\teditable: !disabled,\n\t\timmediatelyRender: false, // SSR-safe — NEVER remove this\n\t\teditorProps: {\n\t\t\tattributes: {\n\t\t\t\t...(editorClassName ? { class: editorClassName } : {}),\n\t\t\t\t...(editorStyle ? { style: cssToString(editorStyle) } : {}),\n\t\t\t},\n\t\t},\n\t\tonUpdate: ({ editor: e }) => {\n\t\t\tonChangeRef.current?.(extractContent(e));\n\t\t},\n\t\tonTransaction: ({ editor: e }) => {\n\t\t\tconst next = extractActiveFormats(e);\n\t\t\tconst prev = prevFormatsRef.current;\n\t\t\tconst changed =\n\t\t\t\tprev.bold !== next.bold ||\n\t\t\t\tprev.italic !== next.italic ||\n\t\t\t\tprev.underline !== next.underline ||\n\t\t\t\tprev.strike !== next.strike ||\n\t\t\t\tprev.bulletList !== next.bulletList ||\n\t\t\t\tprev.orderedList !== next.orderedList ||\n\t\t\t\tprev.blockquote !== next.blockquote ||\n\t\t\t\tprev.codeBlock !== next.codeBlock ||\n\t\t\t\tprev.superscript !== next.superscript ||\n\t\t\t\tprev.subscript !== next.subscript ||\n\t\t\t\tprev.textAlign !== next.textAlign ||\n\t\t\t\tprev.fontFamily !== next.fontFamily ||\n\t\t\t\tprev.fontSize !== next.fontSize ||\n\t\t\t\tprev.color !== next.color ||\n\t\t\t\tprev.highlight !== next.highlight ||\n\t\t\t\tprev.link?.href !== next.link?.href;\n\t\t\tif (changed) {\n\t\t\t\tprevFormatsRef.current = next;\n\t\t\t\tonSelectionChangeRef.current?.(next);\n\t\t\t}\n\t\t},\n\t\tonFocus: () => onFocusRef.current?.(),\n\t\tonBlur: () => onBlurRef.current?.(),\n\t});\n\n\t// ── enqueue ───────────────────────────────────────────────────────────────\n\t// Run immediately if the editor is ready; otherwise defer to the queue.\n\t// Closures passed to enqueue MUST capture all parameters explicitly —\n\t// they must NOT close over `editor` (which would be null at enqueue time).\n\tfunction enqueue(op: (e: Editor) => void): void {\n\t\tif (editor) {\n\t\t\top(editor);\n\t\t} else {\n\t\t\tpendingQueue.current.push(op);\n\t\t}\n\t}\n\n\t// Flush the pending queue and fire onReady when editor transitions null → ready.\n\tuseEffect(() => {\n\t\tif (!editor) return;\n\t\tif (pendingQueue.current.length > 0) {\n\t\t\tconst queue = pendingQueue.current.splice(0);\n\t\t\tqueue.forEach((op) => op(editor));\n\t\t}\n\t\tif (!hasCalledOnReady.current) {\n\t\t\thasCalledOnReady.current = true;\n\t\t\tonReadyRef.current?.();\n\t\t}\n\t}, [editor]);\n\n\tuseImperativeHandle(\n\t\tref,\n\t\t() => ({\n\t\t\t// ── Focus ────────────────────────────────────────────────────────\n\t\t\tfocus: (position) => enqueue((e) => e.commands.focus(position)),\n\t\t\tblur: () => enqueue((e) => e.commands.blur()),\n\n\t\t\t// ── Content ──────────────────────────────────────────────────────\n\t\t\tclearContent: () => enqueue((e) => e.commands.clearContent(true)),\n\t\t\tsetContent: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => e.commands.setContent(normalised, { emitUpdate: true }));\n\t\t\t},\n\t\t\tinsertContent: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => e.commands.insertContent(normalised));\n\t\t\t},\n\t\t\tinsertInlineContent: (html) => {\n\t\t\t\tenqueue((e) => insertInlineHtml(e, html));\n\t\t\t},\n\t\t\tinsertAtStart: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => e.commands.insertContentAt(1, normalised));\n\t\t\t},\n\t\t\tinsertBlock: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) =>\n\t\t\t\t\te.commands.insertContentAt(e.state.doc.content.size, normalised),\n\t\t\t\t);\n\t\t\t},\n\t\t\tappendInline: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\t// doc.content.size is after the last </p> (block boundary).\n\t\t\t\t// Subtract 1 to land inside the last paragraph so text appends\n\t\t\t\t// inline rather than being wrapped in a new paragraph each call.\n\t\t\t\tenqueue((e) =>\n\t\t\t\t\te.commands.insertContentAt(e.state.doc.content.size - 1, normalised),\n\t\t\t\t);\n\t\t\t},\n\t\t\t// Backwards-compatible aliases\n\t\t\tinsertAtEnd(html) {\n\t\t\t\tthis.insertBlock(html);\n\t\t\t},\n\t\t\tappendContent(html) {\n\t\t\t\tthis.appendInline(html);\n\t\t\t},\n\t\t\tgetContent: () =>\n\t\t\t\teditor\n\t\t\t\t\t? extractContent(editor)\n\t\t\t\t\t: { html: '', text: '', isEmpty: true, characterCount: 0 },\n\t\t\tgetJSON: () => editor?.getJSON() ?? null,\n\t\t\tgetMentions: () => {\n\t\t\t\tconst agentIds = new Set<string>();\n\t\t\t\tconst teamIds = new Set<string>();\n\t\t\t\tif (!editor) return { agentIds: [], teamIds: [] };\n\t\t\t\teditor.state.doc.descendants((node) => {\n\t\t\t\t\tif (node.type.name === 'mentionAgent' && node.attrs['id'] != null) {\n\t\t\t\t\t\tagentIds.add(String(node.attrs['id']));\n\t\t\t\t\t} else if (\n\t\t\t\t\t\tnode.type.name === 'mentionTeam' &&\n\t\t\t\t\t\tnode.attrs['id'] != null\n\t\t\t\t\t) {\n\t\t\t\t\t\tteamIds.add(String(node.attrs['id']));\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\treturn { agentIds: Array.from(agentIds), teamIds: Array.from(teamIds) };\n\t\t\t},\n\n\t\t\t// ── Selection ────────────────────────────────────────────────────\n\t\t\tgetCursorPosition: () => {\n\t\t\t\tif (!editor) return { from: 0, to: 0 };\n\t\t\t\tconst { from, to } = editor.state.selection;\n\t\t\t\treturn { from, to };\n\t\t\t},\n\t\t\tinsertAtPosition: (pos, html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => e.commands.insertContentAt(pos, normalised));\n\t\t\t},\n\t\t\tgetSelectedText: () => {\n\t\t\t\tif (!editor) return '';\n\t\t\t\tconst { state } = editor;\n\t\t\t\tconst { from, to, empty } = state.selection;\n\t\t\t\tif (!empty) {\n\t\t\t\t\treturn state.doc.textBetween(from, to, ' ');\n\t\t\t\t}\n\t\t\t\t// When the cursor is inside a link with nothing selected, return the\n\t\t\t\t// full link text — useful for pre-filling a link modal's text field.\n\t\t\t\tconst linkMarkType = state.schema.marks['link'];\n\t\t\t\tif (linkMarkType) {\n\t\t\t\t\tconst range = getMarkRange(state.doc.resolve(from), linkMarkType);\n\t\t\t\t\tif (range) {\n\t\t\t\t\t\treturn state.doc.textBetween(range.from, range.to, ' ');\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn '';\n\t\t\t},\n\n\t\t\t// ── Character count ───────────────────────────────────────────────\n\t\t\tgetCharacterCount: () => ({\n\t\t\t\tcount:\n\t\t\t\t\teditor?.storage.characterCount?.characters?.() ??\n\t\t\t\t\teditor?.getText().length ??\n\t\t\t\t\t0,\n\t\t\t\tlimit: maxCharacters ?? null,\n\t\t\t}),\n\n\t\t\t// ── Sections ─────────────────────────────────────────────────────\n\t\t\tgetSectionContent: (sectionId) =>\n\t\t\t\teditor\n\t\t\t\t\t? extractSectionContent(editor, sectionId)\n\t\t\t\t\t: { html: '', text: '', isEmpty: true, characterCount: 0 },\n\n\t\t\tsetSectionContent: (sectionId, html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => setSectionContentInEditor(e, sectionId, normalised));\n\t\t\t},\n\n\t\t\tfocusSection: (sectionId) => {\n\t\t\t\tenqueue((e) => {\n\t\t\t\t\tif (sectionId === 'body') {\n\t\t\t\t\t\tlet endOfBody = e.state.doc.content.size - 1;\n\t\t\t\t\t\te.state.doc.descendants((node, pos) => {\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\tnode.type.name === 'sectionDivider' &&\n\t\t\t\t\t\t\t\tendOfBody === e.state.doc.content.size - 1\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\tendOfBody = pos - 1;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn endOfBody === e.state.doc.content.size - 1;\n\t\t\t\t\t\t});\n\t\t\t\t\t\tif (endOfBody < 1) endOfBody = 1;\n\t\t\t\t\t\te.chain().focus().setTextSelection(endOfBody).run();\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tlet targetPos = -1;\n\t\t\t\t\te.state.doc.descendants((node, pos) => {\n\t\t\t\t\t\tif (targetPos !== -1) return false;\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tnode.type.name === 'sectionDivider' &&\n\t\t\t\t\t\t\tnode.attrs['sectionId'] === sectionId\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t// pos + nodeSize lands right after the divider;\n\t\t\t\t\t\t\t// +1 more puts us inside the first paragraph of that section.\n\t\t\t\t\t\t\ttargetPos = pos + node.nodeSize + 1;\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\tif (targetPos !== -1) {\n\t\t\t\t\t\te.chain().focus().setTextSelection(targetPos).run();\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t},\n\n\t\t\tclearSection: (sectionId) => {\n\t\t\t\tenqueue((e) => setSectionContentInEditor(e, sectionId, '<p></p>'));\n\t\t\t},\n\n\t\t\t// ── Convenience body shorthands ───────────────────────────────────\n\t\t\tgetBodyContent: () =>\n\t\t\t\teditor\n\t\t\t\t\t? extractBodyContent(editor)\n\t\t\t\t\t: { html: '', text: '', isEmpty: true, characterCount: 0 },\n\t\t\tsetBodyContent: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => setSectionContentInEditor(e, 'body', normalised));\n\t\t\t},\n\t\t\tsetBodyAndSections: (body, sections) => {\n\t\t\t\tconst html = buildSectionedContent(\n\t\t\t\t\tnormalizeHtml(body),\n\t\t\t\t\tsections.map((s) => ({\n\t\t\t\t\t\tid: s.id,\n\t\t\t\t\t\tcontent: normalizeHtml(s.content),\n\t\t\t\t\t})),\n\t\t\t\t);\n\t\t\t\tenqueue((e) => e.commands.setContent(html, { emitUpdate: true }));\n\t\t\t},\n\t\t\tappendBodyContent: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\t// findSectionEndPos returns the position of the first divider (or\n\t\t\t\t// doc.content.size), which is the block boundary after the last </p>.\n\t\t\t\t// Subtract 1 to stay inside the last paragraph so successive calls\n\t\t\t\t// append inline text rather than creating a new paragraph each time.\n\t\t\t\tenqueue((e) => {\n\t\t\t\t\tconst boundaryPos = findSectionEndPos(e, 'body');\n\t\t\t\t\te.commands.insertContentAt(boundaryPos - 1, normalised);\n\t\t\t\t});\n\t\t\t},\n\t\t\tinsertAtSectionStart: (sectionId, html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => {\n\t\t\t\t\tconst pos = findSectionStartPos(e, sectionId);\n\t\t\t\t\tif (pos !== -1) e.commands.insertContentAt(pos, normalised);\n\t\t\t\t});\n\t\t\t},\n\t\t\tinsertAtSectionEnd: (sectionId, html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => {\n\t\t\t\t\tconst pos = findSectionEndPos(e, sectionId);\n\t\t\t\t\te.commands.insertContentAt(pos, normalised);\n\t\t\t\t});\n\t\t\t},\n\t\t\t// ── Formats & actions ─────────────────────────────────────────────\n\t\t\tgetActiveFormats: () =>\n\t\t\t\teditor ? extractActiveFormats(editor) : DEFAULT_FORMAT_STATE,\n\t\t\tactions: {\n\t\t\t\ttoggleBold: () => editor?.chain().focus().toggleBold().run(),\n\t\t\t\ttoggleItalic: () => editor?.chain().focus().toggleItalic().run(),\n\t\t\t\ttoggleUnderline: () => editor?.chain().focus().toggleUnderline().run(),\n\t\t\t\ttoggleStrike: () => editor?.chain().focus().toggleStrike().run(),\n\t\t\t\ttoggleBulletList: () =>\n\t\t\t\t\teditor?.chain().focus().toggleBulletList().run(),\n\t\t\t\ttoggleOrderedList: () =>\n\t\t\t\t\teditor?.chain().focus().toggleOrderedList().run(),\n\t\t\t\ttoggleBlockquote: () =>\n\t\t\t\t\teditor?.chain().focus().toggleBlockquote().run(),\n\t\t\t\ttoggleCodeBlock: () => editor?.chain().focus().toggleCodeBlock().run(),\n\t\t\t\tsetTextAlign: (align) =>\n\t\t\t\t\teditor?.chain().focus().setTextAlign(align).run(),\n\t\t\t\tsetFontFamily: (font) =>\n\t\t\t\t\teditor?.chain().focus().setFontFamily(font).run(),\n\t\t\t\tsetFontSize: (size) => editor?.chain().focus().setFontSize(size).run(),\n\t\t\t\tsetColor: (color) => editor?.chain().focus().setColor(color).run(),\n\t\t\t\tsetHighlight: (color) =>\n\t\t\t\t\teditor?.chain().focus().toggleHighlight({ color }).run(),\n\t\t\t\tunsetColor: () => editor?.chain().focus().unsetColor().run(),\n\t\t\t\tunsetHighlight: () => editor?.chain().focus().unsetHighlight().run(),\n\t\t\t\tsetLink: (href, text) => {\n\t\t\t\t\tif (!editor) return;\n\t\t\t\t\tif (text !== undefined) {\n\t\t\t\t\t\teditor\n\t\t\t\t\t\t\t.chain()\n\t\t\t\t\t\t\t.focus()\n\t\t\t\t\t\t\t.extendMarkRange('link')\n\t\t\t\t\t\t\t.command(({ tr, state }) => {\n\t\t\t\t\t\t\t\tconst { from, to } = tr.selection;\n\t\t\t\t\t\t\t\tconst linkMarkType = state.schema.marks['link'];\n\t\t\t\t\t\t\t\tif (!linkMarkType) return false;\n\t\t\t\t\t\t\t\tconst linkNode = state.schema.text(text, [\n\t\t\t\t\t\t\t\t\tlinkMarkType.create({ href }),\n\t\t\t\t\t\t\t\t]);\n\t\t\t\t\t\t\t\tconst space = state.schema.text(' ');\n\t\t\t\t\t\t\t\ttr.replaceWith(from, to, [linkNode, space]);\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t.run();\n\t\t\t\t\t} else {\n\t\t\t\t\t\teditor\n\t\t\t\t\t\t\t.chain()\n\t\t\t\t\t\t\t.focus()\n\t\t\t\t\t\t\t.extendMarkRange('link')\n\t\t\t\t\t\t\t.setLink({ href })\n\t\t\t\t\t\t\t.insertContent(' ')\n\t\t\t\t\t\t\t.run();\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tupdateLink: (href) =>\n\t\t\t\t\teditor\n\t\t\t\t\t\t?.chain()\n\t\t\t\t\t\t.focus()\n\t\t\t\t\t\t.extendMarkRange('link')\n\t\t\t\t\t\t.setLink({ href })\n\t\t\t\t\t\t.run(),\n\t\t\t\tremoveLink: () =>\n\t\t\t\t\teditor?.chain().focus().extendMarkRange('link').unsetLink().run(),\n\t\t\t\tinsertEmoji: (emoji) =>\n\t\t\t\t\teditor?.chain().focus().insertContent(emoji).run(),\n\t\t\t\tinsertVariable: (variableName) =>\n\t\t\t\t\teditor?.chain().focus().insertContent(`{{${variableName}}}`).run(),\n\t\t\t\tinsertHtml: (html) =>\n\t\t\t\t\teditor?.commands.insertContent(normalizeHtml(html)),\n\t\t\t\tundo: () => editor?.chain().focus().undo().run(),\n\t\t\t\tredo: () => editor?.chain().focus().redo().run(),\n\t\t\t\tcanUndo: () => editor?.can().undo() ?? false,\n\t\t\t\tcanRedo: () => editor?.can().redo() ?? false,\n\t\t\t\ttoggleSuperscript: () =>\n\t\t\t\t\teditor?.chain().focus().toggleSuperscript().run(),\n\t\t\t\ttoggleSubscript: () => editor?.chain().focus().toggleSubscript().run(),\n\t\t\t\tinsertImage: (src) => editor?.chain().focus().setImage({ src }).run(),\n\t\t\t},\n\t\t}),\n\t\t// eslint-disable-next-line react-hooks/exhaustive-deps\n\t\t[editor],\n\t);\n\n\tif (!editor) return null;\n\n\treturn (\n\t\t<BikEditorShell\n\t\t\tminHeight={minHeight}\n\t\t\tmaxHeight={maxHeight}\n\t\t\ttightParagraphs={!features?.richPaste}\n\t\t\tstyle={style}\n\t\t\tclassName={className}\n\t\t>\n\t\t\t<EditorContent editor={editor} />\n\t\t\t<LinkBubbleMenu editor={editor} renderLinkTooltip={link?.renderTooltip} />\n\t\t</BikEditorShell>\n\t);\n};\n\nexport const BikEditor = forwardRef<BikEditorRef, BikEditorProps>(\n\tBikEditorInner,\n);\nBikEditor.displayName = 'BikEditor';\n"],"names":["cssToString","style","k","v","c","BikEditorInner","props","ref","initialContent","sections","features","disabled","maxCharacters","shortcuts","sendShortcut","mentions","slashCommands","link","onPaste","onReady","onChange","onSend","onFocus","onBlur","onSelectionChange","minHeight","maxHeight","className","editorClassName","editorStyle","initialEditorContent","buildSectionedContent","normalizeHtml","s","pendingQueue","useRef","hasCalledOnReady","onReadyRef","onChangeRef","onSelectionChangeRef","prevFormatsRef","DEFAULT_FORMAT_STATE","onFocusRef","onBlurRef","onSendRef","agentMentionsRef","teamMentionsRef","slashCommandsRef","editor","useEditor","buildExtensions","snapshot","e","extractContent","next","extractActiveFormats","prev","enqueue","op","useEffect","useImperativeHandle","position","html","normalised","insertInlineHtml","agentIds","teamIds","node","from","to","pos","state","empty","linkMarkType","range","getMarkRange","sectionId","extractSectionContent","setSectionContentInEditor","endOfBody","targetPos","extractBodyContent","body","boundaryPos","findSectionEndPos","findSectionStartPos","align","font","size","color","href","text","tr","linkNode","space","emoji","variableName","src","jsxs","BikEditorShell","jsx","EditorContent","LinkBubbleMenu","BikEditor","forwardRef"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"BikEditor.js","sources":["../../../src/editor/BikEditor.tsx"],"sourcesContent":["'use client';\n\n/**\n * IMPLEMENTATION LAYER — TipTap-specific.\n * If the underlying editor is swapped, this file changes; BikEditor.types.ts and\n * src/editor/index.ts (the consumer contract) do NOT change.\n */\nimport { Editor, getMarkRange } from '@tiptap/core';\nimport { EditorContent, useEditor } from '@tiptap/react';\nimport React, {\n\tforwardRef,\n\tuseEffect,\n\tuseImperativeHandle,\n\tuseRef,\n} from 'react';\nimport { BikEditorShell } from './BikEditor.styles';\nimport {\n\tBikEditorProps,\n\tBikEditorRef,\n\tDEFAULT_FORMAT_STATE,\n\tFormatState,\n} from './BikEditor.types';\nimport {\n\tbuildSectionedContent,\n\textractActiveFormats,\n\textractBodyContent,\n\textractContent,\n\textractSectionContent,\n\tfindSectionEndPos,\n\tfindSectionStartPos,\n\tinsertInlineHtml,\n\tnormalizeHtml,\n\tsetSectionContentInEditor,\n} from './BikEditor.utils';\nimport { buildExtensions } from './extensions/buildExtensions';\nimport { LinkBubbleMenu } from './floating/LinkBubbleMenu';\n\n/** Convert React.CSSProperties to an inline CSS string for editorProps.attributes. */\nfunction cssToString(style: React.CSSProperties): string {\n\treturn Object.entries(style)\n\t\t.map(\n\t\t\t([k, v]) => `${k.replace(/([A-Z])/g, (c) => `-${c.toLowerCase()}`)}:${v}`,\n\t\t)\n\t\t.join(';');\n}\n\nconst BikEditorInner = (\n\tprops: BikEditorProps,\n\tref: React.Ref<BikEditorRef>,\n) => {\n\tconst {\n\t\tinitialContent,\n\t\tsections,\n\t\tfeatures,\n\t\tdisabled,\n\t\tmaxCharacters,\n\t\tshortcuts,\n\t\tsendShortcut,\n\t\tmentions,\n\t\tslashCommands,\n\t\tlink,\n\t\tonPaste,\n\t\tonReady,\n\t\tonChange,\n\t\tonSend,\n\t\tonFocus,\n\t\tonBlur,\n\t\tonSelectionChange,\n\t\tminHeight,\n\t\tmaxHeight,\n\t\tstyle,\n\t\tclassName,\n\t\teditorClassName,\n\t\teditorStyle,\n\t} = props;\n\n\tconst initialEditorContent = sections?.length\n\t\t? buildSectionedContent(\n\t\t\t\tnormalizeHtml(initialContent ?? ''),\n\t\t\t\tsections.map((s) => ({ ...s, content: normalizeHtml(s.content) })),\n\t\t )\n\t\t: normalizeHtml(initialContent ?? '');\n\n\t// ── Command queue ─────────────────────────────────────────────────────────\n\t// TipTap's useEditor initializes asynchronously; the editor instance is null\n\t// until the first commit. Any imperative method called before the editor is\n\t// ready is enqueued here and flushed automatically once it becomes non-null.\n\t// Consumers never need setTimeout or readiness guards.\n\tconst pendingQueue = useRef<Array<(e: Editor) => void>>([]);\n\tconst hasCalledOnReady = useRef(false);\n\t// Keep stable refs to all callbacks so useEditor receives the same function\n\t// identity on every render — prevents TipTap from re-registering event\n\t// handlers every time the parent re-renders with new inline function props.\n\tconst onReadyRef = useRef(onReady);\n\tonReadyRef.current = onReady;\n\tconst onChangeRef = useRef(onChange);\n\tonChangeRef.current = onChange;\n\tconst onSelectionChangeRef = useRef(onSelectionChange);\n\tonSelectionChangeRef.current = onSelectionChange;\n\tconst prevFormatsRef = useRef<FormatState>(DEFAULT_FORMAT_STATE);\n\tconst onFocusRef = useRef(onFocus);\n\tonFocusRef.current = onFocus;\n\tconst onBlurRef = useRef(onBlur);\n\tonBlurRef.current = onBlur;\n\tconst onSendRef = useRef(onSend);\n\tonSendRef.current = onSend;\n\tconst agentMentionsRef = useRef(mentions?.agents ?? []);\n\tagentMentionsRef.current = mentions?.agents ?? [];\n\tconst teamMentionsRef = useRef(mentions?.teams ?? []);\n\tteamMentionsRef.current = mentions?.teams ?? [];\n\tconst slashCommandsRef = useRef(slashCommands?.items ?? []);\n\tslashCommandsRef.current = slashCommands?.items ?? [];\n\n\tconst editor = useEditor({\n\t\textensions: buildExtensions({\n\t\t\tfeatures,\n\t\t\tplaceholder: props.placeholder,\n\t\t\tmaxCharacters,\n\t\t\thasSections: (sections?.length ?? 0) > 0,\n\t\t\tmentions: {\n\t\t\t\tagents: mentions ? agentMentionsRef : undefined,\n\t\t\t\tteams: mentions ? teamMentionsRef : undefined,\n\t\t\t},\n\t\t\tslashCommands: slashCommands ? slashCommandsRef : undefined,\n\t\t\tonPaste,\n\t\t\tonSend: onSend ? (snapshot) => onSendRef.current?.(snapshot) : undefined,\n\t\t\tsendShortcut,\n\t\t\tshortcuts,\n\t\t\tonMentionSelected: mentions?.onSelect,\n\t\t\tonSlashCommandSelected: slashCommands?.onSelect,\n\t\t\trenderMentionItem: mentions?.renderItem,\n\t\t\trenderMentionDropdown: mentions?.renderDropdown,\n\t\t\trenderSlashCommandItem: slashCommands?.renderItem,\n\t\t\trenderSlashCommandDropdown: slashCommands?.renderDropdown,\n\t\t}),\n\t\tcontent: initialEditorContent,\n\t\teditable: !disabled,\n\t\timmediatelyRender: false, // SSR-safe — NEVER remove this\n\t\teditorProps: {\n\t\t\tattributes: {\n\t\t\t\t...(editorClassName ? { class: editorClassName } : {}),\n\t\t\t\t...(editorStyle ? { style: cssToString(editorStyle) } : {}),\n\t\t\t},\n\t\t},\n\t\tonUpdate: ({ editor: e }) => {\n\t\t\tonChangeRef.current?.(extractContent(e));\n\t\t},\n\t\tonTransaction: ({ editor: e }) => {\n\t\t\tconst next = extractActiveFormats(e);\n\t\t\tconst prev = prevFormatsRef.current;\n\t\t\tconst changed =\n\t\t\t\tprev.bold !== next.bold ||\n\t\t\t\tprev.italic !== next.italic ||\n\t\t\t\tprev.underline !== next.underline ||\n\t\t\t\tprev.strike !== next.strike ||\n\t\t\t\tprev.bulletList !== next.bulletList ||\n\t\t\t\tprev.orderedList !== next.orderedList ||\n\t\t\t\tprev.blockquote !== next.blockquote ||\n\t\t\t\tprev.codeBlock !== next.codeBlock ||\n\t\t\t\tprev.superscript !== next.superscript ||\n\t\t\t\tprev.subscript !== next.subscript ||\n\t\t\t\tprev.textAlign !== next.textAlign ||\n\t\t\t\tprev.fontFamily !== next.fontFamily ||\n\t\t\t\tprev.fontSize !== next.fontSize ||\n\t\t\t\tprev.color !== next.color ||\n\t\t\t\tprev.highlight !== next.highlight ||\n\t\t\t\tprev.link?.href !== next.link?.href;\n\t\t\tif (changed) {\n\t\t\t\tprevFormatsRef.current = next;\n\t\t\t\tonSelectionChangeRef.current?.(next);\n\t\t\t}\n\t\t},\n\t\tonFocus: () => onFocusRef.current?.(),\n\t\tonBlur: () => onBlurRef.current?.(),\n\t});\n\n\t// ── enqueue ───────────────────────────────────────────────────────────────\n\t// Run immediately if the editor is ready; otherwise defer to the queue.\n\t// Closures passed to enqueue MUST capture all parameters explicitly —\n\t// they must NOT close over `editor` (which would be null at enqueue time).\n\tfunction enqueue(op: (e: Editor) => void): void {\n\t\tif (editor) {\n\t\t\top(editor);\n\t\t} else {\n\t\t\tpendingQueue.current.push(op);\n\t\t}\n\t}\n\n\t// Flush the pending queue and fire onReady when editor transitions null → ready.\n\tuseEffect(() => {\n\t\tif (!editor) return;\n\t\tif (pendingQueue.current.length > 0) {\n\t\t\tconst queue = pendingQueue.current.splice(0);\n\t\t\tqueue.forEach((op) => op(editor));\n\t\t}\n\t\tif (!hasCalledOnReady.current) {\n\t\t\thasCalledOnReady.current = true;\n\t\t\tonReadyRef.current?.();\n\t\t}\n\t}, [editor]);\n\n\tuseImperativeHandle(\n\t\tref,\n\t\t() => ({\n\t\t\t// ── Focus ────────────────────────────────────────────────────────\n\t\t\tfocus: (position) => enqueue((e) => e.commands.focus(position)),\n\t\t\tblur: () => enqueue((e) => e.commands.blur()),\n\n\t\t\t// ── Content ──────────────────────────────────────────────────────\n\t\t\tclearContent: () => enqueue((e) => e.commands.clearContent(true)),\n\t\t\tsetContent: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => e.commands.setContent(normalised, { emitUpdate: true }));\n\t\t\t},\n\t\t\tinsertContent: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => e.commands.insertContent(normalised));\n\t\t\t},\n\t\t\tinsertInlineContent: (html) => {\n\t\t\t\tenqueue((e) => insertInlineHtml(e, html));\n\t\t\t},\n\t\t\tinsertAtStart: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => e.commands.insertContentAt(1, normalised));\n\t\t\t},\n\t\t\tinsertBlock: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) =>\n\t\t\t\t\te.commands.insertContentAt(e.state.doc.content.size, normalised),\n\t\t\t\t);\n\t\t\t},\n\t\t\tappendInline: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\t// doc.content.size is after the last </p> (block boundary).\n\t\t\t\t// Subtract 1 to land inside the last paragraph so text appends\n\t\t\t\t// inline rather than being wrapped in a new paragraph each call.\n\t\t\t\tenqueue((e) =>\n\t\t\t\t\te.commands.insertContentAt(e.state.doc.content.size - 1, normalised),\n\t\t\t\t);\n\t\t\t},\n\t\t\t// Backwards-compatible aliases\n\t\t\tinsertAtEnd(html) {\n\t\t\t\tthis.insertBlock(html);\n\t\t\t},\n\t\t\tappendContent(html) {\n\t\t\t\tthis.appendInline(html);\n\t\t\t},\n\t\t\tgetContent: () =>\n\t\t\t\teditor\n\t\t\t\t\t? extractContent(editor)\n\t\t\t\t\t: { html: '', text: '', isEmpty: true, characterCount: 0 },\n\t\t\tgetJSON: () => editor?.getJSON() ?? null,\n\t\t\tgetMentions: () => {\n\t\t\t\tconst agentIds = new Set<string>();\n\t\t\t\tconst teamIds = new Set<string>();\n\t\t\t\tif (!editor) return { agentIds: [], teamIds: [] };\n\t\t\t\teditor.state.doc.descendants((node) => {\n\t\t\t\t\tif (node.type.name === 'mentionAgent' && node.attrs['id'] != null) {\n\t\t\t\t\t\tagentIds.add(String(node.attrs['id']));\n\t\t\t\t\t} else if (\n\t\t\t\t\t\tnode.type.name === 'mentionTeam' &&\n\t\t\t\t\t\tnode.attrs['id'] != null\n\t\t\t\t\t) {\n\t\t\t\t\t\tteamIds.add(String(node.attrs['id']));\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\treturn { agentIds: Array.from(agentIds), teamIds: Array.from(teamIds) };\n\t\t\t},\n\n\t\t\t// ── Selection ────────────────────────────────────────────────────\n\t\t\tgetCursorPosition: () => {\n\t\t\t\tif (!editor) return { from: 0, to: 0 };\n\t\t\t\tconst { from, to } = editor.state.selection;\n\t\t\t\treturn { from, to };\n\t\t\t},\n\t\t\tinsertAtPosition: (pos, html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => e.commands.insertContentAt(pos, normalised));\n\t\t\t},\n\t\t\tgetSelectedText: () => {\n\t\t\t\tif (!editor) return '';\n\t\t\t\tconst { state } = editor;\n\t\t\t\tconst { from, to, empty } = state.selection;\n\t\t\t\tif (!empty) {\n\t\t\t\t\treturn state.doc.textBetween(from, to, ' ');\n\t\t\t\t}\n\t\t\t\t// When the cursor is inside a link with nothing selected, return the\n\t\t\t\t// full link text — useful for pre-filling a link modal's text field.\n\t\t\t\tconst linkMarkType = state.schema.marks['link'];\n\t\t\t\tif (linkMarkType) {\n\t\t\t\t\tconst range = getMarkRange(state.doc.resolve(from), linkMarkType);\n\t\t\t\t\tif (range) {\n\t\t\t\t\t\treturn state.doc.textBetween(range.from, range.to, ' ');\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn '';\n\t\t\t},\n\n\t\t\t// ── Character count ───────────────────────────────────────────────\n\t\t\tgetCharacterCount: () => ({\n\t\t\t\tcount:\n\t\t\t\t\teditor?.storage.characterCount?.characters?.() ??\n\t\t\t\t\teditor?.getText().length ??\n\t\t\t\t\t0,\n\t\t\t\tlimit: maxCharacters ?? null,\n\t\t\t}),\n\n\t\t\t// ── Sections ─────────────────────────────────────────────────────\n\t\t\tgetSectionContent: (sectionId) =>\n\t\t\t\teditor\n\t\t\t\t\t? extractSectionContent(editor, sectionId)\n\t\t\t\t\t: { html: '', text: '', isEmpty: true, characterCount: 0 },\n\n\t\t\tsetSectionContent: (sectionId, html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => setSectionContentInEditor(e, sectionId, normalised));\n\t\t\t},\n\n\t\t\tfocusSection: (sectionId) => {\n\t\t\t\tenqueue((e) => {\n\t\t\t\t\tif (sectionId === 'body') {\n\t\t\t\t\t\tlet endOfBody = e.state.doc.content.size - 1;\n\t\t\t\t\t\te.state.doc.descendants((node, pos) => {\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\tnode.type.name === 'sectionDivider' &&\n\t\t\t\t\t\t\t\tendOfBody === e.state.doc.content.size - 1\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\tendOfBody = pos - 1;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn endOfBody === e.state.doc.content.size - 1;\n\t\t\t\t\t\t});\n\t\t\t\t\t\tif (endOfBody < 1) endOfBody = 1;\n\t\t\t\t\t\te.chain().focus().setTextSelection(endOfBody).run();\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tlet targetPos = -1;\n\t\t\t\t\te.state.doc.descendants((node, pos) => {\n\t\t\t\t\t\tif (targetPos !== -1) return false;\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tnode.type.name === 'sectionDivider' &&\n\t\t\t\t\t\t\tnode.attrs['sectionId'] === sectionId\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t// pos + nodeSize lands right after the divider;\n\t\t\t\t\t\t\t// +1 more puts us inside the first paragraph of that section.\n\t\t\t\t\t\t\ttargetPos = pos + node.nodeSize + 1;\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\tif (targetPos !== -1) {\n\t\t\t\t\t\te.chain().focus().setTextSelection(targetPos).run();\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t},\n\n\t\t\tclearSection: (sectionId) => {\n\t\t\t\tenqueue((e) => setSectionContentInEditor(e, sectionId, '<p></p>'));\n\t\t\t},\n\n\t\t\t// ── Convenience body shorthands ───────────────────────────────────\n\t\t\tgetBodyContent: () =>\n\t\t\t\teditor\n\t\t\t\t\t? extractBodyContent(editor)\n\t\t\t\t\t: { html: '', text: '', isEmpty: true, characterCount: 0 },\n\t\t\tsetBodyContent: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => setSectionContentInEditor(e, 'body', normalised));\n\t\t\t},\n\t\t\tsetBodyAndSections: (body, sections) => {\n\t\t\t\tconst html = buildSectionedContent(\n\t\t\t\t\tnormalizeHtml(body),\n\t\t\t\t\tsections.map((s) => ({\n\t\t\t\t\t\tid: s.id,\n\t\t\t\t\t\tcontent: normalizeHtml(s.content),\n\t\t\t\t\t})),\n\t\t\t\t);\n\t\t\t\tenqueue((e) => e.commands.setContent(html, { emitUpdate: true }));\n\t\t\t},\n\t\t\tappendBodyContent: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\t// findSectionEndPos returns the position of the first divider (or\n\t\t\t\t// doc.content.size), which is the block boundary after the last </p>.\n\t\t\t\t// Subtract 1 to stay inside the last paragraph so successive calls\n\t\t\t\t// append inline text rather than creating a new paragraph each time.\n\t\t\t\tenqueue((e) => {\n\t\t\t\t\tconst boundaryPos = findSectionEndPos(e, 'body');\n\t\t\t\t\te.commands.insertContentAt(boundaryPos - 1, normalised, {\n\t\t\t\t\t\tparseOptions: { preserveWhitespace: true },\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t},\n\t\t\tinsertAtSectionStart: (sectionId, html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => {\n\t\t\t\t\tconst pos = findSectionStartPos(e, sectionId);\n\t\t\t\t\tif (pos !== -1)\n\t\t\t\t\t\te.commands.insertContentAt(pos, normalised, {\n\t\t\t\t\t\t\tparseOptions: { preserveWhitespace: true },\n\t\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t},\n\t\t\tinsertAtSectionEnd: (sectionId, html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => {\n\t\t\t\t\tconst pos = findSectionEndPos(e, sectionId);\n\t\t\t\t\te.commands.insertContentAt(pos, normalised, {\n\t\t\t\t\t\tparseOptions: { preserveWhitespace: true },\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t},\n\t\t\t// ── Formats & actions ─────────────────────────────────────────────\n\t\t\tgetActiveFormats: () =>\n\t\t\t\teditor ? extractActiveFormats(editor) : DEFAULT_FORMAT_STATE,\n\t\t\tactions: {\n\t\t\t\ttoggleBold: () => editor?.chain().focus().toggleBold().run(),\n\t\t\t\ttoggleItalic: () => editor?.chain().focus().toggleItalic().run(),\n\t\t\t\ttoggleUnderline: () => editor?.chain().focus().toggleUnderline().run(),\n\t\t\t\ttoggleStrike: () => editor?.chain().focus().toggleStrike().run(),\n\t\t\t\ttoggleBulletList: () =>\n\t\t\t\t\teditor?.chain().focus().toggleBulletList().run(),\n\t\t\t\ttoggleOrderedList: () =>\n\t\t\t\t\teditor?.chain().focus().toggleOrderedList().run(),\n\t\t\t\ttoggleBlockquote: () =>\n\t\t\t\t\teditor?.chain().focus().toggleBlockquote().run(),\n\t\t\t\ttoggleCodeBlock: () => editor?.chain().focus().toggleCodeBlock().run(),\n\t\t\t\tsetTextAlign: (align) =>\n\t\t\t\t\teditor?.chain().focus().setTextAlign(align).run(),\n\t\t\t\tsetFontFamily: (font) =>\n\t\t\t\t\teditor?.chain().focus().setFontFamily(font).run(),\n\t\t\t\tsetFontSize: (size) => editor?.chain().focus().setFontSize(size).run(),\n\t\t\t\tsetColor: (color) => editor?.chain().focus().setColor(color).run(),\n\t\t\t\tsetHighlight: (color) =>\n\t\t\t\t\teditor?.chain().focus().toggleHighlight({ color }).run(),\n\t\t\t\tunsetColor: () => editor?.chain().focus().unsetColor().run(),\n\t\t\t\tunsetHighlight: () => editor?.chain().focus().unsetHighlight().run(),\n\t\t\t\tsetLink: (href, text) => {\n\t\t\t\t\tif (!editor) return;\n\t\t\t\t\tif (text !== undefined) {\n\t\t\t\t\t\teditor\n\t\t\t\t\t\t\t.chain()\n\t\t\t\t\t\t\t.focus()\n\t\t\t\t\t\t\t.extendMarkRange('link')\n\t\t\t\t\t\t\t.command(({ tr, state }) => {\n\t\t\t\t\t\t\t\tconst { from, to } = tr.selection;\n\t\t\t\t\t\t\t\tconst linkMarkType = state.schema.marks['link'];\n\t\t\t\t\t\t\t\tif (!linkMarkType) return false;\n\t\t\t\t\t\t\t\tconst linkNode = state.schema.text(text, [\n\t\t\t\t\t\t\t\t\tlinkMarkType.create({ href }),\n\t\t\t\t\t\t\t\t]);\n\t\t\t\t\t\t\t\tconst space = state.schema.text(' ');\n\t\t\t\t\t\t\t\ttr.replaceWith(from, to, [linkNode, space]);\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t.run();\n\t\t\t\t\t} else {\n\t\t\t\t\t\teditor\n\t\t\t\t\t\t\t.chain()\n\t\t\t\t\t\t\t.focus()\n\t\t\t\t\t\t\t.extendMarkRange('link')\n\t\t\t\t\t\t\t.setLink({ href })\n\t\t\t\t\t\t\t.insertContent(' ')\n\t\t\t\t\t\t\t.run();\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tupdateLink: (href) =>\n\t\t\t\t\teditor\n\t\t\t\t\t\t?.chain()\n\t\t\t\t\t\t.focus()\n\t\t\t\t\t\t.extendMarkRange('link')\n\t\t\t\t\t\t.setLink({ href })\n\t\t\t\t\t\t.run(),\n\t\t\t\tremoveLink: () =>\n\t\t\t\t\teditor?.chain().focus().extendMarkRange('link').unsetLink().run(),\n\t\t\t\tinsertEmoji: (emoji) =>\n\t\t\t\t\teditor?.chain().focus().insertContent(emoji).run(),\n\t\t\t\tinsertVariable: (variableName) =>\n\t\t\t\t\teditor?.chain().focus().insertContent(`{{${variableName}}}`).run(),\n\t\t\t\tinsertHtml: (html) =>\n\t\t\t\t\teditor?.commands.insertContent(normalizeHtml(html)),\n\t\t\t\tundo: () => editor?.chain().focus().undo().run(),\n\t\t\t\tredo: () => editor?.chain().focus().redo().run(),\n\t\t\t\tcanUndo: () => editor?.can().undo() ?? false,\n\t\t\t\tcanRedo: () => editor?.can().redo() ?? false,\n\t\t\t\ttoggleSuperscript: () =>\n\t\t\t\t\teditor?.chain().focus().toggleSuperscript().run(),\n\t\t\t\ttoggleSubscript: () => editor?.chain().focus().toggleSubscript().run(),\n\t\t\t\tinsertImage: (src) => editor?.chain().focus().setImage({ src }).run(),\n\t\t\t},\n\t\t}),\n\t\t// eslint-disable-next-line react-hooks/exhaustive-deps\n\t\t[editor],\n\t);\n\n\tif (!editor) return null;\n\n\treturn (\n\t\t<BikEditorShell\n\t\t\tminHeight={minHeight}\n\t\t\tmaxHeight={maxHeight}\n\t\t\ttightParagraphs={!features?.richPaste}\n\t\t\tstyle={style}\n\t\t\tclassName={className}\n\t\t>\n\t\t\t<EditorContent editor={editor} />\n\t\t\t<LinkBubbleMenu editor={editor} renderLinkTooltip={link?.renderTooltip} />\n\t\t</BikEditorShell>\n\t);\n};\n\nexport const BikEditor = forwardRef<BikEditorRef, BikEditorProps>(\n\tBikEditorInner,\n);\nBikEditor.displayName = 'BikEditor';\n"],"names":["cssToString","style","k","v","c","BikEditorInner","props","ref","initialContent","sections","features","disabled","maxCharacters","shortcuts","sendShortcut","mentions","slashCommands","link","onPaste","onReady","onChange","onSend","onFocus","onBlur","onSelectionChange","minHeight","maxHeight","className","editorClassName","editorStyle","initialEditorContent","buildSectionedContent","normalizeHtml","s","pendingQueue","useRef","hasCalledOnReady","onReadyRef","onChangeRef","onSelectionChangeRef","prevFormatsRef","DEFAULT_FORMAT_STATE","onFocusRef","onBlurRef","onSendRef","agentMentionsRef","teamMentionsRef","slashCommandsRef","editor","useEditor","buildExtensions","snapshot","e","extractContent","next","extractActiveFormats","prev","enqueue","op","useEffect","useImperativeHandle","position","html","normalised","insertInlineHtml","agentIds","teamIds","node","from","to","pos","state","empty","linkMarkType","range","getMarkRange","sectionId","extractSectionContent","setSectionContentInEditor","endOfBody","targetPos","extractBodyContent","body","boundaryPos","findSectionEndPos","findSectionStartPos","align","font","size","color","href","text","tr","linkNode","space","emoji","variableName","src","jsxs","BikEditorShell","jsx","EditorContent","LinkBubbleMenu","BikEditor","forwardRef"],"mappings":"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"}
|
|
@@ -22,11 +22,14 @@ export declare function normalizeHtml(html: string): string;
|
|
|
22
22
|
/**
|
|
23
23
|
* Make editor HTML portable across email clients and chat renderers.
|
|
24
24
|
*
|
|
25
|
-
* 1.
|
|
25
|
+
* 1. Preserve consecutive spaces by converting every second space in a run
|
|
26
|
+
* to ` ` (U+00A0). Standard HTML collapses adjacent regular spaces;
|
|
27
|
+
* alternating with ` ` prevents that — same convention Gmail uses.
|
|
28
|
+
* 2. Double a trailing `<br>` in content paragraphs so the blank line is
|
|
26
29
|
* visible. A single trailing `<br>` before `</p>` is swallowed by most
|
|
27
30
|
* email clients; `<br><br>` renders as a visible blank line (matches
|
|
28
31
|
* Gmail's output).
|
|
29
|
-
*
|
|
32
|
+
* 3. Convert empty `<p></p>` to `<p><br></p>` — email clients collapse
|
|
30
33
|
* zero-height paragraphs without a `<br>`.
|
|
31
34
|
*/
|
|
32
35
|
export declare function toPortableHtml(html: string): string;
|