Skip to content

fix: after selecting and dragging text, the table still scrolls even after releasing the mouse. #328

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

Open
wants to merge 10 commits into
base: master
Choose a base branch
from

Conversation

QdabuliuQ
Copy link

@QdabuliuQ QdabuliuQ commented Jul 16, 2025

๐Ÿค” This is a ...

  • ๐Ÿ†• New feature
  • ๐Ÿž Bug fix
  • ๐Ÿ“ Site / documentation improvement
  • ๐Ÿ“ฝ๏ธ Demo improvement
  • ๐Ÿ’„ Component style improvement
  • ๐Ÿค– TypeScript definition improvement
  • ๐Ÿ“ฆ Bundle size optimization
  • โšก๏ธ Performance optimization
  • โญ๏ธ Feature enhancement
  • ๐ŸŒ Internationalization
  • ๐Ÿ›  Refactoring
  • ๐ŸŽจ Code style optimization
  • โœ… Test Case
  • ๐Ÿ”€ Branch merge
  • โฉ Workflow
  • โŒจ๏ธ Accessibility improvement
  • โ“ Other (about what?)

๐Ÿ”— Related Issues

ant-design/ant-design#53924
ant-design/ant-design#54548

๐Ÿ’ก Background and Solution

้€‰ๆ‹ฉๆ–‡ๆœฌ๏ผŒ้ผ ๆ ‡ๆŒ‰ไฝๆ–‡ๆœฌๆ‹–ๆ‹ฝๅˆฐ่กจๆ ผๅค–่พน๏ผŒๆพๅผ€้ผ ๆ ‡๏ผŒ้ผ ๆ ‡ไธŠไธ‹็งปๅŠจไผš่งฆๅ‘่กจๆ ผๆปšๅŠจ

467032935-9bec2f1c-866f-40d0-be9e-b6e19b6c0be8.mov

rc-virtual-list ็š„ useScrollDrag hook ็›‘ๅฌ mouseup

๐Ÿ“ Change Log

Language Changelog
๐Ÿ‡บ๐Ÿ‡ธ English Fix virtual-list drag scrolling issue
๐Ÿ‡จ๐Ÿ‡ณ Chinese ไฟฎๅค virtual-list ๆ‹–ๆ‹ฝๆปšๅŠจๅผ‚ๅธธ

Summary by CodeRabbit

  • Bug Fixes

    • ไฟฎๅคๅœจๅˆ—่กจไธญๆ‹–ๆ‹ฝๅนถๆ”พไธ‹ๆ–‡ๆœฌๅŽไปๅฏ่ƒฝ็ปง็ปญๆปšๅŠจ็š„้—ฎ้ข˜ใ€‚็Žฐๅœจๅœจ้ผ ๆ ‡ๆพๅผ€ๅŠๅŽŸ็”Ÿๆ‹–ๆ‹ฝๅผ€ๅง‹/็ป“ๆŸ็ญ‰ๅœบๆ™ฏไธ‹้ƒฝไผšๆญฃ็กฎ็ปˆๆญขๆ‹–ๆ‹ฝๆปšๅŠจ๏ผŒ้ฟๅ…่ฏฏ่งฆๅ‘ๆปšๅŠจไบ‹ไปถ๏ผŒๆๅ‡ๅˆ—่กจไบคไบ’็จณๅฎšๆ€งไธŽๅฏๆŽงๆ€งใ€‚
  • Tests

    • ๆ–ฐๅขž็”จไพ‹๏ผŒ้ชŒ่ฏโ€œๆ‹–ๆ‹ฝๅนถๆ”พไธ‹ๆ–‡ๆœฌไธๅบ”่งฆๅ‘ๆปšๅŠจโ€๏ผŒไธบไธŠ่ฟฐ่กŒไธบๆไพ›ๅ›žๅฝ’ไฟ้šœใ€‚

The package version was changed from 3.19.2 to 3.19.1, possibly to correct a versioning error or revert a previous update.
Copy link

vercel bot commented Jul 16, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
virtual-list Ready Ready Preview Comment Aug 19, 2025 2:19pm

Copy link

coderabbitai bot commented Jul 16, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

ๅœจ useScrollDrag ้’ฉๅญๅ†…ๆ–ฐๅขžๅนถไฝฟ็”จ clearDragState() ้›†ไธญ้‡็ฝฎๆ‹–ๆ‹ฝ็Šถๆ€๏ผŒๅฐ†ๅŽŸๆœ‰็š„้ผ ๆ ‡ๅผน่ตทๅค„็†ๆ›ฟๆขไธบๅฏน document ๅฑ‚็š„ mouseupใ€dragstart ไธŽ dragend ็›‘ๅฌๅนถๅœจ cleanup ไธญ็งป้™คใ€‚ๆต‹่ฏ•ๆ–ฐๅขž้ชŒ่ฏๆ–‡ๆœฌๅŽŸ็”Ÿๆ‹–ๆ”พไธไผš่งฆๅ‘ๆปšๅŠจๅ›ž่ฐƒใ€‚

Changes

Cohort / File(s) ๅ˜ๆ›ดๆ‘˜่ฆ
Hook ๅฎž็Žฐๆ›ดๆ–ฐ
src/hooks/useScrollDrag.ts
ๆ–ฐๅขž clearDragState() ่พ…ๅŠฉๅ‡ฝๆ•ฐ๏ผ›็งป้™คๅ†…่” onMouseUp๏ผŒๆ”นไธบ document ๅฑ‚ mouseup ็›‘ๅฌๅนถ็ป‘ๅฎš clearDragState๏ผ›ๆ–ฐๅขžๅฏน document dragstart ไธŽ dragend ็š„็›‘ๅฌไธŽๆธ…็†๏ผ›ไฟ็•™ onMouseDown/onMouseMove ่กŒไธบใ€‚
ๆต‹่ฏ•ๆ–ฐๅขž
tests/scroll.test.js
ๆ–ฐๅขž็”จไพ‹ โ€œshould not scroll after drop table textโ€๏ผšๅœจ้€‰ไธญๆ–‡ๆœฌๅนถๆจกๆ‹ŸๅŽŸ็”Ÿ dragstart/dragover/drop/dragend ๆต็จ‹ๆ—ถๆ–ญ่จ€ onScroll ๆœช่ขซ่ฐƒ็”จ๏ผŒ้ชŒ่ฏๆ‹–ๆ”พไธไผš่งฆๅ‘ๆปšๅŠจใ€‚

Sequence Diagram(s)

sequenceDiagram
    participant User as ็”จๆˆท
    participant Document as Document
    participant Hook as useScrollDrag

    User->>Document: mousedown / ้€‰ไธญๆ–‡ๆœฌ
    Document->>Hook: onMouseDown / onMouseMove (ไฟๆŒๅŽŸ่กŒไธบ)
    Note right of Hook #DFF2E1: mouseDownLock ๅฏ่ƒฝไธบ true\nๆปšๅŠจๅฏ่ƒฝๅœจ่ฟ›่กŒ
    User->>Document: dragstart
    Document->>Hook: dragstart -> clearDragState()
    Note right of Hook #FCE8D6: clearDragState ๅœๆญขๆปšๅŠจๅŠจ็”ป\nๅนถๅฐ† mouseDownLock ่ฎพไธบ false
    User->>Document: drop / dragend / mouseup
    Document->>Hook: dragend / mouseup -> clearDragState()
Loading

Estimated code review effort

๐ŸŽฏ 3 (Moderate) | โฑ๏ธ ~20 minutes

Possibly related PRs

  • fix: Skip scroll when draggable ย #304 โ€” ไฟฎๆ”น useScrollDrag ไธญๆ‹–ๆ‹ฝไบคไบ’ไปฅ้ฟๅ…ๅœจๆ‹–ๆ‹ฝ็›ฎๆ ‡ไธŠ่งฆๅ‘ๆปšๅŠจ๏ผŒไธŽๆœฌๆฌกๅฏนๆ‹–ๆ‹ฝๆธ…็†็š„ๆ”นๅŠจ้ซ˜ๅบฆ็›ธๅ…ณใ€‚
  • feat: mouse down to scrollย #293 โ€” ๆ—ฉๆœŸๅฏนๅŒไธ€ hook ็š„ๅ˜ๆ›ด๏ผŒๆถ‰ๅŠๆ‹–ๆ‹ฝ/ๆปšๅŠจๅค„็†้€ป่พ‘๏ผŒไธŽๆœฌๆฌกๅฎž็Žฐๅ˜ๅŠจๅœจไปฃ็ ๅฑ‚้ข็›ดๆŽฅๅ…ณ่”ใ€‚

Poem

ๅฐๅ…”ๆŠ–ๆŠ–ๅฐพ๏ผŒๆธ…็†ๆ‹–ๆ‹ฝ้”๏ผŒ
ๆ–‡ๆœฌๆป‘่ฝ้™ๆ— ๅฃฐ๏ผŒ
ไบ‹ไปถๅœจๆ–‡ๆกฃๅค„ๆ”ถๆŸ๏ผŒ
ๆปšๅŠจไธๆƒŠๆ‰ฐ๏ผŒไปฃ็ ๆ›ดๆธ…ๆ™ฐ ๐Ÿ‡โœจ

Tip

๐Ÿ”Œ Remote MCP (Model Context Protocol) integration is now available!

Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats.

โœจ Finishing Touches
  • ๐Ÿ“ Generate Docstrings
๐Ÿงช Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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
๐Ÿชง Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@QdabuliuQ
Copy link
Author

bugๅค็Žฐdemo๏ผšhttps://stackblitz.com/edit/vitejs-vite-b3ssma5u?file=src%2FApp.tsx

Copy link

codecov bot commented Jul 17, 2025

Codecov Report

โœ… All modified and coverable lines are covered by tests.
โœ… Project coverage is 97.86%. Comparing base (5769845) to head (b77332d).

Additional details and impacted files
@@            Coverage Diff             @@
##           master     #328      +/-   ##
==========================================
+ Coverage   97.85%   97.86%   +0.01%     
==========================================
  Files          19       19              
  Lines         794      798       +4     
  Branches      193      193              
==========================================
+ Hits          777      781       +4     
  Misses         17       17              

โ˜” 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.

Introduces a test to verify that the list does not scroll when table text is dragged and dropped, ensuring onScroll is not triggered during drag-and-drop interactions.
Copy link

@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

๐Ÿ“œ Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

๐Ÿ“ฅ Commits

Reviewing files that changed from the base of the PR and between 0ce568c and bae7ddc.

๐Ÿ“’ Files selected for processing (1)
  • tests/scroll.test.js (1 hunks)

@QdabuliuQ
Copy link
Author

ๆœ‰ๆฒกๆœ‰ๅคงไฝฌreviewๅ‘€

Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR fixes a bug where text dragging in a table continues to trigger scrolling after the mouse is released. The issue occurred when users selected text, dragged it outside the table, and released the mouse - subsequent mouse movements would still cause unwanted table scrolling.

  • Adds native drag event listeners to properly reset drag state during native drag operations
  • Introduces a centralized clearDragState function to handle state cleanup consistently
  • Adds comprehensive test coverage for the text dragging scenario

Reviewed Changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 13 comments.

File Description
src/hooks/useScrollDrag.ts Implements drag event handlers and centralizes state cleanup logic
tests/scroll.test.js Adds test case to verify scrolling doesn't occur after text drag operations

Copy link

@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

๐Ÿงน Nitpick comments (3)
tests/scroll.test.js (3)

767-772: ้‡ๅค่ฐƒ็”จ selectElementText๏ผŒๆ— ๅฎž้™…ๆ„ไน‰

selectElementText ๅœจ่ฟ›ๅ…ฅ if ๅˆ†ๆ”ฏๅ‰ๅทฒๆ‰ง่กŒไธ€ๆฌก๏ผŒๅˆ†ๆ”ฏๅ†…ๅ†ๆฌก่ฐƒ็”จๅนถไธๆ”นๅ˜่กŒไธบ๏ผŒๅปบ่ฎฎๅŽป้™คไปฅ้ฟๅ…ๆททๆท†ใ€‚

-    if (targetItem && listHolder) {
-      selectElementText(targetItem);
+    if (targetItem && listHolder) {

735-735: ็”จไพ‹ๆ ‡้ข˜ๅปบ่ฎฎไปŽโ€œtableโ€ๆ”นไธบโ€œlistโ€

ๆœฌไป“ๅบ“ๅœบๆ™ฏๆ˜ฏ่™šๆ‹Ÿๅˆ—่กจ๏ผŒๆ ‡้ข˜ไธญ็š„ โ€œtableโ€ ๅฎนๆ˜“ๅผ•่ตท่ฏฏ่งฃ๏ผŒๅปบ่ฎฎๆ›ดๅ‡†็กฎ่กจ่พพใ€‚

-it('should not scroll after drop table text', () => {
+it('should not scroll after dropping selected list text', () => {

761-761: ้€‰ๆ‹ฉๅ™จไธŽๆธฒๆŸ“็ป“ๆž„็š„่€ฆๅˆๅปบ่ฎฎ้™ไฝŽ

ไธบไบ†้€‰ๆ‹ฉ็›ฎๆ ‡ๅ…ƒ็ด ๏ผŒ่ฟ™้‡Œ็ป™ li ไบบไธบๅŠ ไธŠไบ† fixed-item ็ฑปใ€‚่™ฝ็„ถ่ƒฝๅทฅไฝœ๏ผŒไฝ†ไผš่ฎฉๆต‹่ฏ•ๅฏน็ฑปๅๆœ‰ไพ่ต–ใ€‚ไนŸๅฏไปฅ็›ดๆŽฅ้€‰ๆ‹ฉ็ฌฌไธ€ไธช li ๅ…ƒ็ด ๏ผŒ่ดด่ฟ‘็œŸๅฎžๆธฒๆŸ“็ป“ๆž„๏ผŒ้™ไฝŽ่€ฆๅˆใ€‚

-        {({ id }) => <li className="fixed-item">{id}</li>}
+        {({ id }) => <li>{id}</li>}

ๅŒๆ—ถๆŠŠๅŽ็ปญๆŸฅ่ฏขๆ”นไธบ๏ผš

-    const fixedItems = container.querySelectorAll('.fixed-item');
+    const fixedItems = container.querySelectorAll('li');
๐Ÿ“œ Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

๐Ÿ’ก Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

๐Ÿ“ฅ Commits

Reviewing files that changed from the base of the PR and between dc9f00e and b77332d.

๐Ÿ“’ Files selected for processing (2)
  • src/hooks/useScrollDrag.ts (3 hunks)
  • tests/scroll.test.js (1 hunks)
๐Ÿšง Files skipped from review as they are similar to previous changes (1)
  • src/hooks/useScrollDrag.ts

Comment on lines +735 to +801
it('should not scroll after drop table text', () => {

// Helper function to select text content of an element
const selectElementText = (element) => {
const range = document.createRange();
range.selectNodeContents(element);
const selection = window.getSelection();
selection.removeAllRanges();
selection.addRange(range);
};

const onScroll = jest.fn();
const onDragStart = jest.fn();
const onDragEnd = jest.fn();
document.addEventListener('dragstart', onDragStart);
document.addEventListener('dragend', onDragEnd);

const { container } = render(
<List
component="ul"
itemKey="id"
itemHeight={20}
height={100}
data={genData(200)}
onScroll={onScroll}
>
{({ id }) => <li className="fixed-item">{id}</li>}
</List>,
);
const fixedItems = container.querySelectorAll('.fixed-item');
const targetItem = fixedItems[0];
if (targetItem) {
selectElementText(targetItem);
}
const listHolder = container.querySelector('.rc-virtual-list-holder');
if (targetItem && listHolder) {
selectElementText(targetItem);

fireEvent.dragStart(targetItem, { bubbles: true });

const rect = listHolder.getBoundingClientRect();
fireEvent.dragOver(listHolder, {
clientY: rect.bottom + 10,
bubbles: true,
});

fireEvent.drop(listHolder, {
clientY: rect.bottom + 10,
bubbles: true,
});

fireEvent.dragEnd(targetItem, { bubbles: true });
}
expect(onScroll).not.toHaveBeenCalled();
expect(onDragStart).toHaveBeenCalled();
expect(onDragEnd).toHaveBeenCalled();

if (listHolder) {
const rect = listHolder.getBoundingClientRect();
const mouseMoveEvent = new MouseEvent('mousemove', {
bubbles: true,
clientY: rect.top - 10,
});
listHolder.dispatchEvent(mouseMoveEvent);
}
expect(onScroll).not.toHaveBeenCalled();

Copy link

Choose a reason for hiding this comment

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

โš ๏ธ Potential issue

ๆต‹่ฏ•ๆœช่งฆๅ‘โ€œๆŒ‰ไฝๆ‹–ๆ‹ฝๆปšๅŠจโ€๏ผŒๆ–ญ่จ€ๅฏ่ƒฝๆˆไธบไผช้˜ณๆ€ง๏ผˆ็ผบๅฐ‘ mousedownโ†’mousemove ๅฏผ่‡ดๅˆๅง‹ๆปšๅŠจ๏ผ‰

ๅฝ“ๅ‰็”จไพ‹ไป…ๆจกๆ‹Ÿไบ†้€‰ไธญๆ–‡ๆœฌ + dragStart/dragOver/drop/dragEnd๏ผŒ็„ถๅŽๅœจๆœ€ๅŽๅšไธ€ๆฌก mousemove ๅนถๆ–ญ่จ€ onScroll ๆœช่ขซ่งฆๅ‘ใ€‚ไฝ†็”ฑไบŽไปŽๆœช่ฟ›ๅ…ฅ useScrollDrag ็š„โ€œๆŒ‰ไฝๆ‹–ๅŠจๆปšๅŠจโ€็Šถๆ€๏ผˆๆœช่งฆๅ‘ mousedownโ†’mousemove๏ผ‰๏ผŒๅณไฝฟๆฒกๆœ‰ๆญคๆฌกไฟฎๅค๏ผŒๆœ€ๅŽ้‚ฃๆฌก mousemove ้€šๅธธไนŸไธไผš่งฆๅ‘ๆปšๅŠจ๏ผŒๅ› ๆญค่ฏฅๆต‹่ฏ•ๅฏ่ƒฝๅœจๆœช่ฆ†็›–็œŸๅฎž็ผบ้™ท้“พ่ทฏ็š„ๆƒ…ๅ†ตไธ‹้€š่ฟ‡ใ€‚

ๅปบ่ฎฎๅœจ dragStart ไน‹ๅ‰ๅ…ˆ็”จ mousedown + mousemove ่งฆๅ‘ๅฑ•็คบไธญ็š„ๆปšๅŠจ๏ผˆๅนถ้€š่ฟ‡ๆŽจ่ฟ›่ฎกๆ—ถๅ™จ่ฎฉ onScroll ่‡ณๅฐ‘่ฐƒ็”จไธ€ๆฌก๏ผ‰๏ผŒ็„ถๅŽๅœจ dragStart/dragEnd ๆธ…็†ๅŽๅ†ๆฌก mousemove๏ผŒๆ–ญ่จ€ onScroll ่ฎกๆ•ฐไธๅ†ๅขžๅŠ ๏ผŒ่ฟ™ๆ ทๆ‰่ƒฝ้ชŒ่ฏโ€œ้‡Šๆ”พๅŽไธไผš็ปง็ปญๆปšๅŠจโ€็š„ๅ…ณ้”ฎ่กŒไธบใ€‚

ๅฏๅ‚่€ƒๅฆ‚ไธ‹่กฅไธไปฅๅขžๅผบ็”จไพ‹็š„ๅฎŒๆ•ดๆ€งไธŽ็จณๅฎšๆ€ง๏ผš

-it('should not scroll after drop table text', () => {
+it('should not scroll after dropping selected list text', () => {
@@
-  const onScroll = jest.fn();
+  const onScroll = jest.fn();
   const onDragStart = jest.fn();
   const onDragEnd = jest.fn();
   document.addEventListener('dragstart', onDragStart);
   document.addEventListener('dragend', onDragEnd);
@@
-        {({ id }) => <li className="fixed-item">{id}</li>}
+        {({ id }) => <li className="fixed-item">{id}</li>}
       </List>,
     );
     const fixedItems = container.querySelectorAll('.fixed-item');
     const targetItem = fixedItems[0];
     if (targetItem) {
       selectElementText(targetItem);
     }
-    const listHolder = container.querySelector('.rc-virtual-list-holder');
+    const listHolder = container.querySelector('.rc-virtual-list-holder');
     if (targetItem && listHolder) {
-      selectElementText(targetItem);
+      // ๅ…ˆ่ฟ›ๅ…ฅโ€œๆŒ‰ไฝๆ‹–ๆ‹ฝๆปšๅŠจโ€็Šถๆ€๏ผŒ็กฎไฟ onScroll ่‡ณๅฐ‘่งฆๅ‘ไธ€ๆฌก
+      fireEvent.mouseDown(targetItem, { button: 0 });
+      const preMove = createEvent.mouseMove(targetItem);
+      preMove.pageY = 100;
+      fireEvent(targetItem, preMove);
+      act(() => {
+        jest.advanceTimersByTime(100);
+      });
+      expect(onScroll).toHaveBeenCalled();
+      const scrollCallCountBeforeDrop = onScroll.mock.calls.length;
 
       fireEvent.dragStart(targetItem, { bubbles: true });
 
       const rect = listHolder.getBoundingClientRect();
       fireEvent.dragOver(listHolder, {
         clientY: rect.bottom + 10,
         bubbles: true,
       });
 
       fireEvent.drop(listHolder, {
         clientY: rect.bottom + 10,
         bubbles: true,
       });
 
       fireEvent.dragEnd(targetItem, { bubbles: true });
-    }
-    expect(onScroll).not.toHaveBeenCalled();
+      // drag ็ป“ๆŸๅŽๅ†ๆฌก็งปๅŠจ้ผ ๆ ‡๏ผŒไธๅบ”ๅ†็ปง็ปญ่งฆๅ‘ๆปšๅŠจ
+      const afterRect = listHolder.getBoundingClientRect();
+      const mouseMoveEvent = new MouseEvent('mousemove', {
+        bubbles: true,
+        clientY: afterRect.top - 10,
+      });
+      listHolder.dispatchEvent(mouseMoveEvent);
+      act(() => {
+        jest.advanceTimersByTime(100);
+      });
+      expect(onScroll.mock.calls.length).toBe(scrollCallCountBeforeDrop);
+    }
+    // ไปไฟๆŒๅฏน drag ไบ‹ไปถๆ˜ฏๅฆ่งฆๅ‘็š„ๆ ก้ชŒ
+    expect(onScroll).toHaveBeenCalled();
     expect(onDragStart).toHaveBeenCalled();
     expect(onDragEnd).toHaveBeenCalled();
 
-    if (listHolder) {
-      const rect = listHolder.getBoundingClientRect();
-      const mouseMoveEvent = new MouseEvent('mousemove', {
-        bubbles: true,
-        clientY: rect.top - 10,
-      });
-      listHolder.dispatchEvent(mouseMoveEvent);
-    }
-    expect(onScroll).not.toHaveBeenCalled();
+    // ๆธ…็†้€‰ๆ‹ฉ
+    const sel = window.getSelection();
+    sel && sel.removeAllRanges();
 
     document.removeEventListener('dragstart', onDragStart);
     document.removeEventListener('dragend', onDragEnd);
   });
๐Ÿ“ 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.

Suggested change
it('should not scroll after drop table text', () => {
// Helper function to select text content of an element
const selectElementText = (element) => {
const range = document.createRange();
range.selectNodeContents(element);
const selection = window.getSelection();
selection.removeAllRanges();
selection.addRange(range);
};
const onScroll = jest.fn();
const onDragStart = jest.fn();
const onDragEnd = jest.fn();
document.addEventListener('dragstart', onDragStart);
document.addEventListener('dragend', onDragEnd);
const { container } = render(
<List
component="ul"
itemKey="id"
itemHeight={20}
height={100}
data={genData(200)}
onScroll={onScroll}
>
{({ id }) => <li className="fixed-item">{id}</li>}
</List>,
);
const fixedItems = container.querySelectorAll('.fixed-item');
const targetItem = fixedItems[0];
if (targetItem) {
selectElementText(targetItem);
}
const listHolder = container.querySelector('.rc-virtual-list-holder');
if (targetItem && listHolder) {
selectElementText(targetItem);
fireEvent.dragStart(targetItem, { bubbles: true });
const rect = listHolder.getBoundingClientRect();
fireEvent.dragOver(listHolder, {
clientY: rect.bottom + 10,
bubbles: true,
});
fireEvent.drop(listHolder, {
clientY: rect.bottom + 10,
bubbles: true,
});
fireEvent.dragEnd(targetItem, { bubbles: true });
}
expect(onScroll).not.toHaveBeenCalled();
expect(onDragStart).toHaveBeenCalled();
expect(onDragEnd).toHaveBeenCalled();
if (listHolder) {
const rect = listHolder.getBoundingClientRect();
const mouseMoveEvent = new MouseEvent('mousemove', {
bubbles: true,
clientY: rect.top - 10,
});
listHolder.dispatchEvent(mouseMoveEvent);
}
expect(onScroll).not.toHaveBeenCalled();
it('should not scroll after dropping selected list text', () => {
// Helper function to select text content of an element
const selectElementText = (element) => {
const range = document.createRange();
range.selectNodeContents(element);
const selection = window.getSelection();
selection.removeAllRanges();
selection.addRange(range);
};
const onScroll = jest.fn();
const onDragStart = jest.fn();
const onDragEnd = jest.fn();
document.addEventListener('dragstart', onDragStart);
document.addEventListener('dragend', onDragEnd);
const { container } = render(
<List
component="ul"
itemKey="id"
itemHeight={20}
height={100}
data={genData(200)}
onScroll={onScroll}
>
{({ id }) => <li className="fixed-item">{id}</li>}
</List>,
);
const fixedItems = container.querySelectorAll('.fixed-item');
const targetItem = fixedItems[0];
if (targetItem) {
selectElementText(targetItem);
}
const listHolder = container.querySelector('.rc-virtual-list-holder');
if (targetItem && listHolder) {
// ๅ…ˆ่ฟ›ๅ…ฅโ€œๆŒ‰ไฝๆ‹–ๆ‹ฝๆปšๅŠจโ€็Šถๆ€๏ผŒ็กฎไฟ onScroll ่‡ณๅฐ‘่งฆๅ‘ไธ€ๆฌก
fireEvent.mouseDown(targetItem, { button: 0 });
const preMove = createEvent.mouseMove(targetItem);
preMove.pageY = 100;
fireEvent(targetItem, preMove);
act(() => {
jest.advanceTimersByTime(100);
});
expect(onScroll).toHaveBeenCalled();
const scrollCallCountBeforeDrop = onScroll.mock.calls.length;
fireEvent.dragStart(targetItem, { bubbles: true });
const rect = listHolder.getBoundingClientRect();
fireEvent.dragOver(listHolder, {
clientY: rect.bottom + 10,
bubbles: true,
});
fireEvent.drop(listHolder, {
clientY: rect.bottom + 10,
bubbles: true,
});
fireEvent.dragEnd(targetItem, { bubbles: true });
// drag ็ป“ๆŸๅŽๅ†ๆฌก็งปๅŠจ้ผ ๆ ‡๏ผŒไธๅบ”ๅ†็ปง็ปญ่งฆๅ‘ๆปšๅŠจ
const afterRect = listHolder.getBoundingClientRect();
const mouseMoveEvent = new MouseEvent('mousemove', {
bubbles: true,
clientY: afterRect.top - 10,
});
listHolder.dispatchEvent(mouseMoveEvent);
act(() => {
jest.advanceTimersByTime(100);
});
expect(onScroll.mock.calls.length).toBe(scrollCallCountBeforeDrop);
}
// ไปไฟๆŒๅฏน drag ไบ‹ไปถๆ˜ฏๅฆ่งฆๅ‘็š„ๆ ก้ชŒ
expect(onScroll).toHaveBeenCalled();
expect(onDragStart).toHaveBeenCalled();
expect(onDragEnd).toHaveBeenCalled();
// ๆธ…็†้€‰ๆ‹ฉ
const sel = window.getSelection();
sel && sel.removeAllRanges();
document.removeEventListener('dragstart', onDragStart);
document.removeEventListener('dragend', onDragEnd);
});

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