Контракт компонента как источник задачи (references/design-contract.md)
Источник:
ds-skills/core-ui-development-skills/src/skills/build-core-ui-components/references/design-contract.md— справочник скилла build-core-ui-components
Контракт — машинное описание компонента, снятое с макета и проверенное валидатором:
один файл components/<slug>.yaml в базе ds-docs/component-contracts. Он заменяет чтение макета
глазами: состав, свойства, токены и правила уже разобраны и сверены с Figma.
Контракт только читать. Он лежит в чужом репозитории и правится дизайн-стороной; замечания к нему возвращать текстом, а не правкой файла.
Если контракта на компонент нет — работать по макету обычным порядком.
Что в контракте есть
source | файл Figma, id набора или секции, страница |
axes | оси вариантов: имя, значения, значение по умолчанию |
props | свойства компонента в макете: текст, булев переключатель, подмена |
slots | места подмены и что туда принимается (accepts) |
masters | сколько мастеров есть, сколько дала бы полная решётка, rules — какие сочетания существуют |
tokens | таблицы «значение оси → имя токена» |
bindings | $имя — ссылка на таблицу токенов, чтобы не повторять её в дереве |
anatomy | дерево узлов базового мастера: раскладка, размеры, заливки, текст |
variants | чем остальные мастера отличаются от базового: set, add, remove, swap, replace, move |
forms | несколько базовых деревьев под одной шапкой, если у семейства разные конструкции |
interaction | виброотклик: жест, событие, идентификатор, включён ли |
gaps | дыры макета: GAP — в источнике нет, SUSPECT — есть, но подозрительно |
Соответствие контракта и кода
axes[].name | словарь as const в constants.ts плюс тип через TValues |
axes[].default | значение по умолчанию в деструктуризации пропсов |
props[] type: text | строковый проп |
props[] type: boolean | булев проп |
props[] type: instance + slots[].accepts | проп ReactElement<IconProps> или children — по образцу соседей |
masters.rules | допустимые сочетания: отражать в типах или в логике, а не воспроизводить несуществующие |
ось Type Scale | вид под крупную типографику — не проп продукта, см. правила чтения ниже |
tokens.* со значением вида space-xs | var(--space-xs) в SCSS |
layout.gap, layout.padding | gap, padding модуля стилей |
size.width: fill / hug | растяжение и хват по образцу соседних компонентов |
fill, stroke.color, text.color | цветовые токены темы |
radius | var(--radius-*) |
text.style | миксин типографики set-typography с соответствующим стилем |
anatomy[].kind: instance + of | вложенный компонент библиотеки |
exposed: false | свойство вложенного компонента наружу не выносить |
exposed: true | кандидат в публичный API — см. проброшенные свойства |
overrides.fill у инстанса | цвет содержимого: чем покрашен вложенный значок |
interaction[].haptic | идентификатор виброотклика |
gaps | вопросы к дизайну, а не требования |
Правила чтения
- Имя токена переносится как есть. Контракт хранит имя-лист (
space-xs,bg-layer-02,radius-m), в коде этоvar(--space-xs). Имя всё равно проверить в теме проекта:src/theme/space.css,src/theme/radius.cssи соседние файлы. Совпадение имён — не гарантия существования переменной в текущей версии темы. - Число вместо имени токена — это дыра, а не значение. Если в контракте стоит
1,6,999, у макета там нет токена; в соответствующемgapsэто записано. Не подбирать токен по значению самостоятельно. $имяразворачивается поbindingsиtokens.fill: $rootFillозначает: взять таблицуtokens.rootFillи выбрать строку по значению оси.- Типографика — только именем стиля.
text: {style: Special/tag/tag-small}— это стиль файла целиком; размер, интерлиньяж и начертание в контракте не пишутся и подбирать их по отдельности не нужно. gapsне чинить. Это перечень мест, где макет неполон или противоречив. Дыра — повод задать вопрос, а не повод придумать значение.- Чего в контракте нет — того нет и в задаче. Формат не описывает тени, размытия и параметры анимации. Их отсутствие в файле не значит, что их нет в макете; значит, что они не сняты. Не додумывать.
- Ось макета не обязана стать осью кода. Дизайнер перечисляет сочетания значениями оси, потому что в Figma иначе нельзя. В коде та же ось часто раскладывается естественнее: ось из четырёх конфигураций «только подпись / значок слева / значок справа / значки с двух сторон» — это два необязательных пропса, а не проп с четырьмя значениями. Сверять надо перечень получающихся состояний, а не форму записи.
forms— это конструкции одного компонента, а не разные компоненты. Как их разложить в код — одним компонентом со свойствами или несколькими, — решать по правилам core-ui и по ближайшим аналогам.- Ось
Type Scale(Base/Scale) — не проп продукта. Это вид компонента под увеличенную типографику: с множителя ×1,2 конструкция переверстывается, ниже — остаётся базовой. Переключает его окружение, а не вызывающий код, поэтому значение оси наружу не выносится. В контракте видScaleстоит либо дельтами вvariants(дерево одно), либо отдельной формой (конструкций две) — и дальше это обычный выбор по предыдущему правилу. Каким механизмом окружение сообщает масштаб, контракт не описывает: это решение core-ui.
Ссылка на дизайн
source контракта даёт готовую ссылку для docs.mdx:
https://www.figma.com/design/<source.file>/Astra-DS?node-id=<source.set или source.component>&p=f&m=dev
Двоеточие в id заменить на дефис: 3185:17027 → 3185-17027. Это единственный случай, когда
Figma-ссылку можно собрать самому: она взята из контракта, а не придумана.
Порядок работы с контрактом
- Прочитать контракт целиком, включая
gaps. - Выписать публичный API: оси,
props, проброшенные наружу вложенные компоненты. - Сверить состав с существующими компонентами библиотеки: что уже есть и переиспользуется.
- Выписать токены и проверить каждое имя в теме проекта.
- Отметить дыры и допущения, которые придётся объявить.
- Собрать код и истории — см. истории из контракта.
- В отчёте назвать: что взято из контракта, что домыслено, какие дыры остались открытыми.