@ai-group/chat-sdk 3.7.0 → 3.7.1-alpha1

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 (48) hide show
  1. package/dist/cjs/components/XAdkSender/InlineTagInput.d.ts +24 -0
  2. package/dist/cjs/components/XAdkSender/InlineTagInput.js +461 -0
  3. package/dist/cjs/components/XAdkSender/InlineTagInput.js.map +7 -0
  4. package/dist/cjs/components/XAdkSender/InputTags.d.ts +8 -0
  5. package/dist/cjs/components/XAdkSender/InputTags.js +51 -0
  6. package/dist/cjs/components/XAdkSender/InputTags.js.map +7 -0
  7. package/dist/cjs/components/XAdkSender/QuickList.d.ts +16 -0
  8. package/dist/cjs/components/XAdkSender/QuickList.js +105 -0
  9. package/dist/cjs/components/XAdkSender/QuickList.js.map +7 -0
  10. package/dist/cjs/components/XAdkSender/index.d.ts +1 -6
  11. package/dist/cjs/components/XAdkSender/index.js +289 -78
  12. package/dist/cjs/components/XAdkSender/index.js.map +3 -3
  13. package/dist/cjs/components/XAdkSender/styles.d.ts +15 -0
  14. package/dist/cjs/components/XAdkSender/styles.js +184 -5
  15. package/dist/cjs/components/XAdkSender/styles.js.map +2 -2
  16. package/dist/cjs/index.d.ts +1 -2
  17. package/dist/cjs/index.js +0 -3
  18. package/dist/cjs/index.js.map +3 -3
  19. package/dist/cjs/types/XAdkSender.d.ts +55 -0
  20. package/dist/cjs/types/XAdkSender.js.map +1 -1
  21. package/dist/esm/components/XAdkSender/InlineTagInput.d.ts +24 -0
  22. package/dist/esm/components/XAdkSender/InlineTagInput.js +437 -0
  23. package/dist/esm/components/XAdkSender/InlineTagInput.js.map +1 -0
  24. package/dist/esm/components/XAdkSender/InputTags.d.ts +8 -0
  25. package/dist/esm/components/XAdkSender/InputTags.js +36 -0
  26. package/dist/esm/components/XAdkSender/InputTags.js.map +1 -0
  27. package/dist/esm/components/XAdkSender/QuickList.d.ts +16 -0
  28. package/dist/esm/components/XAdkSender/QuickList.js +96 -0
  29. package/dist/esm/components/XAdkSender/QuickList.js.map +1 -0
  30. package/dist/esm/components/XAdkSender/index.d.ts +1 -6
  31. package/dist/esm/components/XAdkSender/index.js +327 -78
  32. package/dist/esm/components/XAdkSender/index.js.map +1 -1
  33. package/dist/esm/components/XAdkSender/styles.d.ts +15 -0
  34. package/dist/esm/components/XAdkSender/styles.js +29 -11
  35. package/dist/esm/components/XAdkSender/styles.js.map +1 -1
  36. package/dist/esm/index.d.ts +1 -2
  37. package/dist/esm/index.js +1 -2
  38. package/dist/esm/index.js.map +1 -1
  39. package/dist/esm/types/XAdkSender.d.ts +55 -0
  40. package/dist/esm/types/XAdkSender.js.map +1 -1
  41. package/dist/umd/chat-sdk.min.js +1 -1
  42. package/package.json +1 -1
  43. package/dist/cjs/components/XAdkSender/Switch.d.ts +0 -16
  44. package/dist/cjs/components/XAdkSender/Switch.js +0 -95
  45. package/dist/cjs/components/XAdkSender/Switch.js.map +0 -7
  46. package/dist/esm/components/XAdkSender/Switch.d.ts +0 -16
  47. package/dist/esm/components/XAdkSender/Switch.js +0 -53
  48. package/dist/esm/components/XAdkSender/Switch.js.map +0 -1
@@ -4,12 +4,18 @@ import _asyncToGenerator from "@babel/runtime/helpers/esm/asyncToGenerator";
4
4
  import _createForOfIteratorHelper from "@babel/runtime/helpers/esm/createForOfIteratorHelper";
5
5
  import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
6
6
  import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
7
- import React, { useState, useRef, useCallback, forwardRef, useImperativeHandle } from "react";
7
+ import React, { useState, useRef, useCallback, forwardRef, useImperativeHandle, useMemo, useEffect } from "react";
8
8
  import { Popconfirm, message, Tooltip, Input, Modal } from "antd";
9
9
  import { ClearOutlined, LoadingOutlined, ArrowUpOutlined, PaperClipOutlined } from "@ant-design/icons";
10
10
  import { useStyles } from "./styles";
11
11
  import FileGallery from "../FileGallery";
12
+ import QuickList from "./QuickList";
13
+ import InputTags from "./InputTags";
14
+ import InlineTagInput from "./InlineTagInput";
12
15
  import { getExt } from "../../utils/file";
16
+ import { jsx as _jsx } from "react/jsx-runtime";
17
+ import { Fragment as _Fragment } from "react/jsx-runtime";
18
+ import { jsxs as _jsxs } from "react/jsx-runtime";
13
19
  var XAdkSender = /*#__PURE__*/forwardRef(function (_ref, ref) {
14
20
  var _ref$clearBtnShow = _ref.clearBtnShow,
15
21
  clearBtnShow = _ref$clearBtnShow === void 0 ? true : _ref$clearBtnShow,
@@ -35,6 +41,8 @@ var XAdkSender = /*#__PURE__*/forwardRef(function (_ref, ref) {
35
41
  onUploadError = _ref.onUploadError,
36
42
  _ref$maxFileSize = _ref.maxFileSize,
37
43
  maxFileSize = _ref$maxFileSize === void 0 ? 10 : _ref$maxFileSize,
44
+ _ref$placeholder = _ref.placeholder,
45
+ placeholder = _ref$placeholder === void 0 ? "" : _ref$placeholder,
38
46
  _ref$validators = _ref.validators,
39
47
  customValidators = _ref$validators === void 0 ? [] : _ref$validators,
40
48
  _ref$allowedFileTypes = _ref.allowedFileTypes,
@@ -45,7 +53,18 @@ var XAdkSender = /*#__PURE__*/forwardRef(function (_ref, ref) {
45
53
  suffix = _ref.suffix,
46
54
  header = _ref.header,
47
55
  prefix = _ref.prefix,
48
- footer = _ref.footer;
56
+ footer = _ref.footer,
57
+ footerLeft = _ref.footerLeft,
58
+ _ref$quickKeys = _ref.quickKeys,
59
+ quickKeys = _ref$quickKeys === void 0 ? [] : _ref$quickKeys,
60
+ _ref$inlineTags = _ref.inlineTags,
61
+ inlineTags = _ref$inlineTags === void 0 ? false : _ref$inlineTags,
62
+ renderTag = _ref.renderTag,
63
+ controlledTags = _ref.tags,
64
+ _ref$defaultTags = _ref.defaultTags,
65
+ defaultTags = _ref$defaultTags === void 0 ? [] : _ref$defaultTags,
66
+ onTagsChange = _ref.onTagsChange,
67
+ onQuickKeyTrigger = _ref.onQuickKeyTrigger;
49
68
  var styles = useStyles();
50
69
  var isControlled = controlledValue !== undefined;
51
70
  var _useState = useState(defaultValue),
@@ -59,16 +78,51 @@ var XAdkSender = /*#__PURE__*/forwardRef(function (_ref, ref) {
59
78
  }
60
79
  onChange === null || onChange === void 0 || onChange(newValue);
61
80
  };
62
- var _useState3 = useState([]),
81
+
82
+ // tags 支持受控/非受控两种模式;inlineTags 打开时会和输入内容混排。
83
+ var isTagsControlled = controlledTags !== undefined;
84
+ var _useState3 = useState(defaultTags),
63
85
  _useState4 = _slicedToArray(_useState3, 2),
64
- files = _useState4[0],
65
- setFiles = _useState4[1];
66
- var _useState5 = useState(false),
86
+ internalTags = _useState4[0],
87
+ setInternalTags = _useState4[1];
88
+ var tags = isTagsControlled ? controlledTags : internalTags;
89
+ var setTags = function setTags(newTags) {
90
+ if (!isTagsControlled) {
91
+ setInternalTags(newTags);
92
+ }
93
+ onTagsChange === null || onTagsChange === void 0 || onTagsChange(newTags);
94
+ };
95
+ var _useState5 = useState([]),
67
96
  _useState6 = _slicedToArray(_useState5, 2),
68
- isDragOver = _useState6[0],
69
- setIsDragOver = _useState6[1];
97
+ files = _useState6[0],
98
+ setFiles = _useState6[1];
99
+ var _useState7 = useState(false),
100
+ _useState8 = _slicedToArray(_useState7, 2),
101
+ isDragOver = _useState8[0],
102
+ setIsDragOver = _useState8[1];
70
103
  var containerRef = useRef(null);
71
104
  var fileInputRef = useRef(null);
105
+ var textareaRef = useRef(null);
106
+ var inlineInputRef = useRef(null);
107
+
108
+ // 快捷键弹层状态:记录触发字符、关键词,以及触发字符在纯文本中的位置。
109
+ // SDK 不内置搜索框;业务方可在 onQuickKeyTrigger 中根据 keyword 自行更新 quickKeys.options。
110
+ var _useState9 = useState(null),
111
+ _useState10 = _slicedToArray(_useState9, 2),
112
+ activeQuickKey = _useState10[0],
113
+ setActiveQuickKey = _useState10[1];
114
+ var _useState11 = useState(""),
115
+ _useState12 = _slicedToArray(_useState11, 2),
116
+ quickKeyKeyword = _useState12[0],
117
+ setQuickKeyKeyword = _useState12[1];
118
+ var _useState13 = useState(-1),
119
+ _useState14 = _slicedToArray(_useState13, 2),
120
+ quickKeyTriggerIdx = _useState14[0],
121
+ setQuickKeyTriggerIdx = _useState14[1];
122
+ var _useState15 = useState(0),
123
+ _useState16 = _slicedToArray(_useState15, 2),
124
+ quickKeyActiveIndex = _useState16[0],
125
+ setQuickKeyActiveIndex = _useState16[1];
72
126
 
73
127
  // 生成唯一ID
74
128
  var generateId = function generateId() {
@@ -85,7 +139,6 @@ var XAdkSender = /*#__PURE__*/forwardRef(function (_ref, ref) {
85
139
  if ((allowedFileTypes === null || allowedFileTypes === void 0 ? void 0 : allowedFileTypes.length) > 0) {
86
140
  var ext = getExt(file);
87
141
  return allowedFileTypes.some(function (type) {
88
- // 1️⃣ MIME 校验
89
142
  if (type.includes("/")) {
90
143
  if (type.endsWith("/*")) {
91
144
  return file.type.startsWith(type.split("/")[0]);
@@ -101,12 +154,6 @@ var XAdkSender = /*#__PURE__*/forwardRef(function (_ref, ref) {
101
154
  return true;
102
155
  };
103
156
 
104
- // 检查文件大小
105
- var checkFileSize = function checkFileSize(file) {
106
- var maxSize = maxFileSize * 1024 * 1024;
107
- return file.size <= maxSize;
108
- };
109
-
110
157
  // 重复文件检测
111
158
  var isDuplicateFile = function isDuplicateFile(file, files) {
112
159
  return files.some(function (f) {
@@ -115,32 +162,24 @@ var XAdkSender = /*#__PURE__*/forwardRef(function (_ref, ref) {
115
162
  };
116
163
 
117
164
  // 内置校验器集合
118
- var builtInValidators = [
119
- // 数量校验(修复批量 bug)
120
- function (_file, _ref3) {
165
+ var builtInValidators = [function (_file, _ref3) {
121
166
  var files = _ref3.files;
122
167
  if (files.length >= maxFiles) {
123
168
  return "\u6700\u591A\u53EA\u80FD\u4E0A\u4F20 ".concat(maxFiles, " \u4E2A\u6587\u4EF6");
124
169
  }
125
170
  return null;
126
- },
127
- // 大小校验
128
- function (file) {
171
+ }, function (file) {
129
172
  var maxSize = maxFileSize * 1024 * 1024;
130
173
  if (file.size > maxSize) {
131
174
  return "\u6587\u4EF6\u5927\u5C0F\u4E0D\u80FD\u8D85\u8FC7 ".concat(maxFileSize, "MB");
132
175
  }
133
176
  return null;
134
- },
135
- // 类型校验
136
- function (file) {
177
+ }, function (file) {
137
178
  if (!checkFileType(file)) {
138
179
  return "不支持的文件类型";
139
180
  }
140
181
  return null;
141
- },
142
- // ⭐ 新增:去重校验
143
- function (file, _ref4) {
182
+ }, function (file, _ref4) {
144
183
  var files = _ref4.files;
145
184
  if (isDuplicateFile(file, files)) {
146
185
  return "文件已存在";
@@ -212,7 +251,7 @@ var XAdkSender = /*#__PURE__*/forwardRef(function (_ref, ref) {
212
251
  }
213
252
  }, [files, maxFiles, maxFileSize, allowedFileTypes]);
214
253
 
215
- // 暴露 addFiles 方法供外层(如 DefaultLayout 拖拽上传)调用
254
+ // 暴露 addFiles 方法
216
255
  useImperativeHandle(ref, function () {
217
256
  return {
218
257
  addFiles: function addFiles(rawFiles) {
@@ -221,6 +260,13 @@ var XAdkSender = /*#__PURE__*/forwardRef(function (_ref, ref) {
221
260
  };
222
261
  }, [handleFileSelect]);
223
262
 
263
+ // 触发文件选择
264
+ var triggerFileSelect = function triggerFileSelect() {
265
+ if (fileInputRef.current) {
266
+ fileInputRef.current.click();
267
+ }
268
+ };
269
+
224
270
  // 上传文件
225
271
  var uploadFiles = /*#__PURE__*/function () {
226
272
  var _ref5 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(fileList) {
@@ -236,7 +282,6 @@ var XAdkSender = /*#__PURE__*/forwardRef(function (_ref, ref) {
236
282
  while (1) switch (_context.prev = _context.next) {
237
283
  case 0:
238
284
  localFile = _step2.value;
239
- // 开始上传
240
285
  setFiles(function (prev) {
241
286
  return prev.map(function (f) {
242
287
  return f.id === localFile.id ? _objectSpread(_objectSpread({}, f), {}, {
@@ -354,13 +399,6 @@ var XAdkSender = /*#__PURE__*/forwardRef(function (_ref, ref) {
354
399
  });
355
400
  };
356
401
 
357
- // 触发文件选择
358
- var triggerFileSelect = function triggerFileSelect() {
359
- if (fileInputRef.current) {
360
- fileInputRef.current.click();
361
- }
362
- };
363
-
364
402
  // 处理拖拽事件
365
403
  var handleDragOver = useCallback(function (e) {
366
404
  e.preventDefault();
@@ -385,9 +423,168 @@ var XAdkSender = /*#__PURE__*/forwardRef(function (_ref, ref) {
385
423
  }
386
424
  }, [allowUpload, handleFileSelect]);
387
425
 
426
+ // 删除标签
427
+ var handleRemoveTag = useCallback(function (id) {
428
+ setTags(tags.filter(function (t) {
429
+ return t.id !== id;
430
+ }));
431
+ }, [tags, setTags]);
432
+
433
+ // 查找当前活跃的快捷键配置
434
+ var activeQuickKeyConfig = useMemo(function () {
435
+ if (!activeQuickKey) return null;
436
+ return quickKeys.find(function (qk) {
437
+ return qk.key === activeQuickKey;
438
+ }) || null;
439
+ }, [activeQuickKey, quickKeys]);
440
+ var activeQuickKeyOptionsLength = (activeQuickKeyConfig === null || activeQuickKeyConfig === void 0 ? void 0 : activeQuickKeyConfig.options.length) || 0;
441
+ useEffect(function () {
442
+ setQuickKeyActiveIndex(0);
443
+ }, [activeQuickKey]);
444
+ useEffect(function () {
445
+ if (activeQuickKeyOptionsLength <= 0) {
446
+ setQuickKeyActiveIndex(0);
447
+ return;
448
+ }
449
+
450
+ // 业务方可能在 onQuickKeyTrigger 中动态更新 options;
451
+ // 这里只做越界归一化,不重置有效索引,避免键盘高亮移动后又跳回第一项。
452
+ setQuickKeyActiveIndex(function (prev) {
453
+ return (prev % activeQuickKeyOptionsLength + activeQuickKeyOptionsLength) % activeQuickKeyOptionsLength;
454
+ });
455
+ }, [activeQuickKeyOptionsLength]);
456
+ var getNextQuickKeyIndex = useCallback(function (current, step) {
457
+ if (activeQuickKeyOptionsLength <= 0) return 0;
458
+ return (current + step + activeQuickKeyOptionsLength) % activeQuickKeyOptionsLength;
459
+ }, [activeQuickKeyOptionsLength]);
460
+
461
+ // 从当前光标前的连续文本片段中查找最近的快捷键,例如 abc@doc 会触发 @。
462
+ var detectQuickKey = useCallback(function (text, cursorPos) {
463
+ var quickKeyChars = quickKeys.map(function (qk) {
464
+ return qk.key;
465
+ });
466
+ if (quickKeyChars.length === 0) return;
467
+ var textBeforeCursor = text.slice(0, cursorPos);
468
+ var found = false;
469
+ for (var i = textBeforeCursor.length - 1; i >= 0; i--) {
470
+ var char = textBeforeCursor[i];
471
+ if (/\s/.test(char)) break;
472
+ if (quickKeyChars.includes(char)) {
473
+ var keyword = textBeforeCursor.slice(i + 1);
474
+ setActiveQuickKey(char);
475
+ setQuickKeyKeyword(keyword);
476
+ setQuickKeyTriggerIdx(i);
477
+ setQuickKeyActiveIndex(0);
478
+ onQuickKeyTrigger === null || onQuickKeyTrigger === void 0 || onQuickKeyTrigger(char, keyword);
479
+ found = true;
480
+ break;
481
+ }
482
+ }
483
+ if (!found && activeQuickKey) {
484
+ var triggerChar = text[quickKeyTriggerIdx];
485
+ var _keyword = text.slice(quickKeyTriggerIdx + 1, cursorPos);
486
+ if (quickKeyTriggerIdx < 0 || !triggerChar || !quickKeyChars.includes(triggerChar) || /\s/.test(_keyword)) {
487
+ setActiveQuickKey(null);
488
+ setQuickKeyKeyword("");
489
+ setQuickKeyTriggerIdx(-1);
490
+ setQuickKeyActiveIndex(0);
491
+ } else {
492
+ setQuickKeyKeyword(_keyword);
493
+ }
494
+ }
495
+ }, [activeQuickKey, onQuickKeyTrigger, quickKeyTriggerIdx, quickKeys]);
496
+
497
+ // 选择快捷项后转成结构化 tag;inline 模式会替换掉触发字符和关键词。
498
+ var handleQuickKeySelect = useCallback(function (option) {
499
+ var _activeQuickKeyConfig, _inlineInputRef$curre2, _textareaRef$current;
500
+ var newTag = {
501
+ id: generateId(),
502
+ label: option.label,
503
+ type: activeQuickKey || "unknown",
504
+ icon: option.icon,
505
+ data: option
506
+ };
507
+ activeQuickKeyConfig === null || activeQuickKeyConfig === void 0 || (_activeQuickKeyConfig = activeQuickKeyConfig.onSelect) === null || _activeQuickKeyConfig === void 0 || _activeQuickKeyConfig.call(activeQuickKeyConfig, option);
508
+ if (inlineTags) {
509
+ var _inlineInputRef$curre;
510
+ (_inlineInputRef$curre = inlineInputRef.current) === null || _inlineInputRef$curre === void 0 || _inlineInputRef$curre.insertTag(newTag, {
511
+ start: quickKeyTriggerIdx,
512
+ end: quickKeyTriggerIdx + 1 + quickKeyKeyword.length
513
+ });
514
+ } else {
515
+ setTags([].concat(_toConsumableArray(tags), [newTag]));
516
+
517
+ // 从输入框中删除快捷键字符和关键词
518
+ if (quickKeyTriggerIdx >= 0) {
519
+ var newValue = value.slice(0, quickKeyTriggerIdx) + value.slice(quickKeyTriggerIdx + 1 + quickKeyKeyword.length);
520
+ setValue(newValue);
521
+ }
522
+ }
523
+ setActiveQuickKey(null);
524
+ setQuickKeyKeyword("");
525
+ setQuickKeyTriggerIdx(-1);
526
+ setQuickKeyActiveIndex(0);
527
+ inlineTags ? (_inlineInputRef$curre2 = inlineInputRef.current) === null || _inlineInputRef$curre2 === void 0 ? void 0 : _inlineInputRef$curre2.focus() : (_textareaRef$current = textareaRef.current) === null || _textareaRef$current === void 0 ? void 0 : _textareaRef$current.focus();
528
+ }, [activeQuickKey, activeQuickKeyConfig, inlineTags, tags, setTags, value, quickKeyTriggerIdx, quickKeyKeyword, setValue]);
529
+
530
+ // 处理输入框变化(含快捷键检测)
531
+ var handleInputChange = function handleInputChange(e) {
532
+ var newValue = e.target.value;
533
+ setValue(newValue);
534
+
535
+ // 检测快捷键触发
536
+ detectQuickKey(newValue, e.target.selectionStart || 0);
537
+ };
538
+ var handleInlineInputChange = function handleInlineInputChange(newValue) {
539
+ var _inlineInputRef$curre3;
540
+ setValue(newValue);
541
+ // contenteditable 的 selection 不一定和 React state 同步,需实时读取内部光标 offset。
542
+ detectQuickKey(newValue, ((_inlineInputRef$curre3 = inlineInputRef.current) === null || _inlineInputRef$curre3 === void 0 ? void 0 : _inlineInputRef$curre3.getCursorOffset()) || newValue.length);
543
+ };
544
+ var handleQuickKeyByText = function handleQuickKeyByText(text, cursorPos) {
545
+ var quickKeyChars = quickKeys.map(function (qk) {
546
+ return qk.key;
547
+ });
548
+ if (quickKeyChars.length === 0) return;
549
+ var textBeforeCursor = text.slice(0, cursorPos);
550
+
551
+ // 检测刚输入的字符是否是快捷键
552
+ var lastChar = textBeforeCursor[cursorPos - 1];
553
+ if (lastChar && quickKeyChars.includes(lastChar)) {
554
+ // 上下键导航后会触发 keyup,此时光标前仍是同一个快捷键字符;
555
+ // 如果重复重置 activeIndex,视觉上会“移动一下又回到第一项”。
556
+ if (activeQuickKey === lastChar && quickKeyTriggerIdx === cursorPos - 1) {
557
+ return;
558
+ }
559
+ setActiveQuickKey(lastChar);
560
+ setQuickKeyKeyword("");
561
+ setQuickKeyTriggerIdx(cursorPos - 1);
562
+ setQuickKeyActiveIndex(0);
563
+ onQuickKeyTrigger === null || onQuickKeyTrigger === void 0 || onQuickKeyTrigger(lastChar, "");
564
+ }
565
+ };
566
+
567
+ // onChange 负责更新搜索词;onKeyUp 兜底捕获刚输入的快捷键字符。
568
+ var isQuickListControlKey = function isQuickListControlKey(key) {
569
+ return key === "ArrowDown" || key === "ArrowUp" || key === "Enter" || key === "Escape";
570
+ };
571
+ var handleKeyUp = function handleKeyUp(e) {
572
+ if (activeQuickKey && isQuickListControlKey(e.key)) return;
573
+ var target = e.target;
574
+ handleQuickKeyByText(target.value || "", target.selectionStart || 0);
575
+ };
576
+ var handleInlineKeyUp = function handleInlineKeyUp(e) {
577
+ var _inlineInputRef$curre4, _inlineInputRef$curre5;
578
+ if (activeQuickKey && isQuickListControlKey(e.key)) return;
579
+ // inline 输入区不是 textarea,不能读 event.target.value,只能从 ref 取纯文本。
580
+ var text = ((_inlineInputRef$curre4 = inlineInputRef.current) === null || _inlineInputRef$curre4 === void 0 ? void 0 : _inlineInputRef$curre4.getText()) || "";
581
+ var cursorPos = ((_inlineInputRef$curre5 = inlineInputRef.current) === null || _inlineInputRef$curre5 === void 0 ? void 0 : _inlineInputRef$curre5.getCursorOffset()) || text.length;
582
+ handleQuickKeyByText(text, cursorPos);
583
+ };
584
+
388
585
  // 处理提交
389
586
  var handleSubmit = function handleSubmit() {
390
- if (!value.trim() && files.length === 0) {
587
+ if (!value.trim() && files.length === 0 && tags.length === 0) {
391
588
  message.warning("请输入消息或选择文件");
392
589
  return;
393
590
  }
@@ -408,10 +605,12 @@ var XAdkSender = /*#__PURE__*/forwardRef(function (_ref, ref) {
408
605
  if (onSubmit) {
409
606
  onSubmit({
410
607
  text: value,
411
- files: formattedFiles
608
+ files: formattedFiles,
609
+ tags: tags
412
610
  });
413
611
  }
414
612
  setValue("");
613
+ setTags([]);
415
614
  setFiles(function (prev) {
416
615
  return prev.filter(function (f) {
417
616
  return f.status !== "success";
@@ -427,10 +626,12 @@ var XAdkSender = /*#__PURE__*/forwardRef(function (_ref, ref) {
427
626
  if (onSubmit) {
428
627
  onSubmit({
429
628
  text: value,
430
- files: formattedFiles
629
+ files: formattedFiles,
630
+ tags: tags
431
631
  });
432
632
  }
433
633
  setValue("");
634
+ setTags([]);
434
635
  setFiles(function (prev) {
435
636
  return prev.filter(function (f) {
436
637
  return f.status !== "success";
@@ -457,21 +658,45 @@ var XAdkSender = /*#__PURE__*/forwardRef(function (_ref, ref) {
457
658
  });
458
659
  };
459
660
 
460
- // 处理输入框变化
461
- var handleInputChange = function handleInputChange(e) {
462
- var newValue = e.target.value;
463
- setValue(newValue);
464
- };
465
-
466
661
  // 处理回车键
467
662
  var handleKeyDown = function handleKeyDown(e) {
468
- if (e.key === "Enter" && !e.shiftKey) {
663
+ var quickKeyOptions = (activeQuickKeyConfig === null || activeQuickKeyConfig === void 0 ? void 0 : activeQuickKeyConfig.options) || [];
664
+ if (activeQuickKey && quickKeyOptions.length > 0) {
665
+ if (e.key === "ArrowDown") {
666
+ e.preventDefault();
667
+ setQuickKeyActiveIndex(function (prev) {
668
+ return getNextQuickKeyIndex(prev, 1);
669
+ });
670
+ return;
671
+ }
672
+ if (e.key === "ArrowUp") {
673
+ e.preventDefault();
674
+ setQuickKeyActiveIndex(function (prev) {
675
+ return getNextQuickKeyIndex(prev, -1);
676
+ });
677
+ return;
678
+ }
679
+ if (e.key === "Enter") {
680
+ e.preventDefault();
681
+ handleQuickKeySelect(quickKeyOptions[Math.min(quickKeyActiveIndex, quickKeyOptions.length - 1)]);
682
+ return;
683
+ }
684
+ if (e.key === "Escape") {
685
+ e.preventDefault();
686
+ setActiveQuickKey(null);
687
+ setQuickKeyKeyword("");
688
+ setQuickKeyTriggerIdx(-1);
689
+ setQuickKeyActiveIndex(0);
690
+ return;
691
+ }
692
+ }
693
+ if (e.key === "Enter" && !e.shiftKey && !activeQuickKey) {
469
694
  e.preventDefault();
470
695
  handleSubmit();
471
696
  }
472
697
  };
473
698
 
474
- // 渲染文件列表 - 使用新的 FileGallery 组件
699
+ // 渲染文件列表
475
700
  var renderFileList = function renderFileList() {
476
701
  if (files.length === 0) return null;
477
702
  return /*#__PURE__*/_jsx("div", {
@@ -484,7 +709,6 @@ var XAdkSender = /*#__PURE__*/forwardRef(function (_ref, ref) {
484
709
  children: files.map(function (file) {
485
710
  return /*#__PURE__*/_jsx(FileGallery, {
486
711
  file: file,
487
- type: "file",
488
712
  removable: true,
489
713
  onRemove: handleRemoveFile
490
714
  }, file.id);
@@ -500,10 +724,10 @@ var XAdkSender = /*#__PURE__*/forwardRef(function (_ref, ref) {
500
724
  var hasFiles = files.some(function (f) {
501
725
  return f.status === "success";
502
726
  });
503
- var canSend = hasContent || hasFiles;
727
+ var hasTags = tags.length > 0;
728
+ var canSend = hasContent || hasFiles || hasTags;
504
729
 
505
- // 定义按钮组件(供外部 slot 函数通过 actionsComponents 使用)
506
- // 注意:sendButtonRender 的结果直接内联到 defaultSuffix 中,避免组件引用变化导致闪烁
730
+ // 定义按钮组件
507
731
  var SendButton = function SendButton(props) {
508
732
  if (sendButtonRender) {
509
733
  return /*#__PURE__*/_jsx(_Fragment, {
@@ -579,19 +803,10 @@ var XAdkSender = /*#__PURE__*/forwardRef(function (_ref, ref) {
579
803
  return slot;
580
804
  };
581
805
 
582
- // 默认的后缀内容(操作按钮组) - 直接内联渲染避免组件引用变化导致 unmount/remount
583
- var defaultSuffix = /*#__PURE__*/_jsxs("div", {
806
+ // 默认后缀仅保留发送/停止按钮;上传与清空统一放到底部 actionBar,方便业务扩展左侧按钮组。
807
+ var defaultSuffix = /*#__PURE__*/_jsx("div", {
584
808
  className: styles.buttonGroup,
585
- children: [allowUpload && /*#__PURE__*/_jsx(Tooltip, {
586
- title: "\u4E0A\u4F20\u6587\u4EF6",
587
- children: /*#__PURE__*/_jsx("button", {
588
- className: "".concat(styles.iconButton, " ").concat(styles.uploadButton),
589
- onClick: triggerFileSelect,
590
- disabled: isDisabled,
591
- "aria-label": "\u4E0A\u4F20\u6587\u4EF6",
592
- children: /*#__PURE__*/_jsx(PaperClipOutlined, {})
593
- })
594
- }), sendButtonRender ? sendButtonRender({
809
+ children: sendButtonRender ? sendButtonRender({
595
810
  loading: loading,
596
811
  disabled: uploading || disabled,
597
812
  canSend: canSend,
@@ -608,6 +823,16 @@ var XAdkSender = /*#__PURE__*/forwardRef(function (_ref, ref) {
608
823
  spin: true
609
824
  }) : /*#__PURE__*/_jsx(ArrowUpOutlined, {})
610
825
  })
826
+ })
827
+ });
828
+ var defaultActionBar = /*#__PURE__*/_jsxs("div", {
829
+ className: styles.actionBar,
830
+ children: [/*#__PURE__*/_jsxs("div", {
831
+ className: styles.actionBarLeft,
832
+ children: [allowUpload && /*#__PURE__*/_jsx(UploadButton, {}), renderSlot(footerLeft, false)]
833
+ }), /*#__PURE__*/_jsxs("div", {
834
+ className: styles.actionBarRight,
835
+ children: [clearBtnShow && /*#__PURE__*/_jsx(ClearButton, {}), renderSlot(suffix, defaultSuffix)]
611
836
  })]
612
837
  });
613
838
  return /*#__PURE__*/_jsxs("div", {
@@ -634,16 +859,32 @@ var XAdkSender = /*#__PURE__*/forwardRef(function (_ref, ref) {
634
859
  className: styles.mainArea,
635
860
  children: /*#__PURE__*/_jsxs("div", {
636
861
  className: styles.senderWrap,
637
- children: [/*#__PURE__*/_jsxs("div", {
862
+ children: [!inlineTags && /*#__PURE__*/_jsx(InputTags, {
863
+ tags: tags,
864
+ onRemove: handleRemoveTag
865
+ }), /*#__PURE__*/_jsxs("div", {
638
866
  className: styles.inputAndButtons,
639
- children: [clearBtnShow && /*#__PURE__*/_jsx(ClearButton, {}), renderSlot(prefix, false), /*#__PURE__*/_jsx("div", {
867
+ children: [renderSlot(prefix, false), inlineTags ? /*#__PURE__*/_jsx(InlineTagInput, {
868
+ ref: inlineInputRef,
869
+ value: value,
870
+ tags: tags,
871
+ placeholder: placeholder,
872
+ disabled: isDisabled,
873
+ onChange: handleInlineInputChange,
874
+ onTagsChange: setTags,
875
+ onKeyDown: handleKeyDown,
876
+ onKeyUp: handleInlineKeyUp,
877
+ renderTag: renderTag
878
+ }) : /*#__PURE__*/_jsx("div", {
640
879
  className: styles.textAreaWrapper,
641
880
  children: /*#__PURE__*/_jsx(Input.TextArea, {
881
+ ref: textareaRef,
642
882
  className: styles.textArea,
643
883
  value: value,
644
884
  onChange: handleInputChange,
645
885
  onKeyDown: handleKeyDown,
646
- placeholder: "\u8BF7\u8F93\u5165\u6D88\u606F...",
886
+ onKeyUp: handleKeyUp,
887
+ placeholder: placeholder,
647
888
  autoSize: {
648
889
  minRows: 1,
649
890
  maxRows: 4
@@ -655,21 +896,29 @@ var XAdkSender = /*#__PURE__*/forwardRef(function (_ref, ref) {
655
896
  padding: 0
656
897
  }
657
898
  })
658
- }), renderSlot(suffix, defaultSuffix)]
659
- }), renderSlot(footer, /*#__PURE__*/_jsx("div", {
660
- className: styles.tip,
661
- children: "\u5185\u5BB9\u7531AI\u751F\u6210,\u65E0\u6CD5\u786E\u4FDD\u771F\u5B9E\u51C6\u786E,\u4EC5\u4F9B\u53C2\u8003"
662
- }))]
899
+ })]
900
+ }), activeQuickKey && activeQuickKeyConfig && /*#__PURE__*/_jsx("div", {
901
+ className: styles.quickListWrapper,
902
+ children: /*#__PURE__*/_jsx(QuickList, {
903
+ config: activeQuickKeyConfig,
904
+ activeIndex: quickKeyActiveIndex,
905
+ onSelect: handleQuickKeySelect,
906
+ onClose: function onClose() {
907
+ setActiveQuickKey(null);
908
+ setQuickKeyKeyword("");
909
+ setQuickKeyTriggerIdx(-1);
910
+ setQuickKeyActiveIndex(0);
911
+ },
912
+ visible: true
913
+ })
914
+ }), footer === false ? defaultActionBar : renderSlot(footer, defaultActionBar)]
663
915
  })
916
+ }), !footer && /*#__PURE__*/_jsx("div", {
917
+ className: styles.tip,
918
+ children: "\u5185\u5BB9\u7531AI\u751F\u6210,\u65E0\u6CD5\u786E\u4FDD\u771F\u5B9E\u51C6\u786E,\u4EC5\u4F9B\u53C2\u8003"
664
919
  })]
665
920
  });
666
921
  });
667
922
  XAdkSender.displayName = "XAdkSender";
668
- import XAdkSenderSwitch from "./Switch";
669
- import { jsx as _jsx } from "react/jsx-runtime";
670
- import { Fragment as _Fragment } from "react/jsx-runtime";
671
- import { jsxs as _jsxs } from "react/jsx-runtime";
672
- var CompoundSender = XAdkSender;
673
- CompoundSender.Switch = XAdkSenderSwitch;
674
- export default CompoundSender;
923
+ export default XAdkSender;
675
924
  //# sourceMappingURL=index.js.map