Правила оформления компонентов: проверяемый список
Источник:
ds-docs/component-contracts/rules/component-rules.md— собирается изcomponent-rules.json
Версия каталога 1.0, снят 2026-09-09. Правила лежат рядом машинным списком —
component-rules.json; этот документ из него собирается, вручную его не правят.
Каждое правило — признак, который видно в файле, а не пожелание. У каждого есть,
где смотреть в выгрузке (dump) и как то же самое достаётся из Plugin API (figma), —
по ним пишется плагин-проверка.
| 🔴 ошибка | Нарушение договорённости, из-за которого компонент нельзя описать контрактом или перенести в код без потерь |
| 🟡 долг | Отступление, которое переживём, но оно копит долг: чинить при ближайшей правке компонента |
| ⚪ наблюдение | Наблюдение: не ошибка, но повод посмотреть глазами |
Свод
| Именование | 4 | 1 |
| Свойства | 5 | 0 |
| Оси | 5 | 0 |
| Версии | 4 | 2 |
| Токены | 6 | 1 |
| Текст | 4 | 2 |
| Слои | 6 | 0 |
| Платформа | 3 | 1 |
| Структура | 4 | 0 |
| Всего | 41 | 7 |
Именование
NAME-001 — Имя компонента — Pascal Case с пробелами
🟡 долг. «Аннотация Pascal Case, только с пробелом» — так компонент ищется в Assets и читается разработчиком
| В выгрузке | masters[*] — имя набора; ключ корневого узла дерева |
| В Plugin API | node.name у COMPONENT_SET и COMPONENT |
| Сообщение дизайнеру | Имя «{name}» не в Pascal Case с пробелом |
| Что делать | Переименовать: «Calculate Elephant Weight», а не «calculate_elephant_weight» |
| Проверяется скриптом | да |
NAME-002 — В имени нет смешанных алфавитов
🔴 ошибка. Слово выглядит латинским, а буква в нём кириллическая: компонент не находится поиском, слаг и имя переменной ломаются. В базе таких имён четыре: «Сalendar Widget», «Datе Input», «Icon Сontainer Сolor», ось «Сurrent slider»
| В выгрузке | имя набора, имя оси, значение оси, имя слоя |
| В Plugin API | node.name, componentPropertyDefinitions — ключи и variantOptions |
| Сообщение дизайнеру | В «{name}» смешаны алфавиты: {word} |
| Что делать | Заменить кириллические буквы на латинские (или наоборот — как задумано) |
| Проверяется скриптом | да |
NAME-003 — В имени нет лишних пробелов
🟡 долг. Двойной пробел и пробел на конце попадают в имя мастера и в путь узла: контракт и сверка видят два разных имени там, где дизайнер видит одно
| В выгрузке | ключи деревьев, имена мастеров |
| В Plugin API | node.name |
| Сообщение дизайнеру | Лишние пробелы в имени «{name}» |
| Что делать | Убрать двойные и краевые пробелы |
| Проверяется скриптом | да |
NAME-004 — Опечатки в известных словах
🟡 долг. Опечатка в имени оси или значения расходится с соседними наборами и попадает в контракт как есть
| В выгрузке | имена осей и значений |
| В Plugin API | componentPropertyDefinitions: ключи и variantOptions |
| Сообщение дизайнеру | Опечатка: «{value}» вместо «{right}» |
| Что делать | Переименовать свойство или значение |
| Проверяется скриптом | да |
Свойства
PROP-001 — Boolean-свойство названо «Show …»
🟡 долг. «Название свойства всегда должно иметь форму Show „Название слоя или компонента“»: иначе неясно, что именно гасится
| В выгрузке | defs: {имя: {type: BOOLEAN}} |
| В Plugin API | componentPropertyDefinitions[key].type === 'BOOLEAN' |
| Сообщение дизайнеру | Логическое свойство «{name}» названо не по правилу «Show …» |
| Что делать | Переименовать в «Show {название слоя}» |
| Проверяется скриптом | да |
PROP-002 — Instance swap назван «Swap … Container» и лежит во frame «… Container»
🟡 долг. «Компонент со свойством Instance swap должен быть помещён во frame [„Название“ Container]», а свойство названо «Swap „Название“ Container» — по этому имени видно точку подстановки
| В выгрузке | defs: {имя: {type: INSTANCE_SWAP}}; путь узла-цели |
| В Plugin API | componentPropertyDefinitions[key].type === 'INSTANCE_SWAP'; node.parent.name |
| Сообщение дизайнеру | Подстановка «{name}» названа не по правилу «Swap … Container» |
| Что делать | Завернуть во frame «{Название} Container» и назвать свойство «Swap {Название} Container» |
| Проверяется скриптом | да |
PROP-003 — Boolean вешается на контейнер, а не на компонент
🟡 долг. «Если есть необходимость скрыть слой через Boolean props, используйте это на frame [„Название“ Container], а не на компоненте»: иначе подстановка и видимость дерутся за один узел
| В выгрузке | props у инстанса + hidden |
| В Plugin API | componentPropertyReferences.visible на узле типа INSTANCE |
| Сообщение дизайнеру | Видимость повешена на инстанс «{name}», а не на его контейнер |
| Что делать | Перенести Boolean на frame-контейнер |
| Проверяется скриптом | да |
PROP-004 — Текстовые свойства названы по словарю
⚪ наблюдение. Словарь имён текста задан правилами: Label, Text, Description, Value, Placeholder, Default Value, Filled Value, Helper text, Warning message, Error message Empty/Filled и соседние
| В выгрузке | defs: {имя: {type: TEXT}} |
| В Plugin API | componentPropertyDefinitions[key].type === 'TEXT' |
| Сообщение дизайнеру | Текстовое свойство «{name}» вне словаря имён |
| Что делать | Взять имя из словаря либо предложить пополнение владельцу ДС |
| Проверяется скриптом | да |
PROP-005 — Свойства перечислены по расположению в компоненте, слева направо
⚪ наблюдение. Главное правило источника: «Properties должны выводиться по логике их расположения в компоненте (визуально), слева направо»
| В выгрузке | порядок ключей defs против порядка путей в дереве |
| В Plugin API | Object.keys(componentPropertyDefinitions) против координат целевых узлов |
| Сообщение дизайнеру | Порядок свойств не совпадает с их расположением в компоненте |
| Что делать | Пересобрать порядок свойств |
| Проверяется скриптом | нет — нужен плагин: координаты узлов, страницы макета, стопы градиента |
Оси
AXIS-001 — Ось Size названа значениями Small / Medium / Large / Max
🟡 долг. «Значения должны быть small (sm), medium (md), large (lg), max»: разнобой в размерах ломает сопоставление компонентов
| В выгрузке | имена мастеров: Size=… |
| В Plugin API | variantGroupProperties['Size'].values |
| Сообщение дизайнеру | Значение размера «{value}» вне ряда Small / Medium / Large / Max |
| Что делать | Переименовать значения оси |
| Проверяется скриптом | да |
AXIS-002 — Ось State названа значениями из словаря состояний
🟡 долг. Словарь состояний задан правилами: Default, Hovered, Focused Empty/Filled, Pressed, Filled, Filled Confirmed, Read Only, Warning, Warning Focused, Error Empty/Filled, Disabled Empty/Filled, Skeleton
| В выгрузке | имена мастеров: State=… |
| В Plugin API | variantGroupProperties['State'].values |
| Сообщение дизайнеру | Состояние «{value}» вне словаря состояний |
| Что делать | Взять значение из словаря либо предложить пополнение |
| Проверяется скриптом | да |
AXIS-003 — Ось с единственным значением не заводится
🟡 долг. Выбора нет, а ось есть: она множит имена мастеров и путает дизайнера
| В выгрузке | оси мастеров |
| В Plugin API | variantGroupProperties[key].values.length === 1 |
| Сообщение дизайнеру | Ось «{axis}» заведена с единственным значением «{value}» |
| Что делать | Убрать ось или добавить второе значение |
| Проверяется скриптом | да |
AXIS-004 — Количество не заводится осью
🟡 долг. Ось из чисел (2, 3, 4, 5…) делает по мастеру на каждое число: это должно быть свойством или слотом, а не решёткой
| В выгрузке | оси мастеров |
| В Plugin API | variantGroupProperties[key].values |
| Сообщение дизайнеру | Количество задано осью «{axis}» ({values}) |
| Что делать | Заменить на слот или Instance swap |
| Проверяется скриптом | да |
AXIS-005 — Решётка вариантов полна или объяснима
⚪ наблюдение. Если мастеров вдвое меньше, чем сочетаний осей, из макета не следует, какие сочетания живые: разработчик не знает, что собирать
| В выгрузке | число мастеров против произведения значений осей |
| В Plugin API | componentSet.children.length против variantGroupProperties |
| Сообщение дизайнеру | Решётка неполная: {count} мастеров при {full} сочетаниях |
| Что делать | Либо дособрать мастера, либо описать правило «какие сочетания живут» |
| Проверяется скриптом | да |
Версии
VER-001 — Отменённая версия помечена крестом в значении оси
⚪ наблюдение. Обе версии держат в одном наборе, чтобы продукт переходил сменой значения, а не свапом компонента. Отменённая ветка помечается «❌ Deprecated», живая — «🟢 Stable»
| В выгрузке | оси мастеров |
| В Plugin API | variantGroupProperties['Version'].values |
| Сообщение дизайнеру | Версия «{value}» помечена не по правилу «❌ Deprecated» / «🟢 Stable» |
| Что делать | Привести значения к «❌ Deprecated» и «🟢 Stable» |
| Проверяется скриптом | да |
VER-002 — Умолчание набора — живая версия
🔴 ошибка. Перетащив компонент в макет, дизайнер получает мастер по умолчанию. Если умолчание указывает на отменённую версию, старое расползается по макетам само
| В выгрузке | первый ключ masters |
| В Plugin API | componentSet.defaultVariant.name |
| Сообщение дизайнеру | Умолчание набора указывает на отменённую версию: {master} |
| Что делать | Переставить порядок мастеров так, чтобы первым шёл 🟢 Stable |
| Проверяется скриптом | да |
VER-003 — Отменённая ось или свойство не остаются в решётке
🟡 долг. Ось с крестом в имени («❌ Progress») стоит у каждого мастера и множит решётку, хотя выбирать в ней нечего
| В выгрузке | имена осей, defs |
| В Plugin API | variantGroupProperties и componentPropertyDefinitions — ключи |
| Сообщение дизайнеру | Отменённая ось «{axis}» осталась в решётке |
| Что делать | Убрать ось вместе с отменёнными мастерами |
| Проверяется скриптом | да |
VER-004 — Живой компонент не собран на отменённом
🔴 ошибка. Внутри живого стоит инстанс отменённой версии ребёнка — переход на новую версию не доведён, и долг расходится дальше по макетам
| В выгрузке | props у инстанса; of |
| В Plugin API | instance.componentProperties, instance.mainComponent.name |
| Сообщение дизайнеру | Внутри стоит отменённое: {child} — {prop} |
| Что делать | Переключить версию на 🟢 Stable или заменить компонент на живой |
| Проверяется скриптом | да |
Токены
TOK-001 — Отступы заданы токенами space, а не числами
🟡 долг. По базе 85 % ненулевых промежутков и 97 % полей уже стоят токеном: числа остаются там, где отступ подогнан под картинку
| В выгрузке | pad и L[3] числом вместо имени токена |
| В Plugin API | node.boundVariables.paddingLeft и соседние; itemSpacing |
| Сообщение дизайнеру | Отступ {value} задан числом, а не токеном space |
| Что делать | Привязать к переменной space-* |
| Проверяется скриптом | да |
TOK-002 — Отступ лежит на шкале space
🟡 долг. Шкала space: 0, 2, 4, 6, 8, 10, 12, 16, 20, 24, 32, 40, 48, 56, 64, 80. Значения вне её — подгонка, которую в коде не повторить
| В выгрузке | pad, L[3] |
| В Plugin API | paddingTop/Right/Bottom/Left, itemSpacing |
| Сообщение дизайнеру | Отступ {value} вне шкалы space |
| Что делать | Взять ближайшую ступень шкалы |
| Проверяется скриптом | да |
TOK-003 — Промежуток авто-слоя не оставлен умолчанием Figma
⚪ наблюдение. Новый авто-слой получает промежуток 10. В базе 99 таких мест: отступ никто не выбирал, он достался по умолчанию
| В выгрузке | L[3] === 10 без токена |
| В Plugin API | node.itemSpacing === 10 && !node.boundVariables.itemSpacing |
| Сообщение дизайнеру | Промежуток 10 — умолчание Figma, а не выбор |
| Что делать | Задать токеном либо поставить 0 |
| Проверяется скриптом | да |
TOK-004 — Скругление лежит на шкале radius
🟡 долг. Шкала radius: 0, 4, 6, 8, 12, 16, 20, 24, 32, 40, 999 плюс четыре особых. В базе нашлось 100 — вне шкалы
| В выгрузке | r |
| В Plugin API | cornerRadius, topLeftRadius и соседние |
| Сообщение дизайнеру | Скругление {value} вне шкалы radius |
| Что делать | Взять ступень шкалы; «полное скругление» — 999 |
| Проверяется скриптом | да |
TOK-005 — Скругление привязано к переменной
⚪ наблюдение. Из 3118 углов базы не привязан ни один: числа совпадают со шкалой, но связи с токеном нет — при смене шкалы макет не поедет за ней
| В выгрузке | r числом |
| В Plugin API | node.boundVariables.topLeftRadius и соседние |
| Сообщение дизайнеру | Скругление {value} задано числом, а не токеном radius |
| Что делать | Применить переменную radius-* |
| Проверяется скриптом | да |
TOK-006 — Цвет задан токеном, а не литералом
🔴 ошибка. Литеральный цвет не переключится в тёмную тему и не переедет в код. Исключение — логотипы и графика: у них токенов нет и быть не должно, цвет там часть рисунка. Признак исключения — обойма «Icon Container Color» либо слово-приставка в имени: «Logo /», «Bank Logo /», «Icon /», «Vector»
| В выгрузке | f вида rgb(…) |
| В Plugin API | fills[0].boundVariables.color; признак графики — имя главного компонента предка-инстанса и имена узлов пути |
| Сообщение дизайнеру | Цвет {value} задан литералом |
| Что делать | Привязать к переменной цвета |
| Проверяется скриптом | да |
Текст
TXT-001 — У надписи назначен текстовый стиль
🔴 ошибка. Без стиля начертание держится на переменных напрямую: контракт не может сослаться на стиль, а разработчик — понять, что это за текст
| В выгрузке | t === TEXT без st |
| В Plugin API | node.textStyleId === '' |
| Сообщение дизайнеру | У надписи «{name}» нет текстового стиля |
| Что делать | Назначить стиль из библиотеки |
| Проверяется скриптом | да |
TXT-002 — Переменная типографики не переопределена поверх стиля
🟡 долг. Текстовый стиль Astra DS сам собран из переменных (font-family, font-size, line-height, letter-spacing, font-weight) — переменные на узле это норма. Дефект другой: на узле стоит своя переменная, отличная от стиля. Тогда стиль перенастроят, а надпись за ним не пойдёт. Правило работает только там, где стиль читается: в файле дизайн-системы стили локальные и видны, в продуктовом файле они приходят библиотекой и своих привязок не отдают — там правило молчит
| В выгрузке | не виден: в выгрузке нет привязок самого стиля — правило проверяет только плагин |
| В Plugin API | aliasIds(node.boundVariables[key]) против aliasIds(style.boundVariables[key]); привязки у текста посегментные — это массивы |
| Сообщение дизайнеру | У надписи «{name}» переменная поверх стиля: {fields} |
| Что делать | Снять переменную с узла — пусть значение приходит из стиля; либо завести отдельный стиль |
| Проверяется скриптом | нет — нужен плагин: координаты узлов, страницы макета, стопы градиента |
TXT-003 — Цвет надписи не литеральный чёрный
🔴 ошибка. Литеральный чёрный — след обёртки «Text / …», где видимый цвет даёт прямоугольник ⚒︎ Text Color поверх надписи
| В выгрузке | t === TEXT, f === rgb(0,0,0) |
| В Plugin API | fills[0].color при пустом boundVariables |
| Сообщение дизайнеру | Цвет надписи «{name}» — литеральный чёрный |
| Что делать | Привязать цвет к переменной текста |
| Проверяется скриптом | да |
TXT-004 — Обрезка хвоста задана осями обёртки, а не руками
⚪ наблюдение. У обёртки «Text / …» есть оси Max Lines и Text Overflow: число строк и способ обрезки читаются оттуда. Полоска ⚒︎ Text Overflow Blur, положенная руками, — приём макета
| В выгрузке | путь узла содержит ⚒︎ Text Overflow Blur |
| В Plugin API | instance.mainComponent.name.startsWith('⚒︎ Text Overflow Blur') |
| Сообщение дизайнеру | Полоска размытия положена руками рядом с надписью |
| Что делать | Либо взять обёртку с Text Overflow=Blur, либо оставить и пометить в описании |
| Проверяется скриптом | да |
Слои
LAY-001 — Подкраска состояния не лежит поверх содержимого
🟡 долг. У слоя состояния два вида: обойма, внутри которой лежит содержимое, и служебный инстанс ⚒︎ State Layer, который кладут абсолютно поверх — так показывают нажатие, не плодя вариантов. Ни к тому, ни к другому порядок в стопке не относится. Правило остаётся для третьего случая: пустая обойма-подкраска, положенная последней, закроет собой содержимое
| В выгрузке | путь узла, наличие детей, abs, порядок в родителе |
| В Plugin API | node.children.length, node.layoutPositioning, индекс в parent.children |
| Сообщение дизайнеру | Пустая обойма состояния «{name}» лежит поверх содержимого |
| Что делать | Переставить под содержимое либо вложить содержимое внутрь обоймы |
| Проверяется скриптом | да |
LAY-002 — Слой состояния красится токеном своего состояния
🟡 долг. У слоя состояния своя таблица: наведение — hover-bg-dark (на тёмном -light), нажатие — press-bg-dark, фокус — focus-bg. Аудит базы нашёл три отклонения: Numkey красит фокус наведением, Tab Item — нажатие фокусом, Icon Button привязан к переменным без имени
| В выгрузке | f у узла State layer в мастере с нужным значением State |
| В Plugin API | fills[0].boundVariables.color → имя переменной через getVariableByIdAsync |
| Сообщение дизайнеру | В состоянии {state} слой красится «{token}», а не {expected} |
| Что делать | Поставить токен состояния по таблице фундамента |
| Проверяется скриптом | да |
LAY-003 — У обоймы состояния есть ось State
🟡 долг. Обойма «State layer …» красится по мастеру: без оси State у компонента состояний попросту нет. Исключение — служебный инстанс ⚒︎ State Layer: он несёт состояние своим свойством, ради того и заведён, чтобы не плодить варианты. Там оси у компонента может и не быть, и это норма
| В выгрузке | наличие State layer / 🥁 при отсутствии оси State |
| В Plugin API | поиск узла State layer и variantGroupProperties['State'] |
| Сообщение дизайнеру | Обойма состояния есть, а оси State нет |
| Что делать | Завести ось State со значениями Default, Hovered, Pressed |
| Проверяется скриптом | да |
LAY-004 — Скрытые слои не копятся в дереве
⚪ наблюдение. Слой лежит в дереве и гасится видимостью: события он ловить не перестаёт, а в код уезжает лишним узлом
| В выгрузке | hidden === true |
| В Plugin API | node.visible === false && !componentPropertyReferences.visible |
| Сообщение дизайнеру | Скрытый слой «{name}» без свойства видимости |
| Что делать | Удалить слой или завести Boolean «Show …» |
| Проверяется скриптом | да |
LAY-005 — Раскладка — авто-слой, а не сетка и не абсолют
⚪ наблюдение. Сетка (grid) и абсолютные слои в вёрстке разворачиваются иначе: контракт их пишет, но переносить их дороже
| В выгрузке | L[0] === 'GRID', abs === true |
| В Plugin API | node.layoutMode, node.layoutPositioning |
| Сообщение дизайнеру | Раскладка сеткой или абсолютное положение у «{name}» |
| Что делать | Переложить на авто-слой, если это не намеренное покрытие |
| Проверяется скриптом | да |
LAY-006 — Высота компонента — счётное число
⚪ наблюдение. «Хорошим тоном считается делать высоту компонентов счётным числом» — фиксировать токенами размера или min/max
| В выгрузке | wh[1] |
| В Plugin API | node.height |
| Сообщение дизайнеру | Высота {value} не кратна 4 |
| Что делать | Подогнать размеры слоёв или зафиксировать min/max |
| Проверяется скриптом | да |
Платформа
PLT-001 — Размер экрана не прибивается числом
🔴 ошибка. Размер устройства подставляет локальная коллекция режимов (Apple, Android, Bottom Nav Bar, Web, Internet Bank View, WebView). Это вариация показа, а не размер компонента: прибитые minHeight и maxHeight переносить в код нельзя
| В выгрузке | wh[1] из ряда высот экрана, minHeight === maxHeight === высоте |
| В Plugin API | node.height, node.minHeight, node.maxHeight |
| Сообщение дизайнеру | Высота экрана {value} прибита min/max |
| Что делать | Снять пределы: размер задаёт режим коллекции платформы |
| Проверяется скриптом | да |
PLT-002 — SYSTEM-слой — место платформы, а не компонент
⚪ наблюдение. Слои SYSTEM Status Bar, SYSTEM Bottom Nav Bar, SYSTEM Keyboard и соседние рисует операционная система: их не документируют и не верстают
| В выгрузке | имя узла |
| В Plugin API | instance.mainComponent.name.startsWith('SYSTEM') |
| Сообщение дизайнеру | SYSTEM-слой «{name}» внутри компонента |
| Что делать | Оставить как есть, но не переносить в код: это место под элемент платформы |
| Проверяется скриптом | да |
PLT-003 — Вставка безопасной зоны — отступ, а не слой
⚪ наблюдение. injected-safe-area-inset-top и -bottom в React присылает host-приложение переменной, во Flutter отступ проставляет платформа. Числа 50, 32, 48 — рост одного устройства
| В выгрузке | имя узла |
| В Plugin API | instance.mainComponent.name.startsWith('injected-safe-area') |
| Сообщение дизайнеру | Вставка безопасной зоны «{name}» стоит слоем |
| Что делать | Оставить в макете, но в код переносить отступом |
| Проверяется скриптом | да |
Структура
STR-002 — Эффект берётся стилем, а не выставляется руками
🟡 долг. Тень и размытие живут стилями эффектов: заданные руками, они расходятся между компонентами. Исключение — скелетон: мерцание загрузки собирают вручную, стиля под него в файле нет, и правило его не трогает
| В выгрузке | fx === 'none' при наличии эффекта |
| В Plugin API | node.effects.length && node.effectStyleId === '' |
| Сообщение дизайнеру | Эффект у «{name}» выставлен вручную |
| Что делать | Применить стиль эффекта |
| Проверяется скриптом | да |
STR-003 — Градиент собран на переменных
⚪ наблюдение. У полоски размытия каждый стоп привязан к переменной (layer-0N-blur-gradient-0M). Градиент из литералов в тёмной теме не переключится
| В выгрузке | f === 'GRADIENT_LINEAR' (стопы в выгрузку не попадают — проверять в плагине) |
| В Plugin API | fills[0].gradientStops[*].boundVariables.color |
| Сообщение дизайнеру | Градиент у «{name}» собран из литеральных цветов |
| Что делать | Привязать стопы к переменным |
| Проверяется скриптом | да |
STR-004 — Компонент не тянет чужую библиотеку без нужды
⚪ наблюдение. Значки приходят из подключённой библиотеки «Astra DS: Icons»: их переменные не входят в наши коллекции, и цвет им задаёт обойма
| В выгрузке | инстанс, чьё имя (of) есть в tools/figma-lint/library-names.json — компонент чужой библиотеки, которого нет у нас, — с литералом rgb в переопределении ov или в заливке f. Фирменная графика (Logo, Bank Logo, Brand) не в счёт. Хеш в VariableID:<хеш>/<id> — признак не нарушения, а нормы: значок покрашен переменной обоймы |
| В Plugin API | instance.mainComponent.remote === true |
| Сообщение дизайнеру | Компонент из чужой библиотеки красится сам |
| Что делать | Красить обоймой icon-container |
| Проверяется скриптом | да |
SRC-001 — Компонент пришёл из известной библиотеки
⚪ наблюдение. Внутри компонента дизайн-системы должны стоять компоненты той же системы или подключённой библиотеки значков. Чужой компонент — след копирования из продуктового файла: он не обновится вместе с системой
| В выгрузке | не виден: в выгрузке ключей компонентов нет — правило работает только в плагине |
| В Plugin API | mainComponent.remote и mainComponent.key против tools/figma-lint/library-registry.json |
| Сообщение дизайнеру | Компонент «{name}» не из наших библиотек |
| Что делать | Заменить на компонент Astra DS либо принести компонент в систему |
| Проверяется скриптом | нет — нужен плагин: координаты узлов, страницы макета, стопы градиента |
Отменённые правила
Правила, которые пробовали и сняли: признак оказался нормальной практикой, а не дефектом. Оставлены здесь, чтобы их не завели заново.
| Правило | Было | Почему снято |
|---|---|---|
STR-001 | Вложен набор, а не отдельный мастер | Вкладывать в компонент отдельный мастер — нормальная практика Astra DS, а не дефект: так берут нужный вид детали, и свойства набора у инстанса при этом остаются. Правило давало 110 срабатываний по базе, все ложные |
Откуда правила
- ../reference/guidelines/component-authoring-rules.md — «Правила оформления компонентов», версия 2.0 (buildin.ai)
- ../reference/guidelines/naming-tags.md — теги-префиксы и суффиксы
- foundations/*.md — фундаменты: state-layer, system-chrome, platform, versions, text-wrapper, space, radius
- skills/astra-component-contract/scripts/contract.mjs — валидатор контрактов: те же правила в коде
Как проверить
node rules/lint-dump.mjs dumps/badge.json
node rules/lint-dump.mjs --dir dumps --summary
Линтер применяет к выгрузке те правила, у которых auto: true. Остальные ждут плагина.