mirror of
https://github.com/gromlab-ru/slm-design.git
synced 2026-08-22 07:30:16 +03:00
chore: Обновить ридми и CI скачивания скилла
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
---
|
||||
name: style-guide
|
||||
description: "Используй при создании, изменении, форматировании или ревью frontend-кода для соблюдения code style и style guide. Триггеры: JS, TS, JSX, TSX, HTML, CSS, .js, .ts, .jsx, .tsx, .module.css, React-компонент, props, стили, CSS Modules, JSDoc, документация, именование, импорты/экспорты, типизация, отформатировать по гайду, поправить кодстайл. НЕ используй для архитектуры SLM, выбора слоя/модуля/public API, генерации .templates, Next.js routing/data fetching/rendering, настройки PostCSS/tooling, backend-кода и вопросов без правки frontend-кода."
|
||||
description: "Используй при создании, изменении, форматировании или ревью frontend-кода и физическом оформлении уже спроектированных SLM-модулей по code style и style guide. Триггеры: JS, TS, JSX, TSX, HTML, CSS, .js, .ts, .jsx, .tsx, .module.css, React-компонент, Provider, Guard, Error Boundary, props, components/, providers/, modules/, ErrorCode, код ошибки, SCREAMING_SNAKE_CASE, стили, CSS Modules, JSDoc, документация, именование, импорты/экспорты, типизация, отформатировать по гайду, поправить кодстайл. НЕ используй для выбора владельца, слоя, модульной границы или public API по SLM, генерации .templates, Next.js routing/data fetching/rendering, настройки PostCSS/tooling, backend-кода и вопросов без правки frontend-кода; в смешанной задаче сначала примени slm-design."
|
||||
metadata:
|
||||
internal: true
|
||||
---
|
||||
|
||||
<!-- Generated from src/SKILL.md. Do not edit manually. -->
|
||||
@@ -38,6 +40,7 @@ description: "Используй при создании, изменении, ф
|
||||
| Переменные и функции | `camelCase` |
|
||||
| Классы, типы, React-компоненты | `PascalCase` |
|
||||
| Константы верхнего уровня | `SCREAMING_SNAKE_CASE` |
|
||||
| Собственные коды ошибок | `SCREAMING_SNAKE_CASE` |
|
||||
| Хуки | `useSomething` |
|
||||
| CSS-классы в CSS Modules | `camelCase` |
|
||||
| Enum-ключи | `SCREAMING_SNAKE_CASE` |
|
||||
@@ -89,6 +92,57 @@ description: "Используй при создании, изменении, ф
|
||||
- Имена соответствуют типу сущности и локальному стандарту проекта.
|
||||
- Комментарии объясняют причину или назначение, а не пересказывают код.
|
||||
|
||||
## Физическая структура SLM
|
||||
|
||||
Сначала определи архитектурную роль единицы по правилам `slm-design`. Этот раздел не выбирает владельца и не решает, нужен компонент или вложенный модуль: он задаёт обязательный путь после принятого архитектурного решения.
|
||||
|
||||
### Сопоставление единиц с каталогами
|
||||
|
||||
- Вложенные framework-компоненты, кроме `Provider`, размещай в `components/`.
|
||||
- `Guard` и `Error Boundary` считай framework-компонентами и размещай в `components/`.
|
||||
- Вложенные `Provider` размещай в `providers/`, а не в `components/`.
|
||||
- Вложенные SLM-модули размещай в `modules/`.
|
||||
- Внутри модуля не используй `ui/`, `parts/` или другой каталог как альтернативное имя для `components/`, `providers/` или `modules/`.
|
||||
- Не создавай эти каталоги заранее: добавляй каталог, когда в модуле появляется соответствующая единица.
|
||||
|
||||
```text
|
||||
checkout/
|
||||
├── index.ts
|
||||
├── checkout.tsx
|
||||
├── styles/
|
||||
├── types/
|
||||
├── components/
|
||||
│ ├── order-summary/
|
||||
│ ├── checkout-guard/
|
||||
│ └── checkout-error-boundary/
|
||||
├── providers/
|
||||
│ └── checkout-events-provider/
|
||||
└── modules/
|
||||
└── form-session/
|
||||
```
|
||||
|
||||
### Корневой framework-файл
|
||||
|
||||
Один главный framework-файл модуля может находиться непосредственно в корне, если он реализует или собирает ответственность модуля. Исключение распространяется и на главный `Provider`.
|
||||
|
||||
Корневой файл не дублируй в `components/` или `providers/`. Остальные компоненты и providers этого модуля размещай в соответствующих каталогах.
|
||||
|
||||
### Ограничение вложенности
|
||||
|
||||
- Единицы внутри `components/` и `providers/` являются соседями относительно модуля.
|
||||
- Каталог компонента или Provider не содержит собственные `components/`, `providers/` или `modules/`.
|
||||
- Следующий структурный уровень создавай только через вложенный модуль в `modules/`.
|
||||
- Runtime-вложенность JSX не повторяй файловой вложенностью: компонент может рендерить другой компонент, оставаясь его файловым соседом.
|
||||
|
||||
### Чеклист структуры SLM
|
||||
|
||||
- Архитектурная роль определена до выбора каталога.
|
||||
- Компоненты, Guards и Error Boundaries находятся в `components/`.
|
||||
- Вложенные Providers находятся в `providers/`.
|
||||
- Вложенные модули находятся в `modules/`.
|
||||
- Главный framework-файл является единственной корневой implementation-единицей модуля.
|
||||
- Компонентные каталоги не создают рекурсивную файловую иерархию.
|
||||
|
||||
## JS/TS
|
||||
|
||||
Применяй этот раздел к `.js`, `.ts` и JS/TS-частям `.jsx` и `.tsx`. Для React-компонентов дополнительно применяй раздел `React и TSX`, для разметки - раздел `HTML, JSX и TSX`.
|
||||
@@ -466,6 +520,28 @@ export type OrderFilters = {
|
||||
}
|
||||
```
|
||||
|
||||
#### Коды ошибок
|
||||
|
||||
- Собственные коды ошибок проекта записывай в `SCREAMING_SNAKE_CASE` независимо от способа их представления.
|
||||
- Не переименовывай непрозрачный код внешнего источника: сначала интерпретируй его на границе владельца и сопоставь с собственным кодом проекта.
|
||||
- Каждый type, объявляющий набор кодов ошибок, документируй многострочным JSDoc.
|
||||
- Каждый литерал в union кодов ошибок снабжай отдельным JSDoc непосредственно перед литералом.
|
||||
- Комментарий литерала объясняет ожидаемый исход, условие его возникновения или решение, которое по нему принимает потребитель.
|
||||
- Не пересказывай в комментарии имя кода и не объединяй несколько кодов одним комментарием.
|
||||
|
||||
```ts
|
||||
/**
|
||||
* Ожидаемые неуспешные исходы сценариев заказа.
|
||||
*/
|
||||
export type OrderErrorCode =
|
||||
/** Товар изменился после добавления в черновик заказа. */
|
||||
| 'PRODUCT_CHANGED'
|
||||
/** Запрошенное количество товара отсутствует на складе. */
|
||||
| 'INSUFFICIENT_STOCK'
|
||||
/** Заказ нельзя отменить в его текущем состоянии. */
|
||||
| 'CANNOT_CANCEL'
|
||||
```
|
||||
|
||||
#### Константы
|
||||
|
||||
- Документируй константу только если она является публичным контрактом, доменным ограничением, magic value или переиспользуемой конфигурацией.
|
||||
@@ -534,29 +610,36 @@ export const formatPrice = (value: number): string => {
|
||||
- Доменные guards размещены рядом с владельцем данных, а не в `shared/lib/value-predicates`.
|
||||
- Импорты типов оформлены через `import type`, а экспорты типов через `export type`.
|
||||
- Public API не раскрывает implementation details.
|
||||
- Собственные error codes записаны в `SCREAMING_SNAKE_CASE`, а каждый код имеет отдельный содержательный JSDoc.
|
||||
- JS/TS-функции, классы, типы, интерфейсы, поля типов, enum, значения enum и константы-контракты документированы по правилам своего подраздела.
|
||||
|
||||
## React и TSX
|
||||
|
||||
Этот раздел описывает прикладную форму React UI-сущности после того, как архитектура уже определила её место: компонент внутри `ui/` или UI-модуль с корневым `.tsx`. Архитектурные границы компонентов, модулей, сегментов и public API определяет `slm-design`. Форму JSX-разметки дополнительно проверяй по разделу `HTML, JSX и TSX`.
|
||||
Этот раздел описывает прикладную форму React framework-компонента после того, как архитектура уже определила его владельца и место. Правила распространяются на визуальные компоненты, Providers, Guards и Error Boundaries. Архитектурные границы компонентов, модулей, сегментов и public API определяет `slm-design`. Форму JSX-разметки дополнительно проверяй по разделу `HTML, JSX и TSX`.
|
||||
|
||||
### Базовая React UI-сущность
|
||||
### Обязательный обвес framework-компонента
|
||||
|
||||
- Используй эту форму для базового React-компонента или UI-модуля с корневым компонентом.
|
||||
- Используй эту форму для каждого React framework-компонента, включая Provider, Guard и Error Boundary.
|
||||
- Каждый вложенный framework-компонент размещай в отдельной папке согласно разделу `Физическая структура SLM`.
|
||||
- Держи `.tsx`, props-типы, CSS Module и локальный `index.ts` в отдельных файлах.
|
||||
- Файлы структуры обязательны даже для невизуального компонента без собственного DOM: `.tsx`, `types/`, `styles/`, `index.ts`.
|
||||
- Не объявляй props-типы внутри `.tsx`.
|
||||
- Не размещай CSS рядом с TSX-кодом: стили живут в `styles/{name}.module.css`.
|
||||
- Корневой CSS-класс всегда называется `.root`.
|
||||
- Для компонента с собственным DOM корневой CSS-класс называется `.root`.
|
||||
- Для невизуального компонента создай пустой CSS Module, но не импортируй его до появления стилизуемого DOM.
|
||||
- Не добавляй Provider, Guard или другой невизуальный компонент DOM-wrapper только ради использования CSS Module.
|
||||
- Компонент обязан иметь JSDoc-комментарий по React-шаблону.
|
||||
- Всё, что не является React-компонентом, документируй по правилам `Документирование JS/TS`.
|
||||
|
||||
### Структура файлов
|
||||
|
||||
- Базовая React UI-сущность живёт в собственной папке.
|
||||
- Файлы структуры обязательны для новой сущности: `.tsx`, `types/`, `styles/`, `index.ts`.
|
||||
- Вложенный framework-компонент живёт в собственной папке.
|
||||
- Имя файла props-типа строится как `{name}-props.type.ts`.
|
||||
- CSS Module строится как `{name}.module.css`.
|
||||
- `index.ts` экспортирует компонент и public props-тип.
|
||||
- Локальный `index.ts` экспортирует компонент и props-тип для использования внутри модуля.
|
||||
- Единственное исключение из собственной папки — главный framework-файл модуля, включая главный Provider.
|
||||
- Для главного framework-файла папкой компонента является корень модуля: `styles/` и `types/` создаются непосредственно в нём.
|
||||
- Корневой `index.ts` остаётся публичным фасетом модуля и экспортирует компонент только через фасет, разрешённый архитектурой и средой выполнения.
|
||||
|
||||
```text
|
||||
user-status/
|
||||
@@ -568,16 +651,29 @@ user-status/
|
||||
└── index.ts
|
||||
```
|
||||
|
||||
Корневой framework-файл использует тот же обвес без дополнительной папки:
|
||||
|
||||
```text
|
||||
module/
|
||||
├── index.ts
|
||||
├── <root-framework-file>.tsx
|
||||
├── styles/
|
||||
│ └── {name}.module.css
|
||||
└── types/
|
||||
└── {name}-props.type.ts
|
||||
```
|
||||
|
||||
### Типизация props
|
||||
|
||||
- Props-типы выноси в `types/{name}-props.type.ts`.
|
||||
- Собственные параметры компонента называй `{Name}Params`.
|
||||
- Атрибуты корневого HTML-элемента называй `RootAttrs`.
|
||||
- Атрибуты собственного корневого HTML-элемента называй `RootAttrs`.
|
||||
- Итоговый тип props называй `{Name}Props`.
|
||||
- `RootAttrs` типизируй через `ComponentPropsWithoutRef<'tag'>`.
|
||||
- Для компонента с собственным DOM типизируй `RootAttrs` через `ComponentPropsWithoutRef<'tag'>`.
|
||||
- Для Provider или другого компонента без собственного DOM не создавай фиктивный `RootAttrs`.
|
||||
- Исключай из `RootAttrs` атрибуты, которыми компонент управляет сам: например `children`, если компонент рендерит собственный контент.
|
||||
- Если собственный параметр конфликтует с HTML-атрибутом, исключай этот атрибут через `Omit`.
|
||||
- Документируй `Params`, `RootAttrs`, `Props` и каждое поле props по правилам `JS/TS`.
|
||||
- Документируй все объявленные `Params`, `RootAttrs`, `Props` и каждое поле props по правилам `JS/TS`.
|
||||
|
||||
```ts
|
||||
import type { ComponentPropsWithoutRef } from 'react'
|
||||
@@ -605,17 +701,20 @@ export type UserStatusProps = RootAttrs & UserStatusParams
|
||||
|
||||
### Реализация TSX
|
||||
|
||||
- В `.tsx` держи сам компонент, импорт props-типа, импорт CSS Module и импорт функции склейки классов.
|
||||
- В `.tsx` держи сам компонент и импорт props-типа.
|
||||
- CSS Module и функцию склейки классов импортируй только для компонента с собственным стилизуемым DOM.
|
||||
- Функцию склейки классов импортируй как `cl`: `import cl from 'clsx'`.
|
||||
- Компонент объявляй через `const` и именованный экспорт, если framework или локальный стандарт не требует другой формы.
|
||||
- Функциональный компонент объявляй через `const` и именованный экспорт, если framework или локальный стандарт не требует другой формы.
|
||||
- Нативный React Error Boundary разрешено объявлять классом, потому что React не предоставляет функциональный lifecycle для перехвата ошибок дочернего дерева.
|
||||
- Не используй `React.FC` по умолчанию.
|
||||
- Параметр компонента называй `props` и типизируй через `{Name}Props`.
|
||||
- Параметр функционального компонента называй `props` и типизируй через `{Name}Props`.
|
||||
- Возвращаемый тип компонента не указывай: TypeScript корректно выводит JSX-результат, а явный `ReactElement` сужает допустимые варианты возврата.
|
||||
- Деструктурируй props внутри тела компонента, а не в сигнатуре.
|
||||
- Из props обязательно выделяй `className` и `...rootAttrs`, если корневой элемент принимает HTML-атрибуты.
|
||||
- Прокидывай `rootAttrs` на корневой DOM-элемент.
|
||||
- Корневой элемент обязан получить `styles.root` первым CSS-классом.
|
||||
- Деструктурируй props функционального компонента внутри тела, а не в сигнатуре.
|
||||
- Из props выделяй `className` и `...rootAttrs`, если компонент имеет собственный корневой DOM-элемент и принимает его HTML-атрибуты.
|
||||
- Прокидывай `rootAttrs` на собственный корневой DOM-элемент.
|
||||
- Собственный корневой DOM-элемент обязан получить `styles.root` первым CSS-классом.
|
||||
- Внешний `className` добавляй последним аргументом в `cl(...)`.
|
||||
- Не добавляй невизуальному компоненту DOM-элемент, `className` или `rootAttrs`, если они не нужны его контракту.
|
||||
- Не создавай вложенный компонент внутри render без причины.
|
||||
- Не дублируй условия в JSX, если их можно выразить через заранее подготовленную переменную с понятным именем.
|
||||
- Для сложной разметки сначала упрощай данные и условия, потом JSX.
|
||||
@@ -668,11 +767,13 @@ export const UserStatus = (props: UserStatusProps) => {
|
||||
|
||||
### Стили
|
||||
|
||||
- CSS Module размещай в `styles/{name}.module.css`.
|
||||
- Корневой CSS-класс всегда называй `.root`.
|
||||
- CSS Module всегда создавай в `styles/{name}.module.css`.
|
||||
- Если компонент имеет собственный DOM, корневой CSS-класс называй `.root`.
|
||||
- `.root` описывает реальный корневой DOM-элемент компонента.
|
||||
- Дополнительные классы описывай рядом с `.root` и подключай через `styles.*`.
|
||||
- Не подменяй `.root` внешним `className`: внешний класс только дополняет `styles.root`.
|
||||
- CSS Module невизуального компонента оставляй пустым и не импортируй, пока у компонента не появится собственный стилизуемый DOM.
|
||||
- Не создавай DOM-wrapper только для применения `.root`.
|
||||
|
||||
```css
|
||||
.root {
|
||||
@@ -685,10 +786,11 @@ export const UserStatus = (props: UserStatusProps) => {
|
||||
|
||||
### Локальный экспорт
|
||||
|
||||
- В `index.ts` экспортируй компонент и public props-тип.
|
||||
- В локальном `index.ts` экспортируй компонент и props-тип.
|
||||
- Компонент экспортируй обычным named export.
|
||||
- Props экспортируй через `export type`.
|
||||
- Не экспортируй `Params` и `RootAttrs` наружу без необходимости.
|
||||
- Для корневого framework-файла используй публичный фасет модуля и не обходи его требования к среде выполнения.
|
||||
|
||||
```ts
|
||||
export { UserStatus } from './user-status'
|
||||
@@ -697,9 +799,10 @@ export type { UserStatusProps } from './types/user-status-props.type'
|
||||
|
||||
### Документирование компонентов
|
||||
|
||||
- Каждый React-компонент должен иметь многострочный JSDoc-комментарий.
|
||||
- Каждый React framework-компонент, включая Provider, Guard и Error Boundary, должен иметь многострочный JSDoc-комментарий.
|
||||
- Комментарий ставь непосредственно перед объявлением компонента.
|
||||
- Компонент документируй по React-шаблону, а не по шаблону функции из `JS/TS`.
|
||||
- Нативный Error Boundary, объявленный классом, также документируй по React-шаблону как компонент.
|
||||
- Компонент описывает назначение и сценарии применения.
|
||||
- Комментарий должен помогать понять, когда использовать компонент, без чтения реализации.
|
||||
- В `Используется для` указывай только реальные сценарии применения.
|
||||
@@ -737,15 +840,16 @@ export const UserStatus = (props: UserStatusProps) => {
|
||||
|
||||
### Чеклист React/TSX
|
||||
|
||||
- Базовая React UI-сущность имеет `.tsx`, `types/`, `styles/` и `index.ts`.
|
||||
- Props вынесены в `types/{name}-props.type.ts` и собраны из `{Name}Params`, `RootAttrs`, `{Name}Props`.
|
||||
- Каждый framework-компонент имеет `.tsx`, `types/`, `styles/` и локальный `index.ts`; главный framework-файл использует корень и фасет модуля.
|
||||
- Props вынесены в `types/{name}-props.type.ts`; `RootAttrs` добавлен только компоненту с собственным DOM.
|
||||
- Props-типы и поля props документированы по правилам `JS/TS`.
|
||||
- Компонент объявлен через `const`, принимает `props` и деструктурирует их внутри тела.
|
||||
- Функциональный компонент объявлен через `const`, принимает `props` и деструктурирует их внутри тела; нативный Error Boundary может быть классом.
|
||||
- Компонент не использует `React.FC` по умолчанию и не указывает возвращаемый тип без необходимости.
|
||||
- Корневой DOM-элемент получает `{...rootAttrs}` и `className={cl(styles.root, ..., className)}`.
|
||||
- CSS Module лежит в `styles/{name}.module.css`, корневой класс называется `.root`.
|
||||
- `index.ts` экспортирует компонент и props-тип.
|
||||
- Каждый React-компонент имеет комментарий по React-шаблону с назначением и сценариями применения.
|
||||
- Собственный корневой DOM-элемент получает `{...rootAttrs}` и `className={cl(styles.root, ..., className)}`.
|
||||
- CSS Module лежит в `styles/{name}.module.css`; у компонента с DOM корневой класс называется `.root`.
|
||||
- Невизуальный компонент имеет пустой CSS Module без неиспользуемого импорта и искусственного DOM-wrapper.
|
||||
- Локальный `index.ts` экспортирует компонент и props-тип; корневой компонент экспортируется через подходящий фасет модуля.
|
||||
- Каждый framework-компонент имеет комментарий по React-шаблону с назначением и сценариями применения.
|
||||
- Callback props названы через `on*`, внутренние обработчики - через `handle*`.
|
||||
- Named handlers и custom hooks документированы по правилам `JS/TS`; вызовы hooks и inline callbacks не документируются.
|
||||
- Hooks вызваны только на верхнем уровне компонента или custom hook.
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
interface:
|
||||
display_name: "Style Guide"
|
||||
short_description: "Frontend code style, naming and local consistency"
|
||||
default_prompt: "Use $style-guide to format or review frontend code according to the project style guide and local code conventions."
|
||||
Reference in New Issue
Block a user