one-design-next 0.0.90 → 0.0.91
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/composer/index.d.ts +4 -3
- package/dist/composer/index.js +55 -56
- package/dist/composer/utils.d.ts +20 -2
- package/dist/composer/utils.js +24 -4
- package/dist/index.d.ts +1 -1
- package/dist/skill-slot/index.d.ts +2 -17
- package/dist/skill-slot/index.js +8 -78
- package/dist/skill-slot/style/index.css +2 -65
- package/package.json +1 -1
package/dist/composer/index.d.ts
CHANGED
|
@@ -28,10 +28,10 @@ export interface ComposerToolConfig {
|
|
|
28
28
|
}
|
|
29
29
|
/**
|
|
30
30
|
* Composer 向内嵌 SkillSlot 透传的配置袋。
|
|
31
|
-
* 技能目录(skills
|
|
32
|
-
* Composer
|
|
31
|
+
* 技能目录(skills)应由「技能管理」模块维护后注入此处;
|
|
32
|
+
* 菜单宽高由 Composer 按输入框与视口计算,不经本袋覆盖。
|
|
33
33
|
*/
|
|
34
|
-
export type ComposerSkillSlotProps = Pick<SkillSlotProps, 'skills' | '
|
|
34
|
+
export type ComposerSkillSlotProps = Pick<SkillSlotProps, 'skills' | 'onManageSkills' | 'skillManageFooter'>;
|
|
35
35
|
export interface ComposerRef {
|
|
36
36
|
/** 聚焦输入框 */
|
|
37
37
|
focus: (options?: FocusOptions) => void;
|
|
@@ -156,6 +156,7 @@ export interface ComposerProps {
|
|
|
156
156
|
/**
|
|
157
157
|
* 向内嵌 SkillSlot 透传的配置袋。
|
|
158
158
|
* 技能目录由业务 / 技能管理模块维护后注入;Composer 只负责触发入口与插入 chip。
|
|
159
|
+
* 菜单宽高由 Composer 按输入框与视口计算,不经本袋覆盖。
|
|
159
160
|
*/
|
|
160
161
|
skillSlotProps?: ComposerSkillSlotProps;
|
|
161
162
|
/**
|
package/dist/composer/index.js
CHANGED
|
@@ -20,7 +20,7 @@ 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
|
+
import { COMPOSER_SKILL_MENU_DENSITY_CAP_PX, filterSkillsByQuery, resolveComposerSkillMenuMaxHeight, resolveComposerSkillMenuWidth, shouldOpenSlashTriggerMenu } from "./utils";
|
|
24
24
|
function createInvocationChipData(skill) {
|
|
25
25
|
return {
|
|
26
26
|
id: "skill-".concat(skill.id, "-").concat(Date.now().toString(36), "-").concat(Math.random().toString(36).slice(2, 6)),
|
|
@@ -92,12 +92,12 @@ var DEFAULT_TOOL_CONFIGS = {
|
|
|
92
92
|
|
|
93
93
|
/**
|
|
94
94
|
* Composer 向内嵌 SkillSlot 透传的配置袋。
|
|
95
|
-
* 技能目录(skills
|
|
96
|
-
* Composer
|
|
95
|
+
* 技能目录(skills)应由「技能管理」模块维护后注入此处;
|
|
96
|
+
* 菜单宽高由 Composer 按输入框与视口计算,不经本袋覆盖。
|
|
97
97
|
*/
|
|
98
98
|
|
|
99
99
|
export var Composer = /*#__PURE__*/forwardRef(function Composer(_ref, ref) {
|
|
100
|
-
var
|
|
100
|
+
var _filteredSkills$lengt, _paramEdit$chipId;
|
|
101
101
|
var valueProp = _ref.value,
|
|
102
102
|
_ref$defaultValue = _ref.defaultValue,
|
|
103
103
|
defaultValue = _ref$defaultValue === void 0 ? '' : _ref$defaultValue,
|
|
@@ -147,11 +147,8 @@ export var Composer = /*#__PURE__*/forwardRef(function Composer(_ref, ref) {
|
|
|
147
147
|
className = _ref.className,
|
|
148
148
|
style = _ref.style;
|
|
149
149
|
var skills = skillSlotProps === null || skillSlotProps === void 0 ? void 0 : skillSlotProps.skills;
|
|
150
|
-
var skillGroups = skillSlotProps === null || skillSlotProps === void 0 ? void 0 : skillSlotProps.skillGroups;
|
|
151
150
|
var onManageSkills = skillSlotProps === null || skillSlotProps === void 0 ? void 0 : skillSlotProps.onManageSkills;
|
|
152
151
|
var skillManageFooter = skillSlotProps === null || skillSlotProps === void 0 ? void 0 : skillSlotProps.skillManageFooter;
|
|
153
|
-
var resolvedMenuMaxHeight = skillSlotProps === null || skillSlotProps === void 0 ? void 0 : skillSlotProps.menuMaxHeight;
|
|
154
|
-
var showGroupTitles = skillSlotProps === null || skillSlotProps === void 0 ? void 0 : skillSlotProps.showGroupTitles;
|
|
155
152
|
var _useControlledState = useControlledState(defaultValue, valueProp),
|
|
156
153
|
_useControlledState2 = _slicedToArray(_useControlledState, 2),
|
|
157
154
|
text = _useControlledState2[0],
|
|
@@ -216,11 +213,15 @@ export var Composer = /*#__PURE__*/forwardRef(function Composer(_ref, ref) {
|
|
|
216
213
|
_useState18 = _slicedToArray(_useState17, 2),
|
|
217
214
|
skillMenuCrossAxis = _useState18[0],
|
|
218
215
|
setSkillMenuCrossAxis = _useState18[1];
|
|
219
|
-
/** composer box
|
|
216
|
+
/** composer box 实宽;技能菜单比它略窄。 */
|
|
220
217
|
var _useState19 = useState(0),
|
|
221
218
|
_useState20 = _slicedToArray(_useState19, 2),
|
|
222
219
|
boxWidth = _useState20[0],
|
|
223
220
|
setBoxWidth = _useState20[1];
|
|
221
|
+
var _useState21 = useState(COMPOSER_SKILL_MENU_DENSITY_CAP_PX),
|
|
222
|
+
_useState22 = _slicedToArray(_useState21, 2),
|
|
223
|
+
skillMenuMaxHeight = _useState22[0],
|
|
224
|
+
setSkillMenuMaxHeight = _useState22[1];
|
|
224
225
|
useLayoutEffect(function () {
|
|
225
226
|
var el = boxRef.current;
|
|
226
227
|
if (!el) return undefined;
|
|
@@ -238,7 +239,7 @@ export var Composer = /*#__PURE__*/forwardRef(function Composer(_ref, ref) {
|
|
|
238
239
|
return ro.disconnect();
|
|
239
240
|
};
|
|
240
241
|
}, []);
|
|
241
|
-
var resolvedMenuWidth = resolveComposerSkillMenuWidth(
|
|
242
|
+
var resolvedMenuWidth = resolveComposerSkillMenuWidth(boxWidth);
|
|
242
243
|
var handleComposerMouseDown = useCallback(function (event) {
|
|
243
244
|
var _editorRef$current;
|
|
244
245
|
if (disabled || event.button !== 0) return;
|
|
@@ -254,10 +255,10 @@ export var Composer = /*#__PURE__*/forwardRef(function Composer(_ref, ref) {
|
|
|
254
255
|
preventScroll: true
|
|
255
256
|
});
|
|
256
257
|
}, [disabled]);
|
|
257
|
-
var
|
|
258
|
-
|
|
259
|
-
paramEdit =
|
|
260
|
-
setParamEdit =
|
|
258
|
+
var _useState23 = useState(null),
|
|
259
|
+
_useState24 = _slicedToArray(_useState23, 2),
|
|
260
|
+
paramEdit = _useState24[0],
|
|
261
|
+
setParamEdit = _useState24[1];
|
|
261
262
|
var openParamPanel = useCallback(function (chipId) {
|
|
262
263
|
if (!renderParamPanel) return;
|
|
263
264
|
requestAnimationFrame(function () {
|
|
@@ -598,10 +599,10 @@ export var Composer = /*#__PURE__*/forwardRef(function Composer(_ref, ref) {
|
|
|
598
599
|
* 不夺回焦点时 Enter 会再次激活按钮而不是发送 */
|
|
599
600
|
(_editorRef$current15 = editorRef.current) === null || _editorRef$current15 === void 0 || _editorRef$current15.focus();
|
|
600
601
|
};
|
|
601
|
-
var
|
|
602
|
-
|
|
603
|
-
fileDragOver =
|
|
604
|
-
setFileDragOver =
|
|
602
|
+
var _useState25 = useState(false),
|
|
603
|
+
_useState26 = _slicedToArray(_useState25, 2),
|
|
604
|
+
fileDragOver = _useState26[0],
|
|
605
|
+
setFileDragOver = _useState26[1];
|
|
605
606
|
var composerBoxFileDragAttrs = fileDragOver ? {
|
|
606
607
|
'data-odn-composer-file-drag': ''
|
|
607
608
|
} : {};
|
|
@@ -661,40 +662,22 @@ export var Composer = /*#__PURE__*/forwardRef(function Composer(_ref, ref) {
|
|
|
661
662
|
return filterSkillsByQuery(skills, slashTriggerQuery);
|
|
662
663
|
}, [skills, slashTriggerActive, slashTriggerQuery]);
|
|
663
664
|
|
|
664
|
-
/* grouped 版本的 trigger query 筛选:按组分别过滤,保留非空组。 */
|
|
665
|
-
var filteredSkillGroups = useMemo(function () {
|
|
666
|
-
if (!skillGroups) return undefined;
|
|
667
|
-
if (!slashTriggerActive) return [];
|
|
668
|
-
return skillGroups.map(function (g) {
|
|
669
|
-
return {
|
|
670
|
-
groupName: g.groupName,
|
|
671
|
-
skills: filterSkillsByQuery(g.skills, slashTriggerQuery)
|
|
672
|
-
};
|
|
673
|
-
}).filter(function (g) {
|
|
674
|
-
return g.skills.length > 0;
|
|
675
|
-
});
|
|
676
|
-
}, [skillGroups, slashTriggerActive, slashTriggerQuery]);
|
|
677
|
-
|
|
678
665
|
/* trigger 浮层:`/` 触发态 + 目录非空 + 过滤后仍有命中。
|
|
679
666
|
* 无匹配时菜单关闭,Enter 不再被当成「选 skill」。`@` 本轮不接。 */
|
|
680
|
-
var hasSkills = !!(skills && skills.length > 0)
|
|
681
|
-
var triggerHitCount =
|
|
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;
|
|
667
|
+
var hasSkills = !!(skills && skills.length > 0);
|
|
668
|
+
var triggerHitCount = (_filteredSkills$lengt = filteredSkills === null || filteredSkills === void 0 ? void 0 : filteredSkills.length) !== null && _filteredSkills$lengt !== void 0 ? _filteredSkills$lengt : 0;
|
|
684
669
|
var triggerMenuVisible = shouldOpenSlashTriggerMenu(triggerInfo === null || triggerInfo === void 0 ? void 0 : triggerInfo.trigger, hasSkills ? triggerHitCount : 0);
|
|
685
670
|
|
|
686
671
|
/* query 变化或浮层关闭 → 高亮项重置到「最上方的可用项」(跳过 disabled)。
|
|
687
672
|
* 用 query 而不是 triggerInfo 整体当依赖:rect 变化(光标移位)不应该 reset。 */
|
|
688
673
|
useEffect(function () {
|
|
689
|
-
var _ref3
|
|
690
|
-
var list = (_ref3 =
|
|
691
|
-
return g.skills;
|
|
692
|
-
})) !== null && _ref3 !== void 0 ? _ref3 : [];
|
|
674
|
+
var _ref3;
|
|
675
|
+
var list = (_ref3 = filteredSkills !== null && filteredSkills !== void 0 ? filteredSkills : skills) !== null && _ref3 !== void 0 ? _ref3 : [];
|
|
693
676
|
var first = list.findIndex(function (s) {
|
|
694
677
|
return !s.disabled;
|
|
695
678
|
});
|
|
696
679
|
setTriggerActiveIndex(first === -1 ? 0 : first);
|
|
697
|
-
}, [filteredSkills,
|
|
680
|
+
}, [filteredSkills, skills, triggerInfo === null || triggerInfo === void 0 ? void 0 : triggerInfo.query, triggerInfo === null]);
|
|
698
681
|
|
|
699
682
|
/* editor 在 trigger 激活时把 ↑↓Enter Esc Tab 丢过来。返回 true = editor 别管了。
|
|
700
683
|
* - ↑↓ 改高亮 index(夹在 [0, max] 内)
|
|
@@ -718,11 +701,9 @@ export var Composer = /*#__PURE__*/forwardRef(function Composer(_ref, ref) {
|
|
|
718
701
|
return true;
|
|
719
702
|
}
|
|
720
703
|
if (e.key === 'Enter' && !e.shiftKey || e.key === 'Tab') {
|
|
721
|
-
var
|
|
704
|
+
var _triggerSkillSlotRef$3, _triggerSkillSlotRef$4;
|
|
722
705
|
e.preventDefault();
|
|
723
|
-
var _skill = (
|
|
724
|
-
return g.skills;
|
|
725
|
-
})[triggerActiveIndex];
|
|
706
|
+
var _skill = (_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];
|
|
726
707
|
if (!_skill) return false;
|
|
727
708
|
handleSelectSkill(_skill, 'trigger');
|
|
728
709
|
return true;
|
|
@@ -735,7 +716,7 @@ export var Composer = /*#__PURE__*/forwardRef(function Composer(_ref, ref) {
|
|
|
735
716
|
return true;
|
|
736
717
|
}
|
|
737
718
|
return false;
|
|
738
|
-
}, [filteredSkills,
|
|
719
|
+
}, [filteredSkills, handleSelectSkill, triggerActiveIndex, triggerMenuVisible]);
|
|
739
720
|
|
|
740
721
|
/* ---- Derived ---- */
|
|
741
722
|
var hasUploadingAttachment = attachments.some(function (a) {
|
|
@@ -757,6 +738,30 @@ export var Composer = /*#__PURE__*/forwardRef(function Composer(_ref, ref) {
|
|
|
757
738
|
var boxRect = box.getBoundingClientRect();
|
|
758
739
|
el.style.top = "".concat(triggerInfo.rect.top - boxRect.top, "px");
|
|
759
740
|
}, [triggerInfo]);
|
|
741
|
+
useLayoutEffect(function () {
|
|
742
|
+
if (!toolMenuOpen && !triggerMenuVisible) return undefined;
|
|
743
|
+
var sync = function sync() {
|
|
744
|
+
var _skillTriggerRef$curr, _skillTriggerRef$curr2, _ref4, _triggerInfo$rect$top, _triggerAnchorRef$cur;
|
|
745
|
+
var triggerTop = toolMenuOpen ? (_skillTriggerRef$curr = (_skillTriggerRef$curr2 = skillTriggerRef.current) === null || _skillTriggerRef$curr2 === void 0 ? void 0 : _skillTriggerRef$curr2.getBoundingClientRect().top) !== null && _skillTriggerRef$curr !== void 0 ? _skillTriggerRef$curr : null : (_ref4 = (_triggerInfo$rect$top = triggerInfo === null || triggerInfo === void 0 ? void 0 : triggerInfo.rect.top) !== null && _triggerInfo$rect$top !== void 0 ? _triggerInfo$rect$top : (_triggerAnchorRef$cur = triggerAnchorRef.current) === null || _triggerAnchorRef$cur === void 0 ? void 0 : _triggerAnchorRef$cur.getBoundingClientRect().top) !== null && _ref4 !== void 0 ? _ref4 : null;
|
|
746
|
+
if (triggerTop === null) return;
|
|
747
|
+
var next = resolveComposerSkillMenuMaxHeight({
|
|
748
|
+
triggerTop: triggerTop,
|
|
749
|
+
viewportHeight: window.innerHeight
|
|
750
|
+
});
|
|
751
|
+
setSkillMenuMaxHeight(function (prev) {
|
|
752
|
+
return prev === next ? prev : next;
|
|
753
|
+
});
|
|
754
|
+
};
|
|
755
|
+
sync();
|
|
756
|
+
window.addEventListener('resize', sync);
|
|
757
|
+
var box = boxRef.current;
|
|
758
|
+
var ro = box && typeof ResizeObserver !== 'undefined' ? new ResizeObserver(sync) : null;
|
|
759
|
+
if (box) ro === null || ro === void 0 || ro.observe(box);
|
|
760
|
+
return function () {
|
|
761
|
+
window.removeEventListener('resize', sync);
|
|
762
|
+
ro === null || ro === void 0 || ro.disconnect();
|
|
763
|
+
};
|
|
764
|
+
}, [toolMenuOpen, triggerMenuVisible, triggerInfo === null || triggerInfo === void 0 ? void 0 : triggerInfo.rect.top]);
|
|
760
765
|
useLayoutEffect(function () {
|
|
761
766
|
var box = boxRef.current;
|
|
762
767
|
var trigger = skillTriggerRef.current;
|
|
@@ -907,9 +912,7 @@ export var Composer = /*#__PURE__*/forwardRef(function Composer(_ref, ref) {
|
|
|
907
912
|
}), showLabel && /*#__PURE__*/React.createElement("span", null, label))));
|
|
908
913
|
};
|
|
909
914
|
var renderSkillBtn = function renderSkillBtn() {
|
|
910
|
-
var hasAnySkills = skills && skills.length > 0
|
|
911
|
-
return g.skills.length > 0;
|
|
912
|
-
});
|
|
915
|
+
var hasAnySkills = skills && skills.length > 0;
|
|
913
916
|
if (!hasAnySkills) return null;
|
|
914
917
|
var _resolvedToolConfigs$3 = resolvedToolConfigs.skill,
|
|
915
918
|
icon = _resolvedToolConfigs$3.icon,
|
|
@@ -946,10 +949,8 @@ export var Composer = /*#__PURE__*/forwardRef(function Composer(_ref, ref) {
|
|
|
946
949
|
key: toolMenuOpen ? 'open' : 'closed',
|
|
947
950
|
variant: "menu",
|
|
948
951
|
searchable: true,
|
|
949
|
-
skills:
|
|
950
|
-
|
|
951
|
-
showGroupTitles: showGroupTitles,
|
|
952
|
-
menuMaxHeight: resolvedMenuMaxHeight,
|
|
952
|
+
skills: skills,
|
|
953
|
+
menuMaxHeight: skillMenuMaxHeight,
|
|
953
954
|
menuWidth: resolvedMenuWidth,
|
|
954
955
|
onSelect: function onSelect(s) {
|
|
955
956
|
return handleSelectSkill(s, 'btn');
|
|
@@ -1164,12 +1165,10 @@ export var Composer = /*#__PURE__*/forwardRef(function Composer(_ref, ref) {
|
|
|
1164
1165
|
popup: /*#__PURE__*/React.createElement(SkillSlot, {
|
|
1165
1166
|
ref: triggerSkillSlotRef,
|
|
1166
1167
|
variant: "menu",
|
|
1167
|
-
skills:
|
|
1168
|
-
skillGroups: filteredSkillGroups,
|
|
1169
|
-
showGroupTitles: showGroupTitles,
|
|
1168
|
+
skills: filteredSkills !== null && filteredSkills !== void 0 ? filteredSkills : [],
|
|
1170
1169
|
activeIndex: triggerActiveIndex,
|
|
1171
1170
|
onActiveIndexChange: setTriggerActiveIndex,
|
|
1172
|
-
menuMaxHeight:
|
|
1171
|
+
menuMaxHeight: skillMenuMaxHeight,
|
|
1173
1172
|
menuWidth: resolvedMenuWidth,
|
|
1174
1173
|
onSelect: function onSelect(s) {
|
|
1175
1174
|
return handleSelectSkill(s, 'trigger');
|
package/dist/composer/utils.d.ts
CHANGED
|
@@ -127,5 +127,23 @@ export declare function shouldOpenSlashTriggerMenu(trigger: string | null | unde
|
|
|
127
127
|
export declare const COMPOSER_SKILL_MENU_INSET_PX = 24;
|
|
128
128
|
/** box 尚未量到宽度时的兜底(与旧默认对齐)。 */
|
|
129
129
|
export declare const COMPOSER_SKILL_MENU_FALLBACK_WIDTH = 260;
|
|
130
|
-
/**
|
|
131
|
-
export declare
|
|
130
|
+
/** 高窗口下列表密度上限;矮窗会被视口截住。 */
|
|
131
|
+
export declare const COMPOSER_SKILL_MENU_DENSITY_CAP_PX = 280;
|
|
132
|
+
/** 列表高度地板,约两条 skill,避免搜索把列表挤成 0。 */
|
|
133
|
+
export declare const COMPOSER_SKILL_MENU_MIN_LIST_PX = 88;
|
|
134
|
+
/** 菜单与视口边缘的安全边距。 */
|
|
135
|
+
export declare const COMPOSER_SKILL_MENU_VIEWPORT_GUTTER_PX = 8;
|
|
136
|
+
/** 搜索栏 / 管理入口 / 菜单 padding,不进入列表滚动区。 */
|
|
137
|
+
export declare const COMPOSER_SKILL_MENU_CHROME_PX = 48;
|
|
138
|
+
/** Popover 贴在触发点上方的 mainAxis offset。 */
|
|
139
|
+
export declare const COMPOSER_SKILL_MENU_OFFSET_PX = 4;
|
|
140
|
+
/** 菜单宽跟随 composer box,比输入框略窄。 */
|
|
141
|
+
export declare function resolveComposerSkillMenuWidth(boxWidth: number): number;
|
|
142
|
+
/**
|
|
143
|
+
* 列表 maxHeight:密度上限与触发点上方可用空间取更矮,再夹到地板。
|
|
144
|
+
* placement=top 且不翻转,故只算上方剩余。
|
|
145
|
+
*/
|
|
146
|
+
export declare function resolveComposerSkillMenuMaxHeight(input: {
|
|
147
|
+
triggerTop: number;
|
|
148
|
+
viewportHeight: number;
|
|
149
|
+
}): number;
|
package/dist/composer/utils.js
CHANGED
|
@@ -505,12 +505,32 @@ export function shouldOpenSlashTriggerMenu(trigger, hitCount) {
|
|
|
505
505
|
export var COMPOSER_SKILL_MENU_INSET_PX = 24;
|
|
506
506
|
/** box 尚未量到宽度时的兜底(与旧默认对齐)。 */
|
|
507
507
|
export var COMPOSER_SKILL_MENU_FALLBACK_WIDTH = 260;
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
508
|
+
/** 高窗口下列表密度上限;矮窗会被视口截住。 */
|
|
509
|
+
export var COMPOSER_SKILL_MENU_DENSITY_CAP_PX = 280;
|
|
510
|
+
/** 列表高度地板,约两条 skill,避免搜索把列表挤成 0。 */
|
|
511
|
+
export var COMPOSER_SKILL_MENU_MIN_LIST_PX = 88;
|
|
512
|
+
/** 菜单与视口边缘的安全边距。 */
|
|
513
|
+
export var COMPOSER_SKILL_MENU_VIEWPORT_GUTTER_PX = 8;
|
|
514
|
+
/** 搜索栏 / 管理入口 / 菜单 padding,不进入列表滚动区。 */
|
|
515
|
+
export var COMPOSER_SKILL_MENU_CHROME_PX = 48;
|
|
516
|
+
/** Popover 贴在触发点上方的 mainAxis offset。 */
|
|
517
|
+
export var COMPOSER_SKILL_MENU_OFFSET_PX = 4;
|
|
518
|
+
|
|
519
|
+
/** 菜单宽跟随 composer box,比输入框略窄。 */
|
|
520
|
+
export function resolveComposerSkillMenuWidth(boxWidth) {
|
|
512
521
|
if (boxWidth > COMPOSER_SKILL_MENU_INSET_PX) {
|
|
513
522
|
return Math.round(boxWidth - COMPOSER_SKILL_MENU_INSET_PX);
|
|
514
523
|
}
|
|
515
524
|
return COMPOSER_SKILL_MENU_FALLBACK_WIDTH;
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
/**
|
|
528
|
+
* 列表 maxHeight:密度上限与触发点上方可用空间取更矮,再夹到地板。
|
|
529
|
+
* placement=top 且不翻转,故只算上方剩余。
|
|
530
|
+
*/
|
|
531
|
+
export function resolveComposerSkillMenuMaxHeight(input) {
|
|
532
|
+
var spaceAbove = input.triggerTop - COMPOSER_SKILL_MENU_VIEWPORT_GUTTER_PX - COMPOSER_SKILL_MENU_OFFSET_PX;
|
|
533
|
+
var available = spaceAbove - COMPOSER_SKILL_MENU_CHROME_PX;
|
|
534
|
+
var capped = Math.min(COMPOSER_SKILL_MENU_DENSITY_CAP_PX, available);
|
|
535
|
+
return Math.max(COMPOSER_SKILL_MENU_MIN_LIST_PX, Math.round(capped));
|
|
516
536
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -79,6 +79,6 @@ export { default as Suggestions, type SuggestionsProps } from './suggestions';
|
|
|
79
79
|
export { default as UserBubble, type UserBubbleProps } from './user-bubble';
|
|
80
80
|
export { default as Welcome, type WelcomeProps } from './welcome';
|
|
81
81
|
export { ComposerSegmentType } from './_genui-types';
|
|
82
|
-
export type { AgentEvent, Attachment, ChatMessage, ChipData, ComposerInvocationSegment, ComposerMentionSegment, ComposerSegment, ComposerTextSegment, Conversation, InlineRefState, InvocationData, MentionData, MessageSnapshot, PreviewTab, PreviewTarget, SendMeta,
|
|
82
|
+
export type { AgentEvent, Attachment, ChatMessage, ChipData, ComposerInvocationSegment, ComposerMentionSegment, ComposerSegment, ComposerTextSegment, Conversation, InlineRefState, InvocationData, MentionData, MessageSnapshot, PreviewTab, PreviewTarget, SendMeta, SkillItem, Source, TextData, ToolCall, ToolStatus, } from './_genui-types';
|
|
83
83
|
export type { InterruptBase, InterruptIntent, InterruptStatus, } from './_interrupt-types';
|
|
84
84
|
export { isInvocationSegment, isMentionSegment, isTextSegment, rawValueToSegments, segmentsHasContent, segmentsToReadableText, type SegmentsToReadableTextOptions, } from './composer/segments';
|
|
@@ -1,24 +1,9 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
|
-
import type {
|
|
2
|
+
import type { SkillItem } from '../_genui-types';
|
|
3
3
|
import './style';
|
|
4
4
|
export interface SkillSlotProps {
|
|
5
|
-
/**
|
|
6
|
-
* 技能列表(扁平结构)。
|
|
7
|
-
* 当 `skillGroups` 未提供时生效;提供 `skillGroups` 则忽略此项。
|
|
8
|
-
*/
|
|
5
|
+
/** 技能列表(扁平结构)。 */
|
|
9
6
|
skills?: SkillItem[];
|
|
10
|
-
/**
|
|
11
|
-
* 分组技能列表。`menu` / `bar` / `card` 均可使用;优先级高于 `skills`。
|
|
12
|
-
* 组标题是否展示由 `showGroupTitles` 控制(默认:menu 展示,bar/card 不展示)。
|
|
13
|
-
*/
|
|
14
|
-
skillGroups?: SkillGroup[];
|
|
15
|
-
/**
|
|
16
|
-
* 是否展示分组标题。
|
|
17
|
-
* - 不传:`menu` 为 true,`bar` / `card` 为 false
|
|
18
|
-
* - 显式传入则覆盖默认
|
|
19
|
-
* 仅在提供 `skillGroups` 时生效;空 `groupName` 始终不渲染标题。
|
|
20
|
-
*/
|
|
21
|
-
showGroupTitles?: boolean;
|
|
22
7
|
variant?: 'menu' | 'bar' | 'card';
|
|
23
8
|
/** 当前选中的 skill id(受控标识;不驱动选中视觉)。 */
|
|
24
9
|
value?: string | null;
|
package/dist/skill-slot/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import _extends from "@babel/runtime/helpers/esm/extends";
|
|
2
2
|
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
|
|
3
3
|
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
|
|
4
|
-
import {
|
|
4
|
+
import { forwardRef, useEffect, useImperativeHandle, useLayoutEffect, useMemo, useRef, useState } from 'react';
|
|
5
5
|
import HoverFill from "../hover-fill";
|
|
6
6
|
import Icon from "../icon";
|
|
7
7
|
import Input from "../input";
|
|
@@ -84,8 +84,6 @@ function SkillDescPopover(_ref) {
|
|
|
84
84
|
|
|
85
85
|
export var SkillSlot = /*#__PURE__*/forwardRef(function SkillSlot(_ref2, ref) {
|
|
86
86
|
var skillsProp = _ref2.skills,
|
|
87
|
-
skillGroups = _ref2.skillGroups,
|
|
88
|
-
showGroupTitlesProp = _ref2.showGroupTitles,
|
|
89
87
|
_ref2$variant = _ref2.variant,
|
|
90
88
|
variant = _ref2$variant === void 0 ? 'bar' : _ref2$variant,
|
|
91
89
|
onSelect = _ref2.onSelect,
|
|
@@ -113,38 +111,14 @@ export var SkillSlot = /*#__PURE__*/forwardRef(function SkillSlot(_ref2, ref) {
|
|
|
113
111
|
|
|
114
112
|
/* 目录全集:过滤前的列表。目录为空才整棵不渲染。 */
|
|
115
113
|
var catalogSkills = useMemo(function () {
|
|
116
|
-
if (skillGroups) return skillGroups.flatMap(function (g) {
|
|
117
|
-
return g.skills;
|
|
118
|
-
});
|
|
119
114
|
return skillsProp !== null && skillsProp !== void 0 ? skillsProp : [];
|
|
120
|
-
}, [
|
|
121
|
-
var visibleGroups = useMemo(function () {
|
|
122
|
-
if (!skillGroups) return undefined;
|
|
123
|
-
if (!searchableMenu) return skillGroups;
|
|
124
|
-
return skillGroups.map(function (g) {
|
|
125
|
-
return {
|
|
126
|
-
groupName: g.groupName,
|
|
127
|
-
skills: g.skills.filter(function (s) {
|
|
128
|
-
return skillMatchesQuery(s, searchQuery);
|
|
129
|
-
})
|
|
130
|
-
};
|
|
131
|
-
}).filter(function (g) {
|
|
132
|
-
return g.skills.length > 0;
|
|
133
|
-
});
|
|
134
|
-
}, [skillGroups, searchableMenu, searchQuery]);
|
|
135
|
-
|
|
136
|
-
/* 优先使用过滤后的 skillGroups,否则回退到 skills。 */
|
|
115
|
+
}, [skillsProp]);
|
|
137
116
|
var skills = useMemo(function () {
|
|
138
|
-
if (visibleGroups) return visibleGroups.flatMap(function (g) {
|
|
139
|
-
return g.skills;
|
|
140
|
-
});
|
|
141
117
|
if (!searchableMenu) return catalogSkills;
|
|
142
118
|
return catalogSkills.filter(function (s) {
|
|
143
119
|
return skillMatchesQuery(s, searchQuery);
|
|
144
120
|
});
|
|
145
|
-
}, [
|
|
146
|
-
var showGroupTitles = showGroupTitlesProp !== null && showGroupTitlesProp !== void 0 ? showGroupTitlesProp : variant === 'menu';
|
|
147
|
-
var groupedWithTitles = !!(skillGroups && showGroupTitles);
|
|
121
|
+
}, [catalogSkills, searchableMenu, searchQuery]);
|
|
148
122
|
/* menu 变体:HoverFill 只管鼠标。键盘高亮视觉暂时关闭(见 style),
|
|
149
123
|
* 避免 mouseleave 后 ::before 接力造成闪一下。`activeIndex` / ↑↓ / Enter
|
|
150
124
|
* 数据层仍工作,恢复视觉时解开 item-highlighted ::before 即可。
|
|
@@ -421,53 +395,11 @@ export var SkillSlot = /*#__PURE__*/forwardRef(function SkillSlot(_ref2, ref) {
|
|
|
421
395
|
}
|
|
422
396
|
return barButton;
|
|
423
397
|
};
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
var renderGroups = function renderGroups() {
|
|
430
|
-
var flatIndex = 0;
|
|
431
|
-
if (variant === 'menu') {
|
|
432
|
-
return /*#__PURE__*/React.createElement(React.Fragment, null, visibleGroups.map(function (group, groupIdx) {
|
|
433
|
-
return /*#__PURE__*/React.createElement(Fragment, {
|
|
434
|
-
key: group.groupName || "_group_".concat(groupIdx)
|
|
435
|
-
}, showGroupTitles && group.groupName ? /*#__PURE__*/React.createElement("div", {
|
|
436
|
-
"data-odn-skill-slot-group-header": true
|
|
437
|
-
}, group.groupName) : null, group.skills.map(function (skill) {
|
|
438
|
-
return renderMenuItem(skill, flatIndex++);
|
|
439
|
-
}), groupIdx < visibleGroups.length - 1 ? /*#__PURE__*/React.createElement("div", {
|
|
440
|
-
"data-odn-skill-slot-divider": true,
|
|
441
|
-
"data-odn-skill-slot-group-divider": true
|
|
442
|
-
}) : null);
|
|
443
|
-
}));
|
|
444
|
-
}
|
|
445
|
-
return /*#__PURE__*/React.createElement(React.Fragment, null, visibleGroups.map(function (group, groupIdx) {
|
|
446
|
-
return /*#__PURE__*/React.createElement("div", {
|
|
447
|
-
key: group.groupName || "_group_".concat(groupIdx),
|
|
448
|
-
"data-odn-skill-slot-group": true
|
|
449
|
-
}, showGroupTitles && group.groupName ? /*#__PURE__*/React.createElement("div", {
|
|
450
|
-
"data-odn-skill-slot-group-header": true
|
|
451
|
-
}, group.groupName) : null, /*#__PURE__*/React.createElement("div", {
|
|
452
|
-
"data-odn-skill-slot-group-items": true
|
|
453
|
-
}, group.skills.map(function (skill) {
|
|
454
|
-
return variant === 'card' ? renderCardItem(skill) : renderBarItem(skill);
|
|
455
|
-
})));
|
|
456
|
-
}));
|
|
457
|
-
};
|
|
458
|
-
|
|
459
|
-
/* 扁平模式下渲染所有项(menu / bar / card)。 */
|
|
460
|
-
var renderFlatItems = function renderFlatItems() {
|
|
461
|
-
return skills.map(function (skill, index) {
|
|
462
|
-
if (variant === 'card') return renderCardItem(skill);
|
|
463
|
-
if (variant === 'menu') return renderMenuItem(skill, index);
|
|
464
|
-
return renderBarItem(skill);
|
|
465
|
-
});
|
|
466
|
-
};
|
|
467
|
-
|
|
468
|
-
/* 有 skillGroups:始终按组遍历(保序);无标题时仍走分组 DOM,仅不渲染 header,
|
|
469
|
-
* bar/card 用 group-items 承接原有 flex/grid,避免拍平后丢组边界。 */
|
|
470
|
-
var listBody = visibleGroups ? renderGroups() : renderFlatItems();
|
|
398
|
+
var listBody = skills.map(function (skill, index) {
|
|
399
|
+
if (variant === 'card') return renderCardItem(skill);
|
|
400
|
+
if (variant === 'menu') return renderMenuItem(skill, index);
|
|
401
|
+
return renderBarItem(skill);
|
|
402
|
+
});
|
|
471
403
|
var manageBtn = renderManageBtn();
|
|
472
404
|
var searchBar = searchableMenu ? /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
|
|
473
405
|
"data-odn-skill-slot-toolbar": true
|
|
@@ -533,7 +465,6 @@ export var SkillSlot = /*#__PURE__*/forwardRef(function SkillSlot(_ref2, ref) {
|
|
|
533
465
|
return /*#__PURE__*/React.createElement("div", {
|
|
534
466
|
"data-odn-skill-slot": true,
|
|
535
467
|
"data-odn-skill-slot-variant": variant,
|
|
536
|
-
"data-odn-skill-slot-grouped": groupedWithTitles || undefined,
|
|
537
468
|
className: className,
|
|
538
469
|
style: rootStyle
|
|
539
470
|
}, listBody);
|
|
@@ -547,7 +478,6 @@ export var SkillSlot = /*#__PURE__*/forwardRef(function SkillSlot(_ref2, ref) {
|
|
|
547
478
|
return /*#__PURE__*/React.createElement("div", {
|
|
548
479
|
"data-odn-skill-slot": true,
|
|
549
480
|
"data-odn-skill-slot-variant": variant,
|
|
550
|
-
"data-odn-skill-slot-grouped": groupedWithTitles || undefined,
|
|
551
481
|
className: className,
|
|
552
482
|
style: rootStyle
|
|
553
483
|
}, searchBar, hasScrollWrap ? /*#__PURE__*/React.createElement("div", {
|
|
@@ -151,7 +151,7 @@
|
|
|
151
151
|
align-items: flex-start;
|
|
152
152
|
gap: 8px;
|
|
153
153
|
width: 100%;
|
|
154
|
-
padding:
|
|
154
|
+
padding: 4px 12px;
|
|
155
155
|
font-size: 13px;
|
|
156
156
|
color: var(--odn-color-black-12);
|
|
157
157
|
text-align: left;
|
|
@@ -196,77 +196,14 @@
|
|
|
196
196
|
word-break: break-word;
|
|
197
197
|
}
|
|
198
198
|
|
|
199
|
-
/* ---- menu 分组标题 ----
|
|
200
|
-
* 分类名不做 uppercase。组间分割线画在组末、左右内缩,不跟标题叠尾线。 */
|
|
201
|
-
[data-odn-skill-slot][data-odn-skill-slot-variant=menu] [data-odn-skill-slot-group-header] {
|
|
202
|
-
padding: 0 16px 4px;
|
|
203
|
-
font-size: 12px;
|
|
204
|
-
font-weight: 500;
|
|
205
|
-
color: var(--odn-color-black-8);
|
|
206
|
-
line-height: 20px;
|
|
207
|
-
user-select: none;
|
|
208
|
-
pointer-events: none;
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
[data-odn-skill-slot][data-odn-skill-slot-variant=menu] [data-odn-skill-slot-list] > [data-odn-skill-slot-group-header]:first-child {
|
|
212
|
-
padding-top: 4px;
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
/* 无组标题时:group 壳不参与布局,子项仍挂在根 flex/grid 上(与拍平一致) */
|
|
216
|
-
[data-odn-skill-slot]:not([data-odn-skill-slot-grouped]) [data-odn-skill-slot-group],
|
|
217
|
-
[data-odn-skill-slot]:not([data-odn-skill-slot-grouped]) [data-odn-skill-slot-group-items] {
|
|
218
|
-
display: contents;
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
/* 有组标题:根改为纵向堆叠组;组内再承接原 bar flex / card grid */
|
|
222
|
-
[data-odn-skill-slot][data-odn-skill-slot-grouped][data-odn-skill-slot-variant=bar],
|
|
223
|
-
[data-odn-skill-slot][data-odn-skill-slot-grouped][data-odn-skill-slot-variant=card] {
|
|
224
|
-
display: flex;
|
|
225
|
-
flex-direction: column;
|
|
226
|
-
flex-wrap: nowrap;
|
|
227
|
-
gap: 12px;
|
|
228
|
-
grid-template-columns: none;
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
[data-odn-skill-slot][data-odn-skill-slot-grouped][data-odn-skill-slot-variant=bar] [data-odn-skill-slot-group-items] {
|
|
232
|
-
display: flex;
|
|
233
|
-
flex-wrap: wrap;
|
|
234
|
-
gap: 8px;
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
[data-odn-skill-slot][data-odn-skill-slot-grouped][data-odn-skill-slot-variant=card] [data-odn-skill-slot-group-items] {
|
|
238
|
-
display: grid;
|
|
239
|
-
grid-template-columns: repeat(2, 1fr);
|
|
240
|
-
gap: 10px;
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
[data-odn-skill-slot][data-odn-skill-slot-variant=bar] [data-odn-skill-slot-group-header],
|
|
244
|
-
[data-odn-skill-slot][data-odn-skill-slot-variant=card] [data-odn-skill-slot-group-header] {
|
|
245
|
-
padding: 0 2px;
|
|
246
|
-
font-size: 12px;
|
|
247
|
-
font-weight: 600;
|
|
248
|
-
color: var(--odn-color-black-8);
|
|
249
|
-
line-height: 20px;
|
|
250
|
-
user-select: none;
|
|
251
|
-
pointer-events: none;
|
|
252
|
-
}
|
|
253
|
-
|
|
254
199
|
/* ---- menu 分隔线 ----
|
|
255
|
-
* 通栏:搜索栏 / 技能管理,标「内容 ↔ 系统操作」。
|
|
256
|
-
* 组间:仅无标题时出现,左右内缩对齐文案(macOS 菜单)。 */
|
|
200
|
+
* 通栏:搜索栏 / 技能管理,标「内容 ↔ 系统操作」。 */
|
|
257
201
|
[data-odn-skill-slot][data-odn-skill-slot-variant=menu] [data-odn-skill-slot-divider] {
|
|
258
202
|
margin: 4px 0;
|
|
259
203
|
height: 1px;
|
|
260
204
|
background: var(--odn-color-black-5);
|
|
261
205
|
}
|
|
262
206
|
|
|
263
|
-
[data-odn-skill-slot][data-odn-skill-slot-variant=menu] [data-odn-skill-slot-group-divider] {
|
|
264
|
-
box-sizing: content-box;
|
|
265
|
-
margin: 0 16px;
|
|
266
|
-
padding: 8px 0;
|
|
267
|
-
background-clip: content-box;
|
|
268
|
-
}
|
|
269
|
-
|
|
270
207
|
/* ---- menu 管理按钮:hug 内容宽;在顶栏靠右,无搜索时仍在列表底 ---- */
|
|
271
208
|
[data-odn-skill-slot][data-odn-skill-slot-variant=menu] [data-odn-skill-slot-manage-btn] {
|
|
272
209
|
display: inline-flex;
|