craft.js icon indicating copy to clipboard operation
craft.js copied to clipboard

Ability to select a node immediately after connectors.create()

Open timc1 opened this issue 5 years ago • 7 comments

Trying to figure out a way to select a node after dragging from the toolbox into the canvas. It doesn't look like there is a way to get the fresh nodeId when using connectors.create(ref, Component)

I might be overlooking something simple, but lmk!

timc1 avatar Feb 09 '21 20:02 timc1

@timc1 https://github.com/prevwong/craft.js/pull/22 In your component, you can call the selectNode function with nodeId.

const { actions: {selectNode}, } = useEditor();
const {
    id,
  } = useNode();

  useEffect(() => {
    selectNode(id);
  }, []);

This will auto-select your node after dragging it from the toolbox into the canvas

GuglaniNiharika avatar Feb 11 '21 14:02 GuglaniNiharika

@GuglaniNiharika if we were to add that for every User component, that would effectively call selectNode on every User component's initial mount?

timc1 avatar Feb 11 '21 14:02 timc1

@timc1 Yes, it will. So, if you drag and drop some component say Heading into canvas, it would make selected property of that particular node as true

GuglaniNiharika avatar Feb 11 '21 14:02 GuglaniNiharika

Yeah, makes sense – the part that is concerning is that every User component on the screen will call selectNode on the initial mount 🤷

timc1 avatar Feb 11 '21 14:02 timc1

@timc1 You want to select the recent most dropped component right? So, if you have the above code in your user components, the initial mount will only happen for the component you are dropping and the id which you receive from useNode will be the id of the recent most instance of the user component. So, if your canvas has 2 instances of user component A and 1 instance of user component B, and now you try and drop user component A again into the canvas, the useNode will give you the id of this last instance. selectNode will be called only with this last instance's id. And user component B won't be rerendered

GuglaniNiharika avatar Feb 11 '21 14:02 GuglaniNiharika

      const {parentNodeId, idx} = props.getParentAndIdx(state, query);
      console.log({parentNodeId, idx});
      const nodeTree = query.parseReactElement(el as ReactElement).toNodeTree();
      // console.log('add to canvas');
      actions.addNodeTree(nodeTree, parentNodeId, idx);

      setTimeout(() => {
          const nodeId = query.node(parentNodeId).descendants()[idx]!;
          actions.selectNode(nodeId);
      }, 100);

Here's sth I came up with. It gives me more control programmtically to serve the purpose of inserting multiple nodes etc.

But the problem is that query.node(...) does not get the latest tree structure. Still trying

addlistener avatar Jul 27 '24 08:07 addlistener

I needed to select a node after it was added and came across this thread. My solution was to watch for state changes in the nodes list and select the node that was added to the list. Here is the code. It can go in any React component descended from the editor. I put it in my Toolbox component.

  const { actions, nodes, connectors, } = useEditor((state) => ({
    nodes: state.nodes,
  }));
// Store the current set of node ids here
  const nodeIdsRef = useRef()

  useEffect(() => {
    const nodeIds = nodeIdsRef.current
    const currentNodeIds = Object.keys(nodes)
    if (!nodeIds) {
      // Store initial set of node ids
      nodeIdsRef.current = new Set(currentNodeIds)
    } else {
      // Get current node ids
      // Check if the size of the current node ids is different than the stored ids
      if (currentNodeIds.length !== nodeIds.size) {
        // It's different, so find out which node id was added
        const newNodeIds = new Set(nodeKeys)
        const diffIds = newNodeIds.difference(currentNodeIds)
        if (diffIds.size) {
          // select the node id that was added
          const node = [...diffIds][0]
          actions.selectNode(node)
        }
        nodeIdsRef.current = newNodeIds
      }
    }
  }, [nodes])

abird avatar May 09 '25 15:05 abird