Начнём с того, что я всё ещё совсем скептик этой идеи из заголовка в том смысле, в котором вы её понимаете по умолчанию. То есть для меня абсолютно очевидно, что невозможно (пока) универсально сгенерировать код компонента или тем более экрана, нарисованного дизайнерами. Невозможно потому, что у вас на уровне проекта скорее всего есть гайдлайны и переиспользуемые блоки, которые эту задачу усложняют в тысячу раз. Сгенерить компонент – не настолько большая проблема. Проблема сделать так, чтобы он переиспользовал то, что уже у вас есть.
Но вот что касается токенов дизайн-системы – это та база, которую вроде бы экспортировать достаточно просто. Токены-то ни от чего не зависят. И с этой мыслью я прожил последние недели.
По правде говоря, мной начала двигать лень ровно в тот момент, когда мы получили пак из 500 🍒 новых иконок от дизайнеров в фигме. И каждую из этих иконок по обычному воркфлоу нужно было выгрузить в SVG, сделать из неё оптимизированный Vector Drawable, осмысленно переименовать как это принято в андроид ресурсах, положить её куда надо и написать Compose геттер а-ля Icons.Filled.ArrowLeft. И, не дай бог, потом что-то обновят. Примечательно то, что из коробки в андроид студии из всего этого нет даже превращения пачки SVG в Vector Drawable, хоть сиди и по одной конвертируй.
Части этой комплексной задачи решаются какими-то разными инструментами типа плагинов для фигмы или сторонних экспортёров-конвертеров. Но я решил написать велосипед, чтобы всё это можно было одной кнопкой сделать и как у нас принято. Хотя бы опыт будет.
Так вот, оказалось что Figma API прям очень простой, я даже не знаю почему это настолько не распространено. Нам буквально нужно два эндпоинта, первый по корневой ноде выгружает дерево нод, второй по любой ноде даёт ссылку на её экспортированную картинку.
То есть основная сложность здесь вообще алгоритмическая. Нужно обойти дерево в поисках нод, которые дизайнеры пометили как экспортируемые, попутно накапливая названия всех родителей. Цепочка названий родителей после несложных преобразований (жесточайших костылей) собираются в финальное название иконки. Итого на выходе массив SVG с "правильными" названиями. Дальше каждая SVG конвертируется в Vector Drawable используя класс Svg2Vector из Build Tools, который сама студия и использует. Инструментов по оптимизации SVG или Vector Drawable множество, я взял первый попавшийся на глаза avocado. Ну а по массиву Drawable ресурсов сгенерировать файлы с кодом с помощью KotlinPoet или даже своими шаблонами это уже дело техники. 🪄
Ну и в результате это просто Gradle плагин в модуле дизайн-системы, всё конфигурируется там и запускается одной таской. А самое фиговое во всей этой истории, что поделиться по сути можно только концептом, т.к. код разбора дерева – это прямое следствие структуры фигмы от дизайнеров и самое уязвимое от изменений место.
К слову, вот тут неплохая статья на эту тему. Я честно не подглядывал, но у меня почти все базворды и подходы по итогу совпали.