@ant-design/agentic-ui 2.30.21 → 2.30.23

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 (107) hide show
  1. package/dist/Bubble/MessagesContent/MarkdownPreview.d.ts +0 -58
  2. package/dist/Bubble/MessagesContent/MarkdownPreview.js +79 -155
  3. package/dist/Bubble/OpenAIMessageBubble/index.d.ts +11 -0
  4. package/dist/Bubble/OpenAIMessageBubble/index.js +8 -0
  5. package/dist/Bubble/OpenAIMessageBubble/mapOllamaMessages.d.ts +7 -0
  6. package/dist/Bubble/OpenAIMessageBubble/mapOllamaMessages.js +136 -0
  7. package/dist/Bubble/OpenAIMessageBubble/mapOpenAIMessages.d.ts +8 -0
  8. package/dist/Bubble/OpenAIMessageBubble/mapOpenAIMessages.js +156 -0
  9. package/dist/Bubble/OpenAIMessageBubble/mapOpenClawMessages.d.ts +8 -0
  10. package/dist/Bubble/OpenAIMessageBubble/mapOpenClawMessages.js +127 -0
  11. package/dist/Bubble/OpenAIMessageBubble/normalizeOllamaMessages.d.ts +16 -0
  12. package/dist/Bubble/OpenAIMessageBubble/normalizeOllamaMessages.js +110 -0
  13. package/dist/Bubble/OpenAIMessageBubble/normalizeOpenClawMessages.d.ts +10 -0
  14. package/dist/Bubble/OpenAIMessageBubble/normalizeOpenClawMessages.js +61 -0
  15. package/dist/Bubble/OpenAIMessageBubble/ollamaTypes.d.ts +48 -0
  16. package/dist/Bubble/OpenAIMessageBubble/ollamaTypes.js +1 -0
  17. package/dist/Bubble/OpenAIMessageBubble/openClawTypes.d.ts +27 -0
  18. package/dist/Bubble/OpenAIMessageBubble/openClawTypes.js +1 -0
  19. package/dist/Bubble/OpenAIMessageBubble/types.d.ts +71 -0
  20. package/dist/Bubble/OpenAIMessageBubble/types.js +1 -0
  21. package/dist/Bubble/OpenAIMessageBubble/useOllamaMessageBubbleData.d.ts +7 -0
  22. package/dist/Bubble/OpenAIMessageBubble/useOllamaMessageBubbleData.js +23 -0
  23. package/dist/Bubble/OpenAIMessageBubble/useOpenAIMessageBubbleData.d.ts +6 -0
  24. package/dist/Bubble/OpenAIMessageBubble/useOpenAIMessageBubbleData.js +20 -0
  25. package/dist/Bubble/OpenAIMessageBubble/useOpenClawMessageBubbleData.d.ts +7 -0
  26. package/dist/Bubble/OpenAIMessageBubble/useOpenClawMessageBubbleData.js +22 -0
  27. package/dist/Bubble/index.d.ts +2 -0
  28. package/dist/Bubble/index.js +1 -0
  29. package/dist/Hooks/useAutoScroll.js +6 -4
  30. package/dist/MarkdownEditor/BaseMarkdownEditor.d.ts +1 -50
  31. package/dist/MarkdownEditor/BaseMarkdownEditor.js +11 -55
  32. package/dist/MarkdownEditor/editor/Editor.js +35 -21
  33. package/dist/MarkdownEditor/editor/elements/Code/index.js +1 -0
  34. package/dist/MarkdownEditor/editor/elements/Table/SimpleTable.js +5 -1
  35. package/dist/MarkdownEditor/editor/elements/Table/commands/tableCommands.js +24 -8
  36. package/dist/MarkdownEditor/editor/elements/index.js +18 -14
  37. package/dist/MarkdownEditor/editor/plugins/elements.d.ts +2 -0
  38. package/dist/MarkdownEditor/editor/plugins/elements.js +4 -2
  39. package/dist/MarkdownEditor/editor/plugins/handlePaste.js +46 -35
  40. package/dist/MarkdownEditor/editor/plugins/hotKeyCommands/backspace.js +133 -133
  41. package/dist/MarkdownEditor/editor/plugins/hotKeyCommands/enter.js +156 -140
  42. package/dist/MarkdownEditor/editor/plugins/hotKeyCommands/match.d.ts +2 -1
  43. package/dist/MarkdownEditor/editor/plugins/hotKeyCommands/match.js +23 -4
  44. package/dist/MarkdownEditor/editor/plugins/hotKeyCommands/tab.js +40 -36
  45. package/dist/MarkdownEditor/editor/plugins/useKeyboard.js +46 -44
  46. package/dist/MarkdownEditor/editor/plugins/withCodeTagPlugin.js +1 -13
  47. package/dist/MarkdownEditor/editor/store.d.ts +15 -1
  48. package/dist/MarkdownEditor/editor/store.js +45 -34
  49. package/dist/MarkdownEditor/editor/tools/InsertAutocomplete.js +15 -11
  50. package/dist/MarkdownEditor/editor/utils/editorCommands.js +98 -17
  51. package/dist/MarkdownEditor/editor/utils/editorUtils.d.ts +11 -0
  52. package/dist/MarkdownEditor/editor/utils/editorUtils.js +43 -6
  53. package/dist/MarkdownEditor/editor/utils/keyboard.js +14 -12
  54. package/dist/MarkdownEditor/types.d.ts +36 -414
  55. package/dist/MarkdownEditor/types.js +1 -4
  56. package/dist/MarkdownInputField/AttachmentButton/AttachmentFileList/AttachmentFileListItem.d.ts +1 -1
  57. package/dist/MarkdownInputField/AttachmentButton/AttachmentFileList/AttachmentFileListItem.js +4 -5
  58. package/dist/MarkdownInputField/AttachmentButton/AttachmentFileList/index.d.ts +1 -1
  59. package/dist/MarkdownInputField/AttachmentButton/index.d.ts +1 -1
  60. package/dist/MarkdownInputField/MarkdownInputField.js +8 -1
  61. package/dist/MarkdownInputField/SendActions/index.js +7 -4
  62. package/dist/MarkdownInputField/SendButton/index.d.ts +6 -0
  63. package/dist/MarkdownInputField/SendButton/index.js +6 -0
  64. package/dist/MarkdownInputField/hooks/useMarkdownInputFieldHandlers.d.ts +2 -1
  65. package/dist/MarkdownInputField/hooks/useMarkdownInputFieldHandlers.js +12 -3
  66. package/dist/MarkdownInputField/hooks/useMarkdownInputFieldRefs.d.ts +1 -0
  67. package/dist/MarkdownInputField/hooks/useMarkdownInputFieldRefs.js +36 -5
  68. package/dist/MarkdownInputField/utils/renderHelpers.js +5 -0
  69. package/dist/MarkdownRenderer/AnimationText.d.ts +1 -5
  70. package/dist/MarkdownRenderer/AnimationText.js +2 -8
  71. package/dist/MarkdownRenderer/CharacterQueue.d.ts +0 -2
  72. package/dist/MarkdownRenderer/CharacterQueue.js +2 -2
  73. package/dist/MarkdownRenderer/FncRefForMarkdown.d.ts +24 -0
  74. package/dist/MarkdownRenderer/FncRefForMarkdown.js +65 -0
  75. package/dist/MarkdownRenderer/MarkdownRenderer.d.ts +1 -9
  76. package/dist/MarkdownRenderer/MarkdownRenderer.js +25 -18
  77. package/dist/MarkdownRenderer/StreamingCursor.d.ts +4 -0
  78. package/dist/MarkdownRenderer/StreamingCursor.js +20 -0
  79. package/dist/MarkdownRenderer/extractFootnoteDefinitions.d.ts +13 -0
  80. package/dist/MarkdownRenderer/extractFootnoteDefinitions.js +40 -0
  81. package/dist/MarkdownRenderer/markdownReactShared.d.ts +11 -38
  82. package/dist/MarkdownRenderer/markdownReactShared.js +28 -54
  83. package/dist/MarkdownRenderer/renderers/ChartRenderer.js +9 -1
  84. package/dist/MarkdownRenderer/renderers/CodeRenderer.d.ts +4 -1
  85. package/dist/MarkdownRenderer/renderers/CodeRenderer.js +27 -3
  86. package/dist/MarkdownRenderer/renderers/SchemaRenderer.d.ts +2 -0
  87. package/dist/MarkdownRenderer/renderers/SchemaRenderer.js +33 -5
  88. package/dist/MarkdownRenderer/streaming/MarkdownBlockPiece.d.ts +1 -3
  89. package/dist/MarkdownRenderer/streaming/MarkdownBlockPiece.js +16 -28
  90. package/dist/MarkdownRenderer/streaming/useStreamingMarkdownReact.js +2 -1
  91. package/dist/MarkdownRenderer/style.js +18 -0
  92. package/dist/MarkdownRenderer/types.d.ts +17 -93
  93. package/dist/MarkdownRenderer/useMarkdownToReact.js +1 -1
  94. package/dist/MarkdownRenderer/useStreaming.d.ts +1 -10
  95. package/dist/MarkdownRenderer/useStreaming.js +5 -13
  96. package/dist/Plugins/mermaid/MermaidRendererImpl.js +481 -7
  97. package/dist/Plugins/mermaid/style.js +71 -22
  98. package/dist/Plugins/mermaid/useMermaidRender.d.ts +2 -1
  99. package/dist/Plugins/mermaid/useMermaidRender.js +41 -13
  100. package/dist/Plugins/mermaid/utils.d.ts +16 -0
  101. package/dist/Plugins/mermaid/utils.js +197 -5
  102. package/dist/ThoughtChainList/MarkdownEditor.d.ts +1 -35
  103. package/dist/ThoughtChainList/MarkdownEditor.js +5 -44
  104. package/dist/Workspace/Browser/index.js +19 -1
  105. package/dist/Workspace/RealtimeFollow/index.d.ts +3 -0
  106. package/dist/Workspace/RealtimeFollow/index.js +5 -3
  107. 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
  /** 单个文件最大大小(字节) */
@@ -140,6 +140,7 @@ import { useLocale } from "../I18n";
140
140
  import { BaseMarkdownEditor } from "../MarkdownEditor";
141
141
  import { BorderBeamAnimation } from "./BorderBeamAnimation";
142
142
  import { useFileUploadManager } from "./FileUploadManager";
143
+ import { resolveSendDisabled } from "./SendButton";
143
144
  import { useMarkdownInputFieldActions } from "./hooks/useMarkdownInputFieldActions";
144
145
  import { useMarkdownInputFieldHandlers } from "./hooks/useMarkdownInputFieldHandlers";
145
146
  import { useMarkdownInputFieldLayout } from "./hooks/useMarkdownInputFieldLayout";
@@ -255,7 +256,7 @@ var MarkdownInputFieldComponent = function MarkdownInputFieldComponent(_0) {
255
256
  inputRef: props.inputRef,
256
257
  value: props.value,
257
258
  setValue: setValue
258
- }), markdownEditorRef = _useMarkdownInputFieldRefs.markdownEditorRef, quickActionsRef = _useMarkdownInputFieldRefs.quickActionsRef, actionsRef = _useMarkdownInputFieldRefs.actionsRef, isSendingRef = _useMarkdownInputFieldRefs.isSendingRef;
259
+ }), markdownEditorRef = _useMarkdownInputFieldRefs.markdownEditorRef, quickActionsRef = _useMarkdownInputFieldRefs.quickActionsRef, actionsRef = _useMarkdownInputFieldRefs.actionsRef, isSendingRef = _useMarkdownInputFieldRefs.isSendingRef, onEditorChange = _useMarkdownInputFieldRefs.onEditorChange;
259
260
  // 文件上传管理
260
261
  var _useFileUploadManager = useFileUploadManager({
261
262
  attachment: attachment,
@@ -280,6 +281,7 @@ var MarkdownInputFieldComponent = function MarkdownInputFieldComponent(_0) {
280
281
  attachment: attachment,
281
282
  triggerSendKey: props.triggerSendKey
282
283
  },
284
+ sendDisabled: resolveSendDisabled(props.sendButtonProps, fileUploadStatus),
283
285
  markdownEditorRef: markdownEditorRef,
284
286
  inputRef: inputRef,
285
287
  isSendingRef: isSendingRef,
@@ -446,6 +448,7 @@ var MarkdownInputFieldComponent = function MarkdownInputFieldComponent(_0) {
446
448
  var _props_onChange1, _props_onMaxLengthExceeded, // 更新编辑器内容以反映截断后的值
447
449
  _markdownEditorRef_current_store, _markdownEditorRef_current;
448
450
  var truncatedValue = value.slice(0, props.maxLength);
451
+ onEditorChange(truncatedValue);
449
452
  setValue(truncatedValue);
450
453
  (_props_onChange1 = props.onChange) === null || _props_onChange1 === void 0 ? void 0 : _props_onChange1.call(props, truncatedValue);
451
454
  (_props_onMaxLengthExceeded = props.onMaxLengthExceeded) === null || _props_onMaxLengthExceeded === void 0 ? void 0 : _props_onMaxLengthExceeded.call(props, value);
@@ -453,6 +456,10 @@ var MarkdownInputFieldComponent = function MarkdownInputFieldComponent(_0) {
453
456
  return;
454
457
  }
455
458
  }
459
+ // Record the value the editor just produced so the external
460
+ // props.value sync effect skips the redundant setMDContent call
461
+ // that would disrupt the live Slate selection while typing.
462
+ onEditorChange(value);
456
463
  setValue(value);
457
464
  (_props_onChange = props.onChange) === null || _props_onChange === void 0 ? void 0 : _props_onChange.call(props, value);
458
465
  },
@@ -58,7 +58,7 @@ import React, { useContext, useMemo } from "react";
58
58
  import { ActionIconBox } from "../../Components/ActionIconBox";
59
59
  import { I18nContext } from "../../I18n";
60
60
  import { AttachmentButton } from "../AttachmentButton";
61
- import { SendButton } from "../SendButton";
61
+ import { SendButton, resolveSendDisabled } from "../SendButton";
62
62
  import { VoiceInputButton } from "../VoiceInput";
63
63
  import { MARKDOWN_INPUT_FIELD_TEST_IDS } from "../testIds";
64
64
  /**
@@ -68,6 +68,7 @@ import { MARKDOWN_INPUT_FIELD_TEST_IDS } from "../testIds";
68
68
  */ export var SendActions = function SendActions(param) {
69
69
  var attachment = param.attachment, voiceRecognizer = param.voiceRecognizer, value = param.value, disabled = param.disabled, typing = param.typing, isLoading = param.isLoading, _param_fileUploadDone = param.fileUploadDone, fileUploadDone = _param_fileUploadDone === void 0 ? true : _param_fileUploadDone, _param_fileUploadStatus = param.fileUploadStatus, fileUploadStatus = _param_fileUploadStatus === void 0 ? fileUploadDone ? 'done' : 'uploading' : _param_fileUploadStatus, fileUploadSummary = param.fileUploadSummary, _param_recording = param.recording, recording = _param_recording === void 0 ? false : _param_recording, _param_collapseSendActions = param.collapseSendActions, collapseSendActions = _param_collapseSendActions === void 0 ? false : _param_collapseSendActions, _param_allowEmptySubmit = param.allowEmptySubmit, allowEmptySubmit = _param_allowEmptySubmit === void 0 ? false : _param_allowEmptySubmit, uploadImage = param.uploadImage, onStartRecording = param.onStartRecording, onStopRecording = param.onStopRecording, onSend = param.onSend, onStop = param.onStop, actionsRender = param.actionsRender, _param_prefixCls = param.prefixCls, prefixCls = _param_prefixCls === void 0 ? 'ant-agentic-md-input-field' : _param_prefixCls, _param_hashId = param.hashId, hashId = _param_hashId === void 0 ? '' : _param_hashId, _param_hasTools = param.hasTools, hasTools = _param_hasTools === void 0 ? false : _param_hasTools, onResize = param.onResize, sendButtonProps = param.sendButtonProps, triggerSendKey = param.triggerSendKey;
70
70
  var fileMap = attachment === null || attachment === void 0 ? void 0 : attachment.fileMap;
71
+ var sendDisabled = resolveSendDisabled(sendButtonProps, fileUploadStatus);
71
72
  var defaultActionsLen = [
72
73
  (attachment === null || attachment === void 0 ? void 0 : attachment.enable) ? '()' : null,
73
74
  voiceRecognizer ? '()' : null,
@@ -104,11 +105,10 @@ import { MARKDOWN_INPUT_FIELD_TEST_IDS } from "../testIds";
104
105
  return Promise.resolve();
105
106
  }
106
107
  }) : null,
107
- /*#__PURE__*/ React.createElement(SendButton, _object_spread({
108
+ /*#__PURE__*/ React.createElement(SendButton, _object_spread_props(_object_spread({
108
109
  key: "send-button",
109
110
  typing: !!typing || !!isLoading,
110
111
  isSendable: allowEmptySubmit || !!(value === null || value === void 0 ? void 0 : value.trim()) || fileMap && fileMap.size > 0 || recording,
111
- disabled: disabled,
112
112
  onClick: function onClick() {
113
113
  if (typing || isLoading) {
114
114
  onStop === null || onStop === void 0 ? void 0 : onStop();
@@ -117,11 +117,14 @@ import { MARKDOWN_INPUT_FIELD_TEST_IDS } from "../testIds";
117
117
  onSend === null || onSend === void 0 ? void 0 : onSend();
118
118
  },
119
119
  triggerSendKey: triggerSendKey
120
- }, sendButtonProps))
120
+ }, sendButtonProps), {
121
+ disabled: disabled || sendDisabled
122
+ }))
121
123
  ].filter(Boolean);
122
124
  }, [
123
125
  attachment,
124
126
  fileUploadDone,
127
+ sendDisabled,
125
128
  value,
126
129
  collapseSendActions,
127
130
  isLoading,
@@ -1,4 +1,5 @@
1
1
  import React from 'react';
2
+ import type { FileUploadManagerReturn } from '../FileUploadManager';
2
3
  /**
3
4
  * 按钮颜色配置
4
5
  */
@@ -18,7 +19,12 @@ export type SendButtonColors = {
18
19
  export type SendButtonCustomizationProps = {
19
20
  compact?: boolean;
20
21
  colors?: SendButtonColors;
22
+ disabled?: boolean;
21
23
  };
24
+ /**
25
+ * 解析发送按钮的最终禁用状态:用户显式传入优先,否则按上传状态判断
26
+ */
27
+ export declare function resolveSendDisabled(sendButtonProps: SendButtonCustomizationProps | undefined, fileUploadStatus: FileUploadManagerReturn['fileUploadStatus'] | undefined): boolean;
22
28
  /**
23
29
  * Props for the SendButton component.
24
30
  */
@@ -70,6 +70,12 @@ import { ErrorBoundary } from "react-error-boundary";
70
70
  import { StopIcon } from "../../AgentRunBar/icons";
71
71
  import { I18nContext } from "../../I18n";
72
72
  import { useStyle } from "./style";
73
+ /**
74
+ * 解析发送按钮的最终禁用状态:用户显式传入优先,否则按上传状态判断
75
+ */ export function resolveSendDisabled(sendButtonProps, fileUploadStatus) {
76
+ var _ref;
77
+ return (_ref = sendButtonProps === null || sendButtonProps === void 0 ? void 0 : sendButtonProps.disabled) !== null && _ref !== void 0 ? _ref : fileUploadStatus === 'uploading';
78
+ }
73
79
  var DEFAULT_SEND_BUTTON_COLORS = {
74
80
  icon: '#00183D',
75
81
  iconHover: '#fff',
@@ -4,6 +4,7 @@ import type { AttachmentFile } from '../AttachmentButton/types';
4
4
  import type { MarkdownInputFieldProps } from '../types/MarkdownInputFieldProps';
5
5
  interface UseMarkdownInputFieldHandlersParams {
6
6
  props: Pick<MarkdownInputFieldProps, 'disabled' | 'typing' | 'onChange' | 'onSend' | 'allowEmptySubmit' | 'markdownProps' | 'attachment' | 'triggerSendKey'>;
7
+ sendDisabled?: boolean;
7
8
  markdownEditorRef: React.MutableRefObject<MarkdownEditorInstance | undefined>;
8
9
  inputRef: React.RefObject<HTMLDivElement>;
9
10
  isSendingRef: React.MutableRefObject<boolean>;
@@ -22,7 +23,7 @@ interface UseMarkdownInputFieldHandlersParams {
22
23
  * 事件处理 Hook
23
24
  * 管理组件中的所有事件处理函数
24
25
  */
25
- export declare const useMarkdownInputFieldHandlers: ({ props, markdownEditorRef, inputRef, isSendingRef, isLoading, setIsLoading, value, setValue, fileMap, setFileMap, recording, stopRecording, isEnlarged, setIsEnlarged, }: UseMarkdownInputFieldHandlersParams) => {
26
+ export declare const useMarkdownInputFieldHandlers: ({ props, sendDisabled, markdownEditorRef, inputRef, isSendingRef, isLoading, setIsLoading, value, setValue, fileMap, setFileMap, recording, stopRecording, isEnlarged, setIsEnlarged, }: UseMarkdownInputFieldHandlersParams) => {
26
27
  handleEnlargeClick: () => void;
27
28
  sendMessage: () => Promise<void>;
28
29
  handlePaste: (e: React.ClipboardEvent<HTMLDivElement>) => Promise<void>;
@@ -189,7 +189,7 @@ import { getFileListFromDataTransferItems } from "../FilePaste";
189
189
  * 事件处理 Hook
190
190
  * 管理组件中的所有事件处理函数
191
191
  */ export var useMarkdownInputFieldHandlers = function useMarkdownInputFieldHandlers(param) {
192
- var props = param.props, markdownEditorRef = param.markdownEditorRef, inputRef = param.inputRef, isSendingRef = param.isSendingRef, isLoading = param.isLoading, setIsLoading = param.setIsLoading, value = param.value, setValue = param.setValue, fileMap = param.fileMap, setFileMap = param.setFileMap, recording = param.recording, stopRecording = param.stopRecording, isEnlarged = param.isEnlarged, setIsEnlarged = param.setIsEnlarged;
192
+ var props = param.props, sendDisabled = param.sendDisabled, markdownEditorRef = param.markdownEditorRef, inputRef = param.inputRef, isSendingRef = param.isSendingRef, isLoading = param.isLoading, setIsLoading = param.setIsLoading, value = param.value, setValue = param.setValue, fileMap = param.fileMap, setFileMap = param.setFileMap, recording = param.recording, stopRecording = param.stopRecording, isEnlarged = param.isEnlarged, setIsEnlarged = param.setIsEnlarged;
193
193
  /**
194
194
  * 处理放大缩小按钮点击
195
195
  * @description 切换编辑器的放大/缩小状态
@@ -206,6 +206,7 @@ import { getFileListFromDataTransferItems } from "../FilePaste";
206
206
  return _ts_generator(this, function(_state) {
207
207
  switch(_state.label){
208
208
  case 0:
209
+ // 这个 disable 是整体 input 的禁用
209
210
  if (props.disabled) return [
210
211
  2
211
212
  ];
@@ -220,6 +221,10 @@ import { getFileListFromDataTransferItems } from "../FilePaste";
220
221
  if (isSendingRef.current) return [
221
222
  2
222
223
  ];
224
+ // 这个是发送按钮的单独禁用
225
+ if (sendDisabled) return [
226
+ 2
227
+ ];
223
228
  if (!recording) return [
224
229
  3,
225
230
  2
@@ -401,8 +406,12 @@ import { getFileListFromDataTransferItems } from "../FilePaste";
401
406
  var isInteractive = target.closest('button') || target.closest('a') || target.closest('input') || target.closest('[contenteditable="true"]');
402
407
  if (isInteractive) return;
403
408
  EditorUtils.focus(editor);
404
- var end = Editor.end(editor, []);
405
- Transforms.select(editor, end);
409
+ try {
410
+ var end = Editor.end(editor, []);
411
+ Transforms.select(editor, end);
412
+ } catch (unused) {
413
+ // editor may have no valid content points yet; focus is still applied
414
+ }
406
415
  });
407
416
  var activeInput = useRefFunction(function(active) {
408
417
  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,
@@ -14,10 +14,6 @@ export interface AnimationTextProps {
14
14
  children: React.ReactNode;
15
15
  animationConfig?: AnimationConfig;
16
16
  }
17
- /**
18
- * 流式文字淡入动画组件。
19
- *
20
- * 同一段流式前缀追加(或尾部截断修正)只触发一次入场动画;非前缀替换时重播。
21
- */
17
+ /** 流式文字淡入,前缀追加只触发一次入场,非前缀替换时重播 */
22
18
  declare const AnimationText: React.NamedExoticComponent<AnimationTextProps>;
23
19
  export default AnimationText;
@@ -45,9 +45,7 @@ function _unsupported_iterable_to_array(o, minLen) {
45
45
  if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
46
46
  }
47
47
  import React, { useEffect, useMemo, useRef, useState } from "react";
48
- /**
49
- * 提取 React children 的纯文本
50
- */ var extractText = function extractText1(children) {
48
+ var extractText = function extractText1(children) {
51
49
  var _children_props;
52
50
  if (typeof children === 'string') return children;
53
51
  if (typeof children === 'number') return String(children);
@@ -60,11 +58,7 @@ import React, { useEffect, useMemo, useRef, useState } from "react";
60
58
  /** 流式同一段内:前后文案仅「前缀关系」变化(增长或尾部截断修正) */ var isStreamingCompatible = function isStreamingCompatible(prev, next) {
61
59
  return prev.startsWith(next) || next.startsWith(prev);
62
60
  };
63
- /**
64
- * 流式文字淡入动画组件。
65
- *
66
- * 同一段流式前缀追加(或尾部截断修正)只触发一次入场动画;非前缀替换时重播。
67
- */ var AnimationText = /*#__PURE__*/ React.memo(function(param) {
61
+ /** 流式文字淡入,前缀追加只触发一次入场,非前缀替换时重播 */ var AnimationText = /*#__PURE__*/ React.memo(function(param) {
68
62
  var children = param.children, animationConfig = param.animationConfig;
69
63
  var _ref = animationConfig || {}, _ref_fadeDuration = _ref.fadeDuration, fadeDuration = _ref_fadeDuration === void 0 ? 250 : _ref_fadeDuration, _ref_easing = _ref.easing, easing = _ref_easing === void 0 ? 'ease-out' : _ref_easing;
70
64
  var _useState = _sliced_to_array(useState(false), 2), animComplete = _useState[0], setAnimComplete = _useState[1];
@@ -23,9 +23,7 @@ export declare class CharacterQueue {
23
23
  complete(): void;
24
24
  /** 释放资源 */
25
25
  dispose(): void;
26
- /** 当前已展示的长度 */
27
26
  getDisplayedLength(): number;
28
- /** 完整内容 */
29
27
  getFullContent(): string;
30
28
  private ensureTicking;
31
29
  private tick;
@@ -126,13 +126,13 @@ var DEFAULT_BACKGROUND_BATCH_MULTIPLIER = 10;
126
126
  }
127
127
  },
128
128
  {
129
- /** 当前已展示的长度 */ key: "getDisplayedLength",
129
+ key: "getDisplayedLength",
130
130
  value: function getDisplayedLength() {
131
131
  return this.displayedLength;
132
132
  }
133
133
  },
134
134
  {
135
- /** 完整内容 */ key: "getFullContent",
135
+ key: "getFullContent",
136
136
  value: function getFullContent() {
137
137
  return this.fullContent;
138
138
  }
@@ -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
+ };
@@ -1,13 +1,5 @@
1
1
  import React from 'react';
2
2
  import type { MarkdownRendererProps, MarkdownRendererRef } from './types';
3
- /**
4
- * MarkdownRenderer —— 流式/只读场景下的轻量 Markdown 渲染器。
5
- *
6
- * 核心优势:
7
- * - 不创建 Slate 实例,无编辑态开销
8
- * - 字符队列驱动流式逐字输出动画
9
- * - Markdown → hast → React 元素树(hast-util-to-jsx-runtime)
10
- * - 特殊块(code / mermaid / chart / katex)通过组件映射拦截渲染
11
- */
3
+ /** 轻量流式 Markdown 渲染器——无 Slate 实例,Markdown → hast → React */
12
4
  declare const InternalMarkdownRenderer: React.ForwardRefExoticComponent<MarkdownRendererProps & React.RefAttributes<MarkdownRendererRef>>;
13
5
  export default InternalMarkdownRenderer;
@@ -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,24 +230,18 @@ 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
- /**
240
- * MarkdownRenderer —— 流式/只读场景下的轻量 Markdown 渲染器。
241
- *
242
- * 核心优势:
243
- * - 不创建 Slate 实例,无编辑态开销
244
- * - 字符队列驱动流式逐字输出动画
245
- * - Markdown → hast → React 元素树(hast-util-to-jsx-runtime)
246
- * - 特殊块(code / mermaid / chart / katex)通过组件映射拦截渲染
247
- */ 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;
243
+ /** 轻量流式 Markdown 渲染器——无 Slate 实例,Markdown → hast → React */ var InternalMarkdownRenderer = /*#__PURE__*/ forwardRef(function(props, ref) {
244
+ 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
245
  var getPrefixCls = useContext(ConfigProvider.ConfigContext).getPrefixCls;
250
246
  // 复用 MarkdownEditor 的 CSS 前缀和样式,保持渲染一致性
251
247
  var prefixCls = getPrefixCls('agentic-md-editor', customPrefixCls);
@@ -333,6 +329,14 @@ var SCHEMA_LANGUAGES = new Set([
333
329
  content,
334
330
  streaming
335
331
  ]);
332
+ useEffect(function() {
333
+ var notify = fncProps === null || fncProps === void 0 ? void 0 : fncProps.onFootnoteDefinitionChange;
334
+ if (!notify) return;
335
+ notify(extractFootnoteDefinitionsFromMarkdown(displayedContent || ''));
336
+ }, [
337
+ displayedContent,
338
+ fncProps === null || fncProps === void 0 ? void 0 : fncProps.onFootnoteDefinitionChange
339
+ ]);
336
340
  // 构建组件映射
337
341
  // code 渲染器通过 pre override 在 useMarkdownToReact 中路由,
338
342
  // 不直接映射到 <code> 标签(否则会影响行内代码 `code`)
@@ -343,11 +347,12 @@ var SCHEMA_LANGUAGES = new Set([
343
347
  apaasify
344
348
  ]);
345
349
  var components = useMemo(function() {
346
- var codeRouter = function codeRouter(codeProps) {
347
- return /*#__PURE__*/ React.createElement(DefaultCodeRouter, _object_spread_props(_object_spread({}, codeProps), {
350
+ var codeRouter = function codeRouter(blockProps) {
351
+ return /*#__PURE__*/ React.createElement(DefaultCodeRouter, _object_spread_props(_object_spread({}, blockProps), {
348
352
  pluginComponents: pluginComponents,
349
353
  apaasifyRender: apaasifyRender,
350
- fileMapConfig: fileMapConfig
354
+ fileMapConfig: fileMapConfig,
355
+ editorCodeProps: editorCodeProps
351
356
  }));
352
357
  };
353
358
  codeRouter.displayName = 'CodeRouter';
@@ -357,7 +362,8 @@ var SCHEMA_LANGUAGES = new Set([
357
362
  }, [
358
363
  pluginComponents,
359
364
  apaasifyRender,
360
- fileMapConfig
365
+ fileMapConfig,
366
+ editorCodeProps
361
367
  ]);
362
368
  // 流式缓存:将不完整的 Markdown token 暂缓,避免 parser 错误解析
363
369
  var safeContent = useStreaming(displayedContent, streaming);
@@ -367,6 +373,7 @@ var SCHEMA_LANGUAGES = new Set([
367
373
  components: components,
368
374
  prefixCls: prefixCls,
369
375
  linkConfig: linkConfig,
376
+ fncProps: fncProps,
370
377
  streaming: streaming,
371
378
  streamingParagraphAnimation: streamingParagraphAnimation,
372
379
  contentRevisionSource: streaming ? displayedContent : undefined,
@@ -0,0 +1,4 @@
1
+ import React from 'react';
2
+ /** 流式闪烁光标,由 MarkdownBlockPiece 控制挂载/卸载 */
3
+ declare const StreamingCursor: React.FC;
4
+ export { StreamingCursor };
@@ -0,0 +1,20 @@
1
+ import React from "react";
2
+ /** 流式闪烁光标,由 MarkdownBlockPiece 控制挂载/卸载 */ var StreamingCursor = function StreamingCursor() {
3
+ return /*#__PURE__*/ React.createElement("span", {
4
+ "data-streaming-cursor": "",
5
+ "data-testid": "streaming-cursor",
6
+ "aria-hidden": "true",
7
+ style: {
8
+ display: 'inline-block',
9
+ width: 2,
10
+ height: '1.1em',
11
+ marginLeft: 2,
12
+ verticalAlign: 'text-bottom',
13
+ backgroundColor: 'currentColor',
14
+ borderRadius: 1,
15
+ animation: 'markdownStreamingCursorFadeIn 0.2s ease-out forwards, markdownStreamingCursorBlink 0.8s ease-in-out 0.2s infinite'
16
+ }
17
+ });
18
+ };
19
+ StreamingCursor.displayName = 'StreamingCursor';
20
+ export { StreamingCursor };