Дизайн-система в нашей компании существует с 2018 года. По поводу неё уже была статья от дизайнеров и выступление от техдиректора. Самое время рассказать, как ситуация выглядит изнутри самой дизайн-системы.
По мере написания стало понятно: материала слишком много, чтобы уложить его в одну статью. Поэтому чуть позже мы опубликуем вторую часть.
В первой же части статьи речь пойдёт о том, как и почему у нас появилась дизайн-система; как она устроена и что в ней хранится; как клиентские приложения IVI получают и обрабатывают данные из дизайн-системы; как мы добавляем в ДС новые сущности и как избавляемся от устаревших.
Некоторые вводные
Чтобы понимать масштаб того, с чем приходится работать нашей ДС, нужно сказать пару слов о самой компании IVI и особенностях нашего продукта.
IVI — это крупнейший онлайн-кинотеатр. По итогам 2020 года у нас:
более 100 тыс. единиц контента
60-миллионная аудитория
за год просмотрено 1,5 млрд часов видео
технический департамент около 300 человек
На всех основных платформах у нас есть нативные приложения в едином дизайне. При этом каждое из них имеет собственную команду разработки и собственный релизный цикл.
Разумеется, поставлять изменения во все эти приложения мы хотим максимально быстро и синхронно. И если с точки зрения содержимого экранов это вопрос во многом решён путём отдачи контента через единое API, то внешний вид элементов этих экранов ещё несколько лет назад задавался разработчиками каждой из платформ вручную.
Поэтому ближе к концу 2017 г. начались первые обсуждения и эксперименты, целью которых было организовать «единый источник правды» о внешнем виде компонентов UI для всех приложений и решить, в каком формате передавать такие данные в платформы. Так начала рождаться наша дизайн-система.
Появление дизайн-системы в IVI
Наши дизайнеры с самого начала были заинтересованы в создании ДС и активно обсуждали эту идею с разработчиками. И уже позже, после горестных рассказов представителей других компаний на тему «как уговорить дизайнеров, что нам нужна дизайн-система», стало ясно, насколько нам повезло.
Поскольку на тот момент в качестве инструментов дизайна в IVI активно использовались Sketch и Zeplin, первые попытки реализации ДС были построены вокруг них. Однако результаты нас не устроили, и мы начали думать над альтернативными вариантами.
В итоге пришли к следующему решению для быстрого старта: договариваемся о некоем универсальном формате описания визуальных свойств компонентов, который пишем вручную и отдаём платформам в виде JSON. В некотором приближении это должно напоминать CSS, только с более ограниченным набором свойств, зато работающее для всех платформ. При этом часть названий свойств мы брали из SVG, часть из CSS, часть из Android и т.д. — получился этакий язык эсперанто, но для стилей.
Взаимодействие с дизайн-системой
Целевые платформы
Говоря о кроссплатформенности, стоит обозначить, кто же именно потребляет данные нашей дизайн-системы. Вот неполный список:
Android-платформы: Android Phone/Tablet, Android TV
Apple-платформы: iPhone/iPad, Apple TV
Smart TV: LG, Samsung, Philips, Sony…
Приставки: PlayStation, XBox…
Windows 10 (нативное приложение)
Веб (www.ivi.ru)
Email (почтовые рассылки)
Чтобы эффективно работать со всей этой красотой, не привлекая внимания санитаров, мы решили сделать нашу ДС:
построенной вокруг данных (основная часть системы — это JSON-файлы)
декларативной (платформы сами определяют, как обрабатывать данные)
унифицированной по структуре данных (описание одного и того же компонента идентично для iPhone, ТВ Philips и почтовой рассылки, отличаться могут только значения свойств)
Превьюер
Разумеется, человеку довольно сложно «считывать» JSON-данные напрямую — необходима их визуализация. Поэтому прямо в нулевой версии дизайн-системы появился и её превьюер — веб-приложение, работающее на основе тех же самых данных, т.е. в некоторой степени ещё одна платформа.
Для внутренней сети собирается полная версия превьюера для всех платформ, а также дополнительные инструменты и демки на его основе. Для внешнего доступа при каждом релизе автоматически пересобирается упрощённый внешний превьюер.
Многие воспринимают визуализацию данных гораздо лучше, чем сами данные, поэтому именно превьюер очень быстро стал «точкой входа» в дизайн-систему.
Что хранится в дизайн-системе
Данные дизайн-системы описывают в первую очередь компоненты и примитивы. Компоненты — это сущности ДС, обладающие сформированным внешним видом, в отличие от примитивов, которые представляют собой значение или группу значений, проявляющихся лишь при стилизации других сущностей.
Примеры примитивов: цвет, прозрачность, типографика.
Примеры компонентов: кнопка, постер, виджет.
Для компонентов мы также описываем состояния (например, наведённое или нажатое) и модификаторы (например, размерные или цветовые вариации). Каждый модификатор или группа состояний определяет один и тот же набор свойств, но в каждой вариации они принимают разные значения. Общий стиль компонента устанавливается комбинацией его состояний и модификаторов (ровно по одному варианту из каждого).
Иконки
Помимо собственно данных, на стороне ДС также генерятся и раскрашиваются иконки. Эта подсистема держится в некоторой степени особняком, но всё равно достаточно тесно связана с остальными частями дизайн-системы.
В дизайне IVI используются двухцветные иконки, а значит, не получится просто отдавать платформам цельный исходник под раскрашивание. Но и хардкодные предраскрашенные иконки — это тоже не очень надёжно, т.к. цвета слоёв должны всегда совпадать с текущей цветовой палитрой приложения (а она время от времени меняется, плюс может отличаться для различных платформ).
Исходники иконок хранятся в виде SVG, которые на стороне подсистемы разделяются на слои и раскрашиваются. Клиентам при этом отдаются графические файлы (SVG и PNG) как предраскрашенных иконок, так и чёрных слоёв для самостоятельного раскрашивания и наложения на стороне платформы.
Немного статистики
По данным на 29 июня 2021, в нашей дизайн-системе содержится:
202 компонента (+ огромное число вариаций)
21 примитив (у многих — десятки значений)
729 иконок (в 122 цветовых вариантах)
278 сущностей, прошедших через статус deprecated
142 продакшен-релиза системы
Как платформы работают с данными из ДС
Каждая из платформ смотрит на файлы данных определённой версии. Их содержимое обрабатывается в момент сборки приложения — происходит кодогенерация. При обновлении версии простые изменения (например, изменение значения свойства) обрабатываются автоматически, а вот для более сложных структурных изменений может потребоваться вмешательство разработчика.
Платформа на своей стороне преобразует значение в нужный вид. Например, если для кнопки в данных ДС прилетело rounding: 6
, в коде приложений оно превратится во что-то вроде:
Windows 10:
CornerRadius="6"
Web:
border-radius: 6px
Android:
android:radius="6dp"
iOS:
self.layer.cornerRadius = 6.0
Smart TV:
border-radius: 8px
(на стороне платформы применяется множитель)
Как я уже отмечал выше, наша дизайн-система декларативна. Поэтому платформа сама определяет, как применять то или иное свойство. Например, значение свойства offsetTop: 12 один и тот же веб-клиент в разных случаях может интерпретировать как top, margin-top, padding-top или, скажем, transform. Более того, платформа не обязана обрабатывать все свойства — среди них могут быть не нужные для данной платформы или не поддерживаемые ей (например, размытие фона или сложная тень).
Абстрактное именование
Ещё до появления дизайн-системы мы неоднократно сталкивались с ситуациям вроде «нужно впихнуть новый размер кнопки между large и medium», «а теперь вся серая гамма становится фиолетовой» и т.п. Это заставило нас задуматься: а точно ли стоит именовать вариации сущностей семантически или лучше от этого абстрагироваться?
В итоге мы выработали подход, суть которого заключается в следующем: имена вариаций не должны зависеть от конкретных значений и их порядка следования (например, от большего к меньшему).
Для перечней, в любом месте которых в любой момент может добавиться новый элемент, мы используем абстрактное именование: названия городов, рек, индейских племён, имена нимф, героев компьютерных игр, марки автомобилей и т.п.
При этом важно избегать ассоциативной связи названия со значением свойства, т.к. значение может быть изменено, и ассоциация станет ложной. Например, марка автомобилей Ferrari стойко ассоциируется с красным цветом, а значит, это название нельзя использовать для именования чего-то, связанного с цветами (например, стилей кнопок).
Первым шагом (примерно за полгода до создания нашей ДС) стало кроссплатформенное именование цветов в палитре — названия мы взяли из статьи Википедии, перечисляющей наиболее старые из постоянно населённых городов. Так, наш фирменный красный стал называться madrid, белый — sofia, сиреневый — dublin, зелёный — beirut и т.д. И лишь партнёрские цвета (например, фирменные цвета банков и соцсетей) сохранили имена с привязкой к названию партнёра.
Затем в ход пошли имена героев Mortal Kombat, которые мы задействовали для размеров кнопок, имена нимф для названий типографики, теги граффитистов для стилей ссылок и так далее по нарастающей. В итоге к моменту запуска дизайн-системы концепция уже устоялась, так что внутри ДС мы стали использовать её же.
Для каждого перечня вариаций мы фиксируем источник, из которого можно брать новые имена (ссылка на источник хранится рядом с самим перечнем, так что долго искать не надо). На момент написания статьи мы используем уже 162 таких источника, часть из которых — это статьи-списки в Википедии, страницы на научных сайтах, в фандом-сообществах, но больше всего среди них различных страниц на замечательном ресурсе Fantasy Name Generators.
При добавлении нового источника мы проверяем, что он не используется в уже имеющихся перечнях. Если какая-либо из задействованных страниц в какой-то момент станет недоступна, мы можем заменить её на другую и брать последующие вариации уже оттуда.
Внедрение нового и поддержка старого
При разработке и развитии дизайн-системы нужно быть готовым к тому, что у каждой платформы есть свои беклоги, квартальные планы и ограничения по ресурсам. Даже самую прекрасную и полезную для платформ фичу не каждая из них будет готова сразу начать внедрять.
В таких реалиях важно сохранять работоспособность старого функционала, пока его использует хотя бы одна из платформ.
Новые подсистемы
Когда нам нужно внести в подсистему что-то новое, и это возможно сделать без потери обратной совместимости в формате, мы стараемся так и поступить.
Однако если это невозможно из-за технической или структурной несовместимости, мы начинаем строить новую подсистему рядом с устаканившейся старой, с которой платформы уже интегрированы.
Как только новый функционал становится достаточно стабильным, чтобы начать интеграционный процесс с платформами, мы обеспечиваем его связь со старым, чтобы не нужно было вносить одни и те же данные сразу в два несовместимых источника.
Система депрекейтов
Дизайн продукта тоже не стоит на месте, поэтому в описания уже существующих компонентов регулярно вносятся изменения. Не все из этих изменений платформы в текущих реалиях могут обработать автоматически, а значит, часть из них всё ещё может использовать устаревшие сущности, которые хотелось бы удалить из ДС. Чтобы удобнее было это отслеживать, мы создали инструмент под названием депрекейтор.
Это небольшой внутренний веб-сервис, в котором каждая устаревшая сущность (например, свойство, вариация или даже целый компонент) представлена в виде отдельной странички, на которой расписано, на что её заменять и какие платформы её используют.
При этом платформенные разработчики могут самостоятельно указывать ответственных за выпиливание каждой сущности из своего кода, а также удалять из списка свою платформу, когда сущность ей больше не используется.
Раз в неделю всем назначенным ответственным прилетает напоминание в слак о том, выпиливание каких депрекейтов от него требуется. Когда все платформы из какой-то сущности вычеркнулись, её можно удалять из дизайн-системы, и тогда уведомление об этом приходит уже нам.
Резюмируя
Особенности нашей дизайн-системы напрямую вытекают из особенностей самой компании IVI и её подхода к продукту.
С одной стороны, у нас много нативных клиентских приложений на различных платформах. С другой стороны, для нас важен «бесшовный» UI и UX: чтобы пользователь воспринимал наши приложения как единый сервис; чтобы независимо от того, с телефона или с телевизора он сейчас взаимодействует с IVI, было понятно, «где тут что находится и как работает».
Поэтому дизайн-систему мы организовали как единый источник правды, формат данных в котором пригоден для использования любой платформой независимо от её возможностей, ограничений и технологического стека. При этом наполнение этих данных таково, что интерфейс каждого нашего приложения остаётся узнаваемым, но в то же время учитывает особенности целевой платформы.
С точки зрения разработки, мы предоставляем данные о дизайне в формате, пригодном для использования любым из клиентских приложений IVI. При этом формат и инфраструктуру строим так, чтобы новый функционал появлялся рядом со старым, не ломая его. Мы отслеживаем использование устаревших частей системы, мотивируя платформы постепенно отказываться от них, что позволяет оперативно избавляться от ненужного.
Из второй части статьи вы узнаете о философии нашей дизайн-системы, её развитии, взаимодействии с дизайнерами и клиентскими разработчиками, а также о том, с какими трудностями мы сталкиваемся и как их преодолеваем.