Tokens

Экспорт переменных и стилей

Как из JSON-токенов создаются переменные и стили Figma: коллекции и режимы в Collection Settings, окно Export to Figma, настройки экспорта, чтение результата, повторный экспорт без дубликатов, ссылки между коллекциями и библиотеками.

Export variables & styles создаёт и обновляет переменные и стили Figma по файлам токенов. Простые токены становятся переменными: Color, Number, String, Boolean, Timing и Easing. Составные токены становятся стилями: заливки, эффектов, текста и сеток. Экспорт можно повторять сколько угодно: плагин помнит, какая переменная какому токену принадлежит, и обновляет её, а не создаёт заново.

Перед первым экспортом: коллекции и режимы

Переменные Figma живут в коллекциях, у коллекции может быть несколько режимов, например Light и Dark. Какие файлы токенов попадают в какую коллекцию и режим, задаёт config.json в папке токенов. Редактировать его удобнее в окне Collection Settings, кнопка внизу дерева файлов.

Collection Settings: группы, список коллекций с числом режимов и файлов, кнопки создания группы и коллекции.

В окне можно:

  • создать коллекцию кнопкой Collection и режим внутри неё, назначить режиму файлы;
  • перетаскивать коллекции и режимы, меняя их порядок в конфигурации; существующие объекты в Figma от этого не перемещаются;
  • отключить коллекцию, режим или файл, не удаляя его из конфигурации;
  • добавить ссылку на другую коллекцию или библиотеку для разрешения алиасов;
  • объединить коллекции в группы: группа соответствует отдельному файлу Figma, в который экспортируется своя часть токенов, например Core и Components.

Тот же config.json в JSON:

JSON
{
  "$schema": "sxl-studio/config",
  "$version": "1.0",
  "settings": { "remBase": 16, "autoExportOnPull": false },
  "collections": [
    {
      "name": "Primitives",
      "hiddenFromPublishing": true,
      "modes": [
        { "name": "Default", "files": { "colors.json": "enabled", "spacing.json": "enabled" } }
      ]
    },
    {
      "name": "Semantic",
      "ref": [{ "type": "local", "collection": "Primitives" }],
      "modes": [
        { "name": "Light", "files": { "semantic-light.json": "enabled" } },
        { "name": "Dark", "files": { "semantic-dark.json": "enabled" } }
      ]
    }
  ]
}
ПолеЧто значит
settings.remBaseБазовый размер для пересчёта rem, em и процентов в пиксели, по умолчанию 16. Число или ссылка на токен "{core.font.base}"; задаётся в окне экспорта, поле rem base
settings.autoExportOnPullЗапускать экспорт автоматически после каждого Pull из Git
collections[].nameИмя коллекции в Figma, должно быть уникальным
collections[].enabledfalse исключает коллекцию из экспорта
collections[].hiddenFromPublishingКоллекция создаётся, но не публикуется в библиотеке. Удобно для примитивов
collections[].refГде искать цели ссылок из другой коллекции, см. ниже
modes[].name, modes[].enabledИмя режима в Figma и его включение
modes[].filesФайлы режима со статусом enabled, disabled или source

Коллекции экспортируются в порядке зависимостей: коллекция, которая ссылается на другую локальную коллекцию через ref, обрабатывается после неё, независимо от порядка в config.json, поэтому первый экспорт в пустой файл завершается за один прогон. Новые коллекции по-прежнему появляются в панели Variables в порядке вашего конфига.

Файл со статусом source сам переменных не создаёт: его токены участвуют в формулах и в вычислении значений и типов. Чистая ссылка {путь} на токен, который есть только в файле source, сама по себе не экспортируется: переменной для неё в этом файле Figma нет, и токен пропускается с причиной alias target … not found, остальные экспортируются. Если цель — переменная библиотеки, объявите у коллекции ref типа library, см. ниже.

Файлы разных режимов содержат одни и те же пути токенов с разными значениями: text.primary в semantic-light.json и в semantic-dark.json. Если в каком-то режиме токена нет, переменная всё равно создаётся, а значение для этого режима подставит Figma; в отчёте экспорта такие пропуски перечислены.

Как экспортировать

  1. Внизу дерева нажмите Export variables & styles. Откроется окно Export to Figma с четырьмя сворачиваемыми блоками: Collections, What to export, Export settings и Delete variables & styles. Список и кнопка Export появляются после загрузки сохранённых настроек, обычно мгновенно.
  2. В блоке Collections отметьте коллекции. Галочка в заголовке выбирает все, поле Filter by name… ищет по имени, переключатель Show selected only оставляет в списке только выбранные. Над списком закреплена строка Selected: N of M с именами выбранных коллекций.
  3. В блоке What to export оставьте включёнными нужные типы переменных и стилей.
  4. При необходимости измените Export settings, для обычного экспорта менять ничего не нужно.
  5. Нажмите Export. В строке внизу окна указано, сколько коллекций и типов выбрано.

Во время экспорта уведомление показывает ход: полоса прогресса, счётчик «N / всего» и текущую стадию. Кнопка Cancel export останавливает экспорт: плагин дописывает текущую переменную, сохраняет служебный файл для уже записанного, пропускает удаления, сортировку и стили и показывает Export cancelled с числом созданных и обновлённых переменных. Повторный экспорт после отмены продолжает с того же места.

Окно Export to Figma: секция Collections с поиском и группами коллекций.

Типы переменных и стилей, начало настроек экспорта.

После экспорта откройте панель Variables в Figma: коллекции, режимы и переменные появятся там, стили в панели стилей. Повторный экспорт обновляет только то, что изменилось в JSON или было изменено вручную в Figma.

Типы

СекцияПереключатели
VariablesColor, Number, String, Boolean, Timing, Easing
StylesFill (включая изображения), Gradient, Typography, Blur (оба вида размытия), Shadow, Effects, Glass, Grid

Все переключатели включены по умолчанию. Выключите тип, чтобы пропустить его целиком, например экспортировать только переменные без стилей.

Export Settings

НастройкаЧто делаетКогда включать
Apply codeSyntax & scopesЗаписывает в Figma scopes, code syntax и флаг скрытия из $extensions, а также блок Code Syntax в описаниях стилей. Выключена по умолчанию. Эти настройки, изменённые в Figma вручную, возвращаются к JSON, когда вместе с ней включён Force update allВключите, когда нужно обновить эти настройки вместе со значениями
Force update allПриводит файл Figma точно к тому, что задано в JSON, не меняя идентификаторов: заново проверяет каждую переменную и стиль и удаляет всё, чего нет во включённом JSON. Перед удалением спрашивает подтверждение. Подробности нижеКогда файл Figma должен полностью совпасть с репозиторием
Delete orphaned variables & stylesУдаляет только то, что SXL экспортировал раньше и чего больше нет в JSON, в выбранных коллекциях и выбранных типах. Созданное вручную не трогает. Перед удалением спрашивает подтверждение. НеобратимоКогда переименования и удаления в JSON закончены и Figma должна им соответствовать
SortВыстраивает локальные стили и их папки в порядке исходных файлов, сохраняя идентификаторы и привязкиКогда изменили порядок стилей в файлах токенов

Готовые сочетания:

  • Ежедневный экспорт: всё по умолчанию. Переменные и стили добавляются и обновляются, ничего не удаляется.
  • Навести порядок: Sort включён, остальное по умолчанию.
  • Синхронизировать удаления: Delete orphaned variables & styles включён на один запуск. Уходит только то, что экспортировал SXL и чего больше нет в JSON.
  • Привести файл к репозиторию: Force update all включён на один запуск, затем выключите. Плагин покажет список удаляемого и дождётся подтверждения.

Sort не удаляет и не пересоздаёт объекты. Figma позволяет плагинам перемещать существующие стили и их папки, но не даёт способа переставить существующие коллекции, моды или переменные. Поэтому изменение их порядка в Collection Settings или JSON не переставляет их в Figma. Итоговый порядок отображения определяет Figma. Порядок существующих коллекций, модов и переменных задавайте вручную в Figma.

Diff-ID

Под переключателями блока Export settings находится подблок Diff-ID: память плагина о том, какой объект Figma принадлежит какому токену. Эти действия не запускают экспорт; подтверждение спрашивается в окне плагина.

ДействиеЧто делает
Clean up Diff-ID, кнопка Clean upУбирает записи о сгенерированных компонентах, которых больше нет в Figma: заменённых новой копией и тех, у кого нет JSON-композиции. То же самое происходит автоматически при экспорте с Delete или Force. Та же кнопка есть в окне Local Workspace, секция Workspace tools
Reset Diff-ID for one collection…, список Collection и кнопка Reset…Забывает идентификаторы одной коллекции. Следующий экспорт заново подключает её переменные по имени; переименованные переменные создаются заново
Reset Diff-ID…, кнопка Reset…Забывает все идентификаторы этого файла Figma. Следующий экспорт заново подключает переменные и стили по имени; переименованные объекты создаются заново, а связи композиций теряются. До этого экспорта в Figma ничего не меняется

Что обновляется и что удаляется

Любой экспорт, с любыми настройками, возвращает к JSON то, что изменили в Figma вручную: имена коллекций, режимов, переменных и стилей, значения переменных и содержимое стилей. Идентификаторы при этом сохраняются, поэтому привязки слоёв не теряются.

НастройкиЧто делает экспорт
Delete и Force выключеныДобавляет и обновляет переменные и стили. Ничего не удаляет; в служебном файле diff-id записи только добавляются и обновляются
Delete orphaned variables & stylesДополнительно удаляет то, что SXL экспортировал раньше (это записано в diff-id) и чего больше нет в JSON, внутри выбранных коллекций и выбранных типов переменных и стилей. Коллекция или режим, убранные из конфигурации, считаются выбранными. Не удаляет объекты, созданные вручную, и не удаляет коллекции, режимы и файлы, отключённые в конфигурации
Force update allПриводит файл Figma точно к JSON без смены идентификаторов. Проверяет каждый объект; совпадающее значение не перезаписывается, поэтому на уже синхронизированном файле результат — 0 создано, 0 обновлено, 0 удалено. Удаляет всё, чего нет во включённом JSON: остатки прежних экспортов, созданные вручную коллекции, режимы, переменные и стили, а также то, что задано только отключёнными в конфигурации коллекциями, режимами и файлами. Записи удалённых объектов убираются из diff-id

Границы Force update all:

  • Если выбрана только часть коллекций, очистка идёт только внутри выбранных. Целые посторонние или отключённые коллекции и посторонние стили удаляются, только когда экспортируются все коллекции; в списке перед удалением сказано, что осталось непроверенным.
  • В файле, для которого ещё нет diff-id, Force не удаляет созданное вручную: первый экспорт подключает существующие объекты по имени.
  • Стили, которые используются композициями, не удаляются ни при каких настройках.
  • Объекты из библиотек и типы, выключенные в What to export, не затрагиваются никогда.

Подтверждение удаления

Если экспорт собирается что-то удалить, он сначала анализирует файл, ничего не меняя, и показывает в уведомлении список по группам:

ГруппаЧто в ней
Removed from JSON (tracked)То, что SXL экспортировал раньше и чего больше нет в JSON
Foreign — not created by SXLСозданное вручную, только при Force update all
Disabled in configЗаданное только отключёнными коллекциями, режимами и файлами, только при Force update all
KeptЧто остаётся, с причиной

Под списком две кнопки: Delete N objects and export и Cancel export. Отмена ничего не меняет. Удаляется только то, что было в подтверждённом списке: объект, который стал лишним уже после подтверждения, остаётся, и экспорт сообщает о нём предупреждением. Если удалять нечего, вопроса нет. Автоматический экспорт после Pull никогда не удаляет и не спрашивает.

Экспорт с включённым Delete или Force заодно забывает записи Diff-ID о сгенерированных компонентах, которых больше нет. Запись забывается, только когда компонента нет в файле Figma и в рабочей области нет JSON-композиции, из которой он создан. Пока JSON существует, запись остаётся: после восстановления из истории версий Apply снова найдёт компонент, а новый Generate сам свернёт старую запись. Плагин не узнаёт об удалении компонента в момент удаления, проверка идёт при экспорте с Delete или Force и по кнопке Clean up Diff-ID; Generate и Apply записи не забывают. В списке такие записи показаны информационными строками с пометкой Diff-ID: «Forget the Diff-ID record of component "X": it no longer exists in Figma and has no composition JSON». Они не входят в число удаляемых объектов и сами по себе вопроса не вызывают: из файла Figma ничего не удаляется. Записи забываются только после успешного экспорта; при отмене, ошибке или выключенных Delete и Force они остаются. В результате экспорта это информационная запись, не предупреждение.

Для агентов через Bridge 1.11 и новее: preview_export_variables возвращает тот же список без записи в файл, забываемые записи компонентов — в deletionPlan.forgottenCompositionRecords[] с полями rootId и name, а export_variables, которому нужно что-то удалить, требует confirmDestructive: true; без него ничего не меняется.

Destructive actions

Блок внизу окна удаляет коллекции переменных и группы стилей из файла Figma целиком. В обоих списках есть поиск и выбор нескольких элементов; кнопка называется Delete all … или Delete N selected …. Удаление необратимо: переменные, привязанные к слоям, теряют привязку. Перед массовым удалением сохраните версию файла Figma и закоммитьте токены.

Читаем результат

Панель Variables в Figma после экспорта: коллекция с режимами Light и Dark и группами color, radius и space, как в файлах токенов.

После экспорта плагин показывает уведомление с заголовком:

ЗаголовокЧто значит
Export completeВсё экспортировано
Export completed with N notice(s)Экспорт прошёл, есть замечания, например пропущенные ячейки режимов или токен, сохранённый как custom
Partial exportЧасть переменных или стилей не экспортирована. Раскройте Details, чтобы увидеть какие и почему
Export failedЭкспорт остановлен, ничего не изменено. Причина в деталях
Export cancelledЭкспорт остановлен кнопкой Cancel export. В подзаголовке указано, сколько переменных успело записаться

Кнопка Copy all копирует весь отчёт, Retry повторяет экспорт. Ошибка одного токена не останавливает остальные: неверное значение, неразрешённая ссылка или несовместимый тип пропускают только этот токен, а в отчёте указан его путь.

Замечания и ошибки перечислены пунктами: значок серьёзности (красный крест — ошибка, жёлтый треугольник — замечание, серый «i» — справочная строка), сначала ошибки, затем замечания. У пункта могут стоять метка коллекции или пути и число затронутых переменных или стилей (×N), а под ним — рекомендация «→ что сделать»; одинаковая рекомендация для нескольких пунктов показана один раз над списком. Список длиннее восьми пунктов сворачивается кнопкой Show N more.

Числа и формулы в полях стилей

Числовые поля стилей принимают формулы, например "{dim.px} / 3". Это поля теней, размытия и эффектов, count, gutterSize, sectionSize и offset сетки, fontSize, lineHeight, letterSpacing, paragraphSpacing, paragraphIndent и listSpacing типографики. Результат вычисляется и записывается числом, а в отчёте появляется замечание: привязать формулу к переменной Figma не может, поле держит не больше одной переменной. Чтобы сохранить связь, вынесите формулу в отдельный токен и сошлитесь на него. Формула с неизвестным операндом пропускает этот стиль с причиной, остальные экспортируются.

Литеральные числа в стилях принимают те же единицы, что и числовые токены, см. Dimension. em в lineHeight и letterSpacing считается от размера шрифта стиля: 1.5em — это 150 %, 0.02em — 2 %.

Поля стекла lightIntensity, refraction, dispersion и поля шума opacity, density хранят долю от 0 до 1. Ссылка на токен прозрачности в них сохраняет долю: 0.48 остаётся 0.48.

Стиль, который экспорт нашёл в файле по имени и подключил, считается в отчёте обновлённым, а не созданным.

Повторный экспорт без дубликатов

Если стиль (текстовый, заливка, градиент, тень, blur или сетка) ссылается на переменную, которой в Figma ещё нет (например, коллекция с ней ещё не экспортирована), стиль создаётся с литеральным значением, а в уведомлении появляется замечание с перечнем полей и переменных. Экспортируйте коллекцию с этими переменными и запустите обычный экспорт ещё раз: привязки восстанавливаются автоматически, ID стиля и его потребители сохраняются, Force update all не нужен.

Слой заливки, цвет которого привязан к переменной, может иметь свою opacity: экспорт проверяет записанное значение и при необходимости повторяет запись, поэтому прозрачность верна уже после первого экспорта. Blend mode у такого слоя Figma не хранит — экспорт оставляет NORMAL и добавляет замечание с именем слоя; чтобы сохранить blend mode, задайте цвет слоя литералом.

Плагин хранит связь между токенами и переменными этого файла Figma в служебном файле diff-id.<ключ файла>.json рядом с токенами. Благодаря ему:

  • изменение значения обновляет ту же переменную;
  • переименование токена в JSON переименовывает переменную, если замену можно доказать однозначно;
  • удалённый из JSON токен не удаляет переменную, пока не включён Delete orphaned variables & styles или Force update all;
  • ссылки между переменными сохраняются.

Файл синхронизируется через Git вместе с токенами: не редактируйте его вручную и не удаляйте, а если используете Prettier, добавьте diff-id.*.json в .prettierignore. Если связь потерялась, например при копировании файла Figma, обычный экспорт сам находит единственную подходящую переменную с тем же именем и типом и подключает её. Неоднозначные совпадения плагин не выбирает наугад и сообщает о них.

Reset Diff-ID… в подблоке Diff-ID окна Export разрывает связь для всего файла, Reset Diff-ID for one collection… там же — для одной коллекции. Сами переменные и стили в Figma при этом не меняются. Следующий экспорт не создаёт дубликатов: он заново подключает существующие переменные по имени и типу, а стили по имени и виду, и записывает их идентификаторы. Нужен редко, например когда служебный файл перестал соответствовать файлу Figma.

Ссылки между коллекциями и библиотеками

Токен может ссылаться на токен из другой коллекции: {color.blue.500} в семантической коллекции указывает на примитив. Чтобы экспорт нашёл цель, у коллекции должна быть ссылка ref:

JSON
{ "name": "Semantic", "ref": [{ "type": "local", "collection": "Primitives" }] }

Для переменных из подключённой библиотеки Figma указывается имя библиотеки и коллекции:

JSON
{ "ref": [{ "type": "library", "library": "Design System Core", "collection": "Primitives" }] }
ПолеЗначение
typelocal для коллекции этого файла, library для библиотеки
collectionИмя коллекции
libraryИмя библиотеки Figma, только для library
modeИмя режима, необязательно

Ссылка задаётся у коллекции целиком или у отдельного режима. Ссылка на библиотеку — точный адрес: плагин ищет переменную только в указанной библиотеке и коллекции и не подменяет её похожей из другого места. Библиотека должна быть подключена к файлу.

Объявляйте ref для каждой коллекции, на токены которой есть ссылки, даже если она экспортируется в этом же прогоне. Без объявления цель, которой ещё нет в текущем экспорте, может найтись в опубликованной библиотеке по памяти diff-id других файлов: переменная сошлётся на библиотеку, а к локальной переменной её перепривяжет только следующий экспорт.

Совместимость ссылки проверяется по виду переменной Figma: number может ссылаться на borderWidth, потому что обе становятся переменными Number, а ссылка с number на color будет пропущена с предупреждением.

Автоматический экспорт после Pull

Если в config.json задано "autoExportOnPull": true, плагин экспортирует токены сразу после каждого Pull из Git с настройками по умолчанию: все типы включены, настройки экспорта выключены, в том числе Apply codeSyntax & scopes. Такой экспорт никогда ничего не удаляет и не спрашивает подтверждения.

Если что-то не работает

Что случилосьЧто делать
Переменные дублируются после экспортаСвязь потеряна или неоднозначна: две переменные с одним именем. Удалите лишнюю в Figma и повторите экспорт
Значение не обновилосьВыполните экспорт с Force update all. Если он соберётся что-то удалить, сначала покажет список и дождётся подтверждения
Ссылка не разрешаетсяПроверьте ref у коллекции, точные имена библиотеки и коллекции и статус файла с целью: для чистой ссылки цель должна быть в файле enabled или в библиотеке из ref, одного файла source недостаточно
Коллекции, моды или переменные не переместились после SortFigma не предоставляет плагинам такую операцию. Sort меняет только порядок стилей и их папок
Токен сохранён как custom и не экспортированЗначение не похоже ни на один тип. Задайте $type явно
В Local Workspace экспорт не запускаетсяДля записи служебного файла Diff-ID нужен существующий файл в папке. Сделайте первый экспорт из Git-источника или проверьте, что Bridge активен

Связанные страницы