~/wiki / figma-i-makety / komponenty-i-varianty-v-figma

Компоненты в Figma, которые не ломаются при обновлении: принципы опытных дизайнеров

Основной чат

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

$ cd раздел/ $ join vibe dev
Компоненты в Figma, которые не ломаются при обновлении: принципы опытных дизайнеров - обложка

Почему компоненты ломаются — и почему это не случайность

Каждый дизайнер, который проработал с Figma больше года, проходил через это. Открываешь файл после обновления библиотеки — а половина макетов в красных значках. Кнопки разъехались, иконки слетели на дефолт, у карточек пропали отступы, текст обрезался. Где-то instance отвалился от мастера, где-то auto layout схлопнулся, где-то переменные перестали резолвиться.

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

Ниже — принципы, которые отделяют живую библиотеку от той, которую все боятся обновлять.

Главный принцип: компонент проектируется под изменения, а не под текущий макет

Большинство компонентов ломаются по одной причине — их сделали под конкретный экран. Дизайнер взял кнопку из макета, нажал Create component, и положил в библиотеку. Через месяц появилась кнопка с иконкой справа, потом loading state, потом размер S, потом вариант danger. Каждое добавление — слом для тех, кто уже использует старую версию.

Правильный фрейминг: компонент — это контракт. Ты обещаешь команде, что у этого элемента такие-то свойства, такие-то состояния, такое-то API. И при обновлении контракт либо не меняется, либо меняется обратно-совместимо.

Что значит "обратно-совместимое обновление"

  • Свойства не переименовываются — даже если старое имя стало неудачным
  • Значения в variants не удаляются и не переименовываются
  • Дефолтные значения остаются такими же
  • Новые свойства добавляются с дефолтом, который повторяет старое поведение
  • Старые слои сохраняют те же имена — instance с override на text не должен слетать

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

Структура компонента: что закладывать сразу

Auto layout как основа, а не как украшение

Компонент без auto layout — это бомба замедленного действия. Любая правка текста или добавление иконки потребует ручного выравнивания во всех instance. С auto layout правильно настроенным — компонент сам пересобирается.

Чеклист по auto layout внутри компонента:

  • Все контейнеры имеют explicit resizing (Fill / Hug / Fixed) — не "по случайности"
  • Padding задан через переменные spacing, а не магические числа
  • Min-width / max-width проставлены там, где компонент может растянуться неадекватно
  • Текстовые слои — Fill container по ширине, Hug по высоте (для большинства случаев)
  • Иконки — fixed размер, Hug контейнер вокруг

Слои называются как в коде, а не как пришлось

Frame ২৪৭, Rectangle 12, button copy 3 — это утечка хаоса в библиотеку. Когда разработчик откроет компонент в Dev Mode или когда MCP-агент будет читать структуру, имена слоёв станут именами в коде или ссылками в подсказках. Мусорные имена = мусорный вывод.

Минимальная гигиена имён:

  • Корневой фрейм совпадает с именем компонента
  • Контейнеры — по роли: container, content, leading, trailing, label
  • Текстовые слои — по смыслу: title, description, не Text и не Заголовок 1
  • Иконки — icon-leading, icon-trailing, а не vector 28

Эти имена ещё и стабилизируют overrides. Если у слоя имя label, и пользователь поменял в нём текст, то при обновлении мастера override прилипнет к слою с тем же именем. Переименовал слой в новой версии — override слетел.

Антипаттерн: "один компонент на все случаи жизни"

Соблазн понятный: сделать одну универсальную Card с двадцатью boolean-свойствами — show image, show badge, show footer, show secondary action, show divider, has hover. На бумаге гибко. На практике — каждый instance выглядит уникально, а обновлять такого монстра больно: любая правка задевает десяток комбинаций, которые ты в голове не держишь.

Признаки, что компонент пора разрезать:

  • Больше 6–8 boolean-свойств
  • Variants комбинаторно взрываются (4 size × 3 type × 2 state × icon = 48 вариантов, из которых реально используются 6)
  • Внутри компонента есть слои, которые в половине случаев скрыты
  • На ревью никто не помнит, как включить нужный вид

Решение — композиция. Базовый Card без лишнего, отдельные slot-компоненты (CardHeader, CardMedia, CardFooter), которые собираются в конкретные паттерны на уровне страницы или паттерн-библиотеки.

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

Обновление компонента — это не действие "сохранил мастер". Это маленький релиз. У релиза есть подготовка, проверка и анонс. Если в команде живёт хотя бы три-четыре продукта на одной библиотеке, "по-быстрому подправил" превращается в десятки слетевших оверрайдов и злых сообщений в чате.

Цикл изменения: шесть шагов

  1. Опиши намерение словами. Что меняется, зачем, чей сценарий это закрывает. Если не получается сформулировать в одно предложение — изменение сырое, рано.
  2. Проверь существующие instance. Find instances в Figma, или прогон по основным макетам. Сколько мест задеты, какие там overrides, какие variants.
  3. Сделай изменение в ветке (branch). Не в основном файле библиотеки. Ветка — это staging, где можно ломать, не обрушивая прод.
  4. Прогон на реальных макетах. Подменяешь одну-две страницы на новую версию, смотришь, что стало с overrides, лейаутом, авторазмерами.
  5. Анонс и публикация. В канал команды — что меняется, что обратно совместимо, что требует миграции, есть ли deprecated-ветка.
  6. Замер последствий. Через день-два прошёлся по продуктам: где встал нормально, где разработчики жалуются, где появились "странные" instance.

Пятый шаг люди пропускают чаще всего. И именно из-за него к дизайн-системе перестают относиться как к продукту.

Версионирование без формального SemVer

Полный SemVer для библиотеки в Figma — обычно перебор. Достаточно трёх категорий изменения, которые ты честно проставляешь в описании публикации:

  • patch — визуальная правка, не задевает API: подвинул на 1 пиксель, поправил тень, заменил иконку на эквивалентную
  • minor — новые свойства, новые variants, новые состояния; всё старое работает как было
  • major — ломающее: переименование свойств, удаление variants, изменение дефолтов, перестройка структуры слоёв

major не делается тихо. Никогда.

Диагностика: как понять, что компонент уже сгнил

Симптомы видно невооружённым глазом, если знать куда смотреть. Прогон на ревью занимает минут двадцать.

Признаки гниющего компонента

  • В Assets лежит Button, Button new, Button v2, Button-final — никто не помнит, какой реально используется
  • На странице Components у мастера висит больше десятка detached копий вокруг — значит, его регулярно "разбирают", потому что неудобно
  • Variants выросли до сорока-пятидесяти, но в продукте встречаются шесть
  • Каждое второе использование — с overrides на размер, отступ, цвет; компонент перестал быть источником истины
  • Разработчики реализовали свой компонент в коде и игнорируют макеты — самый громкий сигнал

Быстрый аудит библиотеки

Раз в спринт-два пройди по библиотеке с этим списком:

  • У каждого компонента есть описание (Description) — что это и когда использовать
  • Нет дубликатов с похожими именами
  • Все опубликованные компоненты реально используются (Library analytics или ручной поиск)
  • Названия variants консистентны: size=sm/md/lg, а не size=small в одном и size=L в другом
  • Цвета и отступы внутри — через переменные, а не хардкод
  • Документировано, какие компоненты deprecated и чем заменяются

Типичные ошибки, которые ломают instance

Переименование слоёв "ради порядка"

Пятничный рефакторинг имён внутри компонента — главный источник тихих катастроф. Все overrides на text, fill, visibility привязаны к именам слоёв. Поменял label на Label — и десятки instance в продуктах потеряли свой текст. Если очень хочется навести порядок — делай это одним релизом, major, с предупреждением.

Удаление variant вместо deprecation

В компоненте есть type=ghost, который уже "не по гайдам". Соблазн — удалить. Реальность — instance, которые на нём стояли, превратятся в красные плашки missing. Правильно: оставить вариант, в Description пометить deprecated, через спринт-два, когда продукты переехали, удалить.

Скрытые слои вместо boolean property

Слой просто скрыт глазом — это не часть API компонента. Пользователь не догадается, что его можно включить. Любое состояние, которое реально используется, должно быть свойством с понятным именем, а не "если приглядеться, в мастере есть выключенный divider".

Переменные мимо коллекций

Раскидал spacing-токены по разным коллекциям, потому что "так получилось". При смене темы или брейкпойнта половина компонентов не переключается. Перед публикацией прогоняй компонент по всем режимам, которые у тебя есть: light/dark, desktop/mobile, brand A / brand B.

Как применять это в реальном макете

Дизайнеру удобно думать на двух уровнях: уровень страницы (продуктовый макет) и уровень системы (библиотека). Между ними должна быть граница.

На уровне макета ты собираешь экран из готовых instance, делаешь overrides только на контент (тексты, изображения, видимость опциональных частей). Никаких "подвину отступ на 4", "поменяю цвет фона на похожий", "отключу auto layout, чтобы влезло". Если хочется так сделать — это сигнал, что в компоненте не хватает свойства или паттерна, и его надо донести до системы.

На уровне системы ты не думаешь про конкретный экран. Ты думаешь про контракт: какие сценарии этот компонент закрывает, какие свойства нужны, как он себя ведёт в крайних случаях (длинный текст, отсутствие иконки, две строки, RTL).

Вопросы для ревью компонента перед публикацией

  • Что будет, если текст внутри станет в три раза длиннее?
  • Что будет, если контент пустой?
  • Как компонент ведёт себя при минимальной и максимальной ширине контейнера?
  • Все ли состояния (default, hover, focus, disabled, loading, error) описаны?
  • Совпадают ли имена свойств с тем, как это называется в коде у разработчиков?
  • Есть ли описание и пример использования в Description?
  • Что сломается у существующих instance после публикации?

Последний вопрос — главный. Если ответ "не знаю" — возвращайся к шагу 2 цикла обновления.

Короткий итог сегмента

Компонент живёт дольше макета, в котором он родился. Поэтому правила игры — не "красиво собрал", а "не сломал тех, кто уже использует". Auto layout как фундамент, осмысленные имена слоёв, явный API через свойства, обратно-совместимые апдейты, релиз с анонсом и аудит раз в спринт. Всё остальное — производное.

Когда в процесс заходит AI и MCP

AI-помощники в Figma и снаружи — это не "магическая кнопка сделать красиво", а ещё один потребитель твоей библиотеки. Если компоненты собраны нормально, AI получает понятный контракт: имена variants, описания, состояния — и собирает из них макет. Если компоненты — мешок фреймов с хардкодом, AI начнёт изобретать свои кнопки рядом с твоими, и в макете появится пять "primary button" разной степени похожести.

Что меняется, когда подключаешь AI/MCP-агента

  • Description у компонента перестаёт быть "когда-нибудь напишу". Это инструкция, которую читает не только новый дизайнер, но и модель: что это, когда использовать, чем отличается от соседа.
  • Имена свойств перестают быть внутренней шуткой. state=hover/active/pressed — понятно всем. state=foo/bar — гарантированный мусор на выходе.
  • Variants с одинаковым смыслом, но разными именами (size=md и Size=Medium в соседних компонентах) AI смешивает в произвольном порядке. Консистентность именования становится не вопросом вкуса, а вопросом качества генерации.
  • Все "неофициальные" компоненты в файле — черновики, эксперименты, старые версии — AI считает легитимными. Либо выноси в отдельную страницу _drafts, либо удаляй.

Анти-паттерны при работе с AI

  • Подключить MCP к проекту, в котором половина переменных хардкод, и ждать, что модель догадается. Не догадается. Сначала чистка библиотеки, потом автоматизация.
  • Сгенерировать экран ассистентом и опубликовать новые компоненты прямо из него. В библиотеке появятся Frame 482, Button copy 3, и через неделю их кто-то заюзает в продукте.
  • Доверить AI правку существующих компонентов без ревью. Любое изменение мастера = потенциальный сломанный instance в десятках файлов.

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

Командный контекст: как договариваться

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

Минимальный набор договорённостей

  • Кто owner библиотеки. Один человек или маленький круг, без которого мастер не меняется.
  • Где живёт changelog. Это может быть страница в Figma, канал в Slack, страница в Notion — главное, чтобы релиз без записи в changelog не считался релизом.
  • Как именуются свойства. Договоритесь один раз: size, variant, state, icon. Не type, kind, style вперемешку.
  • Как помечается deprecated. Префикс в имени, эмодзи-метка, отдельная секция — что угодно, но единообразно.
  • Что считается breaking change. Удаление variant, переименование property, удаление слоя с overrides — всё это требует анонса.

Как объяснять решение команде

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

  • "Если я переименую слой сейчас, у нас в трёх продуктах слетят тексты в кнопках. Чинить — день работы. Давай сделаем это в следующем major-релизе вместе с остальными правками."
  • "Этот вариант кнопки используется на checkout. Если удалим — у платежей появятся missing components. Помечаем deprecated, через спринт убираем."
  • "Свойство называется kind, потому что у разработчиков в коде так же. Если переименуем в type, перестанет совпадать с кодом и при ручной разработке начнут путаться."

Аргумент в терминах "сломаем такому-то продукту вот это" работает лучше, чем "это против гайдов".

Как проверять качество системы

Раз в спринт-два полезно делать короткий аудит — не глобальный редизайн, а гигиену.

Чеклист спринтового аудита

  • Прошёлся по Library analytics: есть ли компоненты с нулевым использованием за квартал?
  • Открыл 3–5 продуктовых файлов: много ли detached instance? Если да — чего не хватает в системе?
  • Проверил, что все опубликованные компоненты переключаются между всеми режимами переменных без визуальных сюрпризов.
  • Прошёл по deprecated-списку: что можно наконец удалить?
  • Сверил имена свойств между похожими компонентами (button, icon button, link) — одинаково ли называется одно и то же?
  • Описания у новых компонентов на месте?

Вопросы для ревью перед мержем библиотеки

  • Какие instance в продуктовых файлах изменятся после публикации?
  • Это breaking change? Если да — где анонс?
  • Появились ли в файле артефакты (frame copy, скрытые слои, локальные стили вместо переменных)?
  • Что в этом релизе deprecated и когда удаляется?
  • AI/MCP-инструменты, если подключены, увидят ли консистентную картину?

Короткий итог

Продвинутая работа с компонентами — это меньше про Figma и больше про коммуникацию: с будущим собой, с командой, с моделью, которая будет читать твою библиотеку. Описания, имена, changelog, deprecation — скучные вещи, которые экономят недели на разборе того, "почему у нас на проде поехала кнопка". Если система выдерживает AI-сборку, переезд между темами и нового дизайнера без брифа — она выдержит и обычный рабочий день.

Анти-паттерны, которые ломают библиотеку медленно

Самые опасные ошибки в компонентах — не те, что роняют файл сегодня, а те, что превращают систему в свалку за полгода. Они не заметны на одном PR, но видны, когда новый дизайнер приходит и говорит: "я не понимаю, какую кнопку брать". Ниже — список паттернов, которые стоит ловить на ревью раньше, чем они приживутся.

Компонент-матрёшка

Один компонент содержит другой, который содержит третий, и каждый со своими variants. На бумаге — мощно. На практике — instance в продукте получает 14 свойств, половина из которых не работает в текущей комбинации. Если уровней вложенности больше двух, спросите себя: это переиспользование или просто страх дублирования.

Кнопка на все случаи жизни

Variants: primary, secondary, ghost, link, text, outline, tonal, subtle, flat. Через полгода никто не помнит, чем ghost отличается от subtle. Признак беды — когда в команде на ревью спрашивают: "а это какая кнопка?" и ответ требует открыть мастер.

Слой, который держит весь компонент

В мастере есть слой bg, без которого падает auto layout, ломается padding и теряется radius. Никто этого не знает, пока кто-то не скроет его в overrides. Если у компонента есть "магический" слой — это техдолг, а не фича.

Свойства, которые ничего не делают

isLoading, hasIcon, showBadge — добавили "на будущее", но визуально ничего не меняют. На ревью выглядит безобидно, в продукте — генерирует ложные ожидания: дизайнер ставит галочку, ждёт спиннер, а его нет.

Локальные стили "только в этом файле"

"Я подкрашу здесь хедер локальным fill, потом перенесём в систему". Не перенесём. Через месяц это попадёт в скриншот для разработки, а ещё через месяц — в прод.

Тихое переименование

Property variant переименовали в kind, потому что "так понятнее". Опубликовали. В трёх продуктовых файлах overrides слетели в дефолт. Любое переименование свойства или variant — это breaking change, даже если буква одна.

Чеклист перед публикацией компонента

  • Имя соответствует конвенции команды, без copy, new, v2.
  • Все свойства реально влияют на визуал или поведение.
  • Auto layout не зависит от скрытого "магического" слоя.
  • Компонент протестирован во всех режимах переменных, которые поддерживает система.
  • Описание заполнено: для чего, где применять, чего избегать.
  • Нет локальных стилей — только токены/переменные.
  • Если это замена существующего — старый помечен deprecated, не удалён.
  • В changelog есть запись с пометкой breaking/non-breaking.

Вопросы, которые стоит задавать на ревью

  • Если этот компонент попадёт к новому дизайнеру без брифа, сможет ли он собрать из него типовой экран?
  • Что произойдёт с instance в продуктовых файлах после публикации — конкретно, с какими?
  • Какое свойство здесь самое непонятное и можно ли его убрать или переименовать сейчас, пока никто не использует?
  • Если завтра поменяется тема (тёмная, brand-вариант, плотная), что сломается первым?
  • Есть ли в этом релизе что-то, что должен знать фронтенд, чтобы не разойтись с кодом?
  • Что мы deprecate этим релизом и когда удалим окончательно?

Итог одной строкой

Компоненты не ломаются от обновлений — они ломаются от непрожитых решений: безымянных слоёв, лишних свойств, тихих переименований и "временных" локальных стилей. Дисциплина в мелочах — описания, единые имена, явные deprecation, прозрачные ревью — стоит дешевле, чем один разбор, почему на проде уехала кнопка.

$ cd ../ ← назад к Figma и макеты