phphe/he-tree-react

Support check droppable based on source and destination nodes data

phamquanganh31101998 opened this issue · 2 comments

Hi, i'm using he-tree-react to support dragging and dropping in tree.
However, from my business, there are some restriction about if source nodes are draggable into/next to droppable nodes. For example, a destination node cannot have more than 2 child levels (including the source node if dropped to it).
Can you support checking if a source node can drop to destination node, based on their two's data? I assume that function will have prototype like (sourceNode, destinationNode) => boolean

phphe commented
import { useHeTree, sortFlatData, walkTreeData } from "he-tree-react";
import type { HeTreeProps } from "he-tree-react";
import { useState, useRef } from 'react';

export default function BasePage() {
  const keys = { idKey: 'id', parentIdKey: 'parent_id' };
  // prettier-ignore
  const [data, setdata] = useState(() => sortFlatData([{ id: 2, parent_id: 1, name: "Technology", }, { id: 5, parent_id: 2, name: "Hardware", }, { id: 10, parent_id: 5, name: "Computer Components", }, { id: 4, parent_id: 2, name: "Programming", }, { id: 8, parent_id: 4, name: "Python", }, { id: 3, parent_id: 1, name: "Science", }, { id: 7, parent_id: 3, name: "Biology", }, { id: 6, parent_id: 3, name: "Physics", },], keys));
  const { renderTree, draggingStat } = useHeTree({
    ...keys,
    data,
    dataType: 'flat',
    onChange: setdata,
    renderNode: ({ id, node, open, checked, draggable }) => <div>
      {node.name} - {id}
    </div>,
    canDrag: ({ id }) => id === 2 ? true : (id === 3 ? false : undefined),
    ...useMaxLevel(2),
  })
  return <div>
    {renderTree({ style: { width: '300px', border: '1px solid #555', padding: '20px' } })}
  </div>
}

function useMaxLevel(maxLevel: number) {
  const draggingLevels = useRef(0);
  const props: Partial<HeTreeProps<any>> = {
    onDragStart(e, stat) {
      let max = stat.level
      walkTreeData(stat.childStats, (childStat) => {
        if (childStat.level > max) {
          max = childStat.level
        }
      }, 'childStats')
      draggingLevels.current = max - stat.level + 1
    },
    canDrop: ({ level }) => draggingLevels.current + level <= maxLevel,
    canDropToRoot: () => draggingLevels.current <= maxLevel,
  }
  return props
}

use useMaxLevel hook in this example. It is modified from https://he-tree-react.phphe.com/v1/guide#draggable-droppable

@phphe thank you, your solution worked like a champs!