@ant-design/agentic-ui 2.11.1 → 2.11.2

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.
@@ -9,10 +9,8 @@ export type SupportedFormat = {
9
9
  export type AttachmentButtonPopoverProps = {
10
10
  children?: React.ReactNode;
11
11
  supportedFormat?: SupportedFormat;
12
- /** 文件选择后的回调函数,参数为选中的文件 */
13
- onFileSelect?: (files: FileList, accept: string) => void;
14
- /** 是否允许一次选择多个文件 */
15
- allowMultiple?: boolean;
12
+ /** 上传图片的处理函数 */
13
+ uploadImage?: (forGallery?: boolean) => Promise<void>;
16
14
  };
17
15
  export declare const SupportedFileFormats: {
18
16
  image: {
@@ -47,12 +47,8 @@ function _unsupported_iterable_to_array(o, minLen) {
47
47
  import { AudioOutlined, FileImageOutlined, FileTextFilled, FolderOpenOutlined, PictureOutlined, VideoCameraOutlined } from "@ant-design/icons";
48
48
  import { Button, Modal, Tooltip } from "antd";
49
49
  import React, { useCallback, useContext, useMemo, useState } from "react";
50
- import { useRefFunction } from "../../Hooks/useRefFunction";
51
50
  import { I18nContext } from "../../I18n";
52
- import { isMobileDevice, isVivoOrOppoDevice, isWeChat, kbToSize } from "./utils";
53
- /**
54
- * 移动设备默认的文件类型 accept 值
55
- */ var MOBILE_DEFAULT_ACCEPT = 'application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-powerpoint,application/vnd.openxmlformats-officedocument.presentationml.presentation,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document,application/pdf,.csv,text/plain,application/x-zip-compressed';
51
+ import { isMobileDevice, isVivoOrOppoDevice, kbToSize } from "./utils";
56
52
  var FILE_SIZE_UNITS = {
57
53
  KB: 1024,
58
54
  MB: 1024 * 1024
@@ -133,7 +129,7 @@ export var AttachmentSupportedFormatsContent = function(param) {
133
129
  });
134
130
  };
135
131
  export var AttachmentButtonPopover = function(param) {
136
- var children = param.children, supportedFormat = param.supportedFormat, onFileSelect = param.onFileSelect, _param_allowMultiple = param.allowMultiple, allowMultiple = _param_allowMultiple === void 0 ? true : _param_allowMultiple;
132
+ var children = param.children, supportedFormat = param.supportedFormat, uploadImage = param.uploadImage;
137
133
  var _useState = _sliced_to_array(useState(false), 2), modalOpen = _useState[0], setModalOpen = _useState[1];
138
134
  var locale = useContext(I18nContext).locale;
139
135
  var isVivoOrOppo = useMemo(function() {
@@ -142,9 +138,6 @@ export var AttachmentButtonPopover = function(param) {
142
138
  var isMobile = useMemo(function() {
143
139
  return isMobileDevice();
144
140
  }, []);
145
- var isWeChatEnv = useMemo(function() {
146
- return isWeChat();
147
- }, []);
148
141
  var trigger = useMemo(function() {
149
142
  return isVivoOrOppo ? [
150
143
  'click'
@@ -155,54 +148,6 @@ export var AttachmentButtonPopover = function(param) {
155
148
  }, [
156
149
  isVivoOrOppo
157
150
  ]);
158
- var format = supportedFormat || SupportedFileFormats.image;
159
- var extensions = format.extensions || [];
160
- /**
161
- * 根据支持的格式获取 accept 属性值
162
- * 优先级:微信 > 手机品牌(oppo/vivo)> 移动设备 > 相册模式 > 默认
163
- */ var getAcceptValue = useRefFunction(function(forGallery) {
164
- // 相册模式
165
- if (forGallery) {
166
- return 'image/*';
167
- }
168
- // 1. 微信环境最优先:设置为空字符串以打开文件浏览器
169
- if (isWeChatEnv) {
170
- return '*';
171
- }
172
- // 2. 手机品牌其次(oppo/vivo):设置为空字符串以打开文件浏览器
173
- if (isVivoOrOppo) {
174
- return '*';
175
- }
176
- // 3. 移动设备其次:设置为空字符串以打开文件浏览器
177
- if (isMobile) {
178
- return '*';
179
- }
180
- // 5. 默认情况:使用具体扩展名列表
181
- return extensions.length > 0 ? extensions.map(function(ext) {
182
- return ".".concat(ext);
183
- }).join(',') : MOBILE_DEFAULT_ACCEPT;
184
- });
185
- /**
186
- * 创建文件输入并触发选择
187
- */ var triggerFileInput = useRefFunction(function(forGallery) {
188
- var accept = getAcceptValue(forGallery);
189
- var input = document.createElement('input');
190
- input.type = 'file';
191
- input.accept = accept;
192
- input.multiple = allowMultiple;
193
- input.style.display = 'none';
194
- input.onchange = function(e) {
195
- var target = e.target;
196
- if (target.files && target.files.length > 0 && onFileSelect) {
197
- onFileSelect(target.files, accept);
198
- }
199
- // 清理
200
- input.remove();
201
- };
202
- document.body.appendChild(input);
203
- input.click();
204
- setModalOpen(false);
205
- });
206
151
  var handleClick = useCallback(function(e) {
207
152
  if (isVivoOrOppo) {
208
153
  e.stopPropagation();
@@ -213,14 +158,16 @@ export var AttachmentButtonPopover = function(param) {
213
158
  isVivoOrOppo
214
159
  ]);
215
160
  var handleOpenGallery = useCallback(function() {
216
- triggerFileInput(true);
161
+ uploadImage === null || uploadImage === void 0 ? void 0 : uploadImage(true);
162
+ setModalOpen(false);
217
163
  }, [
218
- triggerFileInput
164
+ uploadImage
219
165
  ]);
220
166
  var handleOpenFile = useCallback(function() {
221
- triggerFileInput(false);
167
+ uploadImage === null || uploadImage === void 0 ? void 0 : uploadImage(false);
168
+ setModalOpen(false);
222
169
  }, [
223
- triggerFileInput
170
+ uploadImage
224
171
  ]);
225
172
  if (isVivoOrOppo) {
226
173
  return /*#__PURE__*/ React.createElement("div", {
@@ -93,7 +93,7 @@ export declare const upLoadFileToServer: (files: ArrayLike<File>, props: UploadP
93
93
  */
94
94
  export declare const AttachmentButton: React.FC<AttachmentButtonProps & {
95
95
  /** 上传图片的处理函数 */
96
- uploadImage(): Promise<void>;
96
+ uploadImage(forGallery?: boolean): Promise<void>;
97
97
  /** 按钮标题文本 */
98
98
  title?: React.ReactNode;
99
99
  }>;
@@ -470,7 +470,7 @@ var ButtonContent = function(param) {
470
470
  * />
471
471
  * ```
472
472
  */ export var AttachmentButton = function(param) {
473
- var disabled = param.disabled, uploadImage = param.uploadImage, title = param.title, supportedFormat = param.supportedFormat, render = param.render, upload = param.upload, uploadWithResponse = param.uploadWithResponse, fileMap = param.fileMap, onFileMapChange = param.onFileMapChange, maxFileSize = param.maxFileSize, maxFileCount = param.maxFileCount, minFileCount = param.minFileCount, allowMultiple = param.allowMultiple;
473
+ var disabled = param.disabled, uploadImage = param.uploadImage, title = param.title, supportedFormat = param.supportedFormat, render = param.render;
474
474
  var context = useContext(ConfigProvider.ConfigContext);
475
475
  var prefix = context === null || context === void 0 ? void 0 : context.getPrefixCls('agentic-md-editor-attachment-button');
476
476
  var _useStyle = useStyle(prefix), wrapSSR = _useStyle.wrapSSR, hashId = _useStyle.hashId;
@@ -484,26 +484,12 @@ var ButtonContent = function(param) {
484
484
  }, /*#__PURE__*/ React.createElement(ButtonContent, {
485
485
  title: title
486
486
  }));
487
- var handleFileSelect = function(files) {
488
- // 触发文件上传
489
- upLoadFileToServer(files, {
490
- upload: upload,
491
- uploadWithResponse: uploadWithResponse,
492
- fileMap: fileMap,
493
- onFileMapChange: onFileMapChange,
494
- maxFileSize: maxFileSize,
495
- maxFileCount: maxFileCount,
496
- minFileCount: minFileCount,
497
- locale: {}
498
- });
499
- };
500
487
  var wrapper = render ? render({
501
488
  children: buttonWithStyle,
502
489
  supportedFormat: format
503
490
  }) : /*#__PURE__*/ React.createElement(AttachmentButtonPopover, {
504
491
  supportedFormat: format,
505
- onFileSelect: handleFileSelect,
506
- allowMultiple: allowMultiple
492
+ uploadImage: uploadImage
507
493
  }, buttonWithStyle);
508
494
  return wrapSSR(/*#__PURE__*/ React.createElement("div", {
509
495
  className: classNames("".concat(prefix), hashId, _define_property({}, "".concat(prefix, "-disabled"), disabled)),
@@ -21,7 +21,7 @@ export interface FileUploadManagerReturn {
21
21
  /** 支持的文件格式 */
22
22
  supportedFormat: SupportedFileFormatsType;
23
23
  /** 上传图片 */
24
- uploadImage: () => Promise<void>;
24
+ uploadImage: (forGallery?: boolean) => Promise<void>;
25
25
  /** 更新附件文件列表 */
26
26
  updateAttachmentFiles: (newFileMap?: Map<string, AttachmentFile>) => void;
27
27
  /** 处理文件删除 */
@@ -180,7 +180,7 @@ import { useRefFunction } from "../../Hooks/useRefFunction";
180
180
  import { I18nContext } from "../../I18n";
181
181
  import { upLoadFileToServer } from "../AttachmentButton";
182
182
  import { SupportedFileFormats } from "../AttachmentButton/AttachmentButtonPopover";
183
- import { isMobileDevice, isVivoOrOppoDevice } from "../AttachmentButton/utils";
183
+ import { isMobileDevice, isVivoOrOppoDevice, isWeChat } from "../AttachmentButton/utils";
184
184
  /**
185
185
  * 文件上传管理器
186
186
  *
@@ -200,167 +200,166 @@ import { isMobileDevice, isVivoOrOppoDevice } from "../AttachmentButton/utils";
200
200
  onFileMapChange === null || onFileMapChange === void 0 ? void 0 : onFileMapChange(new Map(newFileMap));
201
201
  });
202
202
  /**
203
+ * 移动设备默认的文件类型 accept 值
204
+ */ var MOBILE_DEFAULT_ACCEPT = 'application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-powerpoint,application/vnd.openxmlformats-officedocument.presentationml.presentation,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document,application/pdf,.csv,text/plain,application/x-zip-compressed';
205
+ /**
203
206
  * 根据支持的格式获取 accept 属性值
204
- * 在移动设备上,使用默认的 accept
205
- * vivo oppo 手机上,如果只支持图片格式,使用 image/* 打开相册;否则使用具体扩展名打开文件选择器
206
- */ var getAcceptValue = function() {
207
+ * 优先级:微信 > 手机品牌(oppo/vivo)> 移动设备 > 相册模式 > 默认
208
+ */ var getAcceptValue = useRefFunction(function(forGallery) {
209
+ // 相册模式
210
+ if (forGallery) {
211
+ return 'image/*';
212
+ }
207
213
  var isMobile = isMobileDevice();
208
214
  var isVivoOrOppo = isVivoOrOppoDevice();
215
+ var isWeChatEnv = isWeChat();
209
216
  var extensions = (supportedFormat === null || supportedFormat === void 0 ? void 0 : supportedFormat.extensions) || [];
210
- // vivo/oppo 设备:判断是否只包含图片格式
211
- var imageExtensions = [
212
- 'jpg',
213
- 'jpeg',
214
- 'png',
215
- 'gif',
216
- 'bmp',
217
- 'webp',
218
- 'svg'
219
- ];
220
- var isImageOnly = extensions.length > 0 && extensions.every(function(ext) {
221
- return imageExtensions.includes(ext.toLowerCase());
222
- });
223
- if (isImageOnly) {
224
- // 只支持图片格式,使用 image/* 打开相册
225
- return 'image/*';
217
+ // 1. 微信环境最优先:设置为空字符串以打开文件浏览器
218
+ if (isWeChatEnv) {
219
+ return '*';
226
220
  }
227
- // 如果是移动设备,返回默认的 accept 值
228
- if (isMobile) {
229
- return '';
221
+ // 2. 手机品牌其次(oppo/vivo):设置为空字符串以打开文件浏览器
222
+ if (isVivoOrOppo) {
223
+ return '*';
230
224
  }
231
- if (!isVivoOrOppo) {
232
- // vivo/oppo 设备,直接使用扩展名列表
233
- return extensions.length > 0 ? extensions.map(function(ext) {
234
- return ".".concat(ext);
235
- }).join(',') : 'image/*';
225
+ // 3. 移动设备其次:设置为空字符串以打开文件浏览器
226
+ if (isMobile) {
227
+ return '*';
236
228
  }
237
- // 支持其他格式,使用具体扩展名列表打开文件选择器
229
+ // 4. 默认情况:使用具体扩展名列表
238
230
  return extensions.length > 0 ? extensions.map(function(ext) {
239
231
  return ".".concat(ext);
240
- }).join(',') : 'image/*';
241
- };
232
+ }).join(',') : MOBILE_DEFAULT_ACCEPT;
233
+ });
242
234
  /**
243
235
  * 上传图片
244
- */ var uploadImage = useRefFunction(/*#__PURE__*/ _async_to_generator(function() {
245
- var isUploading, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, file, currentFileCount, errorMsg, input, _attachment_allowMultiple;
246
- return _ts_generator(this, function(_state) {
247
- // 检查是否有文件正在上传中
248
- isUploading = false;
249
- _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
250
- try {
251
- for(_iterator = ((fileMap === null || fileMap === void 0 ? void 0 : fileMap.values()) || [])[Symbol.iterator](); !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
252
- file = _step.value;
253
- if (file.status === 'uploading') {
254
- isUploading = true;
255
- break;
256
- }
257
- }
258
- } catch (err) {
259
- _didIteratorError = true;
260
- _iteratorError = err;
261
- } finally{
236
+ */ var uploadImage = useRefFunction(/*#__PURE__*/ function() {
237
+ var _ref = _async_to_generator(function(forGallery) {
238
+ var isUploading, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, file, currentFileCount, errorMsg, accept, input, _attachment_allowMultiple;
239
+ return _ts_generator(this, function(_state) {
240
+ // 检查是否有文件正在上传中
241
+ isUploading = false;
242
+ _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
262
243
  try {
263
- if (!_iteratorNormalCompletion && _iterator.return != null) {
264
- _iterator.return();
244
+ for(_iterator = ((fileMap === null || fileMap === void 0 ? void 0 : fileMap.values()) || [])[Symbol.iterator](); !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
245
+ file = _step.value;
246
+ if (file.status === 'uploading') {
247
+ isUploading = true;
248
+ break;
249
+ }
265
250
  }
251
+ } catch (err) {
252
+ _didIteratorError = true;
253
+ _iteratorError = err;
266
254
  } finally{
267
- if (_didIteratorError) {
268
- throw _iteratorError;
255
+ try {
256
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
257
+ _iterator.return();
258
+ }
259
+ } finally{
260
+ if (_didIteratorError) {
261
+ throw _iteratorError;
262
+ }
269
263
  }
270
264
  }
271
- }
272
- if (isUploading) {
273
- return [
274
- 2
275
- ];
276
- }
277
- // 检查是否已达到最大文件数量限制
278
- currentFileCount = (fileMap === null || fileMap === void 0 ? void 0 : fileMap.size) || 0;
279
- if ((attachment === null || attachment === void 0 ? void 0 : attachment.maxFileCount) && currentFileCount >= attachment.maxFileCount) {
280
- errorMsg = (locale === null || locale === void 0 ? void 0 : locale['markdownInput.maxFileCountExceeded']) ? locale['markdownInput.maxFileCountExceeded'].replace('${maxFileCount}', String(attachment.maxFileCount)) : "最多只能上传 ".concat(attachment.maxFileCount, " 个文件");
281
- message.error(errorMsg);
282
- return [
283
- 2
284
- ];
285
- }
286
- input = document.createElement('input');
287
- input.id = 'uploadImage' + '_' + Math.random();
288
- input.type = 'file';
289
- input.accept = getAcceptValue();
290
- input.multiple = (_attachment_allowMultiple = attachment === null || attachment === void 0 ? void 0 : attachment.allowMultiple) !== null && _attachment_allowMultiple !== void 0 ? _attachment_allowMultiple : true;
291
- input.style.display = 'none';
292
- input.onchange = /*#__PURE__*/ function() {
293
- var _ref = _async_to_generator(function(e) {
294
- var error;
295
- return _ts_generator(this, function(_state) {
296
- switch(_state.label){
297
- case 0:
298
- if (input.dataset.readonly) {
265
+ if (isUploading) {
266
+ return [
267
+ 2
268
+ ];
269
+ }
270
+ // 检查是否已达到最大文件数量限制
271
+ currentFileCount = (fileMap === null || fileMap === void 0 ? void 0 : fileMap.size) || 0;
272
+ if ((attachment === null || attachment === void 0 ? void 0 : attachment.maxFileCount) && currentFileCount >= attachment.maxFileCount) {
273
+ errorMsg = (locale === null || locale === void 0 ? void 0 : locale['markdownInput.maxFileCountExceeded']) ? locale['markdownInput.maxFileCountExceeded'].replace('${maxFileCount}', String(attachment.maxFileCount)) : "最多只能上传 ".concat(attachment.maxFileCount, " 个文件");
274
+ message.error(errorMsg);
275
+ return [
276
+ 2
277
+ ];
278
+ }
279
+ accept = getAcceptValue(forGallery || false);
280
+ input = document.createElement('input');
281
+ input.id = 'uploadImage' + '_' + Math.random();
282
+ input.type = 'file';
283
+ input.accept = accept;
284
+ input.multiple = (_attachment_allowMultiple = attachment === null || attachment === void 0 ? void 0 : attachment.allowMultiple) !== null && _attachment_allowMultiple !== void 0 ? _attachment_allowMultiple : true;
285
+ input.style.display = 'none';
286
+ input.onchange = /*#__PURE__*/ function() {
287
+ var _ref = _async_to_generator(function(e) {
288
+ var error;
289
+ return _ts_generator(this, function(_state) {
290
+ switch(_state.label){
291
+ case 0:
292
+ if (input.dataset.readonly) {
293
+ return [
294
+ 2
295
+ ];
296
+ }
297
+ input.dataset.readonly = 'true';
298
+ _state.label = 1;
299
+ case 1:
300
+ _state.trys.push([
301
+ 1,
302
+ 3,
303
+ 4,
304
+ 5
305
+ ]);
306
+ return [
307
+ 4,
308
+ upLoadFileToServer(e.target.files, _object_spread_props(_object_spread({}, attachment), {
309
+ fileMap: fileMap,
310
+ onFileMapChange: function(newFileMap) {
311
+ updateAttachmentFiles(newFileMap);
312
+ },
313
+ locale: locale
314
+ }))
315
+ ];
316
+ case 2:
317
+ _state.sent();
318
+ return [
319
+ 3,
320
+ 5
321
+ ];
322
+ case 3:
323
+ error = _state.sent();
324
+ console.error('Error uploading files:', error);
325
+ return [
326
+ 3,
327
+ 5
328
+ ];
329
+ case 4:
330
+ input.value = '';
331
+ delete input.dataset.readonly;
332
+ return [
333
+ 7
334
+ ];
335
+ case 5:
299
336
  return [
300
337
  2
301
338
  ];
302
- }
303
- input.dataset.readonly = 'true';
304
- _state.label = 1;
305
- case 1:
306
- _state.trys.push([
307
- 1,
308
- 3,
309
- 4,
310
- 5
311
- ]);
312
- return [
313
- 4,
314
- upLoadFileToServer(e.target.files, _object_spread_props(_object_spread({}, attachment), {
315
- fileMap: fileMap,
316
- onFileMapChange: function(newFileMap) {
317
- updateAttachmentFiles(newFileMap);
318
- },
319
- locale: locale
320
- }))
321
- ];
322
- case 2:
323
- _state.sent();
324
- return [
325
- 3,
326
- 5
327
- ];
328
- case 3:
329
- error = _state.sent();
330
- console.error('Error uploading files:', error);
331
- return [
332
- 3,
333
- 5
334
- ];
335
- case 4:
336
- input.value = '';
337
- delete input.dataset.readonly;
338
- return [
339
- 7
340
- ];
341
- case 5:
342
- return [
343
- 2
344
- ];
345
- }
339
+ }
340
+ });
346
341
  });
347
- });
348
- return function(e) {
349
- return _ref.apply(this, arguments);
350
- };
351
- }();
352
- if (input.dataset.readonly) {
342
+ return function(e) {
343
+ return _ref.apply(this, arguments);
344
+ };
345
+ }();
346
+ if (input.dataset.readonly) {
347
+ return [
348
+ 2
349
+ ];
350
+ }
351
+ document.body.appendChild(input);
352
+ input.click();
353
+ input.remove();
353
354
  return [
354
355
  2
355
356
  ];
356
- }
357
- input.click();
358
- input.remove();
359
- return [
360
- 2
361
- ];
357
+ });
362
358
  });
363
- }));
359
+ return function(forGallery) {
360
+ return _ref.apply(this, arguments);
361
+ };
362
+ }());
364
363
  /**
365
364
  * 处理文件删除
366
365
  */ var handleFileRemoval = useRefFunction(/*#__PURE__*/ function() {
@@ -31,7 +31,7 @@ export interface SendActionsProps {
31
31
  /** 是否允许空内容提交 */
32
32
  allowEmptySubmit?: boolean;
33
33
  /** 上传图片回调 */
34
- uploadImage?: () => Promise<void>;
34
+ uploadImage?: (forGallery?: boolean) => Promise<void>;
35
35
  /** 开始录音回调 */
36
36
  onStartRecording?: () => Promise<void>;
37
37
  /** 停止录音回调 */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ant-design/agentic-ui",
3
- "version": "2.11.1",
3
+ "version": "2.11.2",
4
4
  "description": "面向智能体的 UI 组件库,提供多步推理可视化、工具调用展示、任务执行协同等 Agentic UI 能力",
5
5
  "repository": "git@github.com:ant-design/agentic-ui.git",
6
6
  "license": "MIT",