Skip to content
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

[next] controlled or cancellable useSortable #1434

Closed
AddMoreScripts opened this issue Jun 12, 2024 · 5 comments
Closed

[next] controlled or cancellable useSortable #1434

AddMoreScripts opened this issue Jun 12, 2024 · 5 comments

Comments

@AddMoreScripts
Copy link

Hi.
I'm trying to upgrade to a new version of DND-KIT, but I'm running into a problem with compatibility.

I'm using the useSortable hook to move cards (change their order).
A problem arises that cards save new positions immediately after moving (optimistic rendring) and this cannot be canceled in any way in the onDragEnd attribute, or return to previous positions. Is there such a possibility?

The point is that I need to send the new order of cards to the server and handle possible responce errors.

May be Is it possible to programmatically cancel the movement? or make the order of elements controlled externally? (for example, change the order programmatically from store).

Thanks!

@clauderic
Copy link
Owner

clauderic commented Jun 12, 2024

There's a few ways you can do this:

If you want to completely disable optimistic re-ordering of items, you can call event.preventDefault() in the onDragOver callback:

import {DragDropProvider} from '@dnd-kit/react';

function App() {
  return (
    <DragDropProvider onDragOver={(event) => event.preventDefault()}>
      ...
    </DragDropProvider>
  )
}

You can also manage the state of your items in React, and update it in onDragOver():

import {useState} from 'react';
import {DragDropProvider} from '@dnd-kit/react';
import {move} from '@dnd-kit/helpers';

function App() {
  const [items, setItems] = useState(['A', 'B', 'C', 'D']);
  
  return (
    <DragDropProvider 
      onDragOver={(event) => {
         const {dragOperation: {source, target}} = event;
         setItems((items) => move(items, source, target));
      }}
    >
      {items.map((item, index) => <Sortable key={item} id={item} index={index} />
    </DragDropProvider>
  )
}

When you update the items in React in the onDragOver callback, @dnd-kit will detect this and will not optimistically update the order of the items so you don't need to call event.preventDefault() in that scenario.

@clauderic
Copy link
Owner

clauderic commented Jun 12, 2024

I don't know if you have seen but there's a new documentation website where you can learn more: https://next.dndkit.com

Not everything is documented yet, but this guide can be helpful: https://next.dndkit.com/react/guides/multiple-sortable-lists

@AddMoreScripts
Copy link
Author

@clauderic

Thank you, the documentation helped 👍. This seems to be the best library for drag and drop in react.
The only thing is that the documentation does not yet say about of groups property in useSortable

A couple more questions about the new version:

  • Will it no longer be possible to specify a strategy for useSortable (horizontal, vertical)?
  • Now it won’t be possible to customize DragOverlay? and change the styles of the dragged ref element? (currently the opacity: 0)

Thanks.

@clauderic
Copy link
Owner

clauderic commented Jun 14, 2024

At the moment I'm not considering introducing strategies for useSortable, it's been a source of frustration for many consumers that have unpredictable layouts so I've been focusing on making sure the library works well with unpredictable layouts out of the box, and perhaps someday will consider introducing strategies as a plugin for consumers who want a small performance improvement and have a predictable layout.

The new library works a bit differently from the previous one when it comes to DragOverlay. It's on my roadmap to introduce a <DragOverlay> component for consumers migrating from the current version of @dnd-kit, but not something I have gotten to doing yet.

The new library moves the element you connect to useRef and creates a placeholder element in its place. The placeholder is a clone of the element being dragged and is hidden by default but you force it to appear by setting the feedback attribute on useSortable to clone:

useSortable({id, feedback: 'clone'});

The clone has the [data-dnd-placeholder] attribute if you want to style it. If you want to style the element being dragged, you can do so in React:

const {ref, isDragSource} = useSortable({id});

return (
  <button style={{background: isDragSource ? 'green' : 'red'} ref={ref}>Drag me</button>
)

@AddMoreScripts
Copy link
Author

Thank you. data-dnd-placeholder works great.

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

No branches or pull requests

2 participants