diff --git a/src/main.ts b/src/main.ts index fe237f3..1bac326 100644 --- a/src/main.ts +++ b/src/main.ts @@ -4,9 +4,14 @@ export default function () { // Глобальный ярлык relaunch в правой панели Figma (команда runAI из manifest.json) figma.root.setRelaunchData({ runAI: '' }) + // Последнее известное состояние окна (позиция в canvas-space + размер), + // чтобы UI могла запросить его через GET_WINDOW_INFO. + let lastSize = { width: 320, height: 200 } + // Ресайз окна плагина (drag за угол в UI -> useWindowResize -> RESIZE_WINDOW) on('RESIZE_WINDOW', function (windowSize: { width: number; height: number }) { const { width, height } = windowSize + lastSize = { width, height } figma.ui.resize(width, height) }) @@ -15,6 +20,7 @@ export default function () { // Ширину панелей Figma API не отдаёт, поэтому прижимаем к bounds видимой области. on('DOCK_WINDOW', function (payload: { position: 'left' | 'right' | 'center'; width: number; height: number }) { const { position, width, height } = payload + lastSize = { width, height } figma.ui.resize(width, height) const b = figma.viewport.bounds let x = b.x @@ -28,5 +34,25 @@ export default function () { figma.ui.reposition(x, y) }) + // UI запрашивает текущие x/y (canvas-space) и размеры окна для отладочного вывода. + on('GET_WINDOW_INFO', function () { + let x = 0 + let y = 0 + try { + // getPosition() есть в рантайме Figma, но отсутствует в @figma/plugin-typings + const pos = (figma.ui as any).getPosition() + x = Math.round(pos.canvasSpace.x) + y = Math.round(pos.canvasSpace.y) + } catch (e) { + // getPosition может быть недоступен в некоторых версиях — оставляем 0 + } + emit('WINDOW_INFO', { + x, + y, + width: lastSize.width, + height: lastSize.height + }) + }) + showUI({ width: 320, height: 200, themeColors: true, title: 'AI assistant (MVP)' }) } diff --git a/src/ui.tsx b/src/ui.tsx index 3bf4e18..855497b 100644 --- a/src/ui.tsx +++ b/src/ui.tsx @@ -10,7 +10,7 @@ import { IconCollapse24, useWindowResize } from '@create-figma-plugin/ui' -import { emit } from '@create-figma-plugin/utilities' +import { emit, on } from '@create-figma-plugin/utilities' import { h, Fragment } from 'preact' import { useState, useEffect } from 'preact/hooks' @@ -19,6 +19,7 @@ const MAX_WINDOW_SIZE = { width: 800, height: 800 } function Plugin () { const [currentWindowSize, setCurrentWindowSize] = useState(MIN_WINDOW_SIZE) + const [windowInfo, setWindowInfo] = useState<{ x: number; y: number; width: number; height: number } | null>(null) // Нативный drag-ресайз окна Figma (тянуть за правый нижний угол). // Опции min/max обязательны: без них хук берёт базу из window.innerWidth на момент @@ -50,6 +51,14 @@ function Plugin () { } }, []) + // Слушаем ответ от main с актуальными x/y (canvas-space) и размерами окна + useEffect(function () { + const off = on('WINDOW_INFO', function (info: { x: number; y: number; width: number; height: number }) { + setWindowInfo(info) + }) + return function () { off() } + }, []) + function toggleWindowSize () { const isMaximized = currentWindowSize.width >= MAX_WINDOW_SIZE.width && @@ -59,6 +68,10 @@ function Plugin () { emit('RESIZE_WINDOW', next) } + function requestWindowInfo () { + emit('GET_WINDOW_INFO') + } + function dockWindow (position: 'left' | 'right' | 'center') { emit('DOCK_WINDOW', { position, @@ -87,6 +100,7 @@ function Plugin () { +
Hello, Figma ✦ AI assistant (MVP) — bootstrap + {windowInfo != null && ( +
+ + x: {windowInfo.x} y: {windowInfo.y} + w: {windowInfo.width} h: {windowInfo.height} +
+ )}
{/* Декоративная иконка drag-хендла в правом нижнем углу (как в старом плагине).