@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
@@ -0,0 +1,105 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __export = (target, all) => {
6
+ for (var name in all)
7
+ __defProp(target, name, { get: all[name], enumerable: true });
8
+ };
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
+
19
+ // src/components/XAdkSender/QuickList.tsx
20
+ var QuickList_exports = {};
21
+ __export(QuickList_exports, {
22
+ default: () => QuickList_default
23
+ });
24
+ module.exports = __toCommonJS(QuickList_exports);
25
+ var import_react = require("react");
26
+ var import_styles = require("./styles");
27
+ var import_jsx_runtime = require("react/jsx-runtime");
28
+ var QuickList = ({
29
+ config,
30
+ activeIndex = 0,
31
+ onSelect,
32
+ onClose,
33
+ visible
34
+ }) => {
35
+ var _a;
36
+ const styles = (0, import_styles.useStyles)();
37
+ const groupedOptions = (0, import_react.useMemo)(() => {
38
+ const groups = {};
39
+ config.options.forEach((opt) => {
40
+ const g = opt.group || "";
41
+ if (!groups[g])
42
+ groups[g] = [];
43
+ groups[g].push(opt);
44
+ });
45
+ return groups;
46
+ }, [config.options]);
47
+ const handleSelect = (0, import_react.useCallback)(
48
+ (opt) => {
49
+ onSelect(opt);
50
+ onClose();
51
+ },
52
+ [onSelect, onClose]
53
+ );
54
+ if (!visible)
55
+ return null;
56
+ const normalizedActiveIndex = config.options.length > 0 ? (activeIndex % config.options.length + config.options.length) % config.options.length : 0;
57
+ const activeOptionId = (_a = config.options[normalizedActiveIndex]) == null ? void 0 : _a.id;
58
+ const getItemClassName = (opt) => `${styles.quickListItem}${opt.id === activeOptionId ? " active" : ""}`;
59
+ const renderOption = (opt) => {
60
+ if (config.renderItem) {
61
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
62
+ "div",
63
+ {
64
+ className: getItemClassName(opt),
65
+ onMouseDown: (event) => event.preventDefault(),
66
+ onClick: () => handleSelect(opt),
67
+ children: config.renderItem(opt)
68
+ },
69
+ opt.id
70
+ );
71
+ }
72
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
73
+ "div",
74
+ {
75
+ className: getItemClassName(opt),
76
+ onMouseDown: (event) => event.preventDefault(),
77
+ onClick: () => handleSelect(opt),
78
+ children: [
79
+ opt.icon && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "quick-list-item-icon", children: opt.icon }),
80
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "quick-list-item-content", children: [
81
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "quick-list-item-label", children: opt.label }),
82
+ opt.description && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "quick-list-item-desc", children: opt.description })
83
+ ] })
84
+ ]
85
+ },
86
+ opt.id
87
+ );
88
+ };
89
+ const groupKeys = Object.keys(groupedOptions);
90
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: styles.quickList, children: [
91
+ config.title && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: styles.quickListHeader, children: config.title }),
92
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: styles.quickListBody, children: [
93
+ groupKeys.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: styles.quickListEmpty, children: "暂无可选项" }),
94
+ groupKeys.map((group) => {
95
+ const items = groupedOptions[group];
96
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
97
+ group && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: styles.quickListGroup, children: group.replace(/_/g, " / ") }),
98
+ items.map(renderOption)
99
+ ] }, group);
100
+ })
101
+ ] })
102
+ ] });
103
+ };
104
+ var QuickList_default = QuickList;
105
+ //# sourceMappingURL=QuickList.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/components/XAdkSender/QuickList.tsx"],
4
+ "sourcesContent": ["import React, { useMemo, useCallback } from \"react\";\nimport type { QuickListOption, QuickKeyConfig } from \"@/types\";\nimport { useStyles } from \"./styles\";\n\nexport interface QuickListProps {\n /** 当前触发的快捷键配置 */\n config: QuickKeyConfig;\n /** 当前键盘选中的选项下标 */\n activeIndex?: number;\n /** 选择回调 */\n onSelect: (option: QuickListOption) => void;\n /** 关闭回调 */\n onClose: () => void;\n /** 是否可见 */\n visible: boolean;\n}\n\nconst QuickList: React.FC<QuickListProps> = ({\n config,\n activeIndex = 0,\n onSelect,\n onClose,\n visible,\n}) => {\n const styles = useStyles();\n\n // SDK 内置列表只负责展示 options;搜索、远程过滤、排序等能力由业务方在外部更新 options 实现。\n const groupedOptions = useMemo(() => {\n const groups: Record<string, QuickListOption[]> = {};\n config.options.forEach((opt) => {\n const g = opt.group || \"\";\n if (!groups[g]) groups[g] = [];\n groups[g].push(opt);\n });\n return groups;\n }, [config.options]);\n\n const handleSelect = useCallback(\n (opt: QuickListOption) => {\n // 先通知选择,再关闭弹层;插入 tag 的逻辑由 XAdkSender 统一处理。\n onSelect(opt);\n onClose();\n },\n [onSelect, onClose],\n );\n\n if (!visible) return null;\n\n const normalizedActiveIndex =\n config.options.length > 0\n ? ((activeIndex % config.options.length) + config.options.length) %\n config.options.length\n : 0;\n const activeOptionId = config.options[normalizedActiveIndex]?.id;\n const getItemClassName = (opt: QuickListOption) =>\n `${styles.quickListItem}${opt.id === activeOptionId ? \" active\" : \"\"}`;\n\n const renderOption = (opt: QuickListOption) => {\n if (config.renderItem) {\n return (\n <div\n key={opt.id}\n className={getItemClassName(opt)}\n onMouseDown={(event) => event.preventDefault()}\n onClick={() => handleSelect(opt)}\n >\n {config.renderItem(opt)}\n </div>\n );\n }\n return (\n <div\n key={opt.id}\n className={getItemClassName(opt)}\n onMouseDown={(event) => event.preventDefault()}\n onClick={() => handleSelect(opt)}\n >\n {opt.icon && <span className=\"quick-list-item-icon\">{opt.icon}</span>}\n <div className=\"quick-list-item-content\">\n <div className=\"quick-list-item-label\">{opt.label}</div>\n {opt.description && (\n <div className=\"quick-list-item-desc\">{opt.description}</div>\n )}\n </div>\n </div>\n );\n };\n\n const groupKeys = Object.keys(groupedOptions);\n\n return (\n <div className={styles.quickList}>\n {config.title && (\n <div className={styles.quickListHeader}>{config.title}</div>\n )}\n <div className={styles.quickListBody}>\n {groupKeys.length === 0 && (\n <div className={styles.quickListEmpty}>暂无可选项</div>\n )}\n {groupKeys.map((group) => {\n const items = groupedOptions[group];\n return (\n <div key={group}>\n {group && (\n <div className={styles.quickListGroup}>\n {group.replace(/_/g, \" / \")}\n </div>\n )}\n {items.map(renderOption)}\n </div>\n );\n })}\n </div>\n </div>\n );\n};\n\nexport default QuickList;\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAA4C;AAE5C,oBAA0B;AA0DlB;AA3CR,IAAM,YAAsC,CAAC;AAAA,EAC3C;AAAA,EACA,cAAc;AAAA,EACd;AAAA,EACA;AAAA,EACA;AACF,MAAM;AAvBN;AAwBE,QAAM,aAAS,yBAAU;AAGzB,QAAM,qBAAiB,sBAAQ,MAAM;AACnC,UAAM,SAA4C,CAAC;AACnD,WAAO,QAAQ,QAAQ,CAAC,QAAQ;AAC9B,YAAM,IAAI,IAAI,SAAS;AACvB,UAAI,CAAC,OAAO,CAAC;AAAG,eAAO,CAAC,IAAI,CAAC;AAC7B,aAAO,CAAC,EAAE,KAAK,GAAG;AAAA,IACpB,CAAC;AACD,WAAO;AAAA,EACT,GAAG,CAAC,OAAO,OAAO,CAAC;AAEnB,QAAM,mBAAe;AAAA,IACnB,CAAC,QAAyB;AAExB,eAAS,GAAG;AACZ,cAAQ;AAAA,IACV;AAAA,IACA,CAAC,UAAU,OAAO;AAAA,EACpB;AAEA,MAAI,CAAC;AAAS,WAAO;AAErB,QAAM,wBACJ,OAAO,QAAQ,SAAS,KAClB,cAAc,OAAO,QAAQ,SAAU,OAAO,QAAQ,UACxD,OAAO,QAAQ,SACf;AACN,QAAM,kBAAiB,YAAO,QAAQ,qBAAqB,MAApC,mBAAuC;AAC9D,QAAM,mBAAmB,CAAC,QACxB,GAAG,OAAO,gBAAgB,IAAI,OAAO,iBAAiB,YAAY;AAEpE,QAAM,eAAe,CAAC,QAAyB;AAC7C,QAAI,OAAO,YAAY;AACrB,aACE;AAAA,QAAC;AAAA;AAAA,UAEC,WAAW,iBAAiB,GAAG;AAAA,UAC/B,aAAa,CAAC,UAAU,MAAM,eAAe;AAAA,UAC7C,SAAS,MAAM,aAAa,GAAG;AAAA,UAE9B,iBAAO,WAAW,GAAG;AAAA;AAAA,QALjB,IAAI;AAAA,MAMX;AAAA,IAEJ;AACA,WACE;AAAA,MAAC;AAAA;AAAA,QAEC,WAAW,iBAAiB,GAAG;AAAA,QAC/B,aAAa,CAAC,UAAU,MAAM,eAAe;AAAA,QAC7C,SAAS,MAAM,aAAa,GAAG;AAAA,QAE9B;AAAA,cAAI,QAAQ,4CAAC,UAAK,WAAU,wBAAwB,cAAI,MAAK;AAAA,UAC9D,6CAAC,SAAI,WAAU,2BACb;AAAA,wDAAC,SAAI,WAAU,yBAAyB,cAAI,OAAM;AAAA,YACjD,IAAI,eACH,4CAAC,SAAI,WAAU,wBAAwB,cAAI,aAAY;AAAA,aAE3D;AAAA;AAAA;AAAA,MAXK,IAAI;AAAA,IAYX;AAAA,EAEJ;AAEA,QAAM,YAAY,OAAO,KAAK,cAAc;AAE5C,SACE,6CAAC,SAAI,WAAW,OAAO,WACpB;AAAA,WAAO,SACN,4CAAC,SAAI,WAAW,OAAO,iBAAkB,iBAAO,OAAM;AAAA,IAExD,6CAAC,SAAI,WAAW,OAAO,eACpB;AAAA,gBAAU,WAAW,KACpB,4CAAC,SAAI,WAAW,OAAO,gBAAgB,mBAAK;AAAA,MAE7C,UAAU,IAAI,CAAC,UAAU;AACxB,cAAM,QAAQ,eAAe,KAAK;AAClC,eACE,6CAAC,SACE;AAAA,mBACC,4CAAC,SAAI,WAAW,OAAO,gBACpB,gBAAM,QAAQ,MAAM,KAAK,GAC5B;AAAA,UAED,MAAM,IAAI,YAAY;AAAA,aANf,KAOV;AAAA,MAEJ,CAAC;AAAA,OACH;AAAA,KACF;AAEJ;AAEA,IAAO,oBAAQ;",
6
+ "names": []
7
+ }
@@ -1,9 +1,4 @@
1
1
  import React from "react";
2
2
  import { XAdkSenderHandle } from "../../types";
3
3
  declare const XAdkSender: React.ForwardRefExoticComponent<import("../../types").SenderUIProps & import("../../types").UploaderCoreProps & React.RefAttributes<XAdkSenderHandle>>;
4
- import XAdkSenderSwitch from "./Switch";
5
- type XAdkSenderComponent = typeof XAdkSender & {
6
- Switch: typeof XAdkSenderSwitch;
7
- };
8
- declare const CompoundSender: XAdkSenderComponent;
9
- export default CompoundSender;
4
+ export default XAdkSender;
@@ -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,23 @@ 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
84
81
  }, ref) => {
85
82
  const styles = (0, import_styles.useStyles)();
86
83
  const isControlled = controlledValue !== void 0;
@@ -92,10 +89,25 @@ var XAdkSender = (0, import_react.forwardRef)(
92
89
  }
93
90
  onChange == null ? void 0 : onChange(newValue);
94
91
  };
92
+ const isTagsControlled = controlledTags !== void 0;
93
+ const [internalTags, setInternalTags] = (0, import_react.useState)(defaultTags);
94
+ const tags = isTagsControlled ? controlledTags : internalTags;
95
+ const setTags = (newTags) => {
96
+ if (!isTagsControlled) {
97
+ setInternalTags(newTags);
98
+ }
99
+ onTagsChange == null ? void 0 : onTagsChange(newTags);
100
+ };
95
101
  const [files, setFiles] = (0, import_react.useState)([]);
96
102
  const [isDragOver, setIsDragOver] = (0, import_react.useState)(false);
97
103
  const containerRef = (0, import_react.useRef)(null);
98
104
  const fileInputRef = (0, import_react.useRef)(null);
105
+ const textareaRef = (0, import_react.useRef)(null);
106
+ const inlineInputRef = (0, import_react.useRef)(null);
107
+ const [activeQuickKey, setActiveQuickKey] = (0, import_react.useState)(null);
108
+ const [quickKeyKeyword, setQuickKeyKeyword] = (0, import_react.useState)("");
109
+ const [quickKeyTriggerIdx, setQuickKeyTriggerIdx] = (0, import_react.useState)(-1);
110
+ const [quickKeyActiveIndex, setQuickKeyActiveIndex] = (0, import_react.useState)(0);
99
111
  const generateId = () => {
100
112
  return Date.now().toString(36) + Math.random().toString(36).substr(2);
101
113
  };
@@ -121,22 +133,16 @@ var XAdkSender = (0, import_react.forwardRef)(
121
133
  }
122
134
  return true;
123
135
  };
124
- const checkFileSize = (file) => {
125
- const maxSize = maxFileSize * 1024 * 1024;
126
- return file.size <= maxSize;
127
- };
128
136
  const isDuplicateFile = (file, files2) => {
129
137
  return files2.some((f) => f.name === file.name && f.size === file.size);
130
138
  };
131
139
  const builtInValidators = [
132
- // 数量校验(修复批量 bug)
133
140
  (_file, { files: files2 }) => {
134
141
  if (files2.length >= maxFiles) {
135
142
  return `最多只能上传 ${maxFiles} 个文件`;
136
143
  }
137
144
  return null;
138
145
  },
139
- // 大小校验
140
146
  (file) => {
141
147
  const maxSize = maxFileSize * 1024 * 1024;
142
148
  if (file.size > maxSize) {
@@ -144,14 +150,12 @@ var XAdkSender = (0, import_react.forwardRef)(
144
150
  }
145
151
  return null;
146
152
  },
147
- // 类型校验
148
153
  (file) => {
149
154
  if (!checkFileType(file)) {
150
155
  return "不支持的文件类型";
151
156
  }
152
157
  return null;
153
158
  },
154
- // ⭐ 新增:去重校验
155
159
  (file, { files: files2 }) => {
156
160
  if (isDuplicateFile(file, files2)) {
157
161
  return "文件已存在";
@@ -215,6 +219,11 @@ var XAdkSender = (0, import_react.forwardRef)(
215
219
  }),
216
220
  [handleFileSelect]
217
221
  );
222
+ const triggerFileSelect = () => {
223
+ if (fileInputRef.current) {
224
+ fileInputRef.current.click();
225
+ }
226
+ };
218
227
  const uploadFiles = async (fileList) => {
219
228
  for (const localFile of fileList) {
220
229
  setFiles(
@@ -289,11 +298,6 @@ var XAdkSender = (0, import_react.forwardRef)(
289
298
  return next;
290
299
  });
291
300
  };
292
- const triggerFileSelect = () => {
293
- if (fileInputRef.current) {
294
- fileInputRef.current.click();
295
- }
296
- };
297
301
  const handleDragOver = (0, import_react.useCallback)(
298
302
  (e) => {
299
303
  e.preventDefault();
@@ -325,8 +329,163 @@ var XAdkSender = (0, import_react.forwardRef)(
325
329
  },
326
330
  [allowUpload, handleFileSelect]
327
331
  );
332
+ const handleRemoveTag = (0, import_react.useCallback)(
333
+ (id) => {
334
+ setTags(tags.filter((t) => t.id !== id));
335
+ },
336
+ [tags, setTags]
337
+ );
338
+ const activeQuickKeyConfig = (0, import_react.useMemo)(() => {
339
+ if (!activeQuickKey)
340
+ return null;
341
+ return quickKeys.find((qk) => qk.key === activeQuickKey) || null;
342
+ }, [activeQuickKey, quickKeys]);
343
+ const activeQuickKeyOptionsLength = (activeQuickKeyConfig == null ? void 0 : activeQuickKeyConfig.options.length) || 0;
344
+ (0, import_react.useEffect)(() => {
345
+ setQuickKeyActiveIndex(0);
346
+ }, [activeQuickKey]);
347
+ (0, import_react.useEffect)(() => {
348
+ if (activeQuickKeyOptionsLength <= 0) {
349
+ setQuickKeyActiveIndex(0);
350
+ return;
351
+ }
352
+ setQuickKeyActiveIndex(
353
+ (prev) => (prev % activeQuickKeyOptionsLength + activeQuickKeyOptionsLength) % activeQuickKeyOptionsLength
354
+ );
355
+ }, [activeQuickKeyOptionsLength]);
356
+ const getNextQuickKeyIndex = (0, import_react.useCallback)(
357
+ (current, step) => {
358
+ if (activeQuickKeyOptionsLength <= 0)
359
+ return 0;
360
+ return (current + step + activeQuickKeyOptionsLength) % activeQuickKeyOptionsLength;
361
+ },
362
+ [activeQuickKeyOptionsLength]
363
+ );
364
+ const detectQuickKey = (0, import_react.useCallback)(
365
+ (text, cursorPos) => {
366
+ const quickKeyChars = quickKeys.map((qk) => qk.key);
367
+ if (quickKeyChars.length === 0)
368
+ return;
369
+ const textBeforeCursor = text.slice(0, cursorPos);
370
+ let found = false;
371
+ for (let i = textBeforeCursor.length - 1; i >= 0; i--) {
372
+ const char = textBeforeCursor[i];
373
+ if (/\s/.test(char))
374
+ break;
375
+ if (quickKeyChars.includes(char)) {
376
+ const keyword = textBeforeCursor.slice(i + 1);
377
+ setActiveQuickKey(char);
378
+ setQuickKeyKeyword(keyword);
379
+ setQuickKeyTriggerIdx(i);
380
+ setQuickKeyActiveIndex(0);
381
+ onQuickKeyTrigger == null ? void 0 : onQuickKeyTrigger(char, keyword);
382
+ found = true;
383
+ break;
384
+ }
385
+ }
386
+ if (!found && activeQuickKey) {
387
+ const triggerChar = text[quickKeyTriggerIdx];
388
+ const keyword = text.slice(quickKeyTriggerIdx + 1, cursorPos);
389
+ if (quickKeyTriggerIdx < 0 || !triggerChar || !quickKeyChars.includes(triggerChar) || /\s/.test(keyword)) {
390
+ setActiveQuickKey(null);
391
+ setQuickKeyKeyword("");
392
+ setQuickKeyTriggerIdx(-1);
393
+ setQuickKeyActiveIndex(0);
394
+ } else {
395
+ setQuickKeyKeyword(keyword);
396
+ }
397
+ }
398
+ },
399
+ [activeQuickKey, onQuickKeyTrigger, quickKeyTriggerIdx, quickKeys]
400
+ );
401
+ const handleQuickKeySelect = (0, import_react.useCallback)(
402
+ (option) => {
403
+ var _a, _b, _c, _d;
404
+ const newTag = {
405
+ id: generateId(),
406
+ label: option.label,
407
+ type: activeQuickKey || "unknown",
408
+ icon: option.icon,
409
+ data: option
410
+ };
411
+ (_a = activeQuickKeyConfig == null ? void 0 : activeQuickKeyConfig.onSelect) == null ? void 0 : _a.call(activeQuickKeyConfig, option);
412
+ if (inlineTags) {
413
+ (_b = inlineInputRef.current) == null ? void 0 : _b.insertTag(newTag, {
414
+ start: quickKeyTriggerIdx,
415
+ end: quickKeyTriggerIdx + 1 + quickKeyKeyword.length
416
+ });
417
+ } else {
418
+ setTags([...tags, newTag]);
419
+ if (quickKeyTriggerIdx >= 0) {
420
+ const newValue = value.slice(0, quickKeyTriggerIdx) + value.slice(quickKeyTriggerIdx + 1 + quickKeyKeyword.length);
421
+ setValue(newValue);
422
+ }
423
+ }
424
+ setActiveQuickKey(null);
425
+ setQuickKeyKeyword("");
426
+ setQuickKeyTriggerIdx(-1);
427
+ setQuickKeyActiveIndex(0);
428
+ inlineTags ? (_c = inlineInputRef.current) == null ? void 0 : _c.focus() : (_d = textareaRef.current) == null ? void 0 : _d.focus();
429
+ },
430
+ [
431
+ activeQuickKey,
432
+ activeQuickKeyConfig,
433
+ inlineTags,
434
+ tags,
435
+ setTags,
436
+ value,
437
+ quickKeyTriggerIdx,
438
+ quickKeyKeyword,
439
+ setValue
440
+ ]
441
+ );
442
+ const handleInputChange = (e) => {
443
+ const newValue = e.target.value;
444
+ setValue(newValue);
445
+ detectQuickKey(newValue, e.target.selectionStart || 0);
446
+ };
447
+ const handleInlineInputChange = (newValue) => {
448
+ var _a;
449
+ setValue(newValue);
450
+ detectQuickKey(
451
+ newValue,
452
+ ((_a = inlineInputRef.current) == null ? void 0 : _a.getCursorOffset()) || newValue.length
453
+ );
454
+ };
455
+ const handleQuickKeyByText = (text, cursorPos) => {
456
+ const quickKeyChars = quickKeys.map((qk) => qk.key);
457
+ if (quickKeyChars.length === 0)
458
+ return;
459
+ const textBeforeCursor = text.slice(0, cursorPos);
460
+ const lastChar = textBeforeCursor[cursorPos - 1];
461
+ if (lastChar && quickKeyChars.includes(lastChar)) {
462
+ if (activeQuickKey === lastChar && quickKeyTriggerIdx === cursorPos - 1) {
463
+ return;
464
+ }
465
+ setActiveQuickKey(lastChar);
466
+ setQuickKeyKeyword("");
467
+ setQuickKeyTriggerIdx(cursorPos - 1);
468
+ setQuickKeyActiveIndex(0);
469
+ onQuickKeyTrigger == null ? void 0 : onQuickKeyTrigger(lastChar, "");
470
+ }
471
+ };
472
+ const isQuickListControlKey = (key) => key === "ArrowDown" || key === "ArrowUp" || key === "Enter" || key === "Escape";
473
+ const handleKeyUp = (e) => {
474
+ if (activeQuickKey && isQuickListControlKey(e.key))
475
+ return;
476
+ const target = e.target;
477
+ handleQuickKeyByText(target.value || "", target.selectionStart || 0);
478
+ };
479
+ const handleInlineKeyUp = (e) => {
480
+ var _a, _b;
481
+ if (activeQuickKey && isQuickListControlKey(e.key))
482
+ return;
483
+ const text = ((_a = inlineInputRef.current) == null ? void 0 : _a.getText()) || "";
484
+ const cursorPos = ((_b = inlineInputRef.current) == null ? void 0 : _b.getCursorOffset()) || text.length;
485
+ handleQuickKeyByText(text, cursorPos);
486
+ };
328
487
  const handleSubmit = () => {
329
- if (!value.trim() && files.length === 0) {
488
+ if (!value.trim() && files.length === 0 && tags.length === 0) {
330
489
  import_antd.message.warning("请输入消息或选择文件");
331
490
  return;
332
491
  }
@@ -345,10 +504,12 @@ var XAdkSender = (0, import_react.forwardRef)(
345
504
  if (onSubmit) {
346
505
  onSubmit({
347
506
  text: value,
348
- files: formattedFiles
507
+ files: formattedFiles,
508
+ tags
349
509
  });
350
510
  }
351
511
  setValue("");
512
+ setTags([]);
352
513
  setFiles((prev) => prev.filter((f) => f.status !== "success"));
353
514
  },
354
515
  onCancel: () => {
@@ -360,10 +521,12 @@ var XAdkSender = (0, import_react.forwardRef)(
360
521
  if (onSubmit) {
361
522
  onSubmit({
362
523
  text: value,
363
- files: formattedFiles
524
+ files: formattedFiles,
525
+ tags
364
526
  });
365
527
  }
366
528
  setValue("");
529
+ setTags([]);
367
530
  setFiles((prev) => prev.filter((f) => f.status !== "success"));
368
531
  }
369
532
  };
@@ -383,12 +546,36 @@ var XAdkSender = (0, import_react.forwardRef)(
383
546
  };
384
547
  });
385
548
  };
386
- const handleInputChange = (e) => {
387
- const newValue = e.target.value;
388
- setValue(newValue);
389
- };
390
549
  const handleKeyDown = (e) => {
391
- if (e.key === "Enter" && !e.shiftKey) {
550
+ const quickKeyOptions = (activeQuickKeyConfig == null ? void 0 : activeQuickKeyConfig.options) || [];
551
+ if (activeQuickKey && quickKeyOptions.length > 0) {
552
+ if (e.key === "ArrowDown") {
553
+ e.preventDefault();
554
+ setQuickKeyActiveIndex((prev) => getNextQuickKeyIndex(prev, 1));
555
+ return;
556
+ }
557
+ if (e.key === "ArrowUp") {
558
+ e.preventDefault();
559
+ setQuickKeyActiveIndex((prev) => getNextQuickKeyIndex(prev, -1));
560
+ return;
561
+ }
562
+ if (e.key === "Enter") {
563
+ e.preventDefault();
564
+ handleQuickKeySelect(
565
+ quickKeyOptions[Math.min(quickKeyActiveIndex, quickKeyOptions.length - 1)]
566
+ );
567
+ return;
568
+ }
569
+ if (e.key === "Escape") {
570
+ e.preventDefault();
571
+ setActiveQuickKey(null);
572
+ setQuickKeyKeyword("");
573
+ setQuickKeyTriggerIdx(-1);
574
+ setQuickKeyActiveIndex(0);
575
+ return;
576
+ }
577
+ }
578
+ if (e.key === "Enter" && !e.shiftKey && !activeQuickKey) {
392
579
  e.preventDefault();
393
580
  handleSubmit();
394
581
  }
@@ -409,7 +596,6 @@ var XAdkSender = (0, import_react.forwardRef)(
409
596
  import_FileGallery.default,
410
597
  {
411
598
  file,
412
- type: "file",
413
599
  removable: true,
414
600
  onRemove: handleRemoveFile
415
601
  },
@@ -423,7 +609,8 @@ var XAdkSender = (0, import_react.forwardRef)(
423
609
  const isDisabled = disabled || uploading || loading;
424
610
  const hasContent = value.trim().length > 0;
425
611
  const hasFiles = files.some((f) => f.status === "success");
426
- const canSend = hasContent || hasFiles;
612
+ const hasTags = tags.length > 0;
613
+ const canSend = hasContent || hasFiles || hasTags;
427
614
  const SendButton = (props) => {
428
615
  if (sendButtonRender) {
429
616
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: sendButtonRender({
@@ -494,33 +681,31 @@ var XAdkSender = (0, import_react.forwardRef)(
494
681
  }
495
682
  return slot;
496
683
  };
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,
684
+ const defaultSuffix = /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: styles.buttonGroup, children: sendButtonRender ? sendButtonRender({
685
+ loading,
686
+ disabled: uploading || disabled,
687
+ canSend,
688
+ onSend: handleSubmit,
689
+ onStop
690
+ }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_antd.Tooltip, { title: loading ? "停止生成" : "发送消息", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
691
+ "button",
692
+ {
693
+ className: `${styles.iconButton} ${styles.sendButton} ${loading ? "stop" : ""}`,
694
+ onClick: loading ? onStop : handleSubmit,
510
695
  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
- ) })
696
+ "aria-label": loading ? "停止生成" : "发送消息",
697
+ children: loading ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_icons.LoadingOutlined, { spin: true }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_icons.ArrowUpOutlined, {})
698
+ }
699
+ ) }) });
700
+ const defaultActionBar = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: styles.actionBar, children: [
701
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: styles.actionBarLeft, children: [
702
+ allowUpload && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(UploadButton, {}),
703
+ renderSlot(footerLeft, false)
704
+ ] }),
705
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: styles.actionBarRight, children: [
706
+ clearBtnShow && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ClearButton, {}),
707
+ renderSlot(suffix, defaultSuffix)
708
+ ] })
524
709
  ] });
525
710
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
526
711
  "div",
@@ -550,17 +735,33 @@ var XAdkSender = (0, import_react.forwardRef)(
550
735
  }
551
736
  ),
552
737
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: styles.mainArea, children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: styles.senderWrap, children: [
738
+ !inlineTags && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_InputTags.default, { tags, onRemove: handleRemoveTag }),
553
739
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: styles.inputAndButtons, children: [
554
- clearBtnShow && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ClearButton, {}),
555
740
  renderSlot(prefix, false),
556
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: styles.textAreaWrapper, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
741
+ inlineTags ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
742
+ import_InlineTagInput.default,
743
+ {
744
+ ref: inlineInputRef,
745
+ value,
746
+ tags,
747
+ placeholder,
748
+ disabled: isDisabled,
749
+ onChange: handleInlineInputChange,
750
+ onTagsChange: setTags,
751
+ onKeyDown: handleKeyDown,
752
+ onKeyUp: handleInlineKeyUp,
753
+ renderTag
754
+ }
755
+ ) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: styles.textAreaWrapper, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
557
756
  import_antd.Input.TextArea,
558
757
  {
758
+ ref: textareaRef,
559
759
  className: styles.textArea,
560
760
  value,
561
761
  onChange: handleInputChange,
562
762
  onKeyDown: handleKeyDown,
563
- placeholder: "请输入消息...",
763
+ onKeyUp: handleKeyUp,
764
+ placeholder,
564
765
  autoSize: { minRows: 1, maxRows: 4 },
565
766
  style: {
566
767
  border: "none",
@@ -569,21 +770,31 @@ var XAdkSender = (0, import_react.forwardRef)(
569
770
  padding: 0
570
771
  }
571
772
  }
572
- ) }),
573
- renderSlot(suffix, defaultSuffix)
773
+ ) })
574
774
  ] }),
575
- renderSlot(
576
- footer,
577
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: styles.tip, children: "内容由AI生成,无法确保真实准确,仅供参考" })
578
- )
579
- ] }) })
775
+ activeQuickKey && activeQuickKeyConfig && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: styles.quickListWrapper, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
776
+ import_QuickList.default,
777
+ {
778
+ config: activeQuickKeyConfig,
779
+ activeIndex: quickKeyActiveIndex,
780
+ onSelect: handleQuickKeySelect,
781
+ onClose: () => {
782
+ setActiveQuickKey(null);
783
+ setQuickKeyKeyword("");
784
+ setQuickKeyTriggerIdx(-1);
785
+ setQuickKeyActiveIndex(0);
786
+ },
787
+ visible: true
788
+ }
789
+ ) }),
790
+ footer === false ? defaultActionBar : renderSlot(footer, defaultActionBar)
791
+ ] }) }),
792
+ !footer && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: styles.tip, children: "内容由AI生成,无法确保真实准确,仅供参考" })
580
793
  ]
581
794
  }
582
795
  );
583
796
  }
584
797
  );
585
798
  XAdkSender.displayName = "XAdkSender";
586
- var CompoundSender = XAdkSender;
587
- CompoundSender.Switch = import_Switch.default;
588
- var XAdkSender_default = CompoundSender;
799
+ var XAdkSender_default = XAdkSender;
589
800
  //# sourceMappingURL=index.js.map