Skip to content

feat: pass full opt object to itemData in convertItemsToNodes#867

Merged
zombieJ merged 3 commits into
react-component:masterfrom
EmilyyyLiu:feat/menuItemData
Jun 3, 2026
Merged

feat: pass full opt object to itemData in convertItemsToNodes#867
zombieJ merged 3 commits into
react-component:masterfrom
EmilyyyLiu:feat/menuItemData

Conversation

@EmilyyyLiu
Copy link
Copy Markdown
Contributor

@EmilyyyLiu EmilyyyLiu commented Jun 3, 2026

描述:

改动内容

src/utils/nodeUtil.tsx 中,将 itemData 从手动构造的部分对象改为直接使用完整的 opt
对象。这样用户传入的所有属性(如 titlefildestest 等)都能在回调的 itemData 中获取到。

具体修改

  • src/utils/nodeUtil.tsx: 将 itemData={{ label, key: mergedKey, itemIcon: restProps?.itemIcon, extra }} 改为
    itemData={opt}
  • src/interface.ts: 在 ItemData 接口中添加 title?: string(TypeScript 支持)
  • src/MenuItem.tsx: 将 title prop 传递给 itemData

动机

当使用 items 属性生成菜单项时,用户希望在 onClickonSelect 回调中通过 info.itemData 获取自定义属性。之前
itemData 只包含 labelkeyitemIconextra,现在所有传入的属性都会被透传。

Summary by CodeRabbit

  • 新特性

    • 在菜单项的选择与点击事件回调中,回传的项数据现新增可选的 title 字段,便于直接获取标题信息。
  • 行为调整

    • 菜单内部生成与透传的项数据逻辑已调整,回调中将透传原始项的额外属性以保留更多上下文信息。
  • 测试

    • 更新测试以覆盖 items 场景下完整项数据在回调中被透传的验证。

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jun 3, 2026

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 280153dc-b1dd-4f92-af52-1bda7da0de5b

📥 Commits

Reviewing files that changed from the base of the PR and between 65ab39b and d31d1ed.

📒 Files selected for processing (1)
  • src/utils/nodeUtil.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/utils/nodeUtil.tsx

Walkthrough

为菜单项事件回调数据新增并透传 title 字段:扩展 ItemData 类型、在 convertItemsToNodes 中保留原始 item 数据作为 itemData,并在 MenuItem.getEventInfo 中将 props.title 填入事件信息;测试更新验证回调接收完整 itemData。

改动

事件数据 title 字段支持

层级 / 文件 说明
ItemData 类型扩展
src/interface.ts
ItemData 接口新增可选字段 title?: string,用于事件回调数据中携带菜单项标题。
节点转换与事件信息中透传 title
src/utils/nodeUtil.tsx, src/MenuItem.tsx, tests/MenuItem.spec.tsx
convertItemsToNodes 将原始菜单项配置 opt 直接作为 itemData 传入 MergedMenuItem(同时显式传递 extra);MenuItemgetEventInfo 在默认构建 itemData 时新增 title: props.title;相关测试更新为断言 onSelect/onClick 接收到包含 items 中全部字段的 itemData

评审工作量估算

🎯 3 (Moderate) | ⏱️ ~20 分钟

可能相关的 PR

  • react-component/menu#740: 涉及 convertItemsToNodes 中对 MergedMenuItemextra 传递改动,与本次对节点构造的调整相关。
  • react-component/menu#863: 修改了 convertItemsToNodesextra/itemData 的准备与传递,和本 PR 在同一路径有重叠。
  • react-component/menu#864: 与本次对 onSelect/onClick 事件载荷构建及透传字段的改动存在直接关联。

建议评审人

  • zombieJ

🐰 我是小兔子,轻轻跳,
代码里藏着标题饶,
事件里带回那一条,
回调完整不再少,
测试见证小确幸 ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed PR标题准确概括了核心改动——将完整的opt对象传递给convertItemsToNodes中的itemData,与代码变更和整体目标完全对应。
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

src/utils/nodeUtil.tsx

ESLint skipped: missing config or dependency (missing-dependency). The ESLint configuration references a package that is not available in the sandbox.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request adds a title property to MenuItem and updates the ItemData interface accordingly. It also refactors nodeUtil.tsx to pass the opt object directly as itemData. A review comment correctly identifies that passing opt directly could result in an undefined key property, which violates the ItemData type requirements, and suggests merging mergedKey into itemData to ensure type safety.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread src/utils/nodeUtil.tsx Outdated
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
src/interface.ts (1)

67-73: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

类型定义与实际数据契约不一致。

ItemData 类型明确列出了允许的字段(labelitemIconextrakeytitle),但在 nodeUtil.tsx 中的变更将整个 opt 对象作为 itemData 传递,而 opt 可能包含任意自定义属性。这会导致:

  1. 类型不安全opt 被类型标注为 any(nodeUtil.tsx:24),可以包含 ItemData 中未定义的字段(如 typechildren 等内部字段以及用户自定义字段)。
  2. 契约不明确:当前类型定义暗示只有列出的字段可用,但实际运行时会包含更多属性。

如果目标是支持所有用户自定义属性,建议使用索引签名扩展类型定义:

建议的类型修复
 export type ItemData = {
   label?: React.ReactNode;
   itemIcon?: RenderIconType;
   extra?: React.ReactNode;
   key: React.Key;
   title?: string;
+  [key: string]: any;
 };

或者使用更精确的类型定义,明确区分已知字段和自定义字段。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/interface.ts` around lines 67 - 73, ItemData's current shape is too
narrow compared to how nodeUtil.tsx passes the entire opt object as itemData
(opt is typed any and may include fields like type/children or custom props);
update the ItemData type to allow additional arbitrary properties by adding an
index signature (e.g., [key: string]: any) or otherwise extend it to include
unknown keys, and then tighten/remove the any on opt in nodeUtil.tsx
(referencing ItemData and the opt variable / itemData usage) so the compiler
knows extra user/custom fields are allowed while preserving the known fields
(label, itemIcon, extra, key, title).
src/MenuItem.tsx (1)

138-153: 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

两种渲染模式的 itemData 构造不一致。

当前实现在两种模式下对 itemData 的处理方式不同:

  1. Children 模式propsItemData 为空时,line 138-144):手动构造 itemData,仅包含 keylabelitemIconextratitle 这些显式字段。
  2. Items 模式propsItemDatanodeUtil.tsx 传入):现在传递完整的 opt 对象,包含所有自定义属性。

这导致:

  • 使用 <MenuItem> 子组件写法时,自定义属性不会出现在回调的 itemData
  • 使用 items prop 写法时,所有自定义属性都会出现在 itemData

建议统一两种模式的行为,或在文档中明确说明这种差异。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/MenuItem.tsx` around lines 138 - 153, The constructed itemData differs
between children mode and items mode; update the children-mode branch that
builds itemData (the block creating itemData when propsItemData is falsy using
eventKey, children, itemIcon, props.extra, props.title) to merge all custom
props into the returned itemData (e.g., spread props or relevant fields) so that
the shape matches the full opt passed from nodeUtil.tsx and custom attributes
are present in the callback itemData (still return propsItemData || itemData for
the itemData field and keep other returned fields like key, keyPath, item:
legacyMenuItemRef.current, domEvent: e unchanged).
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/utils/nodeUtil.tsx`:
- Line 54: convertItemsToNodes currently passes the entire opt into
MergedMenuItem as itemData (itemData={opt}), which leaks internal/custom props
(e.g., foo, type, children) and leaves itemData.key undefined when key was
missing; change it to build a sanitized itemData object instead of passing opt:
include key: mergedKey, label, and only the expected props (e.g., extra and any
intended itemIcon/item-specific fields), and pass restProps only to the
component props (keep {...restProps} as before) while supplying
itemData={itemData} to MergedMenuItem so callbacks receive the constrained
shape.

---

Outside diff comments:
In `@src/interface.ts`:
- Around line 67-73: ItemData's current shape is too narrow compared to how
nodeUtil.tsx passes the entire opt object as itemData (opt is typed any and may
include fields like type/children or custom props); update the ItemData type to
allow additional arbitrary properties by adding an index signature (e.g., [key:
string]: any) or otherwise extend it to include unknown keys, and then
tighten/remove the any on opt in nodeUtil.tsx (referencing ItemData and the opt
variable / itemData usage) so the compiler knows extra user/custom fields are
allowed while preserving the known fields (label, itemIcon, extra, key, title).

In `@src/MenuItem.tsx`:
- Around line 138-153: The constructed itemData differs between children mode
and items mode; update the children-mode branch that builds itemData (the block
creating itemData when propsItemData is falsy using eventKey, children,
itemIcon, props.extra, props.title) to merge all custom props into the returned
itemData (e.g., spread props or relevant fields) so that the shape matches the
full opt passed from nodeUtil.tsx and custom attributes are present in the
callback itemData (still return propsItemData || itemData for the itemData field
and keep other returned fields like key, keyPath, item:
legacyMenuItemRef.current, domEvent: e unchanged).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 052cb7ba-95d3-48f7-aa50-16853cd31a79

📥 Commits

Reviewing files that changed from the base of the PR and between e9643ea and 0f8ea52.

📒 Files selected for processing (3)
  • src/MenuItem.tsx
  • src/interface.ts
  • src/utils/nodeUtil.tsx

Comment thread src/utils/nodeUtil.tsx Outdated
@codecov
Copy link
Copy Markdown

codecov Bot commented Jun 3, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.72%. Comparing base (e9643ea) to head (d31d1ed).

Additional details and impacted files
@@           Coverage Diff           @@
##           master     #867   +/-   ##
=======================================
  Coverage   99.72%   99.72%           
=======================================
  Files          26       26           
  Lines         732      732           
  Branches      204      204           
=======================================
  Hits          730      730           
  Misses          2        2           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
tests/MenuItem.spec.tsx (1)

184-203: ⚡ Quick win

建议补一条 children 模式下 title 透传断言。

当前用例只覆盖了 items 模式;本次改动还涉及 MenuItem 在 children 模式下把 props.title 注入 itemData。建议在同组里补一个 <MenuItem title="..."> 点击后 info.itemData.title 的断言,避免该路径后续回归。

可参考补充用例
+    it('should pass title in itemData when using children mode', () => {
+      const onClick = jest.fn();
+      const { container } = render(
+        <Menu onClick={onClick}>
+          <MenuItem key="1" title="child-title">
+            Menu Item
+          </MenuItem>
+        </Menu>,
+      );
+
+      fireEvent.click(container.querySelector('.rc-menu-item')!);
+      expect(onClick).toHaveBeenCalledWith(
+        expect.objectContaining({
+          key: '1',
+          itemData: expect.objectContaining({
+            key: '1',
+            title: 'child-title',
+          }),
+        }),
+      );
+    });
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/MenuItem.spec.tsx` around lines 184 - 203, Add a sibling test in
MenuItem.spec.tsx that exercises the children mode: render <Menu
selectable><MenuItem title="test title">Menu Item</MenuItem></Menu> with jest
mocks for onSelect and onClick (same as the existing items-mode test),
fireEvent.click the rendered .rc-menu-item, and assert that both onSelect and
onClick were called with an info object whose itemData includes the title
property (expect.objectContaining({ title: 'test title' })). This ensures
MenuItem in children mode correctly injects props.title into itemData.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@tests/MenuItem.spec.tsx`:
- Around line 184-203: Add a sibling test in MenuItem.spec.tsx that exercises
the children mode: render <Menu selectable><MenuItem title="test title">Menu
Item</MenuItem></Menu> with jest mocks for onSelect and onClick (same as the
existing items-mode test), fireEvent.click the rendered .rc-menu-item, and
assert that both onSelect and onClick were called with an info object whose
itemData includes the title property (expect.objectContaining({ title: 'test
title' })). This ensures MenuItem in children mode correctly injects props.title
into itemData.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 15de9fe6-ab71-4c5c-be3b-2bbbfa882c38

📥 Commits

Reviewing files that changed from the base of the PR and between 0f8ea52 and 65ab39b.

📒 Files selected for processing (1)
  • tests/MenuItem.spec.tsx

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
@zombieJ zombieJ merged commit c4c8913 into react-component:master Jun 3, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants