@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.
- package/dist/Bubble/MessagesContent/MarkdownPreview.d.ts +0 -58
- package/dist/Bubble/MessagesContent/MarkdownPreview.js +79 -155
- package/dist/Bubble/OpenAIMessageBubble/index.d.ts +11 -0
- package/dist/Bubble/OpenAIMessageBubble/index.js +8 -0
- package/dist/Bubble/OpenAIMessageBubble/mapOllamaMessages.d.ts +7 -0
- package/dist/Bubble/OpenAIMessageBubble/mapOllamaMessages.js +136 -0
- package/dist/Bubble/OpenAIMessageBubble/mapOpenAIMessages.d.ts +8 -0
- package/dist/Bubble/OpenAIMessageBubble/mapOpenAIMessages.js +156 -0
- package/dist/Bubble/OpenAIMessageBubble/mapOpenClawMessages.d.ts +8 -0
- package/dist/Bubble/OpenAIMessageBubble/mapOpenClawMessages.js +127 -0
- package/dist/Bubble/OpenAIMessageBubble/normalizeOllamaMessages.d.ts +16 -0
- package/dist/Bubble/OpenAIMessageBubble/normalizeOllamaMessages.js +110 -0
- package/dist/Bubble/OpenAIMessageBubble/normalizeOpenClawMessages.d.ts +10 -0
- package/dist/Bubble/OpenAIMessageBubble/normalizeOpenClawMessages.js +61 -0
- package/dist/Bubble/OpenAIMessageBubble/ollamaTypes.d.ts +48 -0
- package/dist/Bubble/OpenAIMessageBubble/ollamaTypes.js +1 -0
- package/dist/Bubble/OpenAIMessageBubble/openClawTypes.d.ts +27 -0
- package/dist/Bubble/OpenAIMessageBubble/openClawTypes.js +1 -0
- package/dist/Bubble/OpenAIMessageBubble/types.d.ts +71 -0
- package/dist/Bubble/OpenAIMessageBubble/types.js +1 -0
- package/dist/Bubble/OpenAIMessageBubble/useOllamaMessageBubbleData.d.ts +7 -0
- package/dist/Bubble/OpenAIMessageBubble/useOllamaMessageBubbleData.js +23 -0
- package/dist/Bubble/OpenAIMessageBubble/useOpenAIMessageBubbleData.d.ts +6 -0
- package/dist/Bubble/OpenAIMessageBubble/useOpenAIMessageBubbleData.js +20 -0
- package/dist/Bubble/OpenAIMessageBubble/useOpenClawMessageBubbleData.d.ts +7 -0
- package/dist/Bubble/OpenAIMessageBubble/useOpenClawMessageBubbleData.js +22 -0
- package/dist/Bubble/index.d.ts +2 -0
- package/dist/Bubble/index.js +1 -0
- package/dist/Hooks/useAutoScroll.js +6 -4
- package/dist/MarkdownEditor/BaseMarkdownEditor.d.ts +1 -50
- package/dist/MarkdownEditor/BaseMarkdownEditor.js +11 -55
- package/dist/MarkdownEditor/editor/Editor.js +35 -21
- package/dist/MarkdownEditor/editor/elements/Code/index.js +1 -0
- package/dist/MarkdownEditor/editor/elements/Table/SimpleTable.js +5 -1
- package/dist/MarkdownEditor/editor/elements/Table/commands/tableCommands.js +24 -8
- package/dist/MarkdownEditor/editor/elements/index.js +18 -14
- package/dist/MarkdownEditor/editor/plugins/elements.d.ts +2 -0
- package/dist/MarkdownEditor/editor/plugins/elements.js +4 -2
- package/dist/MarkdownEditor/editor/plugins/handlePaste.js +46 -35
- package/dist/MarkdownEditor/editor/plugins/hotKeyCommands/backspace.js +133 -133
- package/dist/MarkdownEditor/editor/plugins/hotKeyCommands/enter.js +156 -140
- package/dist/MarkdownEditor/editor/plugins/hotKeyCommands/match.d.ts +2 -1
- package/dist/MarkdownEditor/editor/plugins/hotKeyCommands/match.js +23 -4
- package/dist/MarkdownEditor/editor/plugins/hotKeyCommands/tab.js +40 -36
- package/dist/MarkdownEditor/editor/plugins/useKeyboard.js +46 -44
- package/dist/MarkdownEditor/editor/plugins/withCodeTagPlugin.js +1 -13
- package/dist/MarkdownEditor/editor/store.d.ts +15 -1
- package/dist/MarkdownEditor/editor/store.js +45 -34
- package/dist/MarkdownEditor/editor/tools/InsertAutocomplete.js +15 -11
- package/dist/MarkdownEditor/editor/utils/editorCommands.js +98 -17
- package/dist/MarkdownEditor/editor/utils/editorUtils.d.ts +11 -0
- package/dist/MarkdownEditor/editor/utils/editorUtils.js +43 -6
- package/dist/MarkdownEditor/editor/utils/keyboard.js +14 -12
- package/dist/MarkdownEditor/types.d.ts +36 -414
- package/dist/MarkdownEditor/types.js +1 -4
- package/dist/MarkdownInputField/AttachmentButton/AttachmentFileList/AttachmentFileListItem.d.ts +1 -1
- package/dist/MarkdownInputField/AttachmentButton/AttachmentFileList/AttachmentFileListItem.js +4 -5
- package/dist/MarkdownInputField/AttachmentButton/AttachmentFileList/index.d.ts +1 -1
- package/dist/MarkdownInputField/AttachmentButton/index.d.ts +1 -1
- package/dist/MarkdownInputField/MarkdownInputField.js +8 -1
- package/dist/MarkdownInputField/SendActions/index.js +7 -4
- package/dist/MarkdownInputField/SendButton/index.d.ts +6 -0
- package/dist/MarkdownInputField/SendButton/index.js +6 -0
- package/dist/MarkdownInputField/hooks/useMarkdownInputFieldHandlers.d.ts +2 -1
- package/dist/MarkdownInputField/hooks/useMarkdownInputFieldHandlers.js +12 -3
- package/dist/MarkdownInputField/hooks/useMarkdownInputFieldRefs.d.ts +1 -0
- package/dist/MarkdownInputField/hooks/useMarkdownInputFieldRefs.js +36 -5
- package/dist/MarkdownInputField/utils/renderHelpers.js +5 -0
- package/dist/MarkdownRenderer/AnimationText.d.ts +1 -5
- package/dist/MarkdownRenderer/AnimationText.js +2 -8
- package/dist/MarkdownRenderer/CharacterQueue.d.ts +0 -2
- package/dist/MarkdownRenderer/CharacterQueue.js +2 -2
- package/dist/MarkdownRenderer/FncRefForMarkdown.d.ts +24 -0
- package/dist/MarkdownRenderer/FncRefForMarkdown.js +65 -0
- package/dist/MarkdownRenderer/MarkdownRenderer.d.ts +1 -9
- package/dist/MarkdownRenderer/MarkdownRenderer.js +25 -18
- package/dist/MarkdownRenderer/StreamingCursor.d.ts +4 -0
- package/dist/MarkdownRenderer/StreamingCursor.js +20 -0
- package/dist/MarkdownRenderer/extractFootnoteDefinitions.d.ts +13 -0
- package/dist/MarkdownRenderer/extractFootnoteDefinitions.js +40 -0
- package/dist/MarkdownRenderer/markdownReactShared.d.ts +11 -38
- package/dist/MarkdownRenderer/markdownReactShared.js +28 -54
- package/dist/MarkdownRenderer/renderers/ChartRenderer.js +9 -1
- package/dist/MarkdownRenderer/renderers/CodeRenderer.d.ts +4 -1
- package/dist/MarkdownRenderer/renderers/CodeRenderer.js +27 -3
- package/dist/MarkdownRenderer/renderers/SchemaRenderer.d.ts +2 -0
- package/dist/MarkdownRenderer/renderers/SchemaRenderer.js +33 -5
- package/dist/MarkdownRenderer/streaming/MarkdownBlockPiece.d.ts +1 -3
- package/dist/MarkdownRenderer/streaming/MarkdownBlockPiece.js +16 -28
- package/dist/MarkdownRenderer/streaming/useStreamingMarkdownReact.js +2 -1
- package/dist/MarkdownRenderer/style.js +18 -0
- package/dist/MarkdownRenderer/types.d.ts +17 -93
- package/dist/MarkdownRenderer/useMarkdownToReact.js +1 -1
- package/dist/MarkdownRenderer/useStreaming.d.ts +1 -10
- package/dist/MarkdownRenderer/useStreaming.js +5 -13
- package/dist/Plugins/mermaid/MermaidRendererImpl.js +481 -7
- package/dist/Plugins/mermaid/style.js +71 -22
- package/dist/Plugins/mermaid/useMermaidRender.d.ts +2 -1
- package/dist/Plugins/mermaid/useMermaidRender.js +41 -13
- package/dist/Plugins/mermaid/utils.d.ts +16 -0
- package/dist/Plugins/mermaid/utils.js +197 -5
- package/dist/ThoughtChainList/MarkdownEditor.d.ts +1 -35
- package/dist/ThoughtChainList/MarkdownEditor.js +5 -44
- package/dist/Workspace/Browser/index.js +19 -1
- package/dist/Workspace/RealtimeFollow/index.d.ts +3 -0
- package/dist/Workspace/RealtimeFollow/index.js +5 -3
- package/package.json +8 -7
package/dist/MarkdownInputField/AttachmentButton/AttachmentFileList/AttachmentFileListItem.js
CHANGED
|
@@ -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
|
-
|
|
405
|
-
|
|
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
|
-
|
|
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,
|
|
77
|
+
var _markdownEditorRef_current_markdownEditorRef, _markdownEditorRef_current, _markdownEditorRef_current_store, _markdownEditorRef_current1;
|
|
66
78
|
if (!markdownEditorRef.current) return;
|
|
67
|
-
|
|
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];
|
|
@@ -126,13 +126,13 @@ var DEFAULT_BACKGROUND_BATCH_MULTIPLIER = 10;
|
|
|
126
126
|
}
|
|
127
127
|
},
|
|
128
128
|
{
|
|
129
|
-
|
|
129
|
+
key: "getDisplayedLength",
|
|
130
130
|
value: function getDisplayedLength() {
|
|
131
131
|
return this.displayedLength;
|
|
132
132
|
}
|
|
133
133
|
},
|
|
134
134
|
{
|
|
135
|
-
|
|
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
|
-
|
|
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(
|
|
347
|
-
return /*#__PURE__*/ React.createElement(DefaultCodeRouter, _object_spread_props(_object_spread({},
|
|
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,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 };
|