lukasbach / react-complex-tree

Unopinionated Accessible Tree Component with Multi-Select and Drag-And-Drop
https://rct.lukasbach.com
MIT License
944 stars 74 forks source link

DROP not working when open a new folder. #267

Closed JongSikLim closed 1 year ago

JongSikLim commented 1 year ago

Describe the bug https://github.com/lukasbach/react-complex-tree/assets/19147143/a5d2a4a5-ad7b-4a48-a913-00ea3a922669

When I open the folder, it doesn't drop. However, after dropping it elsewhere, it works. Do you have any suspicions about this behavior?

I'm currently using a ControlledTreeEnvironment, and I'm controlling the custom expandedItems when the Arrow button is pressed in the video. I thought it was a memoization issue, but I removed all the memoization at the top and this didn't fix it.

It wasn't an issue with the canDropAt callback function either. The callback function wasn't even called. Also, there is no other separate Droppable control code.

To Reproduce Steps to reproduce the behavior:

  1. Render tree
  2. Expand a folder
  3. Try to move an element

Expected behavior Should be able to drop on folder.

Screenshots

https://github.com/lukasbach/react-complex-tree/assets/19147143/0a5da687-0b51-4887-bb2e-9e06f27b4494

Desktop (please complete the following information):

Smartphone (please complete the following information):

Additional context

lukasbach commented 1 year ago

Looks like something is memoized incorrectly. Can you share the code that renders the tree, and also the version of RCT that you are using?

JongSikLim commented 1 year ago

@lukasbach I'm using lastest RCT version.

Here are my codes, some codes are replaced to console for security. And there is no memorization in parents. I guess I call the setComponents in our business logic, can it occur this problem?

import React, {useState} from "react";

const Sample = () => {
  const [components, setComponets] = useState();
  const [focusedItem, setFocusedItem] = useState();
  const [expandedItems, setExpandedItems] = useState(['root']);
  const [selectedItems, setSelectedItems] = useState(['root']);

  return (
    <ControlledTreeEnvironment
      items={components}
      getItemTitle={(item) => item.index.toString()}
      viewState={{
        TemplateComponentTree: {
          expandedItems,
          selectedItems,
          focusedItem,
        },
      }}
      canDragAndDrop={true}
      canDropOnFolder={true}
      canReorderItems={true}
      canDropAt={() => {        
        // Can't drop on own parent        
      }}

      renderItemArrow={({ item }) => {
        if (item.isFolder) {
          return (
            //Icon button component
            <></>
          );
        }
        return null;
      }}
      renderItem={(props) => {
        return <ComponentItem {...props} treeRef={treeRef} />;
      }}      
      renderTreeContainer={({ children, containerProps }) => (
        <ComponentTreeContainer {...(containerProps as any)}>
          {children}
        </ComponentTreeContainer>
      )}
      renderItemsContainer={({ children, containerProps }) => (
        <ComponentTreeItemContainer {...(containerProps as any)}>
          {children}
        </ComponentTreeItemContainer>
      )}
      onFocusItem={(item) => setFocusedItem(item.index)}
      onExpandItem={(item) => setExpandedItems([...expandedItems, item.index])}
      onCollapseItem={(item) =>
        setExpandedItems(
          expandedItems.filter(
            (expandedItemIndex) => expandedItemIndex !== item.index
          )
        )
      }
      onSelectItems={(items) => {
        if (items.length > 0) {
          setTimeout(() => {
            setSelectedItems([items[0]]);
          }, 0);
        }
      }}
      onDrop={(items, target) => {
        if (items.length === 0) return; 
        // moveComponent        
      }}
      defaultInteractionMode={{
        mode: "custom",
        extends: InteractionMode.ClickItemToExpand,
        createInteractiveElementProps: (item, _, actions, renderFlags) => ({
          onClick: () => {
            if (renderFlags && !renderFlags.isFocused) actions.focusItem();
            else actions.selectItem();
          },
          onFocus: () => {
            actions.focusItem();
          },
        }),
      }}
    >
      <Tree<NotificationTemplateComponent>
        ref={treeRef}
        treeId="TemplateComponentTree"
        rootItem="root"
      />
    </ControlledTreeEnvironment>
  );
};

export default Sample;
lukasbach commented 1 year ago

Hm sorry, I don't see anything particular that could be the reason for the issue..