-
-
Notifications
You must be signed in to change notification settings - Fork 611
feat: support rowspan expanded #1278
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
feat: support rowspan expanded #1278
Conversation
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
""" Walkthrough此次更改引入了一个新的“expandedRowSpan”演示文档及相关 React 代码示例,展示了带有可展开行和自定义行合并(rowSpan)功能的表格。同时,核心表格组件逻辑被增强,以支持在行展开时动态调整单元格的 rowSpan 属性,并在数据结构中显式维护 rowKey。 Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant DemoPage
participant DemoComponent
participant Table
participant BodyRow
User->>DemoPage: 访问 expandedRowSpan 演示页
DemoPage->>DemoComponent: 渲染 Demo 组件
DemoComponent->>Table: 渲染带有 columns/data/expandable 的表格
Table->>BodyRow: 传递 rowKeys, rowKey, columns, expandedKeys 等
BodyRow->>getCellProps: 计算每个单元格的 rowSpan(考虑展开行)
getCellProps-->>BodyRow: 返回调整后的单元格属性
BodyRow-->>Table: 渲染行
Table-->>DemoComponent: 渲染完整表格
Possibly related PRs
Suggested reviewers
Poem
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
tests/Expanded.spec.tsxOops! Something went wrong! :( ESLint: 8.57.1 ESLint couldn't find the config "prettier" to extend from. Please check that the name of the config is correct. The config "prettier" was referenced from the config file in "/.eslintrc.js". If you still have problems, please stop by https://eslint.org/chat/help to chat with the team. Note ⚡️ AI Code Reviews for VS Code, Cursor, WindsurfCodeRabbit now has a plugin for VS Code, Cursor and Windsurf. This brings AI code reviews directly in the code editor. Each commit is reviewed immediately, finding bugs before the PR is raised. Seamless context handoff to your AI code agent ensures that you can easily incorporate review feedback. 📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
⏰ Context from checks skipped due to timeout of 90000ms (1)
✨ Finishing Touches
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (5)
src/Body/index.tsx (1)
45-50
: 改进代码格式和可读性将
useFlattenRecords
调用重新格式化为多行,提高了代码的可读性。每个参数单独一行,使函数调用更加清晰。docs/examples/expandedRowSpan.tsx (3)
12-21
: 考虑优化onCell回调函数的实现方式当前实现使用了多个独立的if语句来处理不同行索引的rowSpan设置,这种方式虽然直观但略显冗长。
可以考虑使用映射或switch语句来简化实现:
- onCell: (_, index) => { - const props: React.TdHTMLAttributes<HTMLTableCellElement> = {}; - if (index === 0) props.rowSpan = 1; - if (index === 1) props.rowSpan = 4; - if (index === 2) props.rowSpan = 0; - if (index === 3) props.rowSpan = 0; - if (index === 4) props.rowSpan = 0; - if (index === 5) props.rowSpan = undefined; - return props; - }, + onCell: (_, index) => { + const rowSpanMap = { + 0: 1, + 1: 4, + 2: 0, + 3: 0, + 4: 0, + 5: undefined + }; + return { rowSpan: rowSpanMap[index] }; + },
8-9
: 考虑使用英文列标题以保持一致性示例中使用了中文列标题"手机号",但大多数其他列使用了英文标题。为保持一致性,建议统一使用一种语言的列标题。
29-36
: 建议使用更具描述性的数据字段名当前数据结构使用了通用字段名(a, b, c, d, e),这不够直观。建议使用与列标题匹配的具有描述性的字段名,以提高代码可读性。
- { a: '12313132132', b: '0571-43243256', c: '小二', d: '文零西路', e: 'Male', key: 'z' }, + { phoneNumber: '12313132132', tel: '0571-43243256', name: '小二', address: '文零西路', gender: 'Male', key: 'z' },src/Body/BodyRow.tsx (1)
82-92
: 考虑添加边界情况处理当前实现假定rowSpan和rowKeys数组都是有效的。可以考虑添加边界情况检查,比如当rowSpan为undefined或NaN时,或者当i索引超出rowKeys数组范围时的处理。
if (expandable) { let currentRowSpan = rowSpan; + // 确保rowSpan是有效的数值 + if (typeof currentRowSpan !== 'number' || isNaN(currentRowSpan)) { + currentRowSpan = 1; + } for (let i = index; i < index + rowSpan; i += 1) { + // 确保索引在数组范围内 + if (i >= rowKeys.length) break; const rowKey = rowKeys[i]; if (expandedKeys.has(rowKey)) { currentRowSpan += 1; } } additionalCellProps.rowSpan = currentRowSpan; }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
docs/demo/expandedRowSpan.md
(1 hunks)docs/examples/expandedRowSpan.tsx
(1 hunks)src/Body/BodyRow.tsx
(6 hunks)src/Body/index.tsx
(2 hunks)src/VirtualTable/VirtualCell.tsx
(1 hunks)src/hooks/useFlattenRecords.ts
(3 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (2)
src/hooks/useFlattenRecords.ts (1)
src/interface.ts (1)
Key
(21-21)
src/Body/BodyRow.tsx (2)
src/interface.ts (1)
Key
(21-21)src/hooks/useRowInfo.tsx (1)
useRowInfo
(8-123)
🔇 Additional comments (14)
src/VirtualTable/VirtualCell.tsx (1)
59-66
: 确保 getCellProps 参数满足新的函数签名要求在调用
getCellProps
时添加了空数组[]
作为新的rowKeys
参数,这符合BodyRow.tsx
中更新后的函数签名要求。此更改使VirtualCell
组件与扩展的行和行合并(rowSpan)功能兼容。docs/demo/expandedRowSpan.md (1)
1-8
: 新增扩展行合并示例文档这个新增的文档文件创建了一个展示扩展行合并(expandedRowSpan)功能的演示页面,引用了
../examples/expandedRowSpan.tsx
中的代码示例。这是对新功能的良好文档支持。src/hooks/useFlattenRecords.ts (3)
14-19
: 向扁平化数据中添加 rowKey 属性在
fillRecords
函数中,将rowKey
属性添加到扁平化数据中,确保每条记录都明确携带其唯一键。这是支持可展开行和行合并功能的重要基础。
41-46
: 扩展 FlattenData 接口在
FlattenData
接口中添加rowKey: Key
属性,确保类型安全并与实际实现保持一致。这种改进增强了代码的可维护性和类型检查。
80-86
: 确保非扩展状态下的 rowKey 一致性在数据映射的回退逻辑中添加
rowKey
属性,确保即使不使用扩展功能,每个扁平化记录也具有正确的rowKey
。这种一致性很重要,可以避免在不同表格状态下出现不一致的行为。src/Body/index.tsx (3)
52-52
: 添加行键(rowKeys)记忆化数组添加了一个新的记忆化数组
rowKeys
,用于存储所有扁平化数据项的rowKey
。这是支持扩展行合并功能的关键变更,确保每个BodyRow
都能访问完整的行键列表,从而正确计算行跨度(rowSpan)。
68-68
: 从扁平化数据中直接解构 rowKey从扁平化数据项中直接解构
rowKey
,替代之前通过getRowKey
计算key
的方式。这简化了代码并消除了重复计算,与useFlattenRecords.ts
中的更改保持一致。
71-83
: 向 BodyRow 组件传递行键信息将
rowKey
同时作为 React key 和 prop 传递给BodyRow
组件,并额外传递rowKeys
数组作为新的 prop。这使得每个行组件都能获取行键信息以及完整的行键列表,从而支持基于展开状态的动态行合并计算。docs/examples/expandedRowSpan.tsx (2)
1-51
: 新增的扩展行与行合并示例全面展示了功能这个新增的示例组件很好地展示了表格支持扩展行与行合并(rowSpan)的功能。完整的示例包含了所有必要的配置项,包括列定义、数据源和行展开渲染函数。
45-45
: 确保展开行渲染函数的样式是必要的展开行渲染函数中设置了margin为0的样式。请确认这个样式设置是必要的,如果只是为了示例,可以考虑添加更多有意义的内容展示。
src/Body/BodyRow.tsx (4)
22-22
: 接口扩展支持行键数组参数为BodyRowProps接口添加rowKeys参数,这是支持展开行状态下行合并计算的关键部分。
34-34
: getCellProps函数参数扩展为getCellProps函数添加rowKeys参数,确保函数能够访问所有行键以正确计算行合并。
78-92
: 优雅实现可展开行的行合并逻辑这段新增代码非常关键,它解决了当表格行可展开时行合并(rowSpan)的正确计算问题。当一个单元格跨越多行且其中某些行被展开时,需要相应地增加rowSpan值以保持表格布局的正确性。
算法思路清晰:遍历原始rowSpan范围内的所有行,检查每行是否被展开,如果是则增加rowSpan值。
177-177
: 正确传递行键数组参数在渲染单元格时正确地将rowKeys参数传递给getCellProps函数,确保行合并计算能够正常工作。
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## master #1278 +/- ##
==========================================
+ Coverage 98.08% 98.12% +0.03%
==========================================
Files 77 78 +1
Lines 7609 7771 +162
Branches 1164 1194 +30
==========================================
+ Hits 7463 7625 +162
Misses 140 140
Partials 6 6 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this 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
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
src/Body/BodyRow.tsx
(6 hunks)src/Body/index.tsx
(2 hunks)src/Panel/index.tsx
(1 hunks)
✅ Files skipped from review due to trivial changes (1)
- src/Panel/index.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
- src/Body/index.tsx
🧰 Additional context used
🪛 GitHub Check: codecov/patch
src/Body/BodyRow.tsx
[warning] 86-86: src/Body/BodyRow.tsx#L86
Added line #L86 was not covered by tests
[warning] 88-95: src/Body/BodyRow.tsx#L88-L95
Added lines #L88 - L95 were not covered by tests
🔇 Additional comments (5)
src/Body/BodyRow.tsx (5)
25-25
: 接口扩展:rowKeys
属性添加
BodyRowProps
接口中添加了rowKeys: React.Key[]
属性,用于支持行展开时的 rowSpan 调整功能。
37-37
: 函数签名更新:getCellProps
函数参数扩展函数参数列表中添加了
rowKeys
参数,与接口更新保持一致,用于后续行展开逻辑中计算正确的 rowSpan。
51-52
: 增加解构属性:expandable
和expandedKeys
从
rowInfo
对象中解构出新增的两个属性,用于确定行是否可展开以及哪些行已被展开。
129-129
:BodyRow
组件属性解构从 props 中解构
rowKeys
,为组件内部函数提供必要参数。
188-188
: 传递rowKeys
参数在调用
getCellProps
时传入rowKeys
参数,使得单元格能够正确计算行合并时的 rowSpan 值。
src/Body/BodyRow.tsx
Outdated
const { rowSpan } = additionalCellProps; | ||
|
||
// For expandable row with rowSpan, | ||
// We should increase the rowSpan if the row is expanded | ||
if (expandable) { | ||
let currentRowSpan = rowSpan; | ||
|
||
for (let i = index; i < index + rowSpan; i += 1) { | ||
const rowKey = rowKeys[i]; | ||
if (expandedKeys.has(rowKey)) { | ||
currentRowSpan += 1; | ||
} | ||
} | ||
additionalCellProps.rowSpan = currentRowSpan; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Verification agent
🧩 Analysis chain
实现行合并与行展开的协同处理
这段代码实现了行展开时动态调整 rowSpan 的核心逻辑,但缺少测试覆盖。
const { rowSpan } = additionalCellProps;
// For expandable row with rowSpan,
// We should increase the rowSpan if the row is expanded
- if (expandable) {
+ if (expandable && rowSpan > 0) {
let currentRowSpan = rowSpan;
for (let i = index; i < index + rowSpan; i += 1) {
+ if (i >= rowKeys.length) break;
const rowKey = rowKeys[i];
if (expandedKeys.has(rowKey)) {
currentRowSpan += 1;
}
}
additionalCellProps.rowSpan = currentRowSpan;
}
代码存在以下隐患:
- 没有检查
rowSpan
是否为有效值 (>0) - 没有检查
i
是否超出rowKeys
数组边界 - 建议为新增的复杂逻辑添加单元测试
🏁 Script executed:
#!/bin/bash
# 检查是否有相关测试文件涵盖 BodyRow 组件中的 rowSpan 功能
echo "查找与 BodyRow 相关的测试文件..."
fd -e test.tsx -e test.ts -e spec.tsx -e spec.ts | grep -i "bodyrow\|body.*row"
echo "查找测试文件中是否包含 rowSpan 相关测试..."
rg -i "rowspan.*test|test.*rowspan" --type ts --type tsx
Length of output: 288
🏁 Script executed:
#!/bin/bash
echo "查找包含 BodyRow 的测试文件..."
rg -l "BodyRow" -g "*.test.ts" -g "*.test.tsx" -g "*.spec.ts" -g "*.spec.tsx"
echo "在测试文件中查找 rowSpan 相关测试..."
rg -n "rowSpan" -g "*.test.ts" -g "*.test.tsx" -g "*.spec.ts" -g "*.spec.tsx"
Length of output: 715
校验 rowSpan 有效性并防止数组越界
在 src/Body/BodyRow.tsx
(约 81–95 行)中,这段逻辑负责在展开行时动态调整 rowSpan
,但存在以下隐患需要修复并补充测试:
- 未过滤
rowSpan
为 0 或负数的情况 - 在循环中可能读取超出
rowKeys
长度的索引 - 缺少针对该逻辑的单元测试
建议修改如下:
- if (expandable) {
+ // 仅对可展开且 rowSpan > 0 的单元格生效
+ if (expandable && rowSpan > 0) {
let currentRowSpan = rowSpan;
for (let i = index; i < index + rowSpan; i += 1) {
+ // 防止越界访问
+ if (i >= rowKeys.length) break;
const rowKey = rowKeys[i];
if (expandedKeys.has(rowKey)) {
currentRowSpan += 1;
}
}
additionalCellProps.rowSpan = currentRowSpan;
}
· 请在 tests/
下新增 BodyRow.spec.tsx
,覆盖以下场景:
rowSpan
为 0、1、>1- 不同
expandedKeys
集合下的展开行为 - 边界情况(
index + rowSpan
超出rowKeys.length
)
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
const { rowSpan } = additionalCellProps; | |
// For expandable row with rowSpan, | |
// We should increase the rowSpan if the row is expanded | |
if (expandable) { | |
let currentRowSpan = rowSpan; | |
for (let i = index; i < index + rowSpan; i += 1) { | |
const rowKey = rowKeys[i]; | |
if (expandedKeys.has(rowKey)) { | |
currentRowSpan += 1; | |
} | |
} | |
additionalCellProps.rowSpan = currentRowSpan; | |
} | |
const { rowSpan } = additionalCellProps; | |
// For expandable row with rowSpan, | |
// We should increase the rowSpan if the row is expanded | |
// 仅对可展开且 rowSpan > 0 的单元格生效 | |
if (expandable && rowSpan > 0) { | |
let currentRowSpan = rowSpan; | |
for (let i = index; i < index + rowSpan; i += 1) { | |
// 防止越界访问 | |
if (i >= rowKeys.length) break; | |
const rowKey = rowKeys[i]; | |
if (expandedKeys.has(rowKey)) { | |
currentRowSpan += 1; | |
} | |
} | |
additionalCellProps.rowSpan = currentRowSpan; | |
} |
🧰 Tools
🪛 GitHub Check: codecov/patch
[warning] 86-86: src/Body/BodyRow.tsx#L86
Added line #L86 was not covered by tests
[warning] 88-95: src/Body/BodyRow.tsx#L88-L95
Added lines #L88 - L95 were not covered by tests
🤖 Prompt for AI Agents
In src/Body/BodyRow.tsx around lines 81 to 95, the code adjusts rowSpan when
rows are expanded but lacks validation and boundary checks. Fix this by first
verifying that rowSpan is a positive number greater than zero before proceeding.
Then, in the loop, ensure the index i does not exceed the length of the rowKeys
array to prevent out-of-bounds access. Additionally, create a new test file
tests/BodyRow.spec.tsx to add unit tests covering cases where rowSpan is 0, 1,
or greater than 1, different expandedKeys sets, and boundary conditions where
index plus rowSpan exceeds rowKeys length.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
docs/examples/expandedSticky.tsx (1)
1-58
: 很好的演示了行合并与固定列结合的展开行功能这个示例展示了表格组件的高级功能,包括:
- 可展开行与固定(sticky)列的结合使用
- 使用
rowSpan
实现单元格合并- 行展开状态的管理
- 固定左侧和右侧列的配置
代码清晰简洁,是一个非常好的教学示例。对于用户理解如何使用这些功能非常有帮助。
不过,有几点小建议:
- 注释掉的代码(第10行)建议直接删除,避免混淆
- 可以添加更多注释说明示例的关键点,特别是关于
rowSpan
设置的逻辑- 考虑添加一些更复杂的数据来更好地展示行合并的效果
- // { title: '分割', dataIndex: 'ca' }, + // 第一列:固定在左侧,并应用行合并
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
docs/demo/expandedSticky.md
(1 hunks)docs/examples/expandedSticky.tsx
(1 hunks)src/Body/BodyRow.tsx
(10 hunks)src/Body/ExpandedRow.tsx
(3 hunks)src/Table.tsx
(1 hunks)src/context/TableContext.tsx
(1 hunks)
✅ Files skipped from review due to trivial changes (2)
- src/context/TableContext.tsx
- docs/demo/expandedSticky.md
🚧 Files skipped from review as they are similar to previous changes (1)
- src/Body/BodyRow.tsx
🧰 Additional context used
🧠 Learnings (1)
src/Table.tsx (1)
Learnt from: bbb169
PR: react-component/table#1202
File: src/Table.tsx:903-904
Timestamp: 2024-11-08T12:53:09.293Z
Learning: 在 `src/Table.tsx` 文件的 React 组件 `Table` 中,即使 `bodyScrollLeft` 频繁更新,也需要在 `TableContextValue` 的 `useMemo` 依赖数组中包含 `bodyScrollLeft` 和 `headerCellRefs`,因为每次滚动时重新计算 `TableContextValue` 是解决该问题所必须的。
🧬 Code Graph Analysis (1)
docs/examples/expandedSticky.tsx (2)
src/interface.ts (2)
Key
(21-21)ColumnType
(108-123)tests/FixedColumn-IE.spec.jsx (1)
columns
(27-40)
🔇 Additional comments (4)
src/Table.tsx (1)
945-946
: 将 classNames 和 styles 添加到依赖数组是正确的做法这个改动确保当
classNames
或styles
属性发生变化时,TableContextValue
会被重新计算。这对于确保表格组件样式的正确传播和更新是必要的。根据之前的反馈,即使
bodyScrollLeft
等属性频繁更新,也需要将它们包含在useMemo
的依赖数组中,这个变更与该指导原则一致。src/Body/ExpandedRow.tsx (3)
17-17
: 很好地添加了 offsetWidth 可选属性为
ExpandedRowProps
接口添加offsetWidth
可选属性是一个良好的设计决策,这使得组件更灵活,能够适应不同的布局需求。
34-34
: 合理设置了默认值为
offsetWidth
设置默认值为 0 是一个明智的选择,保持了向后兼容性,确保现有代码不会因为这个新属性而出错。
49-49
: 正确调整了展开行的宽度计算更新了宽度计算逻辑,从
componentWidth
中减去offsetWidth
,这确保了当使用 rowSpan 时展开行的宽度能够正确对齐。这个修改对于支持复杂表格布局(如带有自定义行合并的可展开行)是必要的。
There was a problem hiding this 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
♻️ Duplicate comments (1)
src/Body/BodyRow.tsx (1)
81-95
: 💡 Verification agent❓ Verification inconclusive
检查 rowSpan 的有效性并防止数组越界
当前实现在处理可展开行的 rowSpan 时存在以下潜在问题:
- 没有验证
rowSpan
是否为正数- 在循环中没有边界检查,如果
index + rowSpan
超出rowKeys
的长度,将导致越界访问建议修改如下:
const { rowSpan } = additionalCellProps; // For expandable row with rowSpan, // We should increase the rowSpan if the row is expanded - if (expandable && rowSpan !== undefined) { + if (expandable && rowSpan !== undefined && rowSpan > 0) { let currentRowSpan = rowSpan; for (let i = index; i < index + rowSpan; i += 1) { + if (i >= rowKeys.length) break; const rowKey = rowKeys[i]; if (expandedKeys.has(rowKey)) { currentRowSpan += 1; } } additionalCellProps.rowSpan = currentRowSpan; }根据代码覆盖率报告,这段代码没有测试覆盖。请添加单元测试来覆盖这个新功能,包括以下场景:
rowSpan
为 0、1 和大于 1 的情况- 不同
expandedKeys
集合下的展开行为- 边界情况(
index + rowSpan
超出rowKeys.length
)
请验证
rowSpan
有效性并防止数组越界当前
src/Body/BodyRow.tsx
(约第 81–95 行)在处理可展开行的rowSpan
时存在以下风险:
- 未校验
rowSpan
是否为正数- 循环到
index + rowSpan
时,若超出rowKeys.length
会导致越界访问建议修改如下:
const { rowSpan } = additionalCellProps; // 对于可展开的行,如果 rowSpan 已定义且大于 0, // 展开行时应相应增加 rowSpan - if (expandable && rowSpan !== undefined) { + if (expandable && rowSpan !== undefined && rowSpan > 0) { let currentRowSpan = rowSpan; for (let i = index; i < index + rowSpan; i += 1) { + if (i >= rowKeys.length) break; // 防止越界 const rowKey = rowKeys[i]; if (expandedKeys.has(rowKey)) { currentRowSpan += 1; } } additionalCellProps.rowSpan = currentRowSpan; }此外,根据最新的覆盖率报告,本段逻辑未被任何单元测试覆盖。请补充测试,至少涵盖:
rowSpan
为 0、1 及 > 1 的场景- 不同
expandedKeys
集合下的展开行为- 边界情况(
index + rowSpan
超出rowKeys.length
)🧰 Tools
🪛 GitHub Check: codecov/patch
[warning] 86-86: src/Body/BodyRow.tsx#L86
Added line #L86 was not covered by tests
[warning] 88-95: src/Body/BodyRow.tsx#L88-L95
Added lines #L88 - L95 were not covered by tests
🧹 Nitpick comments (2)
src/Body/BodyRow.tsx (2)
106-129
: 优化 getOffsetData 函数实现新增的
getOffsetData
函数在计算列偏移量时有以下几点可以改进:
- 在访问
column.width
时缺少类型检查- 当遇到第一个没有
rowSpan
的列时就停止计算,这种行为可能不符合预期建议修改如下:
const getOffsetData = ( columnsData: { column: ColumnType<any>; cell: { additionalCellProps: React.TdHTMLAttributes<HTMLElement> }; }[], ) => { let offsetWidth = 0; let offsetColumn = 0; let isRowSpanEnd = false; columnsData.forEach(item => { if (!isRowSpanEnd) { const { column, cell } = item; if (cell.additionalCellProps.rowSpan !== undefined) { offsetColumn += 1; - if (typeof column.width === 'number') { + const columnWidth = column.width; + if (typeof columnWidth === 'number') { - offsetWidth = offsetWidth + (column.width ?? 0); + offsetWidth = offsetWidth + columnWidth; } } else { isRowSpanEnd = true; } } }); return { offsetWidth, offsetColumn }; };请添加单元测试来验证这个新函数的行为,尤其是在不同列配置下的表现。
🧰 Tools
🪛 GitHub Check: codecov/patch
[warning] 121-122: src/Body/BodyRow.tsx#L121-L122
Added lines #L121 - L122 were not covered by tests
180-189
: 依赖数组优化建议在
useMemo
中,依赖数组包含了rowKeys
,这意味着每当rowKeys
变化时,即使其他依赖保持不变,也会重新计算columnsData
和offsetData
。根据使用场景,可以考虑是否需要在依赖数组中包含
rowKeys
。如果rowKeys
的变化频率很高,而实际上对计算结果影响不大,可以考虑将其从依赖数组中移除,或者使用其他方式优化。
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
src/Body/BodyRow.tsx
(10 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
src/Body/BodyRow.tsx (2)
src/interface.ts (2)
Key
(21-21)ColumnType
(108-123)src/hooks/useRowInfo.tsx (1)
useRowInfo
(8-123)
🪛 GitHub Check: codecov/patch
src/Body/BodyRow.tsx
[warning] 86-86: src/Body/BodyRow.tsx#L86
Added line #L86 was not covered by tests
[warning] 88-95: src/Body/BodyRow.tsx#L88-L95
Added lines #L88 - L95 were not covered by tests
[warning] 121-122: src/Body/BodyRow.tsx#L121-L122
Added lines #L121 - L122 were not covered by tests
🔇 Additional comments (1)
src/Body/BodyRow.tsx (1)
10-10
: 代码结构调整正确,确保文档更新导入类型、接口扩展和参数添加的变更看起来是合理的。这些变更使得组件能够支持行合并与行展开的协同工作。
请确保更新相关文档,明确说明
rowKeys
参数的用途和要求,特别是对于 API 调用者来说,了解这个新增参数的含义和正确使用方式非常重要。Also applies to: 25-25, 37-37, 51-52
offsetWidth={offsetData.offsetWidth} | ||
colSpan={flattenColumns.length - offsetData.offsetColumn} | ||
isEmpty={false} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
确保 colSpan 不会为负值
当计算展开行的 colSpan
时,需要确保结果不会为负值:
<ExpandedRow
expanded={expanded}
className={cls(
`${prefixCls}-expanded-row`,
`${prefixCls}-expanded-row-level-${indent + 1}`,
expandedClsName,
)}
prefixCls={prefixCls}
component={RowComponent}
cellComponent={cellComponent}
offsetWidth={offsetData.offsetWidth}
- colSpan={flattenColumns.length - offsetData.offsetColumn}
+ colSpan={Math.max(1, flattenColumns.length - offsetData.offsetColumn)}
isEmpty={false}
>
当 offsetData.offsetColumn
大于或等于 flattenColumns.length
时,计算结果可能为零或负值,这将导致意外的渲染结果。
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
offsetWidth={offsetData.offsetWidth} | |
colSpan={flattenColumns.length - offsetData.offsetColumn} | |
isEmpty={false} | |
<ExpandedRow | |
expanded={expanded} | |
className={cls( | |
`${prefixCls}-expanded-row`, | |
`${prefixCls}-expanded-row-level-${indent + 1}`, | |
expandedClsName, | |
)} | |
prefixCls={prefixCls} | |
component={RowComponent} | |
cellComponent={cellComponent} | |
offsetWidth={offsetData.offsetWidth} | |
colSpan={Math.max( | |
1, | |
flattenColumns.length - offsetData.offsetColumn | |
)} | |
isEmpty={false} | |
> |
🤖 Prompt for AI Agents
In src/Body/BodyRow.tsx around lines 259 to 261, the calculation of colSpan as
flattenColumns.length minus offsetData.offsetColumn can result in zero or
negative values if offsetData.offsetColumn is greater than or equal to
flattenColumns.length. To fix this, add a check to ensure colSpan is never less
than 1 by using a conditional or Math.max to set a minimum value of 1 for
colSpan.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
tests/Expanded.spec.tsx (1)
64-86
: 考虑使用Testing Library推荐的查询方法当前使用的直接DOM查询方法(
querySelector
、querySelectorAll
)虽然有效,但考虑使用Testing Library推荐的查询方法(如getByRole
、getByTestId
等)可能更好,这样对实现变更更具弹性。测试断言逻辑本身非常全面,验证了:
- 每行的单元格数量
- 特定单元格的rowspan和colspan属性
- 展开行的正确渲染
确保了rowspan功能在展开行存在时能正常工作。
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
tests/Expanded.spec.tsx
(1 hunks)
🔇 Additional comments (4)
tests/Expanded.spec.tsx (4)
1-5
: 导入组件和测试工具实现得很好导入选择恰当,包括了React、测试工具和必要的类型定义。使用
@rc-component/util/lib/test/domHook
来模拟DOM元素原型是测试DOM相关功能的好方法。
6-27
: 测试环境设置合理且完整测试环境设置很完善:
- 使用
vi.useFakeTimers()
模拟定时器- 通过
spyElementPrototypes
模拟DOM元素属性- 在测试后正确清理资源
这确保了测试在可控环境中进行,提高了测试的可靠性和一致性。
28-45
: 列定义和测试数据设计得当列定义中巧妙地利用了
onCell
回调为不同行设置不同的rowSpan
值,覆盖了多种场景:
- rowSpan=1(正常行)
- rowSpan=2(跨两行)
- rowSpan=0(隐藏行)
- rowSpan=undefined(默认值)
同时包含了
Table.EXPAND_COLUMN
以测试展开功能,测试数据结构简单但足够完成测试目标。
47-63
: 测试用例设置和异步处理正确测试用例设置了带有展开功能的表格,并使用了
defaultExpandAllRows
确保所有行都被展开。
异步处理部分使用act
包装并正确运行了所有计时器,确保组件完全渲染后再进行断言。
Summary by CodeRabbit