Словарь раскладки: нейтральный к платформе (references/layout-vocabulary.md)
Источник:
ds-docs/component-contracts/skills/astra-component-contract/references/layout-vocabulary.md— справочник скилла astra-component-contract
Карточка описывает слои словами CSS — так их отдаёт Figma MCP, и так проза читается вебом. Контракт этот словарь не повторяет: CSS — язык одной платформы, а контракт читает генератор кода под React, Flutter и что угодно дальше. Поэтому имена здесь — от модели Figma, из которой выводятся обе платформы, но без жаргона инструмента.
Принцип: одно понятие — одно слово; слово называет намерение («заполнить родителя»), а не приём платформы («flex: 1 0 0»).
Таблица соответствий
layoutMode: HORIZONTAL / VERTICAL / NONE | layout.direction: row / column / none | flex-direction: row / column; display: block | Row / Column / Stack |
primaryAxisAlignItems: MIN / CENTER / MAX / SPACE_BETWEEN | layout.mainAlign: start / center / end / spaceBetween | justify-content: flex-start / center / flex-end / space-between | mainAxisAlignment: start / center / end / spaceBetween |
counterAxisAlignItems: MIN / CENTER / MAX / BASELINE | layout.crossAlign: start / center / end / baseline / stretch | align-items: flex-start / center / flex-end / baseline / stretch | crossAxisAlignment: start / center / end / baseline / stretch |
itemSpacing | layout.gap | gap | spacing / SizedBox между детьми |
paddingTop/Right/Bottom/Left | layout.padding — число, токен, {vertical, horizontal} или {top, right, bottom, left} | padding | Padding(EdgeInsets…) |
layoutWrap: WRAP | layout.wrap: true | flex-wrap: wrap | Wrap |
layoutSizingHorizontal: HUG / FILL / FIXED | size.width: hug / fill / число / токен | width: auto / flex: 1 0 0 + align-self: stretch / width: Npx | внутренний размер / Expanded / SizedBox(width) |
layoutSizingVertical | size.height — те же слова | height | те же |
minWidth / maxWidth / minHeight / maxHeight | size.minWidth … | min-width … | ConstrainedBox(BoxConstraints…) |
layoutPositioning: AUTO / ABSOLUTE | position: flow / absolute | position: static / absolute | ребёнок Row/Column / Positioned в Stack |
x, y при ABSOLUTE + constraints | inset: {top, right, bottom, left} | top / right / bottom / left | Positioned(top: …) |
clipsContent | clip: true | overflow: hidden | clipBehavior / ClipRRect |
fills | fill: токен; заливки нет — fill: none | background | color / BoxDecoration.color |
strokes, strokeWeight, стороны | stroke: {color, weight, sides} | border | Border |
topLeftRadius … bottomLeftRadius | radius: {topLeft, topRight, bottomRight, bottomLeft} | border-radius четырьмя значениями | BorderRadius.only |
cornerRadius | radius: токен / число | border-radius | BorderRadius |
opacity | opacity: 0…1 | opacity | Opacity |
visible, привязан к булеву свойству | visibleWhen: <свойство> | условный рендер | if / Visibility |
characters, привязан к текстовому свойству | textFrom: <свойство> | проп | параметр String |
fontFamily, fontSize, lineHeight, fontWeight, letterSpacing | не пишутся: их несёт стиль — text.style | font-*, line-height, letter-spacing из класса стиля | TextStyle из TextTheme |
| цвет текста | text.color: токен | color | TextStyle.color |
textAlignHorizontal | text.align: start / center / end | text-align | textAlign |
maxLines | text.lines: число / auto | white-space: nowrap (при 1) | maxLines |
textTruncation: ENDING | text.truncate: ellipsis / none | text-overflow: ellipsis | overflow: TextOverflow.ellipsis |
componentProperties инстанса | props: {Имя: значение} | пропсы | аргументы конструктора |
overrides инстанса | overrides: {…} в этом же словаре | стили поверх компонента | обёртка |
textStyleId | text.style: имя стиля; поверх инстанса — overrides.textStyle | класс типографики | TextTheme |
explicitVariableModes | modes: {<коллекция>: <режим>} | тема или брейкпоинт, закреплённые на узле | Theme.of(context) на поддереве |
componentPropertyReferences.mainComponent | swapFrom: <свойство подмены> | проп-компонент | параметр Widget |
isExposedInstance | exposed: true / false | проп вложенного компонента в API родителя | параметр-объект вложенного виджета |
| слой состояния подкрашен | fill: токен на слое состояния (hover-bg-dark, focus-bg, press-bg-dark) | -hover / -pressed, см. foundations/state-layer.md | по той же основе |
| порядок детей | order: [имя, имя] на родителе | порядок в разметке | порядок в children |
Всё, чего в таблице нет, в контракт не пишется — идёт в gaps с текстом «свойство X не
переведено в словарь». Курсор-указатель и «интерактивность» — не свойства макета: Figma их
не хранит, и контракт их не выдумывает.
Слова
Там, где ждётся слово, скрипт принимает только эти:
layout.direction | row, column, none |
layout.mainAlign | start, center, end, spaceBetween |
layout.crossAlign | start, center, end, baseline, stretch |
size.* | hug, fill, число, токен |
position | flow, absolute |
text.align | start, center, end |
text.truncate | ellipsis, none |
text.lines | число, auto |
fill, stroke.color | токен или none |
kind | frame, text, shape, instance, slot, group |
Что скрипт считает CSS-словом
Если встретит у узла — ошибка с подсказкой:
flex-direction, display | layout.direction |
justify-content | layout.mainAlign |
align-items, align-self | layout.crossAlign (у родителя) |
flex, flex-grow | size.width: fill или size.height: fill |
padding, padding-* на узле | layout.padding |
gap на узле | layout.gap |
width, height, min-*, max-* на узле | size.width, size.minHeight … |
top, right, bottom, left на узле | inset |
background, background-color | fill |
border, border-color, border-width | stroke |
border-radius | radius |
overflow | clip |
font-family, font-size, line-height, font-weight, letter-spacing | text.style — имя стиля файла; что внутри, знает фундамент типографики |
color, text-align, text-overflow, white-space | text.color, text.align, text.truncate, text.lines |
cursor | ничего — курсор не свойство макета |
Почему не CSS — и когда CSS всё-таки
За нейтральный словарь: генератор Flutter не переводит flex: 1 0 0 в Expanded по догадке,
у каждого слова одно значение, и словарь совпадает с тем, что Figma и так хранит.
За CSS: его знают все разработчики; проза карточки уже на нём; для React перевод не нужен.
Второй вариант контракта — на CSS-именах — отличается только этим файлом и таблицей имён в скрипте. Всё остальное общее, так что сравнить можно на одном и том же компоненте.