one-design-next 0.0.86 → 0.0.87
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chat-list/index.d.ts +15 -4
- package/dist/chat-list/index.js +55 -40
- package/dist/chat-list/style/index.css +31 -2
- package/dist/composer/editor.d.ts +4 -1
- package/dist/composer/editor.js +28 -9
- package/dist/composer/index.js +109 -66
- package/dist/composer/style/index.css +15 -8
- package/dist/composer/utils.d.ts +13 -1
- package/dist/composer/utils.js +33 -11
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/skill-slot/index.d.ts +4 -3
- package/dist/skill-slot/index.js +56 -28
- package/dist/skill-slot/style/index.css +83 -43
- package/package.json +1 -1
package/dist/composer/index.js
CHANGED
|
@@ -16,10 +16,11 @@ import { Message } from "../message";
|
|
|
16
16
|
import Popover from "../popover";
|
|
17
17
|
import SkillSlot from "../skill-slot";
|
|
18
18
|
import Tooltip from "../tooltip";
|
|
19
|
-
import { ComposerEditor } from "./editor";
|
|
19
|
+
import { COMPOSER_EDITOR_MAX_ROWS_PX, ComposerEditor } from "./editor";
|
|
20
20
|
import { chipHasEditableParams, isMentionChip } from "./inline-ref";
|
|
21
21
|
import { rawValueToSegments, segmentsHasContent } from "./segments";
|
|
22
22
|
import "./style";
|
|
23
|
+
import { filterSkillsByQuery, resolveComposerSkillMenuWidth, shouldOpenSlashTriggerMenu } from "./utils";
|
|
23
24
|
function createInvocationChipData(skill) {
|
|
24
25
|
return {
|
|
25
26
|
id: "skill-".concat(skill.id, "-").concat(Date.now().toString(36), "-").concat(Math.random().toString(36).slice(2, 6)),
|
|
@@ -96,7 +97,7 @@ var DEFAULT_TOOL_CONFIGS = {
|
|
|
96
97
|
*/
|
|
97
98
|
|
|
98
99
|
export var Composer = /*#__PURE__*/forwardRef(function Composer(_ref, ref) {
|
|
99
|
-
var
|
|
100
|
+
var _filteredSkillGroups$, _filteredSkills$lengt, _paramEdit$chipId;
|
|
100
101
|
var valueProp = _ref.value,
|
|
101
102
|
_ref$defaultValue = _ref.defaultValue,
|
|
102
103
|
defaultValue = _ref$defaultValue === void 0 ? '' : _ref$defaultValue,
|
|
@@ -150,7 +151,6 @@ export var Composer = /*#__PURE__*/forwardRef(function Composer(_ref, ref) {
|
|
|
150
151
|
var onManageSkills = skillSlotProps === null || skillSlotProps === void 0 ? void 0 : skillSlotProps.onManageSkills;
|
|
151
152
|
var skillManageFooter = skillSlotProps === null || skillSlotProps === void 0 ? void 0 : skillSlotProps.skillManageFooter;
|
|
152
153
|
var resolvedMenuMaxHeight = skillSlotProps === null || skillSlotProps === void 0 ? void 0 : skillSlotProps.menuMaxHeight;
|
|
153
|
-
var resolvedMenuWidth = (_skillSlotProps$menuW = skillSlotProps === null || skillSlotProps === void 0 ? void 0 : skillSlotProps.menuWidth) !== null && _skillSlotProps$menuW !== void 0 ? _skillSlotProps$menuW : 260;
|
|
154
154
|
var showGroupTitles = skillSlotProps === null || skillSlotProps === void 0 ? void 0 : skillSlotProps.showGroupTitles;
|
|
155
155
|
var _useControlledState = useControlledState(defaultValue, valueProp),
|
|
156
156
|
_useControlledState2 = _slicedToArray(_useControlledState, 2),
|
|
@@ -192,7 +192,7 @@ export var Composer = /*#__PURE__*/forwardRef(function Composer(_ref, ref) {
|
|
|
192
192
|
_useState10 = _slicedToArray(_useState9, 2),
|
|
193
193
|
expanded = _useState10[0],
|
|
194
194
|
setExpanded = _useState10[1];
|
|
195
|
-
/**
|
|
195
|
+
/** 右上角按钮:拉到当前生效上限(10 行盒高,矮屏被整框 50vh 截住)。 */
|
|
196
196
|
var _useState11 = useState(false),
|
|
197
197
|
_useState12 = _slicedToArray(_useState11, 2),
|
|
198
198
|
fullExpanded = _useState12[0],
|
|
@@ -202,8 +202,7 @@ export var Composer = /*#__PURE__*/forwardRef(function Composer(_ref, ref) {
|
|
|
202
202
|
_useState14 = _slicedToArray(_useState13, 2),
|
|
203
203
|
editorHeight = _useState14[0],
|
|
204
204
|
setEditorHeight = _useState14[1];
|
|
205
|
-
/**
|
|
206
|
-
* 阻止升格 transition / 换行未触顶时的 scrollbar 闪现 */
|
|
205
|
+
/** 内容已超过 10 行,或整框 50vh 把编辑器挤到放不下当前内容 */
|
|
207
206
|
var _useState15 = useState(false),
|
|
208
207
|
_useState16 = _slicedToArray(_useState15, 2),
|
|
209
208
|
atMax = _useState16[0],
|
|
@@ -211,6 +210,35 @@ export var Composer = /*#__PURE__*/forwardRef(function Composer(_ref, ref) {
|
|
|
211
210
|
var fileInputRef = useRef(null);
|
|
212
211
|
var editorRef = useRef(null);
|
|
213
212
|
var boxRef = useRef(null);
|
|
213
|
+
var skillTriggerRef = useRef(null);
|
|
214
|
+
var triggerAnchorRef = useRef(null);
|
|
215
|
+
var _useState17 = useState(0),
|
|
216
|
+
_useState18 = _slicedToArray(_useState17, 2),
|
|
217
|
+
skillMenuCrossAxis = _useState18[0],
|
|
218
|
+
setSkillMenuCrossAxis = _useState18[1];
|
|
219
|
+
/** composer box 实宽;技能菜单默认比它略窄。显式 menuWidth 覆盖。 */
|
|
220
|
+
var _useState19 = useState(0),
|
|
221
|
+
_useState20 = _slicedToArray(_useState19, 2),
|
|
222
|
+
boxWidth = _useState20[0],
|
|
223
|
+
setBoxWidth = _useState20[1];
|
|
224
|
+
useLayoutEffect(function () {
|
|
225
|
+
var el = boxRef.current;
|
|
226
|
+
if (!el) return undefined;
|
|
227
|
+
var sync = function sync() {
|
|
228
|
+
var next = el.getBoundingClientRect().width;
|
|
229
|
+
setBoxWidth(function (prev) {
|
|
230
|
+
return prev === next ? prev : next;
|
|
231
|
+
});
|
|
232
|
+
};
|
|
233
|
+
sync();
|
|
234
|
+
if (typeof ResizeObserver === 'undefined') return undefined;
|
|
235
|
+
var ro = new ResizeObserver(sync);
|
|
236
|
+
ro.observe(el);
|
|
237
|
+
return function () {
|
|
238
|
+
return ro.disconnect();
|
|
239
|
+
};
|
|
240
|
+
}, []);
|
|
241
|
+
var resolvedMenuWidth = resolveComposerSkillMenuWidth(skillSlotProps === null || skillSlotProps === void 0 ? void 0 : skillSlotProps.menuWidth, boxWidth);
|
|
214
242
|
var handleComposerMouseDown = useCallback(function (event) {
|
|
215
243
|
var _editorRef$current;
|
|
216
244
|
if (disabled || event.button !== 0) return;
|
|
@@ -226,10 +254,10 @@ export var Composer = /*#__PURE__*/forwardRef(function Composer(_ref, ref) {
|
|
|
226
254
|
preventScroll: true
|
|
227
255
|
});
|
|
228
256
|
}, [disabled]);
|
|
229
|
-
var
|
|
230
|
-
|
|
231
|
-
paramEdit =
|
|
232
|
-
setParamEdit =
|
|
257
|
+
var _useState21 = useState(null),
|
|
258
|
+
_useState22 = _slicedToArray(_useState21, 2),
|
|
259
|
+
paramEdit = _useState22[0],
|
|
260
|
+
setParamEdit = _useState22[1];
|
|
233
261
|
var openParamPanel = useCallback(function (chipId) {
|
|
234
262
|
if (!renderParamPanel) return;
|
|
235
263
|
requestAnimationFrame(function () {
|
|
@@ -369,13 +397,19 @@ export var Composer = /*#__PURE__*/forwardRef(function Composer(_ref, ref) {
|
|
|
369
397
|
}
|
|
370
398
|
}, [text, attachments.length, expanded]);
|
|
371
399
|
|
|
372
|
-
// lite
|
|
400
|
+
// lite 回落到单行后同步退出手动展开态。
|
|
373
401
|
useEffect(function () {
|
|
374
402
|
if (variant === 'lite' && !expanded) {
|
|
375
403
|
setFullExpanded(false);
|
|
376
404
|
}
|
|
377
405
|
}, [variant, expanded]);
|
|
378
406
|
|
|
407
|
+
// 内容已顶满(满 10 行或整框 50vh 溢出)时展开态没有可切换的高度。
|
|
408
|
+
var atHeightCap = atMax || editorHeight >= COMPOSER_EDITOR_MAX_ROWS_PX;
|
|
409
|
+
useEffect(function () {
|
|
410
|
+
if (atHeightCap) setFullExpanded(false);
|
|
411
|
+
}, [atHeightCap]);
|
|
412
|
+
|
|
379
413
|
/* ---- Send ----
|
|
380
414
|
* 内部 text 是 raw value(chip 序列化为零宽 marker)。
|
|
381
415
|
* 对外只有一份契约:`onSend(segments, meta?)`
|
|
@@ -564,10 +598,10 @@ export var Composer = /*#__PURE__*/forwardRef(function Composer(_ref, ref) {
|
|
|
564
598
|
* 不夺回焦点时 Enter 会再次激活按钮而不是发送 */
|
|
565
599
|
(_editorRef$current15 = editorRef.current) === null || _editorRef$current15 === void 0 || _editorRef$current15.focus();
|
|
566
600
|
};
|
|
567
|
-
var
|
|
568
|
-
|
|
569
|
-
fileDragOver =
|
|
570
|
-
setFileDragOver =
|
|
601
|
+
var _useState23 = useState(false),
|
|
602
|
+
_useState24 = _slicedToArray(_useState23, 2),
|
|
603
|
+
fileDragOver = _useState24[0],
|
|
604
|
+
setFileDragOver = _useState24[1];
|
|
571
605
|
var composerBoxFileDragAttrs = fileDragOver ? {
|
|
572
606
|
'data-odn-composer-file-drag': ''
|
|
573
607
|
} : {};
|
|
@@ -617,39 +651,37 @@ export var Composer = /*#__PURE__*/forwardRef(function Composer(_ref, ref) {
|
|
|
617
651
|
}, [openParamPanel]);
|
|
618
652
|
|
|
619
653
|
/* trigger query 实时筛选 skills(substring match,case-insensitive)。
|
|
620
|
-
*
|
|
654
|
+
* trigger 已结束时返回空列表,避免 Popover 关闭动画那一帧把子节点切回全量目录。
|
|
655
|
+
* 依赖 query / trigger 而不是整个 triggerInfo:rect 变化不应重建列表。 */
|
|
656
|
+
var slashTriggerActive = (triggerInfo === null || triggerInfo === void 0 ? void 0 : triggerInfo.trigger) === '/';
|
|
657
|
+
var slashTriggerQuery = slashTriggerActive ? triggerInfo === null || triggerInfo === void 0 ? void 0 : triggerInfo.query : undefined;
|
|
621
658
|
var filteredSkills = useMemo(function () {
|
|
622
|
-
var _triggerInfo$query;
|
|
623
659
|
if (!skills) return undefined;
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
return s.label.toLowerCase().includes(q);
|
|
628
|
-
});
|
|
629
|
-
}, [skills, triggerInfo === null || triggerInfo === void 0 ? void 0 : triggerInfo.query]);
|
|
660
|
+
if (!slashTriggerActive) return [];
|
|
661
|
+
return filterSkillsByQuery(skills, slashTriggerQuery);
|
|
662
|
+
}, [skills, slashTriggerActive, slashTriggerQuery]);
|
|
630
663
|
|
|
631
664
|
/* grouped 版本的 trigger query 筛选:按组分别过滤,保留非空组。 */
|
|
632
665
|
var filteredSkillGroups = useMemo(function () {
|
|
633
|
-
var _triggerInfo$query2;
|
|
634
666
|
if (!skillGroups) return undefined;
|
|
635
|
-
|
|
636
|
-
if (!q) return skillGroups;
|
|
667
|
+
if (!slashTriggerActive) return [];
|
|
637
668
|
return skillGroups.map(function (g) {
|
|
638
669
|
return {
|
|
639
670
|
groupName: g.groupName,
|
|
640
|
-
skills: g.skills
|
|
641
|
-
return s.label.toLowerCase().includes(q);
|
|
642
|
-
})
|
|
671
|
+
skills: filterSkillsByQuery(g.skills, slashTriggerQuery)
|
|
643
672
|
};
|
|
644
673
|
}).filter(function (g) {
|
|
645
674
|
return g.skills.length > 0;
|
|
646
675
|
});
|
|
647
|
-
}, [skillGroups,
|
|
676
|
+
}, [skillGroups, slashTriggerActive, slashTriggerQuery]);
|
|
648
677
|
|
|
649
|
-
/* trigger
|
|
650
|
-
*
|
|
678
|
+
/* trigger 浮层:`/` 触发态 + 目录非空 + 过滤后仍有命中。
|
|
679
|
+
* 无匹配时菜单关闭,Enter 不再被当成「选 skill」。`@` 本轮不接。 */
|
|
651
680
|
var hasSkills = !!(skills && skills.length > 0) || !!(skillGroups && skillGroups.length > 0);
|
|
652
|
-
var
|
|
681
|
+
var triggerHitCount = skillGroups ? (_filteredSkillGroups$ = filteredSkillGroups === null || filteredSkillGroups === void 0 ? void 0 : filteredSkillGroups.reduce(function (n, g) {
|
|
682
|
+
return n + g.skills.length;
|
|
683
|
+
}, 0)) !== null && _filteredSkillGroups$ !== void 0 ? _filteredSkillGroups$ : 0 : (_filteredSkills$lengt = filteredSkills === null || filteredSkills === void 0 ? void 0 : filteredSkills.length) !== null && _filteredSkills$lengt !== void 0 ? _filteredSkills$lengt : 0;
|
|
684
|
+
var triggerMenuVisible = shouldOpenSlashTriggerMenu(triggerInfo === null || triggerInfo === void 0 ? void 0 : triggerInfo.trigger, hasSkills ? triggerHitCount : 0);
|
|
653
685
|
|
|
654
686
|
/* query 变化或浮层关闭 → 高亮项重置到「最上方的可用项」(跳过 disabled)。
|
|
655
687
|
* 用 query 而不是 triggerInfo 整体当依赖:rect 变化(光标移位)不应该 reset。 */
|
|
@@ -691,7 +723,8 @@ export var Composer = /*#__PURE__*/forwardRef(function Composer(_ref, ref) {
|
|
|
691
723
|
var _skill = (_ref6 = (_triggerSkillSlotRef$3 = (_triggerSkillSlotRef$4 = triggerSkillSlotRef.current) === null || _triggerSkillSlotRef$4 === void 0 ? void 0 : _triggerSkillSlotRef$4.getActiveSkill()) !== null && _triggerSkillSlotRef$3 !== void 0 ? _triggerSkillSlotRef$3 : filteredSkills === null || filteredSkills === void 0 ? void 0 : filteredSkills[triggerActiveIndex]) !== null && _ref6 !== void 0 ? _ref6 : filteredSkillGroups === null || filteredSkillGroups === void 0 ? void 0 : filteredSkillGroups.flatMap(function (g) {
|
|
692
724
|
return g.skills;
|
|
693
725
|
})[triggerActiveIndex];
|
|
694
|
-
if (_skill)
|
|
726
|
+
if (!_skill) return false;
|
|
727
|
+
handleSelectSkill(_skill, 'trigger');
|
|
695
728
|
return true;
|
|
696
729
|
}
|
|
697
730
|
if (e.key === 'Escape') {
|
|
@@ -704,29 +737,6 @@ export var Composer = /*#__PURE__*/forwardRef(function Composer(_ref, ref) {
|
|
|
704
737
|
return false;
|
|
705
738
|
}, [filteredSkills, filteredSkillGroups, handleSelectSkill, triggerActiveIndex, triggerMenuVisible]);
|
|
706
739
|
|
|
707
|
-
/* trigger 浮 anchor:跟随 caret 的 0×0 隐形元素,给 Popover 当 children。
|
|
708
|
-
* Popover 需要 DOM children 当 reference,没有"虚拟 anchor" API,只能这么搞。
|
|
709
|
-
*
|
|
710
|
-
* 使用 position: absolute 而非 fixed——Drawer 等容器的 transform 会创建
|
|
711
|
-
* 新的 containing block,导致 fixed 定位失准。absolute 相对于最近 positioned
|
|
712
|
-
* 祖先([data-odn-composer] 有 position:relative),通过减去 offsetParent
|
|
713
|
-
* 的 viewport rect 得到正确的局部坐标。 */
|
|
714
|
-
var triggerAnchorRef = useRef(null);
|
|
715
|
-
useLayoutEffect(function () {
|
|
716
|
-
var el = triggerAnchorRef.current;
|
|
717
|
-
if (!el || !triggerInfo) return;
|
|
718
|
-
var offsetParent = el.offsetParent;
|
|
719
|
-
if (offsetParent) {
|
|
720
|
-
var parentRect = offsetParent.getBoundingClientRect();
|
|
721
|
-
el.style.left = "".concat(triggerInfo.rect.left - parentRect.left, "px");
|
|
722
|
-
el.style.top = "".concat(triggerInfo.rect.top - parentRect.top, "px");
|
|
723
|
-
} else {
|
|
724
|
-
// fallback:没有 offsetParent(比如 display:none),用 viewport 坐标
|
|
725
|
-
el.style.left = "".concat(triggerInfo.rect.left, "px");
|
|
726
|
-
el.style.top = "".concat(triggerInfo.rect.top, "px");
|
|
727
|
-
}
|
|
728
|
-
}, [triggerInfo]);
|
|
729
|
-
|
|
730
740
|
/* ---- Derived ---- */
|
|
731
741
|
var hasUploadingAttachment = attachments.some(function (a) {
|
|
732
742
|
var _a$status2;
|
|
@@ -740,6 +750,29 @@ export var Composer = /*#__PURE__*/forwardRef(function Composer(_ref, ref) {
|
|
|
740
750
|
var effectiveLabeled = isLite ? false : toolsLabeled;
|
|
741
751
|
// lite 模式下仅允许一个工具按钮(数量在两态下保持恒定)
|
|
742
752
|
var effectiveTools = isLite ? tools.slice(0, 1) : tools;
|
|
753
|
+
useLayoutEffect(function () {
|
|
754
|
+
var el = triggerAnchorRef.current;
|
|
755
|
+
var box = boxRef.current;
|
|
756
|
+
if (!el || !box || !triggerInfo) return;
|
|
757
|
+
var boxRect = box.getBoundingClientRect();
|
|
758
|
+
el.style.top = "".concat(triggerInfo.rect.top - boxRect.top, "px");
|
|
759
|
+
}, [triggerInfo]);
|
|
760
|
+
useLayoutEffect(function () {
|
|
761
|
+
var box = boxRef.current;
|
|
762
|
+
var trigger = skillTriggerRef.current;
|
|
763
|
+
if (!box || !trigger) {
|
|
764
|
+
setSkillMenuCrossAxis(function (prev) {
|
|
765
|
+
return prev === 0 ? prev : 0;
|
|
766
|
+
});
|
|
767
|
+
return;
|
|
768
|
+
}
|
|
769
|
+
var boxRect = box.getBoundingClientRect();
|
|
770
|
+
var triggerRect = trigger.getBoundingClientRect();
|
|
771
|
+
var next = Math.round(boxRect.left + boxRect.width / 2 - (triggerRect.left + triggerRect.width / 2));
|
|
772
|
+
setSkillMenuCrossAxis(function (prev) {
|
|
773
|
+
return prev === next ? prev : next;
|
|
774
|
+
});
|
|
775
|
+
}, [boxWidth, toolMenuOpen, effectiveLabeled, isLite, expanded, fullExpanded]);
|
|
743
776
|
|
|
744
777
|
/* 统一解析 toolConfigs:
|
|
745
778
|
* - key 未配置 → 整份默认
|
|
@@ -891,12 +924,17 @@ export var Composer = /*#__PURE__*/forwardRef(function Composer(_ref, ref) {
|
|
|
891
924
|
visible: toolMenuOpen ? false : undefined,
|
|
892
925
|
transitionDuration: toolMenuOpen ? 0 : undefined
|
|
893
926
|
}, /*#__PURE__*/React.createElement("div", {
|
|
927
|
+
ref: skillTriggerRef,
|
|
894
928
|
"data-odn-composer-skill-trigger": true
|
|
895
929
|
}, /*#__PURE__*/React.createElement(Popover, {
|
|
896
930
|
trigger: "click",
|
|
897
931
|
arrowed: false,
|
|
898
|
-
placement: "
|
|
899
|
-
|
|
932
|
+
placement: "top",
|
|
933
|
+
shift: false,
|
|
934
|
+
offset: {
|
|
935
|
+
mainAxis: 4,
|
|
936
|
+
crossAxis: skillMenuCrossAxis
|
|
937
|
+
},
|
|
900
938
|
visible: !disabled && toolMenuOpen,
|
|
901
939
|
onVisibleChange: function onVisibleChange(v) {
|
|
902
940
|
if (disabled) return;
|
|
@@ -1089,7 +1127,7 @@ export var Composer = /*#__PURE__*/forwardRef(function Composer(_ref, ref) {
|
|
|
1089
1127
|
},
|
|
1090
1128
|
onPressEnter: function onPressEnter(e) {
|
|
1091
1129
|
if (e.nativeEvent.isComposing || e.keyCode === 229) return;
|
|
1092
|
-
// trigger
|
|
1130
|
+
// trigger 浮层有可选中项时,普通 Enter 留给浮层做选择;Shift+Enter 继续换行
|
|
1093
1131
|
if (triggerMenuVisible && !e.shiftKey) {
|
|
1094
1132
|
e.preventDefault();
|
|
1095
1133
|
return false;
|
|
@@ -1106,12 +1144,13 @@ export var Composer = /*#__PURE__*/forwardRef(function Composer(_ref, ref) {
|
|
|
1106
1144
|
}
|
|
1107
1145
|
});
|
|
1108
1146
|
|
|
1109
|
-
/*
|
|
1110
|
-
* 共用 SkillSlot
|
|
1147
|
+
/* `/` 浮层:anchor 水平铺满 composer box、竖直跟 caret,菜单与输入框水平居中。
|
|
1148
|
+
* 共用 SkillSlot 渲染;过滤后无命中时 triggerMenuVisible=false,不挂菜单。 */
|
|
1111
1149
|
var triggerMenu = hasSkills ? /*#__PURE__*/React.createElement(Popover, {
|
|
1112
1150
|
trigger: "click",
|
|
1113
1151
|
arrowed: false,
|
|
1114
|
-
placement: "
|
|
1152
|
+
placement: "top",
|
|
1153
|
+
shift: false,
|
|
1115
1154
|
offset: 4,
|
|
1116
1155
|
visible: triggerMenuVisible,
|
|
1117
1156
|
onVisibleChange: function onVisibleChange(v) {
|
|
@@ -1143,7 +1182,9 @@ export var Composer = /*#__PURE__*/forwardRef(function Composer(_ref, ref) {
|
|
|
1143
1182
|
"data-odn-composer-trigger-anchor": true,
|
|
1144
1183
|
style: {
|
|
1145
1184
|
position: 'absolute',
|
|
1146
|
-
|
|
1185
|
+
left: 0,
|
|
1186
|
+
right: 0,
|
|
1187
|
+
top: 0,
|
|
1147
1188
|
height: 0,
|
|
1148
1189
|
pointerEvents: 'none'
|
|
1149
1190
|
},
|
|
@@ -1152,6 +1193,7 @@ export var Composer = /*#__PURE__*/forwardRef(function Composer(_ref, ref) {
|
|
|
1152
1193
|
|
|
1153
1194
|
// lite:有附件即强制升格(否则按钮会和附件/多行内容打架)
|
|
1154
1195
|
var liteExpanded = isLite && !isInlineLite;
|
|
1196
|
+
var showExpandBtn = !isInlineLite && !atHeightCap;
|
|
1155
1197
|
var fullExpandLabel = fullExpanded ? '收起输入框' : '展开输入框';
|
|
1156
1198
|
return /*#__PURE__*/React.createElement("div", {
|
|
1157
1199
|
"data-odn-composer": true,
|
|
@@ -1159,6 +1201,7 @@ export var Composer = /*#__PURE__*/forwardRef(function Composer(_ref, ref) {
|
|
|
1159
1201
|
"data-odn-composer-expanded": liteExpanded ? '' : undefined,
|
|
1160
1202
|
"data-odn-composer-full-expanded": fullExpanded ? '' : undefined,
|
|
1161
1203
|
"data-odn-composer-atmax": atMax ? '' : undefined,
|
|
1204
|
+
"data-odn-composer-height-cap": atHeightCap ? '' : undefined,
|
|
1162
1205
|
"data-odn-composer-disabled": disabled || undefined,
|
|
1163
1206
|
"data-odn-composer-spacing": spacing === 'drawer' ? 'drawer' : undefined,
|
|
1164
1207
|
"aria-disabled": disabled || undefined,
|
|
@@ -1167,7 +1210,7 @@ export var Composer = /*#__PURE__*/forwardRef(function Composer(_ref, ref) {
|
|
|
1167
1210
|
onMouseDown: handleComposerMouseDown
|
|
1168
1211
|
}, /*#__PURE__*/React.createElement("div", {
|
|
1169
1212
|
"data-odn-composer-inner": true
|
|
1170
|
-
}, hiddenFileInput,
|
|
1213
|
+
}, hiddenFileInput, paramPanelNode, /*#__PURE__*/React.createElement("div", _extends({
|
|
1171
1214
|
ref: boxRef,
|
|
1172
1215
|
"data-odn-composer-box": true
|
|
1173
1216
|
}, composerBoxFileDragAttrs, {
|
|
@@ -1175,7 +1218,7 @@ export var Composer = /*#__PURE__*/forwardRef(function Composer(_ref, ref) {
|
|
|
1175
1218
|
onDragOver: handleComposerDragOver,
|
|
1176
1219
|
onDragLeave: handleComposerDragLeave,
|
|
1177
1220
|
onDrop: handleComposerDrop
|
|
1178
|
-
}),
|
|
1221
|
+
}), triggerMenu, showExpandBtn && /*#__PURE__*/React.createElement(Tooltip, {
|
|
1179
1222
|
popup: fullExpandLabel,
|
|
1180
1223
|
placement: "top"
|
|
1181
1224
|
}, /*#__PURE__*/React.createElement("button", {
|
|
@@ -31,6 +31,11 @@
|
|
|
31
31
|
--odn-composer-expand-control-offset: 38px;
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
+
/* 满 10 行或溢出后缩放按钮隐藏,右上角不必再给按钮留位。 */
|
|
35
|
+
[data-odn-composer][data-odn-composer-height-cap] {
|
|
36
|
+
--odn-composer-expand-control-offset: 6px;
|
|
37
|
+
}
|
|
38
|
+
|
|
34
39
|
[data-odn-composer-box] {
|
|
35
40
|
position: relative;
|
|
36
41
|
display: flex;
|
|
@@ -168,7 +173,7 @@
|
|
|
168
173
|
padding-bottom: 42px;
|
|
169
174
|
}
|
|
170
175
|
|
|
171
|
-
/* ─────────── scrollbar
|
|
176
|
+
/* ─────────── scrollbar 显隐控制 ───────────
|
|
172
177
|
* base-ui 的 ScrollArea autohide 默认在 root hover / scrolling 时会把
|
|
173
178
|
* [data-hovering] / [data-scrolling] 标到 Scrollbar 上,opacity 切到 1,
|
|
174
179
|
* 那条灰色 thumb 就显出来。这是 ScrollArea 的预设行为,对 chat composer
|
|
@@ -180,13 +185,13 @@
|
|
|
180
185
|
* 3. thumb 背景透明(即便前两条都被压,看到的也是空 div)
|
|
181
186
|
*
|
|
182
187
|
* 触顶(atmax)时三条全部回滚,由 ScrollArea autohide 接管。 */
|
|
183
|
-
[data-odn-composer][data-odn-composer-
|
|
188
|
+
[data-odn-composer]:not([data-odn-composer-atmax]) [data-odn-scroll-area-scrollbar] {
|
|
184
189
|
display: none !important;
|
|
185
190
|
opacity: 0 !important;
|
|
186
191
|
pointer-events: none !important;
|
|
187
192
|
}
|
|
188
193
|
|
|
189
|
-
[data-odn-composer][data-odn-composer-
|
|
194
|
+
[data-odn-composer]:not([data-odn-composer-atmax]) [data-odn-scroll-area-thumb] {
|
|
190
195
|
background-color: transparent !important;
|
|
191
196
|
}
|
|
192
197
|
|
|
@@ -194,20 +199,20 @@
|
|
|
194
199
|
* 不能用 `revert` —— revert 跳过整个 author origin,连 ODN ScrollArea
|
|
195
200
|
* 的 `opacity: 0` / thumb `background-color: var(--odn-scrollbar-...)`
|
|
196
201
|
* 都会被擦掉,结果是 thumb 元素存在但没颜色(看不到 bar)。 */
|
|
197
|
-
[data-odn-composer][data-odn-composer-
|
|
202
|
+
[data-odn-composer][data-odn-composer-atmax] [data-odn-scroll-area-scrollbar] {
|
|
198
203
|
display: flex !important;
|
|
199
204
|
opacity: 0 !important;
|
|
200
205
|
pointer-events: none !important;
|
|
201
206
|
transition: opacity 0.18s ease;
|
|
202
207
|
}
|
|
203
208
|
|
|
204
|
-
[data-odn-composer][data-odn-composer-
|
|
205
|
-
[data-odn-composer][data-odn-composer-
|
|
209
|
+
[data-odn-composer][data-odn-composer-atmax] [data-odn-scroll-area-scrollbar][data-hovering],
|
|
210
|
+
[data-odn-composer][data-odn-composer-atmax] [data-odn-scroll-area-scrollbar][data-scrolling] {
|
|
206
211
|
opacity: 1 !important;
|
|
207
212
|
pointer-events: auto !important;
|
|
208
213
|
}
|
|
209
214
|
|
|
210
|
-
[data-odn-composer][data-odn-composer-
|
|
215
|
+
[data-odn-composer][data-odn-composer-atmax] [data-odn-scroll-area-thumb] {
|
|
211
216
|
background-color: var(--odn-scrollbar-background-color) !important;
|
|
212
217
|
}
|
|
213
218
|
|
|
@@ -225,6 +230,7 @@
|
|
|
225
230
|
flex: 1 1 auto;
|
|
226
231
|
min-height: 0;
|
|
227
232
|
overflow: hidden;
|
|
233
|
+
max-height: 242px;
|
|
228
234
|
}
|
|
229
235
|
|
|
230
236
|
[data-odn-composer] [data-odn-composer-editor] {
|
|
@@ -509,5 +515,6 @@ p[data-odn-composer-hint] {
|
|
|
509
515
|
|
|
510
516
|
[data-odn-composer][data-odn-composer-full-expanded] [data-odn-composer-box] {
|
|
511
517
|
box-sizing: border-box;
|
|
512
|
-
|
|
518
|
+
/* 拉到当前上限:10 行盒高 302px(242 编辑器 + 60 chrome)与 50vh 取小。 */
|
|
519
|
+
min-height: min(302px, 50vh);
|
|
513
520
|
}
|
package/dist/composer/utils.d.ts
CHANGED
|
@@ -101,7 +101,7 @@ export declare function isEditorEmpty(editor: HTMLElement, chipIdAttr?: string):
|
|
|
101
101
|
* 之后空 text / chip 前 leading br 的清理逻辑不变(TreeWalker / querySelectorAll
|
|
102
102
|
* 在 line div 内部一样工作)。
|
|
103
103
|
*/
|
|
104
|
-
export declare function normalizeEditorDom(editor: HTMLElement
|
|
104
|
+
export declare function normalizeEditorDom(editor: HTMLElement): void;
|
|
105
105
|
export interface TriggerProbe {
|
|
106
106
|
/** 触发字符 */
|
|
107
107
|
trigger: string;
|
|
@@ -117,3 +117,15 @@ export interface TriggerProbe {
|
|
|
117
117
|
export declare function probeTrigger(range: Range, triggers: readonly string[],
|
|
118
118
|
/** caret 与触发字符之间允许的最大 query 字符数;默认 50 */
|
|
119
119
|
maxQueryLen?: number): TriggerProbe | null;
|
|
120
|
+
/** 按 trigger query 做 label 子串匹配(忽略大小写)。query 为空则返回原列表。 */
|
|
121
|
+
export declare function filterSkillsByQuery<T extends {
|
|
122
|
+
label: string;
|
|
123
|
+
}>(items: T[], query?: string | null): T[];
|
|
124
|
+
/** `/` 技能菜单只在「有可选中的过滤结果」时打开;空匹配不应拦截 Enter。 */
|
|
125
|
+
export declare function shouldOpenSlashTriggerMenu(trigger: string | null | undefined, hitCount: number): boolean;
|
|
126
|
+
/** 技能菜单比 composer box 左右各缩 12px。 */
|
|
127
|
+
export declare const COMPOSER_SKILL_MENU_INSET_PX = 24;
|
|
128
|
+
/** box 尚未量到宽度时的兜底(与旧默认对齐)。 */
|
|
129
|
+
export declare const COMPOSER_SKILL_MENU_FALLBACK_WIDTH = 260;
|
|
130
|
+
/** 未显式传 menuWidth 时,菜单比 composer box 略窄。 */
|
|
131
|
+
export declare function resolveComposerSkillMenuWidth(explicit: number | undefined, boxWidth: number): number;
|
package/dist/composer/utils.js
CHANGED
|
@@ -294,6 +294,11 @@ export function getPlainText(editor) {
|
|
|
294
294
|
}
|
|
295
295
|
return out;
|
|
296
296
|
}
|
|
297
|
+
var kebab = function kebab(s) {
|
|
298
|
+
return s.replace(/[A-Z]/g, function (m) {
|
|
299
|
+
return "-".concat(m.toLowerCase());
|
|
300
|
+
});
|
|
301
|
+
};
|
|
297
302
|
|
|
298
303
|
/**
|
|
299
304
|
* editor 是否为完全空(无 chip + 文本剔除 ZWSP / 换行后为空)。
|
|
@@ -310,16 +315,6 @@ export function isEditorEmpty(editor) {
|
|
|
310
315
|
// 仅过滤换行符(contenteditable 默认 <br> 单独存在时 textContent 是 '\n',视觉仍为空)
|
|
311
316
|
return text.replace(/\n/g, '') === '';
|
|
312
317
|
}
|
|
313
|
-
var kebab = function kebab(s) {
|
|
314
|
-
return s.replace(/[A-Z]/g, function (m) {
|
|
315
|
-
return "-".concat(m.toLowerCase());
|
|
316
|
-
});
|
|
317
|
-
};
|
|
318
|
-
var makeIsHost = function makeIsHost(chipIdAttr) {
|
|
319
|
-
return function (el) {
|
|
320
|
-
return el instanceof HTMLElement && el.dataset[chipIdAttr] !== undefined;
|
|
321
|
-
};
|
|
322
|
-
};
|
|
323
318
|
|
|
324
319
|
/* ────────────────────────────────────────────────────────────────────
|
|
325
320
|
* DOM 不变量 · chip 后 ZWSP 锚点 + 行首占位清理
|
|
@@ -338,7 +333,6 @@ var makeIsHost = function makeIsHost(chipIdAttr) {
|
|
|
338
333
|
* 在 line div 内部一样工作)。
|
|
339
334
|
*/
|
|
340
335
|
export function normalizeEditorDom(editor) {
|
|
341
|
-
var _chipIdAttr = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'mentionId';
|
|
342
336
|
ensureLineRoots(editor);
|
|
343
337
|
var emptyTexts = [];
|
|
344
338
|
var orphanAnchorTexts = [];
|
|
@@ -491,4 +485,32 @@ export function probeTrigger(range, triggers) {
|
|
|
491
485
|
triggerOffset: triggerOffset,
|
|
492
486
|
caretOffset: caret
|
|
493
487
|
};
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
/** 按 trigger query 做 label 子串匹配(忽略大小写)。query 为空则返回原列表。 */
|
|
491
|
+
export function filterSkillsByQuery(items, query) {
|
|
492
|
+
var q = query === null || query === void 0 ? void 0 : query.trim().toLowerCase();
|
|
493
|
+
if (!q) return items;
|
|
494
|
+
return items.filter(function (s) {
|
|
495
|
+
return s.label.toLowerCase().includes(q);
|
|
496
|
+
});
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
/** `/` 技能菜单只在「有可选中的过滤结果」时打开;空匹配不应拦截 Enter。 */
|
|
500
|
+
export function shouldOpenSlashTriggerMenu(trigger, hitCount) {
|
|
501
|
+
return trigger === '/' && hitCount > 0;
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
/** 技能菜单比 composer box 左右各缩 12px。 */
|
|
505
|
+
export var COMPOSER_SKILL_MENU_INSET_PX = 24;
|
|
506
|
+
/** box 尚未量到宽度时的兜底(与旧默认对齐)。 */
|
|
507
|
+
export var COMPOSER_SKILL_MENU_FALLBACK_WIDTH = 260;
|
|
508
|
+
|
|
509
|
+
/** 未显式传 menuWidth 时,菜单比 composer box 略窄。 */
|
|
510
|
+
export function resolveComposerSkillMenuWidth(explicit, boxWidth) {
|
|
511
|
+
if (explicit !== undefined) return explicit;
|
|
512
|
+
if (boxWidth > COMPOSER_SKILL_MENU_INSET_PX) {
|
|
513
|
+
return Math.round(boxWidth - COMPOSER_SKILL_MENU_INSET_PX);
|
|
514
|
+
}
|
|
515
|
+
return COMPOSER_SKILL_MENU_FALLBACK_WIDTH;
|
|
494
516
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -58,7 +58,7 @@ export { APPROVAL_DEFAULT_ACTIONS_HINT, default as Approval, type ApprovalDecisi
|
|
|
58
58
|
export { ARTIFACT_DEDICATED_FILE_ICON_TYPES, ARTIFACT_FILE_GLOW_COLORS, ARTIFACT_FILE_ICON_TYPES, default as Artifact, ArtifactFileIcon, getArtifactAction, getArtifactActionFromKind, getArtifactGlowColor, type ArtifactAction, type ArtifactActionKind, type ArtifactFileIconProps, type ArtifactFileIconSize, type ArtifactFileIconType, type ArtifactProps, type ArtifactSize, } from './artifact';
|
|
59
59
|
export { default as Attachments, type AttachmentsProps } from './attachments';
|
|
60
60
|
export { default as ChatItem, formatRelativeTime, type ChatItemProps, } from './chat-item';
|
|
61
|
-
export { default as ChatList, matchChatListFilterTime, matchChatListFilterType, type ChatListFilterTime, type ChatListFilterType, type ChatListItem, type ChatListProps, } from './chat-list';
|
|
61
|
+
export { default as ChatList, matchChatListFilterStatus, matchChatListFilterTime, matchChatListFilterType, type ChatListFilterStatus, type ChatListFilterTime, type ChatListFilterType, type ChatListItem, type ChatListProps, } from './chat-list';
|
|
62
62
|
export { CLARIFY_DOCK_MAX_OPTIONS, CLARIFY_DOCK_SKIPPED_LABEL, CLARIFY_DOCK_SKIPPED_VALUE, ClarifyDockPanel, ClarifyDockTrigger, clarifyDockLayoutId, parseClarifyBoundDate, toISODate, useClarifyDockState, type ClarifyDockAnswerItem, type ClarifyDockHostMessage, type ClarifyDockMessageState, type ClarifyDockPanelProps, type ClarifyDockQuestion, type ClarifyDockResolvePayload, type ClarifyDockSpec, type ClarifyDockState, type ClarifyDockTriggerProps, type ClarifyInput, type ClarifyOption, } from './clarify-dock';
|
|
63
63
|
export { default as CodeBlock, type CodeBlockProps } from './code-block';
|
|
64
64
|
export { default as Composer, type ComposerProps, type ComposerRef, type ComposerSkillSlotProps, type ComposerTool, type ComposerToolConfig, } from './composer';
|
package/dist/index.js
CHANGED
|
@@ -64,7 +64,7 @@ export { APPROVAL_DEFAULT_ACTIONS_HINT, default as Approval } from "./approval";
|
|
|
64
64
|
export { ARTIFACT_DEDICATED_FILE_ICON_TYPES, ARTIFACT_FILE_GLOW_COLORS, ARTIFACT_FILE_ICON_TYPES, default as Artifact, ArtifactFileIcon, getArtifactAction, getArtifactActionFromKind, getArtifactGlowColor } from "./artifact";
|
|
65
65
|
export { default as Attachments } from "./attachments";
|
|
66
66
|
export { default as ChatItem, formatRelativeTime } from "./chat-item";
|
|
67
|
-
export { default as ChatList, matchChatListFilterTime, matchChatListFilterType } from "./chat-list";
|
|
67
|
+
export { default as ChatList, matchChatListFilterStatus, matchChatListFilterTime, matchChatListFilterType } from "./chat-list";
|
|
68
68
|
export { CLARIFY_DOCK_MAX_OPTIONS, CLARIFY_DOCK_SKIPPED_LABEL, CLARIFY_DOCK_SKIPPED_VALUE, ClarifyDockPanel, ClarifyDockTrigger, clarifyDockLayoutId, parseClarifyBoundDate, toISODate, useClarifyDockState } from "./clarify-dock";
|
|
69
69
|
export { default as CodeBlock } from "./code-block";
|
|
70
70
|
export { default as Composer } from "./composer";
|
|
@@ -24,15 +24,16 @@ export interface SkillSlotProps {
|
|
|
24
24
|
value?: string | null;
|
|
25
25
|
onSelect?: (skill: SkillItem) => void;
|
|
26
26
|
/**
|
|
27
|
-
* 技能管理回调。提供后 menu
|
|
28
|
-
*
|
|
27
|
+
* 技能管理回调。提供后 menu 变体渲染「技能管理」按钮:
|
|
28
|
+
* 有搜索栏时在搜索行最右侧 hug,无搜索时仍在列表底部。
|
|
29
|
+
* 按钮内容默认左侧管理 icon +「技能管理」文字。
|
|
29
30
|
* (`skillManageFooter` 为非推荐逃生舱,见该 prop 注释。)
|
|
30
31
|
*/
|
|
31
32
|
onManageSkills?: () => void;
|
|
32
33
|
/**
|
|
33
34
|
* 技能管理按钮的自定义内容(ReactNode)。
|
|
34
35
|
* 仅在 `onManageSkills` 提供且 `variant='menu'` 时生效。
|
|
35
|
-
*
|
|
36
|
+
* 不传时默认渲染左侧管理 icon +「技能管理」文字。
|
|
36
37
|
* 非推荐:徽标 / 待处理数等业务状态应留在技能管理,勿经此槽塞进选 skill 菜单。
|
|
37
38
|
*/
|
|
38
39
|
skillManageFooter?: React.ReactNode;
|