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

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 (78) hide show
  1. package/dist/cjs/components/Sources/components/CarouselCard.d.ts +12 -0
  2. package/dist/cjs/components/Sources/components/CarouselCard.js +130 -0
  3. package/dist/cjs/components/Sources/components/CarouselCard.js.map +7 -0
  4. package/dist/cjs/components/Sources/index.d.ts +5 -0
  5. package/dist/cjs/components/Sources/index.js +162 -0
  6. package/dist/cjs/components/Sources/index.js.map +7 -0
  7. package/dist/cjs/components/Sources/styles.d.ts +59 -0
  8. package/dist/cjs/components/Sources/styles.js +179 -0
  9. package/dist/cjs/components/Sources/styles.js.map +7 -0
  10. package/dist/cjs/components/XAdkSender/InlineTagInput.d.ts +25 -0
  11. package/dist/cjs/components/XAdkSender/InlineTagInput.js +485 -0
  12. package/dist/cjs/components/XAdkSender/InlineTagInput.js.map +7 -0
  13. package/dist/cjs/components/XAdkSender/InputTags.d.ts +8 -0
  14. package/dist/cjs/components/XAdkSender/InputTags.js +51 -0
  15. package/dist/cjs/components/XAdkSender/InputTags.js.map +7 -0
  16. package/dist/cjs/components/XAdkSender/QuickList.d.ts +16 -0
  17. package/dist/cjs/components/XAdkSender/QuickList.js +105 -0
  18. package/dist/cjs/components/XAdkSender/QuickList.js.map +7 -0
  19. package/dist/cjs/components/XAdkSender/index.d.ts +1 -6
  20. package/dist/cjs/components/XAdkSender/index.js +350 -84
  21. package/dist/cjs/components/XAdkSender/index.js.map +3 -3
  22. package/dist/cjs/components/XAdkSender/styles.d.ts +15 -0
  23. package/dist/cjs/components/XAdkSender/styles.js +184 -5
  24. package/dist/cjs/components/XAdkSender/styles.js.map +2 -2
  25. package/dist/cjs/index.d.ts +4 -2
  26. package/dist/cjs/index.js +3 -3
  27. package/dist/cjs/index.js.map +3 -3
  28. package/dist/cjs/types/Sources.d.ts +30 -0
  29. package/dist/cjs/types/Sources.js +18 -0
  30. package/dist/cjs/types/Sources.js.map +7 -0
  31. package/dist/cjs/types/XAdkSender.d.ts +92 -4
  32. package/dist/cjs/types/XAdkSender.js.map +1 -1
  33. package/dist/cjs/types/index.d.ts +1 -0
  34. package/dist/cjs/types/index.js +3 -1
  35. package/dist/cjs/types/index.js.map +2 -2
  36. package/dist/esm/components/Sources/components/CarouselCard.d.ts +12 -0
  37. package/dist/esm/components/Sources/components/CarouselCard.js +107 -0
  38. package/dist/esm/components/Sources/components/CarouselCard.js.map +1 -0
  39. package/dist/esm/components/Sources/index.d.ts +5 -0
  40. package/dist/esm/components/Sources/index.js +127 -0
  41. package/dist/esm/components/Sources/index.js.map +1 -0
  42. package/dist/esm/components/Sources/styles.d.ts +59 -0
  43. package/dist/esm/components/Sources/styles.js +34 -0
  44. package/dist/esm/components/Sources/styles.js.map +1 -0
  45. package/dist/esm/components/XAdkSender/InlineTagInput.d.ts +25 -0
  46. package/dist/esm/components/XAdkSender/InlineTagInput.js +467 -0
  47. package/dist/esm/components/XAdkSender/InlineTagInput.js.map +1 -0
  48. package/dist/esm/components/XAdkSender/InputTags.d.ts +8 -0
  49. package/dist/esm/components/XAdkSender/InputTags.js +36 -0
  50. package/dist/esm/components/XAdkSender/InputTags.js.map +1 -0
  51. package/dist/esm/components/XAdkSender/QuickList.d.ts +16 -0
  52. package/dist/esm/components/XAdkSender/QuickList.js +96 -0
  53. package/dist/esm/components/XAdkSender/QuickList.js.map +1 -0
  54. package/dist/esm/components/XAdkSender/index.d.ts +1 -6
  55. package/dist/esm/components/XAdkSender/index.js +407 -88
  56. package/dist/esm/components/XAdkSender/index.js.map +1 -1
  57. package/dist/esm/components/XAdkSender/styles.d.ts +15 -0
  58. package/dist/esm/components/XAdkSender/styles.js +29 -11
  59. package/dist/esm/components/XAdkSender/styles.js.map +1 -1
  60. package/dist/esm/index.d.ts +4 -2
  61. package/dist/esm/index.js +4 -2
  62. package/dist/esm/index.js.map +1 -1
  63. package/dist/esm/types/Sources.d.ts +30 -0
  64. package/dist/esm/types/Sources.js +2 -0
  65. package/dist/esm/types/Sources.js.map +1 -0
  66. package/dist/esm/types/XAdkSender.d.ts +92 -4
  67. package/dist/esm/types/XAdkSender.js.map +1 -1
  68. package/dist/esm/types/index.d.ts +1 -0
  69. package/dist/esm/types/index.js +1 -0
  70. package/dist/esm/types/index.js.map +1 -1
  71. package/dist/umd/chat-sdk.min.js +1 -1
  72. package/package.json +1 -1
  73. package/dist/cjs/components/XAdkSender/Switch.d.ts +0 -16
  74. package/dist/cjs/components/XAdkSender/Switch.js +0 -95
  75. package/dist/cjs/components/XAdkSender/Switch.js.map +0 -7
  76. package/dist/esm/components/XAdkSender/Switch.d.ts +0 -16
  77. package/dist/esm/components/XAdkSender/Switch.js +0 -53
  78. package/dist/esm/components/XAdkSender/Switch.js.map +0 -1
@@ -37,8 +37,10 @@ var import_antd = require("antd");
37
37
  var import_icons = require("@ant-design/icons");
38
38
  var import_styles = require("./styles");
39
39
  var import_FileGallery = __toESM(require("../FileGallery"));
40
+ var import_QuickList = __toESM(require("./QuickList"));
41
+ var import_InputTags = __toESM(require("./InputTags"));
42
+ var import_InlineTagInput = __toESM(require("./InlineTagInput"));
40
43
  var import_file = require("../../utils/file");
41
- var import_Switch = __toESM(require("./Switch"));
42
44
  var import_jsx_runtime = require("react/jsx-runtime");
43
45
  var XAdkSender = (0, import_react.forwardRef)(
44
46
  ({
@@ -59,28 +61,25 @@ var XAdkSender = (0, import_react.forwardRef)(
59
61
  onUploadSuccess,
60
62
  onUploadError,
61
63
  maxFileSize = 10,
64
+ placeholder = "",
62
65
  validators: customValidators = [],
63
- // allowedFileTypes = [
64
- // "image/*",
65
- // "audio/*",
66
- // "video/*",
67
- // "application/pdf",
68
- // "text/plain",
69
- // ".doc",
70
- // ".docx",
71
- // ".xls",
72
- // ".xlsx",
73
- // ".ppt",
74
- // ".pptx",
75
- // "",
76
- // ],
77
66
  allowedFileTypes = [],
78
67
  maxFiles = Infinity,
79
68
  sendButtonRender,
80
69
  suffix,
81
70
  header,
82
71
  prefix,
83
- footer
72
+ footer,
73
+ footerLeft,
74
+ quickKeys = [],
75
+ inlineTags = false,
76
+ renderTag,
77
+ tags: controlledTags,
78
+ defaultTags = [],
79
+ onTagsChange,
80
+ onQuickKeyTrigger,
81
+ submitFormat = "text",
82
+ formatTag
84
83
  }, ref) => {
85
84
  const styles = (0, import_styles.useStyles)();
86
85
  const isControlled = controlledValue !== void 0;
@@ -92,10 +91,25 @@ var XAdkSender = (0, import_react.forwardRef)(
92
91
  }
93
92
  onChange == null ? void 0 : onChange(newValue);
94
93
  };
94
+ const isTagsControlled = controlledTags !== void 0;
95
+ const [internalTags, setInternalTags] = (0, import_react.useState)(defaultTags);
96
+ const tags = isTagsControlled ? controlledTags : internalTags;
97
+ const setTags = (newTags) => {
98
+ if (!isTagsControlled) {
99
+ setInternalTags(newTags);
100
+ }
101
+ onTagsChange == null ? void 0 : onTagsChange(newTags);
102
+ };
95
103
  const [files, setFiles] = (0, import_react.useState)([]);
96
104
  const [isDragOver, setIsDragOver] = (0, import_react.useState)(false);
97
105
  const containerRef = (0, import_react.useRef)(null);
98
106
  const fileInputRef = (0, import_react.useRef)(null);
107
+ const textareaRef = (0, import_react.useRef)(null);
108
+ const inlineInputRef = (0, import_react.useRef)(null);
109
+ const [activeQuickKey, setActiveQuickKey] = (0, import_react.useState)(null);
110
+ const [quickKeyKeyword, setQuickKeyKeyword] = (0, import_react.useState)("");
111
+ const [quickKeyTriggerIdx, setQuickKeyTriggerIdx] = (0, import_react.useState)(-1);
112
+ const [quickKeyActiveIndex, setQuickKeyActiveIndex] = (0, import_react.useState)(0);
99
113
  const generateId = () => {
100
114
  return Date.now().toString(36) + Math.random().toString(36).substr(2);
101
115
  };
@@ -103,6 +117,65 @@ var XAdkSender = (0, import_react.forwardRef)(
103
117
  const data = (response == null ? void 0 : response.data) ?? response;
104
118
  return (Array.isArray(data) ? data[0] : data) ?? {};
105
119
  };
120
+ const escapeXml = (text) => text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&apos;");
121
+ const escapeMarkdownLabel = (text) => text.replace(/\\/g, "\\\\").replace(/\]/g, "\\]");
122
+ const getTagSubmitValue = (tag) => {
123
+ var _a, _b;
124
+ return String(tag.value ?? ((_a = tag.data) == null ? void 0 : _a.value) ?? ((_b = tag.data) == null ? void 0 : _b.name) ?? tag.label ?? "");
125
+ };
126
+ const defaultFormatTag = (tag, format, index) => {
127
+ const value2 = getTagSubmitValue(tag);
128
+ if (format === "xml") {
129
+ return `<tag type="${escapeXml(tag.type)}" id="${escapeXml(tag.id)}" label="${escapeXml(tag.label)}" value="${escapeXml(value2)}" />`;
130
+ }
131
+ if (format === "markdown") {
132
+ return `[/${escapeMarkdownLabel(tag.label)}](xadk-tag://${encodeURIComponent(tag.type)}/${encodeURIComponent(tag.id)})`;
133
+ }
134
+ return `/${value2 || `tag-${index + 1}`}`;
135
+ };
136
+ const serializeTag = (tag, format, index) => (formatTag == null ? void 0 : formatTag(tag, { format, index })) ?? defaultFormatTag(tag, format, index);
137
+ const getSubmitParts = (0, import_react.useCallback)(() => {
138
+ var _a;
139
+ if (inlineTags) {
140
+ const parts = ((_a = inlineInputRef.current) == null ? void 0 : _a.getParts()) || [];
141
+ if (parts.length > 0)
142
+ return parts;
143
+ }
144
+ const textParts = value ? [{ type: "text", text: value }] : [];
145
+ const tagParts = tags.map((tag) => ({ type: "tag", tag }));
146
+ return [...tagParts, ...textParts];
147
+ }, [inlineTags, tags, value]);
148
+ const serializeParts = (parts, format) => {
149
+ if (format === "structured") {
150
+ return parts.reduce(
151
+ (content, part) => content + (part.type === "text" ? part.text : ""),
152
+ ""
153
+ );
154
+ }
155
+ let tagIndex = 0;
156
+ return parts.map((part) => {
157
+ if (part.type === "text")
158
+ return part.text;
159
+ const result = serializeTag(part.tag, format, tagIndex);
160
+ tagIndex += 1;
161
+ return result;
162
+ }).join("");
163
+ };
164
+ const createSubmitData = (formattedFiles) => {
165
+ const parts = getSubmitParts();
166
+ const rawText = parts.reduce(
167
+ (content, part) => content + (part.type === "text" ? part.text : ""),
168
+ ""
169
+ );
170
+ return {
171
+ text: serializeParts(parts, submitFormat),
172
+ rawText,
173
+ format: submitFormat,
174
+ parts,
175
+ files: formattedFiles,
176
+ tags
177
+ };
178
+ };
106
179
  const checkFileType = (file) => {
107
180
  if ((allowedFileTypes == null ? void 0 : allowedFileTypes.length) > 0) {
108
181
  const ext = (0, import_file.getExt)(file);
@@ -121,22 +194,16 @@ var XAdkSender = (0, import_react.forwardRef)(
121
194
  }
122
195
  return true;
123
196
  };
124
- const checkFileSize = (file) => {
125
- const maxSize = maxFileSize * 1024 * 1024;
126
- return file.size <= maxSize;
127
- };
128
197
  const isDuplicateFile = (file, files2) => {
129
198
  return files2.some((f) => f.name === file.name && f.size === file.size);
130
199
  };
131
200
  const builtInValidators = [
132
- // 数量校验(修复批量 bug)
133
201
  (_file, { files: files2 }) => {
134
202
  if (files2.length >= maxFiles) {
135
203
  return `最多只能上传 ${maxFiles} 个文件`;
136
204
  }
137
205
  return null;
138
206
  },
139
- // 大小校验
140
207
  (file) => {
141
208
  const maxSize = maxFileSize * 1024 * 1024;
142
209
  if (file.size > maxSize) {
@@ -144,14 +211,12 @@ var XAdkSender = (0, import_react.forwardRef)(
144
211
  }
145
212
  return null;
146
213
  },
147
- // 类型校验
148
214
  (file) => {
149
215
  if (!checkFileType(file)) {
150
216
  return "不支持的文件类型";
151
217
  }
152
218
  return null;
153
219
  },
154
- // ⭐ 新增:去重校验
155
220
  (file, { files: files2 }) => {
156
221
  if (isDuplicateFile(file, files2)) {
157
222
  return "文件已存在";
@@ -215,6 +280,11 @@ var XAdkSender = (0, import_react.forwardRef)(
215
280
  }),
216
281
  [handleFileSelect]
217
282
  );
283
+ const triggerFileSelect = () => {
284
+ if (fileInputRef.current) {
285
+ fileInputRef.current.click();
286
+ }
287
+ };
218
288
  const uploadFiles = async (fileList) => {
219
289
  for (const localFile of fileList) {
220
290
  setFiles(
@@ -289,11 +359,6 @@ var XAdkSender = (0, import_react.forwardRef)(
289
359
  return next;
290
360
  });
291
361
  };
292
- const triggerFileSelect = () => {
293
- if (fileInputRef.current) {
294
- fileInputRef.current.click();
295
- }
296
- };
297
362
  const handleDragOver = (0, import_react.useCallback)(
298
363
  (e) => {
299
364
  e.preventDefault();
@@ -325,8 +390,165 @@ var XAdkSender = (0, import_react.forwardRef)(
325
390
  },
326
391
  [allowUpload, handleFileSelect]
327
392
  );
393
+ const handleRemoveTag = (0, import_react.useCallback)(
394
+ (id) => {
395
+ setTags(tags.filter((t) => t.id !== id));
396
+ },
397
+ [tags, setTags]
398
+ );
399
+ const activeQuickKeyConfig = (0, import_react.useMemo)(() => {
400
+ if (!activeQuickKey)
401
+ return null;
402
+ return quickKeys.find((qk) => qk.key === activeQuickKey) || null;
403
+ }, [activeQuickKey, quickKeys]);
404
+ const activeQuickKeyOptionsLength = (activeQuickKeyConfig == null ? void 0 : activeQuickKeyConfig.options.length) || 0;
405
+ (0, import_react.useEffect)(() => {
406
+ setQuickKeyActiveIndex(0);
407
+ }, [activeQuickKey]);
408
+ (0, import_react.useEffect)(() => {
409
+ if (activeQuickKeyOptionsLength <= 0) {
410
+ setQuickKeyActiveIndex(0);
411
+ return;
412
+ }
413
+ setQuickKeyActiveIndex(
414
+ (prev) => (prev % activeQuickKeyOptionsLength + activeQuickKeyOptionsLength) % activeQuickKeyOptionsLength
415
+ );
416
+ }, [activeQuickKeyOptionsLength]);
417
+ const getNextQuickKeyIndex = (0, import_react.useCallback)(
418
+ (current, step) => {
419
+ if (activeQuickKeyOptionsLength <= 0)
420
+ return 0;
421
+ return (current + step + activeQuickKeyOptionsLength) % activeQuickKeyOptionsLength;
422
+ },
423
+ [activeQuickKeyOptionsLength]
424
+ );
425
+ const detectQuickKey = (0, import_react.useCallback)(
426
+ (text, cursorPos) => {
427
+ const quickKeyChars = quickKeys.map((qk) => qk.key);
428
+ if (quickKeyChars.length === 0)
429
+ return;
430
+ const textBeforeCursor = text.slice(0, cursorPos);
431
+ let found = false;
432
+ for (let i = textBeforeCursor.length - 1; i >= 0; i--) {
433
+ const char = textBeforeCursor[i];
434
+ if (/\s/.test(char))
435
+ break;
436
+ if (quickKeyChars.includes(char)) {
437
+ const keyword = textBeforeCursor.slice(i + 1);
438
+ setActiveQuickKey(char);
439
+ setQuickKeyKeyword(keyword);
440
+ setQuickKeyTriggerIdx(i);
441
+ setQuickKeyActiveIndex(0);
442
+ onQuickKeyTrigger == null ? void 0 : onQuickKeyTrigger(char, keyword);
443
+ found = true;
444
+ break;
445
+ }
446
+ }
447
+ if (!found && activeQuickKey) {
448
+ const triggerChar = text[quickKeyTriggerIdx];
449
+ const keyword = text.slice(quickKeyTriggerIdx + 1, cursorPos);
450
+ if (quickKeyTriggerIdx < 0 || !triggerChar || !quickKeyChars.includes(triggerChar) || /\s/.test(keyword)) {
451
+ setActiveQuickKey(null);
452
+ setQuickKeyKeyword("");
453
+ setQuickKeyTriggerIdx(-1);
454
+ setQuickKeyActiveIndex(0);
455
+ } else {
456
+ setQuickKeyKeyword(keyword);
457
+ }
458
+ }
459
+ },
460
+ [activeQuickKey, onQuickKeyTrigger, quickKeyTriggerIdx, quickKeys]
461
+ );
462
+ const handleQuickKeySelect = (0, import_react.useCallback)(
463
+ (option) => {
464
+ var _a, _b, _c, _d;
465
+ const newTag = {
466
+ id: generateId(),
467
+ label: option.label,
468
+ type: activeQuickKey || "unknown",
469
+ value: option.value ?? option.name ?? option.label,
470
+ trigger: activeQuickKey || void 0,
471
+ icon: option.icon,
472
+ data: option
473
+ };
474
+ (_a = activeQuickKeyConfig == null ? void 0 : activeQuickKeyConfig.onSelect) == null ? void 0 : _a.call(activeQuickKeyConfig, option);
475
+ if (inlineTags) {
476
+ (_b = inlineInputRef.current) == null ? void 0 : _b.insertTag(newTag, {
477
+ start: quickKeyTriggerIdx,
478
+ end: quickKeyTriggerIdx + 1 + quickKeyKeyword.length
479
+ });
480
+ } else {
481
+ setTags([...tags, newTag]);
482
+ if (quickKeyTriggerIdx >= 0) {
483
+ const newValue = value.slice(0, quickKeyTriggerIdx) + value.slice(quickKeyTriggerIdx + 1 + quickKeyKeyword.length);
484
+ setValue(newValue);
485
+ }
486
+ }
487
+ setActiveQuickKey(null);
488
+ setQuickKeyKeyword("");
489
+ setQuickKeyTriggerIdx(-1);
490
+ setQuickKeyActiveIndex(0);
491
+ inlineTags ? (_c = inlineInputRef.current) == null ? void 0 : _c.focus() : (_d = textareaRef.current) == null ? void 0 : _d.focus();
492
+ },
493
+ [
494
+ activeQuickKey,
495
+ activeQuickKeyConfig,
496
+ inlineTags,
497
+ tags,
498
+ setTags,
499
+ value,
500
+ quickKeyTriggerIdx,
501
+ quickKeyKeyword,
502
+ setValue
503
+ ]
504
+ );
505
+ const handleInputChange = (e) => {
506
+ const newValue = e.target.value;
507
+ setValue(newValue);
508
+ detectQuickKey(newValue, e.target.selectionStart || 0);
509
+ };
510
+ const handleInlineInputChange = (newValue) => {
511
+ var _a;
512
+ setValue(newValue);
513
+ detectQuickKey(
514
+ newValue,
515
+ ((_a = inlineInputRef.current) == null ? void 0 : _a.getCursorOffset()) || newValue.length
516
+ );
517
+ };
518
+ const handleQuickKeyByText = (text, cursorPos) => {
519
+ const quickKeyChars = quickKeys.map((qk) => qk.key);
520
+ if (quickKeyChars.length === 0)
521
+ return;
522
+ const textBeforeCursor = text.slice(0, cursorPos);
523
+ const lastChar = textBeforeCursor[cursorPos - 1];
524
+ if (lastChar && quickKeyChars.includes(lastChar)) {
525
+ if (activeQuickKey === lastChar && quickKeyTriggerIdx === cursorPos - 1) {
526
+ return;
527
+ }
528
+ setActiveQuickKey(lastChar);
529
+ setQuickKeyKeyword("");
530
+ setQuickKeyTriggerIdx(cursorPos - 1);
531
+ setQuickKeyActiveIndex(0);
532
+ onQuickKeyTrigger == null ? void 0 : onQuickKeyTrigger(lastChar, "");
533
+ }
534
+ };
535
+ const isQuickListControlKey = (key) => key === "ArrowDown" || key === "ArrowUp" || key === "Enter" || key === "Escape";
536
+ const handleKeyUp = (e) => {
537
+ if (activeQuickKey && isQuickListControlKey(e.key))
538
+ return;
539
+ const target = e.target;
540
+ handleQuickKeyByText(target.value || "", target.selectionStart || 0);
541
+ };
542
+ const handleInlineKeyUp = (e) => {
543
+ var _a, _b;
544
+ if (activeQuickKey && isQuickListControlKey(e.key))
545
+ return;
546
+ const text = ((_a = inlineInputRef.current) == null ? void 0 : _a.getText()) || "";
547
+ const cursorPos = ((_b = inlineInputRef.current) == null ? void 0 : _b.getCursorOffset()) || text.length;
548
+ handleQuickKeyByText(text, cursorPos);
549
+ };
328
550
  const handleSubmit = () => {
329
- if (!value.trim() && files.length === 0) {
551
+ if (!value.trim() && files.length === 0 && tags.length === 0) {
330
552
  import_antd.message.warning("请输入消息或选择文件");
331
553
  return;
332
554
  }
@@ -343,12 +565,10 @@ var XAdkSender = (0, import_react.forwardRef)(
343
565
  onOk: () => {
344
566
  const formattedFiles = formatFilesForServer(successFiles);
345
567
  if (onSubmit) {
346
- onSubmit({
347
- text: value,
348
- files: formattedFiles
349
- });
568
+ onSubmit(createSubmitData(formattedFiles));
350
569
  }
351
570
  setValue("");
571
+ setTags([]);
352
572
  setFiles((prev) => prev.filter((f) => f.status !== "success"));
353
573
  },
354
574
  onCancel: () => {
@@ -358,12 +578,10 @@ var XAdkSender = (0, import_react.forwardRef)(
358
578
  } else {
359
579
  const formattedFiles = formatFilesForServer(successFiles);
360
580
  if (onSubmit) {
361
- onSubmit({
362
- text: value,
363
- files: formattedFiles
364
- });
581
+ onSubmit(createSubmitData(formattedFiles));
365
582
  }
366
583
  setValue("");
584
+ setTags([]);
367
585
  setFiles((prev) => prev.filter((f) => f.status !== "success"));
368
586
  }
369
587
  };
@@ -383,12 +601,36 @@ var XAdkSender = (0, import_react.forwardRef)(
383
601
  };
384
602
  });
385
603
  };
386
- const handleInputChange = (e) => {
387
- const newValue = e.target.value;
388
- setValue(newValue);
389
- };
390
604
  const handleKeyDown = (e) => {
391
- if (e.key === "Enter" && !e.shiftKey) {
605
+ const quickKeyOptions = (activeQuickKeyConfig == null ? void 0 : activeQuickKeyConfig.options) || [];
606
+ if (activeQuickKey && quickKeyOptions.length > 0) {
607
+ if (e.key === "ArrowDown") {
608
+ e.preventDefault();
609
+ setQuickKeyActiveIndex((prev) => getNextQuickKeyIndex(prev, 1));
610
+ return;
611
+ }
612
+ if (e.key === "ArrowUp") {
613
+ e.preventDefault();
614
+ setQuickKeyActiveIndex((prev) => getNextQuickKeyIndex(prev, -1));
615
+ return;
616
+ }
617
+ if (e.key === "Enter") {
618
+ e.preventDefault();
619
+ handleQuickKeySelect(
620
+ quickKeyOptions[Math.min(quickKeyActiveIndex, quickKeyOptions.length - 1)]
621
+ );
622
+ return;
623
+ }
624
+ if (e.key === "Escape") {
625
+ e.preventDefault();
626
+ setActiveQuickKey(null);
627
+ setQuickKeyKeyword("");
628
+ setQuickKeyTriggerIdx(-1);
629
+ setQuickKeyActiveIndex(0);
630
+ return;
631
+ }
632
+ }
633
+ if (e.key === "Enter" && !e.shiftKey && !activeQuickKey) {
392
634
  e.preventDefault();
393
635
  handleSubmit();
394
636
  }
@@ -409,7 +651,6 @@ var XAdkSender = (0, import_react.forwardRef)(
409
651
  import_FileGallery.default,
410
652
  {
411
653
  file,
412
- type: "file",
413
654
  removable: true,
414
655
  onRemove: handleRemoveFile
415
656
  },
@@ -423,7 +664,8 @@ var XAdkSender = (0, import_react.forwardRef)(
423
664
  const isDisabled = disabled || uploading || loading;
424
665
  const hasContent = value.trim().length > 0;
425
666
  const hasFiles = files.some((f) => f.status === "success");
426
- const canSend = hasContent || hasFiles;
667
+ const hasTags = tags.length > 0;
668
+ const canSend = hasContent || hasFiles || hasTags;
427
669
  const SendButton = (props) => {
428
670
  if (sendButtonRender) {
429
671
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: sendButtonRender({
@@ -494,33 +736,31 @@ var XAdkSender = (0, import_react.forwardRef)(
494
736
  }
495
737
  return slot;
496
738
  };
497
- const defaultSuffix = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: styles.buttonGroup, children: [
498
- allowUpload && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_antd.Tooltip, { title: "上传文件", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
499
- "button",
500
- {
501
- className: `${styles.iconButton} ${styles.uploadButton}`,
502
- onClick: triggerFileSelect,
503
- disabled: isDisabled,
504
- "aria-label": "上传文件",
505
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_icons.PaperClipOutlined, {})
506
- }
507
- ) }),
508
- sendButtonRender ? sendButtonRender({
509
- loading,
739
+ const defaultSuffix = /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: styles.buttonGroup, children: sendButtonRender ? sendButtonRender({
740
+ loading,
741
+ disabled: uploading || disabled,
742
+ canSend,
743
+ onSend: handleSubmit,
744
+ onStop
745
+ }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_antd.Tooltip, { title: loading ? "停止生成" : "发送消息", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
746
+ "button",
747
+ {
748
+ className: `${styles.iconButton} ${styles.sendButton} ${loading ? "stop" : ""}`,
749
+ onClick: loading ? onStop : handleSubmit,
510
750
  disabled: uploading || disabled,
511
- canSend,
512
- onSend: handleSubmit,
513
- onStop
514
- }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_antd.Tooltip, { title: loading ? "停止生成" : "发送消息", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
515
- "button",
516
- {
517
- className: `${styles.iconButton} ${styles.sendButton} ${loading ? "stop" : ""}`,
518
- onClick: loading ? onStop : handleSubmit,
519
- disabled: uploading || disabled,
520
- "aria-label": loading ? "停止生成" : "发送消息",
521
- children: loading ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_icons.LoadingOutlined, { spin: true }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_icons.ArrowUpOutlined, {})
522
- }
523
- ) })
751
+ "aria-label": loading ? "停止生成" : "发送消息",
752
+ children: loading ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_icons.LoadingOutlined, { spin: true }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_icons.ArrowUpOutlined, {})
753
+ }
754
+ ) }) });
755
+ const defaultActionBar = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: styles.actionBar, children: [
756
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: styles.actionBarLeft, children: [
757
+ allowUpload && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(UploadButton, {}),
758
+ renderSlot(footerLeft, false)
759
+ ] }),
760
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: styles.actionBarRight, children: [
761
+ clearBtnShow && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ClearButton, {}),
762
+ renderSlot(suffix, defaultSuffix)
763
+ ] })
524
764
  ] });
525
765
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
526
766
  "div",
@@ -550,17 +790,33 @@ var XAdkSender = (0, import_react.forwardRef)(
550
790
  }
551
791
  ),
552
792
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: styles.mainArea, children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: styles.senderWrap, children: [
793
+ !inlineTags && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_InputTags.default, { tags, onRemove: handleRemoveTag }),
553
794
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: styles.inputAndButtons, children: [
554
- clearBtnShow && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ClearButton, {}),
555
795
  renderSlot(prefix, false),
556
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: styles.textAreaWrapper, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
796
+ inlineTags ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
797
+ import_InlineTagInput.default,
798
+ {
799
+ ref: inlineInputRef,
800
+ value,
801
+ tags,
802
+ placeholder,
803
+ disabled: isDisabled,
804
+ onChange: handleInlineInputChange,
805
+ onTagsChange: setTags,
806
+ onKeyDown: handleKeyDown,
807
+ onKeyUp: handleInlineKeyUp,
808
+ renderTag
809
+ }
810
+ ) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: styles.textAreaWrapper, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
557
811
  import_antd.Input.TextArea,
558
812
  {
813
+ ref: textareaRef,
559
814
  className: styles.textArea,
560
815
  value,
561
816
  onChange: handleInputChange,
562
817
  onKeyDown: handleKeyDown,
563
- placeholder: "请输入消息...",
818
+ onKeyUp: handleKeyUp,
819
+ placeholder,
564
820
  autoSize: { minRows: 1, maxRows: 4 },
565
821
  style: {
566
822
  border: "none",
@@ -569,21 +825,31 @@ var XAdkSender = (0, import_react.forwardRef)(
569
825
  padding: 0
570
826
  }
571
827
  }
572
- ) }),
573
- renderSlot(suffix, defaultSuffix)
828
+ ) })
574
829
  ] }),
575
- renderSlot(
576
- footer,
577
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: styles.tip, children: "内容由AI生成,无法确保真实准确,仅供参考" })
578
- )
579
- ] }) })
830
+ activeQuickKey && activeQuickKeyConfig && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: styles.quickListWrapper, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
831
+ import_QuickList.default,
832
+ {
833
+ config: activeQuickKeyConfig,
834
+ activeIndex: quickKeyActiveIndex,
835
+ onSelect: handleQuickKeySelect,
836
+ onClose: () => {
837
+ setActiveQuickKey(null);
838
+ setQuickKeyKeyword("");
839
+ setQuickKeyTriggerIdx(-1);
840
+ setQuickKeyActiveIndex(0);
841
+ },
842
+ visible: true
843
+ }
844
+ ) }),
845
+ footer === false ? defaultActionBar : renderSlot(footer, defaultActionBar)
846
+ ] }) }),
847
+ !footer && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: styles.tip, children: "内容由AI生成,无法确保真实准确,仅供参考" })
580
848
  ]
581
849
  }
582
850
  );
583
851
  }
584
852
  );
585
853
  XAdkSender.displayName = "XAdkSender";
586
- var CompoundSender = XAdkSender;
587
- CompoundSender.Switch = import_Switch.default;
588
- var XAdkSender_default = CompoundSender;
854
+ var XAdkSender_default = XAdkSender;
589
855
  //# sourceMappingURL=index.js.map