Skip to content

[codex] refactor grouped data hooks#44

Merged
zombieJ merged 4 commits into
masterfrom
codex/remove-interface-file
May 15, 2026
Merged

[codex] refactor grouped data hooks#44
zombieJ merged 4 commits into
masterfrom
codex/remove-interface-file

Conversation

@zombieJ
Copy link
Copy Markdown
Member

@zombieJ zombieJ commented May 15, 2026

Summary

  • Remove the shared interface.ts and move public/list-related types next to their owning modules.
  • Replace the old contiguous segment flow with useGroupData and useFlattenData.
  • Remove useGroupSegments, useFlattenRows, and the tiny util file after inlining their remaining responsibilities.
  • Update hook tests and behavior tests to cover the new grouping/flattening flow.

Validation

  • npx tsc --noEmit --pretty false
  • npm test -- --runInBand
  • npm run lint
  • npm run compile

Summary by CodeRabbit

发布说明

  • Bug Fixes

    • 改进分组滚动定位的准确性,支持按分组键精确滚动到目标位置。
  • Refactor

    • 优化内部分组数据结构处理,提升列表渲染性能。
    • 调整分组滚动配置方式,使API设计更简洁易用。

Review Change Stack

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 15, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 28a7ab8f-bdcf-4191-83af-779360afb8c7

📥 Commits

Reviewing files that changed from the base of the PR and between 12ce58b and 118d98e.

📒 Files selected for processing (10)
  • src/List.tsx
  • src/hooks/index.ts
  • src/hooks/useFlattenRows.ts
  • src/hooks/useGroupSegments.ts
  • src/hooks/useStickyGroupHeader.tsx
  • src/index.ts
  • src/interface.ts
  • src/util/index.ts
  • tests/hooks.test.tsx
  • tests/listy.behavior.test.tsx

Walkthrough

该 PR 重构了分组数据结构和相关 API。useGroupSegments 从返回连续段索引改为返回按 key 聚合的 Map,useFlattenRows 相应接收新的 groupData 结构;scrollTo 移除工具函数依赖改用结构判断;公共类型从 interface.ts 迁移到 List.tsx;测试全面更新以验证新的 Map 结构。

Changes

Group Data Structure and List Type Reorganization

Layer / File(s) Summary
useGroupSegments: segments to aggregated Map
src/hooks/useGroupSegments.ts
useGroupSegments 返回值改为 Map<K, GroupSegmentItem<T>[]>,按 key 聚合所有相同 key 元素及其索引,移除连续段游标逻辑。
useFlattenRows: adapt to Map-based groupData
src/hooks/useFlattenRows.ts
useFlattenRows 参数改为接收 groupData Map,返回 groupKeyToItems 映射,按 groupData 插入顺序生成 header 和 item 行。
List component: types and hook integration
src/List.tsx
List.tsx 内声明 ScrollAlign、GroupScrollToConfig、ListyScrollToConfig、ListyRef、ListyProps 等公共类型;调整 useFlattenRows 调用为新参数顺序。
scrollTo: structural check replaces isGroupScrollConfig
src/List.tsx
scrollTo 改用 'groupKey' in config 结构性判断替代 isGroupScrollConfig 工具函数,简化分组滚动和普通滚动的分支逻辑。
Type exports reorganization
src/index.ts, src/hooks/useStickyGroupHeader.tsx
ListyRef 和 ListyProps 的 re-export 来源改为 List.tsx;useStickyGroupHeader 的 Group 导入改为 useGroupSegments。
Tests: verify Map-based grouping and flattening
tests/hooks.test.tsx, tests/listy.behavior.test.tsx
hooks 测试验证 useGroupSegments 返回 Map、支持跨完整数据集分组、处理空状态;useFlattenRows 测试验证 groupKeyToItems 映射;behavior 测试移除 useFlattenRows mock 改用真实实现。

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • react-component/listy#17: 主 PR 引入了分组/展平管道,本 PR 重构该管道的核心数据结构,将 useGroupSegments 改为 Map 返回,更新 useFlattenRows 的参数与输出。

Poem

🐰 兔子跳跃过 segments 的段落,
聚合 keys 入 Map 的魔法,
scrollTo 不再问"是哪种滚动",
类型归家回 List 的温暖,
扁平化行列绽新生!

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/remove-interface-file

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/hooks/useFlattenRows.ts

Oops! Something went wrong! :(

ESLint: 8.57.1

ESLint couldn't find the plugin "eslint-plugin-react".

(The package "eslint-plugin-react" was not found when loaded as a Node module from the directory "".)

It's likely that the plugin isn't installed correctly. Try reinstalling by running the following:

npm install eslint-plugin-react@latest --save-dev

The plugin "eslint-plugin-react" was referenced from the config file in ".eslintrc.js » /node_modules/.pnpm/@umijs[email protected][email protected]/node_modules/@umijs/fabric/dist/eslint.js".

If you still can't figure out the problem, please stop by https://eslint.org/chat/help to chat with the team.

src/List.tsx

Oops! Something went wrong! :(

ESLint: 8.57.1

ESLint couldn't find the plugin "eslint-plugin-react".

(The package "eslint-plugin-react" was not found when loaded as a Node module from the directory "".)

It's likely that the plugin isn't installed correctly. Try reinstalling by running the following:

npm install eslint-plugin-react@latest --save-dev

The plugin "eslint-plugin-react" was referenced from the config file in ".eslintrc.js » /node_modules/.pnpm/@umijs[email protected][email protected]/node_modules/@umijs/fabric/dist/eslint.js".

If you still can't figure out the problem, please stop by https://eslint.org/chat/help to chat with the team.

src/hooks/useStickyGroupHeader.tsx

Oops! Something went wrong! :(

ESLint: 8.57.1

ESLint couldn't find the plugin "eslint-plugin-react".

(The package "eslint-plugin-react" was not found when loaded as a Node module from the directory "".)

It's likely that the plugin isn't installed correctly. Try reinstalling by running the following:

npm install eslint-plugin-react@latest --save-dev

The plugin "eslint-plugin-react" was referenced from the config file in ".eslintrc.js » /node_modules/.pnpm/@umijs[email protected][email protected]/node_modules/@umijs/fabric/dist/eslint.js".

If you still can't figure out the problem, please stop by https://eslint.org/chat/help to chat with the team.

  • 3 others

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.

@codecov
Copy link
Copy Markdown

codecov Bot commented May 15, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 95.90%. Comparing base (12ce58b) to head (118d98e).
⚠️ Report is 1 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master      #44      +/-   ##
==========================================
- Coverage   96.37%   95.90%   -0.48%     
==========================================
  Files           5        4       -1     
  Lines         138      122      -16     
  Branches       38       34       -4     
==========================================
- Hits          133      117      -16     
  Misses          5        5              

☔ 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

@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 refactors the grouping and flattening logic by replacing useGroupSegments and useFlattenRows with useGroupData and useFlattenData, while also consolidating type definitions into List.tsx. Feedback highlights a breaking change where support for static group keys was removed, potentially causing runtime errors, and suggests optimizing the data flattening process by combining multiple iterations into a single pass.

import * as React from 'react';

export interface Group<T, K extends React.Key = React.Key> {
key: (item: T) => K;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

The Group.key type has been narrowed from ((item: T) => K) | K to strictly (item: T) => K. This is a breaking change that removes support for static group keys, which was previously supported in interface.ts. Unless this was an intentional API simplification, consider restoring the union type to maintain backward compatibility.

Suggested change
key: (item: T) => K;
key: ((item: T) => K) | K;

}

data.forEach((item, index) => {
const groupKey = group.key(item);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

To support both function and static values for group.key (consistent with the previous implementation in useGroupSegments), the logic should check the type of group.key before calling it to avoid runtime errors.

Suggested change
const groupKey = group.key(item);
const groupKey = typeof group.key === 'function' ? group.key(item) : group.key;

Comment on lines +37 to +49
groupData.forEach((groupItems, groupKey) => {
groupKeyToItems.set(
groupKey,
groupItems.map(({ item }) => item),
);

headerRows.push({ groupKey, rowIndex: flatRows.length });
flatRows.push({ type: 'header', groupKey });

groupItems.forEach(({ item, index }) => {
flatRows.push({ type: 'item', item, index });
});
});
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

The current implementation iterates over groupItems twice: once for mapping items to groupKeyToItems and once for populating flatRows. These operations can be combined into a single pass to improve performance and reduce intermediate array allocations.

    groupData.forEach((groupItems, groupKey) => {
      const items: T[] = [];
      headerRows.push({ groupKey, rowIndex: flatRows.length });
      flatRows.push({ type: 'header', groupKey });

      groupItems.forEach(({ item, index }) => {
        items.push(item);
        flatRows.push({ type: 'item', item, index });
      });
      groupKeyToItems.set(groupKey, items);
    });

@zombieJ zombieJ marked this pull request as ready for review May 15, 2026 10:05
@zombieJ zombieJ merged commit e39fe69 into master May 15, 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.

1 participant