107 lines
11 KiB
Markdown
107 lines
11 KiB
Markdown
# Knowledge — Figma AI Plugin
|
||
|
||
> Копилка находок и решений по проекту. Не наступай на грабли дважды.
|
||
> Пополняется по ходу разработки. Формат: проблема → решение (+ контекст/ссылка).
|
||
> Hermes имеет право править и дополнять этот файл самостоятельно (см. IDEA.md).
|
||
|
||
## Сборка / окружение
|
||
|
||
### TypeScript 7.x ломает `@create-figma-plugin/build`
|
||
- **Симптом:** `TypeError: Cannot read properties of undefined (reading 'getCurrentDirectory')` при `build-figma-plugin`.
|
||
- **Причина:** `build-figma-plugin` ожидает `ts.sys`, которого нет в TS 7.
|
||
- **Решение:** зафиксировать `typescript` на `~5.6.3` в `package.json` devDependencies.
|
||
- **Ссылка:** package.json
|
||
|
||
### tsconfig: не оверрайдить `jsx` на `react-jsx`
|
||
- **Симптом:** `error TS5089: Option 'jsxFactory' cannot be specified when option 'jsx' is 'react-jsx'`.
|
||
- **Причина:** базовый `@create-figma-plugin/tsconfig` уже задаёт `jsx: react` + `jsxFactory: h`.
|
||
- **Решение:** в проектном tsconfig только `extends` + добавляем `lib`/`types`. Не трогать `jsx`/`jsxFactory`. Preact `h` уже импортируется в `ui.tsx`.
|
||
- **Ссылка:** tsconfig.json
|
||
|
||
### `Text muted` не существует — используй `Muted`
|
||
- **Симптом:** `Property 'muted' does not exist on type ... Text`.
|
||
- **Решение:** для приглушённого текста брать компонент `<Muted>` из `@create-figma-plugin/ui`, а не проп `muted` у `<Text>`.
|
||
- **Ссылка:** src/ui.tsx
|
||
|
||
### Кнопка-иконка рядом с другими IconButton — бери РОДНУЮ иконку, не инлайн-SVG
|
||
- **Симптом:** иконка копирования рядом с кнопкой развернуть выглядит «другого размера»/тоньше, хотя `viewBox` один (`24×24`).
|
||
- **Причина:** `IconButton` из `@create-figma-plugin/ui` оборачивает иконку в `<div class="icon">` (`position:absolute`, БЕЗ задания размера) — размер берётся целиком из самой SVG. Родные иконки сета (`IconExpand24`, `IconCheck24`, `IconCopySmall24` и т.п.) — **залитые** (`fill="currentColor"`). Моя инлайн-SVG была **контурной** (`stroke`, `fill="none"`, `stroke-width=2`) — на том же `24×24` viewBox контурные lucide-иконки визуально кажутся меньше и легче, чем залитые соседки. Отсюда ощущение «разные размеры».
|
||
- **Правило (как делать правильно):**
|
||
1. Рядом с `IconButton` НИКОГДА не ставить текстовую `<Button>` с лейблом — только `IconButton` (пользователь прямо сказал: *"Очевидно же, что там достаточно кнопки иконки"*).
|
||
2. Брать иконку из родного сета `@create-figma-plugin/ui` (он же — адаптация lucide, залитые 24px): `IconCopySmall24`, `IconDuplicateSmall24`, `IconClipboardSmall24`, `IconCheck24`, `IconExpand24` и т.д. — гарантированно совпадёт по габариту и весу с соседями.
|
||
3. Если нужной иконки в сете нет (напр. copy/clipboard там только 16px `-small`), и ты делаешь инлайн-SVG — делай её **залитой** (`fill="currentColor"`, без `stroke`), `width/height=24`, `viewBox="0 0 24 24`, чтобы вес совпал с родными. Контурные (`stroke`) иконки lucide рядом с залитыми соседями НЕ класть.
|
||
4. Подтверждение действия (копирование) — переключать иконку на `IconCheck24` на ~1.2 с, без текстовой подписи.
|
||
- **Ссылка:** node_modules/@create-figma-plugin/ui/lib/components/icon-button/icon-button.module.css (`.icon` без размера), icon-24/icon-*-24.js (залитые SVG), src/ui.tsx (кнопки в тулбаре).
|
||
|
||
### Плагин не запускается в Figma — нет папки `build/` на Matebook
|
||
- **Симптом:** плагин не открывается / Figma молча ничего не делает при Run (ошибка не всегда видна).
|
||
- **Причина:** `manifest.json` указывает `main: build/main.js` и `ui: build/ui.js`, но в скопированной на Matebook папке папки `build/` нет (старая команда синхронизации исключала её через `--exclude build`).
|
||
- **Решение:** пересобрать на VPS (`npm run build`) и залить на Matebook ВЕСЬ проект вместе с `build/` — исключать только `node_modules` и `.git` (они для запуска в Figma не нужны, Figma исполняет собранные `build/*.js`). После распаковки проверить наличие `build/main.js` и `build/ui.js`.
|
||
- **Ссылка:** IDEA.md (раздел «Рабочий флоу», шаг 4), этот файл (раздел синхронизации через tar).
|
||
|
||
## Рабочий флоу (VPS → Matebook → Figma)
|
||
|
||
### Копия на Matebook через tar (rsync/scp с пробелами в пути падают)
|
||
- **Симптом:** `rsync: command not found` (на Windows), `scp: ambiguous target` (пробел в пути).
|
||
- **Решение:**
|
||
1. На VPS: `npm run build` (обязательно — иначе нет папки `build/`)
|
||
2. На VPS: `tar czf /tmp/x.tar.gz --exclude node_modules --exclude .git .` ← `build/` НЕ исключать!
|
||
3. `scp /tmp/x.tar.gz risow@10.200.201.5:D:/x.tar.gz`
|
||
4. На Matebook (PowerShell): `Set-Location 'D:/Figma Plugins/figma-ai-plugin'; tar xzf 'D:/x.tar.gz'`
|
||
- **Ловушка:** старая команда исключала `--exclude build` → в папке плагина на Matebook не было `build/`, и Figma не находила `build/main.js`/`build/ui.js` → плагин не запускался. См. gotcha «Плагин не запускается — нет `build/`».
|
||
- **Ссылка:** IDEA.md (раздел «Рабочий флоу»)
|
||
|
||
### Gitea push через токен в URL
|
||
- **Симптом:** `could not read Username` при `git push` (нет credential helper).
|
||
- **Решение:** remote как `http://<TOKEN>:@<host>/admin/figma-ai-plugin.git`. Токен должен иметь scope `write:repository` (без `write:user` создать репо нельзя — создавать через basic auth admin-ом).
|
||
- **Ссылка:** IDEA.md, Gitea http://x1qnvk08zec2u5cx6yh5iexh.155.212.186.39.sslip.io/admin/figma-ai-plugin
|
||
|
||
## ЭТАЛОН — ресайз и позиционирование (подтверждено пользователем)
|
||
|
||
> Зафиксировано после коммита `47cad79`. Любые правки в `ui.tsx`/`main.ts` сверять с этим.
|
||
> Среда замера: zoom=1, Figma UI виден (лимит окна ≈ 454×783 при full HD viewport).
|
||
|
||
### Модель координат
|
||
- `reposition(x,y)` / `getPosition().canvasSpace` — В canvas-space, отсчёт от **верха шапки** окна плагина (38px).
|
||
- `resize(w,h)` — в ЭКРАННЫХ px. Figma КЛАМПИТ до своего лимита при видимом UI (≈454×783), при спрятанном UI (Ctrl+\) — до всего viewport.
|
||
- Перевод: `wCanvas = w/zoom`, `hCanvasFull = (38+h)/zoom`.
|
||
|
||
### Периметральные ручки (8 фиолетовых div)
|
||
- **Drag** (>4px) = ресайз (single-/dual-axis). Якорь фиксируется в `RESIZE_START`, размер считается от якоря.
|
||
- **Чистый клик** (без движения):
|
||
- Угол **не в доке** → телепорт в угол (`dockWindow`).
|
||
- Угол **в доке** (край) → свободная ось = 50% viewport (`DOCK_HALF`), прижим в угол, выход из дока.
|
||
- Край → телепорт в край (`dockWindow`).
|
||
- Центр — ТОЛЬКО кнопкой в шапке (в периметр не входит).
|
||
|
||
### Что есть «док»
|
||
- **Док = окно растянуто у КРАЯ** (одна ось = 320, другая = max viewport). Углы и центр доком НЕ считаются.
|
||
- Краевые кнопки (▬▭▏▕) пишут `dockedPosRef`; углы/центр — нет.
|
||
|
||
### Ожидаемые значения (zoom=1, bounds 3513,-1774 · 908×872, видимый UI)
|
||
Реальный лимит: maxW≈454, maxH≈783. Растяжение срабатывает ТОЛЬКО по «своей» оси (другая клампится):
|
||
|
||
| Кнопка | Реал. W×H | x | y | relX | relY |
|
||
|---|---|---|---|---|---|
|
||
| ◤ top-left | 454×417 | 3513 | -1774 | 0 | 0 |
|
||
| ▬ top-center | 454×320 | 3740 | -1774 | 227 | 0 |
|
||
| ◥ top-right | 454×417 | 3867 | -1774 | 354 | 0 |
|
||
| ▏ center-left | 320×783 | 3513 | -1748 | 0 | 26 |
|
||
| ⊕ center | 454×417 | 3740 | -1565 | 227 | 209 |
|
||
| ▕ center-right | 320×783 | 4101 | -1748 | 588 | 26 |
|
||
| ◣ bottom-left | 454×417 | 3513 | -1357 | 0 | 417 |
|
||
| ▭ bottom-center | 454×320 | 3740 | -1260 | 227 | 514 |
|
||
| ◢ bottom-right | 454×417 | 3867 | -1357 | 354 | 417 |
|
||
|
||
- `▬ top-center`: relX=227 (окно ПО ЦЕНТРУ по X), relY=0 (прижат к верху).
|
||
- `▏ center-left`: relY=26, gapT=gapB=25 (вертикально ОТЦЕНТРИРОВАНО).
|
||
- Баг детектора: если видишь relX=0 на `▬` — окно прижалось к левому краю вместо центра (позиция считается от канона, а не реального размера). Фикс: `DOCK_REFINE` считает от реального `window.innerWidth/Height`.
|
||
|
||
### Кнопки в шапке
|
||
`[размер] [copy] [центр=IconDockToSide24] [развернуть/свернуть]`. Сетка 3×3 из тела УДАЛЕНА.
|
||
|
||
## Ресурсы (не терять)
|
||
- UI Storybook: https://yuanqing.github.io/create-figma-plugin/ui/
|
||
- Figma Plugin API docs: https://www.figma.com/plugin-docs/
|
||
- Исходный плагин «AI assistant» (движок): `D:\YandexDisk\Figma Plugins DEVs\AI assistant` (Matebook)
|