@ant-design/agentic-ui 2.29.52 → 2.29.54

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 (37) hide show
  1. package/dist/Hooks/useElementSize.js +0 -1
  2. package/dist/MarkdownEditor/editor/utils/dom.js +9 -1
  3. package/dist/MarkdownEditor/editor/utils/media.js +17 -7
  4. package/dist/MarkdownInputField/AttachmentButton/AttachmentButtonPopover.js +4 -1
  5. package/dist/MarkdownInputField/AttachmentButton/AttachmentFileList/AttachmentFileIcon.d.ts +6 -0
  6. package/dist/MarkdownInputField/AttachmentButton/AttachmentFileList/AttachmentFileIcon.js +56 -2
  7. package/dist/MarkdownInputField/AttachmentButton/AttachmentFileList/AttachmentFileListItem.js +24 -3
  8. package/dist/MarkdownInputField/AttachmentButton/AttachmentFileList/index.d.ts +2 -0
  9. package/dist/MarkdownInputField/AttachmentButton/AttachmentFileList/index.js +3 -2
  10. package/dist/MarkdownInputField/AttachmentButton/AttachmentFileList/style.js +12 -5
  11. package/dist/MarkdownInputField/AttachmentButton/types.d.ts +1 -0
  12. package/dist/MarkdownInputField/AttachmentButton/utils.d.ts +8 -0
  13. package/dist/MarkdownInputField/AttachmentButton/utils.js +7 -1
  14. package/dist/MarkdownInputField/FileMapView/FileMapViewItem.js +22 -3
  15. package/dist/MarkdownInputField/FileMapView/index.js +13 -0
  16. package/dist/MarkdownInputField/FileMapView/style.js +22 -14
  17. package/dist/MarkdownInputField/MarkdownInputField.js +21 -13
  18. package/dist/MarkdownInputField/QuickActions/index.js +3 -1
  19. package/dist/MarkdownInputField/SendActions/index.js +5 -2
  20. package/dist/MarkdownInputField/hooks/useMarkdownInputFieldHandlers.js +2 -1
  21. package/dist/MarkdownInputField/hooks/useMarkdownInputFieldStyles.d.ts +2 -2
  22. package/dist/MarkdownInputField/hooks/useMarkdownInputFieldStyles.js +3 -3
  23. package/dist/MarkdownInputField/testIds.d.ts +28 -0
  24. package/dist/MarkdownInputField/testIds.js +16 -0
  25. package/dist/MarkdownInputField/types/MarkdownInputFieldProps.d.ts +5 -0
  26. package/dist/MarkdownInputField/utils/renderHelpers.js +3 -1
  27. package/dist/Plugins/chart/ChartStatistic/index.d.ts +32 -5
  28. package/dist/Plugins/chart/ChartStatistic/index.js +35 -74
  29. package/dist/Plugins/chart/ChartStatistic/style.js +20 -2
  30. package/dist/Plugins/chart/index.d.ts +1 -1
  31. package/dist/ToolUseBarThink/index.js +6 -3
  32. package/dist/ToolUseBarThink/style.js +1 -0
  33. package/dist/Workspace/RealtimeFollow/index.d.ts +4 -0
  34. package/dist/Workspace/RealtimeFollow/index.js +2 -2
  35. package/dist/index.d.ts +1 -0
  36. package/dist/index.js +1 -0
  37. package/package.json +1 -1
@@ -54,7 +54,6 @@ export var useElementSize = function useElementSize(element) {
54
54
  if (!element.current) return;
55
55
  var resizeObserver = new ResizeObserver(function(entries) {
56
56
  var entry = entries[0];
57
- console.log(entry);
58
57
  setSize({
59
58
  width: entry.borderBoxSize[0].inlineSize,
60
59
  height: entry.borderBoxSize[0].blockSize
@@ -69,7 +69,15 @@ var rSpecial = /[\s~`!@#$%^&*()\-_+=[\]{}|\\;:"'<>,.?/]+/g;
69
69
  if (alt.startsWith('attachment:')) return 'attachment';
70
70
  }
71
71
  name = name || '';
72
- if (name === null || name === void 0 ? void 0 : (_name_startsWith = name.startsWith) === null || _name_startsWith === void 0 ? void 0 : _name_startsWith.call(name, 'data:')) return 'image';
72
+ if (name === null || name === void 0 ? void 0 : (_name_startsWith = name.startsWith) === null || _name_startsWith === void 0 ? void 0 : _name_startsWith.call(name, 'data:')) {
73
+ var _mimeMatch_;
74
+ var mimeMatch = name.match(/^data:([^/]+)\/[^;]+/);
75
+ var mainType = mimeMatch === null || mimeMatch === void 0 ? void 0 : (_mimeMatch_ = mimeMatch[1]) === null || _mimeMatch_ === void 0 ? void 0 : _mimeMatch_.toLowerCase();
76
+ if (mainType === 'image') return 'image';
77
+ if (mainType === 'video') return 'video';
78
+ if (mainType === 'audio') return 'audio';
79
+ return 'other';
80
+ }
73
81
  var originName = name.split('?')[0];
74
82
  var ext = (_originName_toLowerCase_match = originName.toLowerCase().match(/\.\w+$/)) === null || _originName_toLowerCase_match === void 0 ? void 0 : _originName_toLowerCase_match[0];
75
83
  if (!ext && originName !== name) return 'image';
@@ -156,7 +156,7 @@ import { ReactEditor } from "slate-react";
156
156
  import { getMediaType } from "./dom";
157
157
  export var getRemoteMediaType = function getRemoteMediaType(url) {
158
158
  return _async_to_generator(function() {
159
- var m, type, contentType, controller, res, e;
159
+ var _mimeMatch_, mimeMatch, mainType, type, contentType, controller, res, e;
160
160
  return _ts_generator(this, function(_state) {
161
161
  switch(_state.label){
162
162
  case 0:
@@ -169,10 +169,20 @@ export var getRemoteMediaType = function getRemoteMediaType(url) {
169
169
  'other'
170
170
  ];
171
171
  if (url.startsWith('data:')) {
172
- m = url.match(/data:image\/(\w+);base64,(.*)/);
173
- if (m) return [
172
+ ;
173
+ mimeMatch = url.match(/^data:([^/]+)\/[^;]+/);
174
+ mainType = mimeMatch === null || mimeMatch === void 0 ? void 0 : (_mimeMatch_ = mimeMatch[1]) === null || _mimeMatch_ === void 0 ? void 0 : _mimeMatch_.toLowerCase();
175
+ if (mainType === 'image') return [
176
+ 2,
177
+ 'image'
178
+ ];
179
+ if (mainType === 'video') return [
180
+ 2,
181
+ 'video'
182
+ ];
183
+ if (mainType === 'audio') return [
174
184
  2,
175
- m[1]
185
+ 'audio'
176
186
  ];
177
187
  return [
178
188
  2,
@@ -230,7 +240,7 @@ export var getRemoteMediaType = function getRemoteMediaType(url) {
230
240
  };
231
241
  export var convertRemoteImages = function convertRemoteImages(node, store) {
232
242
  return _async_to_generator(function() {
233
- var _store_editor, schema, stack, _item_children, item, _item_url, _item_url1, ext, m, _stack;
243
+ var _store_editor, schema, stack, _item_children, item, _item_url, _item_url1, ext, dataUrlType, _stack;
234
244
  return _ts_generator(this, function(_state) {
235
245
  schema = (store === null || store === void 0 ? void 0 : (_store_editor = store.editor) === null || _store_editor === void 0 ? void 0 : _store_editor.children) || [];
236
246
  if (schema) {
@@ -254,8 +264,8 @@ export var convertRemoteImages = function convertRemoteImages(node, store) {
254
264
  }
255
265
  }
256
266
  } else if (item === null || item === void 0 ? void 0 : (_item_url1 = item.url) === null || _item_url1 === void 0 ? void 0 : _item_url1.startsWith('data:')) {
257
- m = item === null || item === void 0 ? void 0 : item.url.match(/data:image\/(\w+);base64,(.*)/);
258
- if (m) {
267
+ dataUrlType = getMediaType(item === null || item === void 0 ? void 0 : item.url);
268
+ if (dataUrlType === 'image' || dataUrlType === 'video' || dataUrlType === 'audio') {
259
269
  try {
260
270
  Transforms.setNodes(store === null || store === void 0 ? void 0 : store.editor, {
261
271
  url: item === null || item === void 0 ? void 0 : item.url
@@ -97,7 +97,10 @@ export var SupportedFileFormats = {
97
97
  'jpg',
98
98
  'jpeg',
99
99
  'png',
100
- 'gif'
100
+ 'gif',
101
+ 'bmp',
102
+ 'webp',
103
+ 'svg'
101
104
  ]
102
105
  },
103
106
  document: {
@@ -1,5 +1,11 @@
1
1
  import React from 'react';
2
2
  import { AttachmentFile } from '../types';
3
+ /** 无 url/previewUrl 时展示文件大小与格式的占位块(内容未拿到) */
4
+ export declare const FileMetaPlaceholder: React.FC<{
5
+ file: AttachmentFile;
6
+ className?: string;
7
+ style?: React.CSSProperties;
8
+ }>;
3
9
  export declare const AttachmentFileIcon: React.FC<{
4
10
  file: AttachmentFile;
5
11
  className: string;
@@ -97,10 +97,10 @@ function _unsupported_iterable_to_array(o, minLen) {
97
97
  if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
98
98
  }
99
99
  import { Eye, FileFailed, FileUploadingSpin, Play } from "@sofa-design/icons";
100
- import { Image } from "antd";
100
+ import { Image, Tooltip } from "antd";
101
101
  import React, { useEffect, useState } from "react";
102
102
  import { getFileTypeIcon } from "../../../Workspace/File/utils";
103
- import { isImageFile, isVideoFile } from "../utils";
103
+ import { isImageFile, isVideoFile, kbToSize } from "../utils";
104
104
  var VideoThumbnail = function VideoThumbnail(param) {
105
105
  var src = param.src, className = param.className, style = param.style;
106
106
  return /*#__PURE__*/ React.createElement("div", {
@@ -200,6 +200,60 @@ var VideoThumbnail = function VideoThumbnail(param) {
200
200
  height: '40px',
201
201
  overflow: 'hidden'
202
202
  };
203
+ /** 无 url/previewUrl 时展示文件大小与格式的占位块(内容未拿到) */ export var FileMetaPlaceholder = function FileMetaPlaceholder(param) {
204
+ var file = param.file, className = param.className, style = param.style;
205
+ var _ref, _file_size, _ref1, _ref2, _rawFormat_split_pop;
206
+ var _file_uploadResponse, _file_uploadResponse1;
207
+ var sizeBytes = (_ref = (_file_size = file.size) !== null && _file_size !== void 0 ? _file_size : (_file_uploadResponse = file.uploadResponse) === null || _file_uploadResponse === void 0 ? void 0 : _file_uploadResponse.fileSize) !== null && _ref !== void 0 ? _ref : 0;
208
+ var sizeText = sizeBytes > 0 ? kbToSize(sizeBytes / 1024) : '';
209
+ var extFromName = file.name ? file.name.split('.').pop() || '' : '';
210
+ var rawFormat = (_ref1 = (_ref2 = (_file_uploadResponse1 = file.uploadResponse) === null || _file_uploadResponse1 === void 0 ? void 0 : _file_uploadResponse1.fileType) !== null && _ref2 !== void 0 ? _ref2 : file.type) !== null && _ref1 !== void 0 ? _ref1 : extFromName;
211
+ var formatSuffix = rawFormat.includes('/') ? ((_rawFormat_split_pop = rawFormat.split('/').pop()) !== null && _rawFormat_split_pop !== void 0 ? _rawFormat_split_pop : '').toUpperCase() : rawFormat.toUpperCase();
212
+ var formatText = formatSuffix || '-';
213
+ return /*#__PURE__*/ React.createElement(Tooltip, {
214
+ title: file.name
215
+ }, /*#__PURE__*/ React.createElement("div", {
216
+ className: className,
217
+ style: _object_spread({
218
+ height: 48,
219
+ boxSizing: 'border-box',
220
+ display: 'flex',
221
+ justifyContent: 'center',
222
+ borderRadius: 'var(--radius-base, 4px)',
223
+ background: 'var(--color-fill-quaternary, rgba(0,0,0,0.04))',
224
+ fontSize: 10,
225
+ color: 'var(--color-text-tertiary, rgba(0,0,0,0.45))',
226
+ lineHeight: 1.2,
227
+ overflow: 'hidden',
228
+ flex: 1,
229
+ minWidth: 80,
230
+ padding: 'var(--padding-1x) var(--padding-2x)',
231
+ flexDirection: 'column'
232
+ }, style)
233
+ }, formatText && /*#__PURE__*/ React.createElement("span", {
234
+ style: {
235
+ lineClamp: 1,
236
+ lineHeight: '20px',
237
+ height: '20px',
238
+ boxSizing: 'border-box',
239
+ overflow: 'hidden',
240
+ textOverflow: 'ellipsis',
241
+ minWidth: 0,
242
+ maxWidth: '100%'
243
+ }
244
+ }, formatText), sizeText && /*#__PURE__*/ React.createElement("span", {
245
+ style: {
246
+ lineClamp: 1,
247
+ overflow: 'hidden',
248
+ textOverflow: 'ellipsis',
249
+ minWidth: 0,
250
+ boxSizing: 'border-box',
251
+ lineHeight: '20px',
252
+ height: '20px',
253
+ maxWidth: '100%'
254
+ }
255
+ }, sizeText)));
256
+ };
203
257
  var IMAGE_PREVIEW_CONFIG = {
204
258
  mask: /*#__PURE__*/ React.createElement("div", null, /*#__PURE__*/ React.createElement(Eye, null)),
205
259
  visible: false
@@ -1,11 +1,24 @@
1
+ function _define_property(obj, key, value) {
2
+ if (key in obj) {
3
+ Object.defineProperty(obj, key, {
4
+ value: value,
5
+ enumerable: true,
6
+ configurable: true,
7
+ writable: true
8
+ });
9
+ } else {
10
+ obj[key] = value;
11
+ }
12
+ return obj;
13
+ }
1
14
  import { FileFailed, FileUploadingSpin, X } from "@sofa-design/icons";
2
15
  import { Tooltip } from "antd";
3
16
  import classNames from "clsx";
4
17
  import { motion } from "framer-motion";
5
18
  import React, { useContext } from "react";
6
19
  import { I18nContext } from "../../../I18n";
7
- import { kbToSize } from "../utils";
8
- import { AttachmentFileIcon } from "./AttachmentFileIcon";
20
+ import { isFileMetaPlaceholderState, kbToSize } from "../utils";
21
+ import { AttachmentFileIcon, FileMetaPlaceholder } from "./AttachmentFileIcon";
9
22
  var getFileNameWithoutExtension = function getFileNameWithoutExtension(fileName) {
10
23
  return fileName.split('.').slice(0, -1).join('.');
11
24
  };
@@ -105,13 +118,21 @@ export var AttachmentFileListItem = function AttachmentFileListItem(param) {
105
118
  e.stopPropagation();
106
119
  onDelete(file);
107
120
  };
121
+ // 有 status 但无 url/previewUrl:文件内容未拿到,展示大小与格式占位块
122
+ if (file.status !== undefined && file.status !== null && !file.url && !file.previewUrl) {
123
+ return /*#__PURE__*/ React.createElement(FileMetaPlaceholder, {
124
+ file: file,
125
+ className: className
126
+ });
127
+ }
108
128
  return /*#__PURE__*/ React.createElement(Tooltip, {
109
129
  title: (locale === null || locale === void 0 ? void 0 : locale.clickToRetry) || '点击重试',
110
130
  open: isErrorStatus ? undefined : false
111
131
  }, /*#__PURE__*/ React.createElement(motion.div, {
112
132
  variants: ANIMATION_VARIANTS,
113
133
  onClick: handleFileClick,
114
- className: className,
134
+ className: classNames(className, _define_property({}, "".concat(prefixCls, "-meta-placeholder"), isFileMetaPlaceholderState(file))),
135
+ "data-testid": "file-item",
115
136
  exit: ANIMATION_VARIANTS.exit
116
137
  }, /*#__PURE__*/ React.createElement(FileIcon, {
117
138
  file: file,
@@ -7,5 +7,7 @@ export type AttachmentFileListProps = {
7
7
  onDownload?: (file: AttachmentFile) => void;
8
8
  onRetry?: (file: AttachmentFile) => void;
9
9
  onClearFileMap?: () => void;
10
+ /** E2E 测试 ID */
11
+ dataTestId?: string;
10
12
  };
11
13
  export declare const AttachmentFileList: React.FC<AttachmentFileListProps>;
@@ -110,7 +110,7 @@ var ClearButton = function ClearButton(param) {
110
110
  }, /*#__PURE__*/ React.createElement(X, null));
111
111
  };
112
112
  export var AttachmentFileList = function AttachmentFileList(param) {
113
- var fileMap = param.fileMap, onDelete = param.onDelete, onPreview = param.onPreview, onDownload = param.onDownload, onRetry = param.onRetry, onClearFileMap = param.onClearFileMap;
113
+ var fileMap = param.fileMap, onDelete = param.onDelete, onPreview = param.onPreview, onDownload = param.onDownload, onRetry = param.onRetry, onClearFileMap = param.onClearFileMap, dataTestId = param.dataTestId;
114
114
  var context = useContext(ConfigProvider.ConfigContext);
115
115
  var prefix = context === null || context === void 0 ? void 0 : context.getPrefixCls('agentic-md-editor-attachment-list');
116
116
  var _useStyle = useStyle(prefix), wrapSSR = _useStyle.wrapSSR, hashId = _useStyle.hashId;
@@ -139,7 +139,8 @@ export var AttachmentFileList = function AttachmentFileList(param) {
139
139
  if (!visible) setImgSrc(undefined);
140
140
  };
141
141
  return wrapSSR(/*#__PURE__*/ React.createElement("div", {
142
- className: classNames("".concat(prefix, "-container"), hashId, _define_property({}, "".concat(prefix, "-container-empty"), !hasFiles))
142
+ className: classNames("".concat(prefix, "-container"), hashId, _define_property({}, "".concat(prefix, "-container-empty"), !hasFiles)),
143
+ "data-testid": dataTestId
143
144
  }, /*#__PURE__*/ React.createElement(motion.div, {
144
145
  variants: ANIMATION_VARIANTS,
145
146
  whileInView: "visible",
@@ -52,8 +52,8 @@ function _object_spread_props(target, source) {
52
52
  }
53
53
  import { resetComponent, useEditorStyleRegister } from "../../../Hooks/useStyle";
54
54
  var genStyle = function genStyle(token) {
55
- var _obj;
56
- return _obj = {}, _define_property(_obj, "".concat(token.componentCls), {
55
+ var _obj, _obj1;
56
+ return _obj1 = {}, _define_property(_obj1, "".concat(token.componentCls), {
57
57
  maxWidth: '100%',
58
58
  display: 'flex',
59
59
  flexDirection: 'row',
@@ -251,15 +251,22 @@ var genStyle = function genStyle(token) {
251
251
  fontSize: '40px',
252
252
  display: 'flex'
253
253
  }
254
- }
255
- }), _define_property(_obj, "".concat(token.componentCls, "-container"), {
254
+ },
255
+ '&-item-meta-placeholder': (_obj = {
256
+ background: 'var(--color-fill-quaternary, rgba(0,0,0,0.04))'
257
+ }, _define_property(_obj, "".concat(token.componentCls, "-item-file-name-text"), {
258
+ color: 'var(--color-text-tertiary, rgba(0,0,0,0.45))'
259
+ }), _define_property(_obj, "".concat(token.componentCls, "-item-file-size"), {
260
+ color: 'var(--color-text-tertiary, rgba(0,0,0,0.45))'
261
+ }), _obj)
262
+ }), _define_property(_obj1, "".concat(token.componentCls, "-container"), {
256
263
  position: 'relative',
257
264
  background: 'var(--color-gray-bg-page)',
258
265
  borderBottom: '1px solid rgba(0, 16, 64, 0.0627)',
259
266
  '&-empty': {
260
267
  border: 'none'
261
268
  }
262
- }), _obj;
269
+ }), _obj1;
263
270
  };
264
271
  /**
265
272
  * @param prefixCls
@@ -15,6 +15,7 @@ export type AttachmentFile = File & {
15
15
  url?: string;
16
16
  status?: 'error' | 'uploading' | 'done';
17
17
  uuid?: string;
18
+ size?: number | null;
18
19
  previewUrl?: string;
19
20
  /** 上传响应数据(使用 uploadWithResponse 时会填充此字段) */
20
21
  uploadResponse?: UploadResponse;
@@ -37,6 +37,14 @@ export declare const isVideoFile: (file: File) => boolean;
37
37
  * 检查文件是否为可展示的媒体类型(图片或视频)
38
38
  */
39
39
  export declare const isMediaFile: (file: File) => boolean;
40
+ /**
41
+ * 是否为「仅元信息占位」状态:有 status 但无 url/previewUrl,内容未拿到时整行以 FileMetaPlaceholder 风格展示
42
+ */
43
+ export declare const isFileMetaPlaceholderState: (file: File & {
44
+ status?: string;
45
+ url?: string;
46
+ previewUrl?: string;
47
+ }) => boolean;
40
48
  /**
41
49
  * 获取设备品牌
42
50
  *
@@ -42,8 +42,9 @@
42
42
  * @param {File} file - 要检查的文件
43
43
  * @returns {boolean} 是否为图片文件
44
44
  */ export var isImageFile = function isImageFile(file) {
45
+ var _file_type;
45
46
  // 首先检查 MIME 类型
46
- if (file.type.startsWith('image/')) {
47
+ if (file === null || file === void 0 ? void 0 : (_file_type = file.type) === null || _file_type === void 0 ? void 0 : _file_type.startsWith('image/')) {
47
48
  return true;
48
49
  }
49
50
  // 如果 MIME 类型不可用或不准确,检查文件扩展名
@@ -106,6 +107,11 @@ var hasVideoExtension = function hasVideoExtension(pathOrName) {
106
107
  */ export var isMediaFile = function isMediaFile(file) {
107
108
  return isImageFile(file) || isVideoFile(file);
108
109
  };
110
+ /**
111
+ * 是否为「仅元信息占位」状态:有 status 但无 url/previewUrl,内容未拿到时整行以 FileMetaPlaceholder 风格展示
112
+ */ export var isFileMetaPlaceholderState = function isFileMetaPlaceholderState(file) {
113
+ return file.status !== undefined && file.status !== null && !file.url && !file.previewUrl;
114
+ };
109
115
  /**
110
116
  * 设备品牌匹配列表
111
117
  */ var UA_MATCH_LIST = [
@@ -6,6 +6,19 @@ function _array_like_to_array(arr, len) {
6
6
  function _array_with_holes(arr) {
7
7
  if (Array.isArray(arr)) return arr;
8
8
  }
9
+ function _define_property(obj, key, value) {
10
+ if (key in obj) {
11
+ Object.defineProperty(obj, key, {
12
+ value: value,
13
+ enumerable: true,
14
+ configurable: true,
15
+ writable: true
16
+ });
17
+ } else {
18
+ obj[key] = value;
19
+ }
20
+ return obj;
21
+ }
9
22
  function _iterable_to_array_limit(arr, i) {
10
23
  var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];
11
24
  if (_i == null) return;
@@ -52,8 +65,8 @@ import { motion } from "framer-motion";
52
65
  import React, { useContext } from "react";
53
66
  import { ActionIconBox } from "../../Components/ActionIconBox";
54
67
  import { I18nContext } from "../../I18n";
55
- import { AttachmentFileIcon } from "../AttachmentButton/AttachmentFileList/AttachmentFileIcon";
56
- import { kbToSize } from "../AttachmentButton/utils";
68
+ import { AttachmentFileIcon, FileMetaPlaceholder } from "../AttachmentButton/AttachmentFileList/AttachmentFileIcon";
69
+ import { isFileMetaPlaceholderState, kbToSize } from "../AttachmentButton/utils";
57
70
  /**
58
71
  * FileMapViewItem 组件 - 文件映射视图项组件
59
72
  *
@@ -104,6 +117,12 @@ import { kbToSize } from "../AttachmentButton/utils";
104
117
  var lastDotIndex = fileName.lastIndexOf('.');
105
118
  var displayName = lastDotIndex > 0 ? fileName.slice(0, lastDotIndex) : fileName;
106
119
  var displayExtension = lastDotIndex > 0 && lastDotIndex < fileName.length - 1 ? fileName.slice(lastDotIndex + 1) : '';
120
+ // 有 status 但无 url/previewUrl:文件内容未拿到,展示大小与格式占位块
121
+ if (file.status !== undefined && file.status !== null && !file.url && !file.previewUrl) {
122
+ return /*#__PURE__*/ React.createElement(FileMetaPlaceholder, {
123
+ file: file
124
+ });
125
+ }
107
126
  return /*#__PURE__*/ React.createElement(Tooltip, {
108
127
  title: /*#__PURE__*/ React.createElement("div", null, locale === null || locale === void 0 ? void 0 : locale.clickToPreview),
109
128
  placement: "topLeft",
@@ -140,7 +159,7 @@ import { kbToSize } from "../AttachmentButton/utils";
140
159
  opacity: 0,
141
160
  x: -20
142
161
  },
143
- className: props.className,
162
+ className: classNames(props.className, _define_property({}, "".concat(props.prefixCls, "-meta-placeholder"), isFileMetaPlaceholderState(file))),
144
163
  "data-testid": "file-item"
145
164
  }, /*#__PURE__*/ React.createElement("div", {
146
165
  className: classNames("".concat(props.prefixCls, "-file-icon"), props.hashId)
@@ -190,6 +190,7 @@ import { ConfigProvider, Image, Modal } from "antd";
190
190
  import classNames from "clsx";
191
191
  import { motion } from "framer-motion";
192
192
  import React, { useContext, useMemo, useState } from "react";
193
+ import { FileMetaPlaceholder } from "../AttachmentButton/AttachmentFileList/AttachmentFileIcon";
193
194
  import { isImageFile, isVideoFile } from "../AttachmentButton/utils";
194
195
  import { FileMapViewItem } from "./FileMapViewItem";
195
196
  import { useStyle } from "./style";
@@ -365,6 +366,12 @@ import { useStyle } from "./style";
365
366
  style: props.style,
366
367
  className: classNames(prefix, hashId, props.className, "".concat(prefix, "-").concat(placement), (_obj = {}, _define_property(_obj, "".concat(prefix, "-image-list-view"), imgList.length > 1), _define_property(_obj, "".concat(prefix, "-image-list-view-").concat(placement), imgList.length > 1), _obj))
367
368
  }, /*#__PURE__*/ React.createElement(Image.PreviewGroup, null, imgList.map(function(file, index) {
369
+ if (file.status !== undefined && file.status !== null && !file.url && !file.previewUrl) {
370
+ return /*#__PURE__*/ React.createElement(FileMetaPlaceholder, {
371
+ file: file,
372
+ key: file.uuid || file.name || index
373
+ });
374
+ }
368
375
  return /*#__PURE__*/ React.createElement(Image, {
369
376
  rootClassName: classNames("".concat(prefix, "-image"), hashId),
370
377
  width: 124,
@@ -396,6 +403,12 @@ import { useStyle } from "./style";
396
403
  width: 124,
397
404
  height: 124
398
405
  };
406
+ if (file.status !== undefined && file.status !== null && !file.url && !file.previewUrl) {
407
+ return /*#__PURE__*/ React.createElement(FileMetaPlaceholder, {
408
+ file: file,
409
+ key: file.uuid || file.name || index
410
+ });
411
+ }
399
412
  return /*#__PURE__*/ React.createElement("div", {
400
413
  role: "button",
401
414
  tabIndex: 0,
@@ -52,8 +52,8 @@ function _object_spread_props(target, source) {
52
52
  }
53
53
  import { resetComponent, useEditorStyleRegister } from "../../Hooks/useStyle";
54
54
  var genStyle = function genStyle(token) {
55
- var _obj;
56
- return _define_property({}, "".concat(token.componentCls), (_obj = {
55
+ var _obj, _obj1;
56
+ return _define_property({}, "".concat(token.componentCls), (_obj1 = {
57
57
  maxWidth: '100%',
58
58
  display: 'flex',
59
59
  minWidth: '0px',
@@ -112,11 +112,11 @@ var genStyle = function genStyle(token) {
112
112
  }
113
113
  }
114
114
  }
115
- }, _define_property(_obj, "".concat(token.antCls, "-image-mask"), {
115
+ }, _define_property(_obj1, "".concat(token.antCls, "-image-mask"), {
116
116
  borderRadius: 'var(--radius-card-base)'
117
- }), _define_property(_obj, "img", {
117
+ }), _define_property(_obj1, "img", {
118
118
  objectFit: 'cover'
119
- }), _define_property(_obj, '&-image', {
119
+ }), _define_property(_obj1, '&-image', {
120
120
  opacity: 1,
121
121
  background: 'var(--color-gray-bg-card-white)',
122
122
  boxSizing: 'border-box',
@@ -137,7 +137,7 @@ var genStyle = function genStyle(token) {
137
137
  transition: 'transform 0.3s'
138
138
  }
139
139
  }
140
- }), _define_property(_obj, '&-video-row', {
140
+ }), _define_property(_obj1, '&-video-row', {
141
141
  display: 'flex',
142
142
  flexWrap: 'wrap',
143
143
  gap: 8,
@@ -145,7 +145,7 @@ var genStyle = function genStyle(token) {
145
145
  '&-right': {
146
146
  alignSelf: 'flex-end'
147
147
  }
148
- }), _define_property(_obj, '&-video-thumb', {
148
+ }), _define_property(_obj1, '&-video-thumb', {
149
149
  position: 'relative',
150
150
  cursor: 'pointer',
151
151
  opacity: 1,
@@ -167,7 +167,7 @@ var genStyle = function genStyle(token) {
167
167
  '& video': {
168
168
  transition: 'transform 0.3s'
169
169
  }
170
- }), _define_property(_obj, '&-video-play-overlay', {
170
+ }), _define_property(_obj1, '&-video-play-overlay', {
171
171
  position: 'absolute',
172
172
  inset: 0,
173
173
  display: 'flex',
@@ -182,11 +182,11 @@ var genStyle = function genStyle(token) {
182
182
  height: 48,
183
183
  color: '#fff'
184
184
  }
185
- }), _define_property(_obj, '&-image-list-view', {
185
+ }), _define_property(_obj1, '&-image-list-view', {
186
186
  background: 'var(--color-gray-bg-tip)',
187
187
  padding: '4px',
188
188
  borderRadius: 'var(--radius-card-base)'
189
- }), _define_property(_obj, '&-more-file-container', {
189
+ }), _define_property(_obj1, '&-more-file-container', {
190
190
  width: '285px',
191
191
  height: '56px',
192
192
  borderRadius: 'var(--radius-card-base)',
@@ -201,13 +201,13 @@ var genStyle = function genStyle(token) {
201
201
  '&:hover': {
202
202
  boxShadow: 'var(--shadow-control-lg)'
203
203
  }
204
- }), _define_property(_obj, '&-more-file-icon', {
204
+ }), _define_property(_obj1, '&-more-file-icon', {
205
205
  width: '16px',
206
206
  height: '16px'
207
- }), _define_property(_obj, '&-more-file-name', {
207
+ }), _define_property(_obj1, '&-more-file-name', {
208
208
  font: 'var(--font-size-h6)',
209
209
  color: 'var(--color-gray-text-secondary)'
210
- }), _define_property(_obj, '&-item', {
210
+ }), _define_property(_obj1, '&-item', {
211
211
  width: '285px',
212
212
  height: '56px',
213
213
  borderRadius: 'var(--radius-card-base)',
@@ -333,7 +333,15 @@ var genStyle = function genStyle(token) {
333
333
  color: 'var(--color-gray-text-light)',
334
334
  fontSize: '12px'
335
335
  }
336
- }), _obj));
336
+ }), _define_property(_obj1, '&-item-meta-placeholder', (_obj = {
337
+ background: 'var(--color-fill-quaternary, rgba(0,0,0,0.04))'
338
+ }, _define_property(_obj, "".concat(token.componentCls, "-item-file-name-text"), {
339
+ color: 'var(--color-text-tertiary, rgba(0,0,0,0.45))'
340
+ }), _define_property(_obj, "".concat(token.componentCls, "-item-file-size"), {
341
+ color: 'var(--color-text-tertiary, rgba(0,0,0,0.45))'
342
+ }), _define_property(_obj, "".concat(token.componentCls, "-item-file-name-extension-container"), {
343
+ color: 'var(--color-text-tertiary, rgba(0,0,0,0.45))'
344
+ }), _obj)), _obj1));
337
345
  };
338
346
  /**
339
347
  * Probubble
@@ -148,6 +148,7 @@ import { QuickActions } from "./QuickActions";
148
148
  import { SkillModeBar } from "./SkillModeBar";
149
149
  import { useStyle } from "./style";
150
150
  import { Suggestion } from "./Suggestion";
151
+ import { MARKDOWN_INPUT_FIELD_TEST_IDS } from "./testIds";
151
152
  import TopOperatingArea from "./TopOperatingArea";
152
153
  import { useAttachmentList, useBeforeTools, useSendActionsNode } from "./utils/renderHelpers";
153
154
  import { useVoiceInputManager } from "./VoiceInputManager";
@@ -196,16 +197,17 @@ import { useVoiceInputManager } from "./VoiceInputManager";
196
197
  enable: false
197
198
  };
198
199
  var MarkdownInputFieldComponent = function MarkdownInputFieldComponent(_0) {
199
- var tagInputProps = _0.tagInputProps, markdownProps = _0.markdownProps, _0_borderRadius = _0.borderRadius, borderRadius = _0_borderRadius === void 0 ? 16 : _0_borderRadius, onBlur = _0.onBlur, onFocus = _0.onFocus, _0_isShowTopOperatingArea = _0.isShowTopOperatingArea, isShowTopOperatingArea = _0_isShowTopOperatingArea === void 0 ? false : _0_isShowTopOperatingArea, props = _object_without_properties(_0, [
200
+ var tagInputProps = _0.tagInputProps, markdownProps = _0.markdownProps, _0_borderRadius = _0.borderRadius, borderRadius = _0_borderRadius === void 0 ? 16 : _0_borderRadius, onBlur = _0.onBlur, onFocus = _0.onFocus, _0_isShowTopOperatingArea = _0.isShowTopOperatingArea, isShowTopOperatingArea = _0_isShowTopOperatingArea === void 0 ? false : _0_isShowTopOperatingArea, testId = _0.testId, props = _object_without_properties(_0, [
200
201
  "tagInputProps",
201
202
  "markdownProps",
202
203
  "borderRadius",
203
204
  "onBlur",
204
205
  "onFocus",
205
- "isShowTopOperatingArea"
206
+ "isShowTopOperatingArea",
207
+ "testId"
206
208
  ]);
207
209
  var _ref;
208
- var _props_skillMode, _props_enlargeable, _props_refinePrompt, _props_enlargeable1, _props_enlargeable2;
210
+ var _props_skillMode, _props_enlargeable, _props_refinePrompt, _props_enlargeable1, _props_enlargeable2, _props_toolsRender;
209
211
  // 默认关闭文件上传,需显式传入 attachment.enable: true 开启
210
212
  var attachment = _object_spread({}, DEFAULT_ATTACHMENT, props.attachment);
211
213
  var getPrefixCls = useContext(ConfigProvider.ConfigContext).getPrefixCls;
@@ -232,7 +234,7 @@ var MarkdownInputFieldComponent = function MarkdownInputFieldComponent(_0) {
232
234
  }), hasEnlargeAction = _useMarkdownInputFieldActions.hasEnlargeAction, hasRefineAction = _useMarkdownInputFieldActions.hasRefineAction, isMultiRowLayout = _useMarkdownInputFieldActions.isMultiRowLayout, totalActionCount = _useMarkdownInputFieldActions.totalActionCount;
233
235
  // 样式计算
234
236
  var _useMarkdownInputFieldStyles = useMarkdownInputFieldStyles({
235
- toolsRender: props.toolsRender,
237
+ hasTools: !!props.toolsRender || !!props.actionsRender,
236
238
  maxHeight: props.maxHeight,
237
239
  style: props.style,
238
240
  attachment: attachment,
@@ -334,13 +336,15 @@ var MarkdownInputFieldComponent = function MarkdownInputFieldComponent(_0) {
334
336
  });
335
337
  var _obj, _obj1;
336
338
  return wrapSSR(/*#__PURE__*/ React.createElement(React.Fragment, null, isShowTopOperatingArea && /*#__PURE__*/ React.createElement("div", {
337
- className: classNames("".concat(baseCls, "-top-area"), hashId)
339
+ className: classNames("".concat(baseCls, "-top-area"), hashId),
340
+ "data-testid": MARKDOWN_INPUT_FIELD_TEST_IDS.TOP_AREA
338
341
  }, /*#__PURE__*/ React.createElement(TopOperatingArea, {
339
342
  targetRef: props.targetRef,
340
343
  operationBtnRender: props.operationBtnRender,
341
344
  isShowBackTo: props.isShowBackTo
342
345
  })), beforeTools ? /*#__PURE__*/ React.createElement("div", {
343
- className: classNames("".concat(baseCls, "-before-tools"), hashId)
346
+ className: classNames("".concat(baseCls, "-before-tools"), hashId),
347
+ "data-testid": MARKDOWN_INPUT_FIELD_TEST_IDS.BEFORE_TOOLS
344
348
  }, beforeTools) : null, /*#__PURE__*/ React.createElement(Suggestion, {
345
349
  tagInputProps: _object_spread({
346
350
  enable: true,
@@ -348,7 +352,7 @@ var MarkdownInputFieldComponent = function MarkdownInputFieldComponent(_0) {
348
352
  }, tagInputProps)
349
353
  }, /*#__PURE__*/ React.createElement("div", {
350
354
  ref: inputRef,
351
- "data-testid": "markdown-input-field",
355
+ "data-testid": testId !== null && testId !== void 0 ? testId : MARKDOWN_INPUT_FIELD_TEST_IDS.ROOT,
352
356
  className: classNames(baseCls, hashId, props.className, (_obj = {}, _define_property(_obj, "".concat(baseCls, "-disabled"), props.disabled), _define_property(_obj, "".concat(baseCls, "-skill-mode"), (_props_skillMode = props.skillMode) === null || _props_skillMode === void 0 ? void 0 : _props_skillMode.open), _define_property(_obj, "".concat(baseCls, "-typing"), false), _define_property(_obj, "".concat(baseCls, "-loading"), isLoading), _define_property(_obj, "".concat(baseCls, "-is-multi-row"), isMultiRowLayout), _define_property(_obj, "".concat(baseCls, "-enlarged"), isEnlarged), _define_property(_obj, "".concat(baseCls, "-focused"), isFocused), _define_property(_obj, "".concat(baseCls, "-has-tools-wrapper"), !!props.toolsRender), _obj)),
353
357
  style: _object_spread_props(_object_spread({}, props.style, enlargedStyle), {
354
358
  height: isEnlarged ? "".concat((_ref = (_props_enlargeable = props.enlargeable) === null || _props_enlargeable === void 0 ? void 0 : _props_enlargeable.height) !== null && _ref !== void 0 ? _ref : 980, "px") : "min(".concat(collapsedHeightPx, "px,100%)"),
@@ -381,12 +385,14 @@ var MarkdownInputFieldComponent = function MarkdownInputFieldComponent(_0) {
381
385
  flex: 1,
382
386
  minHeight: 0
383
387
  },
384
- className: classNames("".concat(baseCls, "-editor"), hashId, (_obj1 = {}, _define_property(_obj1, "".concat(baseCls, "-editor-hover"), isHover), _define_property(_obj1, "".concat(baseCls, "-editor-disabled"), props.disabled), _obj1))
388
+ className: classNames("".concat(baseCls, "-editor"), hashId, (_obj1 = {}, _define_property(_obj1, "".concat(baseCls, "-editor-hover"), isHover), _define_property(_obj1, "".concat(baseCls, "-editor-disabled"), props.disabled), _obj1)),
389
+ "data-testid": MARKDOWN_INPUT_FIELD_TEST_IDS.EDITOR
385
390
  }, /*#__PURE__*/ React.createElement(SkillModeBar, {
386
391
  skillMode: props.skillMode,
387
392
  onSkillModeOpenChange: props.onSkillModeOpenChange
388
393
  }), /*#__PURE__*/ React.createElement("div", {
389
- className: classNames("".concat(baseCls, "-editor-content"), hashId)
394
+ className: classNames("".concat(baseCls, "-editor-content"), hashId),
395
+ "data-testid": MARKDOWN_INPUT_FIELD_TEST_IDS.EDITOR_CONTENT
390
396
  }, attachmentList, /*#__PURE__*/ React.createElement(BaseMarkdownEditor, _object_spread({
391
397
  editorRef: markdownEditorRef,
392
398
  leafRender: props.leafRender,
@@ -484,13 +490,15 @@ var MarkdownInputFieldComponent = function MarkdownInputFieldComponent(_0) {
484
490
  setTopRightPadding(width);
485
491
  setQuickRightOffset(rightOffset);
486
492
  }
487
- }) : null))), props.toolsRender ? /*#__PURE__*/ React.createElement("div", {
488
- className: classNames("".concat(baseCls, "-tools-wrapper"), hashId)
493
+ }) : null))), props.toolsRender || props.actionsRender ? /*#__PURE__*/ React.createElement("div", {
494
+ className: classNames("".concat(baseCls, "-tools-wrapper"), hashId),
495
+ "data-testid": MARKDOWN_INPUT_FIELD_TEST_IDS.TOOLS_WRAPPER
489
496
  }, /*#__PURE__*/ React.createElement("div", {
490
497
  ref: actionsRef,
491
498
  contentEditable: false,
492
- className: classNames("".concat(baseCls, "-send-tools"), hashId)
493
- }, props.toolsRender(_object_spread_props(_object_spread({
499
+ className: classNames("".concat(baseCls, "-send-tools"), hashId),
500
+ "data-testid": MARKDOWN_INPUT_FIELD_TEST_IDS.SEND_TOOLS
501
+ }, props === null || props === void 0 ? void 0 : (_props_toolsRender = props.toolsRender) === null || _props_toolsRender === void 0 ? void 0 : _props_toolsRender.call(props, _object_spread_props(_object_spread({
494
502
  value: value,
495
503
  fileMap: fileMap,
496
504
  onFileMapChange: setFileMap,
@@ -203,6 +203,7 @@ import React, { useState } from "react";
203
203
  import { useRefFunction } from "../../Hooks/useRefFunction";
204
204
  import Enlargement from "../Enlargement";
205
205
  import { RefinePromptButton } from "../RefinePromptButton";
206
+ import { MARKDOWN_INPUT_FIELD_TEST_IDS } from "../testIds";
206
207
  /**
207
208
  * QuickActions 组件 - 快速操作区域
208
209
  *
@@ -306,7 +307,8 @@ import { RefinePromptButton } from "../RefinePromptButton";
306
307
  e.stopPropagation();
307
308
  e.preventDefault();
308
309
  },
309
- className: classNames("".concat(prefixCls, "-quick-actions"), hashId, _define_property({}, "".concat(prefixCls, "-quick-actions-vertical"), enlargeable))
310
+ className: classNames("".concat(prefixCls, "-quick-actions"), hashId, _define_property({}, "".concat(prefixCls, "-quick-actions-vertical"), enlargeable)),
311
+ "data-testid": MARKDOWN_INPUT_FIELD_TEST_IDS.QUICK_ACTIONS
310
312
  }, [
311
313
  // Enlargement组件 - 显示在最上方
312
314
  enlargeable && /*#__PURE__*/ React.createElement(Enlargement, {
@@ -60,6 +60,7 @@ import { I18nContext } from "../../I18n";
60
60
  import { AttachmentButton } from "../AttachmentButton";
61
61
  import { SendButton } from "../SendButton";
62
62
  import { VoiceInputButton } from "../VoiceInput";
63
+ import { MARKDOWN_INPUT_FIELD_TEST_IDS } from "../testIds";
63
64
  /**
64
65
  * SendActions 组件 - 发送操作按钮区域
65
66
  *
@@ -170,7 +171,8 @@ import { VoiceInputButton } from "../VoiceInput";
170
171
  e.stopPropagation();
171
172
  e.preventDefault();
172
173
  },
173
- className: classNames("".concat(prefixCls, "-send-actions"), _define_property({}, "".concat(prefixCls, "-send-has-tools"), hasTools), hashId)
174
+ className: classNames("".concat(prefixCls, "-send-actions"), _define_property({}, "".concat(prefixCls, "-send-has-tools"), hasTools), hashId),
175
+ "data-testid": MARKDOWN_INPUT_FIELD_TEST_IDS.SEND_ACTIONS
174
176
  }, collapseSendActions && actionsList.length > 2 ? /*#__PURE__*/ React.createElement(React.Fragment, null, /*#__PURE__*/ React.createElement(Popover, {
175
177
  trigger: "click",
176
178
  styles: {
@@ -196,7 +198,8 @@ import { VoiceInputButton } from "../VoiceInput";
196
198
  style: {
197
199
  fontSize: 16,
198
200
  color: 'var(--color-gray-text-secondary)'
199
- }
201
+ },
202
+ "data-testid": MARKDOWN_INPUT_FIELD_TEST_IDS.MORE_ACTIONS
200
203
  }, /*#__PURE__*/ React.createElement(EllipsisVertical, null))), actionsList.find(function(item) {
201
204
  if (/*#__PURE__*/ React.isValidElement(item) && (item === null || item === void 0 ? void 0 : item.key) === 'send-button') {
202
205
  return true;
@@ -306,7 +306,8 @@ import { getFileListFromDataTransferItems } from "../FilePaste";
306
306
  ];
307
307
  case 1:
308
308
  imageFiles = _state.sent().filter(function(file) {
309
- return file.type.startsWith('image/');
309
+ var _file_type;
310
+ return file === null || file === void 0 ? void 0 : (_file_type = file.type) === null || _file_type === void 0 ? void 0 : _file_type.startsWith('image/');
310
311
  });
311
312
  // 如果没有图片文件,直接返回
312
313
  if (imageFiles.length === 0) {
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
2
  import type { MarkdownInputFieldProps } from '../types/MarkdownInputFieldProps';
3
3
  interface UseMarkdownInputFieldStylesParams {
4
- toolsRender?: MarkdownInputFieldProps['toolsRender'];
4
+ hasTools?: boolean;
5
5
  maxHeight?: MarkdownInputFieldProps['maxHeight'];
6
6
  style?: React.CSSProperties;
7
7
  attachment?: {
@@ -27,5 +27,5 @@ interface UseMarkdownInputFieldStylesReturn {
27
27
  * 样式计算 Hook
28
28
  * 计算组件所需的样式值
29
29
  */
30
- export declare const useMarkdownInputFieldStyles: ({ toolsRender, maxHeight, style, attachment, isEnlarged, rightPadding, topRightPadding, quickRightOffset, hasEnlargeAction, hasRefineAction, totalActionCount, isMultiRowLayout, }: UseMarkdownInputFieldStylesParams) => UseMarkdownInputFieldStylesReturn;
30
+ export declare const useMarkdownInputFieldStyles: ({ hasTools, maxHeight, style, attachment, isEnlarged, rightPadding, topRightPadding, quickRightOffset, hasEnlargeAction, hasRefineAction, totalActionCount, isMultiRowLayout, }: UseMarkdownInputFieldStylesParams) => UseMarkdownInputFieldStylesReturn;
31
31
  export {};
@@ -3,13 +3,13 @@ import { useMemo } from "react";
3
3
  * 样式计算 Hook
4
4
  * 计算组件所需的样式值
5
5
  */ export var useMarkdownInputFieldStyles = function useMarkdownInputFieldStyles(param) {
6
- var toolsRender = param.toolsRender, maxHeight = param.maxHeight, style = param.style, attachment = param.attachment, isEnlarged = param.isEnlarged, rightPadding = param.rightPadding, topRightPadding = param.topRightPadding, quickRightOffset = param.quickRightOffset, hasEnlargeAction = param.hasEnlargeAction, hasRefineAction = param.hasRefineAction, totalActionCount = param.totalActionCount, isMultiRowLayout = param.isMultiRowLayout;
6
+ var hasTools = param.hasTools, maxHeight = param.maxHeight, style = param.style, attachment = param.attachment, isEnlarged = param.isEnlarged, rightPadding = param.rightPadding, topRightPadding = param.topRightPadding, quickRightOffset = param.quickRightOffset, hasEnlargeAction = param.hasEnlargeAction, hasRefineAction = param.hasRefineAction, totalActionCount = param.totalActionCount, isMultiRowLayout = param.isMultiRowLayout;
7
7
  var computedRightPadding = useMemo(function() {
8
- var bottomOverlayPadding = toolsRender ? 0 : rightPadding || 52;
8
+ var bottomOverlayPadding = hasTools ? 0 : rightPadding || 52;
9
9
  var topOverlayPadding = (topRightPadding || 0) + (quickRightOffset || 0);
10
10
  return Math.max(bottomOverlayPadding, topOverlayPadding);
11
11
  }, [
12
- toolsRender,
12
+ hasTools,
13
13
  rightPadding,
14
14
  topRightPadding,
15
15
  quickRightOffset
@@ -0,0 +1,28 @@
1
+ /**
2
+ * MarkdownInputField 内置 testId 常量
3
+ * 用于 E2E 测试与自动化测试中的 data-testid 定位
4
+ */
5
+ export declare const MARKDOWN_INPUT_FIELD_TEST_IDS: {
6
+ /** 根容器 */
7
+ readonly ROOT: "markdown-input-field";
8
+ /** 顶部操作区域 */
9
+ readonly TOP_AREA: "markdown-input-field-top-area";
10
+ /** 前置工具栏区域 */
11
+ readonly BEFORE_TOOLS: "markdown-input-field-before-tools";
12
+ /** 编辑器容器 */
13
+ readonly EDITOR: "markdown-input-field-editor";
14
+ /** 编辑器内容区 */
15
+ readonly EDITOR_CONTENT: "markdown-input-field-editor-content";
16
+ /** 快速操作区(放大、提示词优化等) */
17
+ readonly QUICK_ACTIONS: "markdown-input-field-quick-actions";
18
+ /** 工具栏包装器 */
19
+ readonly TOOLS_WRAPPER: "markdown-input-field-tools-wrapper";
20
+ /** 发送工具区域 */
21
+ readonly SEND_TOOLS: "markdown-input-field-send-tools";
22
+ /** 发送操作区(附件、语音、发送按钮等) */
23
+ readonly SEND_ACTIONS: "markdown-input-field-send-actions";
24
+ /** 更多操作按钮(折叠时的省略号) */
25
+ readonly MORE_ACTIONS: "markdown-input-field-more-actions";
26
+ /** 附件列表 */
27
+ readonly ATTACHMENT_LIST: "markdown-input-field-attachment-list";
28
+ };
@@ -0,0 +1,16 @@
1
+ /**
2
+ * MarkdownInputField 内置 testId 常量
3
+ * 用于 E2E 测试与自动化测试中的 data-testid 定位
4
+ */ export var MARKDOWN_INPUT_FIELD_TEST_IDS = {
5
+ /** 根容器 */ ROOT: 'markdown-input-field',
6
+ /** 顶部操作区域 */ TOP_AREA: 'markdown-input-field-top-area',
7
+ /** 前置工具栏区域 */ BEFORE_TOOLS: 'markdown-input-field-before-tools',
8
+ /** 编辑器容器 */ EDITOR: 'markdown-input-field-editor',
9
+ /** 编辑器内容区 */ EDITOR_CONTENT: 'markdown-input-field-editor-content',
10
+ /** 快速操作区(放大、提示词优化等) */ QUICK_ACTIONS: 'markdown-input-field-quick-actions',
11
+ /** 工具栏包装器 */ TOOLS_WRAPPER: 'markdown-input-field-tools-wrapper',
12
+ /** 发送工具区域 */ SEND_TOOLS: 'markdown-input-field-send-tools',
13
+ /** 发送操作区(附件、语音、发送按钮等) */ SEND_ACTIONS: 'markdown-input-field-send-actions',
14
+ /** 更多操作按钮(折叠时的省略号) */ MORE_ACTIONS: 'markdown-input-field-more-actions',
15
+ /** 附件列表 */ ATTACHMENT_LIST: 'markdown-input-field-attachment-list'
16
+ };
@@ -363,6 +363,11 @@ export type MarkdownInputFieldProps = {
363
363
  * ```
364
364
  */
365
365
  targetRef?: React.RefObject<HTMLDivElement>;
366
+ /**
367
+ * 测试 ID
368
+ * @description 用于 E2E 或自动化测试中的 `data-testid` 属性,覆盖根元素的默认 `markdown-input-field`
369
+ */
370
+ testId?: string;
366
371
  /**
367
372
  * 顶部操作区域自定义操作按钮渲染函数
368
373
  * @description 用于在顶部操作区域中央渲染自定义操作按钮
@@ -53,6 +53,7 @@ function _object_spread_props(target, source) {
53
53
  import React, { useMemo } from "react";
54
54
  import { AttachmentFileList } from "../AttachmentButton/AttachmentFileList";
55
55
  import { SendActions } from "../SendActions";
56
+ import { MARKDOWN_INPUT_FIELD_TEST_IDS } from "../testIds";
56
57
  /**
57
58
  * 附件列表渲染 Hook
58
59
  */ export var useAttachmentList = function useAttachmentList(param) {
@@ -65,7 +66,8 @@ import { SendActions } from "../SendActions";
65
66
  onRetry: handleFileRetry,
66
67
  onClearFileMap: function onClearFileMap() {
67
68
  updateAttachmentFiles(undefined);
68
- }
69
+ },
70
+ dataTestId: MARKDOWN_INPUT_FIELD_TEST_IDS.ATTACHMENT_LIST
69
71
  });
70
72
  }, [
71
73
  attachment === null || attachment === void 0 ? void 0 : attachment.enable,
@@ -1,6 +1,33 @@
1
1
  import React from 'react';
2
+ /** 各子区域类名,用于 Semantic 样式定制 */
3
+ export interface ChartStatisticClassNames {
4
+ root?: string;
5
+ header?: string;
6
+ headerLeft?: string;
7
+ title?: React.ReactNode;
8
+ subtitle?: React.ReactNode;
9
+ questionIcon?: string;
10
+ value?: string;
11
+ valuePrefix?: string;
12
+ valueSuffix?: string;
13
+ extra?: string;
14
+ }
15
+ /** 各子区域内联样式,用于 Semantic 样式定制 */
16
+ export interface ChartStatisticStyles {
17
+ root?: React.CSSProperties;
18
+ header?: React.CSSProperties;
19
+ headerLeft?: React.CSSProperties;
20
+ title?: React.CSSProperties;
21
+ subtitle?: React.CSSProperties;
22
+ questionIcon?: React.CSSProperties;
23
+ value?: React.CSSProperties;
24
+ valuePrefix?: React.CSSProperties;
25
+ valueSuffix?: React.CSSProperties;
26
+ extra?: React.CSSProperties;
27
+ }
2
28
  export interface ChartStatisticProps {
3
- title?: string;
29
+ title?: React.ReactNode;
30
+ subtitle?: React.ReactNode;
4
31
  tooltip?: string;
5
32
  value?: number | string | null | undefined;
6
33
  precision?: number;
@@ -9,15 +36,15 @@ export interface ChartStatisticProps {
9
36
  suffix?: React.ReactNode;
10
37
  formatter?: (value: number | string | null | undefined) => React.ReactNode;
11
38
  className?: string;
12
- /** 自定义CSS类名(支持多个类名) */
13
- classNames?: string | string[] | Record<string, boolean | undefined>;
39
+ /** 各子区域类名(Semantic 样式) */
40
+ classNames?: ChartStatisticClassNames;
14
41
  style?: React.CSSProperties;
42
+ /** 各子区域内联样式(Semantic 样式) */
43
+ styles?: ChartStatisticStyles;
15
44
  theme?: 'light' | 'dark';
16
45
  size?: 'small' | 'default' | 'large';
17
46
  block?: boolean;
18
47
  extra?: React.ReactNode;
19
- /** 自定义样式对象(支持多个样式对象) */
20
- styles?: React.CSSProperties | React.CSSProperties[];
21
48
  }
22
49
  declare const ChartStatistic: React.FC<ChartStatisticProps>;
23
50
  export default ChartStatistic;
@@ -1,11 +1,3 @@
1
- function _array_like_to_array(arr, len) {
2
- if (len == null || len > arr.length) len = arr.length;
3
- for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
4
- return arr2;
5
- }
6
- function _array_without_holes(arr) {
7
- if (Array.isArray(arr)) return _array_like_to_array(arr);
8
- }
9
1
  function _define_property(obj, key, value) {
10
2
  if (key in obj) {
11
3
  Object.defineProperty(obj, key, {
@@ -19,12 +11,6 @@ function _define_property(obj, key, value) {
19
11
  }
20
12
  return obj;
21
13
  }
22
- function _iterable_to_array(iter) {
23
- if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
24
- }
25
- function _non_iterable_spread() {
26
- throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
27
- }
28
14
  function _object_spread(target) {
29
15
  for(var i = 1; i < arguments.length; i++){
30
16
  var source = arguments[i] != null ? arguments[i] : {};
@@ -40,25 +26,14 @@ function _object_spread(target) {
40
26
  }
41
27
  return target;
42
28
  }
43
- function _to_consumable_array(arr) {
44
- return _array_without_holes(arr) || _iterable_to_array(arr) || _unsupported_iterable_to_array(arr) || _non_iterable_spread();
45
- }
46
- function _unsupported_iterable_to_array(o, minLen) {
47
- if (!o) return;
48
- if (typeof o === "string") return _array_like_to_array(o, minLen);
49
- var n = Object.prototype.toString.call(o).slice(8, -1);
50
- if (n === "Object" && o.constructor) n = o.constructor.name;
51
- if (n === "Map" || n === "Set") return Array.from(n);
52
- if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
53
- }
54
29
  import { QuestionCircleOutlined } from "@ant-design/icons";
55
30
  import { ConfigProvider, Tooltip } from "antd";
31
+ import clsx from "clsx";
56
32
  import React, { useContext } from "react";
57
33
  import { useStyle } from "./style";
58
34
  import { formatNumber } from "./utils";
59
35
  var ChartStatistic = function ChartStatistic(param) {
60
- var title = param.title, tooltip = param.tooltip, value = param.value, precision = param.precision, _param_groupSeparator = param.groupSeparator, groupSeparator = _param_groupSeparator === void 0 ? ',' : _param_groupSeparator, _param_prefix = param.prefix, prefix = _param_prefix === void 0 ? '' : _param_prefix, _param_suffix = param.suffix, suffix = _param_suffix === void 0 ? '' : _param_suffix, formatter = param.formatter, _param_className = param.className, className = _param_className === void 0 ? '' : _param_className, classNames = param.classNames, style = param.style, styles = param.styles, _param_theme = param.theme, theme = _param_theme === void 0 ? 'light' : _param_theme, _param_size = param.size, size = _param_size === void 0 ? 'default' : _param_size, _param_block = param.block, block = _param_block === void 0 ? false : _param_block, extra = param.extra;
61
- var _Object;
36
+ var title = param.title, subtitle = param.subtitle, tooltip = param.tooltip, value = param.value, precision = param.precision, _param_groupSeparator = param.groupSeparator, groupSeparator = _param_groupSeparator === void 0 ? ',' : _param_groupSeparator, _param_prefix = param.prefix, prefix = _param_prefix === void 0 ? '' : _param_prefix, _param_suffix = param.suffix, suffix = _param_suffix === void 0 ? '' : _param_suffix, formatter = param.formatter, _param_className = param.className, className = _param_className === void 0 ? '' : _param_className, classNames = param.classNames, style = param.style, styles = param.styles, _param_theme = param.theme, theme = _param_theme === void 0 ? 'light' : _param_theme, _param_size = param.size, size = _param_size === void 0 ? 'default' : _param_size, _param_block = param.block, block = _param_block === void 0 ? false : _param_block, extra = param.extra;
62
37
  var getPrefixCls = useContext(ConfigProvider.ConfigContext).getPrefixCls;
63
38
  var prefixCls = getPrefixCls('chart-statistic');
64
39
  var _useStyle = useStyle(prefixCls), wrapSSR = _useStyle.wrapSSR, hashId = _useStyle.hashId;
@@ -75,68 +50,54 @@ var ChartStatistic = function ChartStatistic(param) {
75
50
  };
76
51
  return formatNumber(value, formatOptions);
77
52
  };
78
- // 渲染标题和问号图标
53
+ // 渲染标题、副标题和问号图标
79
54
  var renderHeader = function renderHeader() {
80
- if (!title && !extra) return null;
55
+ if (!title && !subtitle && !extra) return null;
81
56
  var titleElement = title ? /*#__PURE__*/ React.createElement("span", {
82
- className: [
83
- "".concat(prefixCls, "-title"),
84
- hashId
85
- ].filter(Boolean).join(' ')
57
+ className: clsx("".concat(prefixCls, "-title"), hashId, classNames === null || classNames === void 0 ? void 0 : classNames.title),
58
+ style: styles === null || styles === void 0 ? void 0 : styles.title
86
59
  }, title) : null;
60
+ var subtitleElement = subtitle ? /*#__PURE__*/ React.createElement("span", {
61
+ className: clsx("".concat(prefixCls, "-subtitle"), hashId, classNames === null || classNames === void 0 ? void 0 : classNames.subtitle),
62
+ style: styles === null || styles === void 0 ? void 0 : styles.subtitle
63
+ }, subtitle) : null;
87
64
  var questionIcon = tooltip ? /*#__PURE__*/ React.createElement(Tooltip, {
88
65
  mouseEnterDelay: 0.3,
89
66
  title: tooltip,
90
67
  placement: "top"
91
68
  }, /*#__PURE__*/ React.createElement(QuestionCircleOutlined, {
92
- className: [
93
- "".concat(prefixCls, "-question-icon"),
94
- hashId
95
- ].filter(Boolean).join(' ')
69
+ className: clsx("".concat(prefixCls, "-question-icon"), hashId, classNames === null || classNames === void 0 ? void 0 : classNames.questionIcon),
70
+ style: styles === null || styles === void 0 ? void 0 : styles.questionIcon
96
71
  })) : null;
97
- var extraElement = extra ? /*#__PURE__*/ React.createElement("div", null, extra) : null;
72
+ var extraElement = extra ? /*#__PURE__*/ React.createElement("div", {
73
+ className: classNames === null || classNames === void 0 ? void 0 : classNames.extra,
74
+ style: styles === null || styles === void 0 ? void 0 : styles.extra
75
+ }, extra) : null;
76
+ var hasHeaderLeft = titleElement || subtitleElement || questionIcon;
98
77
  return /*#__PURE__*/ React.createElement("div", {
99
- className: [
100
- "".concat(prefixCls, "-header"),
101
- hashId
102
- ].filter(Boolean).join(' ')
103
- }, /*#__PURE__*/ React.createElement("div", {
104
- className: [
105
- "".concat(prefixCls, "-header-left"),
106
- hashId
107
- ].filter(Boolean).join(' ')
108
- }, titleElement, questionIcon), extraElement);
78
+ className: clsx("".concat(prefixCls, "-header"), hashId, classNames === null || classNames === void 0 ? void 0 : classNames.header),
79
+ style: styles === null || styles === void 0 ? void 0 : styles.header
80
+ }, hasHeaderLeft && /*#__PURE__*/ React.createElement("div", {
81
+ className: clsx("".concat(prefixCls, "-header-left"), hashId, classNames === null || classNames === void 0 ? void 0 : classNames.headerLeft),
82
+ style: styles === null || styles === void 0 ? void 0 : styles.headerLeft
83
+ }, (titleElement || questionIcon) && /*#__PURE__*/ React.createElement("div", {
84
+ className: clsx("".concat(prefixCls, "-header-row"), hashId)
85
+ }, titleElement, questionIcon), subtitleElement), extraElement);
109
86
  };
110
- var mergedClassName = [
111
- prefixCls,
112
- "".concat(prefixCls, "-").concat(theme),
113
- size !== 'default' && "".concat(prefixCls, "-").concat(size),
114
- block && "".concat(prefixCls, "-block"),
115
- hashId,
116
- className,
117
- classNames
118
- ].filter(Boolean).join(' ');
119
- var mergedStyle = _object_spread({}, style, Array.isArray(styles) ? (_Object = Object).assign.apply(_Object, [
120
- {}
121
- ].concat(_to_consumable_array(styles))) : styles || {});
87
+ var rootClassName = clsx(prefixCls, "".concat(prefixCls, "-").concat(theme), size !== 'default' && "".concat(prefixCls, "-").concat(size), block && "".concat(prefixCls, "-block"), hashId, className, classNames === null || classNames === void 0 ? void 0 : classNames.root);
88
+ var rootStyle = _object_spread({}, style, styles === null || styles === void 0 ? void 0 : styles.root);
122
89
  return wrapSSR(/*#__PURE__*/ React.createElement("div", {
123
- className: mergedClassName,
124
- style: mergedStyle
90
+ className: rootClassName,
91
+ style: rootStyle
125
92
  }, renderHeader(), /*#__PURE__*/ React.createElement("div", {
126
- className: [
127
- "".concat(prefixCls, "-value"),
128
- hashId
129
- ].filter(Boolean).join(' ')
93
+ className: clsx("".concat(prefixCls, "-value"), hashId, classNames === null || classNames === void 0 ? void 0 : classNames.value),
94
+ style: styles === null || styles === void 0 ? void 0 : styles.value
130
95
  }, prefix && /*#__PURE__*/ React.createElement("span", {
131
- className: [
132
- "".concat(prefixCls, "-value-prefix"),
133
- hashId
134
- ].filter(Boolean).join(' ')
96
+ className: clsx("".concat(prefixCls, "-value-prefix"), hashId, classNames === null || classNames === void 0 ? void 0 : classNames.valuePrefix),
97
+ style: styles === null || styles === void 0 ? void 0 : styles.valuePrefix
135
98
  }, prefix), renderValue(), suffix && /*#__PURE__*/ React.createElement("span", {
136
- className: [
137
- "".concat(prefixCls, "-value-suffix"),
138
- hashId
139
- ].filter(Boolean).join(' ')
99
+ className: clsx("".concat(prefixCls, "-value-suffix"), hashId, classNames === null || classNames === void 0 ? void 0 : classNames.valueSuffix),
100
+ style: styles === null || styles === void 0 ? void 0 : styles.valueSuffix
140
101
  }, suffix))));
141
102
  };
142
103
  export default ChartStatistic;
@@ -64,15 +64,27 @@ var genStyle = function genStyle(token) {
64
64
  justifyContent: 'space-between'
65
65
  }, _define_property(_obj, "".concat(token.componentCls, "-header-left"), {
66
66
  display: 'flex',
67
- alignItems: 'center',
68
- gap: '4px',
67
+ flexDirection: 'column',
68
+ alignItems: 'flex-start',
69
+ gap: '2px',
69
70
  flex: 1
71
+ }), _define_property(_obj, "".concat(token.componentCls, "-header-row"), {
72
+ display: 'flex',
73
+ alignItems: 'center',
74
+ gap: '4px'
70
75
  }), _define_property(_obj, "".concat(token.componentCls, "-title"), {
71
76
  fontFamily: 'PingFang SC',
72
77
  fontSize: '13px',
73
78
  fontWeight: 500,
74
79
  color: '#2C3E5D',
75
80
  margin: 0
81
+ }), _define_property(_obj, "".concat(token.componentCls, "-subtitle"), {
82
+ fontFamily: 'PingFang SC',
83
+ fontSize: '12px',
84
+ fontWeight: 400,
85
+ color: '#8C8C8C',
86
+ margin: 0,
87
+ lineHeight: 1.4
76
88
  }), _define_property(_obj, "".concat(token.componentCls, "-question-icon"), {
77
89
  fontSize: '14px',
78
90
  color: '#B3B9C4',
@@ -98,6 +110,8 @@ var genStyle = function genStyle(token) {
98
110
  }), _obj1)), _define_property(_obj10, // Dark theme styles
99
111
  '&-dark', (_obj4 = {}, _define_property(_obj4, "".concat(token.componentCls, "-header"), (_obj2 = {}, _define_property(_obj2, "".concat(token.componentCls, "-title"), {
100
112
  color: 'rgba(255, 255, 255, 0.65)'
113
+ }), _define_property(_obj2, "".concat(token.componentCls, "-subtitle"), {
114
+ color: 'rgba(255, 255, 255, 0.45)'
101
115
  }), _define_property(_obj2, "".concat(token.componentCls, "-question-icon"), {
102
116
  color: 'rgba(255, 255, 255, 0.45)',
103
117
  '&:hover': {
@@ -112,6 +126,8 @@ var genStyle = function genStyle(token) {
112
126
  }), _obj3)), _obj4)), _define_property(_obj10, // Size variants
113
127
  '&-small', (_obj6 = {}, _define_property(_obj6, "".concat(token.componentCls, "-header"), (_obj5 = {}, _define_property(_obj5, "".concat(token.componentCls, "-title"), {
114
128
  fontSize: '12px'
129
+ }), _define_property(_obj5, "".concat(token.componentCls, "-subtitle"), {
130
+ fontSize: '11px'
115
131
  }), _define_property(_obj5, "".concat(token.componentCls, "-question-icon"), {
116
132
  fontSize: '14px'
117
133
  }), _obj5)), _define_property(_obj6, "".concat(token.componentCls, "-value"), {
@@ -120,6 +136,8 @@ var genStyle = function genStyle(token) {
120
136
  gap: '12px'
121
137
  }, _define_property(_obj8, "".concat(token.componentCls, "-header"), (_obj7 = {}, _define_property(_obj7, "".concat(token.componentCls, "-title"), {
122
138
  fontSize: '13px'
139
+ }), _define_property(_obj7, "".concat(token.componentCls, "-subtitle"), {
140
+ fontSize: '13px'
123
141
  }), _define_property(_obj7, "".concat(token.componentCls, "-question-icon"), {
124
142
  fontSize: '14px'
125
143
  }), _obj7)), _define_property(_obj8, "".concat(token.componentCls, "-value"), {
@@ -27,7 +27,7 @@ export { default as RadarChart } from './RadarChart';
27
27
  export { default as ScatterChart } from './ScatterChart';
28
28
  export type { AreaChartConfigItem, AreaChartDataItem, AreaChartProps, } from './AreaChart';
29
29
  export type { BarChartConfigItem, BarChartDataItem, BarChartProps, } from './BarChart';
30
- export type { ChartStatisticProps } from './ChartStatistic';
30
+ export type { ChartStatisticClassNames, ChartStatisticProps, ChartStatisticStyles, } from './ChartStatistic';
31
31
  export type { DonutChartConfig, DonutChartData, DonutChartProps, } from './DonutChart';
32
32
  export type { FunnelChartDataItem, FunnelChartProps } from './FunnelChart';
33
33
  export type { LineChartConfigItem, LineChartDataItem, LineChartProps, } from './LineChart';
@@ -90,6 +90,7 @@ import classNames from "clsx";
90
90
  import { AnimatePresence, motion } from "framer-motion";
91
91
  import { useMergedState } from "rc-util";
92
92
  import React, { memo, useContext, useCallback, useEffect, useMemo, useRef, useState } from "react";
93
+ import { useLocale } from "../I18n";
93
94
  import { useRefFunction } from "../Hooks/useRefFunction";
94
95
  import { useStyle } from "./style";
95
96
  var getChevronStyle = function getChevronStyle(expanded) {
@@ -197,6 +198,7 @@ var ExpandButton = function ExpandButton(param) {
197
198
  };
198
199
  var ThinkContainer = function ThinkContainer(param) {
199
200
  var thinkContent = param.thinkContent, expandedState = param.expandedState, floatingExpandedState = param.floatingExpandedState, status = param.status, light = param.light, prefixCls = param.prefixCls, hashId = param.hashId, customClassNames = param.classNames, styles = param.styles, onToggleFloatingExpand = param.onToggleFloatingExpand;
201
+ var locale = useLocale();
200
202
  var contentInnerRef = useRef(null);
201
203
  var _useState = _sliced_to_array(useState(false), 2), isContentOverflowing = _useState[0], setIsContentOverflowing = _useState[1];
202
204
  var _useState1 = _sliced_to_array(useState(false), 2), contentExpanded = _useState1[0], setContentExpanded = _useState1[1];
@@ -210,7 +212,7 @@ var ThinkContainer = function ThinkContainer(param) {
210
212
  }) : /*#__PURE__*/ React.createElement(ChevronsUpDown, {
211
213
  style: FLOATING_ICON_STYLE
212
214
  });
213
- var floatingText = floatingExpandedState ? '收起' : '展开';
215
+ var floatingText = floatingExpandedState ? locale.collapse : locale.expand;
214
216
  var showFloatingExpand = status === 'loading' && !light;
215
217
  var checkOverflow = useCallback(function() {
216
218
  var el = contentInnerRef.current;
@@ -253,7 +255,7 @@ var ThinkContainer = function ThinkContainer(param) {
253
255
  var contentExpandButton = useMemo(function() {
254
256
  if (!showContentExpand) return null;
255
257
  var icon = contentExpanded ? /*#__PURE__*/ React.createElement(ChevronsDownUp, null) : /*#__PURE__*/ React.createElement(ChevronsUpDown, null);
256
- var text = contentExpanded ? '收起' : '展开';
258
+ var text = contentExpanded ? locale.collapse : locale.expand;
257
259
  return /*#__PURE__*/ React.createElement("div", {
258
260
  className: contentExpandClassName,
259
261
  onClick: handleContentExpandToggle,
@@ -271,7 +273,8 @@ var ThinkContainer = function ThinkContainer(param) {
271
273
  showContentExpand,
272
274
  contentExpanded,
273
275
  contentExpandClassName,
274
- handleContentExpandToggle
276
+ handleContentExpandToggle,
277
+ locale
275
278
  ]);
276
279
  // 缓存容器元素
277
280
  var contentVariants = useMemo(function() {
@@ -249,6 +249,7 @@ var genStyle = function genStyle(token) {
249
249
  width: '100%',
250
250
  padding: 8,
251
251
  display: 'flex',
252
+ flexDirection: 'column',
252
253
  maxHeight: 700,
253
254
  overflow: 'hidden',
254
255
  overflowY: 'auto',
@@ -36,6 +36,10 @@ export interface RealtimeFollowData {
36
36
  }>;
37
37
  segmentedExtra?: React.ReactNode;
38
38
  }
39
+ /** 供测试覆盖使用:根据 type 将 content 转为编辑器所需字符串 */
40
+ export declare const getContentForEditor: (type: RealtimeFollowMode, content: string | DiffContent | undefined) => string;
41
+ /** 供测试覆盖使用:决定是否根据 type/htmlViewMode 更新编辑器内容 */
42
+ export declare const shouldUpdateEditor: (type: RealtimeFollowMode, htmlViewMode: 'preview' | 'code') => boolean;
39
43
  /**
40
44
  * RealtimeFollow 组件
41
45
  *
@@ -244,14 +244,14 @@ var Overlay = function Overlay(param) {
244
244
  className: classNames("".concat(finalPrefixCls, "-overlay"), (_obj = {}, _define_property(_obj, "".concat(finalPrefixCls, "-overlay--loading"), status === 'loading'), _define_property(_obj, "".concat(finalPrefixCls, "-overlay--error"), status === 'error'), _obj), hashId)
245
245
  }, content);
246
246
  };
247
- var getContentForEditor = function getContentForEditor(type, content) {
247
+ /** 供测试覆盖使用:根据 type 将 content 转为编辑器所需字符串 */ export var getContentForEditor = function getContentForEditor(type, content) {
248
248
  if (type === 'html') {
249
249
  var html = typeof content === 'string' ? content : '';
250
250
  return "```html\n".concat(html, "\n```");
251
251
  }
252
252
  return String(content);
253
253
  };
254
- var shouldUpdateEditor = function shouldUpdateEditor(type, htmlViewMode) {
254
+ /** 供测试覆盖使用:决定是否根据 type/htmlViewMode 更新编辑器内容 */ export var shouldUpdateEditor = function shouldUpdateEditor(type, htmlViewMode) {
255
255
  if (type === 'shell') return true;
256
256
  if (type === 'markdown' || type === 'md') return true;
257
257
  if (type === 'html' && htmlViewMode === 'code') return true;
package/dist/index.d.ts CHANGED
@@ -56,6 +56,7 @@ export * from './MarkdownInputField/AttachmentButton/utils';
56
56
  export { ActionItemContainer } from './MarkdownInputField/BeforeToolContainer/BeforeToolContainer';
57
57
  export * from './MarkdownInputField/FileMapView';
58
58
  export * from './MarkdownInputField/MarkdownInputField';
59
+ export { MARKDOWN_INPUT_FIELD_TEST_IDS } from './MarkdownInputField/testIds';
59
60
  export * from './MarkdownInputField/VoiceInput';
60
61
  export * from './Schema';
61
62
  export * from './Schema/SchemaRenderer/templateEngine';
package/dist/index.js CHANGED
@@ -65,6 +65,7 @@ export * from "./MarkdownInputField/AttachmentButton/utils";
65
65
  export { ActionItemContainer } from "./MarkdownInputField/BeforeToolContainer/BeforeToolContainer";
66
66
  export * from "./MarkdownInputField/FileMapView";
67
67
  export * from "./MarkdownInputField/MarkdownInputField";
68
+ export { MARKDOWN_INPUT_FIELD_TEST_IDS } from "./MarkdownInputField/testIds";
68
69
  export * from "./MarkdownInputField/VoiceInput";
69
70
  // ─── Schema ──────────────────────────────────────────────────────────────────
70
71
  export * from "./Schema";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ant-design/agentic-ui",
3
- "version": "2.29.52",
3
+ "version": "2.29.54",
4
4
  "description": "面向智能体的 UI 组件库,提供多步推理可视化、工具调用展示、任务执行协同等 Agentic UI 能力",
5
5
  "repository": "git@github.com:ant-design/agentic-ui.git",
6
6
  "license": "MIT",