Storybook Addon
@sxl-studio/storybook-addon — панель Storybook, отображающая дизайн-контекст Figma из SXL Studio Code Connect.
Overview
@sxl-studio/storybook-addon — кастомный аддон для Storybook, опубликованный в npm. Добавляет панель SXL Studio в Storybook, которая отображает дизайн-контекст Figma для каждой story — Figma Embed, информацию о компоненте, резолвнутый JSON композиции, статус токенов и бейджи готовности.
Аддон читает данные из файла реестра diff-code-connect.<fileKey>.json, генерируемого плагином SXL Studio для Figma, — дизайнеры и разработчики используют единый источник истины.
Ключевые возможности
- Название компонента + дата обновления — заголовок панели с кнопкой «Open in Figma»
- Бейджи Tokens / Status — цветовые индикаторы состояния
- Description — описание компонента из Figma
- Figma Design Embed — интерактивный iframe со ссылкой «Open in Figma Dev Mode»
- Индикатор подключения во вкладке — точка рядом с
SXL Studioпоказывает, связан ли текущий story - API Contract — Component Properties и количество вариантов из Figma
- Code Connect — Import path, файлы реализации (фреймворк + путь), шаблон кода
- Composition JSON — блок JSON с копированием, состояниями загрузки и диагностикой источника
Установка
npm i -D @sxl-studio/storybook-addon
Поддерживаемые версии Storybook: v9, v10.
Регистрация аддона (main)
Аддон должен оказаться в массиве addons. Preset подтягивается автоматически (см. ниже), отдельно импортировать его в main не нужно, если всё работает — только строка пакета в addons.
Вариант A — один файл конфигурации
Подходит, если весь Storybook настроен в вашем репозитории без общего пресета.
// .storybook/main.ts
export default {
addons: [
"@storybook/addon-docs",
"@sxl-studio/storybook-addon",
],
};
Вариант B — общий конфиг из пакета (design system, монорепозиторий)
Часто main и preview импортируются из внутреннего пакета (@scope/storybook-vue, @your-org/storybook-config и т.д.). Важно не заменить список аддонов целиком, а дописать SXL к уже существующим:
// .storybook/main.ts
import sharedMain from "@your-org/storybook-vue/main";
const config = {
...sharedMain,
addons: [...(sharedMain.addons ?? []), "@sxl-studio/storybook-addon"],
};
export default config;
sharedMain.addons ?? []сохраняет аддоны из shared-конфига.@sxl-studio/storybook-addonдобавляется в конец (порядок обычно не критичен; при конфликтах см. README пакета).
Перезапустите dev-сервер Storybook после изменения main/preview.
Пресет (v1.1+): не привязан к одной структуре папок
Пакет объявляет preset (Storybook подключает его через поле storybook.preset в package.json, когда аддон указан в addons). Фиксированная раскладка монорепозитория не требуется.
- CSP — для Figma Embed в панели менеджера в конфиг Vite добавляются заголовки
frame-srcдляhttps://www.figma.com. - Composition JSON — если относительно каталога Storybook (или на два уровня выше
.storybook) существует папкаtokens/tokensс выгрузкой токенов из плагина, файлы отдаются по/sxl-tokens/…в dev и копируются в статику приstorybook build. Тогда полеcompositionFilePathиз реестра подхватывается без ручной настройки Vite. - Имя файла реестра — плагин может записывать
diff-code-connect.<figmaFileKey>.json. Если вpreviewимпортируется стабильное имя вродеdiff-code-connect.SXL-Components.json, а такого файла нет, но в том же каталоге есть другойdiff-code-connect.*.json, пресет добавляет resolve.alias в Vite (при нескольких кандидатах берётся первый по сортировке имён). Альтернатива — импортировать фактический файл илиfromDiffCodeConnect(raw). - Без локальной папки — composition запрашивается по Git из
repository.urlв реестре (как настроено в плагине), если raw-доступен.
Если preset не подхватился автоматически, в addons можно явно указать @sxl-studio/storybook-addon/preset (см. README npm-пакета).
Реестр Code Connect в preview
Плагин записывает реестр в файл вида diff-code-connect.<figmaFileKey>.json. Его нужно один раз подключить в parameters.sxl.registry. Путь к файлу зависит от вашего репозитория (корень приложения, папка tokens/tokens, CI-артефакт и т.д.) — главное, чтобы JSON попал в бандл Storybook (импорт из preview или копирование в staticDirs).
fromDiffCodeConnect или сырой JSON
fromDiffCodeConnect(raw)— явно приводитdiff-code-connect/ v2components[]к формату аддона. Используйте, если хотите единообразный слой или смешиваете форматы.- Прямой импорт JSON в
registry— для актуального файла из плагина обычно достаточно: аддон понимает структуру реестра.
Вариант A — минимальный preview
// .storybook/preview.ts
import raw from "../path/to/diff-code-connect.<fileKey>.json";
import { fromDiffCodeConnect } from "@sxl-studio/storybook-addon";
export default {
parameters: {
sxl: { registry: fromDiffCodeConnect(raw) },
},
};
Сырой объект:
import registry from "../path/to/diff-code-connect.<fileKey>.json";
export default {
parameters: {
sxl: { registry },
},
};
Вариант B — поверх shared-preview (как в монорепозитории)
Если у вас уже есть sharedPreview с декораторами и глобальными параметрами, смержите parameters, чтобы не потерять настройки shared-слоя. Поле sxl задаётся рядом с остальными:
// .storybook/preview.ts
import sharedPreview from "@your-org/storybook-vue/preview";
import registry from "../../tokens/tokens/diff-code-connect.<fileKey>.json";
export default {
...sharedPreview,
parameters: {
...sharedPreview.parameters,
sxl: { registry },
},
};
При необходимости добавьте свои globalTypes, initialGlobals и т.д. рядом — на работу SXL это не влияет, если parameters.sxl.registry присутствует.
Практическое замечание: имя файла содержит <fileKey> из Figma; при смене файла в Figma плагин может выдать новое имя — обновите импорт или используйте стабильное имя импорта при условии, что пресет аддона может сопоставить его с единственным diff-code-connect.*.json в каталоге tokens/tokens (см. раздел про пресет выше).
Автоматический матчинг
Аддон автоматически пытается сопоставить текущую story с записью реестра:
- Сначала учитываются явные параметры story:
sxl.component/sxl.figmaNodeId(если заданы). - Иначе выполняется эвристика по контексту story (
title, имя story, путь файла): имя из реестра (displayName) должно пройти порог уверенного совпадения. Одна запись в реестре не подставляется ко всем stories — на чужих компонентах будет сообщение об отсутствии интеграции. - Редактировать story-файлы не обязательно, если имена в реестре и в Storybook согласованы.
Для stories без подходящей записи в реестре панель показывает, что интеграция Storybook в плагине для этого компонента не настроена («No Figma integration…»).
Ручная привязка (опционально)
При необходимости (когда автоматический матчинг не срабатывает) можно явно указать компонент в per-story параметрах:
export const Default = {
parameters: {
sxl: { component: "WButton" },
},
};
Прямые параметры (без реестра)
Для быстрого прототипирования или малого числа stories:
export const Default = {
parameters: {
sxl: {
figmaUrl: "https://www.figma.com/design/ABC123?node-id=1-2",
description: "Основная кнопка действия",
tokensBool: "true",
readiness: "ready-for-dev",
},
},
};
Данные из плагина
Плагин SXL Studio записывает следующие данные в реестр, которые аддон отображает:
| Поле в плагине | Что отображается в Storybook |
|---|---|
| Display Name | Заголовок панели (название компонента) |
| Updated At | Дата последнего обновления привязки |
| Design Embed | Центрированный iframe Figma + кнопка «Open in Figma Dev Mode» |
| Composition JSON | Резолвнутый JSON (inline/map/resolver/fetch), состояния load/error, кнопка Copy JSON |
| Metadata / Description | Блок описания компонента |
| Tokens (True/False) | Бейдж tokensBool (true/false) с legacy fallback от tokenStatus |
| Status | Бейдж: Complete / Ready for Dev / In Progress / Backlog |
| Import Path | Import-путь компонента в секции «Code Connect» |
| Files | Файлы реализации с фреймворком |
| Snippet Template | Шаблон кода в блоке кода |
Секция Storybook Integration в плагине имеет свою кнопку Connect — независимую от кнопки Code Connect.
Справочник параметров
| Параметр | Тип | Где задаётся |
|---|---|---|
sxl.registry | SxlRegistry | глобально в preview.ts |
sxl.component | string | per-story |
sxl.componentName | string | per-story (алиас для component) |
sxl.figmaNodeId | string | per-story |
sxl.figmaUrl | string | per-story (manual) |
sxl.description | string | per-story override |
sxl.tokensBool | "true" | "false" | явный override бейджа Tokens |
sxl.tokenStatus | "assigned" | "partial" | "none" | legacy-override (маппится в tokensBool) |
sxl.readiness | "complete" | "ready-for-dev" | "in-progress" | "backlog" | per-story override |
sxl.designEmbed | boolean | per-story override |
sxl.compositionJson | boolean | per-story override |
sxl.metadata | boolean | per-story override |
sxl.compositionSources | Record<string, string> | map compositionFilePath → raw JSON |
sxl.compositionFetchBaseUrl | string | базовый URL для fetch по compositionFilePath |
sxl.compositionDevProxyPrefix | string | same-origin proxy prefix для private Git/CORS |
sxl.resolveComposition | (path) => Promise<string | undefined> | кастомный resolver до fetch-fallback |
sxl.debugFigmaEmbed | boolean | debug-логи embed (resolved, iframe-load, iframe-error) |
sxl.embedUrlMode | "auto" | "embed-kit-2" | "legacy" | стратегия URL embed (auto: Safari+localhost → legacy, non-localhost браузеры → Embed Kit 2.0) |
Диагностика Embed (CSP)
Если iframe Figma пустой:
- Включите
parameters.sxl.debugFigmaEmbed: trueи проверьте события[SXL Studio addon] Figma embedв консоли браузера. - В Vite-конфиге Storybook смержите CSP через
mergeSxlFigmaFrameSrcHeaderиз@sxl-studio/storybook-addon/preset. - Проверьте, что ссылка Open embed in new tab открывается с тем же URL.
- Аддон поддерживает оба формата: Embed Kit 2.0 (
embed.figma.com) и legacy (www.figma.com/embed). В режимеautoдля Safari+localhost используется legacy, а для Safari/Chromium/Firefox на non-localhost — Embed Kit 2.0. - Аддон подставляет
embed-hostиз текущего host Storybook (например,localhost:6006илиstorybook.company.com) для стабильной идентификации локации. - Если логин запрашивается при каждом обновлении страницы, разрешите third-party cookies и Storage Access для
figma.comв настройках браузера (авторизация embed контролируется privacy-политикой браузера).
Архитектура
Figma Plugin (Code Connect + Storybook Integration)
│
▼
diff-code-connect.<fileKey>.json ← реестр в Git
│
▼
fromDiffCodeConnect() ← конвертер в аддоне
│
▼
Storybook parameters.sxl.registry ← загружается в preview.ts
│
▼
Панель SXL Studio в Storybook ← рендерит данные для story
Аддон — чистый потребитель данных. Он не модифицирует ни Figma-файл, ни реестр. Все записи происходят в плагине.
Структура пакета
@sxl-studio/storybook-addon
├── src/
│ ├── manager.tsx — регистрация панели
│ ├── preset.ts — viteFinal (CSP, локальные tokens, alias), staticDirs, managerEntries
│ ├── components/
│ │ └── SxlPanel.tsx — UI панели (useParameter hook)
│ ├── convert.ts — конвертер fromDiffCodeConnect
│ ├── types.ts — SxlRegistry, SxlRegistryEntry и т.д.
│ ├── constants.ts — ADDON_ID, PANEL_ID, PARAM_KEY
│ └── index.ts — barrel-экспорты
Публикация
Аддон публикуется под npm scope @sxl-studio:
npm publish --access public
Peer dependencies: storybook ^9.0.0 || ^10.0.0, react.
Краткий чеклист
- Установить
@sxl-studio/storybook-addonв devDependencies. - В
.storybook/main.tsдобавить пакет вaddons(к минимальному списку или через...(sharedMain.addons ?? [])). - В
.storybook/preview.tsзадатьparameters.sxl.registry(импорт JSON и/илиfromDiffCodeConnect). - Убедиться, что в реестре из плагина заполнены нужные поля (в т.ч.
$figmaFileKeyдля embed). - Перезапустить Storybook.
Связанные разделы
- Code Connect & Storybook — полный гайд настройки со стороны плагина
- Bridge — MCP/WS/HTTP соединение с Figma
- Transformer — CLI трансформер токенов