Как мы в Точке сделали свой дизайн-линтер
Привет! Я Саша, дизайнер в финтех-компании Точка. Я работаю в команде Технологичная среда, которая автоматизирует рутинные процессы. У нас есть внутренний плагин для Фигмы, который проверяет макеты на соответствие техническим параметрам. За несколько лет он сэкономили нашим дизайнерам много сил, а компании — денег.
В статье поделюсь техническими деталями создания плагина для тех, кто захочет повторить наш опыт.
Как мы пришли к созданию своего плагина
В продуктовых командах часто спорят о том, где правда: в коде или в дизайне. Обычно побеждает код: с этим сложно не согласиться, ведь это тот результат, который увидит клиент. Но чтобы в коде оказалось именно то, что было задумано командой, макет должен быть максимально точным. Именно он станет точкой синхронизации для команды: разработчик сверстает всё как в макете, тестировщик будет сравнивать вёрстку с макетом, дизайнер — указывать разработчику на различия с макетом. Тогда работа дизайнера, разработчика и тестировщика будет синхронизирована.
К сожалению, макеты устаревают
Жизненный цикл макета итеративный. Между завершением одной итерации и началом следующей может пройти не один месяц, пока команда собирает метрики и готовится к доработке функционала. Макет в это время остаётся замороженным. А вот дизайн-система обновляется непрерывно. За время, пока с макетом не работали, некоторые компоненты могли измениться или быть удалены. Соответственно, перед возвращением к макету дизайнеру придётся подтянуть обновления библиотек и убедиться, что все компоненты в макете актуальные, лэйаут не сломался, стили не отвязались — в общем, что нет никаких конфликтов.
Процесс дизайн-ревью
Сейчас в Точке 50 продуктовых дизайнеров. В большинстве команд выстроен процесс дизайн-ревью — это когда дизайнеры проверяют макеты друг друга (не путать с этапом, когда дизайнер проверяет свёрстанный макет, хотя и такой процесс у нас тоже есть). Схему его проведения мы подсмотрели у разработчиков:
создаём отдельную ветку в Фигме с новым функционалом,
бросаем реквест на ревью другим дизайнерам,
собираем лайки от коллег,
отправляем макет в разработку.
Обычно ревью проводят 2-3 человека. Каждый из них, кроме клиентской истории, вслед за дизайнером проверяет технические параметры макета: наличие устаревших и локальных компонентов, актуальность их названий, привязку цветов, текстов и эффектов к стилям.
Гигиена важна
Проверка технических параметров помогает с его поддержкой на длинной дистанции: ошибки не переходят из макета в макет, обновления библиотек дизайн-системы становятся менее болезненными. Кроме того, это позволяет разным дизайнерам работать с макетом по единым правилам и обеспечивает синхронизацию с разработчиками: все названия компонентов и стилей актуальны как в Фигме, так и, например, в сторибуке.
На поиск проблем вручную нужно много времени. А если учесть, что дизайнер, а затем и несколько ревьюверов делают одно и то же, можно умножить это время минимум на 3. Кроме того, это достаточно рутинный и утомительный процесс. А самое главное — ручная проверка никогда не гарантирует исправления всех проблем. Поэтому мы решили внедрить в этот процесс автоматизацию.
Раньше мы пользовались общедоступными плагинами из комьюнити Фигмы для простых точечных проверок. Например, для поиска скрытых слоёв или отвязанных стилей. Они хороши, но даже на этом этапе кажется, что проще запустить один плагин вместо пяти разных.
В комьюнити Фигмы уже существует пара неплохих плагинов для комплексной проверки макета. Но, пользуясь ими, дизайнеру всё время приходится отвечать на вопрос: а это действительно ошибка, или можно оставить всё как есть? Такие плагины не учитывают структуру и правила конкретно вашей дизайн-системы. Из этого вытекает важная мысль — в каждой дизайн-системе есть правила, которые нельзя охватить общедоступными плагинами. Нам хотелось сэкономить время дизайнера и минимизировать количество размышлений и действий, которые нужны для приведения макета в порядок. Поэтому мы решили написать собственный плагин.
Какой функционал у линтера Tochka Helper
Как у разработчиков есть линтеры для анализа кода, так и у нас появился плагин для анализа макета. Он сканирует страницу по разным параметрам и находит элементы, в которых есть ошибки, или на которые стоит обратить внимание. Результаты группируются по правилам проверки — так дизайнерам проще исправлять однотипные проблемы. Например, сначала разбираемся с компонентами, потом с цветами элементов, затем со стилями текстов и т.д. Опционально можно указать, сканируется ли сейчас макет или библиотека, так как часть правил релевантна только для чего-то одного.
В основе — три принципа, которые отличают наш плагин от доступных в комьюнити Фигмы:
Контекстный анализ — подсвечиваются только значимые с точки зрения дизайн-системы ошибки. Например, не каждая отвязанная заливка — это проблема (об этом я ещё расскажу подробнее).
Группировка однотипных ошибок с учётом архитектуры UI-кита — исправление десятков однородных элементов в один клик.
Автоисправление с контролем — плагин предлагает решения, но не меняет макет без подтверждения, чтобы у дизайнера остался контроль над ситуацией.
Сейчас плагин может проверить:
Наличие инстансов устаревших в дизайн-системе компонентов.
Наличие инстансов недоступных в текущем пространстве компонентов — на случай, если при переезде из одной Фигмы в другую потерялся доступ.
Наличие локальных компонентов, не вынесенных в библиотеку, и их инстансов.
Наличие элементов с отвязанным или устаревшим стилем цвета заливки или обводки.
Наличие элементов с недоступным в текущем пространстве Фигмы стилем цвета заливки или обводки — на случай, если не подключена нужная библиотека, или к ней уже нет доступа.
Привязку значений отступов и скруглений к переменным дизайн-системы.
Наличие элементов с отвязанным или устаревшим стилем текста или эффекта.
Наличие примитивных элементов с автоматически сгенерированным названием — чтобы не было разных «Frame 35» и «Rectangle 6».
Наличие потенциальных персональных данных на странице.
Наличие скрытых элементов вне инстансов.
Соответствие платформы макета платформе используемых компонентов.
Соответствие названия инстанса названию мастер-компонента — на случай, если переименовали инстанс или взяли его из другого раздетаченного.
Соответствие размеров артбордов типовым для платформ и их настройки.
Дескрипшен мастер-компонентов в библиотеке.
А ещё мы добавили в плагин аналитику, которая позволяет понять, как и какими функциями дизайнеры пользуются чаще. Например, мы узнали, что за год использования самые популярные правила проверки — это поиск устаревших компонентов и отвязанных стилей цветов. На них я остановлюсь подробнее: расскажу о сути проблемы и поделюсь деталями из под капота.
Как мы работаем с устаревшими компонентами
Со временем, компоненты дизайн-системы устаревают. Причин для этого может быть несколько:
Компонент больше не используется, и ему на замену пришёл другой.
Случился редизайн компонента, и теперь он выглядит кардинально иначе.
Компонент был пересобран с использованием новых подходов или технологий.
Во всех трёх случаях изменения в исходном мастер-компоненте приведут к поломкам в макете: от поехавшего лэйаута до сбрасывания содержимого. Поэтому мы уже много лет действуем следующим способом: помечаем компонент как устаревший, добавляя в начало названия эмодзи ❌, а вместо него создаём новый. Такое обновление библиотеки точно ничего не сломает в макете. А при встрече с красным крестиком дизайнер будет знать, что компонент пора заменить на актуальный.
Ещё до того, как в Фигме появился встроенный поиск, нам хотелось дать дизайнеру возможность быстро убедиться, что все компоненты в макете актуальные. Задачей плагина стало отыскать все инстансы, у которых в названии мастер-компонента есть красный крестик. Для этого достаточно проверить поле Name у мастер-компонента (mainComponent) инстанса.
Следующим шагом стала группировка элементов. В первую очередь мы группируем инстансы по принадлежности к общему мастер-компоненту: например, все ячейки размера M. Для этого проверяем поля Key их мастер-компонентов, они должны совпадать. Но также на группировку влияет вложенность инстанса в другие инстансы. Например, ячейка, лежащая внутри карточки, и ячейка, лежащая внутри выпадающего списка, попадут в разные группы, потому что, скорее всего, будут иметь разные настройки.
Лайфхак для группировки
Каждый элемент на странице имеет свой уникальный id, который выглядит как две группы цифр, разделённых двоеточием.
1:96
У инстансов, вложенных в другие инстансы, к цифрам добавляется префикс «I» и id всех родительских инстансов до самого верхнеуровневого через точку с запятой.
I 6:47; 6:39; 1:96
Таким образом, глядя на id элемента, можно сразу сказать, вложен он в другой инстанс или нет. И если вложен, то выделить id родительского инстанса, и уже по нему получить ключ мастер-компонента.
Теперь, чтобы правильно сгруппировать устаревшие элементы, останется лишь проверить, что ключи их мастер-компонентов и ключи мастер-компонентов родительских инстансов совпадают.
Автоматическая замена
Но найти устаревшие элементы — это только половина дела. Нужно ещё выяснить, на что их заменить. Какое-то время мы пытались прописывать в дескрипшене устаревшего компонента название актуального, но продержались недолго. Названия компонентов менялись, актуальные тоже со временем устаревали. Тогда мы подумали, что было бы здорово зашить в устаревший компонент ключ актуального, чтобы он всегда сам знал, на кого ему заменяться. Ведь в отличие от названия, ключ компоненту присваивается раз и навсегда (если, конечно, не переносить его в другую библиотеку).
Способ нашёлся: с помощью Plugin Data можно сохранить в компоненте собственную информацию, в том том числе и ключ другого компонента. Получить доступ к этой информации может только плагин, который её туда сохранил. Другим плагинам она недоступна. Поэтому способ довольно безопасный.
Чтобы любой дизайнер мог самостоятельно разметить компонент, мы добавили несколько специальных методов в плагин:
Copy Key — копирует ключ актуального компонента.
Set Key — записывает скопированный ключ в устаревший компонент.
Show Key — показывает записанный ключ или сообщает, что его ещё нет.
Delete Key — стирает ключ.
Теперь, когда компонент помечается устаревшим, и в название добавляется красный крестик, он ещё должен быть дополнительно размечен. Это минута времени, которая сэкономит дизайнерам часы.
Разметка нескольких компонентов разом
Однажды у нас произошло масштабное обновление иллюстраций. Кроме метафоры, изменились и размеры изображений. Было принято решение пересоздать компоненты, содержащие иллюстрации, заново, а старые пометить как устаревшие. Смотреть в глаза дизайнеру, которому нужно было вручную разметить около тысячи компонентов иллюстраций, оказалось невыносимо. Тогда мы начали искать способ упростить этот процесс. Заметив, что названия компонентов не изменились, мы решили завязаться на это. Обновили метод Copy Key так, чтобы он копировал ключи сразу всех выделенных компонентов и при этом запоминал их названия (так метод превратился в Copy Keys). А после этого написали новый метод Set Keys by Matched Names, чтобы ключи назначались компонентам с совпадающими названиями. Так разметка тысячи иллюстраций тоже свелась к паре кликов. Этот же способ позволяет размечать наборы компонентов.
Не делаем лишнюю работу
При замене инстанса мы используем стандартный метод из API Фигмы swapComponent. Как известно, Фигма хорошо сохраняет оверрайды инстансов только на первом уровне. Те, что вложенны глубже, будут сброшены к дефолту. Поэтому мы по умолчанию игнорируем устаревшие элементы, которые вложены в другие устаревшие элементы, и не показываем их в списке ошибок, так как они скорее всего сами исправятся при замене родительского элемента. Это позволяет сэкономить время дизайнера и не отвлекать его на проблемы, которые исправятся сами собой.
После замены
Каждую из групп устаревших элементов можно заменить одним кликом. Но на этом проверка не заканчивается. Ведь элемент может ссылаться на другой уже устаревший компонент или содержать внутри себя устаревшие, которые не сбросились сами. Поэтому сразу после замены плагин проверяет новые элементы и, если обнаруживает в них устаревшие, добавляет их в список. При этом алгоритм снова попытается сгруппировать найденные элементы: либо добавит в уже существующие группы, либо создаст для них новые.
Недоступные компоненты
Кроме естественного устаревания компонентов бывает вынужденное. Например, если компания переехала из одного пространства Фигмы в другое, и доступ к старому невозможен. У инстансов в макете не будет никаких красных крестиков, но при попытке перейти к мастер-компоненту Фигма сообщит, что у вас нет доступа к библиотеке. При этом обновляться такие инстансы, естественно, перестанут. Отыскать их вручную тяжело, поэтому мы решили научить этому наш плагин.
Алгоритм здесь такой: при запуске плагина обходим все инстансы на странице и собираем уникальные ключи их мастер-компонентов. Затем пытаемся получить эти компоненты от Фигмы с помощью метода importComponentByKeyAsync (или аналогичного для набора компонентов). Все компоненты, которые Фигма не вернула, считаем устаревшими. Дальше останется только найти и сгруппировать принадлежащие им инстансы. Каждый компонент — это отдельный запрос, и проверка может занимать достаточно много времени. Поэтому мы сделали её опциональной.
Устаревшие компоненты — одно из самых популярных правил проверки.
По итогам прошлого года, проверка на устаревшие и недоступные компоненты — это одно из самых популярных действий в плагине. Оно становится особенно актуально в период больших изменений в продукте. Например, у нас это совпало с редизайном элементов форм и внедрением в продукт тёмной темы. За последний год плагин уже помог отыскать в макетах 20 тысяч устаревших компонентов, из них 13,5 тысяч было заменено им автоматически. Проверка на устаревшие компоненты уступает лишь проверке стилей цветов. Расскажу про неё дальше.
Отвязанные стили цветов
При поддержке продукта важно иметь возможность доставлять обновления в макеты. В этом случае использование UI-кита обеспечивает наследственную связь между мастер-компонентом и его инстансами, между стилями и элементами, к которым они применены. Поэтому важно, чтобы эта связь была установлена: например, чтобы цвет заливки или обводки элемента был связан со стилем или переменной из библиотеки. Иногда эта связь нарушается. Причины могут быть разные:
Дизайнер забыл задать стиль на старте.
Дизайнер случайно отвязал стиль и забыл привязать обратно.
Что-то сломалось под капотом у Фигмы.
Почему не Styles Organizer
Чтобы отловить такие ситуации можно воспользоваться общедоступными плагинами. Например, есть чудесный Styles & Variables Organizer. Но у него есть ряд недостатков:
Игнорирует скрытые элементы — думаю, всем, кто занимался поддержкой дизайн-системы, знакома ситуация, когда в файле завелись призрачные моды. Избавиться от них вручную очень непросто, потому что элементы, использующие цвета из таких модов, скрыты и лежат где-то очень глубоко.
Собирает все элементы с одинаковым хексом в одну группу — учитывая, что один и тот же хекс может быть связан с десятком различных переменных, быстро починить отвязанные стили не получится.
Нам хотелось получить больше контроля над ситуацией, поэтому мы добавили в плагин собственное правило проверки стилей и переменных цветов.
Поиск и группировка
Первым делом мы научили плагин не игнорировать скрытые элементы и находить элементы с отвязанным стилем заливки или обводки. Для этого проверяем, что список заливок элемента не пуст, и при этом отсутствует стиль из библиотеки — fillStyleId. Аналогично проверяем обводки. В случае с переменными проверяем поля fills и strokes у объекта boundVariables.
Затем, по той же логике, что я описывал в части про устаревшие компоненты, мы научились группировать однородные элементы. В случае с инстансами сравниваются ключи мастер-компонентов и ключи мастер-компонентов родительских инстансов. А вот в случае простых элементов всё хитрее — в отличие от инстансов у них нет чёткого признака однородности, поэтому их мы группируем по типам. Например, отдельно тексты, отдельно круги, отдельно фреймы и т.д. В особую группу мы выделяем артборды — фреймы, лежащие прямо на странице и ни во что не вложенные.
Починить, но не навредить
После того, как элементы с цветами без стилей найдены, дизайнеру остаётся назначить нужные стили. В случае с обычными элементами проблем нет. А вот с инстансами есть нюанс. Имя ему — оверрайд. Как только дизайнер вручную назначит стиль цвета элементу внутри инстанса, он сделает оверрайд — переопределит цвет, заданный мастер-компонентом. Фигма всегда будет считать предопределенное значение более приоритетным, чем то, что задано в мастере. И даже если в мастер-компоненте цвет изменится, в макете он не обновится. Поэтому дизайнеру на этом этапе нужно принять решение: действительно ли он хочет переопределить исходный цвет. Если нет, то правильно будет вместо этого сбросить значение цвета к дефолтному, выбрав действие Reset fill или Reset stroke в правой панели дизайна. К сожалению, API Фигмы не позволяет сделать это автоматически за дизайнера. Поэтому это действие остаётся за человеком.
Цвета, отвязанные в библиотеке
В UI-ките тоже бывают баги. Иногда цвет элемента может отвязаться прямо в мастер-компоненте. В таком случае кажется, что лучше не пытаться чинить это в макете, а дождаться, когда починят в библиотеке, и уже потом просто подтянуть обновление — проблема исправится сама.
А бывают компоненты, которые изначально содержат элементы с отвязанными цветами. Часто это какая-то графика, например, логотипы компаний или иллюстрации. Они могут быть не связаны с дизайн-системой, а являться частью чужих брендов. В таком случае нет смысла считать это проблемой в макете, ведь тут нечего исправлять.
Что считать ошибкой, а что нет
Зная, что существуют оверрайды цветов, и что в библиотеках тоже могут быть отвязанные цвета, мы сформулировали правило, на основании которого плагин решает, считать отвязанный цвет элемента внутри инстанса ошибкой или не беспокоить этим дизайнера.
Если в инстансе цвет отвязан, но оверрайда нет, то это не ошибка. Либо это графика и так и задумано, либо что-то сломалось в библиотеке. В таком случае лучше дождаться, пока починят там, и не делать оверрайд, который заблокирует связь с мастером.
Если в инстансе цвет отвязан, при этом есть оверрайд, то это явно ошибка. Связь с мастером уже заблокирована и лучше хотя бы привязать цвет инстанса к библиотечному стилю.
Как понять, что оверрайд есть
Список всех оверрайдов инстанса доступен через API. За это отвечает поле overrides. Достаточно проверить массив overriddenFields внутри него и найти элементы, содержащие значения fillStyleId, fills, strokeStyleId, strokes.
Устаревшие стили
Кроме проверки элементов на отвязанные стили мы также проверяем их на актуальность. Но тут всё аналогично устаревшим компонентам: стиль или переменную в библиотеке помечаем красным крестиком, в макетах находим все использующие их элементы и группируем по описанной выше логике.
Стили цветов — самое популярное правило проверки.
За год плагин помог отыскать 20,5 тысяч проблемных элементов. Это даже больше, чем устаревших компонентов. Проверка цветов оказалась самой востребованной функцией плагина в нашем дизайн-комьюнити.
Итоги
Уже понятно, что дизайнеры получили полезный инструмент и сберегли свои нервные клетки. А зачем же всё это бизнесу?
В начале статьи я писал, что мы добавили в плагин аналитику, где собираем данные обо всех действиях дизайнеров. Мой коллега-аналитик подсчитал количество сэкономленных плагином человеко-часов — сами эти подсчёты достойны отдельной статьи, но если перевести их в деньги, получится весьма внушительная сумма.
Так плагин для Фигмы оказался не просто вечерним хобби дизайнера, а полноценным внутренним продуктом, приносящим пользу.