@sberbusiness/triplex-next-mcp-server 0.24.0-beta2 → 1.40.0-beta
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -0
- package/bundle/components/AlertContext.md +268 -0
- package/bundle/components/BodyPage.md +186 -0
- package/bundle/components/Button.md +93 -85
- package/bundle/components/ButtonDropdown.md +36 -70
- package/bundle/components/ButtonDropdownExtended.md +422 -0
- package/bundle/components/ButtonIcon.md +41 -48
- package/bundle/components/Caption.md +291 -0
- package/bundle/components/Checkbox.md +43 -122
- package/bundle/components/CheckboxXGroup.md +109 -46
- package/bundle/components/CheckboxYGroup.md +77 -49
- package/bundle/components/CodeText.md +197 -0
- package/bundle/components/Col.md +311 -162
- package/bundle/components/CollapsibleTree.md +584 -0
- package/bundle/components/CollapsibleTreeExtended.md +422 -0
- package/bundle/components/Dropdown.md +748 -346
- package/bundle/components/EmptyView.md +14 -15
- package/bundle/components/FooterPage.md +203 -0
- package/bundle/components/Gap.md +115 -57
- package/bundle/components/HeaderPage.md +226 -0
- package/bundle/components/HelpBox.md +45 -84
- package/bundle/components/ImageGallery.md +423 -0
- package/bundle/components/ImageGalleryExtended.md +606 -0
- package/bundle/components/LightBox.md +2252 -233
- package/bundle/components/List.md +216 -183
- package/bundle/components/ListActionItem.md +157 -0
- package/bundle/components/ListItem.md +276 -0
- package/bundle/components/ListItemControlsButton.md +103 -0
- package/bundle/components/ListItemControlsButtonDropdown.md +107 -0
- package/bundle/components/ListItemSelectable.md +99 -0
- package/bundle/components/ListItemTable.md +390 -0
- package/bundle/components/ListMaster.md +876 -156
- package/bundle/components/ListMasterFooter.md +80 -0
- package/bundle/components/ListMasterHeader.md +86 -0
- package/bundle/components/ListSortable.md +153 -0
- package/bundle/components/ListSortableItem.md +175 -0
- package/bundle/components/ListTableItem.md +391 -0
- package/bundle/components/ModalWindow.md +427 -237
- package/bundle/components/MonthYearField.md +145 -109
- package/bundle/components/Notification.md +625 -155
- package/bundle/components/Overlay.md +271 -170
- package/bundle/components/Page.md +284 -186
- package/bundle/components/Pagination.md +206 -229
- package/bundle/components/Portal.md +131 -67
- package/bundle/components/Row.md +171 -69
- package/bundle/components/Text.md +320 -0
- package/bundle/components/TextField.md +364 -97
- package/bundle/components/Title.md +296 -0
- package/bundle/guides/codestyle.md +38 -11
- package/bundle/guides/commits.md +119 -26
- package/bundle/guides/context.md +34 -30
- package/bundle/guides/stories.md +110 -40
- package/bundle/guides/template.md +3 -7
- package/bundle/guides/tests.md +48 -2
- package/bundle/manifest.json +275 -30
- package/bundle/release-notes/1.26.0.mdx +33 -2
- package/bundle/release-notes/1.27.0.mdx +43 -0
- package/bundle/release-notes/1.28.0.mdx +25 -0
- package/bundle/release-notes/1.29.0.mdx +47 -0
- package/bundle/release-notes/1.30.0.mdx +56 -0
- package/bundle/release-notes/1.31.0.mdx +52 -0
- package/bundle/release-notes/1.32.0.mdx +35 -0
- package/bundle/release-notes/1.33.0.mdx +61 -0
- package/bundle/release-notes/1.34.0.mdx +35 -0
- package/bundle/release-notes/1.35.0.mdx +21 -0
- package/bundle/release-notes/1.35.1.mdx +11 -0
- package/bundle/release-notes/1.36.0.mdx +21 -0
- package/bundle/release-notes/1.37.0.mdx +71 -0
- package/bundle/release-notes/1.38.0.mdx +36 -0
- package/bundle/release-notes/1.39.0.mdx +66 -0
- package/bundle/release-notes/1.40.0.mdx +27 -0
- package/bundle/release-notes/1.41.0.mdx +7 -0
- package/package.json +1 -1
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
---
|
|
2
|
+
component: Title
|
|
3
|
+
category: Typography
|
|
4
|
+
related: [Text, Caption, CodeText]
|
|
5
|
+
tokens:
|
|
6
|
+
- --triplex-next-Typography-Primary_Color
|
|
7
|
+
- --triplex-next-Typography-PrimaryInvert_Color
|
|
8
|
+
- --triplex-next-Typography-Complementary_Color
|
|
9
|
+
- --triplex-next-Typography-ComplementaryInvert_Color
|
|
10
|
+
- --triplex-next-Typography-Secondary_Color
|
|
11
|
+
- --triplex-next-Typography-SecondaryInvert_Color
|
|
12
|
+
- --triplex-next-Typography-Tertiary_Color
|
|
13
|
+
- --triplex-next-Typography-TertiaryInvert_Color
|
|
14
|
+
- --triplex-next-Typography-Disabled_Color
|
|
15
|
+
- --triplex-next-Typography-DisabledInvert_Color
|
|
16
|
+
- --triplex-next-Typography-Brand_Color
|
|
17
|
+
- --triplex-next-Typography-BrandInvert_Color
|
|
18
|
+
- --triplex-next-Typography-Info_Color
|
|
19
|
+
- --triplex-next-Typography-InfoInvert_Color
|
|
20
|
+
- --triplex-next-Typography-Success_Color
|
|
21
|
+
- --triplex-next-Typography-SuccessInvert_Color
|
|
22
|
+
- --triplex-next-Typography-Warning_Color
|
|
23
|
+
- --triplex-next-Typography-WarningInvert_Color
|
|
24
|
+
- --triplex-next-Typography-Error_Color
|
|
25
|
+
- --triplex-next-Typography-ErrorInvert_Color
|
|
26
|
+
- --triplex-next-Typography-System_Color
|
|
27
|
+
- --triplex-next-Typography-SystemInvert_Color
|
|
28
|
+
stories: stories/Typography/Title.stories.tsx
|
|
29
|
+
version: "1.0"
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
# Title
|
|
33
|
+
|
|
34
|
+
## Назначение
|
|
35
|
+
|
|
36
|
+
Заголовок (типографика). Рендерит семантический heading `<h1>`–`<h3>` (тег по умолчанию совпадает со значением `size`) со шрифтом SBSansDisplay и цветом из палитры `EFontType`. `margin` у заголовков обнулён — отступы задаёт layout потребителя.
|
|
37
|
+
|
|
38
|
+
Используй когда: нужен заголовок страницы, секции, карточки или модального окна.
|
|
39
|
+
|
|
40
|
+
Не используй когда:
|
|
41
|
+
- Нужен обычный текст интерфейса — используй `Text`.
|
|
42
|
+
- Нужна крупная цифра/показатель (32px), не являющаяся заголовком — используй `Caption` с размером `D1`.
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## Варианты и props
|
|
47
|
+
|
|
48
|
+
### Обязательные props
|
|
49
|
+
|
|
50
|
+
| Prop | Тип | Описание |
|
|
51
|
+
|---|---|---|
|
|
52
|
+
| `size` | `ETitleSize` | Размер заголовка: `H1` (28/36px), `H2` (24/32px), `H3` (20/28px). В скобках — font-size/line-height. Значения enum — строки `"h1"`/`"h2"`/`"h3"`. |
|
|
53
|
+
|
|
54
|
+
### Опциональные props
|
|
55
|
+
|
|
56
|
+
| Prop | Тип | По умолчанию | Описание |
|
|
57
|
+
|---|---|---|---|
|
|
58
|
+
| `weight` | `EFontWeightTitle` | `SEMIBOLD` | Начертание: `REGULAR` / `MEDIUM` (500) / `SEMIBOLD` (600) / `BOLD` (700). Каждому соответствует своё семейство SBSansDisplay*. |
|
|
59
|
+
| `type` | `EFontType` | `PRIMARY` | Цвет текста из общей палитры типографики (11 базовых + 11 `*_INVERT`). |
|
|
60
|
+
| `underline` | `boolean` | — | Подчёркивание. Совместим со `strikethrough` (оба сразу — `underline line-through`). |
|
|
61
|
+
| `strikethrough` | `boolean` | — | Зачёркивание. |
|
|
62
|
+
| `tag` | `string` | значение `size` | HTML-тег корневого элемента. По умолчанию равен значению `size` (`"h1"`/`"h2"`/`"h3"`) — визуальный размер и уровень heading связаны. Передай `tag` явно, чтобы развязать их (например, `size={ETitleSize.H1} tag="h2"`). |
|
|
63
|
+
|
|
64
|
+
Компонент типизирован как `TTitleProps<T extends keyof JSX.IntrinsicElements>` и принимает все атрибуты соответствующего HTML-элемента через spread.
|
|
65
|
+
|
|
66
|
+
### Ограничения
|
|
67
|
+
|
|
68
|
+
- Внешний тип `forwardRef<HTMLElement, TTitleProps<keyof JSX.IntrinsicElements>>` «растворяет» дженерик: TypeScript не сужает атрибуты под конкретный `tag`. Известное ограничение публичного API, не исправлять без обсуждения (breaking).
|
|
69
|
+
- Дефолт `` tag = `${size}` `` — намеренный трюк (значения `ETitleSize` совпадают с именами тегов); при изменении значений enum сломается и дефолтный тег — ещё одна причина не трогать значения.
|
|
70
|
+
- `EFontType.BRAND` дополнительно задаёт `user-select: none` (особенность стилей `Typography.module.less`).
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## Дизайн-токены
|
|
75
|
+
|
|
76
|
+
Цвета — общие CSS-переменные семейства Typography (см. frontmatter): `--triplex-next-Typography-{Type}_Color` и `--triplex-next-Typography-{Type}Invert_Color`.
|
|
77
|
+
|
|
78
|
+
Размеры шрифта и line-height — фиксированные пиксельные значения в `styles/Title.module.less` (токенов для них нет).
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## Инварианты
|
|
83
|
+
|
|
84
|
+
- **`forwardRef`** — обязателен, `ref` пробрасывается на корневой heading-элемент.
|
|
85
|
+
- **Значения enum** `ETitleSize` (строки `"h1"`/`"h2"`/`"h3"`), `EFontWeightTitle`, `EFontType` — публичный API из barrel. Изменение — breaking change; значения `ETitleSize` дополнительно используются как дефолтный `tag`.
|
|
86
|
+
- **`TTitleProps`**, **`ITypographyProps`** — публичные типы.
|
|
87
|
+
- **`displayName = "Title"`** — не убирать.
|
|
88
|
+
- `margin: 0` на `h1`–`h3` в `Title.module.less` — контракт: отступы вокруг заголовка задаёт потребитель.
|
|
89
|
+
- Классы собираются только через `clsx`.
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## Accessibility
|
|
94
|
+
|
|
95
|
+
- По умолчанию рендерится настоящий heading (`<h1>`–`<h3>`) — уровень в accessibility-дереве определяется `size`. Следи за иерархией заголовков страницы; если визуальный размер не совпадает с нужным уровнем — задай `tag` явно.
|
|
96
|
+
- Компонент не интерактивный: focus management и keyboard navigation не применимы.
|
|
97
|
+
- Цвет (`type`) не передаёт семантику для screen reader'ов.
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## Связанные компоненты
|
|
102
|
+
|
|
103
|
+
- `Text` — основной текст интерфейса (B1–B4, SBSansText).
|
|
104
|
+
- `Caption` — мелкие подписи и крупный показатель D1.
|
|
105
|
+
- `CodeText` — моноширинный текст.
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## Stories
|
|
110
|
+
|
|
111
|
+
Основные истории: `stories/Typography/Title.stories.tsx`
|
|
112
|
+
Файлы примеров: `stories/Typography/examples/Title/`
|
|
113
|
+
|
|
114
|
+
| Story | Example file | Что демонстрирует |
|
|
115
|
+
|---|---|---|
|
|
116
|
+
| `Playground` | `Playground.tsx` | Интерактивный контроль props `size`, `weight`, `type`, `tag`, `underline`, `strikethrough` |
|
|
117
|
+
| `Default` | `Default.tsx` | Минимальное использование |
|
|
118
|
+
| `Sizes` | `Sizes.tsx` | Размеры H1 / H2 / H3 |
|
|
119
|
+
| `Weights` | `Weights.tsx` | Начертания REGULAR / MEDIUM / SEMIBOLD / BOLD |
|
|
120
|
+
| `Types` | `Types.tsx` | Все значения `EFontType`: базовые + инвертированные на тёмной подложке |
|
|
121
|
+
| `Decorations` | `Decorations.tsx` | `underline`, `strikethrough` и их комбинация |
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
## История изменений
|
|
126
|
+
|
|
127
|
+
| Дата | Изменение |
|
|
128
|
+
|---|---|
|
|
129
|
+
| 2026-07-20 | Создан документ. AI-рефакторинг: decoration-логика вынесена во внутренний хелпер `getTextDecorationClassName` (`utils.ts`), комментарии переведены в JSDoc, unit-тесты расширены (все значения `ETitleSize`/`EFontWeightTitle`, дефолтные heading-теги). Stories переведены на modern pattern (`examples/Title/`). |
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
## Примеры использования
|
|
134
|
+
|
|
135
|
+
### Default
|
|
136
|
+
|
|
137
|
+
`stories/Typography/examples/Title/Default.tsx`
|
|
138
|
+
|
|
139
|
+
```tsx
|
|
140
|
+
import React from "react";
|
|
141
|
+
import { Title, ETitleSize } from "@sberbusiness/triplex-next";
|
|
142
|
+
|
|
143
|
+
export const Default = () => <Title size={ETitleSize.H1}>Заголовок страницы</Title>;
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### Sizes
|
|
147
|
+
|
|
148
|
+
`stories/Typography/examples/Title/Sizes.tsx`
|
|
149
|
+
|
|
150
|
+
```tsx
|
|
151
|
+
import React from "react";
|
|
152
|
+
import { Title, ETitleSize } from "@sberbusiness/triplex-next";
|
|
153
|
+
|
|
154
|
+
export const Sizes = () => (
|
|
155
|
+
<div style={{ display: "flex", flexDirection: "column", gap: "16px" }}>
|
|
156
|
+
<Title size={ETitleSize.H1}>Заголовок H1</Title>
|
|
157
|
+
<Title size={ETitleSize.H2}>Заголовок H2</Title>
|
|
158
|
+
<Title size={ETitleSize.H3}>Заголовок H3</Title>
|
|
159
|
+
</div>
|
|
160
|
+
);
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### Weights
|
|
164
|
+
|
|
165
|
+
`stories/Typography/examples/Title/Weights.tsx`
|
|
166
|
+
|
|
167
|
+
```tsx
|
|
168
|
+
import React from "react";
|
|
169
|
+
import { Title, ETitleSize, EFontWeightTitle } from "@sberbusiness/triplex-next";
|
|
170
|
+
|
|
171
|
+
export const Weights = () => (
|
|
172
|
+
<div style={{ display: "flex", flexDirection: "column", gap: "16px" }}>
|
|
173
|
+
<Title size={ETitleSize.H2} weight={EFontWeightTitle.REGULAR}>
|
|
174
|
+
Regular - Обычный вес
|
|
175
|
+
</Title>
|
|
176
|
+
<Title size={ETitleSize.H2} weight={EFontWeightTitle.MEDIUM}>
|
|
177
|
+
Medium - Средний вес
|
|
178
|
+
</Title>
|
|
179
|
+
<Title size={ETitleSize.H2} weight={EFontWeightTitle.SEMIBOLD}>
|
|
180
|
+
Semibold - Полужирный
|
|
181
|
+
</Title>
|
|
182
|
+
<Title size={ETitleSize.H2} weight={EFontWeightTitle.BOLD}>
|
|
183
|
+
Bold - Жирный
|
|
184
|
+
</Title>
|
|
185
|
+
</div>
|
|
186
|
+
);
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### Types
|
|
190
|
+
|
|
191
|
+
`stories/Typography/examples/Title/Types.tsx`
|
|
192
|
+
|
|
193
|
+
```tsx
|
|
194
|
+
import React from "react";
|
|
195
|
+
import { Title, ETitleSize, EFontType } from "@sberbusiness/triplex-next";
|
|
196
|
+
|
|
197
|
+
export const Types = () => (
|
|
198
|
+
<div style={{ display: "flex", gap: "16px" }}>
|
|
199
|
+
<div style={{ display: "flex", flexDirection: "column", gap: "16px" }}>
|
|
200
|
+
<Title size={ETitleSize.H2} type={EFontType.PRIMARY}>
|
|
201
|
+
Primary
|
|
202
|
+
</Title>
|
|
203
|
+
<Title size={ETitleSize.H2} type={EFontType.COMPLEMENTARY}>
|
|
204
|
+
Complementary
|
|
205
|
+
</Title>
|
|
206
|
+
<Title size={ETitleSize.H2} type={EFontType.SECONDARY}>
|
|
207
|
+
Secondary
|
|
208
|
+
</Title>
|
|
209
|
+
<Title size={ETitleSize.H2} type={EFontType.TERTIARY}>
|
|
210
|
+
Tertiary
|
|
211
|
+
</Title>
|
|
212
|
+
<Title size={ETitleSize.H2} type={EFontType.BRAND}>
|
|
213
|
+
Brand
|
|
214
|
+
</Title>
|
|
215
|
+
<Title size={ETitleSize.H2} type={EFontType.INFO}>
|
|
216
|
+
Info
|
|
217
|
+
</Title>
|
|
218
|
+
<Title size={ETitleSize.H2} type={EFontType.SUCCESS}>
|
|
219
|
+
Success
|
|
220
|
+
</Title>
|
|
221
|
+
<Title size={ETitleSize.H2} type={EFontType.WARNING}>
|
|
222
|
+
Warning
|
|
223
|
+
</Title>
|
|
224
|
+
<Title size={ETitleSize.H2} type={EFontType.ERROR}>
|
|
225
|
+
Error
|
|
226
|
+
</Title>
|
|
227
|
+
<Title size={ETitleSize.H2} type={EFontType.DISABLED}>
|
|
228
|
+
Disabled
|
|
229
|
+
</Title>
|
|
230
|
+
<Title size={ETitleSize.H2} type={EFontType.SYSTEM}>
|
|
231
|
+
System
|
|
232
|
+
</Title>
|
|
233
|
+
</div>
|
|
234
|
+
<div style={{ display: "flex", flexDirection: "column", gap: "16px", backgroundColor: "#1F1F22" }}>
|
|
235
|
+
<Title size={ETitleSize.H2} type={EFontType.PRIMARY_INVERT}>
|
|
236
|
+
Primary Invert
|
|
237
|
+
</Title>
|
|
238
|
+
<Title size={ETitleSize.H2} type={EFontType.COMPLEMENTARY_INVERT}>
|
|
239
|
+
Complementary Invert
|
|
240
|
+
</Title>
|
|
241
|
+
<Title size={ETitleSize.H2} type={EFontType.SECONDARY_INVERT}>
|
|
242
|
+
Secondary Invert
|
|
243
|
+
</Title>
|
|
244
|
+
<Title size={ETitleSize.H2} type={EFontType.TERTIARY_INVERT}>
|
|
245
|
+
Tertiary Invert
|
|
246
|
+
</Title>
|
|
247
|
+
<Title size={ETitleSize.H2} type={EFontType.BRAND_INVERT}>
|
|
248
|
+
Brand Invert
|
|
249
|
+
</Title>
|
|
250
|
+
<Title size={ETitleSize.H2} type={EFontType.INFO_INVERT}>
|
|
251
|
+
Info Invert
|
|
252
|
+
</Title>
|
|
253
|
+
<Title size={ETitleSize.H2} type={EFontType.SUCCESS_INVERT}>
|
|
254
|
+
Success Invert
|
|
255
|
+
</Title>
|
|
256
|
+
<Title size={ETitleSize.H2} type={EFontType.WARNING_INVERT}>
|
|
257
|
+
Warning Invert
|
|
258
|
+
</Title>
|
|
259
|
+
<Title size={ETitleSize.H2} type={EFontType.ERROR_INVERT}>
|
|
260
|
+
Error Invert
|
|
261
|
+
</Title>
|
|
262
|
+
<Title size={ETitleSize.H2} type={EFontType.DISABLED_INVERT}>
|
|
263
|
+
Disabled Invert
|
|
264
|
+
</Title>
|
|
265
|
+
<Title size={ETitleSize.H2} type={EFontType.SYSTEM_INVERT}>
|
|
266
|
+
System Invert
|
|
267
|
+
</Title>
|
|
268
|
+
</div>
|
|
269
|
+
</div>
|
|
270
|
+
);
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
### Decorations
|
|
274
|
+
|
|
275
|
+
`stories/Typography/examples/Title/Decorations.tsx`
|
|
276
|
+
|
|
277
|
+
```tsx
|
|
278
|
+
import React from "react";
|
|
279
|
+
import { Title, ETitleSize } from "@sberbusiness/triplex-next";
|
|
280
|
+
|
|
281
|
+
export const Decorations = () => (
|
|
282
|
+
<div style={{ display: "flex", flexDirection: "column", gap: "16px" }}>
|
|
283
|
+
<Title size={ETitleSize.H2}>Заголовок без декораций</Title>
|
|
284
|
+
<Title size={ETitleSize.H2} underline>
|
|
285
|
+
Заголовок с подчеркиванием
|
|
286
|
+
</Title>
|
|
287
|
+
<Title size={ETitleSize.H2} strikethrough>
|
|
288
|
+
Заголовок с зачеркиванием
|
|
289
|
+
</Title>
|
|
290
|
+
<Title size={ETitleSize.H2} underline strikethrough>
|
|
291
|
+
Заголовок с подчеркиванием и зачеркиванием
|
|
292
|
+
</Title>
|
|
293
|
+
</div>
|
|
294
|
+
);
|
|
295
|
+
```
|
|
296
|
+
|
|
@@ -24,15 +24,15 @@
|
|
|
24
24
|
|
|
25
25
|
### Именование
|
|
26
26
|
|
|
27
|
-
| Сущность
|
|
28
|
-
|
|
29
|
-
| Interface
|
|
30
|
-
| Union type
|
|
31
|
-
| Enum
|
|
32
|
-
| Константа (модульного уровня) | UPPER_SNAKE_CASE
|
|
33
|
-
| Компонент
|
|
34
|
-
| Хук
|
|
35
|
-
| Утилита
|
|
27
|
+
| Сущность | Префикс | Пример |
|
|
28
|
+
| ----------------------------- | ----------------- | ------------------------------------- |
|
|
29
|
+
| Interface | `I` | `IButtonProps`, `IButtonGeneralProps` |
|
|
30
|
+
| Union type | `T` | `TButtonProps` |
|
|
31
|
+
| Enum | `E` | `EButtonTheme`, `EComponentSize` |
|
|
32
|
+
| Константа (модульного уровня) | UPPER_SNAKE_CASE | `DEFAULT_TIMEOUT` |
|
|
33
|
+
| Компонент | PascalCase | `Button`, `DateField` |
|
|
34
|
+
| Хук | camelCase с `use` | `useClickOutside` |
|
|
35
|
+
| Утилита | camelCase | `formatDate`, `uniqueId` |
|
|
36
36
|
|
|
37
37
|
### Интерфейсы компонента
|
|
38
38
|
|
|
@@ -113,10 +113,12 @@ import { Button } from "../Button";
|
|
|
113
113
|
```
|
|
114
114
|
|
|
115
115
|
Правила:
|
|
116
|
+
|
|
116
117
|
- В новых stories/examples, которые показывают копируемый код, импортируй публичный API из `@sberbusiness/triplex-next` или публичных subentry.
|
|
117
118
|
- В unit-тестах и внутреннем коде следуй локальному паттерну файла и предпочитай ближайшие импорты для тестируемого модуля и внутренних зависимостей.
|
|
118
119
|
|
|
119
120
|
Порядок импортов (prettier-plugin-organize-imports не используется, но придерживайся):
|
|
121
|
+
|
|
120
122
|
1. React
|
|
121
123
|
2. Сторонние библиотеки
|
|
122
124
|
3. Внутренние (`@sberbusiness/triplex-next/...`)
|
|
@@ -133,9 +135,31 @@ import { Button } from "../Button";
|
|
|
133
135
|
- Имена классов — **camelCase**: `styles.secondaryLight`, `styles.iconOnly`.
|
|
134
136
|
- Никаких **inline styles** в компонентах (в stories допустимо для лейаута примеров).
|
|
135
137
|
- **Цвета** — только через CSS-переменные токенов (`var(--triplex-next-...)`). Никаких hex/rgb.
|
|
138
|
+
- Runtime CSS-переменные, которые компонент задаёт сам (например через `style` для динамической высоты,
|
|
139
|
+
transform или координат), называй с префиксом `--triplex-next-runtime-...`.
|
|
140
|
+
Они не являются дизайн-токенами и не должны попадать в `src/components/DesignTokens` или generated-файлы.
|
|
136
141
|
- **Переиспользуемые размерные константы** (z-index, отступы страницы, ширины оверлеев) — через LESS-переменные из `src/styles/components/` (`@page-padding-desktop-x`, `@sideOverlayLGWidth` и т.д.). Компонент-специфичные значения (высота кнопки, радиус скругления) можно задавать литералом.
|
|
137
142
|
- `!important` — только в крайнем случае, с комментарием почему.
|
|
138
143
|
|
|
144
|
+
Паттерн runtime CSS-переменных:
|
|
145
|
+
|
|
146
|
+
```text
|
|
147
|
+
--triplex-next-runtime-{Component}-{Element}_{Property}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Примеры:
|
|
151
|
+
|
|
152
|
+
```tsx
|
|
153
|
+
interface IStyle extends React.CSSProperties {
|
|
154
|
+
"--triplex-next-runtime-ImageGalleryExtended-Track_Shift": string;
|
|
155
|
+
}
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
```less
|
|
159
|
+
.track {
|
|
160
|
+
transform: translateX(var(--triplex-next-runtime-ImageGalleryExtended-Track_Shift, 0%));
|
|
161
|
+
}
|
|
162
|
+
```
|
|
139
163
|
|
|
140
164
|
### Применение LESS-переменных (общие размерные константы)
|
|
141
165
|
|
|
@@ -166,7 +190,7 @@ import { Button } from "../Button";
|
|
|
166
190
|
В stories добавляй пример значения для демонстрации — это не хардкод, а иллюстрация:
|
|
167
191
|
|
|
168
192
|
```typescript
|
|
169
|
-
// В stories/examples/
|
|
193
|
+
// В stories/examples/Default.tsx — пример для документации
|
|
170
194
|
<ModalCloseButton aria-label="Закрыть" />
|
|
171
195
|
```
|
|
172
196
|
|
|
@@ -191,8 +215,11 @@ import { Button } from "../Button";
|
|
|
191
215
|
## Принципы написания кода
|
|
192
216
|
|
|
193
217
|
### DRY (Don't Repeat Yourself)
|
|
218
|
+
|
|
194
219
|
### KISS (Keep It Simple, Stupid)
|
|
220
|
+
|
|
195
221
|
### YAGNI (You Aren't Gonna Need It)
|
|
222
|
+
|
|
196
223
|
### Single Responsibility
|
|
197
224
|
|
|
198
225
|
### Не добавляй без задачи
|
|
@@ -202,4 +229,4 @@ import { Button } from "../Button";
|
|
|
202
229
|
- Не добавляй обработку ошибок для сценариев, которые не могут произойти.
|
|
203
230
|
- Не мигрируй legacy stories/tests на новый шаблон "по пути", если это не часть текущей задачи.
|
|
204
231
|
|
|
205
|
-
---
|
|
232
|
+
---
|
package/bundle/guides/commits.md
CHANGED
|
@@ -2,22 +2,40 @@
|
|
|
2
2
|
|
|
3
3
|
---
|
|
4
4
|
|
|
5
|
+
## Задачи и тикеты
|
|
6
|
+
|
|
7
|
+
Задачи ведутся в Linear, команда `TRI` (https://linear.app/triplex-next).
|
|
8
|
+
Номер задачи `TRI-XXX` — обязательный префикс веток и коммитов: по нему
|
|
9
|
+
GitHub-интеграция Linear линкует PR и двигает статусы задачи
|
|
10
|
+
(ветка → In Progress, PR → In Review, merge → Done).
|
|
11
|
+
|
|
12
|
+
**Legacy:** исторические ветки и коммиты используют префикс `TRIPLEX-XXX`.
|
|
13
|
+
Существующие не переименовываем; всё новое — только `TRI-XXX`.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
5
17
|
## Именование веток
|
|
6
18
|
|
|
7
|
-
**Формат:** `
|
|
19
|
+
**Формат:** `TRI-XXX-короткое-описание`
|
|
8
20
|
|
|
9
21
|
- Строчные буквы, слова через дефис.
|
|
10
|
-
- Всегда начинается с номера
|
|
22
|
+
- Всегда начинается с номера задачи Linear.
|
|
11
23
|
|
|
12
24
|
```text
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
25
|
+
TRI-12-add-badge-component
|
|
26
|
+
TRI-15-fix-button-focus-style
|
|
27
|
+
TRI-21-alert-ai-ready
|
|
16
28
|
```
|
|
17
29
|
|
|
18
30
|
**Исключения:**
|
|
19
|
-
- Релизная ветка: `
|
|
20
|
-
|
|
31
|
+
- Релизная ветка: `prerelease-X.Y.Z` (например, `prerelease-1.40.0`) — в неё
|
|
32
|
+
собираются фиксы релиза и бамп версии, PR идёт в `main`
|
|
33
|
+
- Перелитие main → release-0: выполняется без отдельной ветки, прямым мержем
|
|
34
|
+
|
|
35
|
+
Исключение касается только **имени ветки**. Коммиты внутри неё подчиняются
|
|
36
|
+
общему правилу `TRI-XXX`: на релиз заводится задача Linear, её номер идёт
|
|
37
|
+
префиксом (`TRI-XXX Подготовка релиза 1.40.0`). Legacy-префикс `TRIPLEX-0`
|
|
38
|
+
для новых релизов не используется.
|
|
21
39
|
|
|
22
40
|
---
|
|
23
41
|
|
|
@@ -28,29 +46,34 @@ TRIPLEX-912-fix-button-focus-style
|
|
|
28
46
|
| `main` | React 18 | `1.xx` | Основная ветка разработки |
|
|
29
47
|
| `release-0` | React 17 | `0.xx` | Поддержка React 17, синхронизируется с main |
|
|
30
48
|
|
|
31
|
-
**Правило:** все фича-ветки создаются от `main`. Изменения попадают в `release-0` через
|
|
49
|
+
**Правило:** все фича-ветки создаются от `main`. Изменения попадают в `release-0` через перелитие. Агент не должен создавать ветки от `release-0` и не должен мерджить в неё напрямую.
|
|
50
|
+
|
|
51
|
+
**Единственное исключение** — skill `release-react17` в рамках выпуска релиза:
|
|
52
|
+
он мержит `main` в `release-0` и пушит напрямую, без PR. Там это компенсируется
|
|
53
|
+
обязательными локальными гейтами (`tsc`, `test-unit`, `build`) и показом diff
|
|
54
|
+
разработчику — `ci.yml` триггерится только на `pull_request` и прямой push
|
|
55
|
+
не проверяет. Вне релиза перелитие остаётся за мейнтейнерами.
|
|
32
56
|
|
|
33
57
|
---
|
|
34
58
|
|
|
35
59
|
## Формат коммитов
|
|
36
60
|
|
|
37
|
-
**Формат:** `
|
|
61
|
+
**Формат:** `TRI-XXX Краткое описание`
|
|
38
62
|
|
|
39
63
|
```text
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
TRIPLEX-912 Исправить стиль фокуса для Button в теме Link
|
|
64
|
+
TRI-12 Добавить компонент Badge с темами и размерами
|
|
65
|
+
TRI-15 Исправить стиль фокуса для Button в теме Link
|
|
43
66
|
```
|
|
44
67
|
|
|
45
68
|
Если нужно уточнение — добавляй через двоеточие:
|
|
46
69
|
|
|
47
70
|
```text
|
|
48
|
-
|
|
49
|
-
|
|
71
|
+
TRI-12 Badge: добавить тему DANGER и размер SM
|
|
72
|
+
TRI-21 Alert: AI refactoring + unit-тесты
|
|
50
73
|
```
|
|
51
74
|
|
|
52
75
|
**Правила:**
|
|
53
|
-
- Все коммиты в ветке начинаются с одного номера
|
|
76
|
+
- Все коммиты в ветке начинаются с одного номера задачи.
|
|
54
77
|
- Первая строка — не длиннее 72 символов.
|
|
55
78
|
- Тело коммита опционально (для сложных изменений).
|
|
56
79
|
- Язык: русский или английский — не смешивать в одном коммите.
|
|
@@ -86,7 +109,6 @@ npx prettier --write src/components/Button/Button.tsx
|
|
|
86
109
|
| Файл/папка | Причина |
|
|
87
110
|
|---|---|
|
|
88
111
|
| `__screenshots__/` | Только из Docker/CI. Если нужно — подтвердить в pre-commit hook |
|
|
89
|
-
| `.mcp.json` | Персональный токен Figma — в `.gitignore` |
|
|
90
112
|
| `.env.local` | Секреты — в `.gitignore` |
|
|
91
113
|
| `node_modules/`, `dist/`, `storybook-static/` | В `.gitignore` |
|
|
92
114
|
|
|
@@ -100,30 +122,101 @@ npx prettier --write src/components/Button/Button.tsx
|
|
|
100
122
|
|
|
101
123
|
## Когда коммитить и пушить
|
|
102
124
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
125
|
+
**Вне задачи Linear агент не создаёт коммиты и не пушит самостоятельно.**
|
|
126
|
+
После завершения работы — остановиться и показать результат разработчику.
|
|
127
|
+
Коммит и пуш — только по явной просьбе.
|
|
128
|
+
|
|
129
|
+
**Исключение — работа по задаче Linear.** Если работа ведётся в ветке задачи
|
|
130
|
+
`TRI-XXX-...` (взятой через skill `take-task`), агент после завершения работ
|
|
131
|
+
и зелёного ревью (`change-reviewer`) **без подтверждения**:
|
|
132
|
+
|
|
133
|
+
1. делает коммит по конвенциям этого файла (skill `commit-component`);
|
|
134
|
+
2. пушит ветку;
|
|
135
|
+
3. создаёт PR (см. «PR-воркфлоу»);
|
|
136
|
+
4. если менялись stories или визуал компонентов — обновляет baseline-скриншоты
|
|
137
|
+
через skill `update-visual-baselines` (CI-workflow «Update Visual
|
|
138
|
+
Snapshots» + чистка orphan-скриншотов);
|
|
139
|
+
5. запускает skill `finish-task` — комментарий-резюме публикуется в задачу
|
|
140
|
+
без подтверждения, проверяется линковка PR;
|
|
141
|
+
6. запускает агента `pr-reviewer` — независимое ревью PR «с чистого листа»
|
|
142
|
+
с комментариями в GitHub (только COMMENT, вердикт и мерж за человеком).
|
|
143
|
+
|
|
144
|
+
Гейты остаются обязательными и в автоматическом режиме — при любом из них
|
|
145
|
+
остановиться и спросить разработчика:
|
|
146
|
+
|
|
147
|
+
- упавшие проверки (tsc / vitest / eslint);
|
|
148
|
+
- изменение публичного поведения без записи в release notes;
|
|
149
|
+
- блокеры от `change-reviewer`;
|
|
150
|
+
- подозрительные/посторонние файлы в `git status`.
|
|
106
151
|
|
|
107
152
|
---
|
|
108
153
|
|
|
109
|
-
##
|
|
154
|
+
## GitHub-операции от аккаунта бота
|
|
155
|
+
|
|
156
|
+
Автоматические GitHub-операции (создание PR, комментарии в PR, запуск
|
|
157
|
+
workflow, авторство коммитов автофинала) выполняются от отдельного
|
|
158
|
+
machine-аккаунта, если у разработчика задан его токен:
|
|
159
|
+
|
|
160
|
+
```bash
|
|
161
|
+
# fine-grained PAT бота: contents:write, pull-requests:write, actions:write
|
|
162
|
+
export TRIPLEX_BOT_GH_TOKEN=... # в ~/.zshenv (не ~/.zshrc — агент работает
|
|
163
|
+
# в неинтерактивном shell), НЕ в репозитории
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
**Паттерн для агентов** — в начале Bash-вызова с командами `gh`:
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
if [ -n "$TRIPLEX_BOT_GH_TOKEN" ]; then export GH_TOKEN="$TRIPLEX_BOT_GH_TOKEN"; fi
|
|
170
|
+
gh pr create ... # выполнится от бота; без токена — от разработчика (fallback)
|
|
171
|
+
```
|
|
110
172
|
|
|
111
|
-
|
|
173
|
+
**Авторство коммитов автофинала** (identity бота выводится из токена,
|
|
174
|
+
дополнительные переменные не нужны):
|
|
112
175
|
|
|
113
176
|
```bash
|
|
114
|
-
|
|
177
|
+
if [ -n "$TRIPLEX_BOT_GH_TOKEN" ]; then
|
|
178
|
+
BOT_LOGIN=$(GH_TOKEN="$TRIPLEX_BOT_GH_TOKEN" gh api user -q .login)
|
|
179
|
+
BOT_EMAIL=$(GH_TOKEN="$TRIPLEX_BOT_GH_TOKEN" gh api user -q '"\(.id)+\(.login)@users.noreply.github.com"')
|
|
180
|
+
git -c user.name="$BOT_LOGIN" -c user.email="$BOT_EMAIL" commit -m "..."
|
|
181
|
+
else
|
|
182
|
+
git commit -m "..."
|
|
183
|
+
fi
|
|
115
184
|
```
|
|
116
185
|
|
|
117
|
-
|
|
186
|
+
Правила:
|
|
187
|
+
|
|
188
|
+
- Токен нигде не печатать, не логировать и не коммитить; в репозитории
|
|
189
|
+
он не хранится ни в каком виде.
|
|
190
|
+
- `git push` остаётся по SSH разработчика — авторство коммита и аккаунт
|
|
191
|
+
пушащего могут различаться, это нормально.
|
|
192
|
+
- Проверка «кто я» перед автофиналом: `gh api user -q .login`
|
|
193
|
+
(с учётом паттерна выше) — чтобы в отчёте было видно, от чьего имени
|
|
194
|
+
созданы PR/комментарии.
|
|
195
|
+
- Действия в Linear выполняются от сессии разработчика — бот на них
|
|
196
|
+
не распространяется.
|
|
118
197
|
|
|
119
|
-
|
|
198
|
+
---
|
|
199
|
+
|
|
200
|
+
## PR-воркфлоу
|
|
201
|
+
|
|
202
|
+
**Работа по задаче Linear:** после коммита агент сам пушит ветку и создаёт PR:
|
|
120
203
|
|
|
121
204
|
```bash
|
|
205
|
+
git push -u origin TRI-XXX-feature-name
|
|
122
206
|
gh pr create \
|
|
123
|
-
--title "
|
|
207
|
+
--title "TRI-XXX Краткое описание" \
|
|
124
208
|
--body "## Что сделано\n- ...\n\n## Как проверить\n- ..."
|
|
125
209
|
```
|
|
126
210
|
|
|
211
|
+
После создания PR финал продолжается автоматически: skill
|
|
212
|
+
`update-visual-baselines` (если менялись stories/визуал) и skill
|
|
213
|
+
`finish-task` — комментарий-резюме в задаче Linear и проверка линковки PR
|
|
214
|
+
(GitHub-интеграция Linear подхватит PR по `TRI-XXX` в имени ветки).
|
|
215
|
+
|
|
216
|
+
**Вне задачи Linear:** агент пушит ветку и создаёт PR только по явной просьбе
|
|
217
|
+
разработчика; по умолчанию PR открывает разработчик через GitHub UI или
|
|
218
|
+
`gh pr create`.
|
|
219
|
+
|
|
127
220
|
---
|
|
128
221
|
|
|
129
222
|
## Release notes
|
|
@@ -163,4 +256,4 @@ stories/release-notes/v1/<текущая версия>.mdx
|
|
|
163
256
|
- [ ] Нет случайно добавленных файлов (`git status`)
|
|
164
257
|
- [ ] Для новых локальных/временных/генерируемых файлов проверено, не нужно ли добавить правило в `.gitignore`
|
|
165
258
|
- [ ] Нет скриншотов из macOS в `__screenshots__/`
|
|
166
|
-
- [ ] Release notes обновлены (если изменился публичный API компонента)
|
|
259
|
+
- [ ] Release notes обновлены (если изменился публичный API **или наблюдаемое поведение** компонента — не только при breaking change)
|