Skip to main content
Lewis_Healey
New Participant
June 8, 2022
Solved

Drag corner to resize plugin window

Is there documentation on how to drag and resize the plugin UI window, like Figma Tokens does it?
Screen Shot 2022-06-09 at 9.13.43 am

This topic has been closed for replies.
Gleb
GlebSolution
Power Member
June 8, 2022

It’s not a native feature, some plugins do it via cursor movement tracking and constantly sending updates to the Figma backend to then call figma.ui.resize() to increase/decrease the window size. You might be able to find helper libraries for this on google, I haven’t searched.

3 replies

Gleb
GlebSolution
Power Member
June 8, 2022

It’s not a native feature, some plugins do it via cursor movement tracking and constantly sending updates to the Figma backend to then call figma.ui.resize() to increase/decrease the window size. You might be able to find helper libraries for this on google, I haven’t searched.

Mohamed_Salem
New Member
April 25, 2024

you can use this react component
which will place an SVG on the bottom right side of the plugin

import React, { useRef } from 'react';

const ResizableCorner = () => {
  const cornerRef = useRef(null);

  const resizeWindow = (e) => {
    const size = {
      w: Math.max(50, Math.floor(e.clientX + 5)),
      h: Math.max(50, Math.floor(e.clientY + 5))
    };
    // Using window.postMessage here; adjust accordingly for your app context
    parent.postMessage({ pluginMessage: { type: 'resize', size: size }}, '*');
    // window.parent.postMessage({ pluginMessage: { type: 'resize', size: { w: width, h: height } } }, '*');

  };

  const handlePointerDown = (e) => {
    const corner = cornerRef.current;
    corner.onpointermove = resizeWindow;
    corner.setPointerCapture(e.pointerId);
    // console.log('handlePointerDown')
  };

  const handlePointerUp = (e) => {
    const corner = cornerRef.current;
    corner.onpointermove = null;
    corner.releasePointerCapture(e.pointerId);
    // console.log('handlePointerUp', corner, corner.releasePointerCapture(e.pointerId))

  };

  return (
    <div style={{ height: '100%', padding: '16px', boxSizing: 'border-box', fontFamily: 'sans-serif', fontSize: '12px', margin: '0' }}>
      <svg
        ref={cornerRef}
        id="corner"
        width="16"
        height="16"
        viewBox="0 0 16 16"
        fill="none"
        xmlns="http://www.w3.org/2000/svg"
        style={{ position: 'absolute', right: '1px', bottom: '2px', cursor: 'nwse-resize' }}
        onPointerDown={handlePointerDown}
        onPointerUp={handlePointerUp}
      >
        <path d="M16 0V16H0L16 0Z" fill="white" />
        <path d="M6.22577 16H3L16 3V6.22576L6.22577 16Z" fill="#8C8C8C" />
        <path d="M11.8602 16H8.63441L16 8.63441V11.8602L11.8602 16Z" fill="#8C8C8C" />
      </svg>
    </div>
  );
};

export default ResizableCorner;

and you can add this code to the plugin.ts file

const pluginDefaultHieght = 580;
const pluginDefaultWidth = 360;
const pluginMaxHieght = 1200;

figma.showUI(__html__,{width: pluginDefaultWidth, height: pluginDefaultHieght});
//Restore previous size when reopen the plugin
figma.clientStorage.getAsync('size').then(size => {
 	if(size) figma.ui.resize(size.w,size.h);
}).catch(err=>{});

figma.ui.onmessage = async (pluginMessage) => {
	switch (pluginMessage.type) {
		case "resize":
                        // if you need to set some limitation
			if (pluginMessage.size.h > pluginMaxHieght) {
				pluginMessage.size.h = pluginMaxHieght
			} else if (pluginMessage.size.h < pluginDefaultHieght ) {
				pluginMessage.size.h = pluginDefaultHieght
			}
                        figma.ui.resize(pluginMessage.size.w,pluginMessage.size.h);
			figma.clientStorage.setAsync('size', pluginMessage.size).catch(err=>{console.log(err)});

			break;
		}

Askenback
New Member
August 26, 2024

In order to use the above code in my plugin I had to adjust the markup slightly by removing the div and adding zIndex. But then it worked perfectly. Thanks @Mohamed_Salem! 🙏

return (
      <svg
        ref={cornerRef}
        id="corner"
        width="16"
        height="16"
        viewBox="0 0 16 16"
        fill="none"
        xmlns="http://www.w3.org/2000/svg"
        style={{ position: 'absolute', right: '1px', bottom: '2px', cursor: 'nwse-resize', zIndex: 100001 }}
        onPointerDown={handlePointerDown}
        onPointerUp={handlePointerUp}
      >
        <path d="M16 0V16H0L16 0Z" fill="#FFF" />
        <path d="M6.22577 16H3L16 3V6.22576L6.22577 16Z" fill="#8C8C8C" />
        <path d="M11.8602 16H8.63441L16 8.63441V11.8602L11.8602 16Z" fill="#8C8C8C" />
      </svg>
  );