one-design-next 0.0.68 → 0.0.70

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.
@@ -5,15 +5,16 @@ import _createForOfIteratorHelper from "@babel/runtime/helpers/esm/createForOfIt
5
5
  import _regeneratorRuntime from "@babel/runtime/helpers/esm/regeneratorRuntime";
6
6
  import _asyncToGenerator from "@babel/runtime/helpers/esm/asyncToGenerator";
7
7
  import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
8
- import { useState, useRef, useCallback, useEffect, useLayoutEffect, useMemo, forwardRef, useImperativeHandle } from 'react';
8
+ import { forwardRef, useCallback, useEffect, useImperativeHandle, useLayoutEffect, useMemo, useRef, useState } from 'react';
9
+ import useControlledState from "../_util/useControlledState";
10
+ import Attachments from "../attachments";
9
11
  import HoverFill from "../hover-fill";
10
12
  import Icon from "../icon";
11
- import Popover from "../popover";
12
- import Attachments from "../attachments";
13
+ import { InvocationParamPopover } from "../invocation/param-popover";
13
14
  import { Message } from "../message";
15
+ import Popover from "../popover";
14
16
  import SkillSlot from "../skill-slot";
15
- import { InvocationParamPopover } from "../invocation/param-popover";
16
- import useControlledState from "../_util/useControlledState";
17
+ import Tooltip from "../tooltip";
17
18
  import { ComposerEditor } from "./editor";
18
19
  import { isMentionChip } from "./inline-ref";
19
20
  import { rawValueToSegments, segmentsHasContent } from "./segments";
@@ -60,8 +61,10 @@ function isFileAccepted(file, accept) {
60
61
  * 工具按钮的自定义配置。
61
62
  * - `icon`:图标名称(Icon 组件的 name),字段不传则不渲染图标。
62
63
  * - `label`:按钮文字,字段不传则不渲染文字。
64
+ * - `tooltip`:入口 hover 说明;字段不传继承默认;传 `false` 关闭。
63
65
  * - 整个配置对象不传(key 不存在于 `toolConfigs`)时使用内置默认值。
64
- * - 传了配置对象但 icon / label 字段都未设置时,兜底显示工具英文名
66
+ * - 仅传 `tooltip`(不传 icon / label)时:保留默认图标与文案,只覆盖说明。
67
+ * - 传了配置对象且 icon / label 均未设置、也未传 tooltip 时(`{}`),兜底显示工具英文名
65
68
  * (如 "attachment" / "webSearch" / "skill")作为 label,无图标,
66
69
  * 方便开发者一眼看出配置遗漏。
67
70
  */
@@ -70,19 +73,29 @@ var DEFAULT_TOOLS = ['attachment', 'webSearch', 'skill'];
70
73
  var DEFAULT_TOOL_CONFIGS = {
71
74
  attachment: {
72
75
  icon: 'paperclip',
73
- label: '附件'
76
+ label: '附件',
77
+ tooltip: '添加附件,支持直接拖拽或粘贴文件'
74
78
  },
75
79
  webSearch: {
76
80
  icon: 'globe',
77
- label: '联网'
81
+ label: '联网',
82
+ tooltip: '联网搜索'
78
83
  },
79
84
  skill: {
80
- icon: 'command',
81
- label: '技能'
85
+ icon: 'wand-sparkles',
86
+ label: '技能',
87
+ tooltip: '选择技能'
82
88
  }
83
89
  };
90
+
91
+ /**
92
+ * Composer 向内嵌 SkillSlot 透传的配置袋。
93
+ * 技能目录(skills / skillGroups)应由「技能管理」模块维护后注入此处;
94
+ * Composer 只负责触发入口与选中后插入 chip,不是目录 SSOT。
95
+ */
96
+
84
97
  export var Composer = /*#__PURE__*/forwardRef(function Composer(_ref, ref) {
85
- var _paramEdit$chipId;
98
+ var _skillSlotProps$menuW, _paramEdit$chipId;
86
99
  var valueProp = _ref.value,
87
100
  _ref$defaultValue = _ref.defaultValue,
88
101
  defaultValue = _ref$defaultValue === void 0 ? '' : _ref$defaultValue,
@@ -106,12 +119,7 @@ export var Composer = /*#__PURE__*/forwardRef(function Composer(_ref, ref) {
106
119
  _ref$toolsLabeled = _ref.toolsLabeled,
107
120
  toolsLabeled = _ref$toolsLabeled === void 0 ? true : _ref$toolsLabeled,
108
121
  toolConfigs = _ref.toolConfigs,
109
- skills = _ref.skills,
110
- skillGroups = _ref.skillGroups,
111
- onManageSkills = _ref.onManageSkills,
112
- skillManageFooter = _ref.skillManageFooter,
113
- skillMenuMaxHeight = _ref.skillMenuMaxHeight,
114
- skillMenuWidth = _ref.skillMenuWidth,
122
+ skillSlotProps = _ref.skillSlotProps,
115
123
  _ref$submitType = _ref.submitType,
116
124
  submitType = _ref$submitType === void 0 ? 'enter' : _ref$submitType,
117
125
  onEnter = _ref.onEnter,
@@ -133,6 +141,13 @@ export var Composer = /*#__PURE__*/forwardRef(function Composer(_ref, ref) {
133
141
  onToolClick = _ref.onToolClick,
134
142
  className = _ref.className,
135
143
  style = _ref.style;
144
+ var skills = skillSlotProps === null || skillSlotProps === void 0 ? void 0 : skillSlotProps.skills;
145
+ var skillGroups = skillSlotProps === null || skillSlotProps === void 0 ? void 0 : skillSlotProps.skillGroups;
146
+ var onManageSkills = skillSlotProps === null || skillSlotProps === void 0 ? void 0 : skillSlotProps.onManageSkills;
147
+ var skillManageFooter = skillSlotProps === null || skillSlotProps === void 0 ? void 0 : skillSlotProps.skillManageFooter;
148
+ var resolvedMenuMaxHeight = skillSlotProps === null || skillSlotProps === void 0 ? void 0 : skillSlotProps.menuMaxHeight;
149
+ var resolvedMenuWidth = (_skillSlotProps$menuW = skillSlotProps === null || skillSlotProps === void 0 ? void 0 : skillSlotProps.menuWidth) !== null && _skillSlotProps$menuW !== void 0 ? _skillSlotProps$menuW : 260;
150
+ var showGroupTitles = skillSlotProps === null || skillSlotProps === void 0 ? void 0 : skillSlotProps.showGroupTitles;
136
151
  var _useControlledState = useControlledState(defaultValue, valueProp),
137
152
  _useControlledState2 = _slicedToArray(_useControlledState, 2),
138
153
  text = _useControlledState2[0],
@@ -168,34 +183,54 @@ export var Composer = /*#__PURE__*/forwardRef(function Composer(_ref, ref) {
168
183
  setTriggerActiveIndex = _useState8[1];
169
184
  /** trigger menu 的命令式句柄:导航语义在 SkillSlot 内,composer 只转发 ↑↓。 */
170
185
  var triggerSkillSlotRef = useRef(null);
171
- /** lite 模式下由单行升格到多行布局;粘性:只在 text 清空时复位 */
186
+ /** lite 模式下由内容高度驱动的单行 / 多行布局状态。 */
172
187
  var _useState9 = useState(false),
173
188
  _useState10 = _slicedToArray(_useState9, 2),
174
189
  expanded = _useState10[0],
175
190
  setExpanded = _useState10[1];
176
- /** ComposerEditor 反馈的 editor 自然高度(offsetHeight,未 clamp),用于 lite 升格判断 */
177
- var _useState11 = useState(0),
191
+ /** full 模式下由右上角按钮控制的 50vh 展开态。 */
192
+ var _useState11 = useState(false),
178
193
  _useState12 = _slicedToArray(_useState11, 2),
179
- editorHeight = _useState12[0],
180
- setEditorHeight = _useState12[1];
194
+ fullExpanded = _useState12[0],
195
+ setFullExpanded = _useState12[1];
196
+ /** ComposerEditor 反馈的 editor 自然高度(offsetHeight,未 clamp),用于 lite 升格判断 */
197
+ var _useState13 = useState(0),
198
+ _useState14 = _slicedToArray(_useState13, 2),
199
+ editorHeight = _useState14[0],
200
+ setEditorHeight = _useState14[1];
181
201
  /** editor 内容是否真正达到 maxRows 触顶——配合 SCSS 控制 viewport overflow,
182
202
  * 阻止升格 transition / 换行未触顶时的 scrollbar 闪现 */
183
- var _useState13 = useState(false),
184
- _useState14 = _slicedToArray(_useState13, 2),
185
- atMax = _useState14[0],
186
- setAtMax = _useState14[1];
203
+ var _useState15 = useState(false),
204
+ _useState16 = _slicedToArray(_useState15, 2),
205
+ atMax = _useState16[0],
206
+ setAtMax = _useState16[1];
187
207
  var fileInputRef = useRef(null);
188
208
  var editorRef = useRef(null);
189
209
  var boxRef = useRef(null);
190
- var _useState15 = useState(null),
191
- _useState16 = _slicedToArray(_useState15, 2),
192
- paramEdit = _useState16[0],
193
- setParamEdit = _useState16[1];
210
+ var handleComposerMouseDown = useCallback(function (event) {
211
+ var _editorRef$current;
212
+ if (disabled || event.button !== 0) return;
213
+ var target = event.target;
214
+ if (target instanceof Element) {
215
+ if (target.closest('[contenteditable]')) return;
216
+ var isInteractive = target.closest('button, a, input, select, textarea, [role="button"]');
217
+ if (!isInteractive) {
218
+ event.preventDefault();
219
+ }
220
+ }
221
+ (_editorRef$current = editorRef.current) === null || _editorRef$current === void 0 || _editorRef$current.focus({
222
+ preventScroll: true
223
+ });
224
+ }, [disabled]);
225
+ var _useState17 = useState(null),
226
+ _useState18 = _slicedToArray(_useState17, 2),
227
+ paramEdit = _useState18[0],
228
+ setParamEdit = _useState18[1];
194
229
  var openParamPanel = useCallback(function (chipId) {
195
230
  if (!renderParamPanel) return;
196
231
  requestAnimationFrame(function () {
197
- var _editorRef$current;
198
- var host = (_editorRef$current = editorRef.current) === null || _editorRef$current === void 0 ? void 0 : _editorRef$current.getChipHost(chipId);
232
+ var _editorRef$current2;
233
+ var host = (_editorRef$current2 = editorRef.current) === null || _editorRef$current2 === void 0 ? void 0 : _editorRef$current2.getChipHost(chipId);
199
234
  if (host) setParamEdit({
200
235
  chipId: chipId,
201
236
  anchor: host
@@ -206,9 +241,9 @@ export var Composer = /*#__PURE__*/forwardRef(function Composer(_ref, ref) {
206
241
  setParamEdit(null);
207
242
  }, []);
208
243
  var handleInlineRefClick = useCallback(function (chipId, anchor) {
209
- var _editorRef$current$ge, _editorRef$current2;
244
+ var _editorRef$current$ge, _editorRef$current3;
210
245
  if (!renderParamPanel) return;
211
- var chips = (_editorRef$current$ge = (_editorRef$current2 = editorRef.current) === null || _editorRef$current2 === void 0 ? void 0 : _editorRef$current2.getChips()) !== null && _editorRef$current$ge !== void 0 ? _editorRef$current$ge : [];
246
+ var chips = (_editorRef$current$ge = (_editorRef$current3 = editorRef.current) === null || _editorRef$current3 === void 0 ? void 0 : _editorRef$current3.getChips()) !== null && _editorRef$current$ge !== void 0 ? _editorRef$current$ge : [];
212
247
  var chip = chips.find(function (c) {
213
248
  return c.id === chipId;
214
249
  });
@@ -228,32 +263,32 @@ export var Composer = /*#__PURE__*/forwardRef(function Composer(_ref, ref) {
228
263
  useImperativeHandle(ref, function () {
229
264
  return {
230
265
  focus: function focus(options) {
231
- var _editorRef$current3;
232
- return (_editorRef$current3 = editorRef.current) === null || _editorRef$current3 === void 0 ? void 0 : _editorRef$current3.focus(options);
266
+ var _editorRef$current4;
267
+ return (_editorRef$current4 = editorRef.current) === null || _editorRef$current4 === void 0 ? void 0 : _editorRef$current4.focus(options);
233
268
  },
234
269
  blur: function blur() {
235
- var _editorRef$current4;
236
- return (_editorRef$current4 = editorRef.current) === null || _editorRef$current4 === void 0 ? void 0 : _editorRef$current4.blur();
270
+ var _editorRef$current5;
271
+ return (_editorRef$current5 = editorRef.current) === null || _editorRef$current5 === void 0 ? void 0 : _editorRef$current5.blur();
237
272
  },
238
273
  clear: function clear() {
239
- var _editorRef$current5;
240
- return (_editorRef$current5 = editorRef.current) === null || _editorRef$current5 === void 0 ? void 0 : _editorRef$current5.clear();
274
+ var _editorRef$current6;
275
+ return (_editorRef$current6 = editorRef.current) === null || _editorRef$current6 === void 0 ? void 0 : _editorRef$current6.clear();
241
276
  },
242
277
  insertSkill: function insertSkill(skill) {
243
- var _editorRef$current6, _editorRef$current7;
278
+ var _editorRef$current7, _editorRef$current8;
244
279
  var data = createInvocationChipData(skill);
245
- (_editorRef$current6 = editorRef.current) === null || _editorRef$current6 === void 0 || _editorRef$current6.insertChip(data);
246
- (_editorRef$current7 = editorRef.current) === null || _editorRef$current7 === void 0 || _editorRef$current7.focus();
280
+ (_editorRef$current7 = editorRef.current) === null || _editorRef$current7 === void 0 || _editorRef$current7.insertChip(data);
281
+ (_editorRef$current8 = editorRef.current) === null || _editorRef$current8 === void 0 || _editorRef$current8.focus();
247
282
  if (skill.initialState === 'pending') openParamPanel(data.id);
248
283
  return data.id;
249
284
  },
250
285
  updateChipData: function updateChipData(id, patch) {
251
- var _editorRef$current8;
252
- return (_editorRef$current8 = editorRef.current) === null || _editorRef$current8 === void 0 ? void 0 : _editorRef$current8.updateChipData(id, patch);
286
+ var _editorRef$current9;
287
+ return (_editorRef$current9 = editorRef.current) === null || _editorRef$current9 === void 0 ? void 0 : _editorRef$current9.updateChipData(id, patch);
253
288
  },
254
289
  get nativeElement() {
255
- var _editorRef$current$na, _editorRef$current9;
256
- return (_editorRef$current$na = (_editorRef$current9 = editorRef.current) === null || _editorRef$current9 === void 0 ? void 0 : _editorRef$current9.nativeElement) !== null && _editorRef$current$na !== void 0 ? _editorRef$current$na : null;
290
+ var _editorRef$current$na, _editorRef$current10;
291
+ return (_editorRef$current$na = (_editorRef$current10 = editorRef.current) === null || _editorRef$current10 === void 0 ? void 0 : _editorRef$current10.nativeElement) !== null && _editorRef$current$na !== void 0 ? _editorRef$current$na : null;
257
292
  }
258
293
  };
259
294
  });
@@ -303,8 +338,13 @@ export var Composer = /*#__PURE__*/forwardRef(function Composer(_ref, ref) {
303
338
  if (!editorHeight) return;
304
339
  if (!expanded && editorHeight - 32 > 2) {
305
340
  setExpanded(true);
341
+ return;
306
342
  }
307
- }, [variant, expanded, editorHeight]);
343
+ if (expanded && editorHeight - 32 <= 2 && attachments.length === 0) {
344
+ setExpanded(false);
345
+ setAtMax(false);
346
+ }
347
+ }, [variant, expanded, editorHeight, attachments.length]);
308
348
 
309
349
  // 清空时回到 lite 单行
310
350
  useEffect(function () {
@@ -314,6 +354,13 @@ export var Composer = /*#__PURE__*/forwardRef(function Composer(_ref, ref) {
314
354
  }
315
355
  }, [text, attachments.length, expanded]);
316
356
 
357
+ // lite 回落到单行后同步退出手动 50vh 展开态。
358
+ useEffect(function () {
359
+ if (variant === 'lite' && !expanded) {
360
+ setFullExpanded(false);
361
+ }
362
+ }, [variant, expanded]);
363
+
317
364
  /* ---- Send ----
318
365
  * 内部 text 是 raw value(chip 序列化为零宽 marker)。
319
366
  * 对外只有一份契约:`onSend(segments, meta?)`
@@ -337,8 +384,8 @@ export var Composer = /*#__PURE__*/forwardRef(function Composer(_ref, ref) {
337
384
  * `onAttachmentsChange={setAttachments}` 直接回写。
338
385
  * - webSearch 无受控接口,直接清。 */
339
386
  var handleSend = useCallback( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee() {
340
- var _editorRef$current$ge2, _editorRef$current10;
341
- var chips, segments, hasAttachments, meta, hasMeta, result, _editorRef$current11;
387
+ var _editorRef$current$ge2, _editorRef$current11;
388
+ var chips, segments, hasAttachments, meta, hasMeta, result, _editorRef$current12;
342
389
  return _regeneratorRuntime().wrap(function _callee$(_context) {
343
390
  while (1) switch (_context.prev = _context.next) {
344
391
  case 0:
@@ -357,7 +404,7 @@ export var Composer = /*#__PURE__*/forwardRef(function Composer(_ref, ref) {
357
404
  }
358
405
  return _context.abrupt("return");
359
406
  case 4:
360
- chips = (_editorRef$current$ge2 = (_editorRef$current10 = editorRef.current) === null || _editorRef$current10 === void 0 ? void 0 : _editorRef$current10.getChips()) !== null && _editorRef$current$ge2 !== void 0 ? _editorRef$current$ge2 : [];
407
+ chips = (_editorRef$current$ge2 = (_editorRef$current11 = editorRef.current) === null || _editorRef$current11 === void 0 ? void 0 : _editorRef$current11.getChips()) !== null && _editorRef$current$ge2 !== void 0 ? _editorRef$current$ge2 : [];
361
408
  segments = rawValueToSegments(text, chips);
362
409
  hasAttachments = attachments.length > 0;
363
410
  if (!(!segmentsHasContent(segments) && !hasAttachments)) {
@@ -382,7 +429,7 @@ export var Composer = /*#__PURE__*/forwardRef(function Composer(_ref, ref) {
382
429
  case 18:
383
430
  closeParamPanel();
384
431
  if (valueProp === undefined) {
385
- (_editorRef$current11 = editorRef.current) === null || _editorRef$current11 === void 0 || _editorRef$current11.clear();
432
+ (_editorRef$current12 = editorRef.current) === null || _editorRef$current12 === void 0 || _editorRef$current12.clear();
386
433
  }
387
434
  if (attachmentsProp === undefined) {
388
435
  setAttachments([]);
@@ -491,7 +538,7 @@ export var Composer = /*#__PURE__*/forwardRef(function Composer(_ref, ref) {
491
538
  updateAttachments([].concat(_toConsumableArray(attachments), _toConsumableArray(accepted)));
492
539
  }, [accept, attachments, attachmentsDisabled, disabled, maxFileCount, maxFileSize, maxTotalSize, onAttachFiles, updateAttachments]);
493
540
  var handleFileChange = function handleFileChange(e) {
494
- var _editorRef$current12;
541
+ var _editorRef$current13;
495
542
  var files = e.target.files;
496
543
  if (!files) return;
497
544
  addFilesFromList(Array.from(files));
@@ -499,12 +546,12 @@ export var Composer = /*#__PURE__*/forwardRef(function Composer(_ref, ref) {
499
546
  /* 文件框关闭后焦点回到 editor:
500
547
  * 键盘(Tab + Enter)唤起文件框的路径下按钮持有焦点,
501
548
  * 不夺回焦点时 Enter 会再次激活按钮而不是发送 */
502
- (_editorRef$current12 = editorRef.current) === null || _editorRef$current12 === void 0 || _editorRef$current12.focus();
549
+ (_editorRef$current13 = editorRef.current) === null || _editorRef$current13 === void 0 || _editorRef$current13.focus();
503
550
  };
504
- var _useState17 = useState(false),
505
- _useState18 = _slicedToArray(_useState17, 2),
506
- fileDragOver = _useState18[0],
507
- setFileDragOver = _useState18[1];
551
+ var _useState19 = useState(false),
552
+ _useState20 = _slicedToArray(_useState19, 2),
553
+ fileDragOver = _useState20[0],
554
+ setFileDragOver = _useState20[1];
508
555
  var composerBoxFileDragAttrs = fileDragOver ? {
509
556
  'data-odn-composer-file-drag': ''
510
557
  } : {};
@@ -541,14 +588,14 @@ export var Composer = /*#__PURE__*/forwardRef(function Composer(_ref, ref) {
541
588
  var handleSelectSkill = useCallback(function (skill, source) {
542
589
  var data = createInvocationChipData(skill);
543
590
  if (source === 'trigger') {
544
- var _editorRef$current13;
545
- (_editorRef$current13 = editorRef.current) === null || _editorRef$current13 === void 0 || _editorRef$current13.replaceTriggerWithChip(data);
591
+ var _editorRef$current14;
592
+ (_editorRef$current14 = editorRef.current) === null || _editorRef$current14 === void 0 || _editorRef$current14.replaceTriggerWithChip(data);
546
593
  setTriggerInfo(null);
547
594
  } else {
548
- var _editorRef$current14, _editorRef$current15;
549
- (_editorRef$current14 = editorRef.current) === null || _editorRef$current14 === void 0 || _editorRef$current14.insertChip(data);
595
+ var _editorRef$current15, _editorRef$current16;
596
+ (_editorRef$current15 = editorRef.current) === null || _editorRef$current15 === void 0 || _editorRef$current15.insertChip(data);
550
597
  setToolMenuOpen(false);
551
- (_editorRef$current15 = editorRef.current) === null || _editorRef$current15 === void 0 || _editorRef$current15.focus();
598
+ (_editorRef$current16 = editorRef.current) === null || _editorRef$current16 === void 0 || _editorRef$current16.focus();
552
599
  }
553
600
  if (skill.initialState === 'pending') openParamPanel(data.id);
554
601
  }, [openParamPanel]);
@@ -599,7 +646,7 @@ export var Composer = /*#__PURE__*/forwardRef(function Composer(_ref, ref) {
599
646
  return !s.disabled;
600
647
  });
601
648
  setTriggerActiveIndex(first === -1 ? 0 : first);
602
- }, [filteredSkills, filteredSkillGroups, skills, skillGroups, triggerInfo === null || triggerInfo === void 0 ? void 0 : triggerInfo.query, triggerInfo == null]);
649
+ }, [filteredSkills, filteredSkillGroups, skills, skillGroups, triggerInfo === null || triggerInfo === void 0 ? void 0 : triggerInfo.query, triggerInfo === null]);
603
650
 
604
651
  /* editor 在 trigger 激活时把 ↑↓Enter Esc Tab 丢过来。返回 true = editor 别管了。
605
652
  * - ↑↓ 改高亮 index(夹在 [0, max] 内)
@@ -632,9 +679,9 @@ export var Composer = /*#__PURE__*/forwardRef(function Composer(_ref, ref) {
632
679
  return true;
633
680
  }
634
681
  if (e.key === 'Escape') {
635
- var _editorRef$current16;
682
+ var _editorRef$current17;
636
683
  e.preventDefault();
637
- (_editorRef$current16 = editorRef.current) === null || _editorRef$current16 === void 0 || _editorRef$current16.cancelTrigger();
684
+ (_editorRef$current17 = editorRef.current) === null || _editorRef$current17 === void 0 || _editorRef$current17.cancelTrigger();
638
685
  setTriggerInfo(null);
639
686
  return true;
640
687
  }
@@ -668,17 +715,39 @@ export var Composer = /*#__PURE__*/forwardRef(function Composer(_ref, ref) {
668
715
  var effectiveTools = isLite ? tools.slice(0, 1) : tools;
669
716
 
670
717
  /* 统一解析 toolConfigs:
671
- * - 不传 toolConfigs → 全部用 DEFAULT_TOOL_CONFIGS
672
- * - 传了 toolConfigs → 每个 key 看用户配置:有 icon 或 label 就用它,否则兜底 { label: key }
718
+ * - key 未配置 → 整份默认
719
+ * - 只传 tooltip → 保留默认 icon/label,覆盖说明
720
+ * - 传了 icon 和/或 label → 按显式字段渲染视觉(缺省字段不渲染)
721
+ * - 空对象 {} → 英文名兜底
673
722
  */
674
723
  var resolvedToolConfigs = function () {
675
724
  if (!toolConfigs) return DEFAULT_TOOL_CONFIGS;
676
725
  var resolve = function resolve(key) {
677
- var cfg = toolConfigs[key];
678
- if (cfg && (cfg.icon || cfg.label)) return cfg;
679
- return {
726
+ var _toolConfigs$key;
727
+ if (!Object.prototype.hasOwnProperty.call(toolConfigs, key)) {
728
+ return DEFAULT_TOOL_CONFIGS[key];
729
+ }
730
+ var cfg = (_toolConfigs$key = toolConfigs[key]) !== null && _toolConfigs$key !== void 0 ? _toolConfigs$key : {};
731
+ var hasIcon = Object.prototype.hasOwnProperty.call(cfg, 'icon');
732
+ var hasLabel = Object.prototype.hasOwnProperty.call(cfg, 'label');
733
+ var hasTooltip = Object.prototype.hasOwnProperty.call(cfg, 'tooltip');
734
+ var tooltip = hasTooltip ? cfg.tooltip : DEFAULT_TOOL_CONFIGS[key].tooltip;
735
+
736
+ /* 仅 tooltip / 未来非视觉字段:保留默认皮肤 */
737
+ if (!hasIcon && !hasLabel) {
738
+ if (!hasTooltip) return {
739
+ label: key
740
+ };
741
+ return _objectSpread(_objectSpread({}, DEFAULT_TOOL_CONFIGS[key]), {}, {
742
+ tooltip: tooltip
743
+ });
744
+ }
745
+ var visualConfig = cfg.icon || cfg.label ? cfg : {
680
746
  label: key
681
747
  };
748
+ return _objectSpread(_objectSpread({}, visualConfig), {}, {
749
+ tooltip: tooltip
750
+ });
682
751
  };
683
752
  return {
684
753
  attachment: resolve('attachment'),
@@ -700,11 +769,15 @@ export var Composer = /*#__PURE__*/forwardRef(function Composer(_ref, ref) {
700
769
  var btnDisabled = disabled || attachmentsDisabled;
701
770
  var _resolvedToolConfigs$ = resolvedToolConfigs.attachment,
702
771
  icon = _resolvedToolConfigs$.icon,
703
- label = _resolvedToolConfigs$.label;
772
+ label = _resolvedToolConfigs$.label,
773
+ tooltip = _resolvedToolConfigs$.tooltip;
704
774
  var showIcon = !!icon;
705
775
  var showLabel = effectiveLabeled && !!label;
706
- return /*#__PURE__*/React.createElement(HoverFill, {
776
+ return /*#__PURE__*/React.createElement(Tooltip, {
707
777
  key: "attachment",
778
+ popup: tooltip,
779
+ placement: "top"
780
+ }, /*#__PURE__*/React.createElement(HoverFill, {
708
781
  "data-odn-composer-tool-btn-wrap": true,
709
782
  bgClassName: "odn-composer-tool-btn-bg",
710
783
  activeColor: TOOL_BTN_ACTIVE,
@@ -726,21 +799,24 @@ export var Composer = /*#__PURE__*/forwardRef(function Composer(_ref, ref) {
726
799
  "data-odn-composer-tool-iconic": !showLabel || undefined,
727
800
  "data-odn-composer-tool-disabled": btnDisabled || undefined,
728
801
  "aria-label": label || 'attachment',
729
- "aria-disabled": btnDisabled || undefined,
730
- title: showLabel ? undefined : label || 'attachment'
802
+ "aria-disabled": btnDisabled || undefined
731
803
  }, showIcon && /*#__PURE__*/React.createElement(Icon, {
732
804
  name: icon,
733
805
  size: 16
734
- }), showLabel && /*#__PURE__*/React.createElement("span", null, label)));
806
+ }), showLabel && /*#__PURE__*/React.createElement("span", null, label))));
735
807
  };
736
808
  var renderWebSearchBtn = function renderWebSearchBtn() {
737
809
  var _resolvedToolConfigs$2 = resolvedToolConfigs.webSearch,
738
810
  icon = _resolvedToolConfigs$2.icon,
739
- label = _resolvedToolConfigs$2.label;
811
+ label = _resolvedToolConfigs$2.label,
812
+ tooltip = _resolvedToolConfigs$2.tooltip;
740
813
  var showIcon = !!icon;
741
814
  var showLabel = effectiveLabeled && !!label;
742
- return /*#__PURE__*/React.createElement(HoverFill, {
815
+ return /*#__PURE__*/React.createElement(Tooltip, {
743
816
  key: "webSearch",
817
+ popup: tooltip,
818
+ placement: "top"
819
+ }, /*#__PURE__*/React.createElement(HoverFill, {
744
820
  "data-odn-composer-tool-btn-wrap": true,
745
821
  bgClassName: "odn-composer-tool-btn-bg",
746
822
  activeColor: TOOL_BTN_ACTIVE,
@@ -764,12 +840,11 @@ export var Composer = /*#__PURE__*/forwardRef(function Composer(_ref, ref) {
764
840
  "data-odn-composer-tool-disabled": disabled || undefined,
765
841
  "aria-label": label || 'webSearch',
766
842
  "aria-pressed": webSearch,
767
- "aria-disabled": disabled || undefined,
768
- title: showLabel ? undefined : label || 'webSearch'
843
+ "aria-disabled": disabled || undefined
769
844
  }, showIcon && /*#__PURE__*/React.createElement(Icon, {
770
845
  name: icon,
771
846
  size: 16
772
- }), showLabel && /*#__PURE__*/React.createElement("span", null, label)));
847
+ }), showLabel && /*#__PURE__*/React.createElement("span", null, label))));
773
848
  };
774
849
  var renderSkillBtn = function renderSkillBtn() {
775
850
  var hasAnySkills = skills && skills.length > 0 || skillGroups && skillGroups.some(function (g) {
@@ -778,11 +853,19 @@ export var Composer = /*#__PURE__*/forwardRef(function Composer(_ref, ref) {
778
853
  if (!hasAnySkills) return null;
779
854
  var _resolvedToolConfigs$3 = resolvedToolConfigs.skill,
780
855
  icon = _resolvedToolConfigs$3.icon,
781
- label = _resolvedToolConfigs$3.label;
856
+ label = _resolvedToolConfigs$3.label,
857
+ tooltip = _resolvedToolConfigs$3.tooltip;
782
858
  var showIcon = !!icon;
783
859
  var showLabel = effectiveLabeled && !!label;
784
- return /*#__PURE__*/React.createElement(Popover, {
860
+ return /*#__PURE__*/React.createElement(Tooltip, {
785
861
  key: "skill",
862
+ popup: tooltip
863
+ /* 技能菜单展开时硬切关掉入口 tooltip,避免与 SkillSlot 叠层 */,
864
+ visible: toolMenuOpen ? false : undefined,
865
+ transitionDuration: toolMenuOpen ? 0 : undefined
866
+ }, /*#__PURE__*/React.createElement("div", {
867
+ "data-odn-composer-skill-trigger": true
868
+ }, /*#__PURE__*/React.createElement(Popover, {
786
869
  trigger: "click",
787
870
  arrowed: false,
788
871
  placement: "topLeft",
@@ -798,10 +881,9 @@ export var Composer = /*#__PURE__*/forwardRef(function Composer(_ref, ref) {
798
881
  variant: "menu",
799
882
  skills: skillGroups ? undefined : skills,
800
883
  skillGroups: skillGroups,
801
- menuMaxHeight: skillMenuMaxHeight,
802
- style: {
803
- width: skillMenuWidth !== null && skillMenuWidth !== void 0 ? skillMenuWidth : 260
804
- },
884
+ showGroupTitles: showGroupTitles,
885
+ menuMaxHeight: resolvedMenuMaxHeight,
886
+ menuWidth: resolvedMenuWidth,
805
887
  onSelect: function onSelect(s) {
806
888
  return handleSelectSkill(s, 'btn');
807
889
  },
@@ -824,12 +906,12 @@ export var Composer = /*#__PURE__*/forwardRef(function Composer(_ref, ref) {
824
906
  "data-odn-composer-tool-active": toolMenuOpen || undefined,
825
907
  "data-odn-composer-tool-disabled": disabled || undefined,
826
908
  "aria-label": label || 'skill',
827
- "aria-disabled": disabled || undefined,
828
- title: showLabel ? undefined : label || 'skill'
909
+ "aria-expanded": toolMenuOpen,
910
+ "aria-disabled": disabled || undefined
829
911
  }, showIcon && /*#__PURE__*/React.createElement(Icon, {
830
912
  name: icon,
831
913
  size: 16
832
- }), showLabel && /*#__PURE__*/React.createElement("span", null, label))));
914
+ }), showLabel && /*#__PURE__*/React.createElement("span", null, label))))));
833
915
  };
834
916
  var toolNodes = effectiveTools.map(function (t) {
835
917
  if (t === 'attachment') return renderAttachmentBtn();
@@ -892,7 +974,7 @@ export var Composer = /*#__PURE__*/forwardRef(function Composer(_ref, ref) {
892
974
  "data-odn-composer-stop-btn": true,
893
975
  title: "\u505C\u6B62\u751F\u6210"
894
976
  }, /*#__PURE__*/React.createElement(Icon, {
895
- name: "pause-filled",
977
+ name: "square-filled",
896
978
  size: 18
897
979
  })) : /*#__PURE__*/React.createElement("button", {
898
980
  type: "button",
@@ -909,8 +991,11 @@ export var Composer = /*#__PURE__*/forwardRef(function Composer(_ref, ref) {
909
991
  // 工具栏(full 专用,作为 textarea 的 bottomElement)
910
992
  var toolbarSlot = /*#__PURE__*/React.createElement("div", {
911
993
  "data-odn-composer-toolbar": true
912
- }, /*#__PURE__*/React.createElement("div", {
913
- "data-odn-composer-toolbar-left": true
994
+ }, /*#__PURE__*/React.createElement(Tooltip.Group, {
995
+ as: "div",
996
+ placement: "top",
997
+ "data-odn-composer-toolbar-left": true,
998
+ visible: toolMenuOpen ? false : undefined
914
999
  }, toolNodes), sendOrStopButton);
915
1000
 
916
1001
  // 文件 input 独立渲染一次,在两种形态下都由同一 ref 控制
@@ -922,9 +1007,9 @@ export var Composer = /*#__PURE__*/forwardRef(function Composer(_ref, ref) {
922
1007
  "data-odn-composer-file-input": true,
923
1008
  onChange: handleFileChange
924
1009
  });
925
- var paramPanelNode = function (_editorRef$current$ge3, _editorRef$current17, _boxRef$current) {
1010
+ var paramPanelNode = function (_editorRef$current$ge3, _editorRef$current18, _boxRef$current) {
926
1011
  if (!paramEdit || !renderParamPanel) return null;
927
- var chips = (_editorRef$current$ge3 = (_editorRef$current17 = editorRef.current) === null || _editorRef$current17 === void 0 ? void 0 : _editorRef$current17.getChips()) !== null && _editorRef$current$ge3 !== void 0 ? _editorRef$current$ge3 : [];
1012
+ var chips = (_editorRef$current$ge3 = (_editorRef$current18 = editorRef.current) === null || _editorRef$current18 === void 0 ? void 0 : _editorRef$current18.getChips()) !== null && _editorRef$current$ge3 !== void 0 ? _editorRef$current$ge3 : [];
928
1013
  var chip = chips.find(function (c) {
929
1014
  return c.id === paramEdit.chipId;
930
1015
  });
@@ -934,8 +1019,8 @@ export var Composer = /*#__PURE__*/forwardRef(function Composer(_ref, ref) {
934
1019
  chip: chip,
935
1020
  anchor: paramEdit.anchor,
936
1021
  onApply: function onApply(patch) {
937
- var _editorRef$current18;
938
- (_editorRef$current18 = editorRef.current) === null || _editorRef$current18 === void 0 || _editorRef$current18.updateChipData(chip.id, patch);
1022
+ var _editorRef$current19;
1023
+ (_editorRef$current19 = editorRef.current) === null || _editorRef$current19 === void 0 || _editorRef$current19.updateChipData(chip.id, patch);
939
1024
  },
940
1025
  onClose: closeParamPanel
941
1026
  };
@@ -999,8 +1084,8 @@ export var Composer = /*#__PURE__*/forwardRef(function Composer(_ref, ref) {
999
1084
  visible: triggerMenuVisible,
1000
1085
  onVisibleChange: function onVisibleChange(v) {
1001
1086
  if (!v) {
1002
- var _editorRef$current19;
1003
- (_editorRef$current19 = editorRef.current) === null || _editorRef$current19 === void 0 || _editorRef$current19.cancelTrigger();
1087
+ var _editorRef$current20;
1088
+ (_editorRef$current20 = editorRef.current) === null || _editorRef$current20 === void 0 || _editorRef$current20.cancelTrigger();
1004
1089
  setTriggerInfo(null);
1005
1090
  }
1006
1091
  },
@@ -1010,12 +1095,11 @@ export var Composer = /*#__PURE__*/forwardRef(function Composer(_ref, ref) {
1010
1095
  variant: "menu",
1011
1096
  skills: skillGroups ? undefined : filteredSkills !== null && filteredSkills !== void 0 ? filteredSkills : [],
1012
1097
  skillGroups: filteredSkillGroups,
1098
+ showGroupTitles: showGroupTitles,
1013
1099
  activeIndex: triggerActiveIndex,
1014
1100
  onActiveIndexChange: setTriggerActiveIndex,
1015
- menuMaxHeight: skillMenuMaxHeight,
1016
- style: {
1017
- width: skillMenuWidth !== null && skillMenuWidth !== void 0 ? skillMenuWidth : 260
1018
- },
1101
+ menuMaxHeight: resolvedMenuMaxHeight,
1102
+ menuWidth: resolvedMenuWidth,
1019
1103
  onSelect: function onSelect(s) {
1020
1104
  return handleSelectSkill(s, 'trigger');
1021
1105
  },
@@ -1036,16 +1120,19 @@ export var Composer = /*#__PURE__*/forwardRef(function Composer(_ref, ref) {
1036
1120
 
1037
1121
  // lite:有附件即强制升格(否则按钮会和附件/多行内容打架)
1038
1122
  var liteExpanded = isLite && !isInlineLite;
1123
+ var fullExpandLabel = fullExpanded ? '收起输入框' : '展开输入框';
1039
1124
  return /*#__PURE__*/React.createElement("div", {
1040
1125
  "data-odn-composer": true,
1041
1126
  "data-odn-composer-variant": variant,
1042
1127
  "data-odn-composer-expanded": liteExpanded ? '' : undefined,
1128
+ "data-odn-composer-full-expanded": fullExpanded ? '' : undefined,
1043
1129
  "data-odn-composer-atmax": atMax ? '' : undefined,
1044
1130
  "data-odn-composer-disabled": disabled || undefined,
1045
1131
  "data-odn-composer-spacing": spacing === 'drawer' ? 'drawer' : undefined,
1046
1132
  "aria-disabled": disabled || undefined,
1047
1133
  className: className !== null && className !== void 0 ? className : spacing === 'drawer' ? 'shrink-0' : undefined,
1048
- style: style
1134
+ style: style,
1135
+ onMouseDown: handleComposerMouseDown
1049
1136
  }, /*#__PURE__*/React.createElement("div", {
1050
1137
  "data-odn-composer-inner": true
1051
1138
  }, hiddenFileInput, triggerMenu, paramPanelNode, /*#__PURE__*/React.createElement("div", _extends({
@@ -1056,8 +1143,27 @@ export var Composer = /*#__PURE__*/forwardRef(function Composer(_ref, ref) {
1056
1143
  onDragOver: handleComposerDragOver,
1057
1144
  onDragLeave: handleComposerDragLeave,
1058
1145
  onDrop: handleComposerDrop
1059
- }), attachmentsSlot, editorNode, !isLite && toolbarSlot, isLite && hasTools && /*#__PURE__*/React.createElement("div", {
1060
- "data-odn-composer-lite-tools": true
1146
+ }), !isInlineLite && /*#__PURE__*/React.createElement(Tooltip, {
1147
+ popup: fullExpandLabel,
1148
+ placement: "top"
1149
+ }, /*#__PURE__*/React.createElement("button", {
1150
+ type: "button",
1151
+ "data-odn-composer-expand-btn": true,
1152
+ "aria-label": fullExpandLabel,
1153
+ "aria-expanded": fullExpanded,
1154
+ onClick: function onClick() {
1155
+ return setFullExpanded(function (current) {
1156
+ return !current;
1157
+ });
1158
+ }
1159
+ }, /*#__PURE__*/React.createElement(Icon, {
1160
+ name: fullExpanded ? 'minimize-2' : 'maximize-2',
1161
+ size: 16
1162
+ }))), attachmentsSlot, editorNode, !isLite && toolbarSlot, isLite && hasTools && /*#__PURE__*/React.createElement(Tooltip.Group, {
1163
+ as: "div",
1164
+ placement: "top",
1165
+ "data-odn-composer-lite-tools": true,
1166
+ visible: toolMenuOpen ? false : undefined
1061
1167
  }, toolNodes), isLite && /*#__PURE__*/React.createElement("div", {
1062
1168
  "data-odn-composer-lite-send": true
1063
1169
  }, sendOrStopButton)), hint && /*#__PURE__*/React.createElement("p", {