Is there any way to get the position of ui plugin

I embed an iframe in the ui html to support hot update, but when I drag and drop, e.clientX and e.clientY have a little problem. Is there a way to get the location information of the UI plugin.

issue: The drag event happens inside my nested iframe, clientX and clientY are calculated relative to the superior iframe (Inner Plugin Iframe), this value seems to be wrong. I may need to add this value to the UI plugin’s location.

drag-end-issue

If you don’t embed the iframe but write the drag and drop code directly in the ui html, it will work.

1 Like

Hi, supporting drag-and-drop from an externally hosted UI is different from doing it directly in the ui html – the latter resides in a null origin iframe so Figma can’t receive drop events directly from it.

For an externally hosted UI, you don’t need to postMessage with any event coordinates. Just subscribe to the drop event in your plugin sandbox code and handle the event normally.

In your UI, you can add any data you want to bring along in the dataTransfer object of the drag event:

elem.addEventListener('dragstart', (e) => {
  e.dataTransfer.setData("image/svg+xml", e.target.innerHTML);
})

and then in your plugin code, subscribe to the drop event:

figma.on('drop', (event: DropEvent) => {
  console.log('[plugin] drop received!!', event);
  const { items } = event;
  
  if (items.length > 0 && items[0].type === 'image/svg+xml') {
    const data = items[0].data

    const newNode = figma.createNodeFromSvg(data);
    newNode.x = event.absoluteX;
    newNode.y = event.absoluteY;

    figma.currentPage.selection = [newNode];
  }
  
  return false;
});

I’m not sure if the above answer solves the problem. I am experiencing the same issue. I have a nested iframe in which I am adding an event listener to trigger the “drop” event on the figma canvas. I register a listener in the iframe to handle the DropEvent returned by Figma. I am able to receive the drop event successfully (as outlined in the answer above, but the coordinates it returns are relative to the inner iframe, not the entire viewport).

From what I understand the drop API works like this:

  1. Send clientX/clientY from drop event
  2. Figma transforms clientX/clientY into Figma canvas coordinates
  3. Figma sends canvas coordinates back to client
  1. and 3) work successfully but the wrong coordinates are being sent in step 1). It seems figma expects clientX/clientY relative to the entire browser window. In my case, we are sending x/y relative to the plugin iframe. (e.g. dropping an element to the left of the iframe sends a negative X value, but it should be positive). I see that the sample plugin figma has successfully implements drop outside the plugin, I’m curious how you were able to send the right coordinates

Following up here, I don’t think browsers natively support drag and drop events from an externally hosted UI due to cross origin security issues. The drag/drop API you described for externally hosted UI works on Figma desktop, but not in Chrome