@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.
- package/dist/cjs/components/XAdkSender/InlineTagInput.d.ts +24 -0
- package/dist/cjs/components/XAdkSender/InlineTagInput.js +461 -0
- package/dist/cjs/components/XAdkSender/InlineTagInput.js.map +7 -0
- package/dist/cjs/components/XAdkSender/InputTags.d.ts +8 -0
- package/dist/cjs/components/XAdkSender/InputTags.js +51 -0
- package/dist/cjs/components/XAdkSender/InputTags.js.map +7 -0
- package/dist/cjs/components/XAdkSender/QuickList.d.ts +16 -0
- package/dist/cjs/components/XAdkSender/QuickList.js +105 -0
- package/dist/cjs/components/XAdkSender/QuickList.js.map +7 -0
- package/dist/cjs/components/XAdkSender/index.d.ts +1 -6
- package/dist/cjs/components/XAdkSender/index.js +289 -78
- package/dist/cjs/components/XAdkSender/index.js.map +3 -3
- package/dist/cjs/components/XAdkSender/styles.d.ts +15 -0
- package/dist/cjs/components/XAdkSender/styles.js +184 -5
- package/dist/cjs/components/XAdkSender/styles.js.map +2 -2
- package/dist/cjs/index.d.ts +1 -2
- package/dist/cjs/index.js +0 -3
- package/dist/cjs/index.js.map +3 -3
- package/dist/cjs/types/XAdkSender.d.ts +55 -0
- package/dist/cjs/types/XAdkSender.js.map +1 -1
- package/dist/esm/components/XAdkSender/InlineTagInput.d.ts +24 -0
- package/dist/esm/components/XAdkSender/InlineTagInput.js +437 -0
- package/dist/esm/components/XAdkSender/InlineTagInput.js.map +1 -0
- package/dist/esm/components/XAdkSender/InputTags.d.ts +8 -0
- package/dist/esm/components/XAdkSender/InputTags.js +36 -0
- package/dist/esm/components/XAdkSender/InputTags.js.map +1 -0
- package/dist/esm/components/XAdkSender/QuickList.d.ts +16 -0
- package/dist/esm/components/XAdkSender/QuickList.js +96 -0
- package/dist/esm/components/XAdkSender/QuickList.js.map +1 -0
- package/dist/esm/components/XAdkSender/index.d.ts +1 -6
- package/dist/esm/components/XAdkSender/index.js +327 -78
- package/dist/esm/components/XAdkSender/index.js.map +1 -1
- package/dist/esm/components/XAdkSender/styles.d.ts +15 -0
- package/dist/esm/components/XAdkSender/styles.js +29 -11
- package/dist/esm/components/XAdkSender/styles.js.map +1 -1
- package/dist/esm/index.d.ts +1 -2
- package/dist/esm/index.js +1 -2
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/types/XAdkSender.d.ts +55 -0
- package/dist/esm/types/XAdkSender.js.map +1 -1
- package/dist/umd/chat-sdk.min.js +1 -1
- package/package.json +1 -1
- package/dist/cjs/components/XAdkSender/Switch.d.ts +0 -16
- package/dist/cjs/components/XAdkSender/Switch.js +0 -95
- package/dist/cjs/components/XAdkSender/Switch.js.map +0 -7
- package/dist/esm/components/XAdkSender/Switch.d.ts +0 -16
- package/dist/esm/components/XAdkSender/Switch.js +0 -53
- 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
|
-
|
|
81
|
+
|
|
82
|
+
// tags 支持受控/非受控两种模式;inlineTags 打开时会和输入内容混排。
|
|
83
|
+
var isTagsControlled = controlledTags !== undefined;
|
|
84
|
+
var _useState3 = useState(defaultTags),
|
|
63
85
|
_useState4 = _slicedToArray(_useState3, 2),
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
var
|
|
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
|
-
|
|
69
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
// 渲染文件列表
|
|
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
|
|
727
|
+
var hasTags = tags.length > 0;
|
|
728
|
+
var canSend = hasContent || hasFiles || hasTags;
|
|
504
729
|
|
|
505
|
-
//
|
|
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
|
-
//
|
|
583
|
-
var defaultSuffix = /*#__PURE__*/
|
|
806
|
+
// 默认后缀仅保留发送/停止按钮;上传与清空统一放到底部 actionBar,方便业务扩展左侧按钮组。
|
|
807
|
+
var defaultSuffix = /*#__PURE__*/_jsx("div", {
|
|
584
808
|
className: styles.buttonGroup,
|
|
585
|
-
children:
|
|
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__*/
|
|
862
|
+
children: [!inlineTags && /*#__PURE__*/_jsx(InputTags, {
|
|
863
|
+
tags: tags,
|
|
864
|
+
onRemove: handleRemoveTag
|
|
865
|
+
}), /*#__PURE__*/_jsxs("div", {
|
|
638
866
|
className: styles.inputAndButtons,
|
|
639
|
-
children: [
|
|
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
|
-
|
|
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
|
-
})
|
|
659
|
-
}),
|
|
660
|
-
className: styles.
|
|
661
|
-
children:
|
|
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
|
-
|
|
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
|