</>404 Dev Found

· дизайн · 5 мин чтения

Дизайн-система как газон: читаем тропы, которые вытоптали команды

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

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

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

Газон не умирает за один день

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

Каждый случай разумен. Вместе они дают дрейф: исключений становится столько, что норма уже не отличается от нарушения.

Две карты одного парка
Две карты одного парка

Тропа — это голосование ногами

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

Я предлагаю читать тропы как данные. Не все они означают одно и то же:

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

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

Садовник нужен, и ему нужно время

У газона должен быть садовник. Не «все понемногу», а человек или маленькая команда, у которой поддержка системы записана в планы, а не делается в остаток между продуктовыми задачами. Триаж обращений, релизы, разбор исключений должны быть в roadmap, иначе их съест первая же срочная фича.

Первое, что я бы завёл, это журнал исключений. Скучный, короткий, обязательный:

исключение: кнопка с иконкой слева, высота 44 вместо 40
кто:        команда «Заказы» (вымышленный пример)
почему:     у нас длинные подписи, иначе переносятся
пересмотр:  начало следующего квартала

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

Асфальт тоже должен уметь заканчиваться

Вторая половина проблемы с обратной стороны: система не только позволяет тропам расти, но и сама оставляет за собой мусор. Устаревший компонент, который «пусть пока будет». Страница документации про вариант, которого уже нет в коде.

Поэтому компоненты и токены я считаю публичным API со всеми вытекающими:

  1. версии по semver, ломающие изменения только в major;
  2. пометка устаревшего и предупреждение прямо в типах, чтобы редактор ругался за вас;
  3. codemod, который переписывает старое использование автоматически;
  4. запрет нового использования в CI;
  5. удаление в следующем major.

Ритм тоже важен. Мелкие релизы раз в месяц-два, ломающие изменения пачкой и заранее объявленные, changelog к каждой версии. Команда должна знать, когда будет больно, и успеть подготовиться.

Пусть карту рисует машина

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

Документацию я бы вписал в definition of done: без примера, таблицы свойств и заметок о доступности компонент не готов. Какая сторона главная, макеты или код, спорят до сих пор. Всё чаще выбирают нейтральный контракт токенов и синхронизацию в одну сторону. Мне эта идея нравится: исчезает вопрос, кто прав.

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


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