thisbeyond / solid-dnd

A lightweight, performant, extensible drag and drop toolkit for Solid JS.
https://solid-dnd.com
MIT License
516 stars 34 forks source link

Any way to dynamically disable sorting? #77

Closed michaelfaisst closed 1 year ago

michaelfaisst commented 1 year ago

Hey there!

First of all, thanks for making this awesome library, from what I've tried, it's very easy and straight forward to use 😄

The only thing I haven't found out how to do is how to disable sorting (or dragging) of single items dynamically. The most straight-forward approach I've tried is use:sortable={!editMode()} but it seems that the sortable directive doesn't use values given to it.

Is there any way to do this as of now?

Cheers, and thanks for the help, Michael

martinpengellyphillips commented 1 year ago

Hmmm. As in prevent a single item in a list from being dragged? Or prevent it from interacting at all with the sortable (not being moved by other items being sorted)?

michaelfaisst commented 1 year ago

@martinpengellyphillips Just preventing a single item from beeing dragged :) If there's no way right now, I could try and add it if you think it would be a useful feature 👍

martinpengellyphillips commented 1 year ago

There are a few ways you can achieve that today. The clearest might be to use the more granular approach to control when a sortable gets the drag activators or not. E.g.

solid-dnd-dynamic-disable

const Sortable = (props) => {
  const sortable = createSortable(props.item);
  const [disabled, setDisabled] = createSignal(false);
  const activators = () => (disabled() ? {} : sortable.dragActivators);

  const [state] = useDragDropContext();
  return (
    <div
      ref={sortable.ref}
      style={transformStyle(sortable.transform)}
      {...activators()}
      class="sortable"
      classList={{
        "cursor-not-allowed": disabled(),
        "bg-gray-500": disabled(),
        "opacity-25": sortable.isActiveDraggable,
        "transition-transform": !!state.active.draggable,
      }}
    >
      {props.item}
      <label class="ml-4 font-normal">
        <input
          class="mr-2"
          type="checkbox"
          onChange={(e) => setDisabled(e.target.checked)}
        />
        Disabled?
      </label>
    </div>
  );
};

Happy to hear other suggestions, but note that I previously removed the concept of 'disabled' from the core as it proved quite tricky to get right for different use cases.

michaelfaisst commented 1 year ago

@martinpengellyphillips awesome, seems to be exactly what I was looking for, thanks 😄