Развитие библиотеки компонентов

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

Взяли Ant Design для Vue тогда еще v3, т.к. на тот момент это был самый адекватный вариант. Фреймворк позволил быстро собрать MVP, наладить работу с формами и таблицами и не углубляться в точечный пользовательский опыт. Но чем дальше, тем больше он мешал, и фронт начал терять время на борьбу с ограничениями, а интерфейс посыпался в нетепичных для фреймворка сценариях.

В таком виде на тот момент только что собранная команда дизайна получила продукт. Мы проработали так некоторое время, но пришлось остановиться и пересобрать подход.

От Ant Design к необходимости своей библиотеки

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

Процесс выглядел просто: дизайнер использует локальную копию антовского компонента в макете, разработчик находит его и подключает нужный элемент из Ant Design.

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

Я и еще 3 дизайнера пришли в команду, когда эта архитектура уже жила своей жизнью. До нас всё разрабатывалось на Ant Design около полугода, и мы ещё столько же продолжали на нём работать.

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

Это и стало триггером, с которого мы начали приводить всё в порядок.

Внутренняя дизайн-кухня и подготовительный этап

Сначала нужно было разобраться с чем мы живём, где у нас повторяется одно и то же под разными именами, а где вообще ад и самодеятельность.

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

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

Синхронизация ожиданий и подходов

Если бы мы внутри команды дизайна не договорились заранее о том, что есть «нормальный подход», библиотека родилась и тут же бы начала сыпаться. Один дизайнер оформлял бы состояние как вариант, другой – как вложенный атом. Отступы, нейминг, логика поведения – всё с самого начала должно было быть одниковым.
Чек-лист готовности к разработке компонента
Я организовал воркшоп, чтобы всё это проговорить: как мы работаем, что каждый ждёт от библиотеки, и как всё это должно выглядеть в продукте. Так сложились базовые договорённости о том, зачем дизайну библиотека, что мы считаем компонентом, а что – нет, и где проходит граница между продуктовым запросом и библиотекой (придумал что-то кастомное – ок, но в библиотеку это не попадёт просто так).

Всё это мы собрали в короткий гайд: кто за что отвечает, по каким правилам проектируем, что считаем валидным компонентом, как предлагать изменения. В итоге с самого старта библиотека стала общим инструментом (пока с т.з. регламентов), который мы договорились строить вдумчиво и со своим процессом внутри.

Структура

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

При этом мы отталкивались не только от удобства дизайнеров, но и от того, как Фигмой пользуется вся продуктовая команда.

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

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

На выходе пришли к общему формату, чтобы названия компонентов были одинаковыми и в Фигме, и в коде. Это сильно упростило поиск, переиспользование и обсуждение фич.
Пример структуры поля ввода
Мы написали краткий гайд как группировать компоненты, в каком порядке проектировать, какие состояния оформлять через варианты, а какие – как отдельные элементы.

В итоге команды начали ориентироваться в библиотеке без объяснений, а новые компоненты сразу ложились в нужную структуру.

Дизайн-токены

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

В основе названий токенов цвета лежит тональная шкала, где каждый цвет представлен рядом оттенков от светлого к тёмному. Такая структура не зависит от функционального назначения и цвет в ней существует сам по себе. Разделили палитру на группы Primary и Secondary, а внутрь каждой положили оттенки с градацией: –10, –20, –30 и т.д. Хватило и для интерфейса, и для визуализаций данных.
Палитра с Primary-токенами
Палитра с Secondary-токенами
С отступами поступили так же. Мы не стали делать степени вроде spacing.sm, spacing.xl, а просто завели переменные по 2-пиксельной сетке: space-2, space-4, space-6, space-8 и т.д. Привязка понятная и удобная и для дизайна, и для кода.

Кстати, это единственный объект в Variables, потому что так намного быстрее поменять значение в выпадающем списке, чем отвлекаться на клавиатуру.
Простая гибкая 2-пиксельная сетка
Мы договорились, что при проектировании каждый дизайнер использует только токены из библиотеки, а если токена не хватает, то не добавляет от себя, а пишет в канал библиотеки.

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

Составление плана реализации

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

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

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

На выходе у нас появился список ~15 компонентов, которые покрывали большую часть ключевых сценариев:
  • кнопки;
  • поля ввода;
  • чекбоксы, радио-кнопки, переключатели;
  • статусы и бейджи;
  • дропдауны;
  • табы и сегментация.

Каждый компонент проектировали сразу с учётом, типовых вариаций, поведения и технических особенностей реализации.
Пример реализованных компонентов
UI-паттерн Right Panel и его пропсы
Мы не пытались охватить всё. Цель была дать минимальный, но рабочий набор, чтобы можно было пересобирать существующие экраны уже на новых компонентах и не тратить время на кучу однотипных решений, а параллельно с дизайном готовили спецификацию: как выглядит, как работает, какие состояния поддерживает, какие кейсы закрывает.

Реализация и внедрение

Жизненный цикл компонента

Если просто отдать всё в разработку без процесса, библиотека моментально превратится в свалку. У каждого своё понимание «готовности», компоненты начнут собираться в обход и косяки станут попадать в прод.

Чтобы этого не случилось, мы вместе с фронтами собрали сквозной процесс прохождения компонента – от запроса до внедрения. Завели отдельную доску в Jira и договорились, что считается готовым на каждом этапе. Параллельно сформировали внутренний дизайн-процесс с момента, когда появляется потребность, до того, как компонент выходит на разработку:
  • для дизайна – полноценная спека: состояния, поведение, corner-кейсы и логика использования.
  • для фронта – архитектурная схема, зависимости, оценка трудозатрат и подготовка к внедрению.

А вот как выглядит процесс разработки.
Процесс разработки компонента с зонами ответственности
  1. Backlog: компонент попадает сюда, когда на него появляется запрос – новый или как доработка существующего.
  2. Design & Specification: проектируется само решение, собираются состояния и варианты использования, формируется спека.
  3. Design Approval: ревью внутри команды дизайна: всё ли понятно, не пропущены ли состояния, не дублируется ли с чем-то, что уже есть.
  4. Ready for Dev: компонент готов к разработке. Подключается фронт и оценивает сложность, задаёт вопросы. Если компонент «сложный», определяется запрос для внедрения.
  5. Tech Specification: зона ответственности фронтов. Они уточняют реализацию, структуру, зависимости, формируют архитектуру и ограничения.
  6. On TDR Approval: финальное согласование техчасти: чтобы всем было понятно, что именно и как будет делаться.
  7. Development: реализация компонента по всем спецификациям. Часто с промежуточной синхронизацией, если возникают пограничные кейсы.
  8. Code Review и Design Review: компонент проходит код-ревью, а затем финальную проверку у дизайнеров: всё ли отображается, как задумывалось, есть ли расхождения по поведению.
  9. Done: компонент считается реализованным и может использоваться в продукте.
Если на каком-то этапе всплывали баги или логические дыры, компонент откатывался назад в процесс. Например, после дизайн-ревью возвращались в Design & Specification, если не хватало состояния или не учитывали какой‑то сценарий. Это нормально. Важно было не «протащить», а сделать так, чтобы потом не переделывать в фичах.

Внутренний дизайн-процесс

Внешне всё выглядит просто: дизайнер передаёт компонент в разработку. Но на самом деле до этого момента происходит куча работы.

Чтобы компонент попал в продукт таким, каким его задумывали изначально и не развалился, у нас есть чёткий порядок как проверяем, что всё ок.
Начинается всё с ревью в дизайн-команде: компонент точно нужен, сценарий покрыт, не дублируем ли уже существующее, и можно ли будет это потом нормально использовать. Если что-то не стыкуется – идёт на доработку.

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

Чтобы не гадать, что считается «готовым», мы договорились: у компонента должна быть спека, он должен лежать в Storybook, покрывать реальные сценарии, быть использован или хотя бы зафиксирован в ближайшей задаче. Если чего-то из этого нет, компонент не считается готовым.
Внутренний дизайн-процесс разработки компонента
  1. Запрос: компонент не возникает «просто так». Его или запрашивает разработка, продакт или сам дизайнер. Мы фиксируем, зачем он вообще нужен, где будет использоваться и есть ли уже что-то похожее.
  2. Анализ: Когда понятно, что нужно, начинаем собирать состояния, размеры, поведение, corner-кейсы и прочее.
  3. Если компонент сложный и влияет на пользовательский сценарий, то подключаем продакта. Он не просто «одобряет», а помогает зафиксировать критичные моменты: кто видит, кто редактирует, что делать при ошибке или если нет доступа. Это вещи, которые из интерфейса не всегда очевидны, но без них фронты потом не смогут нормально реализовать компонент.
  4. Проектирование: компонент готов к разработке. Подключается фронт и оценивает сложность, задаёт вопросы. В случае «сложного компонента», определяется продуктовый запрос для внедрения.
  5. Формирование спеки: когда визуал собран, описываем поведение, состояния и связи с другими компонентами. Если нужно – делаем простой сценарий использования. Всё это фиксируем рядом с компонентом в той же Фигме.
  6. Внутреннее ревью: Перед передачей в разработку компонент проходит проверку внутри дизайн-команды. Цель – убедиться, что компонент актуален, не дублирует существующее, покрывает нужные сценарии и не оставляет открытых вопросов.
Отдельно зафиксировали, как работаем с обновлениями: если компонент уже есть в библиотеке, но нужно что-то поменять, то мы запускаем доработку как отдельную задачу. Спека обновляется, проходит ревью заново, и мы сразу проверяем, кого это может затронуть.

Внедрение

C самого начала мы продумали и то, как они будут встраиваться в продукт. Не в формате отдельного большого проекта, а прямо по ходу работы над запросом.

Все новые запросы проектируются с обновлёнными компонентами из библиотеки. Если ты делаешь что-то с нуля, то зачем тащить старое? Смотрим, какие элементы используются, и если чего-то нет – проектируем, обсуждаем, дорабатываем. Так компоненты сразу попадают в живую работу.

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

Если компонент комплексный и задевает пользовательский сценарий или поведение (обычно это что-то, где задействованы права, роли, логика переходов, критичные сценарии), внедряем его через продуктовый запрос через согласование с продактом: чем компонент влияет на опыт, нужно ли тестирование, есть ли риски. Согласовываем, в рамках какого запроса он поедет в прод, и запускаем оттуда.

Мы смогли запустить процесс, в котором все знают, где смотреть, с кем обсуждать и куда писать, если что-то пошло не так.

Поддержка и развитие

Когда библиотека только запускается, все вовлечены, всем интересно, всё что-то пилят. Но со временем ажиотаж спадает, поэтому заложили процессы, которые помогут системе жить дальше: аудит, обратную связь, документацию и понятные зоны ответственности.

Аудит и карта покрытия

Раз в квартал мы собираемся «рабочей группой» на синк, чтобы пройтись по библиотеке, чтобы понять, что где развалилось или устарело и подсвечиваем, что пора допилить, пересобрать или переосмыслить.

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

Фидбэк и запросы на изменения

Обратную связь собираем о продуктовой команды и саппорта.

Собираем всё это в рабочем режиме через Slack или синки (комментами в Фигме мы не пользуемся), коллекционируем в отдельном списке в Jira, который потом отдельно разбираем и что-то заносим в бэклог.

Если изменение касается только визуала или состояний, пускаем по ветке обычного апдейта компонента, но если затрагивается логика работы или влияет на сценарий пользователя, то обязательно заходит с привязкой к продуктовому запросу.

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

Как я уже писал выше, у нас есть общий Storybook и внутренняя дока в Фигме + канал в Slack.

Главная точка входа – Storybook. В нём лежат все компоненты с живыми примерами, неформальным описанием и вариациями. Там же и кейсы, состояния, важные нюансы поведения.
Компонент Button в Storybook
В Фигме и канале у нас:
  • changelog, где фиксируем что появилось нового и что изменилось в существующих компонентах;
  • глоссарий, чтобы не путаться в терминах и говорить на одном языке;
  • спека и примеры как надо, а как не надо с пояснениями.
Кусок спеки для хинта
Особенно это важно для новых людей – когда они получают доступ в Фигму, у них сразу есть точка входа и крадкое руководство как работает библиотека, где что лежит, что использовать, а что не трогать.

Зоны ответственности

Мы договорились ещё на старте, кто за что отвечает, и это помогает держать процессы в норме и не бегать в панике или тянуть всё на себе, а работать в связке.

Я, как дизайн-лид, отвечаю за архитектуру библиотеки, развитие, приоритеты и то, чтобы библиотека оставалась адекватной, под реальные задачи.

Ответственный front-dev следит за качеством реализации, поддержкой токенов и тем, чтобы Storybook не превращался в свалку.

Продакт помогает связывать задачи библиотеки с реальными задачами продукта. От его связки с дизайнером зависит в каком виде и содержании будет внедрён «сложный» компонент.

Дизайнеры инициируют запросы на компонента, готовят макеты, ревьюят, проверяют визуал.

И вот мы тут

Библиотека началась с желания навести порядок, но по пути превратилась в устойчивый процесс, который сейчас держит продукт: мы сократили время на разработку, согласовали пользовательский опыт и высвободили время для нормальной продуктовой работы.

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

Мы связали Фигму, Storybook и Jira в один стек, чтобы любой участник команды знал где искать, что смотреть и что актуально.
Кусок спеки для хинта
Для новых ребят собрали гайдлайны и выстроили простой онбординг, чтобы вливаться было проще. А ещё недавно у нас появился UX-писатель, который закроет потребность в связности интерфейса и языка. Надеемся, что благодаря ему продукт станет звучать понятнее и последовательнее.

Можно сказать, что сейчас у нас есть фундамент, и мы только начали свой путь к зрелому продукту с т.з. дизайна. Не всё идеально, ещё куча работы впереди, но маршрут понятен.
Made on
Tilda