FISYCO

Публичная бета
РазрывСтоимостьКак работаетПродуктБезопасность
Войти

Иконки из Figma в React: весь путь

6 мин чтения

Инженерия
A grid of icon tiles on a Figma-like canvas flowing into a code file card and a pull request card with a check mark

Набор иконок живёт в Figma, а продукт использует его в React. Между ними обычно стоит человек. Он выгружает SVG, переименовывает файлы, кладёт их в репозиторий и надеется, что больше ничего не поменялось. В этом руководстве мы проведём иконки из Figma в React по всему пути: от компонента иконки в Figma до смерженного pull request. На каждом шаге покажем, что получается на выходе.

Мы делаем FISYCO, который автоматизирует этот путь. Шаги ниже работают с любыми инструментами, а примеры взяты из реального вывода нашего генератора для трёх иконок.

Коротко
- Относитесь к иконкам как к данным: читайте их из Figma по ID узла, а не по имени файла. Тогда переименование останется переименованием, а не новой иконкой.
- Выберите для продукта один формат доставки: React-компоненты, один SVG-спрайт или пакет SVG-файлов. У каждого есть понятный лучший случай.
- Чистите каждый SVG дважды: санитизируйте на входе в систему и оптимизируйте при генерации кода.
- Доставляйте изменения pull request'ом с читаемым диффом и запускайте его по публикации библиотеки в Figma.

Шаг 1. Решите, что считать иконкой

В файлах Figma иконки лежат вперемешку со всем остальным, поэтому сначала определите границы. Направьте экспорт на страницы и секции с компонентами иконок, а не на весь файл. Секция на категорию, например Navigation, Status или Social, делает границы наглядными. Позже имя секции может стать частью пути в выводе.

Читайте компоненты, а не отдельные фреймы. Компонент сохраняет ID узла, когда его переименовывают или перетаскивают внутри файла. Имя же просто текст. От этого ID зависит всё дальнейшее: по нему вы отличаете «переименовали» от «удалили и добавили».

Шаг 2. Выгрузите SVG из Figma

REST API Figma рендерит узлы в изображения через GET /v1/images/:file_key с format=svg (Figma REST API: images). Вызов принимает список ID узлов и возвращает временную ссылку на каждый SVG. Большие наборы идут пачками: мы запрашиваем 100 узлов за вызов и ограничиваем каждый SVG одним мегабайтом.

В сравнении тарифов Figma только REST API для переменных отмечен как доступный лишь на Enterprise. Экспорт иконок в это ограничение не упирается (почему для переменных нужен обходной путь).

Шаг 3. Очистите SVG на входе

SVG это документ, а документ извне может нести то, чего вы не хотите видеть в коде. Например, <script>, обработчики событий вроде onload, <foreignObject> или ссылки с адресом javascript:. Удалите их до того, как файл сохранится или попадёт в превью. Мы санитизируем каждый SVG перед записью в наш реестр, и весь сгенерированный код строится из этой очищенной копии.

На этом же шаге удобно проводить проверки качества, которые не меняют файл. Нет viewBox, пустые контуры и группы, цвета, которые не будут следовать за цветом текста. Сообщайте о них дизайнеру, а не исправляйте молча.

Шаг 4. Поймите, что изменилось

Сравните новую выгрузку с предыдущей по ID узла и хешу содержимого:

Если иконку вынесли за пределы выбранных страниц или секций, она считается удалённой. Именно эта таблица делает pull request пригодным для ревью. Без неё каждая выгрузка выглядит как «изменились все иконки». Ревьюеры одобряют на доверии, и продакшен тихо расходится с дизайном. С ней ревьюер видит три изменённые иконки и одно переименование.

Для имён нужно ещё одно правило. Приводите имя из Figma к виду, пригодному для кода: нижний регистр, пробелы в дефисы, только a-z0-9-. Если две иконки сводятся к одному имени, отметьте конфликт и предложите name-2. Не позволяйте одному файлу затереть другой.

Шаг 5. Выберите формат доставки

Есть три разумных способа доставить иконки в кодовую базу на React.

React-компоненты

Вот вывод для иконки стрелки. Он сгенерирован с TypeScript, именованными экспортами, размером 1em и одной заменой цвета, #1A1A1A → currentColor:

import * as React from "react";
import type { SVGProps } from "react";
const ArrowRight = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="none" viewBox="0 0 24 24" {...props}><path stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 12h14m-6-6 6 6-6 6" /></svg>;
export { ArrowRight };

Здесь важны три детали. 1em заставляет иконку следовать за размером шрифта вокруг. currentColor заставляет её следовать за цветом текста, так что состояния наведения и неактивности вы получаете даром. А передача props в <svg> позволяет потребителю задать aria-label, className или другой размер.

Замену цвета как раз и пропускают. Дизайнеры рисуют иконки в настоящем цвете, и без замены каждая иконка уезжает в код с этим цветом намертво. Замена подходит для одноцветных иконок, а многоцветные сохраняют свои заливки.

Для доступности передавайте aria-hidden="true", когда иконка стоит рядом с текстовой подписью. Если иконка несёт смысл сама по себе, передавайте role="img" с aria-label (MDN: img role).

SVG-спрайт

Спрайт это один скрытый SVG с <symbol> на каждую иконку:

<svg xmlns="http://www.w3.org/2000/svg" style="display:none">
<symbol id="fsc-arrow-right" viewBox="0 0 24 24">…</symbol>
<symbol id="fsc-check-circle" viewBox="0 0 24 24">…</symbol>
</svg>

Страница подключает его один раз и ссылается на иконки через <svg><use href="#fsc-arrow-right" /></svg>. Префикс, здесь fsc-, не даёт ID символов столкнуться с другими ID на странице.

Пакет

Пакет хранит исходные файлы и добавляет манифест, чтобы набор мог прочитать любой потребитель:

src/icons/
├── icons/
│   ├── arrow-right.svg
│   ├── check-circle.svg
│   └── github.svg
├── index.json
└── package.json

Манифест сопоставляет ID и имя каждой иконки с её файлом. Этот ID и есть ID узла Figma за иконкой, поэтому потребитель тоже может отслеживать её через переименования.

Шаг 6. Оптимизируйте при генерации

Оптимизация относится к генерации, а не к хранению. Запускайте SVGO с пресетом по умолчанию, когда собираете компоненты. Заодно добавляйте префикс к ID внутри каждой иконки. Тогда две иконки с <clipPath id="a"> не сломают друг друга на одной странице. Храните SVG неоптимизированным: если оптимизатор изменится, вы перегенерируете код из оригинала, а не оптимизируете дважды.

Шаг 7. Доставьте pull request'ом

Запишите сгенерированные файлы в ветку и откройте pull request в репозиторий. Хороший pull request с иконками:

  • трогает только файлы, которыми владеет эта доставка. Поэтому он может удалить иконки, убранные в Figma, и не задеть ничего другого;
  • перечисляет в описании добавленные, изменённые, переименованные и удалённые иконки;
  • несёт метку о добавленных, изменённых или удалённых иконках, чтобы её подхватили заметки к релизу.

Дальше пусть идёт обычное ревью. Ревьюер проверяет дифф трёх иконок, а не перегенерированную папку из двухсот.

Шаг 8. Запускайте из Figma

Последний ручной шаг это запуск экспорта. При публикации библиотеки Figma отправляет вебхук LIBRARY_PUBLISH (Figma webhooks). Событие перечисляет созданные, изменённые и удалённые компоненты (created_components, modified_components, deleted_components). Запускайте по нему синхронизацию, а по списку скачивайте только изменённые иконки, а не весь набор.

Когда это настроено, публикация в Figma сама открывает pull request, и никому не нужно выгружать файлы руками.

Собрать самим или взять готовое

Этот конвейер можно собрать самостоятельно: API Figma, SVGO и скрипт, который пишет ветку, покрывают большую часть. Дольше всего доводятся до ума скучные части. Стабильные ID, распознавание переименований, удаление только своего и дифф, которому ревьюер может доверять.

Если поддерживать это не хочется, те же шаги выполняет FISYCO. Он ограничивает выгрузку страницами и секциями, санитизирует каждый SVG и доставляет компоненты, спрайт или пакет. После каждой публикации библиотеки он открывает pull request. Тот же подход работает и для токенов, подробнее в статье токены из Figma в код.

Подключите библиотеку иконок из Figma и получите первый pull request уже сегодня.
#Иконки#Figma#Pull request
KK

Автор статьи

Kirill Karpov

Основатель FISYCO

Кирилл Карпов — основатель FISYCO, инструмента контроля дизайн-системы, который держит Figma и код продакшена в согласии.

Новые статьи на почту

Дизайн-системы, токены и доставка дизайна в код. Без спама, отписка в один клик.

Подписываясь, вы соглашаетесь получать письма блога FISYCO. Подробности — в политике конфиденциальности.

Держите дизайн-систему и код в согласии

FISYCO связывает библиотеки Figma с кодовой базой, находит расхождения и присылает правку пулреквестом.

Начать бесплатно

Похожие статьи

6 мин чтения

Инженерия

Style Dictionary на практике: токены в CSS, SCSS и TypeScript

Рабочая настройка Style Dictionary 5 для токенов DTCG, проверенная настоящей сборкой: ссылки, режимы, единицы и эксперимент, в котором переименование тихо ломает CSS.

6 мин чтения

Инженерия

Как отдать переменные Figma разработчикам без тарифа Enterprise

Единственный официальный API для переменных Figma доступен только на Enterprise. Разбираем три пути, которыми переменные выходят из Figma, и где каждый упирается.

6 мин чтения

Инженерия

Токены из Figma в код без ручного экспорта

Процесс, который держит токены в Figma и коде синхронными: смысловые имена, сравнение вместо копирования и каждое изменение через pull request.

Иконки из Figma в React-компоненты: весь путь | FISYCO