mui / mui-x

MUI X: Build complex and data-rich applications using a growing list of advanced React components, like the Data Grid, Date and Time Pickers, Charts, and more!
https://mui.com/x/
4.51k stars 1.31k forks source link

[data grid] Drag the rows within to another data grid or DOM element #12759

Open EkaLinMan opened 6 months ago

EkaLinMan commented 6 months ago

Summary

I've already done the research, and it seems Row ordering is the only way to drag the row, but rowReordering is not my purpose. I hope to achieve the below descriptions:

  1. Drag the single/ multiple rows from the data grid.
  2. The developer can customize the text in the draggable box based on selected row counts or row data, like advanced Customizing the reorder value
  3. If rowReordering is disabled, don't execute the reordering when dragging.
  4. If the target is another grid, the default behavior is moving the rows from data gird1 to data gird2, or the developer can customize the behaviors with the row data.
  5. If the target is an external container, the developer can customize the behaviors with the row data.

It seems to be a useful feature. I also appreciate it if someone could provide a simple demo to achieve steps 1, 2, 3, and 5, but I guess the only way now is customizing the grid row to be draggable with native D&D API:

  1. Utilize the slots to customize the row component.
  2. Invoke the useGridApiContext in the row component to retrieve the data of selected rows
  3. Utilize the native D&D API to implement the drag & drop feature (also hold the data that is being dragged during a drag and drop operation) and the draggable box to display the information.

Examples

The similar behaviors: https://ag-grid.com/javascript-data-grid/row-dragging-to-grid/ https://ag-grid.com/javascript-data-grid/row-dragging-to-external-dropzone/ https://www.material-react-table.com/docs/guides/row-ordering-dnd#drag-and-drop-rows-to-other-ui-or-tables

Motivation

No response

Search keywords: drag

michelengelen commented 6 months ago

Hey @EkaLinMan This would be a new feature request, since we currently only handle internal dragging for row reordering.

IMHO exposing the onDragEnd in some way could already be beneficial. With this exposed you could easily build the desired behavior. From what I can see it is exactly what MRT does in their example. All of the state management is custom and gets triggered by the call to onDragEnd.

I will add this to our board for the team to discuss it.

WDYT @mui/xgrid ... would that be a feasible approach for us?

cherniavskii commented 6 months ago

IMHO exposing the onDragEnd in some way could already be beneficial.

This is already possible via rowDragEnd event – see https://stackblitz.com/edit/react-pojshk?file=Demo.tsx Not sure it would be enough to drag the row to a different Data Grid though.

cherniavskii commented 6 months ago

I gave it a try – it looks like it's possible to intercept the rows dropped to a DOM element – see this demo: https://stackblitz.com/edit/react-pojshk-kxfjdx?file=Demo.tsx

@EkaLinMan Is this what you're looking for?

EkaLinMan commented 6 months ago

Hi @michelengelen , @cherniavskii , thanks for your reply. I choose not to use rowReordering because I don't want to reorder the rows, also from my point of view, it's not so intuitive to trigger rowReordering to implement other drag-and-drop feature, especially since my target is an external grid/ container (which is very distant) instead of the internal dragging.

We also need to achieve the below goals, I think it's better to centralize the logic in one component.

  1. I need to drag the multiple selected rows.
  2. I need to initiate dragging when the client starts dragging within the row, not just when interacting with a specific icon.
  3. I need to customize the draggable box text.

In the end, I implemented my DraggableGridRow to replace the default row component. The demo is here: https://codesandbox.io/p/sandbox/jovial-jerry-p8yzh5

Thanks!

michelengelen commented 6 months ago

Looks like a viable solution to me.

@cherniavskii do you think we should add a recipe for this? Or should we explore adding a custom approach for dragging rows?