@ant-design/agentic-ui 2.30.21 → 2.30.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/dist/Bubble/MessagesContent/MarkdownPreview.js +6 -5
  2. package/dist/Bubble/OpenAIMessageBubble/index.d.ts +11 -0
  3. package/dist/Bubble/OpenAIMessageBubble/index.js +8 -0
  4. package/dist/Bubble/OpenAIMessageBubble/mapOllamaMessages.d.ts +7 -0
  5. package/dist/Bubble/OpenAIMessageBubble/mapOllamaMessages.js +136 -0
  6. package/dist/Bubble/OpenAIMessageBubble/mapOpenAIMessages.d.ts +8 -0
  7. package/dist/Bubble/OpenAIMessageBubble/mapOpenAIMessages.js +156 -0
  8. package/dist/Bubble/OpenAIMessageBubble/mapOpenClawMessages.d.ts +8 -0
  9. package/dist/Bubble/OpenAIMessageBubble/mapOpenClawMessages.js +127 -0
  10. package/dist/Bubble/OpenAIMessageBubble/normalizeOllamaMessages.d.ts +16 -0
  11. package/dist/Bubble/OpenAIMessageBubble/normalizeOllamaMessages.js +110 -0
  12. package/dist/Bubble/OpenAIMessageBubble/normalizeOpenClawMessages.d.ts +10 -0
  13. package/dist/Bubble/OpenAIMessageBubble/normalizeOpenClawMessages.js +61 -0
  14. package/dist/Bubble/OpenAIMessageBubble/ollamaTypes.d.ts +48 -0
  15. package/dist/Bubble/OpenAIMessageBubble/ollamaTypes.js +1 -0
  16. package/dist/Bubble/OpenAIMessageBubble/openClawTypes.d.ts +27 -0
  17. package/dist/Bubble/OpenAIMessageBubble/openClawTypes.js +1 -0
  18. package/dist/Bubble/OpenAIMessageBubble/types.d.ts +71 -0
  19. package/dist/Bubble/OpenAIMessageBubble/types.js +1 -0
  20. package/dist/Bubble/OpenAIMessageBubble/useOllamaMessageBubbleData.d.ts +7 -0
  21. package/dist/Bubble/OpenAIMessageBubble/useOllamaMessageBubbleData.js +23 -0
  22. package/dist/Bubble/OpenAIMessageBubble/useOpenAIMessageBubbleData.d.ts +6 -0
  23. package/dist/Bubble/OpenAIMessageBubble/useOpenAIMessageBubbleData.js +20 -0
  24. package/dist/Bubble/OpenAIMessageBubble/useOpenClawMessageBubbleData.d.ts +7 -0
  25. package/dist/Bubble/OpenAIMessageBubble/useOpenClawMessageBubbleData.js +22 -0
  26. package/dist/Bubble/index.d.ts +2 -0
  27. package/dist/Bubble/index.js +1 -0
  28. package/dist/MarkdownEditor/editor/Editor.js +24 -12
  29. package/dist/MarkdownEditor/editor/elements/Table/SimpleTable.js +5 -1
  30. package/dist/MarkdownEditor/editor/elements/Table/commands/tableCommands.js +24 -8
  31. package/dist/MarkdownEditor/editor/elements/index.js +18 -14
  32. package/dist/MarkdownEditor/editor/store.d.ts +12 -0
  33. package/dist/MarkdownEditor/editor/store.js +30 -5
  34. package/dist/MarkdownEditor/editor/tools/InsertAutocomplete.js +15 -11
  35. package/dist/MarkdownInputField/AttachmentButton/AttachmentFileList/AttachmentFileListItem.d.ts +1 -1
  36. package/dist/MarkdownInputField/AttachmentButton/AttachmentFileList/AttachmentFileListItem.js +4 -5
  37. package/dist/MarkdownInputField/AttachmentButton/AttachmentFileList/index.d.ts +1 -1
  38. package/dist/MarkdownInputField/AttachmentButton/index.d.ts +1 -1
  39. package/dist/MarkdownInputField/MarkdownInputField.js +6 -1
  40. package/dist/MarkdownInputField/hooks/useMarkdownInputFieldHandlers.js +6 -2
  41. package/dist/MarkdownInputField/hooks/useMarkdownInputFieldRefs.d.ts +1 -0
  42. package/dist/MarkdownInputField/hooks/useMarkdownInputFieldRefs.js +36 -5
  43. package/dist/MarkdownInputField/utils/renderHelpers.js +5 -0
  44. package/dist/MarkdownRenderer/FncRefForMarkdown.d.ts +24 -0
  45. package/dist/MarkdownRenderer/FncRefForMarkdown.js +65 -0
  46. package/dist/MarkdownRenderer/MarkdownRenderer.js +24 -9
  47. package/dist/MarkdownRenderer/extractFootnoteDefinitions.d.ts +13 -0
  48. package/dist/MarkdownRenderer/extractFootnoteDefinitions.js +40 -0
  49. package/dist/MarkdownRenderer/markdownReactShared.d.ts +4 -1
  50. package/dist/MarkdownRenderer/markdownReactShared.js +20 -10
  51. package/dist/MarkdownRenderer/renderers/CodeRenderer.d.ts +4 -1
  52. package/dist/MarkdownRenderer/renderers/CodeRenderer.js +27 -3
  53. package/dist/MarkdownRenderer/renderers/SchemaRenderer.d.ts +2 -0
  54. package/dist/MarkdownRenderer/renderers/SchemaRenderer.js +33 -5
  55. package/dist/MarkdownRenderer/streaming/useStreamingMarkdownReact.js +2 -1
  56. package/dist/MarkdownRenderer/types.d.ts +5 -9
  57. package/dist/MarkdownRenderer/useMarkdownToReact.js +1 -1
  58. package/dist/Plugins/mermaid/MermaidRendererImpl.js +481 -7
  59. package/dist/Plugins/mermaid/style.js +71 -22
  60. package/dist/Plugins/mermaid/useMermaidRender.d.ts +2 -1
  61. package/dist/Plugins/mermaid/useMermaidRender.js +41 -13
  62. package/dist/Plugins/mermaid/utils.d.ts +16 -0
  63. package/dist/Plugins/mermaid/utils.js +197 -5
  64. package/dist/Workspace/Browser/index.js +19 -1
  65. package/package.json +8 -7
@@ -110,13 +110,13 @@ export var AttachmentFileListItem = function AttachmentFileListItem(param) {
110
110
  var isDoneStatus = file.status === 'done';
111
111
  var canDelete = !isAttachmentFileLoading(file.status);
112
112
  var handleFileClick = function handleFileClick() {
113
+ if (canRetry) {
114
+ onRetry === null || onRetry === void 0 ? void 0 : onRetry(file);
115
+ return;
116
+ }
113
117
  if (!isDoneStatus) return;
114
118
  onPreview === null || onPreview === void 0 ? void 0 : onPreview(file);
115
119
  };
116
- var handleRetryClick = function handleRetryClick() {
117
- if (!canRetry) return;
118
- onRetry === null || onRetry === void 0 ? void 0 : onRetry(file);
119
- };
120
120
  var handleDeleteClick = function handleDeleteClick(e) {
121
121
  e.stopPropagation();
122
122
  onDelete(file);
@@ -145,7 +145,6 @@ export var AttachmentFileListItem = function AttachmentFileListItem(param) {
145
145
  }), /*#__PURE__*/ React.createElement("div", {
146
146
  className: classNames("".concat(prefixCls, "-file-info"), hashId)
147
147
  }, /*#__PURE__*/ React.createElement("div", {
148
- onClick: handleRetryClick,
149
148
  className: classNames("".concat(prefixCls, "-file-name"), hashId)
150
149
  }, /*#__PURE__*/ React.createElement("span", {
151
150
  className: classNames("".concat(prefixCls, "-file-name-text"), hashId)
@@ -3,7 +3,7 @@ import { AttachmentFile } from '../types';
3
3
  export type AttachmentFileListProps = {
4
4
  fileMap?: Map<string, AttachmentFile>;
5
5
  onDelete: (file: AttachmentFile) => void;
6
- onPreview?: (file: AttachmentFile) => void;
6
+ onPreview?: (file: AttachmentFile) => void | Promise<void>;
7
7
  onDownload?: (file: AttachmentFile) => void;
8
8
  onRetry?: (file: AttachmentFile) => void;
9
9
  onClearFileMap?: () => void;
@@ -31,7 +31,7 @@ export type AttachmentButtonProps = {
31
31
  /** 删除文件回调 */
32
32
  onDelete?: (file: AttachmentFile) => Promise<void>;
33
33
  /** 预览文件回调 */
34
- onPreview?: (file: AttachmentFile) => Promise<void>;
34
+ onPreview?: (file: AttachmentFile) => void | Promise<void>;
35
35
  /** 下载文件回调 */
36
36
  onDownload?: (file: AttachmentFile) => Promise<void>;
37
37
  /** 单个文件最大大小(字节) */
@@ -255,7 +255,7 @@ var MarkdownInputFieldComponent = function MarkdownInputFieldComponent(_0) {
255
255
  inputRef: props.inputRef,
256
256
  value: props.value,
257
257
  setValue: setValue
258
- }), markdownEditorRef = _useMarkdownInputFieldRefs.markdownEditorRef, quickActionsRef = _useMarkdownInputFieldRefs.quickActionsRef, actionsRef = _useMarkdownInputFieldRefs.actionsRef, isSendingRef = _useMarkdownInputFieldRefs.isSendingRef;
258
+ }), markdownEditorRef = _useMarkdownInputFieldRefs.markdownEditorRef, quickActionsRef = _useMarkdownInputFieldRefs.quickActionsRef, actionsRef = _useMarkdownInputFieldRefs.actionsRef, isSendingRef = _useMarkdownInputFieldRefs.isSendingRef, onEditorChange = _useMarkdownInputFieldRefs.onEditorChange;
259
259
  // 文件上传管理
260
260
  var _useFileUploadManager = useFileUploadManager({
261
261
  attachment: attachment,
@@ -446,6 +446,7 @@ var MarkdownInputFieldComponent = function MarkdownInputFieldComponent(_0) {
446
446
  var _props_onChange1, _props_onMaxLengthExceeded, // 更新编辑器内容以反映截断后的值
447
447
  _markdownEditorRef_current_store, _markdownEditorRef_current;
448
448
  var truncatedValue = value.slice(0, props.maxLength);
449
+ onEditorChange(truncatedValue);
449
450
  setValue(truncatedValue);
450
451
  (_props_onChange1 = props.onChange) === null || _props_onChange1 === void 0 ? void 0 : _props_onChange1.call(props, truncatedValue);
451
452
  (_props_onMaxLengthExceeded = props.onMaxLengthExceeded) === null || _props_onMaxLengthExceeded === void 0 ? void 0 : _props_onMaxLengthExceeded.call(props, value);
@@ -453,6 +454,10 @@ var MarkdownInputFieldComponent = function MarkdownInputFieldComponent(_0) {
453
454
  return;
454
455
  }
455
456
  }
457
+ // Record the value the editor just produced so the external
458
+ // props.value sync effect skips the redundant setMDContent call
459
+ // that would disrupt the live Slate selection while typing.
460
+ onEditorChange(value);
456
461
  setValue(value);
457
462
  (_props_onChange = props.onChange) === null || _props_onChange === void 0 ? void 0 : _props_onChange.call(props, value);
458
463
  },
@@ -401,8 +401,12 @@ import { getFileListFromDataTransferItems } from "../FilePaste";
401
401
  var isInteractive = target.closest('button') || target.closest('a') || target.closest('input') || target.closest('[contenteditable="true"]');
402
402
  if (isInteractive) return;
403
403
  EditorUtils.focus(editor);
404
- var end = Editor.end(editor, []);
405
- Transforms.select(editor, end);
404
+ try {
405
+ var end = Editor.end(editor, []);
406
+ Transforms.select(editor, end);
407
+ } catch (unused) {
408
+ // editor may have no valid content points yet; focus is still applied
409
+ }
406
410
  });
407
411
  var activeInput = useRefFunction(function(active) {
408
412
  if (inputRef.current) {
@@ -13,5 +13,6 @@ export declare const useMarkdownInputFieldRefs: (props: UseMarkdownInputFieldRef
13
13
  quickActionsRef: import("react").RefObject<HTMLDivElement>;
14
14
  actionsRef: import("react").RefObject<HTMLDivElement>;
15
15
  isSendingRef: import("react").MutableRefObject<boolean>;
16
+ onEditorChange: (value: string) => void;
16
17
  };
17
18
  export {};
@@ -50,7 +50,8 @@ function _object_spread_props(target, source) {
50
50
  }
51
51
  return target;
52
52
  }
53
- import { useEffect, useImperativeHandle, useRef } from "react";
53
+ import { useCallback, useEffect, useImperativeHandle, useRef } from "react";
54
+ import { ReactEditor } from "slate-react";
54
55
  /**
55
56
  * Refs 管理 Hook
56
57
  * 管理组件中所有的 refs 和相关逻辑
@@ -59,12 +60,41 @@ import { useEffect, useImperativeHandle, useRef } from "react";
59
60
  var quickActionsRef = useRef(null);
60
61
  var actionsRef = useRef(null);
61
62
  var isSendingRef = useRef(false);
62
- // 同步外部 value 到编辑器
63
+ /**
64
+ * Tracks the last value emitted by the editor's own onChange callback.
65
+ * When props.value matches this ref we know the update originated from the
66
+ * editor itself and there is no need to call setMDContent — doing so would
67
+ * replace the live Slate document while the user is actively typing, causing
68
+ * ReactEditor.deselect() to throw "Failed to execute 'collapseToEnd' on
69
+ * 'Selection': There is no selection", which crashes the component tree.
70
+ */ var lastEditorValueRef = useRef(undefined);
71
+ /** Called by MarkdownInputField's onChange handler to record what the editor just emitted. */ var onEditorChange = useCallback(function(value) {
72
+ lastEditorValueRef.current = value;
73
+ }, []);
74
+ // 同步外部 value 到编辑器 — 只在 value 来自外部(非编辑器自身输入)时写回
63
75
  useEffect(function() {
64
76
  var _props_value;
65
- var _markdownEditorRef_current_store, _markdownEditorRef_current;
77
+ var _markdownEditorRef_current_markdownEditorRef, _markdownEditorRef_current, _markdownEditorRef_current_store, _markdownEditorRef_current1;
66
78
  if (!markdownEditorRef.current) return;
67
- (_markdownEditorRef_current = markdownEditorRef.current) === null || _markdownEditorRef_current === void 0 ? void 0 : (_markdownEditorRef_current_store = _markdownEditorRef_current.store) === null || _markdownEditorRef_current_store === void 0 ? void 0 : _markdownEditorRef_current_store.setMDContent((_props_value = props.value) !== null && _props_value !== void 0 ? _props_value : '');
79
+ // Primary guard: this value was just produced by the editor itself
80
+ // the Slate document is already correct, no write-back needed.
81
+ if (props.value === lastEditorValueRef.current) return;
82
+ // Secondary guard: the editor is focused, meaning the user is actively
83
+ // typing. A stale props.value (delayed by debounce + React batching) could
84
+ // arrive *after* the editor has moved on to a newer character. Calling
85
+ // setMDContent in that window replaces the live document and triggers
86
+ // ReactEditor.deselect() on a focused editor → InvalidStateError → white
87
+ // screen. Skip the write; _safeDeselect in store.ts also defends here as
88
+ // a last resort, but not calling setMDContent at all is the clean fix.
89
+ var slateEditor = (_markdownEditorRef_current = markdownEditorRef.current) === null || _markdownEditorRef_current === void 0 ? void 0 : (_markdownEditorRef_current_markdownEditorRef = _markdownEditorRef_current.markdownEditorRef) === null || _markdownEditorRef_current_markdownEditorRef === void 0 ? void 0 : _markdownEditorRef_current_markdownEditorRef.current;
90
+ if (slateEditor) {
91
+ try {
92
+ if (ReactEditor.isFocused(slateEditor)) return;
93
+ } catch (unused) {
94
+ // ReactEditor.isFocused can throw if the editor is being torn down
95
+ }
96
+ }
97
+ (_markdownEditorRef_current1 = markdownEditorRef.current) === null || _markdownEditorRef_current1 === void 0 ? void 0 : (_markdownEditorRef_current_store = _markdownEditorRef_current1.store) === null || _markdownEditorRef_current_store === void 0 ? void 0 : _markdownEditorRef_current_store.setMDContent((_props_value = props.value) !== null && _props_value !== void 0 ? _props_value : '');
68
98
  }, [
69
99
  props.value
70
100
  ]);
@@ -104,6 +134,7 @@ import { useEffect, useImperativeHandle, useRef } from "react";
104
134
  markdownEditorRef: markdownEditorRef,
105
135
  quickActionsRef: quickActionsRef,
106
136
  actionsRef: actionsRef,
107
- isSendingRef: isSendingRef
137
+ isSendingRef: isSendingRef,
138
+ onEditorChange: onEditorChange
108
139
  };
109
140
  };
@@ -64,6 +64,10 @@ import { MARKDOWN_INPUT_FIELD_TEST_IDS } from "../testIds";
64
64
  fileMap: fileMap,
65
65
  onDelete: handleFileRemoval,
66
66
  onRetry: handleFileRetry,
67
+ onPreview: (attachment === null || attachment === void 0 ? void 0 : attachment.onPreview) ? function(file) {
68
+ var _attachment_onPreview;
69
+ void Promise.resolve((_attachment_onPreview = attachment.onPreview) === null || _attachment_onPreview === void 0 ? void 0 : _attachment_onPreview.call(attachment, file)).catch(function() {});
70
+ } : undefined,
67
71
  onClearFileMap: function onClearFileMap() {
68
72
  updateAttachmentFiles(undefined);
69
73
  },
@@ -71,6 +75,7 @@ import { MARKDOWN_INPUT_FIELD_TEST_IDS } from "../testIds";
71
75
  });
72
76
  }, [
73
77
  attachment === null || attachment === void 0 ? void 0 : attachment.enable,
78
+ attachment === null || attachment === void 0 ? void 0 : attachment.onPreview,
74
79
  fileMap,
75
80
  handleFileRemoval,
76
81
  handleFileRetry,
@@ -0,0 +1,24 @@
1
+ import React from 'react';
2
+ import type { MarkdownEditorProps } from '../MarkdownEditor/types';
3
+ export interface MarkdownLinkInterceptConfig {
4
+ openInNewTab?: boolean;
5
+ onClick?: (url?: string) => boolean | void;
6
+ }
7
+ /**
8
+ * 从 GFM 脚注引用 <sup><a href="#user-content-fn-x">…</a></sup> 解析标识符
9
+ */
10
+ export declare const extractFootnoteRefFromSupChildren: (children: React.ReactNode) => {
11
+ identifier: string;
12
+ url?: string;
13
+ } | undefined;
14
+ export interface FncRefForMarkdownProps {
15
+ fncProps?: MarkdownEditorProps['fncProps'];
16
+ linkConfig?: MarkdownLinkInterceptConfig;
17
+ identifier: string;
18
+ children: React.ReactNode;
19
+ url?: string;
20
+ }
21
+ /**
22
+ * 将 Markdown hast 中的脚注引用与 Slate 只读路径的 FncLeaf 对齐
23
+ */
24
+ export declare const FncRefForMarkdown: React.FC<FncRefForMarkdownProps>;
@@ -0,0 +1,65 @@
1
+ import React, { useMemo } from "react";
2
+ import { FncLeaf } from "../MarkdownEditor/editor/elements/FncLeaf";
3
+ var FOOTNOTE_HREF_ID = /user-content-fn-([^#?]+)$/i;
4
+ var extractSingleChildText = function extractSingleChildText1(node) {
5
+ if (node === null || node === undefined || node === false) return '';
6
+ if (typeof node === 'string' || typeof node === 'number') return String(node);
7
+ if (Array.isArray(node)) return node.map(extractSingleChildText).join('');
8
+ if (/*#__PURE__*/ React.isValidElement(node) && node.props !== undefined && node.props.children !== undefined && node.props.children !== null) {
9
+ return extractSingleChildText(node.props.children);
10
+ }
11
+ return '';
12
+ };
13
+ /**
14
+ * 从 GFM 脚注引用 <sup><a href="#user-content-fn-x">…</a></sup> 解析标识符
15
+ */ export var extractFootnoteRefFromSupChildren = function extractFootnoteRefFromSupChildren(children) {
16
+ var _el_props, _el_props1;
17
+ var childArray = React.Children.toArray(children);
18
+ if (childArray.length !== 1) return undefined;
19
+ var only = childArray[0];
20
+ if (!/*#__PURE__*/ React.isValidElement(only)) return undefined;
21
+ var el = only;
22
+ if (typeof el.type !== 'string' || el.type !== 'a') return undefined;
23
+ var href = (_el_props = el.props) === null || _el_props === void 0 ? void 0 : _el_props.href;
24
+ var labelText = extractSingleChildText((_el_props1 = el.props) === null || _el_props1 === void 0 ? void 0 : _el_props1.children);
25
+ if (typeof href === 'string') {
26
+ var m = FOOTNOTE_HREF_ID.exec(href);
27
+ if (m === null || m === void 0 ? void 0 : m[1]) {
28
+ return {
29
+ identifier: decodeURIComponent(m[1]),
30
+ url: href.startsWith('http') ? href : undefined
31
+ };
32
+ }
33
+ }
34
+ if (labelText) {
35
+ return {
36
+ identifier: labelText
37
+ };
38
+ }
39
+ return undefined;
40
+ };
41
+ /**
42
+ * 将 Markdown hast 中的脚注引用与 Slate 只读路径的 FncLeaf 对齐
43
+ */ export var FncRefForMarkdown = function FncRefForMarkdown(param) {
44
+ var fncProps = param.fncProps, linkConfig = param.linkConfig, identifier = param.identifier, children = param.children, url = param.url;
45
+ var leaf = useMemo(function() {
46
+ return {
47
+ fnc: true,
48
+ text: "[^".concat(identifier, "]"),
49
+ identifier: identifier,
50
+ url: url
51
+ };
52
+ }, [
53
+ identifier,
54
+ url
55
+ ]);
56
+ return /*#__PURE__*/ React.createElement(FncLeaf, {
57
+ attributes: {
58
+ 'data-slate-leaf': true
59
+ },
60
+ leaf: leaf,
61
+ text: leaf,
62
+ fncProps: fncProps,
63
+ linkConfig: linkConfig
64
+ }, children);
65
+ };
@@ -146,6 +146,7 @@ import { CodeBlockRenderer } from "./renderers/CodeRenderer";
146
146
  import { MermaidBlockRenderer } from "./renderers/MermaidRenderer";
147
147
  import { SchemaBlockRenderer } from "./renderers/SchemaRenderer";
148
148
  import { useRendererVarStyle } from "./style";
149
+ import { extractFootnoteDefinitionsFromMarkdown } from "./extractFootnoteDefinitions";
149
150
  import { useMarkdownToReact } from "./useMarkdownToReact";
150
151
  import { useStreaming } from "./useStreaming";
151
152
  var SCHEMA_LANGUAGES = new Set([
@@ -187,11 +188,12 @@ var SCHEMA_LANGUAGES = new Set([
187
188
  /**
188
189
  * 默认的代码块路由——根据语言分发到对应渲染器
189
190
  */ var DefaultCodeRouter = function DefaultCodeRouter(props) {
190
- var language = props.language, pluginComponents = props.pluginComponents, apaasifyRender = props.apaasifyRender, fileMapConfig = props.fileMapConfig, rest = _object_without_properties(props, [
191
+ var language = props.language, pluginComponents = props.pluginComponents, apaasifyRender = props.apaasifyRender, fileMapConfig = props.fileMapConfig, editorCodeProps = props.editorCodeProps, rest = _object_without_properties(props, [
191
192
  "language",
192
193
  "pluginComponents",
193
194
  "apaasifyRender",
194
- "fileMapConfig"
195
+ "fileMapConfig",
196
+ "editorCodeProps"
195
197
  ]);
196
198
  if (language === 'mermaid') {
197
199
  var MermaidComp = pluginComponents.mermaid || MermaidBlockRenderer;
@@ -228,12 +230,14 @@ var SCHEMA_LANGUAGES = new Set([
228
230
  var SchemaComp = pluginComponents.schema || SchemaBlockRenderer;
229
231
  return /*#__PURE__*/ React.createElement(SchemaComp, _object_spread_props(_object_spread({}, rest), {
230
232
  language: language,
231
- apaasifyRender: apaasifyRender
233
+ apaasifyRender: apaasifyRender,
234
+ editorCodeProps: editorCodeProps
232
235
  }));
233
236
  }
234
237
  var CodeComp = pluginComponents.code || CodeBlockRenderer;
235
238
  return /*#__PURE__*/ React.createElement(CodeComp, _object_spread_props(_object_spread({}, rest), {
236
- language: language
239
+ language: language,
240
+ editorCodeProps: editorCodeProps
237
241
  }));
238
242
  };
239
243
  /**
@@ -245,7 +249,7 @@ var SCHEMA_LANGUAGES = new Set([
245
249
  * - Markdown → hast → React 元素树(hast-util-to-jsx-runtime)
246
250
  * - 特殊块(code / mermaid / chart / katex)通过组件映射拦截渲染
247
251
  */ var InternalMarkdownRenderer = /*#__PURE__*/ forwardRef(function(props, ref) {
248
- var content = props.content, _props_streaming = props.streaming, streaming = _props_streaming === void 0 ? false : _props_streaming, isFinished = props.isFinished, queueOptions = props.queueOptions, plugins = props.plugins, remarkPlugins = props.remarkPlugins, htmlConfig = props.htmlConfig, className = props.className, style = props.style, customPrefixCls = props.prefixCls, linkConfig = props.linkConfig, streamingParagraphAnimation = props.streamingParagraphAnimation, apaasify = props.apaasify, eleRender = props.eleRender, fileMapConfig = props.fileMapConfig;
252
+ var content = props.content, _props_streaming = props.streaming, streaming = _props_streaming === void 0 ? false : _props_streaming, isFinished = props.isFinished, queueOptions = props.queueOptions, plugins = props.plugins, remarkPlugins = props.remarkPlugins, htmlConfig = props.htmlConfig, className = props.className, style = props.style, customPrefixCls = props.prefixCls, linkConfig = props.linkConfig, streamingParagraphAnimation = props.streamingParagraphAnimation, apaasify = props.apaasify, eleRender = props.eleRender, fileMapConfig = props.fileMapConfig, fncProps = props.fncProps, editorCodeProps = props.codeProps;
249
253
  var getPrefixCls = useContext(ConfigProvider.ConfigContext).getPrefixCls;
250
254
  // 复用 MarkdownEditor 的 CSS 前缀和样式,保持渲染一致性
251
255
  var prefixCls = getPrefixCls('agentic-md-editor', customPrefixCls);
@@ -333,6 +337,14 @@ var SCHEMA_LANGUAGES = new Set([
333
337
  content,
334
338
  streaming
335
339
  ]);
340
+ useEffect(function() {
341
+ var notify = fncProps === null || fncProps === void 0 ? void 0 : fncProps.onFootnoteDefinitionChange;
342
+ if (!notify) return;
343
+ notify(extractFootnoteDefinitionsFromMarkdown(displayedContent || ''));
344
+ }, [
345
+ displayedContent,
346
+ fncProps === null || fncProps === void 0 ? void 0 : fncProps.onFootnoteDefinitionChange
347
+ ]);
336
348
  // 构建组件映射
337
349
  // code 渲染器通过 pre override 在 useMarkdownToReact 中路由,
338
350
  // 不直接映射到 <code> 标签(否则会影响行内代码 `code`)
@@ -343,11 +355,12 @@ var SCHEMA_LANGUAGES = new Set([
343
355
  apaasify
344
356
  ]);
345
357
  var components = useMemo(function() {
346
- var codeRouter = function codeRouter(codeProps) {
347
- return /*#__PURE__*/ React.createElement(DefaultCodeRouter, _object_spread_props(_object_spread({}, codeProps), {
358
+ var codeRouter = function codeRouter(blockProps) {
359
+ return /*#__PURE__*/ React.createElement(DefaultCodeRouter, _object_spread_props(_object_spread({}, blockProps), {
348
360
  pluginComponents: pluginComponents,
349
361
  apaasifyRender: apaasifyRender,
350
- fileMapConfig: fileMapConfig
362
+ fileMapConfig: fileMapConfig,
363
+ editorCodeProps: editorCodeProps
351
364
  }));
352
365
  };
353
366
  codeRouter.displayName = 'CodeRouter';
@@ -357,7 +370,8 @@ var SCHEMA_LANGUAGES = new Set([
357
370
  }, [
358
371
  pluginComponents,
359
372
  apaasifyRender,
360
- fileMapConfig
373
+ fileMapConfig,
374
+ editorCodeProps
361
375
  ]);
362
376
  // 流式缓存:将不完整的 Markdown token 暂缓,避免 parser 错误解析
363
377
  var safeContent = useStreaming(displayedContent, streaming);
@@ -367,6 +381,7 @@ var SCHEMA_LANGUAGES = new Set([
367
381
  components: components,
368
382
  prefixCls: prefixCls,
369
383
  linkConfig: linkConfig,
384
+ fncProps: fncProps,
370
385
  streaming: streaming,
371
386
  streamingParagraphAnimation: streamingParagraphAnimation,
372
387
  contentRevisionSource: streaming ? displayedContent : undefined,
@@ -0,0 +1,13 @@
1
+ /** 与 `fncProps.onFootnoteDefinitionChange` 数组元素一致 */
2
+ export interface FootnoteDefinitionRow {
3
+ id: any;
4
+ placeholder: any;
5
+ origin_text: any;
6
+ url: any;
7
+ origin_url: any;
8
+ }
9
+ /**
10
+ * 从 Markdown 源码提取 GFM 脚注定义,结构与 Slate 只读 Editor 中
11
+ * `fncProps.onFootnoteDefinitionChange` 入参对齐。
12
+ */
13
+ export declare const extractFootnoteDefinitionsFromMarkdown: (content: string) => FootnoteDefinitionRow[];
@@ -0,0 +1,40 @@
1
+ import remarkGfm from "remark-gfm";
2
+ import remarkParse from "remark-parse";
3
+ import { unified } from "unified";
4
+ import { visit } from "unist-util-visit";
5
+ var mdastFootnoteProcessor = unified().use(remarkParse).use(remarkGfm, {
6
+ singleTilde: false
7
+ });
8
+ var mdastPlainText = function mdastPlainText1(node) {
9
+ if (!node) return '';
10
+ if (node.type === 'text') return node.value || '';
11
+ if (Array.isArray(node.children)) {
12
+ return node.children.map(mdastPlainText).join('');
13
+ }
14
+ return '';
15
+ };
16
+ /**
17
+ * 从 Markdown 源码提取 GFM 脚注定义,结构与 Slate 只读 Editor 中
18
+ * `fncProps.onFootnoteDefinitionChange` 入参对齐。
19
+ */ export var extractFootnoteDefinitionsFromMarkdown = function extractFootnoteDefinitionsFromMarkdown(content) {
20
+ if (!(content === null || content === void 0 ? void 0 : content.trim())) return [];
21
+ try {
22
+ var tree = mdastFootnoteProcessor.parse(content);
23
+ var list = [];
24
+ visit(tree, 'footnoteDefinition', function(node) {
25
+ var _node_label;
26
+ list.push({
27
+ id: node.identifier,
28
+ placeholder: (_node_label = node.label) !== null && _node_label !== void 0 ? _node_label : node.identifier,
29
+ origin_text: mdastPlainText({
30
+ children: node.children
31
+ }),
32
+ url: undefined,
33
+ origin_url: undefined
34
+ });
35
+ });
36
+ return list;
37
+ } catch (unused) {
38
+ return [];
39
+ }
40
+ };
@@ -1,6 +1,7 @@
1
1
  import React from 'react';
2
2
  import type { Processor } from 'unified';
3
3
  import { type MarkdownRemarkPlugin, type MarkdownToHtmlConfig } from '../MarkdownEditor/editor/utils/markdownToHtml';
4
+ import type { MarkdownEditorProps } from '../MarkdownEditor/types';
4
5
  import type { MarkdownRendererEleProps, RendererBlockProps } from './types';
5
6
  declare const createHastProcessor: (extraRemarkPlugins?: MarkdownRemarkPlugin[], config?: MarkdownToHtmlConfig) => Processor;
6
7
  /**
@@ -12,7 +13,7 @@ declare const createHastProcessor: (extraRemarkPlugins?: MarkdownRemarkPlugin[],
12
13
  declare const buildEditorAlignedComponents: (prefixCls: string, userComponents: Record<string, React.ComponentType<RendererBlockProps>>, streaming?: boolean, linkConfig?: {
13
14
  openInNewTab?: boolean | undefined;
14
15
  onClick?: ((url?: string) => boolean | void) | undefined;
15
- } | undefined, streamingParagraphAnimation?: boolean, eleRender?: ((props: MarkdownRendererEleProps, defaultDom: React.ReactNode) => React.ReactNode) | undefined) => {
16
+ } | undefined, fncProps?: MarkdownEditorProps['fncProps'], streamingParagraphAnimation?: boolean, eleRender?: ((props: MarkdownRendererEleProps, defaultDom: React.ReactNode) => React.ReactNode) | undefined) => {
16
17
  p: (props: any) => React.ReactNode;
17
18
  h1: (props: any) => React.ReactNode;
18
19
  h2: (props: any) => React.ReactNode;
@@ -77,6 +78,8 @@ export interface UseMarkdownToReactOptions {
77
78
  openInNewTab?: boolean;
78
79
  onClick?: (url?: string) => boolean | void;
79
80
  };
81
+ /** 脚注:与只读 Slate 路径 FncLeaf / fncProps 对齐 */
82
+ fncProps?: MarkdownEditorProps['fncProps'];
80
83
  /** 是否处于流式状态,用于最后一个块的打字动画 */
81
84
  streaming?: boolean;
82
85
  /**
@@ -140,6 +140,7 @@ import { REMARK_REHYPE_DIRECTIVE_HANDLERS } from "../MarkdownEditor/editor/utils
140
140
  import { parseChineseCurrencyToNumber } from "../Plugins/chart/utils";
141
141
  import { ToolUseBarThink } from "../ToolUseBarThink";
142
142
  import AnimationText from "./AnimationText";
143
+ import { FncRefForMarkdown, extractFootnoteRefFromSupChildren } from "./FncRefForMarkdown";
143
144
  import { StreamingAnimationContext } from "./StreamingAnimationContext";
144
145
  var INLINE_MATH_WITH_SINGLE_DOLLAR = {
145
146
  singleDollarTextMath: true
@@ -432,7 +433,7 @@ var extractLanguageFromClassName = function extractLanguageFromClassName(classNa
432
433
  *
433
434
  * MarkdownEditor 的 Slate 元素使用 data-be 属性和 prefixCls 类名,
434
435
  * 这里为原生 HTML 标签添加相同的属性,使共用的 CSS 能正确命中。
435
- */ var buildEditorAlignedComponents = function buildEditorAlignedComponents(prefixCls, userComponents, streaming, linkConfig, streamingParagraphAnimation, eleRender) {
436
+ */ var buildEditorAlignedComponents = function buildEditorAlignedComponents(prefixCls, userComponents, streaming, linkConfig, fncProps, streamingParagraphAnimation, eleRender) {
436
437
  var listCls = "".concat(prefixCls, "-list");
437
438
  var tableCls = "".concat(prefixCls, "-content-table");
438
439
  var contentCls = prefixCls; // e.g. ant-agentic-md-editor-content
@@ -1119,12 +1120,22 @@ var extractLanguageFromClassName = function extractLanguageFromClassName(classNa
1119
1120
  node: node
1120
1121
  }, rest), defaultDom);
1121
1122
  },
1122
- // 脚注引用 sup > a(remark-gfm 有定义时生成)
1123
+ // 脚注引用 sup > a(remark-gfm 有定义时生成)— 与 Slate FncLeaf 对齐
1123
1124
  sup: function sup(props) {
1124
1125
  var node = props.node, children = props.children, rest = _object_without_properties(props, [
1125
1126
  "node",
1126
1127
  "children"
1127
1128
  ]);
1129
+ var meta = extractFootnoteRefFromSupChildren(children);
1130
+ if (meta) {
1131
+ return jsx(FncRefForMarkdown, {
1132
+ fncProps: fncProps,
1133
+ linkConfig: linkConfig,
1134
+ identifier: meta.identifier,
1135
+ url: meta.url,
1136
+ children: children
1137
+ });
1138
+ }
1128
1139
  var defaultDom = jsx('span', _object_spread_props(_object_spread({}, rest), {
1129
1140
  'data-fnc': 'fnc',
1130
1141
  'data-testid': 'markdown-footnote-ref',
@@ -1146,15 +1157,14 @@ var extractLanguageFromClassName = function extractLanguageFromClassName(classNa
1146
1157
  "children"
1147
1158
  ]);
1148
1159
  if (rest['data-fnc'] === 'fnc') {
1149
- return jsx('span', _object_spread_props(_object_spread({}, rest), {
1150
- 'data-testid': 'markdown-footnote-ref',
1151
- className: "".concat(contentCls, "-fnc"),
1152
- style: {
1153
- fontSize: 12,
1154
- cursor: 'pointer'
1155
- },
1160
+ var raw = rest['data-fnc-name'];
1161
+ var identifier = raw !== undefined && raw !== null && String(raw).length > 0 ? String(raw) : extractChildrenText(children) || '?';
1162
+ return jsx(FncRefForMarkdown, {
1163
+ fncProps: fncProps,
1164
+ linkConfig: linkConfig,
1165
+ identifier: identifier,
1156
1166
  children: children
1157
- }));
1167
+ });
1158
1168
  }
1159
1169
  return jsx('span', _object_spread_props(_object_spread({}, rest), {
1160
1170
  children: children
@@ -1,7 +1,10 @@
1
1
  import React from 'react';
2
+ import type { MarkdownEditorProps } from '../../MarkdownEditor/types';
2
3
  import type { RendererBlockProps } from '../types';
3
4
  /**
4
5
  * 代码块渲染器——复用 MarkdownEditor 的 CodeContainer 和样式体系。
5
6
  * 不依赖 Slate 上下文,提供与 CodeRenderer readonly 模式一致的视觉效果。
6
7
  */
7
- export declare const CodeBlockRenderer: React.FC<RendererBlockProps>;
8
+ export declare const CodeBlockRenderer: React.FC<RendererBlockProps & {
9
+ editorCodeProps?: MarkdownEditorProps['codeProps'];
10
+ }>;
@@ -52,6 +52,7 @@ import { I18nContext } from "../../I18n";
52
52
  import { CodeContainer } from "../../Plugins/code/components/CodeContainer";
53
53
  import { LoadImage } from "../../Plugins/code/components/LoadImage";
54
54
  import { langIconMap } from "../../Plugins/code/langIconMap";
55
+ import { debugInfo } from "../../Utils/debugUtils";
55
56
  var extractTextContent = function extractTextContent1(children) {
56
57
  var _children_props;
57
58
  if (typeof children === 'string') return children;
@@ -67,8 +68,10 @@ var extractTextContent = function extractTextContent1(children) {
67
68
  * 不依赖 Slate 上下文,提供与 CodeRenderer readonly 模式一致的视觉效果。
68
69
  */ export var CodeBlockRenderer = function CodeBlockRenderer(props) {
69
70
  var _i18n_locale, _i18n_locale1, _i18n_locale2;
70
- var language = props.language, children = props.children;
71
- var _useState = _sliced_to_array(useState('github'), 2), theme = _useState[0], setTheme = _useState[1];
71
+ var language = props.language, children = props.children, editorCodeProps = props.editorCodeProps;
72
+ var _useState = _sliced_to_array(useState(function() {
73
+ return (editorCodeProps === null || editorCodeProps === void 0 ? void 0 : editorCodeProps.theme) || 'github';
74
+ }), 2), theme = _useState[0], setTheme = _useState[1];
72
75
  var _useState1 = _sliced_to_array(useState(true), 2), isExpanded = _useState1[0], setIsExpanded = _useState1[1];
73
76
  var i18n = useContext(I18nContext);
74
77
  var code = useMemo(function() {
@@ -101,7 +104,7 @@ var extractTextContent = function extractTextContent1(children) {
101
104
  code
102
105
  ]);
103
106
  var langIcon = langIconMap.get((language === null || language === void 0 ? void 0 : language.toLowerCase()) || '');
104
- return /*#__PURE__*/ React.createElement(CodeContainer, {
107
+ var defaultDom = /*#__PURE__*/ React.createElement(CodeContainer, {
105
108
  element: fakeElement,
106
109
  showBorder: false,
107
110
  hide: false,
@@ -214,5 +217,26 @@ var extractTextContent = function extractTextContent1(children) {
214
217
  }, /*#__PURE__*/ React.createElement("code", {
215
218
  className: language ? "language-".concat(language) : undefined
216
219
  }, children))));
220
+ var customRender = editorCodeProps === null || editorCodeProps === void 0 ? void 0 : editorCodeProps.render;
221
+ if (!customRender) {
222
+ return defaultDom;
223
+ }
224
+ try {
225
+ var renderElementProps = {
226
+ attributes: {},
227
+ children: null,
228
+ element: fakeElement
229
+ };
230
+ var rendered = customRender(renderElementProps, defaultDom, editorCodeProps);
231
+ if (rendered === undefined) {
232
+ return defaultDom;
233
+ }
234
+ return rendered;
235
+ } catch (error) {
236
+ debugInfo('CodeBlockRenderer - codeProps.render 异常,回退默认', {
237
+ error: (error === null || error === void 0 ? void 0 : error.message) || String(error)
238
+ });
239
+ return defaultDom;
240
+ }
217
241
  };
218
242
  CodeBlockRenderer.displayName = 'CodeBlockRenderer';
@@ -1,4 +1,5 @@
1
1
  import React from 'react';
2
+ import type { MarkdownEditorProps } from '../../MarkdownEditor/types';
2
3
  import type { RendererBlockProps } from '../types';
3
4
  /**
4
5
  * Schema / Apaasify 渲染器
@@ -12,4 +13,5 @@ import type { RendererBlockProps } from '../types';
12
13
  */
13
14
  export declare const SchemaBlockRenderer: React.FC<RendererBlockProps & {
14
15
  apaasifyRender?: (value: any) => React.ReactNode;
16
+ editorCodeProps?: MarkdownEditorProps['codeProps'];
15
17
  }>;