Конвенции макета Astra DS (references/figma-conventions.md)

Источник: ds-docs/src/skills/astra-figma-to-md/references/figma-conventions.md — справочник скилла astra-figma-to-md

Словарь, по которому читается Figma. Источник — «Правила оформления компонентов», версия 2.0 (документ команды дизайн-системы). Всё, что здесь написано, — договорённость дизайнеров, а не догадка парсера. Если в макете встретилось имя, не описанное здесь, — это находка, а не повод изобрести трактовку.

Именование

Pascal Case с пробелами — и для компонентов, и для слоёв: Calculate Elephant Weight, Middle Container, State layer. В документ имена переносятся дословно, без перевода и без придуманных якорей вроде A-01. Читатель должен найти слой в макете поиском по имени.

Префиксы в именах

✱ ИмяАтом. Часть большего компонента, в макетах напрямую не используетсяУзлом дерева с пометкой «по умолчанию». Внутрь не спускаться — у атома своя документация
⚒︎ ИмяКостыль. Слой, нарисованный потому, что иначе в Figma не выразить — а не потому, что так устроен компонентПоказать в дереве и назвать костылём: какого вида и что он делает. Геометрию не расписывать. Подробности — ниже
State layer, ⚒︎ State LayerСлой состояния: hover · focus · press · drag полупрозрачным покрытиемИмя узла ссылается на foundations/state-layer.md — там непрозрачности и разделение React / Flutter. В карточке они не повторяются
❌ Имя (используйте …)УстаревшееОдним абзацем в «Структуру», с указанием замены. Основой документа быть не может
🥁 ИмяАннотация хаптикиСлоем не документировать; сам факт хаптики и её идентификатор — в описание действия
SYSTEM ИмяПревью системного UI: строка статуса, домашний индикатор, кнопки Android, лист «Поделиться»Своей карточки не заводит. Рисует его операционная система, свойств у нас нет. В дереве родителя — узел с ролью и ссылкой на foundations/system-chrome.md. Внутрь не спускаться, высоту числом не писать
injected-safe-area-inset-*Невидимая распорка под системный элементТак же: узел со ссылкой на фундамент. Число из мастера — высота одного устройства, в код не идёт; пишется height: auto и opacity: 0

Костыли ⚒︎

Два молотка в имени слоя означают, что перед вами обход ограничения Figma, а не решение о компоненте. В коде такого слоя чаще всего нет вовсе: там это состояние, свойство или правило.

Читатель обязан узнать об этом из карточки, иначе он воспроизведёт костыль в коде. Поэтому узел называется костылём прямо — какого вида и что делает:

- **Роль:** костыль: цвет текста задан заливкой по маске, а не заливкой самого текстового слоя
- **Примечание:** в коде цвет — обычное свойство текста; маска нужна только Figma

Что встречается в библиотеке:

⚒︎ State Layer, ⚒︎ State Layer Entire Areaв Figma нет наведения и нажатиясостояние hover · press · focus, фундамент
⚒︎ Text Colorу компонента Text цвет не выведен свойствомобычный цвет текста; в Figma подменяется инстансом из 23 значений
⚒︎ Aspect Ratio/1:1нет пропорции как свойстваaspect-ratio
⚒︎ Blur, ⚒︎ Text Overflow Blur/*нет градиентного затухания текстаобрезка текста или маска градиентом

Список не закрыт: встретился незнакомый ⚒︎ — назвать его костылём, описать функцию и завести находку в аудит, чтобы список пополнился.

⚒︎ Text Color и группа Text. У компонентов Text визуал зашит в набор: стиль берётся именем набора (Text / Body / H3), а цвет приносит вложенный ⚒︎ Text Color. Свойством ни то ни другое не выведено, и по-другому эти компоненты не работают. В карточке это называется прямо, а не пересказывается как «цвет задан».

Контейнеры и слоты

[Имя Container]Фрейм под Instance swap — это слот. Квадратные скобки обязательны по конвенцииЗаменяемый контейнер. В «Свойствах» — строка Swap Имя Container. В документе скобки снимаются: слот помечается знаком ▣, скобки — разметка канваса
SlotФрейм со свободным контентом: можно менять padding и gapСамая свободная область наполнения. Описывать, что принимает и без каких ограничений
State layerПолупрозрачное покрытие, показывающее состояние. Обязано покрывать всю область измененияНе отдельной веткой дерева, а свойством слоя раскладки: «вся площадь — зона нажатия»

Скрывать слой полагается через Boolean на фрейме-контейнере, а не на самом компоненте. Поэтому выключатель всегда относится к [Имя Container], а не к тому, что внутри.

Слеш в имени набора — группа, а не ось

Basic List / Primary и Basic List / Secondary — это два разных набора, сложенных в Figma в одну группу. Слеш в имени работает как папка в панели ассетов: он не создаёт осей и не делает из двух наборов один.

Внутри одного раздела слеш схлопывается до общего имени. Карточка одна — на Basic List, — а то, что стоит после слеша, становится измерением в «Вариантах» наравне с обычными осями. Так разобран Navigation Bar: 19 наборов вида Navigation Bar/{размер}/{вид}/{фон}/{тон}/{действие} дали одну карточку с пятью измерениями.

Если наборы с общим префиксом лежат в разных разделах — карточки остаются разными. Общее имя тут случайно: разделы рисовали в разное время и по разным поводам, и сводить их в один документ значит склеивать то, что дизайнер держит порознь. Так живут Format Container / Text Container и Format Container / Text Container State — префикс общий, разделы разные, карточки отдельные.

Имя файла берётся от общего имени компонента, без слешей и без хвоста: navigation-bar.md, basic-list.md. Полное имя набора остаётся в заголовке документа.

Swapper и Swapper Utility — знак пустого места

Если в дереве стоит инстанс Swapper Utility или Swapper, это не элемент интерфейса. Это заглушка, которой дизайнер помечает: здесь ничего не нарисовано, сюда подставляют чужой компонент. На канвасе она выглядит как фиолетовый пунктирный прямоугольник со значком.

В документе это пишется прямо: «сюда подставляется другой компонент, по умолчанию пусто». Не «стоит компонент Swapper Utility» — читатель решит, что в макете есть что-то, чего там нет.

Заглушка всегда лежит внутри слота — [Имя Container] или Slot. Свойство подмены живёт на слоте, а не на самой заглушке: в «Свойствах» это Swap Имя Container.

Slot и Swap — одно и то же

Разница только в том, что разрешает Figma: Swap подставляет компонент, Slot принимает любые элементы. Со стороны реализации контракт один — «сюда подставляется чужое содержимое». Документировать их надо одинаково, не разводя на две сущности.

Компонент по умолчанию

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

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

Тип узла

Перед именем слоя в документе ставится знак его типа. Он отвечает на вопрос, чем узел является технически, — это нужно тому, кто верстает.

#FRAME, COMPONENT
▣SLOT
TEXT
○RECTANGLE, ELLIPSE, VECTOR, LINE
◆INSTANCE
△GROUP

Тип берётся из ответа get_metadata: там каждый узел приходит своим тегом — frame, slot, instance, text, symbol. Это единственный надёжный источник: по имени слоя тип не угадать.

Имена в документе

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

При переносе имени в документ убираются:

[Left Container]Left Container
Slot Container, Slot ListContainer, List
✱ Icon ContainerIcon Container
⚒︎ State Layerне выносится отдельной строкой, описывается свойством
❌ Basic List (используйте Basic List) / 2имя как есть — пометка устаревания несёт смысл

Если после снятия префиксов два слоя стали называться одинаково, различать их описанием роли, а не возвращать префикс.

Свойства компонента

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

TypeТип: варианты, сильно отличающиеся структурой
StyleВизуальный вариант: затрагивает все свойства компонента
SizeРазмер: sm, md, lg, max
StateСостояние: наведение, нажатие, заполнено, недоступно, ошибка
SelectedВыделение или выбор: True / False
Show Имя слояBoolean: показ слоя. Форма имени обязательна
Swap Имя ContainerInstance swap: замена содержимого. Имя совпадает с фреймом в слоях

Текстовые свойства именуются по смыслу: Label, Text, Description, Value — статичный текст; Placeholder — наполнитель; Default Value — значение по умолчанию; Filled Value — заполненное; Helper text — подсказка; Warning message — предупреждение; Error message Empty / Error message Filled — ошибки незаполнения и валидации; Disabled Empty / Disabled Filled — заблокированные состояния.

Аннотации

Заметки, которые дизайнер вешает на слой в Dev Mode. В них обычно то, что по свойствам не прочитать: какие части можно менять, что передаётся снаружи, в чём замысел варианта.

Аннотация относится к тому слою, на котором висит, и часто начинается с его имени: «Container. Можно передавать контент. Менять отступы».

Читаются наравне со свойствами и имеют приоритет над выводом из макета: то, что дизайнер написал словами, — правило, а конкретное значение в мастере при этом может быть просто умолчанием.

Устаревшее

Три признака: префикс ❌, имя вида «(используйте …)», ось Version со значением ❌ Deprecated. Устаревшие мастера живут в блоке ❖ Компонент наравне с живыми — это штатная ситуация, а не ошибка макета.

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

Словарь состояний

Значения State берутся отсюда. В документе оставлять английское имя как в макете, русское — пояснением.

DefaultПо умолчанию
HoveredНаведение
Focused EmptyФокус до ввода или выбора
Focused FilledФокус при вводе или выборе
PressedНажатие
FilledЗаполнено или выбрано
Filled ConfirmedЗаполнено и подтверждено
Read OnlyТолько чтение
WarningПредупреждение
Warning FocusedПредупреждение с фокусом
Error EmptyОшибка незаполнения
Error FilledОшибка валидации
Disabled EmptyЗаблокировано, не заполнено
Disabled FilledЗаблокировано, заполнено
SkeletonСкелетон

Текст спецификации в макете часто перечисляет состояния этого словаря как термины — это не доказательство, что вариант смоделирован. Состав вариантов определяют мастера, а не текст.

Статичный или кликабельный

Заменяет архетипы. Это внутреннее правило разбора: в шапку документа тип не пишется, но определить его надо — от него зависит, какие состояния компонент обязан иметь.

  • Статичный — по компоненту нельзя кликнуть, у него только информативные состояния.
  • Кликабельный — есть наведение, нажатие, фокус, выделение, перетаскивание, смахивание.

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

Размеры

Хорошим тоном считается счётная высота компонента, зафиксированная токеном размера либо min/max. Поэтому у высоты в документе всегда указывается, задана она жёстко или получается из содержимого — это разные вещи для вёрстки.

Атомарность

Компоненты организованы по атомарному дизайну: атом → молекула → организм → шаблон. Атом внутри компонента документируется ссылкой и ролью, не пересказом устройства. Дублировать документацию атома в карточке молекулы запрещено — она разъедется при первом же изменении атома.