@ant-design/agentic-ui 2.21.0 → 2.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. package/dist/MarkdownEditor/editor/elements/TagPopup/index.js +4 -4
  2. package/dist/MarkdownEditor/editor/elements/TagPopup/style.js +14 -12
  3. package/dist/MarkdownEditor/editor/parser/parse/applyContextPropsAndConfig.d.ts +8 -0
  4. package/dist/MarkdownEditor/editor/parser/parse/applyContextPropsAndConfig.js +58 -0
  5. package/dist/MarkdownEditor/editor/parser/parse/parseBlockElements.d.ts +67 -0
  6. package/dist/MarkdownEditor/editor/parser/parse/parseBlockElements.js +289 -0
  7. package/dist/MarkdownEditor/editor/parser/parse/parseElements.d.ts +27 -0
  8. package/dist/MarkdownEditor/editor/parser/parse/parseElements.js +83 -0
  9. package/dist/MarkdownEditor/editor/parser/parse/parseEmptyLines.d.ts +9 -0
  10. package/dist/MarkdownEditor/editor/parser/parse/parseEmptyLines.js +60 -0
  11. package/dist/MarkdownEditor/editor/parser/parse/parseFootnote.d.ts +10 -0
  12. package/dist/MarkdownEditor/editor/parser/parse/parseFootnote.js +12 -0
  13. package/dist/MarkdownEditor/editor/parser/parse/parseHtml.d.ts +63 -0
  14. package/dist/MarkdownEditor/editor/parser/parse/parseHtml.js +759 -0
  15. package/dist/MarkdownEditor/editor/parser/parse/parseMath.d.ts +24 -0
  16. package/dist/MarkdownEditor/editor/parser/parse/parseMath.js +58 -0
  17. package/dist/MarkdownEditor/editor/parser/parse/parseMedia.d.ts +27 -0
  18. package/dist/MarkdownEditor/editor/parser/parse/parseMedia.js +127 -0
  19. package/dist/MarkdownEditor/editor/parser/parse/parseTable.js +36 -3
  20. package/dist/MarkdownEditor/editor/parser/parse/parseText.d.ts +26 -0
  21. package/dist/MarkdownEditor/editor/parser/parse/parseText.js +304 -0
  22. package/dist/MarkdownEditor/editor/parser/parserMarkdownToSlateNode.d.ts +3 -40
  23. package/dist/MarkdownEditor/editor/parser/parserMarkdownToSlateNode.js +128 -1855
  24. package/dist/MarkdownEditor/editor/parser/parserSlateNodeToMarkdown.js +131 -18
  25. package/dist/MarkdownEditor/editor/parser/remarkParse.js +24 -17
  26. package/dist/MarkdownEditor/editor/plugins/elements.js +1 -1
  27. package/dist/Plugins/code/components/CodeToolbar.js +3 -16
  28. package/package.json +1 -1
@@ -360,16 +360,103 @@ var inlineNode = new Set([
360
360
  // 检查 configProps 是否为空对象(删除 finished 后可能变成空对象)
361
361
  var hasValidProps = Object.keys(configProps).length > 0;
362
362
  if (hasValidProps) {
363
- var nodeConfig = node.type === 'chart' && configProps.config ? configProps.config : configProps;
364
- // 过滤掉 undefined 值,但保留 false
365
- var propsToSerialize = Object.keys(nodeConfig).reduce(function(acc, key) {
366
- if (nodeConfig[key] !== undefined) {
367
- acc[key] = nodeConfig[key];
363
+ /**
364
+ * 将对象转换为数组(处理 {0: {...}, 1: {...}} 这种错误格式)
365
+ * @param obj - 要转换的对象
366
+ * @returns 转换后的数组,如果不是数字键对象则返回原对象
367
+ */ var convertObjectToArray = function(obj) {
368
+ if (!obj || (typeof obj === "undefined" ? "undefined" : _type_of(obj)) !== 'object' || Array.isArray(obj)) {
369
+ return obj;
370
+ }
371
+ var keys = Object.keys(obj);
372
+ // 检查是否所有键都是数字字符串(如 "0", "1", "2")
373
+ var allNumericKeys = keys.length > 0 && keys.every(function(key) {
374
+ return /^\d+$/.test(key);
375
+ });
376
+ if (allNumericKeys) {
377
+ // 按数字顺序排序并转换为数组
378
+ var sortedKeys = keys.sort(function(a, b) {
379
+ return parseInt(a, 10) - parseInt(b, 10);
380
+ });
381
+ return sortedKeys.map(function(key) {
382
+ return obj[key];
383
+ });
384
+ }
385
+ return obj;
386
+ };
387
+ // 对于图表类型,配置应该总是以数组形式存储在 config 中
388
+ if (node.type === 'chart') {
389
+ var chartConfig = configProps.config;
390
+ // 如果 config 不存在,但 configProps 看起来像图表配置(有 chartType),使用 configProps
391
+ if (!chartConfig && configProps.chartType) {
392
+ chartConfig = configProps;
393
+ }
394
+ // 如果 chartConfig 是对象且键都是数字(如 {0: {...}}),转换为数组
395
+ chartConfig = convertObjectToArray(chartConfig);
396
+ // 如果 chartConfig 还不是数组,将其包装为数组
397
+ // 这样可以确保即使只有一个配置项,也会被放入数组中
398
+ if (!Array.isArray(chartConfig)) {
399
+ // 如果 chartConfig 是对象,检查是否是 {0: {...}} 格式但转换失败的情况
400
+ if (chartConfig && (typeof chartConfig === "undefined" ? "undefined" : _type_of(chartConfig)) === 'object') {
401
+ var keys = Object.keys(chartConfig);
402
+ // 如果只有一个键且是数字,提取该值
403
+ if (keys.length === 1 && /^\d+$/.test(keys[0])) {
404
+ chartConfig = [
405
+ chartConfig[keys[0]]
406
+ ];
407
+ } else if (chartConfig.chartType) {
408
+ // 如果 chartConfig 有 chartType,说明是单个配置对象
409
+ chartConfig = [
410
+ chartConfig
411
+ ];
412
+ } else {
413
+ // 其他情况,也包装为数组
414
+ chartConfig = [
415
+ chartConfig
416
+ ];
417
+ }
418
+ } else if (chartConfig) {
419
+ chartConfig = [
420
+ chartConfig
421
+ ];
422
+ } else {
423
+ chartConfig = [];
424
+ }
425
+ }
426
+ // 序列化为 { config: [...] } 格式
427
+ if (chartConfig.length > 0) {
428
+ str += "<!--".concat(JSON.stringify({
429
+ config: chartConfig
430
+ }), "-->\n");
431
+ }
432
+ } else {
433
+ // 非图表类型,使用原有逻辑
434
+ var nodeConfig = configProps;
435
+ // 如果 nodeConfig 是对象且键都是数字(如 {0: {...}}),转换为数组
436
+ nodeConfig = convertObjectToArray(nodeConfig);
437
+ var propsToSerialize = void 0;
438
+ // 如果 nodeConfig 是数组,直接使用数组
439
+ if (Array.isArray(nodeConfig)) {
440
+ propsToSerialize = nodeConfig;
441
+ } else {
442
+ // 如果是对象,过滤掉 undefined 值,但保留 false 值
443
+ propsToSerialize = Object.keys(nodeConfig).reduce(function(acc, key) {
444
+ if (nodeConfig[key] !== undefined) {
445
+ acc[key] = nodeConfig[key];
446
+ }
447
+ return acc;
448
+ }, {});
449
+ }
450
+ // 对于数组,直接序列化;对于对象,检查是否为空
451
+ if (Array.isArray(propsToSerialize)) {
452
+ if (propsToSerialize.length > 0) {
453
+ str += "<!--".concat(JSON.stringify({
454
+ config: propsToSerialize
455
+ }), "-->\n");
456
+ }
457
+ } else if (propsToSerialize && (typeof propsToSerialize === "undefined" ? "undefined" : _type_of(propsToSerialize)) === 'object' && Object.keys(propsToSerialize).length > 0) {
458
+ str += "<!--".concat(JSON.stringify(propsToSerialize), "-->\n");
368
459
  }
369
- return acc;
370
- }, {});
371
- if (propsToSerialize && (typeof propsToSerialize === "undefined" ? "undefined" : _type_of(propsToSerialize)) === 'object' && !Array.isArray(propsToSerialize) && Object.keys(propsToSerialize).length > 0) {
372
- str += "<!--".concat(JSON.stringify(propsToSerialize), "-->\n");
373
460
  }
374
461
  }
375
462
  }
@@ -561,25 +648,51 @@ export var isMix = function(t) {
561
648
  if (!t.text && !t.tag) return '';
562
649
  var str = (t === null || t === void 0 ? void 0 : (_t_text = t.text) === null || _t_text === void 0 ? void 0 : _t_text.replace(RegExp("(?<!\\\\)\\\\", "g"), '\\').replace(/\n/g, ' \n')) || '';
563
650
  var preStr = '', afterStr = '';
564
- // Extract whitespace
565
- if (t.code || t.bold || t.strikethrough || t.italic) {
566
- var _str_match, _str_match1;
567
- preStr = ((_str_match = str.match(/^\s+/)) === null || _str_match === void 0 ? void 0 : _str_match[0]) || '';
568
- afterStr = ((_str_match1 = str.match(/\s+$/)) === null || _str_match1 === void 0 ? void 0 : _str_match1[0]) || '';
569
- str = str.trim();
570
- }
571
651
  // Apply formats in a consistent order:
572
652
  // 1. Code (most specific)
573
653
  // 2. Bold (strong emphasis)
574
654
  // 3. Italic (emphasis)
575
655
  // 4. Strikethrough (modification)
576
656
  if (t.code && !t.tag) {
657
+ // Extract whitespace for non-tag code
658
+ if (t.code || t.bold || t.strikethrough || t.italic) {
659
+ var _str_match, _str_match1;
660
+ preStr = ((_str_match = str.match(/^\s+/)) === null || _str_match === void 0 ? void 0 : _str_match[0]) || '';
661
+ afterStr = ((_str_match1 = str.match(/\s+$/)) === null || _str_match1 === void 0 ? void 0 : _str_match1[0]) || '';
662
+ str = str.trim();
663
+ }
577
664
  str = "`".concat(str, "`");
578
665
  } else if (t.tag) {
666
+ // 如果是 tag,优先检查是否有 value,如果有 value 则使用 value 和 placeholder
667
+ // 如果没有 value 但有 text(且不为空),则使用 text
668
+ // 如果没有 text 也没有 value,则使用 placeholder
669
+ // 对于 tag,如果 text 只是空白字符,不保留空白字符
670
+ var trimmedStr = str.trim();
579
671
  if (t.value) {
580
- str = "`".concat("${placeholder:".concat((t === null || t === void 0 ? void 0 : t.placeholder) || '-', ",value:").concat(t.value, "}") || '', "`");
672
+ // value,优先使用 value placeholder(即使有 text 也使用 value
673
+ str = "`${placeholder:".concat((t === null || t === void 0 ? void 0 : t.placeholder) || '-', ",value:").concat(t.value, "}`");
674
+ } else if (trimmedStr) {
675
+ // 没有 value 但有 text 且不为空,提取空白字符并使用 text
676
+ if (t.code || t.bold || t.strikethrough || t.italic) {
677
+ var _str_match2, _str_match3;
678
+ preStr = ((_str_match2 = str.match(/^\s+/)) === null || _str_match2 === void 0 ? void 0 : _str_match2[0]) || '';
679
+ afterStr = ((_str_match3 = str.match(/\s+$/)) === null || _str_match3 === void 0 ? void 0 : _str_match3[0]) || '';
680
+ }
681
+ str = "`".concat(trimmedStr, "`");
682
+ } else if (t.placeholder) {
683
+ // 没有 text 也没有 value,使用 placeholder(不保留空白字符)
684
+ str = "`${placeholder:".concat(t.placeholder, "}`");
581
685
  } else {
582
- str = "`".concat(str || "${placeholder:".concat((t === null || t === void 0 ? void 0 : t.placeholder) || '-', "}") || '', "`");
686
+ // 都没有,使用默认值(不保留空白字符)
687
+ str = "`${placeholder:-}`";
688
+ }
689
+ } else {
690
+ // Extract whitespace for other formats
691
+ if (t.bold || t.strikethrough || t.italic) {
692
+ var _str_match4, _str_match5;
693
+ preStr = ((_str_match4 = str.match(/^\s+/)) === null || _str_match4 === void 0 ? void 0 : _str_match4[0]) || '';
694
+ afterStr = ((_str_match5 = str.match(/\s+$/)) === null || _str_match5 === void 0 ? void 0 : _str_match5[0]) || '';
695
+ str = str.trim();
583
696
  }
584
697
  }
585
698
  // For mixed formats, we want to ensure proper nesting
@@ -63,12 +63,14 @@ import { visit } from "unist-util-visit";
63
63
  return function(tree) {
64
64
  // 使用 visit 访问 paragraph 节点,并通过 index 和 parent 来替换
65
65
  visit(tree, 'paragraph', function(paragraphNode, index, parent) {
66
+ var _parent_children;
66
67
  var textContent = extractParagraphText(paragraphNode);
67
- if (!textContent) {
68
+ if (!textContent || !index || !parent) {
68
69
  return;
69
70
  }
71
+ var nextNode = parent === null || parent === void 0 ? void 0 : (_parent_children = parent.children) === null || _parent_children === void 0 ? void 0 : _parent_children[index + 1];
70
72
  // 检查是否以 ! 开头(图片)
71
- if (textContent.startsWith('!')) {
73
+ if (textContent.startsWith('!') && !nextNode) {
72
74
  // 提取 URL(去掉开头的 !)
73
75
  var imageUrl = textContent.slice(1).trim();
74
76
  // 如果 URL 不为空,则创建 image 节点并替换
@@ -87,8 +89,11 @@ import { visit } from "unist-util-visit";
87
89
  return;
88
90
  }
89
91
  // 检查是否以 | 开头(表格)
90
- if (textContent.startsWith('|')) {
91
- // 创建不完整的表格节点
92
+ // 注意:如果 remark-gfm 已经正确解析了表格,表格节点应该是 'table' 类型,不会进入这里
93
+ // 这里只处理未被解析的表格行(通常是不完整的表格输入)
94
+ if (textContent.startsWith('|') && !nextNode) {
95
+ // 只有不完整的表格输入(比如只有 | 开头,没有结束)才转换为表格节点
96
+ // 创建不完整的表格节点(用于不完整的表格输入)
92
97
  var tableNode = {
93
98
  type: 'table',
94
99
  finished: false,
@@ -121,21 +126,23 @@ import { visit } from "unist-util-visit";
121
126
  }
122
127
  return;
123
128
  }
124
- // 检查是否以 [ 开头(链接)
125
- if (textContent.startsWith('[')) {
126
- // 创建不完整的链接节点
127
- var linkNode = {
128
- type: 'link',
129
- url: '',
130
- finished: false,
131
- children: paragraphNode.children
132
- };
133
- // 替换父节点中的 paragraph 节点为 link 节点
134
- if (parent && Array.isArray(parent.children) && typeof index === 'number') {
135
- parent.children[index] = linkNode;
129
+ if (textContent.startsWith('[') && !nextNode) {
130
+ // 检查是否匹配 [内容](url) 格式
131
+ var linkPattern = /^\[([^\]]+)\]\(([^)]+)\)$/;
132
+ var match = textContent.match(linkPattern);
133
+ if (match) {
134
+ var linkNode = {
135
+ type: 'link',
136
+ url: match[2],
137
+ finished: false,
138
+ children: paragraphNode.children
139
+ };
140
+ if (parent && Array.isArray(parent.children) && typeof index === 'number') {
141
+ parent.children[index] = linkNode;
142
+ }
136
143
  }
137
- return;
138
144
  }
145
+ return;
139
146
  });
140
147
  };
141
148
  }
@@ -24,7 +24,7 @@ function _unsupported_iterable_to_array(o, minLen) {
24
24
  if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
25
25
  }
26
26
  import { Editor, Node, Path, Point, Range, Transforms } from "slate";
27
- import { decodeURIComponentUrl } from "../parser/parserMarkdownToSlateNode";
27
+ import { decodeURIComponentUrl } from "../parser/parse/parseHtml";
28
28
  import { EditorUtils } from "../utils/editorUtils";
29
29
  export var insertAfter = function(editor, path) {
30
30
  var node = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : {
@@ -6,9 +6,8 @@
6
6
  import { ChevronsUpDown, Copy, Moon } from "@sofa-design/icons";
7
7
  import { message, Segmented } from "antd";
8
8
  import copy from "copy-to-clipboard";
9
- import React, { useContext, useMemo } from "react";
9
+ import React, { useContext } from "react";
10
10
  import { ActionIconBox } from "../../../Components/ActionIconBox";
11
- import { Loading } from "../../../Components/Loading";
12
11
  import { I18nContext } from "../../../I18n";
13
12
  import { langIconMap } from "../langIconMap";
14
13
  import { LanguageSelector } from "./LanguageSelector";
@@ -41,17 +40,10 @@ import { LoadImage } from "./LoadImage";
41
40
  * />
42
41
  * ```
43
42
  */ export var CodeToolbar = function(props) {
44
- var _element_otherProps, _element_language, _element_language1, _i18n_locale, _i18n_locale1;
43
+ var _element_language, _element_language1, _i18n_locale, _i18n_locale1;
45
44
  // 获取国际化上下文
46
45
  var i18n = useContext(I18nContext);
47
46
  var element = props.element, readonly = props.readonly, onCloseClick = props.onCloseClick, languageSelectorProps = props.languageSelectorProps, onViewModeToggle = props.onViewModeToggle, theme = props.theme, isExpanded = props.isExpanded, onExpandToggle = props.onExpandToggle, setTheme = props.setTheme, _props_viewMode = props.viewMode, viewMode = _props_viewMode === void 0 ? 'code' : _props_viewMode;
48
- // 检查代码块是否未闭合 - 使用 useMemo 确保正确响应变化
49
- var isUnclosed = useMemo(function() {
50
- var _element_otherProps;
51
- return (element === null || element === void 0 ? void 0 : (_element_otherProps = element.otherProps) === null || _element_otherProps === void 0 ? void 0 : _element_otherProps.finished) === false;
52
- }, [
53
- element === null || element === void 0 ? void 0 : (_element_otherProps = element.otherProps) === null || _element_otherProps === void 0 ? void 0 : _element_otherProps.finished
54
- ]);
55
47
  return /*#__PURE__*/ React.createElement("div", {
56
48
  "data-testid": "code-toolbar",
57
49
  contentEditable: false,
@@ -112,12 +104,7 @@ import { LoadImage } from "./LoadImage";
112
104
  },
113
105
  src: langIconMap.get(((_element_language1 = element.language) === null || _element_language1 === void 0 ? void 0 : _element_language1.toLowerCase()) || '')
114
106
  })), /*#__PURE__*/ React.createElement("div", null, element.language ? /*#__PURE__*/ React.createElement("span", null, element.katex ? 'Formula' : element.language === 'html' && element.render ? 'Html Renderer' : element.language) : /*#__PURE__*/ React.createElement("span", null, 'plain text'))) : // 非只读模式:显示语言选择器
115
- /*#__PURE__*/ React.createElement(LanguageSelector, languageSelectorProps), isUnclosed && /*#__PURE__*/ React.createElement(Loading, {
116
- style: {
117
- fontSize: '14px',
118
- flexShrink: 0
119
- }
120
- })), /*#__PURE__*/ React.createElement("div", {
107
+ /*#__PURE__*/ React.createElement(LanguageSelector, languageSelectorProps)), /*#__PURE__*/ React.createElement("div", {
121
108
  style: {
122
109
  display: 'flex',
123
110
  gap: 5,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ant-design/agentic-ui",
3
- "version": "2.21.0",
3
+ "version": "2.22.0",
4
4
  "description": "面向智能体的 UI 组件库,提供多步推理可视化、工具调用展示、任务执行协同等 Agentic UI 能力",
5
5
  "repository": "git@github.com:ant-design/agentic-ui.git",
6
6
  "license": "MIT",