@bikdotai/bik-component-library 0.0.823 → 0.0.824-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/components/adbanner/AdBanner.js.map +1 -0
- package/dist/cjs/components/{banner → adbanner}/Banner.styled.js +13 -9
- package/dist/cjs/components/adbanner/Banner.styled.js.map +1 -0
- package/dist/cjs/components/adbanner/BannerInline.js.map +1 -0
- package/dist/cjs/components/adbanner/BannerWithImage.js.map +1 -0
- package/dist/cjs/components/adbanner/CardBanner.js.map +1 -0
- package/dist/cjs/components/adbanner/CardBannerWithImage.js.map +1 -0
- package/dist/cjs/components/adbanner/model.js.map +1 -0
- package/dist/cjs/editor/BikEditor.js +1 -1
- package/dist/cjs/editor/BikEditor.js.map +1 -1
- package/dist/cjs/editor/BikEditor.styles.js +122 -2
- package/dist/cjs/editor/BikEditor.styles.js.map +1 -1
- package/dist/cjs/editor/BikEditor.types.js.map +1 -1
- package/dist/cjs/editor/BikEditor.utils.js +3 -2
- package/dist/cjs/editor/BikEditor.utils.js.map +1 -1
- package/dist/cjs/editor/extensions/buildExtensions.js +3 -1
- package/dist/cjs/editor/extensions/buildExtensions.js.map +1 -1
- package/dist/cjs/editor/extensions/jsonHighlight/JsonHighlightExtension.js +3 -0
- package/dist/cjs/editor/extensions/jsonHighlight/JsonHighlightExtension.js.map +1 -0
- package/dist/cjs/editor/extensions/jsonHighlight/tokenizeJson.js +2 -0
- package/dist/cjs/editor/extensions/jsonHighlight/tokenizeJson.js.map +1 -0
- package/dist/cjs/icons/BIK AI specific/WandSparkles.js +2 -0
- package/dist/cjs/icons/BIK AI specific/WandSparkles.js.map +1 -0
- package/dist/cjs/icons/index.js +1 -1
- package/dist/cjs/index.js +1 -1
- package/dist/esm/components/adbanner/AdBanner.js.map +1 -0
- package/dist/esm/components/{banner → adbanner}/Banner.styled.js +18 -14
- package/dist/esm/components/adbanner/Banner.styled.js.map +1 -0
- package/dist/esm/components/adbanner/BannerInline.js.map +1 -0
- package/dist/esm/components/adbanner/BannerWithImage.js.map +1 -0
- package/dist/esm/components/adbanner/CardBanner.js.map +1 -0
- package/dist/esm/components/adbanner/CardBannerWithImage.js.map +1 -0
- package/dist/esm/components/adbanner/model.js.map +1 -0
- package/dist/esm/editor/BikEditor.js +254 -181
- package/dist/esm/editor/BikEditor.js.map +1 -1
- package/dist/esm/editor/BikEditor.styles.d.ts +9 -0
- package/dist/esm/editor/BikEditor.styles.js +128 -6
- package/dist/esm/editor/BikEditor.styles.js.map +1 -1
- package/dist/esm/editor/BikEditor.types.d.ts +76 -0
- package/dist/esm/editor/BikEditor.types.js.map +1 -1
- package/dist/esm/editor/BikEditor.utils.d.ts +15 -1
- package/dist/esm/editor/BikEditor.utils.js +155 -92
- package/dist/esm/editor/BikEditor.utils.js.map +1 -1
- package/dist/esm/editor/extensions/buildExtensions.d.ts +1 -1
- package/dist/esm/editor/extensions/buildExtensions.js +86 -55
- package/dist/esm/editor/extensions/buildExtensions.js.map +1 -1
- package/dist/esm/editor/extensions/jsonHighlight/JsonHighlightExtension.d.ts +14 -0
- package/dist/esm/editor/extensions/jsonHighlight/JsonHighlightExtension.js +64 -0
- package/dist/esm/editor/extensions/jsonHighlight/JsonHighlightExtension.js.map +1 -0
- package/dist/esm/editor/extensions/jsonHighlight/tokenizeJson.d.ts +18 -0
- package/dist/esm/editor/extensions/jsonHighlight/tokenizeJson.js +21 -0
- package/dist/esm/editor/extensions/jsonHighlight/tokenizeJson.js.map +1 -0
- package/dist/esm/editor/index.d.ts +1 -1
- package/dist/esm/icons/BIK AI specific/WandSparkles.d.ts +7 -0
- package/dist/esm/icons/BIK AI specific/WandSparkles.js +39 -0
- package/dist/esm/icons/BIK AI specific/WandSparkles.js.map +1 -0
- package/dist/esm/icons/BIK AI specific/index.d.ts +1 -0
- package/dist/esm/icons/index.d.ts +1 -1
- package/dist/esm/icons/index.js +18 -16
- package/dist/esm/icons/index.js.map +1 -1
- package/dist/esm/index.d.ts +1 -1
- package/dist/esm/index.js +2 -2
- package/package.json +1 -1
- package/dist/cjs/components/banner/AdBanner.js.map +0 -1
- package/dist/cjs/components/banner/Banner.styled.js.map +0 -1
- package/dist/cjs/components/banner/BannerInline.js.map +0 -1
- package/dist/cjs/components/banner/BannerWithImage.js.map +0 -1
- package/dist/cjs/components/banner/CardBanner.js.map +0 -1
- package/dist/cjs/components/banner/CardBannerWithImage.js.map +0 -1
- package/dist/cjs/components/banner/model.js.map +0 -1
- package/dist/esm/components/banner/AdBanner.js.map +0 -1
- package/dist/esm/components/banner/Banner.stories.d.ts +0 -39
- package/dist/esm/components/banner/Banner.styled.js.map +0 -1
- package/dist/esm/components/banner/BannerInline.js.map +0 -1
- package/dist/esm/components/banner/BannerWithImage.js.map +0 -1
- package/dist/esm/components/banner/CardBanner.js.map +0 -1
- package/dist/esm/components/banner/CardBannerWithImage.js.map +0 -1
- package/dist/esm/components/banner/model.js.map +0 -1
- /package/dist/cjs/components/{banner → adbanner}/AdBanner.js +0 -0
- /package/dist/cjs/components/{banner → adbanner}/BannerInline.js +0 -0
- /package/dist/cjs/components/{banner → adbanner}/BannerWithImage.js +0 -0
- /package/dist/cjs/components/{banner → adbanner}/CardBanner.js +0 -0
- /package/dist/cjs/components/{banner → adbanner}/CardBannerWithImage.js +0 -0
- /package/dist/cjs/components/{banner → adbanner}/model.js +0 -0
- /package/dist/esm/components/{banner → adbanner}/AdBanner.d.ts +0 -0
- /package/dist/esm/components/{banner → adbanner}/AdBanner.js +0 -0
- /package/dist/esm/components/{banner → adbanner}/Banner.styled.d.ts +0 -0
- /package/dist/esm/components/{banner → adbanner}/BannerInline.d.ts +0 -0
- /package/dist/esm/components/{banner → adbanner}/BannerInline.js +0 -0
- /package/dist/esm/components/{banner → adbanner}/BannerWithImage.d.ts +0 -0
- /package/dist/esm/components/{banner → adbanner}/BannerWithImage.js +0 -0
- /package/dist/esm/components/{banner → adbanner}/CardBanner.d.ts +0 -0
- /package/dist/esm/components/{banner → adbanner}/CardBanner.js +0 -0
- /package/dist/esm/components/{banner → adbanner}/CardBannerWithImage.d.ts +0 -0
- /package/dist/esm/components/{banner → adbanner}/CardBannerWithImage.js +0 -0
- /package/dist/esm/components/{banner → adbanner}/index.d.ts +0 -0
- /package/dist/esm/components/{banner → adbanner}/model.d.ts +0 -0
- /package/dist/esm/components/{banner → adbanner}/model.js +0 -0
|
@@ -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\tremoveMentionTriggerOnDismiss: mentions?.removeTriggerOnDismiss,\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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"}
|
|
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\tuseState,\n} from 'react';\nimport { BodyCaption } from '@src/components/TypographyStyle';\nimport { Copy, WandSparkles } from '../icons';\nimport {\n\tBikEditorShell,\n\tBikJsonActions,\n\tBikJsonError,\n} from './BikEditor.styles';\nimport {\n\tBikEditorProps,\n\tBikEditorRef,\n\tDEFAULT_FORMAT_STATE,\n\tFormatState,\n\tJsonParseResult,\n} from './BikEditor.types';\nimport {\n\tbuildJsonCodeBlockHtml,\n\tbuildSectionedContent,\n\textractActiveFormats,\n\textractBodyContent,\n\textractContent,\n\textractSectionContent,\n\tfindSectionEndPos,\n\tfindSectionStartPos,\n\tgetCodeBlockText,\n\tinsertInlineHtml,\n\tnormalizeHtml,\n\tparseJson,\n\tsetCodeBlockText,\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\trenderJsonError,\n\t} = props;\n\n\tconst isJsonMode = !!features?.jsonMode;\n\n\t// Live JSON parse error, shown inside the editor when jsonMode is on.\n\t// null = valid (or not applicable) → nothing rendered.\n\tconst [jsonError, setJsonError] = useState<JsonParseResult | null>(null);\n\t// Transient \"Copied\" state for the jsonMode copy button.\n\tconst [jsonCopied, setJsonCopied] = useState(false);\n\n\t// JSON body mode: treat initialContent as raw JSON text and wrap it in a code\n\t// block. Skips section/HTML normalisation entirely.\n\tconst initialEditorContent = isJsonMode\n\t\t? buildJsonCodeBlockHtml(initialContent ?? '')\n\t\t: 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\tremoveMentionTriggerOnDismiss: mentions?.removeTriggerOnDismiss,\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\tif (isJsonMode) {\n\t\t\t\tconst result = parseJson(getCodeBlockText(e));\n\t\t\t\tsetJsonError(result.valid ? null : result);\n\t\t\t}\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\t// Surface an error for invalid initialContent immediately on mount.\n\t\tif (isJsonMode) {\n\t\t\tconst result = parseJson(getCodeBlockText(editor));\n\t\t\tsetJsonError(result.valid ? null : result);\n\t\t}\n\t}, [editor, isJsonMode]);\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\n\t\t\t// ── JSON body ─────────────────────────────────────────────────────\n\t\t\tjson: features?.jsonMode\n\t\t\t\t? {\n\t\t\t\t\t\tgetText: () => (editor ? getCodeBlockText(editor) : ''),\n\t\t\t\t\t\tsetText: (raw) => enqueue((e) => setCodeBlockText(e, raw)),\n\t\t\t\t\t\tparse: () => parseJson(editor ? getCodeBlockText(editor) : ''),\n\t\t\t\t\t\tisValid: () =>\n\t\t\t\t\t\t\tparseJson(editor ? getCodeBlockText(editor) : '').valid,\n\t\t\t\t\t\tformat: (indent = 2) =>\n\t\t\t\t\t\t\tenqueue((e) => {\n\t\t\t\t\t\t\t\tconst { valid, value } = parseJson(getCodeBlockText(e));\n\t\t\t\t\t\t\t\tif (!valid || value === null) return;\n\t\t\t\t\t\t\t\tsetCodeBlockText(e, JSON.stringify(value, null, indent));\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\tminify: () =>\n\t\t\t\t\t\t\tenqueue((e) => {\n\t\t\t\t\t\t\t\tconst { valid, value } = parseJson(getCodeBlockText(e));\n\t\t\t\t\t\t\t\tif (!valid || value === null) return;\n\t\t\t\t\t\t\t\tsetCodeBlockText(e, JSON.stringify(value));\n\t\t\t\t\t\t\t}),\n\t\t\t\t }\n\t\t\t\t: undefined,\n\t\t}),\n\t\t// eslint-disable-next-line react-hooks/exhaustive-deps\n\t\t[editor],\n\t);\n\n\t// ── jsonMode floating actions ────────────────────────────────────────────\n\t// Beautify pretty-prints in place (no-op / disabled while the JSON is broken);\n\t// Copy writes the raw text to the clipboard with transient feedback.\n\tconst handleJsonBeautify = () => {\n\t\tif (!editor) return;\n\t\tconst { valid, value } = parseJson(getCodeBlockText(editor));\n\t\tif (!valid || value === null) return;\n\t\tsetCodeBlockText(editor, JSON.stringify(value, null, 2));\n\t};\n\tconst handleJsonCopy = () => {\n\t\tif (!editor) return;\n\t\tvoid navigator.clipboard?.writeText(getCodeBlockText(editor));\n\t\tsetJsonCopied(true);\n\t\tsetTimeout(() => setJsonCopied(false), 1500);\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\tjsonMode={isJsonMode}\n\t\t\tstyle={style}\n\t\t\tclassName={className}\n\t\t>\n\t\t\t<EditorContent editor={editor} />\n\t\t\t{isJsonMode && (\n\t\t\t\t<BikJsonActions>\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tonClick={handleJsonBeautify}\n\t\t\t\t\t\tdisabled={!!jsonError}\n\t\t\t\t\t\ttitle=\"Format JSON\"\n\t\t\t\t\t\tstyle={{ padding: 8 }}\n\t\t\t\t\t>\n\t\t\t\t\t\t<WandSparkles size={16} />\n\t\t\t\t\t\t<BodyCaption> Beautify </BodyCaption>\n\t\t\t\t\t</button>\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tonClick={handleJsonCopy}\n\t\t\t\t\t\ttitle=\"Copy JSON\"\n\t\t\t\t\t\tstyle={{ padding: 8 }}\n\t\t\t\t\t>\n\t\t\t\t\t\t<Copy size={16} />\n\t\t\t\t\t\t{jsonCopied && <BodyCaption> Copied </BodyCaption>}\n\t\t\t\t\t</button>\n\t\t\t\t</BikJsonActions>\n\t\t\t)}\n\t\t\t<LinkBubbleMenu editor={editor} renderLinkTooltip={link?.renderTooltip} />\n\t\t\t{isJsonMode && jsonError ? (\n\t\t\t\trenderJsonError ? (\n\t\t\t\t\trenderJsonError(jsonError)\n\t\t\t\t) : (\n\t\t\t\t\t<BikJsonError>\n\t\t\t\t\t\t{jsonError.line != null && (\n\t\t\t\t\t\t\t<strong>\n\t\t\t\t\t\t\t\tLine {jsonError.line}\n\t\t\t\t\t\t\t\t{jsonError.column != null ? `, column ${jsonError.column}` : ''}\n\t\t\t\t\t\t\t\t:{' '}\n\t\t\t\t\t\t\t</strong>\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t{jsonError.error}\n\t\t\t\t\t</BikJsonError>\n\t\t\t\t)\n\t\t\t) : null}\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","renderJsonError","isJsonMode","jsonError","setJsonError","useState","jsonCopied","setJsonCopied","initialEditorContent","buildJsonCodeBlockHtml","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","result","parseJson","getCodeBlockText","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","raw","setCodeBlockText","indent","valid","value","handleJsonBeautify","handleJsonCopy","jsxs","BikEditorShell","jsx","EditorContent","BikJsonActions","WandSparkles","BodyCaption","Copy","LinkBubbleMenu","BikJsonError","BikEditor","forwardRef"],"mappings":"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"}
|
|
@@ -2,4 +2,13 @@ export declare const BikEditorShell: import('styled-components').StyledComponent
|
|
|
2
2
|
minHeight?: string | undefined;
|
|
3
3
|
maxHeight?: string | undefined;
|
|
4
4
|
tightParagraphs?: boolean | undefined;
|
|
5
|
+
jsonMode?: boolean | undefined;
|
|
5
6
|
}, never>;
|
|
7
|
+
/**
|
|
8
|
+
* Floating Beautify / Copy action group for jsonMode, pinned to the top-right of
|
|
9
|
+
* the editor so it never collides with a consumer-owned title/header. Sits above
|
|
10
|
+
* the scrolling code area (absolute inside the position:relative shell).
|
|
11
|
+
*/
|
|
12
|
+
export declare const BikJsonActions: import('styled-components').StyledComponent<"div", any, {}, never>;
|
|
13
|
+
/** Inline JSON parse-error banner rendered by BikEditor in jsonMode. */
|
|
14
|
+
export declare const BikJsonError: import('styled-components').StyledComponent<"div", any, {}, never>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import i from "styled-components";
|
|
2
|
-
import { COLORS as
|
|
3
|
-
const
|
|
1
|
+
import o, { css as i } from "styled-components";
|
|
2
|
+
import { COLORS as r } from "../constants/Theme.js";
|
|
3
|
+
const a = o.div`
|
|
4
4
|
position: relative;
|
|
5
5
|
width: 100%;
|
|
6
6
|
|
|
@@ -48,11 +48,11 @@ const o = i.div`
|
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
.bik-mention {
|
|
51
|
-
color: ${
|
|
51
|
+
color: ${r.content.brand};
|
|
52
52
|
padding: 1px 4px;
|
|
53
53
|
}
|
|
54
54
|
.bik-mention--team {
|
|
55
|
-
color: ${
|
|
55
|
+
color: ${r.content.brand};
|
|
56
56
|
}
|
|
57
57
|
/* Typed mention chips (agent-builder): distinct colour per reference kind. */
|
|
58
58
|
.bik-mention[data-kind='tool'] {
|
|
@@ -70,6 +70,82 @@ const o = i.div`
|
|
|
70
70
|
.bik-variable {
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
+
/* JSON body mode — scoped so normal-mode code blocks keep their default look
|
|
74
|
+
(no reserved gutter, no monospace override). */
|
|
75
|
+
${({ jsonMode: e }) => e && i`
|
|
76
|
+
/* The code block IS the editor surface. Put the grey on the scroller so
|
|
77
|
+
it always fills the min-height (no blank strip below short JSON) and
|
|
78
|
+
drop the frame padding so it reaches the edges. */
|
|
79
|
+
.ProseMirror {
|
|
80
|
+
padding: 0;
|
|
81
|
+
background: #f6f8fa;
|
|
82
|
+
}
|
|
83
|
+
/* ProseMirror appends an empty trailing paragraph AFTER the code block
|
|
84
|
+
(a <p><br class="ProseMirror-trailingBreak"></p> caret-escape node).
|
|
85
|
+
In JSON mode there's nothing to escape to — it only renders as a blank
|
|
86
|
+
line under the JSON, which is the "extra space at the bottom". Hide it. */
|
|
87
|
+
.ProseMirror pre + p {
|
|
88
|
+
display: none;
|
|
89
|
+
}
|
|
90
|
+
.ProseMirror pre {
|
|
91
|
+
position: relative;
|
|
92
|
+
margin: 0;
|
|
93
|
+
background: transparent;
|
|
94
|
+
/* Left padding reserves the line-number gutter; the extra top padding
|
|
95
|
+
keeps line 1 clear of the floating Beautify/Copy actions. Each
|
|
96
|
+
.bik-json-lineno widget hangs back into the left padding with a
|
|
97
|
+
matching negative margin. */
|
|
98
|
+
padding: 34px 12px 12px 3.5em;
|
|
99
|
+
font-family: 'SFMono-Regular', ui-monospace, 'JetBrains Mono', Menlo,
|
|
100
|
+
Consolas, 'Liberation Mono', monospace;
|
|
101
|
+
font-size: 13px;
|
|
102
|
+
line-height: 1.6;
|
|
103
|
+
white-space: pre;
|
|
104
|
+
overflow-x: auto;
|
|
105
|
+
tab-size: 2;
|
|
106
|
+
}
|
|
107
|
+
.ProseMirror pre code {
|
|
108
|
+
background: none;
|
|
109
|
+
padding: 0;
|
|
110
|
+
font-size: inherit;
|
|
111
|
+
color: #1f2328;
|
|
112
|
+
}
|
|
113
|
+
/* Line-number gutter. Numbers hang into the code block's left padding via
|
|
114
|
+
a negative margin (width + margin-right == the reserved padding, so the
|
|
115
|
+
code text still starts at the padding edge). Stacked right borders form
|
|
116
|
+
one continuous divider line. */
|
|
117
|
+
.bik-json-lineno {
|
|
118
|
+
display: inline-block;
|
|
119
|
+
box-sizing: border-box;
|
|
120
|
+
width: 2.5em;
|
|
121
|
+
margin-left: -3.5em;
|
|
122
|
+
margin-right: 1em;
|
|
123
|
+
padding-right: 0.7em;
|
|
124
|
+
text-align: right;
|
|
125
|
+
color: #8c959f;
|
|
126
|
+
border-right: 1px solid #e1e4e8;
|
|
127
|
+
user-select: none;
|
|
128
|
+
-webkit-user-select: none;
|
|
129
|
+
}
|
|
130
|
+
.bik-json-key {
|
|
131
|
+
color: #0550ae;
|
|
132
|
+
}
|
|
133
|
+
.bik-json-string {
|
|
134
|
+
color: #0a7d33;
|
|
135
|
+
}
|
|
136
|
+
.bik-json-number {
|
|
137
|
+
color: #b5590a;
|
|
138
|
+
}
|
|
139
|
+
.bik-json-boolean,
|
|
140
|
+
.bik-json-null {
|
|
141
|
+
color: #8250df;
|
|
142
|
+
font-weight: 500;
|
|
143
|
+
}
|
|
144
|
+
.bik-json-punct {
|
|
145
|
+
color: #57606a;
|
|
146
|
+
}
|
|
147
|
+
`}
|
|
148
|
+
|
|
73
149
|
a,
|
|
74
150
|
.bik-link {
|
|
75
151
|
color: #4f46e5;
|
|
@@ -82,8 +158,54 @@ const o = i.div`
|
|
|
82
158
|
text-decoration-color: #6366f1;
|
|
83
159
|
}
|
|
84
160
|
}
|
|
161
|
+
`, d = o.div`
|
|
162
|
+
position: absolute;
|
|
163
|
+
top: 6px;
|
|
164
|
+
right: 6px;
|
|
165
|
+
z-index: 2;
|
|
166
|
+
display: flex;
|
|
167
|
+
gap: 6px;
|
|
168
|
+
|
|
169
|
+
button {
|
|
170
|
+
display: inline-flex;
|
|
171
|
+
align-items: center;
|
|
172
|
+
gap: 4px;
|
|
173
|
+
padding: 8px;
|
|
174
|
+
font-family: inherit;
|
|
175
|
+
font-size: 12px;
|
|
176
|
+
line-height: 1.4;
|
|
177
|
+
color: #57606a;
|
|
178
|
+
background: rgba(255, 255, 255, 0.85);
|
|
179
|
+
backdrop-filter: blur(2px);
|
|
180
|
+
border: 1px solid #e0e0e0;
|
|
181
|
+
border-radius: 4px;
|
|
182
|
+
cursor: pointer;
|
|
183
|
+
|
|
184
|
+
&:hover:not(:disabled) {
|
|
185
|
+
background: #ffffff;
|
|
186
|
+
border-color: #adb5bd;
|
|
187
|
+
}
|
|
188
|
+
&:disabled {
|
|
189
|
+
opacity: 0.5;
|
|
190
|
+
cursor: not-allowed;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
`, s = o.div`
|
|
194
|
+
padding: 6px 12px;
|
|
195
|
+
font-size: 12px;
|
|
196
|
+
line-height: 1.5;
|
|
197
|
+
color: #d1242f;
|
|
198
|
+
background: #fff0f0;
|
|
199
|
+
border-top: 1px solid #ffd7d5;
|
|
200
|
+
word-break: break-word;
|
|
201
|
+
|
|
202
|
+
strong {
|
|
203
|
+
font-weight: 600;
|
|
204
|
+
}
|
|
85
205
|
`;
|
|
86
206
|
export {
|
|
87
|
-
|
|
207
|
+
a as BikEditorShell,
|
|
208
|
+
d as BikJsonActions,
|
|
209
|
+
s as BikJsonError
|
|
88
210
|
};
|
|
89
211
|
//# sourceMappingURL=BikEditor.styles.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BikEditor.styles.js","sources":["../../../src/editor/BikEditor.styles.ts"],"sourcesContent":["import styled from 'styled-components';\nimport { COLORS } from '../constants/Theme';\n\nexport const BikEditorShell = styled.div<{\n\tminHeight?: string;\n\tmaxHeight?: string;\n\ttightParagraphs?: boolean;\n}>`\n\tposition: relative;\n\twidth: 100%;\n\n\t.ProseMirror {\n\t\tmin-height: ${({ minHeight }) => minHeight ?? '80px'};\n\t\tmax-height: ${({ maxHeight }) => maxHeight ?? 'none'};\n\t\toverflow-y: auto;\n\t\toutline: none;\n\t\tpadding: 8px 12px;\n\t\tfont-size: 14px;\n\t\tline-height: 1.5;\n\t\tword-break: break-word;\n\n\t\t/* Paragraph spacing.\n\t\t Email/signature (rich): paragraphs carry the browser-default 1em block\n\t\t margin — the SAME spacing the sent HTML gets (we emit plain <p>, which\n\t\t renders against the default <p> margin in Gmail and our email viewer),\n\t\t so editor view == emitted HTML == Gmail. A single Enter = a new\n\t\t paragraph with a visible gap, like pasted Gmail/ChatGPT/Docs content.\n\t\t Other channels (WhatsApp/IG/FB/comments) are plain-text messaging, with\n\t\t no paragraph-gap concept — paragraphs are tight (margin:0) regardless of\n\t\t typed vs pasted. (A margin:0 attr still overrides to tight either way.) */\n\t\tp {\n\t\t\tmargin: ${({ tightParagraphs }) => (tightParagraphs ? '0' : '1em 0')};\n\t\t\tpadding: 0;\n\t\t}\n\n\t\tul,\n\t\tol {\n\t\t\tmargin: 0;\n\t\t\tpadding-left: 1.5em;\n\t\t}\n\n\t\tli + li {\n\t\t\tmargin-top: 2px;\n\t\t}\n\n\t\tp.is-editor-empty:first-child::before {\n\t\t\tcontent: attr(data-placeholder);\n\t\t\tfloat: left;\n\t\t\tcolor: #adb5bd;\n\t\t\tpointer-events: none;\n\t\t\theight: 0;\n\t\t}\n\t}\n\n\t.bik-mention {\n\t\tcolor: ${COLORS.content.brand};\n\t\tpadding: 1px 4px;\n\t}\n\t.bik-mention--team {\n\t\tcolor: ${COLORS.content.brand};\n\t}\n\t/* Typed mention chips (agent-builder): distinct colour per reference kind. */\n\t.bik-mention[data-kind='tool'] {\n\t\tcolor: #1570ef;\n\t\tbackground: #eff8ff;\n\t\tborder-radius: 4px;\n\t\tfont-weight: 500;\n\t}\n\t.bik-mention[data-kind='subagent'] {\n\t\tcolor: #6938ef;\n\t\tbackground: #f4f3ff;\n\t\tborder-radius: 4px;\n\t\tfont-weight: 500;\n\t}\n\t.bik-variable {\n\t}\n\n\ta,\n\t.bik-link {\n\t\tcolor: #4f46e5;\n\t\ttext-decoration: underline;\n\t\ttext-decoration-color: #a5b4fc;\n\t\ttext-underline-offset: 2px;\n\t\tcursor: pointer;\n\t\t&:hover {\n\t\t\tcolor: #3730a3;\n\t\t\ttext-decoration-color: #6366f1;\n\t\t}\n\t}\n`;\n"],"names":["BikEditorShell","styled","minHeight","maxHeight","tightParagraphs","COLORS"],"mappings":";;AAGO,MAAMA,IAAiBC,EAAO;AAAA;AAAA;AAAA;AAAA;AAAA,
|
|
1
|
+
{"version":3,"file":"BikEditor.styles.js","sources":["../../../src/editor/BikEditor.styles.ts"],"sourcesContent":["import styled, { css } from 'styled-components';\nimport { COLORS } from '../constants/Theme';\n\nexport const BikEditorShell = styled.div<{\n\tminHeight?: string;\n\tmaxHeight?: string;\n\ttightParagraphs?: boolean;\n\tjsonMode?: boolean;\n}>`\n\tposition: relative;\n\twidth: 100%;\n\n\t.ProseMirror {\n\t\tmin-height: ${({ minHeight }) => minHeight ?? '80px'};\n\t\tmax-height: ${({ maxHeight }) => maxHeight ?? 'none'};\n\t\toverflow-y: auto;\n\t\toutline: none;\n\t\tpadding: 8px 12px;\n\t\tfont-size: 14px;\n\t\tline-height: 1.5;\n\t\tword-break: break-word;\n\n\t\t/* Paragraph spacing.\n\t\t Email/signature (rich): paragraphs carry the browser-default 1em block\n\t\t margin — the SAME spacing the sent HTML gets (we emit plain <p>, which\n\t\t renders against the default <p> margin in Gmail and our email viewer),\n\t\t so editor view == emitted HTML == Gmail. A single Enter = a new\n\t\t paragraph with a visible gap, like pasted Gmail/ChatGPT/Docs content.\n\t\t Other channels (WhatsApp/IG/FB/comments) are plain-text messaging, with\n\t\t no paragraph-gap concept — paragraphs are tight (margin:0) regardless of\n\t\t typed vs pasted. (A margin:0 attr still overrides to tight either way.) */\n\t\tp {\n\t\t\tmargin: ${({ tightParagraphs }) => (tightParagraphs ? '0' : '1em 0')};\n\t\t\tpadding: 0;\n\t\t}\n\n\t\tul,\n\t\tol {\n\t\t\tmargin: 0;\n\t\t\tpadding-left: 1.5em;\n\t\t}\n\n\t\tli + li {\n\t\t\tmargin-top: 2px;\n\t\t}\n\n\t\tp.is-editor-empty:first-child::before {\n\t\t\tcontent: attr(data-placeholder);\n\t\t\tfloat: left;\n\t\t\tcolor: #adb5bd;\n\t\t\tpointer-events: none;\n\t\t\theight: 0;\n\t\t}\n\t}\n\n\t.bik-mention {\n\t\tcolor: ${COLORS.content.brand};\n\t\tpadding: 1px 4px;\n\t}\n\t.bik-mention--team {\n\t\tcolor: ${COLORS.content.brand};\n\t}\n\t/* Typed mention chips (agent-builder): distinct colour per reference kind. */\n\t.bik-mention[data-kind='tool'] {\n\t\tcolor: #1570ef;\n\t\tbackground: #eff8ff;\n\t\tborder-radius: 4px;\n\t\tfont-weight: 500;\n\t}\n\t.bik-mention[data-kind='subagent'] {\n\t\tcolor: #6938ef;\n\t\tbackground: #f4f3ff;\n\t\tborder-radius: 4px;\n\t\tfont-weight: 500;\n\t}\n\t.bik-variable {\n\t}\n\n\t/* JSON body mode — scoped so normal-mode code blocks keep their default look\n\t (no reserved gutter, no monospace override). */\n\t${({ jsonMode }) =>\n\t\tjsonMode &&\n\t\tcss`\n\t\t\t/* The code block IS the editor surface. Put the grey on the scroller so\n\t\t\t it always fills the min-height (no blank strip below short JSON) and\n\t\t\t drop the frame padding so it reaches the edges. */\n\t\t\t.ProseMirror {\n\t\t\t\tpadding: 0;\n\t\t\t\tbackground: #f6f8fa;\n\t\t\t}\n\t\t\t/* ProseMirror appends an empty trailing paragraph AFTER the code block\n\t\t\t (a <p><br class=\"ProseMirror-trailingBreak\"></p> caret-escape node).\n\t\t\t In JSON mode there's nothing to escape to — it only renders as a blank\n\t\t\t line under the JSON, which is the \"extra space at the bottom\". Hide it. */\n\t\t\t.ProseMirror pre + p {\n\t\t\t\tdisplay: none;\n\t\t\t}\n\t\t\t.ProseMirror pre {\n\t\t\t\tposition: relative;\n\t\t\t\tmargin: 0;\n\t\t\t\tbackground: transparent;\n\t\t\t\t/* Left padding reserves the line-number gutter; the extra top padding\n\t\t\t\t keeps line 1 clear of the floating Beautify/Copy actions. Each\n\t\t\t\t .bik-json-lineno widget hangs back into the left padding with a\n\t\t\t\t matching negative margin. */\n\t\t\t\tpadding: 34px 12px 12px 3.5em;\n\t\t\t\tfont-family: 'SFMono-Regular', ui-monospace, 'JetBrains Mono', Menlo,\n\t\t\t\t\tConsolas, 'Liberation Mono', monospace;\n\t\t\t\tfont-size: 13px;\n\t\t\t\tline-height: 1.6;\n\t\t\t\twhite-space: pre;\n\t\t\t\toverflow-x: auto;\n\t\t\t\ttab-size: 2;\n\t\t\t}\n\t\t\t.ProseMirror pre code {\n\t\t\t\tbackground: none;\n\t\t\t\tpadding: 0;\n\t\t\t\tfont-size: inherit;\n\t\t\t\tcolor: #1f2328;\n\t\t\t}\n\t\t\t/* Line-number gutter. Numbers hang into the code block's left padding via\n\t\t\t a negative margin (width + margin-right == the reserved padding, so the\n\t\t\t code text still starts at the padding edge). Stacked right borders form\n\t\t\t one continuous divider line. */\n\t\t\t.bik-json-lineno {\n\t\t\t\tdisplay: inline-block;\n\t\t\t\tbox-sizing: border-box;\n\t\t\t\twidth: 2.5em;\n\t\t\t\tmargin-left: -3.5em;\n\t\t\t\tmargin-right: 1em;\n\t\t\t\tpadding-right: 0.7em;\n\t\t\t\ttext-align: right;\n\t\t\t\tcolor: #8c959f;\n\t\t\t\tborder-right: 1px solid #e1e4e8;\n\t\t\t\tuser-select: none;\n\t\t\t\t-webkit-user-select: none;\n\t\t\t}\n\t\t\t.bik-json-key {\n\t\t\t\tcolor: #0550ae;\n\t\t\t}\n\t\t\t.bik-json-string {\n\t\t\t\tcolor: #0a7d33;\n\t\t\t}\n\t\t\t.bik-json-number {\n\t\t\t\tcolor: #b5590a;\n\t\t\t}\n\t\t\t.bik-json-boolean,\n\t\t\t.bik-json-null {\n\t\t\t\tcolor: #8250df;\n\t\t\t\tfont-weight: 500;\n\t\t\t}\n\t\t\t.bik-json-punct {\n\t\t\t\tcolor: #57606a;\n\t\t\t}\n\t\t`}\n\n\ta,\n\t.bik-link {\n\t\tcolor: #4f46e5;\n\t\ttext-decoration: underline;\n\t\ttext-decoration-color: #a5b4fc;\n\t\ttext-underline-offset: 2px;\n\t\tcursor: pointer;\n\t\t&:hover {\n\t\t\tcolor: #3730a3;\n\t\t\ttext-decoration-color: #6366f1;\n\t\t}\n\t}\n`;\n\n/**\n * Floating Beautify / Copy action group for jsonMode, pinned to the top-right of\n * the editor so it never collides with a consumer-owned title/header. Sits above\n * the scrolling code area (absolute inside the position:relative shell).\n */\nexport const BikJsonActions = styled.div`\n\tposition: absolute;\n\ttop: 6px;\n\tright: 6px;\n\tz-index: 2;\n\tdisplay: flex;\n\tgap: 6px;\n\n\tbutton {\n\t\tdisplay: inline-flex;\n\t\talign-items: center;\n\t\tgap: 4px;\n\t\tpadding: 8px;\n\t\tfont-family: inherit;\n\t\tfont-size: 12px;\n\t\tline-height: 1.4;\n\t\tcolor: #57606a;\n\t\tbackground: rgba(255, 255, 255, 0.85);\n\t\tbackdrop-filter: blur(2px);\n\t\tborder: 1px solid #e0e0e0;\n\t\tborder-radius: 4px;\n\t\tcursor: pointer;\n\n\t\t&:hover:not(:disabled) {\n\t\t\tbackground: #ffffff;\n\t\t\tborder-color: #adb5bd;\n\t\t}\n\t\t&:disabled {\n\t\t\topacity: 0.5;\n\t\t\tcursor: not-allowed;\n\t\t}\n\t}\n`;\n\n/** Inline JSON parse-error banner rendered by BikEditor in jsonMode. */\nexport const BikJsonError = styled.div`\n\tpadding: 6px 12px;\n\tfont-size: 12px;\n\tline-height: 1.5;\n\tcolor: #d1242f;\n\tbackground: #fff0f0;\n\tborder-top: 1px solid #ffd7d5;\n\tword-break: break-word;\n\n\tstrong {\n\t\tfont-weight: 600;\n\t}\n`;\n"],"names":["BikEditorShell","styled","minHeight","maxHeight","tightParagraphs","COLORS","jsonMode","css","BikJsonActions","BikJsonError"],"mappings":";;AAGO,MAAMA,IAAiBC,EAAO;AAAA;AAAA;AAAA;AAAA;AAAA,gBAUrB,CAAC,EAAE,WAAAC,QAAgBA,KAAa,MAAM;AAAA,gBACtC,CAAC,EAAE,WAAAC,QAAgBA,KAAa,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,aAkBzC,CAAC,EAAE,iBAAAC,EAAA,MAAuBA,IAAkB,MAAM,OAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,WAwB5DC,EAAO,QAAQ,KAAK;AAAA;AAAA;AAAA;AAAA,WAIpBA,EAAO,QAAQ,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GAoB5B,CAAC,EAAE,UAAAC,QACJA,KACAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GAwEC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GAqBUC,IAAiBP,EAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GAmCxBQ,IAAeR,EAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;"}
|
|
@@ -22,6 +22,16 @@ export interface EditorFeatures {
|
|
|
22
22
|
* features={{ allowedMarks: ['bold'] }}
|
|
23
23
|
*/
|
|
24
24
|
allowedMarks?: Array<'bold' | 'italic' | 'strike' | 'underline' | 'code'>;
|
|
25
|
+
/**
|
|
26
|
+
* Turn the editor into a Postman-style JSON body editor: the whole document
|
|
27
|
+
* becomes one syntax-highlighted JSON code block. Disables the rich-text stack
|
|
28
|
+
* (mentions, typography, rich paste, sections). Drive it via `ref.json.*`.
|
|
29
|
+
* Default: `false`.
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* <BikEditor features={{ jsonMode: true }} initialContent='{ "id": 1 }' />
|
|
33
|
+
*/
|
|
34
|
+
jsonMode?: boolean;
|
|
25
35
|
}
|
|
26
36
|
/**
|
|
27
37
|
* A named content section placed below the main body, separated by an invisible divider.
|
|
@@ -96,6 +106,51 @@ export interface EditorSnapshot {
|
|
|
96
106
|
/** Character count at this point in time. */
|
|
97
107
|
characterCount: number;
|
|
98
108
|
}
|
|
109
|
+
/**
|
|
110
|
+
* Result of parsing the JSON body (features.jsonMode). Returned by `ref.json.parse()`.
|
|
111
|
+
* Empty / whitespace-only content is treated as valid with a `null` value.
|
|
112
|
+
*/
|
|
113
|
+
export interface JsonParseResult {
|
|
114
|
+
/** True when the current text is valid JSON. */
|
|
115
|
+
valid: boolean;
|
|
116
|
+
/** The parsed value (`null` when empty or invalid). */
|
|
117
|
+
value: unknown;
|
|
118
|
+
/**
|
|
119
|
+
* Human-readable error message, cleaned of the raw parser noise
|
|
120
|
+
* (e.g. `"Bad control character in string literal"` instead of
|
|
121
|
+
* `"… in JSON at position 94 (line 7 column 9)"`). `null` when valid.
|
|
122
|
+
*/
|
|
123
|
+
error: string | null;
|
|
124
|
+
/** 1-based line of the error, or `null` when valid / not locatable. */
|
|
125
|
+
line: number | null;
|
|
126
|
+
/** 1-based column of the error, or `null` when valid / not locatable. */
|
|
127
|
+
column: number | null;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* JSON body controls, available on the ref when `features.jsonMode` is on.
|
|
131
|
+
* Access via `editorRef.current.json`.
|
|
132
|
+
*
|
|
133
|
+
* @example
|
|
134
|
+
* editorRef.current?.json?.format(); // pretty-print (2-space indent)
|
|
135
|
+
* const { valid, value } = editorRef.current!.json!.parse();
|
|
136
|
+
*/
|
|
137
|
+
export interface JsonBodyApi {
|
|
138
|
+
/** Current raw text of the JSON body. */
|
|
139
|
+
getText: () => string;
|
|
140
|
+
/** Replace the whole JSON body with `raw` and fire onChange. */
|
|
141
|
+
setText: (raw: string) => void;
|
|
142
|
+
/** Parse the current text without throwing — see JsonParseResult. */
|
|
143
|
+
parse: () => JsonParseResult;
|
|
144
|
+
/** True when the current text is valid JSON. */
|
|
145
|
+
isValid: () => boolean;
|
|
146
|
+
/**
|
|
147
|
+
* Pretty-print the current text in place. No-op when the text is invalid.
|
|
148
|
+
* @param indent Number of spaces per level. Default `2`.
|
|
149
|
+
*/
|
|
150
|
+
format: (indent?: number) => void;
|
|
151
|
+
/** Collapse the current text to a single line. No-op when invalid. */
|
|
152
|
+
minify: () => void;
|
|
153
|
+
}
|
|
99
154
|
/** One item shown in the @agent or #team mention dropdown. */
|
|
100
155
|
export interface MentionItem {
|
|
101
156
|
/** Unique identifier stored as a node attribute. Used to look up the item later. */
|
|
@@ -571,6 +626,14 @@ export interface BikEditorRef {
|
|
|
571
626
|
getActiveFormats: () => FormatState;
|
|
572
627
|
/** All formatting and insertion commands. See EditorActions. */
|
|
573
628
|
actions: EditorActions;
|
|
629
|
+
/**
|
|
630
|
+
* JSON body controls. Present only when `features.jsonMode` is on
|
|
631
|
+
* (`undefined` otherwise). See JsonBodyApi.
|
|
632
|
+
*
|
|
633
|
+
* @example
|
|
634
|
+
* editorRef.current?.json?.format();
|
|
635
|
+
*/
|
|
636
|
+
json?: JsonBodyApi;
|
|
574
637
|
}
|
|
575
638
|
/**
|
|
576
639
|
* Props for `<BikEditor />`. All props are optional.
|
|
@@ -678,6 +741,19 @@ export interface BikEditorProps {
|
|
|
678
741
|
* )}}
|
|
679
742
|
*/
|
|
680
743
|
link?: LinkConfig;
|
|
744
|
+
/**
|
|
745
|
+
* Custom renderer for the JSON parse error shown below the editor in
|
|
746
|
+
* `features.jsonMode`. Receives the current {@link JsonParseResult} (always
|
|
747
|
+
* an invalid one — it's only called when the JSON is broken). Omit to use the
|
|
748
|
+
* built-in inline error banner; the error is never rendered when the JSON is
|
|
749
|
+
* valid or when `jsonMode` is off.
|
|
750
|
+
*
|
|
751
|
+
* @example
|
|
752
|
+
* renderJsonError={(err) => (
|
|
753
|
+
* <MyBanner>Line {err.line}: {err.error}</MyBanner>
|
|
754
|
+
* )}
|
|
755
|
+
*/
|
|
756
|
+
renderJsonError?: (error: JsonParseResult) => React.ReactNode;
|
|
681
757
|
/**
|
|
682
758
|
* Called once, immediately after the editor finishes initializing.
|
|
683
759
|
* Any imperative ref methods called before this fires are queued internally
|