Skip to content

fix: new drag-n-drop-list component using dnd-kit lib - #279

Merged
smarcet merged 5 commits into
mainfrom
feat/dnd-kit-list
Jul 6, 2026
Merged

fix: new drag-n-drop-list component using dnd-kit lib#279
smarcet merged 5 commits into
mainfrom
feat/dnd-kit-list

Conversation

@tomrndom

@tomrndom tomrndom commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

ref: https://github.com/fntechgit/sponsor-services/pull/57

from https://github.com/fntechgit/sponsor-services/pull/57#discussion_r3505871793

Signed-off-by: Tomás Castillo tcastilloboireau@gmail.com

Summary by CodeRabbit

  • New Features

    • Added a new drag-and-drop list component for MUI-based UIs, letting users reorder items visually.
    • Supports custom item rendering, drag handles, and automatic order updates after reordering.
    • Added a bundled entry so the component is available in builds.
  • Tests

    • Added coverage for rendering, drag-and-drop reordering, missing IDs, custom ID fields, and order updates.

Signed-off-by: Tomás Castillo <tcastilloboireau@gmail.com>
@tomrndom
tomrndom requested a review from smarcet July 1, 2026 18:54
@coderabbitai

coderabbitai Bot commented Jul 1, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@tomrndom, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 48 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 9b8c44d2-f424-49f3-8068-ff40c0cf98ac

📥 Commits

Reviewing files that changed from the base of the PR and between 1c4bf3b and 9e3278b.

📒 Files selected for processing (1)
  • src/components/mui/DragNDropList/sortable-item.js
📝 Walkthrough

Walkthrough

Adds a new DragNDropList MUI component with a SortableItem helper, built on @dnd-kit for drag-and-drop reordering. Includes new dev/peer dependencies, a Jest test suite, a webpack entry, and a commented-out export placeholder in the components index.

Changes

DragNDropList component addition

Layer / File(s) Summary
Dependency declarations for @dnd-kit packages
package.json
Adds @dnd-kit/core, @dnd-kit/sortable, and @dnd-kit/utilities to devDependencies and peerDependencies.
DragNDropList component implementation
src/components/mui/DragNDropList/index.js, src/components/mui/DragNDropList/sortable-item.js
Implements SortableItem (via useSortable) and DragNDropList with dnd-kit sensors, handleDragEnd reorder logic using arrayMove and updateOrderKey, getItemId fallback logic, and propTypes/default exports.
Test suite and build wiring
src/components/mui/__tests__/drag-n-drop-list.test.js, webpack.common.js, src/components/index.js
Adds Jest/RTL tests covering rendering, drag-and-drop reorder, id resolution, and updateOrderKey behavior; adds a webpack entry for the new bundle; adds a commented-out MuiDragNDropList export.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant SortableItem
  participant DndContext
  participant DragNDropList
  User->>SortableItem: pointer/keyboard drag start
  SortableItem->>DndContext: drag events (active, over)
  DndContext->>DragNDropList: onDragEnd(active, over)
  DragNDropList->>DragNDropList: compute old/new index, arrayMove, update updateOrderKey
  DragNDropList->>User: onReorder(reorderedItems)
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: adding a new drag-and-drop list component built with dnd-kit.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/dnd-kit-list

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

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 (2)
src/components/mui/drag-n-drop-list.js (1)

71-74: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider an activation constraint on PointerSensor.

Without activationConstraint (e.g. { distance: 8 }), any interactive controls rendered by renderItem (buttons, checkboxes, links) may have their click behavior swallowed by drag activation on the first pointer move.

♻️ Suggested tweak
-    useSensor(PointerSensor),
+    useSensor(PointerSensor, { activationConstraint: { distance: 8 } }),
🤖 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/components/mui/drag-n-drop-list.js` around lines 71 - 74, Add an
activation constraint to the PointerSensor used in useSensors so simple clicks
on interactive content inside renderItem are not interpreted as drag starts.
Update the sensor setup in drag-n-drop-list.js to configure PointerSensor with a
small distance threshold (for example, 8px) while leaving KeyboardSensor and
sortableKeyboardCoordinates unchanged.
src/components/mui/__tests__/drag-n-drop-list.test.js (1)

131-179: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Add regression coverage for falsy idKey values (e.g. id: 0).

All fixtures here use truthy ids. Once the getItemId truthy-check bug in drag-n-drop-list.js (Lines 61-62) is fixed, add a case with an item whose id is 0 to prevent regression.

🤖 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/components/mui/__tests__/drag-n-drop-list.test.js` around lines 131 -
179, Add regression coverage in DragAndDropList id resolution tests for a falsy
idKey value such as 0. Extend the existing id resolution block in
drag-n-drop-list.test.js with a case that renders DragAndDropList using an item
whose id (or custom idKey) is 0 and verifies getItemId still returns that id
rather than falling back to new-{index}. Make sure the assertion exercises the
onReorder path so the bug in getItemId is covered.
🤖 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/components/mui/drag-n-drop-list.js`:
- Around line 61-62: `getItemId` in `DragNDropList` is using a truthy check that
treats valid ids like 0 or empty string as missing, which can desync
`SortableContext` ids from `handleDragEnd` lookups and cause `arrayMove` to
reorder the wrong item. Update the id resolution in `getItemId` to check for
null/undefined instead of truthiness, and make sure `handleDragEnd` only calls
`arrayMove` when both `active.id` and `over.id` resolve to valid indexes in the
current list.

---

Nitpick comments:
In `@src/components/mui/__tests__/drag-n-drop-list.test.js`:
- Around line 131-179: Add regression coverage in DragAndDropList id resolution
tests for a falsy idKey value such as 0. Extend the existing id resolution block
in drag-n-drop-list.test.js with a case that renders DragAndDropList using an
item whose id (or custom idKey) is 0 and verifies getItemId still returns that
id rather than falling back to new-{index}. Make sure the assertion exercises
the onReorder path so the bug in getItemId is covered.

In `@src/components/mui/drag-n-drop-list.js`:
- Around line 71-74: Add an activation constraint to the PointerSensor used in
useSensors so simple clicks on interactive content inside renderItem are not
interpreted as drag starts. Update the sensor setup in drag-n-drop-list.js to
configure PointerSensor with a small distance threshold (for example, 8px) while
leaving KeyboardSensor and sortableKeyboardCoordinates 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: d7d4e316-de35-4f98-994e-301385a42329

📥 Commits

Reviewing files that changed from the base of the PR and between 8f682d6 and a07f066.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (5)
  • package.json
  • src/components/index.js
  • src/components/mui/__tests__/drag-n-drop-list.test.js
  • src/components/mui/drag-n-drop-list.js
  • webpack.common.js

Comment thread src/components/mui/drag-n-drop-list.js Outdated
…atched id

Signed-off-by: Tomás Castillo <tcastilloboireau@gmail.com>

Copilot AI left a comment

Copy link
Copy Markdown

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 introduces a new MUI-friendly drag-and-drop list component built on dnd-kit, and wires it into the build so it can be consumed alongside existing MUI components.

Changes:

  • Added src/components/mui/drag-n-drop-list.js implementing a sortable list with pointer + keyboard sensors and automatic order-field updates.
  • Added Jest coverage for rendering, reordering behavior, id handling, and custom updateOrderKey.
  • Added @dnd-kit/* dependencies and registered the new component entry in Webpack.

Reviewed changes

Copilot reviewed 5 out of 6 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
yarn.lock Locks newly added @dnd-kit/* transitive dependencies.
webpack.common.js Adds a build entry for components/mui/drag-n-drop-list.
src/components/mui/drag-n-drop-list.js New dnd-kit-based sortable list component.
src/components/mui/tests/drag-n-drop-list.test.js Unit tests covering reorder + id/order behaviors.
src/components/index.js Adds a commented-out export note for the new component (consistent with other “3rd party deps” exports).
package.json Adds @dnd-kit/* to devDependencies + peerDependencies.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/components/mui/drag-n-drop-list.js Outdated
Comment thread src/components/mui/DragNDropList/index.js

@smarcet smarcet left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

@tomrndom please review

Signed-off-by: Tomás Castillo <tcastilloboireau@gmail.com>

@santipalenque santipalenque left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

other than this, LGTM

Comment thread src/components/mui/drag-n-drop-list.js Outdated
Signed-off-by: Tomás Castillo <tcastilloboireau@gmail.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

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 (1)
src/components/mui/DragNDropList/sortable-item.js (1)

22-47: 🚀 Performance & Scalability | 🔵 Trivial | 💤 Low value

Consider React.memo for row-level performance.

Each SortableItem re-renders whenever the parent DragNDropList re-renders (e.g., on every drag-move tick if the parent re-renders items), even for rows unaffected by the current drag. Memoizing (with a comparator that accounts for renderItem identity) can reduce wasted renders in larger lists.

🤖 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/components/mui/DragNDropList/sortable-item.js` around lines 22 - 47, Wrap
SortableItem with React.memo to prevent unnecessary row re-renders during
DragNDropList updates, especially on drag-move ticks. Update the SortableItem
component so it only re-renders when its relevant props change, and make sure
the comparator accounts for renderItem identity (and any other props that affect
output) to avoid stale rendering. Keep the existing useSortable, Box, and
renderItem behavior unchanged while improving row-level performance.
🤖 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/components/mui/DragNDropList/sortable-item.js`:
- Around line 22-46: In SortableItem, the dragged row only updates transform and
transition, so it can still render beneath neighboring items during a drag.
Update the Box styling in SortableItem to bump stacking order when isDragging is
true by applying a higher zIndex alongside the existing background change,
keeping the logic localized to the useSortable result and the Box wrapper.

---

Nitpick comments:
In `@src/components/mui/DragNDropList/sortable-item.js`:
- Around line 22-47: Wrap SortableItem with React.memo to prevent unnecessary
row re-renders during DragNDropList updates, especially on drag-move ticks.
Update the SortableItem component so it only re-renders when its relevant props
change, and make sure the comparator accounts for renderItem identity (and any
other props that affect output) to avoid stale rendering. Keep the existing
useSortable, Box, and renderItem behavior unchanged while improving row-level
performance.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 0a58eba3-7faf-4105-8fb2-f83e4b269b52

📥 Commits

Reviewing files that changed from the base of the PR and between cd9d3b7 and 1c4bf3b.

📒 Files selected for processing (5)
  • src/components/index.js
  • src/components/mui/DragNDropList/index.js
  • src/components/mui/DragNDropList/sortable-item.js
  • src/components/mui/__tests__/drag-n-drop-list.test.js
  • webpack.common.js
✅ Files skipped from review due to trivial changes (1)
  • src/components/index.js
🚧 Files skipped from review as they are similar to previous changes (2)
  • webpack.common.js
  • src/components/mui/tests/drag-n-drop-list.test.js

Comment thread src/components/mui/DragNDropList/sortable-item.js
Signed-off-by: Tomás Castillo <tcastilloboireau@gmail.com>
@tomrndom
tomrndom requested a review from smarcet July 3, 2026 14:36

@smarcet smarcet left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM

@smarcet
smarcet merged commit 4362941 into main Jul 6, 2026
5 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.

4 participants