От UI-kit до дизайн-системы +31


Опыт онлайн-кинотеатра Иви

Когда в начале 2017 года мы впервые задумались о создании собственной системы доставки дизайна в код, об этом уже многие говорили и кто-то даже делал. Однако, об опыте построения кроссплатформенных дизайн-систем и по сей день мало что известно, а понятных и проверенных рецептов, описывающих технологии и способы подобной трансформации процесса имплементации дизайна в уже работающий продукт как не было, так и нет. Да и под «компонентами в коде» часто понимают очень разные вещи.


Меж тем компания год от года удваивала штат — нужно было масштабировать отдел дизайна и оптимизировать процессы создания и передачи макетов в разработку. Умножаем всё это на «зоопарк» платформ, которые нужно поддерживать, и получаем подобие вавилонского столпотворения, которое просто не способно «нормально делать» и приносить доход. Развитие платформ часто шло параллельно, и один и тот же функционал мог выходить на разных платформах с лагом в несколько месяцев.


Отдельные наборы макетов для каждой платформы

Традиционно, мы начали с проблем, которые помогла бы решить дизайн-система и сформулировали требования к её проектированию. Помимо создания единого визуального языка, увеличения скорости макетирования и разработки, повышения качества продукта в целом, было жизненно необходимо максимально унифицировать дизайн. Это нужно для того, чтобы развитие функционала стало возможным сразу на всех наших платформах одновременно: Web, iOS, Android, Smart TV, tvOS, Android TV, Windows 10, xBox One, PS4, Roku — не прорабатывая при этом каждую из них в отдельности. И это у нас получилось!

Дизайн > данные


Когда принципиальные договорённости отделов продукта и разработки были достигнуты, мы сели за подбор технологического стека и проработку деталей всего процесса — от макета до релиза. Чтобы полностью автоматизировать процесс передачи дизайна в разработку поисследовали вариант с парсером параметров компонентов прямо из Sketch-файлов с макетами. Оказалось, что находить нужные нам куски кода и извлекать нужные нам параметры — затея сложная и опасная. Во-первых, дизайнерам придётся быть крайне аккуратными в именовании всех слоёв исходника, во-вторых, это работает только для самых простых компонентов, а в-третьих, зависимость от чужой технологии и структуры кода исходного Sketch-макета ставит под угрозу будущее всего проекта. Мы решили отказаться от автоматизации на этом участке. Так в команде дизайн-системы появился первый человек, на вход которому подаются дизайн-макеты, а на выходе — данные, описывающие все параметры компонентов и иерархически упорядоченные по методологии атомарного дизайна.

Дело оставалось за малым: где и как хранить данные, как передавать в разработку и как интерпретировать в разработке на всех поддерживаемых нами платформах. Вечер переставал быть томным… Итогом регулярных встреч рабочей группы, состоящей из дизайнеров и тимлидов от каждой платформы стали договорённости о нижеследующем.

Вручную разбираем визуал на элементы-атомы: шрифты, цвета, прозрачности, отступы, скругления, иконки, картинки и длительности для анимаций. И собираем из этого кнопки, инпуты, чекбоксы, виджеты банковских карт и т. д. Стилям любого из уровней, кроме пиктограмм присваиваем несемантические имена, например названия городов, имена нимф, покемонов, марки автомобилей… Тут условие одно — список не должен исчерпаться раньше, чем закончатся стили — шоу маст гоу он! Семантикой же не стоит увлекаться, чтобы не пришлось добавлять среднюю кнопку между «small» и «medium», например.

Визуальный язык


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

Ранее мы уже успели «обкатать» большинство элементов дизайна в приложении под Windows 10, которое на тот момент являлось для нас новой платформой, то есть требовалась отрисовка и разработка «с нуля». Рисуя его, мы смогли подготовить и проверить большинство компонентов и понять, какие из них должны были войти в будущую дизайн-систему Иви. Без такой «песочницы» подобный опыт можно было получить только большим числом итераций на уже работающих платформах, а на это потребовалось бы больше года.

Переиспользование одинаковых компонентов на разных платформах уменьшает количество макетов и массив данных дизайн-системы в разы, поэтому дизайну предстояло решить ещё одну задачу, ранее не описанную в практиках продуктового дизайна и разработки — как, например кнопку для телефонов и планшетов переиспользовать на телевизорах? И как в принципе быть с размерами шрифтов и элементов на таких разных платформах?

Очевидно, требовалось спроектировать кроссплатформенную модульную сетку, которая будет задавать нужные нам размеры текста и элементов для каждой конкретной платформы. За точку отсчёта для сетки мы выбрали размер и количество постеров фильмов, которые хотим видеть на том или ином экране и, исходя из этого сформулировали правило построения колонок сетки, при условии — ширина одной колонки равна ширине постера.


Теперь нужно привести к одному размеру макета все большие экраны и вписать их в общую сетку. Apple TV и Roku разрабатываются в размер 1920x1080, Android TV — 960x540, Smart TV, в зависимости от вендора бывают такими же, а бывают 1280x720. Когда приложение рендерится и отображается на экранах Full HD, 960 умножается на 2, 1280 на 1,33, а 1920 выводится как есть.

Опуская скучные подробности, мы пришли к тому, что вообще все экраны, включая телеэкраны с точки зрения элементов и их размеров покрываются одним дизайн-макетом, а все телеэкраны являются частным случаем общей кроссплатформенной сетки, и состоят из пяти или шести колонок, как средний планшет или десктоп. Кому интересны подробности, го в комменты.


Единый UI для всех платформ

Теперь для отрисовки новой фичи нам не нужно рисовать макеты под каждую из платформ, плюс варианты адаптивности для каждой из них. Достаточно показать один макет и его адаптивность для всех платформ и устройств любой ширины: телефоны — 320–599, всё остальное — 600–1280.

Данные > разработка


Конечно, как бы нам ни хотелось прийти к абсолютно унифицированному дизайну, каждая платформа имеет свои уникальные особенности. Несмотря на то, что и веб, и Smart TV используют стек ReactJS + TypeScript, приложение для Smart TV запускается на устаревших WebKit- и Presto-клиентах, и потому не может использовать общие стили с вебом. А email-рассылки и вовсе вынуждены работать с табличной вёрсткой. При этом ни одна из не-html-платформ не использует и не планирует использовать React Native или какие-то её аналоги, опасаясь ухудшения производительности, так как у нас слишком много кастомных лэйаутов, коллекций со сложной логикой обновления, изображений и видео. Поэтому для нас не подходит распространённая схема — поставлять готовые CSS-стили или React-компоненты. Поэтому мы решили передавать данные в формате JSON, описывая значения в абстрактном декларативном виде.
Так свойство rounding: 8 приложение Windows 10 преобразует в CornerRadius="8", веб — border-radius: 8px, Android — android:radius="8dp", iOS — self.layer.cornerRadius = 8.0.
Cвойство offsetTop: 12 один и тот же веб-клиент в разных случаях может интерпретировать как top, margin-top, padding-top или transform

Декларативность описания также предполагает, что если платформа технически не может использовать какое-либо свойство или его значение, она может его проигнорировать. С точки зрения терминологии мы сделали некое подобие языка эсперанто: что-то взяли из Android, что-то из SVG, что-то из CSS.

В случае если на той или иной платформе потребуется отображать элементы как-то иначе, мы реализовали возможность передачи соответствующей генерации данных в виде отдельного JSON-файла. Например, состояние «в фокусе» для Smart TV, диктует изменение позиции текста под постером, значит для этой платформы данный компонент в значении свойства «отступ» будет содержать необходимые ей 8 поинтов отступа. Хоть это и усложняет инфраструктуру дизайн-системы, зато даёт дополнительную степень свободы, оставляя нам возможность самим управлять визуальной «непохожестью» платформ, а не быть заложниками нами же созданной архитектуры.


Пиктограммы


Иконографика в цифровом продукте — это всегда объёмный и не самый простой подпроект, часто имеющий отдельного дизайнера. Глифов всегда много, каждый из них имеет несколько размеров и цветов, к тому же платформам они нужны, как правило в разных форматах. В общем, не было повода не завести всё это в дизайн-систему.


Глифы загружаются в векторном SVG-формате, а значения цветов автоматически заменяются переменными. Приложения-клиенты могут получать их уже готовыми к использованию — в любом формате и цвете.

Предпросмотр


Поверх JSON’а с данными мы написали инструмент для предпросмотра компонентов — JS-приложение, на лету пропускающее JSON-данные через свои генераторы разметки и стилей, и отображающее в браузере различные вариации каждого из компонентов. По сути, предпросмотр является точно таким же клиентом, как и платформенные приложения, и работает с теми же данными.

Понять, как работает тот или иной компонент, проще всего путём взаимодействия с ним. Поэтому мы не стали использовать инструменты, подобные Storybook, а сделали интерактивный предпросмотр — можно пощупать, понаводить, покликать… При добавлении в дизайн-систему нового компонента он появляется в предпросмотре, чтобы платформам было на что ориентироваться при его внедрении.

Документация


На основе тех данных, которые в виде JSON поставляются платформам, автоматически формируется документация по компонентам. Описывается перечень свойств и возможные типы значений в каждом из них. После автогенерации информацию можно уточнить в ручном режиме, добавить текстовое описание. Предпросмотр и документация снабжены перекрёстными ссылками друг на друга на уровне каждого компонента, а вся информация, попадающая в документацию, доступна разработчикам в виде дополнительных JSON-файлов.

Депрекатор


Ещё одной необходимостью стала возможность со временем заменять и обновлять уже существующие компоненты. Дизайн-система научилась сообщать разработчикам, какие свойства или даже целые компоненты использовать нельзя и удалять их, как только они перестают использоваться на всех платформах. Пока в этом процессе ещё много «ручного» труда, но мы не стоим на месте.

Клиентская разработка


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

Для верстки экранов iOS-приложения мы используем два базовых механизма, которые предоставляет iviUIKit: cвободная компоновка элементов и компоновка коллекций элементов. Мы используем VIPER, и всё взаимодействие с iviUIKit сосредоточено во View, а большая часть взаимодействия с Apple UIKit сосредоточена в iviUIKit. Размеры и расположение элементов задаётся в терминах колонок и синтаксических конструкций, работающих поверх нативных констрейнтов iOS SDK, делающих их более прикладными. Особенно это упростило нам жизнь при работе с UICollectionView. Мы написали несколько настраиваемых обёрток для лэйаутов, в том числе довольно сложных. Клиентского кода получилось минимум и он стал декларативным.

Для генерации стилей в проекте Android мы используем Gradle, превращая данные дизайн-системы в стили формата XML. При этом у нас есть несколько генераторов различного уровня:

  • Базовые. Парсят данные примитивов для генераторов более высокого уровня.
  • Ресурсные. Скачивают картинки, иконки, и прочую графику.
  • Компонентные. Пишутся для каждого компонента, где описано какие свойства и как перевести в стили.

Релизы приложений


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

Итоги


Скоро год как дизайн-система стала частью инфраструктуры, обслуживающей развитие онлайн-кинотеатра Иви, и уже можно делать кое-какие выводы:

  • Это большой и сложный в реализации проект, требующий постоянных выделенных ресурсов.
  • Это позволило нам создать свой уникальный кроссплатформенный визуальный язык, отвечающий задачам сервиса онлайн видео.
  • У нас больше нет визуально и функционально отстающих платформ.

Предпросмотр компонентов дизайн-системы Иви — design.ivi.ru




К сожалению, не доступен сервер mySQL