feat: show live window x/y/size debug readout inside plugin

- main.ts: track lastSize; GET_WINDOW_INFO handler returns x/y via
  figma.ui.getPosition().canvasSpace (typed as any) + stored width/height
- ui.tsx: WINDOW_INFO listener, '🔍 Инфо' button, render x/y/w/h block
This commit is contained in:
Hermes Agent committed 2026-09-09 13:12:17 +02:00
1 parent bc9b2e60e9
commit ecbbd5d8c1
2 files changed
+48 -1

No files matched your search

+26
View File
@@ -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)' })
}
+22 -1
View File
@@ -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 () {
<Button onClick={function () { dockWindow('left') }}>◧ Лево</Button>
<Button onClick={function () { dockWindow('center') }}>▣ Центр</Button>
<Button onClick={function () { dockWindow('right') }}>Право ◨</Button>
<Button onClick={requestWindowInfo}>🔍 Инфо</Button>
</div>
<div
style={{
@@ -100,6 +114,13 @@ function Plugin () {
<Text style={{ fontSize: '13px', fontWeight: 600 }}>Hello, Figma ✦</Text>
<VerticalSpace space="small" />
<Muted>AI assistant (MVP) — bootstrap</Muted>
{windowInfo != null && (
<div>
<VerticalSpace space="small" />
<Muted>x: {windowInfo.x} y: {windowInfo.y}</Muted>
<Muted>w: {windowInfo.width} h: {windowInfo.height}</Muted>
</div>
)}
</div>
</Container>
{/* Декоративная иконка drag-хендла в правом нижнем углу (как в старом плагине).