import { useState } from 'react'; import { useDrag, useDrop } from 'react-dnd'; import { StyledCollapse, StyledNodeLine, StyledTreeNodeContainer, StyledTreeNodeItem, } from './styles'; import type { Node, NodeLIneProps, TreeNodeProps } from './types'; const NodeLine = ({ node, onDrop, allowDrop = true, isTop = false, }: NodeLIneProps) => { const [{ isOver }, drop] = useDrop( () => ({ accept: 'node', drop: (item: Node, monitor) => { const didDrop = monitor.didDrop(); if (didDrop) { return; } onDrop?.(item, node, { internal: false, topLine: isTop, bottomLine: !isTop, }); }, collect: monitor => ({ isOver: monitor.isOver(), canDrop: monitor.canDrop(), }), }), [onDrop] ); return ; }; export const TreeNode = ({ node, index, allDrop = true, ...otherProps }: TreeNodeProps) => { const { onAdd, onDelete, onDrop, indent } = otherProps; const [collapsed, setCollapsed] = useState(false); const [{ isDragging }, drag] = useDrag(() => ({ type: 'node', item: node, collect: monitor => ({ isDragging: monitor.isDragging(), }), })); const [{ canDrop, isOver }, drop] = useDrop( () => ({ accept: 'node', drop: (item: Node, monitor) => { const didDrop = monitor.didDrop(); if (didDrop || item.id === node.id || !allDrop) { return; } onDrop?.(item, node, { internal: true, topLine: false, bottomLine: false, }); }, collect: monitor => ({ isOver: monitor.isOver(), canDrop: monitor.canDrop(), }), }), [onDrop, allDrop] ); return ( {index === 0 && ( )} {node.render?.(node, { onAdd: () => onAdd?.(node), onDelete: () => onDelete?.(node), collapsed, setCollapsed, })} {(!node.children?.length || collapsed) && ( )} {node.children && node.children.map((childNode, index) => ( ))} ); }; export default TreeNode;