@ant-design/agentic-ui 2.11.2 → 2.12.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 (31) hide show
  1. package/dist/Bubble/MessagesContent/BubbleExtra.js +7 -1
  2. package/dist/MarkdownEditor/editor/types/Table.d.ts +1 -0
  3. package/dist/MarkdownEditor/editor/utils/ace.d.ts +22 -105
  4. package/dist/MarkdownEditor/editor/utils/ace.js +328 -106
  5. package/dist/MarkdownEditor/types.d.ts +1 -1
  6. package/dist/MarkdownInputField/AttachmentButton/index.js +5 -3
  7. package/dist/MarkdownInputField/MarkdownInputField.d.ts +32 -0
  8. package/dist/MarkdownInputField/MarkdownInputField.js +26 -8
  9. package/dist/Plugins/chart/ChartRender.js +75 -13
  10. package/dist/Plugins/chart/LineChart/index.js +10 -4
  11. package/dist/Plugins/chart/index.js +17 -5
  12. package/dist/Plugins/chart/utils.d.ts +40 -0
  13. package/dist/Plugins/chart/utils.js +116 -0
  14. package/dist/Plugins/code/CodeUI/Katex/Katex.d.ts +0 -1
  15. package/dist/Plugins/code/CodeUI/Katex/Katex.js +182 -6
  16. package/dist/Plugins/code/components/AceEditor.d.ts +4 -6
  17. package/dist/Plugins/code/components/AceEditor.js +362 -40
  18. package/dist/Plugins/code/loadAceEditor.d.ts +26 -0
  19. package/dist/Plugins/code/loadAceEditor.js +266 -0
  20. package/dist/Plugins/katex/InlineKatex.d.ts +0 -1
  21. package/dist/Plugins/katex/InlineKatex.js +183 -7
  22. package/dist/Plugins/katex/Katex.d.ts +0 -1
  23. package/dist/Plugins/katex/Katex.js +184 -6
  24. package/dist/Plugins/katex/loadKatex.d.ts +18 -0
  25. package/dist/Plugins/katex/loadKatex.js +181 -0
  26. package/dist/Plugins/mermaid/Mermaid.js +315 -113
  27. package/dist/Schema/SchemaEditor/AceEditorWrapper.d.ts +1 -1
  28. package/dist/Schema/SchemaEditor/AceEditorWrapper.js +342 -53
  29. package/dist/Utils/loadCSS.d.ts +31 -0
  30. package/dist/Utils/loadCSS.js +264 -0
  31. package/package.json +1 -1
@@ -210,16 +210,46 @@ var mermaidLoader = null;
210
210
  /**
211
211
  * Mermaid 渲染器组件实现
212
212
  * 负责实际的图表渲染逻辑
213
- */ var MermaidRendererImpl = function(props) {
213
+ */ /**
214
+ * 检查 Mermaid 代码是否可能完整
215
+ * 用于流式输入时判断是否应该尝试渲染
216
+ */ 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;
238
+ };
239
+ var MermaidRendererImpl = function(props) {
214
240
  var _props_element;
215
241
  var _useGetSetState = _sliced_to_array(useGetSetState({
216
242
  code: '',
217
- error: ''
243
+ error: '',
244
+ isTyping: false
218
245
  }), 2), state = _useGetSetState[0], setState = _useGetSetState[1];
219
246
  var containerRef = useRef(null);
220
247
  var divRef = useRef(null);
221
248
  var timer = useRef(null);
249
+ var renderTimer = useRef(null); // 实际渲染的定时器
222
250
  var mermaidRef = useRef(null);
251
+ var lastCodeRef = useRef(''); // 记录上一次的代码
252
+ var changeCountRef = useRef(0); // 记录变化次数
223
253
  var id = useMemo(function() {
224
254
  return 'm' + (Date.now() + Math.ceil(Math.random() * 1000));
225
255
  }, []);
@@ -230,22 +260,31 @@ var mermaidLoader = null;
230
260
  if (!isVisible) {
231
261
  return undefined;
232
262
  }
263
+ // 如果代码没有变化且没有错误,不需要重新渲染
233
264
  if (currentState.code === nextCode && currentState.error === '') {
234
265
  return undefined;
235
266
  }
267
+ // 清理所有定时器
236
268
  if (timer.current !== null) {
237
269
  window.clearTimeout(timer.current);
238
270
  timer.current = null;
239
271
  }
272
+ if (renderTimer.current !== null) {
273
+ window.clearTimeout(renderTimer.current);
274
+ renderTimer.current = null;
275
+ }
240
276
  if (!nextCode) {
241
277
  timer.current = window.setTimeout(function() {
242
278
  setState({
243
279
  code: '',
244
- error: ''
280
+ error: '',
281
+ isTyping: false
245
282
  });
246
283
  if (divRef.current) {
247
284
  divRef.current.innerHTML = '';
248
285
  }
286
+ lastCodeRef.current = '';
287
+ changeCountRef.current = 0;
249
288
  timer.current = null;
250
289
  }, 0);
251
290
  return function() {
@@ -255,116 +294,246 @@ var mermaidLoader = null;
255
294
  }
256
295
  };
257
296
  }
258
- var delay = currentState.code ? 300 : 0;
259
- timer.current = window.setTimeout(/*#__PURE__*/ _async_to_generator(function() {
260
- var _mermaidRef_current, api, _tmp, svg, error, api1, parseError, _document_querySelector;
261
- return _ts_generator(this, function(_state) {
262
- switch(_state.label){
263
- case 0:
264
- _state.trys.push([
265
- 0,
266
- 5,
267
- 10,
268
- 11
269
- ]);
270
- if (!((_mermaidRef_current = mermaidRef.current) !== null && _mermaidRef_current !== void 0)) return [
271
- 3,
272
- 1
273
- ];
274
- _tmp = _mermaidRef_current;
275
- return [
276
- 3,
277
- 3
278
- ];
279
- case 1:
280
- return [
281
- 4,
282
- loadMermaid()
283
- ];
284
- case 2:
285
- _tmp = _state.sent();
286
- _state.label = 3;
287
- case 3:
288
- api = _tmp;
289
- mermaidRef.current = api;
290
- return [
291
- 4,
292
- api.render(id, nextCode)
293
- ];
294
- case 4:
295
- svg = _state.sent().svg;
296
- if (divRef.current) {
297
- divRef.current.innerHTML = svg;
298
- }
299
- setState({
300
- code: nextCode,
301
- error: ''
302
- });
303
- return [
304
- 3,
305
- 11
306
- ];
307
- case 5:
308
- error = _state.sent();
309
- api1 = mermaidRef.current;
310
- if (!api1) return [
311
- 3,
312
- 9
313
- ];
314
- _state.label = 6;
315
- case 6:
316
- _state.trys.push([
317
- 6,
318
- 8,
319
- ,
320
- 9
321
- ]);
322
- return [
323
- 4,
324
- api1.parse(nextCode)
325
- ];
326
- case 7:
327
- _state.sent();
328
- return [
329
- 3,
330
- 9
331
- ];
332
- case 8:
333
- parseError = _state.sent();
334
- setState({
335
- error: String(parseError),
336
- code: ''
337
- });
338
- return [
339
- 2
340
- ];
341
- case 9:
342
- setState({
343
- error: String(error),
344
- code: ''
345
- });
346
- return [
347
- 3,
348
- 11
349
- ];
350
- case 10:
351
- (_document_querySelector = document.querySelector('#d' + id)) === null || _document_querySelector === void 0 ? void 0 : _document_querySelector.classList.add('hidden');
352
- return [
353
- 7
354
- ];
355
- case 11:
356
- timer.current = null;
357
- return [
358
- 2
359
- ];
360
- }
297
+ // 检测代码是否在快速变化(流式输入)
298
+ var isCodeChanging = nextCode !== lastCodeRef.current;
299
+ if (isCodeChanging) {
300
+ changeCountRef.current += 1;
301
+ lastCodeRef.current = nextCode;
302
+ // 如果代码在快速变化,标记为正在输入
303
+ setState({
304
+ isTyping: true
361
305
  });
362
- }), delay);
306
+ }
307
+ // 检查代码是否可能完整
308
+ var likelyComplete = isCodeLikelyComplete(nextCode);
309
+ // 防抖延迟:根据代码变化频率动态调整
310
+ // 如果代码变化频繁(流式输入),使用更长的延迟
311
+ var baseDelay = 300;
312
+ var typingDelay = changeCountRef.current > 3 ? 1000 : 800; // 频繁变化时延长到 1 秒
313
+ var delay = currentState.code ? likelyComplete ? baseDelay : typingDelay : 0;
314
+ // 第一层防抖:检测代码变化
315
+ timer.current = window.setTimeout(function() {
316
+ // 再次检查代码是否还在变化
317
+ var finalCode = props.element.value || '';
318
+ if (finalCode !== nextCode) {
319
+ // 代码还在变化,重新调度
320
+ timer.current = null;
321
+ return;
322
+ }
323
+ // 第二层防抖:实际渲染
324
+ // 如果代码可能不完整,再等待一段时间
325
+ var finalDelay = likelyComplete ? 0 : 500;
326
+ 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;
328
+ return _ts_generator(this, function(_state) {
329
+ switch(_state.label){
330
+ case 0:
331
+ _state.trys.push([
332
+ 0,
333
+ 5,
334
+ 10,
335
+ 11
336
+ ]);
337
+ if (!((_mermaidRef_current = mermaidRef.current) !== null && _mermaidRef_current !== void 0)) return [
338
+ 3,
339
+ 1
340
+ ];
341
+ _tmp = _mermaidRef_current;
342
+ return [
343
+ 3,
344
+ 3
345
+ ];
346
+ case 1:
347
+ return [
348
+ 4,
349
+ loadMermaid()
350
+ ];
351
+ case 2:
352
+ _tmp = _state.sent();
353
+ _state.label = 3;
354
+ case 3:
355
+ api = _tmp;
356
+ mermaidRef.current = api;
357
+ // 验证代码是否完整(基本检查)
358
+ trimmedCode = nextCode.trim();
359
+ if (!trimmedCode) {
360
+ setState({
361
+ code: '',
362
+ error: ''
363
+ });
364
+ if (divRef.current) {
365
+ divRef.current.innerHTML = '';
366
+ }
367
+ timer.current = null;
368
+ return [
369
+ 2
370
+ ];
371
+ }
372
+ return [
373
+ 4,
374
+ api.render(id, trimmedCode)
375
+ ];
376
+ case 4:
377
+ svg = _state.sent().svg;
378
+ 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);
414
+ } else {
415
+ wrapper.innerHTML = svg;
416
+ }
417
+ }
418
+ divRef.current.appendChild(wrapper);
419
+ }
420
+ // 渲染成功,重置状态
421
+ setState({
422
+ code: nextCode,
423
+ error: '',
424
+ isTyping: false
425
+ });
426
+ changeCountRef.current = 0; // 重置变化计数
427
+ return [
428
+ 3,
429
+ 11
430
+ ];
431
+ case 5:
432
+ error = _state.sent();
433
+ api1 = mermaidRef.current;
434
+ finalCode = props.element.value || '';
435
+ // 如果代码还在变化中,不显示错误(可能是中间状态)
436
+ if (finalCode !== nextCode || state().isTyping) {
437
+ // 代码还在变化,可能是流式输入,不显示错误
438
+ renderTimer.current = null;
439
+ return [
440
+ 2
441
+ ];
442
+ }
443
+ if (!api1) return [
444
+ 3,
445
+ 9
446
+ ];
447
+ _state.label = 6;
448
+ case 6:
449
+ _state.trys.push([
450
+ 6,
451
+ 8,
452
+ ,
453
+ 9
454
+ ]);
455
+ return [
456
+ 4,
457
+ api1.parse(finalCode)
458
+ ];
459
+ case 7:
460
+ _state.sent();
461
+ // 如果能解析,说明可能是渲染问题,不显示错误
462
+ renderTimer.current = null;
463
+ return [
464
+ 2
465
+ ];
466
+ case 8:
467
+ parseError = _state.sent();
468
+ // 确实是语法错误,但只在代码稳定后显示
469
+ if (finalCode === nextCode && !state().isTyping) {
470
+ setState({
471
+ error: String(parseError),
472
+ code: '',
473
+ isTyping: false
474
+ });
475
+ // 确保清理渲染内容
476
+ if (divRef.current) {
477
+ divRef.current.innerHTML = '';
478
+ }
479
+ }
480
+ renderTimer.current = null;
481
+ return [
482
+ 2
483
+ ];
484
+ case 9:
485
+ // 其他错误,只在代码稳定后显示
486
+ if (finalCode === nextCode && !state().isTyping) {
487
+ setState({
488
+ error: String(error),
489
+ code: '',
490
+ isTyping: false
491
+ });
492
+ // 确保清理渲染内容
493
+ if (divRef.current) {
494
+ divRef.current.innerHTML = '';
495
+ }
496
+ }
497
+ return [
498
+ 3,
499
+ 11
500
+ ];
501
+ case 10:
502
+ // 清理 Mermaid 生成的临时元素
503
+ tempElement = document.querySelector('#d' + id);
504
+ if (tempElement) {
505
+ tempElement.classList.add('hidden');
506
+ // 尝试移除临时元素,避免 DOM 污染
507
+ try {
508
+ if (tempElement.parentNode) {
509
+ tempElement.parentNode.removeChild(tempElement);
510
+ }
511
+ } catch (e) {
512
+ // 忽略移除失败
513
+ }
514
+ }
515
+ renderTimer.current = null;
516
+ return [
517
+ 7
518
+ ];
519
+ case 11:
520
+ timer.current = null;
521
+ return [
522
+ 2
523
+ ];
524
+ }
525
+ });
526
+ }), finalDelay);
527
+ }, delay);
363
528
  return function() {
364
529
  if (timer.current !== null) {
365
530
  window.clearTimeout(timer.current);
366
531
  timer.current = null;
367
532
  }
533
+ if (renderTimer.current !== null) {
534
+ window.clearTimeout(renderTimer.current);
535
+ renderTimer.current = null;
536
+ }
368
537
  };
369
538
  }, [
370
539
  props === null || props === void 0 ? void 0 : (_props_element = props.element) === null || _props_element === void 0 ? void 0 : _props_element.value,
@@ -383,7 +552,12 @@ var mermaidLoader = null;
383
552
  padding: '0.75rem 0',
384
553
  borderRadius: '1em',
385
554
  display: 'flex',
386
- justifyContent: 'center'
555
+ justifyContent: 'center',
556
+ // 增加隔离:防止内容溢出影响其他元素
557
+ position: 'relative',
558
+ isolation: 'isolate',
559
+ contain: 'layout style paint',
560
+ overflow: 'hidden'
387
561
  },
388
562
  contentEditable: false
389
563
  }, /*#__PURE__*/ React.createElement("div", {
@@ -391,19 +565,47 @@ var mermaidLoader = null;
391
565
  ref: divRef,
392
566
  style: {
393
567
  width: '100%',
568
+ maxWidth: '100%',
394
569
  display: 'flex',
395
570
  justifyContent: 'center',
396
- visibility: snapshot.code && !snapshot.error ? 'visible' : 'hidden'
571
+ visibility: snapshot.code && !snapshot.error ? 'visible' : 'hidden',
572
+ // 增加隔离样式
573
+ position: 'relative',
574
+ isolation: 'isolate',
575
+ contain: 'layout style paint',
576
+ overflow: 'hidden',
577
+ // 防止 SVG 样式影响外部
578
+ pointerEvents: snapshot.code && !snapshot.error ? 'auto' : 'none'
579
+ },
580
+ // 使用 data 属性标记,方便样式隔离
581
+ "data-mermaid-container": "true"
582
+ }), snapshot.isTyping && !snapshot.code && /*#__PURE__*/ React.createElement("div", {
583
+ style: {
584
+ textAlign: 'center',
585
+ color: '#6B7280',
586
+ padding: '0.5rem',
587
+ position: 'relative',
588
+ zIndex: 1,
589
+ fontStyle: 'italic'
397
590
  }
398
- }), snapshot.error && /*#__PURE__*/ React.createElement("div", {
591
+ }, "正在加载..."), snapshot.error && !snapshot.isTyping && /*#__PURE__*/ React.createElement("div", {
399
592
  style: {
400
593
  textAlign: 'center',
401
- color: 'rgba(239, 68, 68, 0.8)'
594
+ color: 'rgba(239, 68, 68, 0.8)',
595
+ padding: '0.5rem',
596
+ // 错误信息也增加隔离
597
+ position: 'relative',
598
+ zIndex: 1,
599
+ wordBreak: 'break-word',
600
+ maxWidth: '100%'
402
601
  }
403
- }, snapshot.error), !snapshot.code && !snapshot.error && /*#__PURE__*/ React.createElement("div", {
602
+ }, snapshot.error), !snapshot.code && !snapshot.error && !snapshot.isTyping && /*#__PURE__*/ React.createElement("div", {
404
603
  style: {
405
604
  textAlign: 'center',
406
- color: '#6B7280'
605
+ color: '#6B7280',
606
+ padding: '0.5rem',
607
+ position: 'relative',
608
+ zIndex: 1
407
609
  }
408
610
  }, "Empty"));
409
611
  };
@@ -1,4 +1,4 @@
1
- import { Ace } from 'ace-builds';
1
+ import type { Ace } from 'ace-builds';
2
2
  import React from 'react';
3
3
  interface AceEditorWrapperProps {
4
4
  /** 代码内容 */