Support scrollbar track click#368
Conversation
|
@QDyanbing is attempting to deploy a commit to the afc163's projects Team on Vercel. A member of the Team first needs to authorize it. |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
Walkthrough重构了 ScrollBar 中滚动偏移的计算逻辑,新增 getScrollOffsetByThumbTop 工具函数统一处理拖拽与轨道点击场景下的比例换算和边界裁剪,新增 isThumbTarget 与 scrollToTrackPosition 处理点击判定,并补充相应测试用例。 Changes滚动条偏移计算重构
Estimated code review effort: 3 (Moderate) | ~20 minutes Sequence Diagram(s)sequenceDiagram
participant User
participant ScrollBar
participant getScrollOffsetByThumbTop
participant onScroll
User->>ScrollBar: mouseDown on track
ScrollBar->>ScrollBar: isThumbTarget(target)
alt 非左键点击或点击目标为thumb
ScrollBar-->>User: 直接返回
else 点击轨道空白处
ScrollBar->>ScrollBar: scrollToTrackPosition(mousePos)
ScrollBar->>getScrollOffsetByThumbTop: 计算thumbTop对应scrollOffset
getScrollOffsetByThumbTop-->>ScrollBar: 返回裁剪后偏移
ScrollBar->>onScroll: 触发滚动
end
Possibly related PRs
Suggested reviewers: Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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
src/ScrollBar.tsxESLint skipped: missing config or dependency (missing-dependency). The ESLint configuration references a package that is not available in the sandbox. tests/scroll.test.jsESLint skipped: the ESLint configuration for this file 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. Comment |
There was a problem hiding this comment.
Code Review
This pull request introduces track-clicking functionality to the ScrollBar component, allowing users to scroll by clicking directly on the scrollbar track. It extracts the scroll offset calculation into a reusable helper function getScrollOffsetByThumbTop and adds a vertical track-clicking test. The review feedback suggests improving the robustness of the new helper function by handling non-finite range values, and expanding test coverage to include horizontal track-clicking scenarios under both LTR and RTL layouts.
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.
| if (enabledScrollRange <= 0 || enabledOffsetRange <= 0) { | ||
| return 0; | ||
| } |
There was a problem hiding this comment.
在 getScrollOffsetByThumbTop 中,如果 enabledScrollRange 或 enabledOffsetRange 为 NaN 或非有限数值(例如在组件初始挂载、尺寸尚未测量完成时),enabledScrollRange <= 0 的判断会返回 false,从而导致后续计算产生 NaN 并传递给 onScroll。
建议使用 Number.isFinite 进行更严谨的防御性检查,确保计算结果的安全性。
| if (enabledScrollRange <= 0 || enabledOffsetRange <= 0) { | |
| return 0; | |
| } | |
| if ( | |
| !Number.isFinite(enabledScrollRange) || | |
| !Number.isFinite(enabledOffsetRange) || | |
| enabledScrollRange <= 0 || | |
| enabledOffsetRange <= 0 | |
| ) { | |
| return 0; | |
| } |
| it('click track to scroll', () => { | ||
| const { container } = genList({ | ||
| itemHeight: 20, | ||
| height: 100, | ||
| data: genData(100), | ||
| }); | ||
|
|
||
| act(() => { | ||
| const scrollbar = container.querySelector('.rc-virtual-list-scrollbar-vertical'); | ||
| const mouseDownEvent = createEvent.mouseDown(scrollbar); | ||
| Object.defineProperty(mouseDownEvent, 'pageY', { value: 50 }); | ||
| fireEvent(scrollbar, mouseDownEvent); | ||
| }); | ||
|
|
||
| expect(container.querySelector('ul').scrollTop).toEqual(950); | ||
| }); |
There was a problem hiding this comment.
虽然新增了竖向滚动条轨道点击的测试,但水平滚动条(尤其是涉及 RTL 和 LTR 逻辑的分支)也包含了较为复杂的坐标计算。
建议补充水平滚动条在 LTR 和 RTL 模式下轨道点击的测试用例,以确保其正确性并防止后续重构引入回归问题。
it('click track to scroll', () => {
const { container } = genList({
itemHeight: 20,
height: 100,
data: genData(100),
});
act(() => {
const scrollbar = container.querySelector('.rc-virtual-list-scrollbar-vertical');
const mouseDownEvent = createEvent.mouseDown(scrollbar);
Object.defineProperty(mouseDownEvent, 'pageY', { value: 50 });
fireEvent(scrollbar, mouseDownEvent);
});
expect(container.querySelector('ul').scrollTop).toEqual(950);
});
it('click horizontal track to scroll', () => {
const { container } = genList({
itemHeight: 20,
height: 100,
data: genData(100),
scrollWidth: 1000,
});
act(() => {
const scrollbar = container.querySelector('.rc-virtual-list-scrollbar-horizontal');
const mouseDownEvent = createEvent.mouseDown(scrollbar);
Object.defineProperty(mouseDownEvent, 'pageX', { value: 50 });
fireEvent(scrollbar, mouseDownEvent);
});
const horizontalScrollbar = container.querySelector('.rc-virtual-list-scrollbar-horizontal');
expect(Number(horizontalScrollbar.parentElement.getAttribute('data-dev-offset'))).toEqual(450);
});
it('click horizontal track to scroll in RTL', () => {
const { container } = genList({
itemHeight: 20,
height: 100,
data: genData(100),
scrollWidth: 1000,
direction: 'rtl',
});
act(() => {
const scrollbar = container.querySelector('.rc-virtual-list-scrollbar-horizontal');
const mouseDownEvent = createEvent.mouseDown(scrollbar);
Object.defineProperty(mouseDownEvent, 'pageX', { value: 50 });
fireEvent(scrollbar, mouseDownEvent);
});
const horizontalScrollbar = container.querySelector('.rc-virtual-list-scrollbar-horizontal');
expect(Number(horizontalScrollbar.parentElement.getAttribute('data-dev-offset'))).toEqual(450);
});
变更内容
背景
Ant Design issue ant-design/ant-design#58499 反馈:Table 开启虚拟滚动后,自定义滚动条仅支持拖拽滑块或滚轮滚动,不支持点击滚动条轨道快速定位。该交互与浏览器原生滚动条体验不一致。
影响
虚拟滚动列表的自定义滚动条现在可以通过点击轨道直接跳转到对应滚动位置;点击滑块本身仍保持原来的拖拽行为。
验证
npm run lint:通过,存在仓库既有 hooks warnings,无 error。npm run tsc:通过。npm test -- tests/scroll.test.js --runInBand:通过。npm test -- tests/scrollWidth.test.tsx --runInBand:通过。git diff --check:通过。Summary by CodeRabbit
Bug Fixes
Tests