@ant-design/agentic-ui 2.16.0 → 2.17.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 (56) hide show
  1. package/dist/MarkdownEditor/editor/elements/Code.js +11 -6
  2. package/dist/MarkdownEditor/editor/elements/Image/index.js +17 -5
  3. package/dist/MarkdownEditor/editor/elements/Media.js +61 -9
  4. package/dist/MarkdownEditor/editor/elements/Table/ReadonlyTableComponent.js +15 -3
  5. package/dist/MarkdownEditor/editor/elements/Table/SimpleTable.js +17 -2
  6. package/dist/MarkdownEditor/editor/elements/Table/Table.js +131 -5
  7. package/dist/MarkdownEditor/editor/parser/parserMarkdownToSlateNode.d.ts +100 -1
  8. package/dist/MarkdownEditor/editor/parser/parserMarkdownToSlateNode.js +945 -284
  9. package/dist/MarkdownEditor/editor/style.js +5 -0
  10. package/dist/MarkdownEditor/editor/types/Table.d.ts +1 -0
  11. package/dist/MarkdownEditor/editor/utils/findMatchingClose.d.ts +36 -0
  12. package/dist/MarkdownEditor/editor/utils/findMatchingClose.js +158 -0
  13. package/dist/MarkdownEditor/editor/utils/markdownToHtml.d.ts +41 -2
  14. package/dist/MarkdownEditor/editor/utils/markdownToHtml.js +159 -7
  15. package/dist/Plugins/chart/AreaChart/index.d.ts +12 -0
  16. package/dist/Plugins/chart/AreaChart/index.js +14 -188
  17. package/dist/Plugins/chart/BarChart/index.d.ts +2 -0
  18. package/dist/Plugins/chart/BarChart/index.js +3 -12
  19. package/dist/Plugins/chart/ChartMark/Container.js +5 -2
  20. package/dist/Plugins/chart/ChartRender.d.ts +1 -0
  21. package/dist/Plugins/chart/ChartRender.js +104 -43
  22. package/dist/Plugins/chart/DonutChart/index.js +4 -2
  23. package/dist/Plugins/chart/DonutChart/types.d.ts +2 -0
  24. package/dist/Plugins/chart/FunnelChart/index.d.ts +2 -0
  25. package/dist/Plugins/chart/FunnelChart/index.js +4 -2
  26. package/dist/Plugins/chart/LineChart/index.d.ts +2 -0
  27. package/dist/Plugins/chart/LineChart/index.js +17 -162
  28. package/dist/Plugins/chart/RadarChart/index.d.ts +2 -0
  29. package/dist/Plugins/chart/RadarChart/index.js +8 -4
  30. package/dist/Plugins/chart/ScatterChart/index.d.ts +2 -0
  31. package/dist/Plugins/chart/ScatterChart/index.js +8 -4
  32. package/dist/Plugins/chart/components/ChartContainer/ChartContainer.d.ts +1 -0
  33. package/dist/Plugins/chart/components/ChartFilter/ChartFilter.d.ts +1 -1
  34. package/dist/Plugins/chart/components/ChartFilter/ChartFilter.js +210 -16
  35. package/dist/Plugins/chart/components/ChartToolBar/ChartToolBar.d.ts +2 -0
  36. package/dist/Plugins/chart/components/ChartToolBar/ChartToolBar.js +9 -2
  37. package/dist/Plugins/chart/components/ChartToolBar/style.js +3 -1
  38. package/dist/Plugins/chart/hooks/index.d.ts +10 -0
  39. package/dist/Plugins/chart/hooks/index.js +8 -0
  40. package/dist/Plugins/chart/hooks/useChartDataFilter.d.ts +46 -0
  41. package/dist/Plugins/chart/hooks/useChartDataFilter.js +182 -0
  42. package/dist/Plugins/chart/hooks/useChartStatistics.d.ts +17 -0
  43. package/dist/Plugins/chart/hooks/useChartStatistics.js +25 -0
  44. package/dist/Plugins/chart/hooks/useChartTheme.d.ts +20 -0
  45. package/dist/Plugins/chart/hooks/useChartTheme.js +30 -0
  46. package/dist/Plugins/chart/hooks/useResponsiveSize.d.ts +23 -0
  47. package/dist/Plugins/chart/hooks/useResponsiveSize.js +94 -0
  48. package/dist/Plugins/chart/index.js +92 -8
  49. package/dist/Plugins/chart/utils/registerChart.d.ts +35 -0
  50. package/dist/Plugins/chart/utils/registerChart.js +54 -0
  51. package/dist/Plugins/chart/utils.d.ts +19 -0
  52. package/dist/Plugins/chart/utils.js +27 -0
  53. package/dist/Plugins/code/components/CodeRenderer.js +53 -2
  54. package/dist/Plugins/code/components/CodeToolbar.js +22 -3
  55. package/dist/Plugins/mermaid/Mermaid.js +66 -66
  56. package/package.json +1 -1
@@ -0,0 +1,35 @@
1
+ /**
2
+ * 注册 Chart.js 基础组件
3
+ *
4
+ * 用于注册图表所需的基础 Chart.js 组件,包括坐标轴、图例、工具提示等。
5
+ * 使用单例模式确保只注册一次。
6
+ *
7
+ * @param {string[]} components - 要注册的组件名称数组
8
+ * @param {Function} registerFn - 注册函数,接收 ChartJS 作为参数
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * registerChartComponents('line-chart', () => {
13
+ * ChartJS.register(
14
+ * CategoryScale,
15
+ * LinearScale,
16
+ * PointElement,
17
+ * LineElement,
18
+ * Filler,
19
+ * Tooltip,
20
+ * Legend,
21
+ * );
22
+ * });
23
+ * ```
24
+ *
25
+ * @since 1.0.0
26
+ */
27
+ export declare const registerChartComponents: (componentName: string, registerFn: () => void) => void;
28
+ /**
29
+ * 注册折线图/面积图所需的组件
30
+ */
31
+ export declare const registerLineChartComponents: () => void;
32
+ /**
33
+ * 注册柱状图所需的组件
34
+ */
35
+ export declare const registerBarChartComponents: () => void;
@@ -0,0 +1,54 @@
1
+ import { BarElement, CategoryScale, Chart as ChartJS, Filler, Legend, LinearScale, LineElement, PointElement, Tooltip } from "chart.js";
2
+ /**
3
+ * Chart.js 组件注册状态映射
4
+ * 用于跟踪哪些 Chart.js 组件已经被注册,避免重复注册
5
+ */ var registeredComponents = new Set();
6
+ /**
7
+ * 注册 Chart.js 基础组件
8
+ *
9
+ * 用于注册图表所需的基础 Chart.js 组件,包括坐标轴、图例、工具提示等。
10
+ * 使用单例模式确保只注册一次。
11
+ *
12
+ * @param {string[]} components - 要注册的组件名称数组
13
+ * @param {Function} registerFn - 注册函数,接收 ChartJS 作为参数
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * registerChartComponents('line-chart', () => {
18
+ * ChartJS.register(
19
+ * CategoryScale,
20
+ * LinearScale,
21
+ * PointElement,
22
+ * LineElement,
23
+ * Filler,
24
+ * Tooltip,
25
+ * Legend,
26
+ * );
27
+ * });
28
+ * ```
29
+ *
30
+ * @since 1.0.0
31
+ */ export var registerChartComponents = function(componentName, registerFn) {
32
+ if (registeredComponents.has(componentName)) {
33
+ return;
34
+ }
35
+ if (typeof window === 'undefined') {
36
+ return;
37
+ }
38
+ registerFn();
39
+ registeredComponents.add(componentName);
40
+ };
41
+ /**
42
+ * 注册折线图/面积图所需的组件
43
+ */ export var registerLineChartComponents = function() {
44
+ registerChartComponents('line-chart', function() {
45
+ ChartJS.register(CategoryScale, LinearScale, PointElement, LineElement, Filler, Tooltip, Legend);
46
+ });
47
+ };
48
+ /**
49
+ * 注册柱状图所需的组件
50
+ */ export var registerBarChartComponents = function() {
51
+ registerChartComponents('bar-chart', function() {
52
+ ChartJS.register(CategoryScale, LinearScale, BarElement, Tooltip, Legend);
53
+ });
54
+ };
@@ -286,3 +286,22 @@ export declare const getDataHash: (data: any[]) => string;
286
286
  * @since 1.0.0
287
287
  */
288
288
  export declare const isConfigEqual: (config1: any, config2: any) => boolean;
289
+ /**
290
+ * 将十六进制颜色转换为带透明度的 RGBA 字符串
291
+ *
292
+ * 支持3位和6位十六进制颜色格式,并添加透明度。
293
+ *
294
+ * @param {string} hex - 十六进制颜色值(如 '#ff0000' 或 '#f00')
295
+ * @param {number} alpha - 透明度值(0-1之间)
296
+ * @returns {string} RGBA 颜色字符串
297
+ *
298
+ * @example
299
+ * ```typescript
300
+ * hexToRgba('#ff0000', 0.5); // 'rgba(255, 0, 0, 0.5)'
301
+ * hexToRgba('#f00', 0.8); // 'rgba(255, 0, 0, 0.8)'
302
+ * ```
303
+ *
304
+ * @since 1.0.0
305
+ */
306
+ export declare const hexToRgba: (hex: string, alpha: number) => string;
307
+ export { registerChartComponents, registerLineChartComponents, registerBarChartComponents, } from './utils/registerChart';
@@ -436,3 +436,30 @@ var intl = new Intl.NumberFormat('en-US', {
436
436
  }
437
437
  return true;
438
438
  };
439
+ /**
440
+ * 将十六进制颜色转换为带透明度的 RGBA 字符串
441
+ *
442
+ * 支持3位和6位十六进制颜色格式,并添加透明度。
443
+ *
444
+ * @param {string} hex - 十六进制颜色值(如 '#ff0000' 或 '#f00')
445
+ * @param {number} alpha - 透明度值(0-1之间)
446
+ * @returns {string} RGBA 颜色字符串
447
+ *
448
+ * @example
449
+ * ```typescript
450
+ * hexToRgba('#ff0000', 0.5); // 'rgba(255, 0, 0, 0.5)'
451
+ * hexToRgba('#f00', 0.8); // 'rgba(255, 0, 0, 0.8)'
452
+ * ```
453
+ *
454
+ * @since 1.0.0
455
+ */ export var hexToRgba = function(hex, alpha) {
456
+ var sanitized = hex.replace('#', '');
457
+ var isShort = sanitized.length === 3;
458
+ var r = parseInt(isShort ? sanitized[0] + sanitized[0] : sanitized.slice(0, 2), 16);
459
+ var g = parseInt(isShort ? sanitized[1] + sanitized[1] : sanitized.slice(2, 4), 16);
460
+ var b = parseInt(isShort ? sanitized[2] + sanitized[2] : sanitized.slice(4, 6), 16);
461
+ var a = Math.max(0, Math.min(1, alpha));
462
+ return "rgba(".concat(r, ", ").concat(g, ", ").concat(b, ", ").concat(a, ")");
463
+ };
464
+ // 导出 Chart.js 注册相关函数
465
+ export { registerChartComponents, registerLineChartComponents, registerBarChartComponents } from "./utils/registerChart";
@@ -64,6 +64,30 @@ function _object_spread(target) {
64
64
  }
65
65
  return target;
66
66
  }
67
+ function ownKeys(object, enumerableOnly) {
68
+ var keys = Object.keys(object);
69
+ if (Object.getOwnPropertySymbols) {
70
+ var symbols = Object.getOwnPropertySymbols(object);
71
+ if (enumerableOnly) {
72
+ symbols = symbols.filter(function(sym) {
73
+ return Object.getOwnPropertyDescriptor(object, sym).enumerable;
74
+ });
75
+ }
76
+ keys.push.apply(keys, symbols);
77
+ }
78
+ return keys;
79
+ }
80
+ function _object_spread_props(target, source) {
81
+ source = source != null ? source : {};
82
+ if (Object.getOwnPropertyDescriptors) {
83
+ Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
84
+ } else {
85
+ ownKeys(Object(source)).forEach(function(key) {
86
+ Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
87
+ });
88
+ }
89
+ return target;
90
+ }
67
91
  function _sliced_to_array(arr, i) {
68
92
  return _array_with_holes(arr) || _iterable_to_array_limit(arr, i) || _unsupported_iterable_to_array(arr, i) || _non_iterable_rest();
69
93
  }
@@ -76,7 +100,7 @@ function _unsupported_iterable_to_array(o, minLen) {
76
100
  if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
77
101
  }
78
102
  import { ConfigProvider, theme as antdTheme } from "antd";
79
- import React, { useMemo, useState } from "react";
103
+ import React, { useEffect, useMemo, useState } from "react";
80
104
  import { MarkdownEditor } from "../../../MarkdownEditor";
81
105
  import { useEditorStore } from "../../../MarkdownEditor/editor/store";
82
106
  import { useCodeEditorState, useRenderConditions, useToolbarConfig } from "../hooks";
@@ -94,7 +118,7 @@ import { AceEditor, AceEditorContainer, CodeContainer, CodeToolbar, HtmlPreview,
94
118
  * - 响应式布局适配
95
119
  * - 支持代码框选中状态管理
96
120
  */ export function CodeRenderer(props) {
97
- var _editorProps_codeProps;
121
+ var _props_element_otherProps, _props_element, _props_element_otherProps1, _props_element1, _editorProps_codeProps;
98
122
  var _useEditorStore = useEditorStore(), editorProps = _useEditorStore.editorProps, readonly = _useEditorStore.readonly;
99
123
  // 使用状态管理Hook
100
124
  var _useCodeEditorState = useCodeEditorState(props.element), state = _useCodeEditorState.state, update = _useCodeEditorState.update, path = _useCodeEditorState.path, handleCloseClick = _useCodeEditorState.handleCloseClick, handleHtmlPreviewClose = _useCodeEditorState.handleHtmlPreviewClose, handleShowBorderChange = _useCodeEditorState.handleShowBorderChange, handleHideChange = _useCodeEditorState.handleHideChange;
@@ -133,6 +157,33 @@ import { AceEditor, AceEditorContainer, CodeContainer, CodeToolbar, HtmlPreview,
133
157
  onViewModeToggle: handleViewModeToggle,
134
158
  viewMode: viewMode
135
159
  }).toolbarProps;
160
+ // 检查代码块是否未闭合
161
+ var isUnclosed = ((_props_element = props.element) === null || _props_element === void 0 ? void 0 : (_props_element_otherProps = _props_element.otherProps) === null || _props_element_otherProps === void 0 ? void 0 : _props_element_otherProps.finish) === false;
162
+ // 5 秒超时机制:如果代码块未闭合,5 秒后自动设置为完成
163
+ useEffect(function() {
164
+ if (isUnclosed && !readonly) {
165
+ var timer = setTimeout(function() {
166
+ var _props_element_otherProps, _props_element;
167
+ // 检查 finish 是否仍然是 false(可能已经被其他逻辑更新)
168
+ if (((_props_element = props.element) === null || _props_element === void 0 ? void 0 : (_props_element_otherProps = _props_element.otherProps) === null || _props_element_otherProps === void 0 ? void 0 : _props_element_otherProps.finish) === false) {
169
+ var _props_element1;
170
+ update({
171
+ otherProps: _object_spread_props(_object_spread({}, (_props_element1 = props.element) === null || _props_element1 === void 0 ? void 0 : _props_element1.otherProps), {
172
+ finish: true
173
+ })
174
+ });
175
+ }
176
+ }, 5000); // 5 秒超时
177
+ return function() {
178
+ clearTimeout(timer);
179
+ };
180
+ }
181
+ }, [
182
+ isUnclosed,
183
+ readonly,
184
+ (_props_element1 = props.element) === null || _props_element1 === void 0 ? void 0 : (_props_element_otherProps1 = _props_element1.otherProps) === null || _props_element_otherProps1 === void 0 ? void 0 : _props_element_otherProps1.finish,
185
+ update
186
+ ]);
136
187
  // 渲染组件
137
188
  return useMemo(function() {
138
189
  // 隐藏配置型 HTML 代码块
@@ -6,8 +6,9 @@
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 } from "react";
9
+ import React, { useContext, useMemo } from "react";
10
10
  import { ActionIconBox } from "../../../Components/ActionIconBox";
11
+ import { Loading } from "../../../Components/Loading";
11
12
  import { I18nContext } from "../../../I18n";
12
13
  import { langIconMap } from "../langIconMap";
13
14
  import { LanguageSelector } from "./LanguageSelector";
@@ -40,10 +41,17 @@ import { LoadImage } from "./LoadImage";
40
41
  * />
41
42
  * ```
42
43
  */ export var CodeToolbar = function(props) {
43
- var _element_language, _element_language1, _i18n_locale, _i18n_locale1;
44
+ var _element_otherProps, _element_language, _element_language1, _i18n_locale, _i18n_locale1;
44
45
  // 获取国际化上下文
45
46
  var i18n = useContext(I18nContext);
46
47
  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.finish) === false;
52
+ }, [
53
+ element === null || element === void 0 ? void 0 : (_element_otherProps = element.otherProps) === null || _element_otherProps === void 0 ? void 0 : _element_otherProps.finish
54
+ ]);
47
55
  return /*#__PURE__*/ React.createElement("div", {
48
56
  "data-testid": "code-toolbar",
49
57
  contentEditable: false,
@@ -72,6 +80,12 @@ import { LoadImage } from "./LoadImage";
72
80
  userSelect: 'none',
73
81
  borderBottom: isExpanded ? theme === 'chaos' ? '1px solid #161616' : '1px solid var(--color-gray-border-light)' : 'none'
74
82
  }
83
+ }, /*#__PURE__*/ React.createElement("div", {
84
+ style: {
85
+ display: 'flex',
86
+ alignItems: 'center',
87
+ gap: 8
88
+ }
75
89
  }, readonly ? // 只读模式:仅显示当前语言信息
76
90
  /*#__PURE__*/ React.createElement("div", {
77
91
  style: {
@@ -98,7 +112,12 @@ import { LoadImage } from "./LoadImage";
98
112
  },
99
113
  src: langIconMap.get(((_element_language1 = element.language) === null || _element_language1 === void 0 ? void 0 : _element_language1.toLowerCase()) || '')
100
114
  })), /*#__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'))) : // 非只读模式:显示语言选择器
101
- /*#__PURE__*/ React.createElement(LanguageSelector, languageSelectorProps), /*#__PURE__*/ React.createElement("div", {
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", {
102
121
  style: {
103
122
  display: 'flex',
104
123
  gap: 5,
@@ -171,6 +171,7 @@ function _ts_generator(thisArg, body) {
171
171
  import React, { lazy, Suspense, useEffect, useMemo, useRef } from "react";
172
172
  import { useGetSetState } from "react-use";
173
173
  import { useIntersectionOnce } from "../../Hooks/useIntersectionOnce";
174
+ import { isCodeBlockLikelyComplete } from "../../MarkdownEditor/editor/utils/findMatchingClose";
174
175
  var mermaidLoader = null;
175
176
  /**
176
177
  * 加载 Mermaid 库
@@ -214,27 +215,7 @@ var mermaidLoader = null;
214
215
  * 检查 Mermaid 代码是否可能完整
215
216
  * 用于流式输入时判断是否应该尝试渲染
216
217
  */ var isCodeLikelyComplete = function(code) {
217
- var trimmed = code.trim();
218
- if (!trimmed) return false;
219
- // 检查是否包含基本的 Mermaid 图表类型关键字
220
- var hasChartType = trimmed.includes('graph') || trimmed.includes('sequenceDiagram') || trimmed.includes('gantt') || trimmed.includes('pie') || trimmed.includes('classDiagram') || trimmed.includes('stateDiagram') || trimmed.includes('erDiagram') || trimmed.includes('journey') || trimmed.includes('gitgraph') || trimmed.includes('flowchart');
221
- if (!hasChartType) return false;
222
- // 检查基本结构完整性(简单启发式检查)
223
- // 如果代码很短,可能是正在输入中
224
- if (trimmed.length < 10) return false;
225
- // 检查是否以常见的不完整模式结尾
226
- var incompletePatterns = [
227
- /graph\s*$/i,
228
- /-->?\s*$/,
229
- /\[.*$/,
230
- /\(.*$/,
231
- /{.*$/
232
- ];
233
- // 如果匹配不完整模式,可能还在输入中
234
- var endsWithIncomplete = incompletePatterns.some(function(pattern) {
235
- return pattern.test(trimmed);
236
- });
237
- return !endsWithIncomplete;
218
+ return isCodeBlockLikelyComplete(code, 'mermaid');
238
219
  };
239
220
  var MermaidRendererImpl = function(props) {
240
221
  var _props_element;
@@ -307,9 +288,9 @@ var MermaidRendererImpl = function(props) {
307
288
  // 检查代码是否可能完整
308
289
  var likelyComplete = isCodeLikelyComplete(nextCode);
309
290
  // 防抖延迟:根据代码变化频率动态调整
310
- // 如果代码变化频繁(流式输入),使用更长的延迟
311
- var baseDelay = 300;
312
- var typingDelay = changeCountRef.current > 3 ? 1000 : 800; // 频繁变化时延长到 1 秒
291
+ // 如果代码变化频繁(流式输入),使用更长的延迟以减少抖动
292
+ var baseDelay = 500; // 增加基础延迟
293
+ var typingDelay = changeCountRef.current > 3 ? 1500 : 1200; // 频繁变化时延长到 1.5
313
294
  var delay = currentState.code ? likelyComplete ? baseDelay : typingDelay : 0;
314
295
  // 第一层防抖:检测代码变化
315
296
  timer.current = window.setTimeout(function() {
@@ -321,10 +302,10 @@ var MermaidRendererImpl = function(props) {
321
302
  return;
322
303
  }
323
304
  // 第二层防抖:实际渲染
324
- // 如果代码可能不完整,再等待一段时间
325
- var finalDelay = likelyComplete ? 0 : 500;
305
+ // 如果代码可能不完整,再等待一段时间,增加延迟以减少抖动
306
+ var finalDelay = likelyComplete ? 200 : 800; // 增加延迟时间
326
307
  renderTimer.current = window.setTimeout(/*#__PURE__*/ _async_to_generator(function() {
327
- var _mermaidRef_current, api, _tmp, trimmedCode, svg, wrapper, parser, svgDoc, svgElement, existingStyle, newStyle, allElements, tempDiv, extractedSvg, error, api1, finalCode, parseError, tempElement;
308
+ var _mermaidRef_current, api, _tmp, trimmedCode, svg, container, error, api1, finalCode, parseError, tempElement;
328
309
  return _ts_generator(this, function(_state) {
329
310
  switch(_state.label){
330
311
  case 0:
@@ -376,46 +357,62 @@ var MermaidRendererImpl = function(props) {
376
357
  case 4:
377
358
  svg = _state.sent().svg;
378
359
  if (divRef.current) {
379
- // 清理旧内容
380
- divRef.current.innerHTML = '';
381
- // 创建隔离的容器包装 SVG
382
- wrapper = document.createElement('div');
383
- wrapper.style.cssText = "\n position: relative;\n width: 100%;\n max-width: 100%;\n overflow: hidden;\n isolation: isolate;\n contain: layout style paint;\n display: flex;\n justify-content: center;\n align-items: center;\n ";
384
- // 解析 SVG 并添加隔离属性
385
- parser = new DOMParser();
386
- svgDoc = parser.parseFromString(svg, 'image/svg+xml');
387
- svgElement = svgDoc.querySelector('svg');
388
- if (svgElement) {
389
- // 确保 SVG 不会溢出
390
- existingStyle = svgElement.getAttribute('style') || '';
391
- newStyle = "".concat(existingStyle, "; max-width: 100%; height: auto; overflow: hidden;").trim();
392
- svgElement.setAttribute('style', newStyle);
393
- // 添加隔离属性和类名
394
- svgElement.setAttribute('data-mermaid-svg', 'true');
395
- svgElement.setAttribute('class', (svgElement.getAttribute('class') || '') + ' mermaid-isolated');
396
- // 限制 SVG 内部元素的样式影响范围
397
- allElements = svgElement.querySelectorAll('*');
398
- allElements.forEach(function(el) {
399
- // 确保内部元素不会影响外部
400
- if (el instanceof SVGElement) {
401
- el.setAttribute('data-mermaid-internal', 'true');
402
- }
403
- });
404
- wrapper.appendChild(svgElement);
405
- } else {
406
- // 如果解析失败,直接使用原始 SVG,但添加包装
407
- tempDiv = document.createElement('div');
408
- tempDiv.innerHTML = svg;
409
- extractedSvg = tempDiv.querySelector('svg');
410
- if (extractedSvg) {
411
- extractedSvg.setAttribute('style', 'max-width: 100%; height: auto; overflow: hidden;');
412
- extractedSvg.setAttribute('data-mermaid-svg', 'true');
413
- wrapper.appendChild(extractedSvg);
360
+ // 使用更平滑的更新方式,避免抖动
361
+ // 先设置透明度,然后更新内容,最后恢复透明度
362
+ container = divRef.current;
363
+ // 如果已有内容,先淡出
364
+ if (container.children.length > 0) {
365
+ container.style.opacity = '0';
366
+ container.style.transition = 'opacity 0.2s ease-in-out';
367
+ }
368
+ // 使用 requestAnimationFrame 确保平滑更新
369
+ requestAnimationFrame(function() {
370
+ // 清理旧内容
371
+ container.innerHTML = '';
372
+ // 创建隔离的容器包装 SVG
373
+ var wrapper = document.createElement('div');
374
+ wrapper.style.cssText = "\n position: relative;\n width: 100%;\n max-width: 100%;\n overflow: hidden;\n isolation: isolate;\n contain: layout style paint;\n display: flex;\n justify-content: center;\n align-items: center;\n min-height: 200px; /* 保持最小高度,避免尺寸抖动 */\n ";
375
+ // 解析 SVG 并添加隔离属性
376
+ var parser = new DOMParser();
377
+ var svgDoc = parser.parseFromString(svg, 'image/svg+xml');
378
+ var svgElement = svgDoc.querySelector('svg');
379
+ if (svgElement) {
380
+ // 确保 SVG 不会溢出
381
+ var existingStyle = svgElement.getAttribute('style') || '';
382
+ var newStyle = "".concat(existingStyle, "; max-width: 100%; height: auto; overflow: hidden;").trim();
383
+ svgElement.setAttribute('style', newStyle);
384
+ // 添加隔离属性和类名
385
+ svgElement.setAttribute('data-mermaid-svg', 'true');
386
+ svgElement.setAttribute('class', (svgElement.getAttribute('class') || '') + ' mermaid-isolated');
387
+ // 限制 SVG 内部元素的样式影响范围
388
+ var allElements = svgElement.querySelectorAll('*');
389
+ allElements.forEach(function(el) {
390
+ // 确保内部元素不会影响外部
391
+ if (el instanceof SVGElement) {
392
+ el.setAttribute('data-mermaid-internal', 'true');
393
+ }
394
+ });
395
+ wrapper.appendChild(svgElement);
414
396
  } else {
415
- wrapper.innerHTML = svg;
397
+ // 如果解析失败,直接使用原始 SVG,但添加包装
398
+ var tempDiv = document.createElement('div');
399
+ tempDiv.innerHTML = svg;
400
+ var extractedSvg = tempDiv.querySelector('svg');
401
+ if (extractedSvg) {
402
+ extractedSvg.setAttribute('style', 'max-width: 100%; height: auto; overflow: hidden;');
403
+ extractedSvg.setAttribute('data-mermaid-svg', 'true');
404
+ wrapper.appendChild(extractedSvg);
405
+ } else {
406
+ wrapper.innerHTML = svg;
407
+ }
416
408
  }
417
- }
418
- divRef.current.appendChild(wrapper);
409
+ container.appendChild(wrapper);
410
+ // 恢复透明度,实现淡入效果
411
+ requestAnimationFrame(function() {
412
+ container.style.opacity = '1';
413
+ container.style.transition = 'opacity 0.3s ease-in-out';
414
+ });
415
+ });
419
416
  }
420
417
  // 渲染成功,重置状态
421
418
  setState({
@@ -566,6 +563,7 @@ var MermaidRendererImpl = function(props) {
566
563
  style: {
567
564
  width: '100%',
568
565
  maxWidth: '100%',
566
+ minHeight: '200px',
569
567
  display: 'flex',
570
568
  justifyContent: 'center',
571
569
  visibility: snapshot.code && !snapshot.error ? 'visible' : 'hidden',
@@ -575,7 +573,9 @@ var MermaidRendererImpl = function(props) {
575
573
  contain: 'layout style paint',
576
574
  overflow: 'hidden',
577
575
  // 防止 SVG 样式影响外部
578
- pointerEvents: snapshot.code && !snapshot.error ? 'auto' : 'none'
576
+ pointerEvents: snapshot.code && !snapshot.error ? 'auto' : 'none',
577
+ // 添加过渡效果,使更新更平滑
578
+ transition: 'opacity 0.3s ease-in-out, min-height 0.2s ease-in-out'
579
579
  },
580
580
  // 使用 data 属性标记,方便样式隔离
581
581
  "data-mermaid-container": "true"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ant-design/agentic-ui",
3
- "version": "2.16.0",
3
+ "version": "2.17.0",
4
4
  "description": "面向智能体的 UI 组件库,提供多步推理可视化、工具调用展示、任务执行协同等 Agentic UI 能力",
5
5
  "repository": "git@github.com:ant-design/agentic-ui.git",
6
6
  "license": "MIT",