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.
@@ -28,10 +28,10 @@ export interface ComposerToolConfig {
28
28
  }
29
29
  /**
30
30
  * Composer 向内嵌 SkillSlot 透传的配置袋。
31
- * 技能目录(skills / skillGroups)应由「技能管理」模块维护后注入此处;
32
- * Composer 只负责触发入口与选中后插入 chip,不是目录 SSOT。
31
+ * 技能目录(skills)应由「技能管理」模块维护后注入此处;
32
+ * 菜单宽高由 Composer 按输入框与视口计算,不经本袋覆盖。
33
33
  */
34
- export type ComposerSkillSlotProps = Pick<SkillSlotProps, 'skills' | 'skillGroups' | 'showGroupTitles' | 'menuMaxHeight' | 'menuWidth' | 'onManageSkills' | 'skillManageFooter'>;
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
  /**
@@ -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 / skillGroups)应由「技能管理」模块维护后注入此处;
96
- * Composer 只负责触发入口与选中后插入 chip,不是目录 SSOT。
95
+ * 技能目录(skills)应由「技能管理」模块维护后注入此处;
96
+ * 菜单宽高由 Composer 按输入框与视口计算,不经本袋覆盖。
97
97
  */
98
98
 
99
99
  export var Composer = /*#__PURE__*/forwardRef(function Composer(_ref, ref) {
100
- var _filteredSkillGroups$, _filteredSkills$lengt, _paramEdit$chipId;
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 实宽;技能菜单默认比它略窄。显式 menuWidth 覆盖。 */
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(skillSlotProps === null || skillSlotProps === void 0 ? void 0 : skillSlotProps.menuWidth, boxWidth);
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 _useState21 = useState(null),
258
- _useState22 = _slicedToArray(_useState21, 2),
259
- paramEdit = _useState22[0],
260
- setParamEdit = _useState22[1];
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 _useState23 = useState(false),
602
- _useState24 = _slicedToArray(_useState23, 2),
603
- fileDragOver = _useState24[0],
604
- setFileDragOver = _useState24[1];
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) || !!(skillGroups && skillGroups.length > 0);
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;
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, _ref4, _ref5;
690
- var list = (_ref3 = (_ref4 = filteredSkills !== null && filteredSkills !== void 0 ? filteredSkills : skills) !== null && _ref4 !== void 0 ? _ref4 : (_ref5 = filteredSkillGroups !== null && filteredSkillGroups !== void 0 ? filteredSkillGroups : skillGroups) === null || _ref5 === void 0 ? void 0 : _ref5.flatMap(function (g) {
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, filteredSkillGroups, skills, skillGroups, triggerInfo === null || triggerInfo === void 0 ? void 0 : triggerInfo.query, triggerInfo === null]);
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 _ref6, _triggerSkillSlotRef$3, _triggerSkillSlotRef$4;
704
+ var _triggerSkillSlotRef$3, _triggerSkillSlotRef$4;
722
705
  e.preventDefault();
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) {
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, filteredSkillGroups, handleSelectSkill, triggerActiveIndex, triggerMenuVisible]);
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 || skillGroups && skillGroups.some(function (g) {
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: skillGroups ? undefined : skills,
950
- skillGroups: skillGroups,
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: skillGroups ? undefined : filteredSkills !== null && filteredSkills !== void 0 ? filteredSkills : [],
1168
- skillGroups: filteredSkillGroups,
1169
- showGroupTitles: showGroupTitles,
1168
+ skills: filteredSkills !== null && filteredSkills !== void 0 ? filteredSkills : [],
1170
1169
  activeIndex: triggerActiveIndex,
1171
1170
  onActiveIndexChange: setTriggerActiveIndex,
1172
- menuMaxHeight: resolvedMenuMaxHeight,
1171
+ menuMaxHeight: skillMenuMaxHeight,
1173
1172
  menuWidth: resolvedMenuWidth,
1174
1173
  onSelect: function onSelect(s) {
1175
1174
  return handleSelectSkill(s, 'trigger');
@@ -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
- /** 未显式传 menuWidth 时,菜单比 composer box 略窄。 */
131
- export declare function resolveComposerSkillMenuWidth(explicit: number | undefined, boxWidth: number): number;
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;
@@ -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
- /** 未显式传 menuWidth 时,菜单比 composer box 略窄。 */
510
- export function resolveComposerSkillMenuWidth(explicit, boxWidth) {
511
- if (explicit !== undefined) return explicit;
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, SkillGroup, SkillItem, Source, TextData, ToolCall, ToolStatus, } from './_genui-types';
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 { SkillGroup, SkillItem } from '../_genui-types';
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;
@@ -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 { Fragment, forwardRef, useEffect, useImperativeHandle, useLayoutEffect, useMemo, useRef, useState } from 'react';
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
- }, [skillGroups, skillsProp]);
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
- }, [visibleGroups, catalogSkills, searchableMenu, searchQuery]);
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
- /* 分组渲染:是否画标题由 showGroupTitles 决定。
426
- * menu 项必须与标题/分割线同级挂在 list 根下——HoverFill 跨项共享背景要求同一
427
- * parentNode;若再包一层 group / group-items,跨组必闪。bar/card 不用 HoverFill,
428
- * 仍用 group 壳承接 flex/grid。 */
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: 8px 12px;
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;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "one-design-next",
3
- "version": "0.0.90",
3
+ "version": "0.0.91",
4
4
  "description": "One Design Next from TAD@tencent.com",
5
5
  "license": "MIT",
6
6
  "type": "module",