@sberbusiness/triplex-next-mcp-server 1.43.0-beta → 1.44.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/bundle/components/AlertProcess.md +3 -2
- package/bundle/components/BodyPage.md +72 -4
- package/bundle/components/CollapsibleTreeExtended.md +6 -1
- package/bundle/components/DatePickerExtended.md +409 -262
- package/bundle/components/ExpandAnimation.md +263 -218
- package/bundle/components/Footer.md +235 -278
- package/bundle/components/Island.md +36 -1
- package/bundle/components/LightBox.md +11 -6
- package/bundle/components/Overlay.md +24 -1
- package/bundle/components/Pagination.md +12 -13
- package/bundle/components/TableBasic.md +2294 -0
- package/bundle/components/Tag.md +259 -78
- package/bundle/components/TopOverlay.md +366 -90
- package/bundle/components/TreeView.md +343 -166
- package/bundle/components/TreeViewNode.md +436 -0
- package/bundle/guides/commits.md +106 -26
- package/bundle/manifest.json +25 -8
- package/bundle/release-notes/1.44.0.mdx +113 -0
- package/bundle/release-notes/1.45.0.mdx +7 -0
- package/package.json +1 -1
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
---
|
|
2
2
|
component: Footer
|
|
3
|
-
category:
|
|
4
|
-
|
|
5
|
-
figma-file: ""
|
|
6
|
-
related: [Page, Header, Button, TableBasic]
|
|
3
|
+
category: Footer
|
|
4
|
+
related: [FooterPage, TableBasic]
|
|
7
5
|
tokens: []
|
|
8
|
-
stories:
|
|
6
|
+
stories: stories/Footer/Footer.stories.tsx
|
|
9
7
|
version: "1.0"
|
|
10
8
|
---
|
|
11
9
|
|
|
@@ -13,327 +11,286 @@ version: "1.0"
|
|
|
13
11
|
|
|
14
12
|
## Назначение
|
|
15
13
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
`Footer.Description` (flex-контейнер) + его под-компоненты
|
|
20
|
-
`Footer.Description.Content` (растяжимый контент слева) и
|
|
21
|
-
`Footer.Description.Controls` (фиксированная группа кнопок справа).
|
|
14
|
+
Контейнер нижнего блока — контент и управляющие элементы (кнопки, ссылки) внизу карточки,
|
|
15
|
+
страницы или таблицы. Собственной визуальной оболочки не имеет: не рисует фон, рамку и отступы,
|
|
16
|
+
только даёт разметку и раскладку через составной `Footer.Description`.
|
|
22
17
|
|
|
23
|
-
|
|
24
|
-
пояснение или статус, справа — действия (`Сохранить`, `Отменить`).
|
|
25
|
-
На мобильных устройствах Controls переносится на следующую строку.
|
|
18
|
+
Наполнение строится тремя частями:
|
|
26
19
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
Не используй как: универсальный flex-контейнер (возьми `Row`/собственный
|
|
31
|
-
layout).
|
|
20
|
+
- `Footer.Description` — строка с контентом и кнопками (`display: flex`);
|
|
21
|
+
- `Footer.Description.Content` — контент, занимает свободное место;
|
|
22
|
+
- `Footer.Description.Controls` — кнопки действий, прижаты вправо.
|
|
32
23
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
src/components/Footer/
|
|
39
|
-
├── Footer.tsx # корень, compound-root, forwardRef + data-tx
|
|
40
|
-
├── index.ts # Barrel: Footer, FooterDescription, FooterDescriptionContent, FooterDescriptionControls
|
|
41
|
-
├── components/
|
|
42
|
-
│ ├── FooterDescription.tsx # Object.assign → Content/Controls
|
|
43
|
-
│ ├── FooterDescriptionContent.tsx # flex-grow: 1; margin-right: auto
|
|
44
|
-
│ └── FooterDescriptionControls.tsx # margin-left: auto; padding-left: 24px
|
|
45
|
-
├── styles/
|
|
46
|
-
│ └── Footer.module.less # flex/space-between + mobile wrap
|
|
47
|
-
└── __tests__/
|
|
48
|
-
└── Footer.test.tsx # smoke: root, ref, arbitrary props
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
Особенности:
|
|
52
|
-
- **`forwardRef`** — есть на всех 4 уровнях.
|
|
53
|
-
- **`data-tx`** — только на корне `Footer`. `Description`/`Content`/
|
|
54
|
-
`Controls` не проставляют (они внутренние под-компоненты одной
|
|
55
|
-
compound-семьи).
|
|
56
|
-
- **`IFooterDescriptionControlsProps`** импортируется из
|
|
57
|
-
`@sberbusiness/triplex-next/components/Table/TableBasic/types` —
|
|
58
|
-
исторический кросс-модульный импорт (type определён в types.ts
|
|
59
|
-
Table, но используется здесь). Не трогать без осознанного
|
|
60
|
-
рефакторинга обоих мест.
|
|
61
|
-
- **Нет собственных stories** — Footer демонстрируется через
|
|
62
|
-
`stories/Page/FooterPage.stories.tsx` и как часть Table/LightBox
|
|
63
|
-
story-групп.
|
|
64
|
-
- **Тесты** покрывают только корень `Footer` (smoke-уровень —
|
|
65
|
-
рендер, ref, props-passthrough).
|
|
66
|
-
|
|
67
|
-
---
|
|
68
|
-
|
|
69
|
-
## Compound-структура
|
|
70
|
-
|
|
71
|
-
```tsx
|
|
72
|
-
<Footer>
|
|
73
|
-
<Footer.Description>
|
|
74
|
-
<Footer.Description.Content>
|
|
75
|
-
Комментарий / описание / статус
|
|
76
|
-
</Footer.Description.Content>
|
|
77
|
-
<Footer.Description.Controls>
|
|
78
|
-
<Button>Отменить</Button>
|
|
79
|
-
<Button>Сохранить</Button>
|
|
80
|
-
</Footer.Description.Controls>
|
|
81
|
-
</Footer.Description>
|
|
82
|
-
</Footer>
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
**Реализация compound-а через `Object.assign`:**
|
|
86
|
-
|
|
87
|
-
```tsx
|
|
88
|
-
export const Footer = Object.assign(
|
|
89
|
-
React.forwardRef<HTMLDivElement, IFooterProps>(function Footer({ children, ...rest }, ref) { ... }),
|
|
90
|
-
{ Description: FooterDescription },
|
|
91
|
-
);
|
|
92
|
-
|
|
93
|
-
export const FooterDescription = Object.assign(
|
|
94
|
-
React.forwardRef<HTMLDivElement, IFooterDescriptionProps>(function FooterDescription(...) { ... }),
|
|
95
|
-
{
|
|
96
|
-
Content: FooterDescriptionContent,
|
|
97
|
-
Controls: FooterDescriptionControls,
|
|
98
|
-
},
|
|
99
|
-
);
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
**Два уровня compound'а:** `Footer.Description` + вложенный
|
|
103
|
-
`Description.Content`/`Description.Controls`. Это редкий паттерн в
|
|
104
|
-
библиотеке — большинство компонентов имеют один уровень.
|
|
105
|
-
|
|
106
|
-
**Все под-компоненты также экспортируются напрямую через barrel:**
|
|
107
|
-
`FooterDescription`, `FooterDescriptionContent`, `FooterDescriptionControls`.
|
|
108
|
-
Можно использовать либо compound-обращение (`Footer.Description.Content`),
|
|
109
|
-
либо прямой импорт. Предпочтение — compound для читаемости.
|
|
24
|
+
Используй когда: нужен нижний блок с текстом и действиями внутри своего контейнера
|
|
25
|
+
(`Island`, таблица, произвольная карточка), и оформление задаёт этот контейнер.
|
|
26
|
+
Не используй когда: нужен футер страницы — там `Page.Footer` (`FooterPage`), он в зависимости
|
|
27
|
+
от обязательного `type` оборачивает контент в карточку (`Island`) и умеет прилипать к нижней
|
|
28
|
+
границе экрана (`EFooterPageType.FIRST`) либо рендерит голый `Footer` (`EFooterPageType.SECOND`).
|
|
110
29
|
|
|
111
30
|
---
|
|
112
31
|
|
|
113
32
|
## Варианты и props
|
|
114
33
|
|
|
115
|
-
|
|
34
|
+
Собственных props нет. `IFooterProps` расширяет `React.HTMLAttributes<HTMLDivElement>`:
|
|
35
|
+
принимаются `children`, `className` и любые HTML-атрибуты div, всё уходит на корневой элемент
|
|
36
|
+
через `...rest`. То же верно для `FooterDescription`, `FooterDescriptionContent`
|
|
37
|
+
и `FooterDescriptionControls`.
|
|
116
38
|
|
|
117
|
-
|
|
118
|
-
|---|---|---|---|
|
|
119
|
-
| `children` | `ReactNode` | — | Обычно ровно один `Footer.Description`. |
|
|
120
|
-
| `className`, `style`, `...HTMLDivAttributes` | — | — | Стандартные. |
|
|
39
|
+
### Обязательные props
|
|
121
40
|
|
|
122
|
-
|
|
123
|
-
data-tx. Никаких собственных классов. Все визуальные свойства —
|
|
124
|
-
в `Description`.
|
|
41
|
+
Обязательных props нет.
|
|
125
42
|
|
|
126
|
-
###
|
|
43
|
+
### Опциональные props
|
|
127
44
|
|
|
128
|
-
| Prop | Тип |
|
|
45
|
+
| Prop | Тип | По умолчанию | Описание |
|
|
129
46
|
|---|---|---|---|
|
|
130
|
-
| `children` | `ReactNode` | — |
|
|
131
|
-
| `className` | `string` | — | Мержится с `styles.footerDescription` через `clsx`. |
|
|
132
|
-
| `...HTMLDivAttributes` | — | — | Стандартные. |
|
|
133
|
-
|
|
134
|
-
Класс `.footerDescription`:
|
|
135
|
-
```less
|
|
136
|
-
display: flex;
|
|
137
|
-
justify-content: space-between;
|
|
138
|
-
align-items: center;
|
|
139
|
-
```
|
|
47
|
+
| `children` | `React.ReactNode` | — | Контент футера. Обычно составной `Footer.Description`. |
|
|
140
48
|
|
|
141
|
-
###
|
|
49
|
+
### Ограничения
|
|
142
50
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
flex-grow: 1;
|
|
152
|
-
margin-right: auto;
|
|
153
|
-
```
|
|
51
|
+
- Корневой `<div>` не получает собственного класса — вертикальные отступы и фон задаёт
|
|
52
|
+
контейнер-родитель либо переданный `className`.
|
|
53
|
+
- Тип props у `FooterDescriptionControls` — `IFooterDescriptionControlsProps` — импортируется
|
|
54
|
+
из `@sberbusiness/triplex-next/components/Table/TableBasic/types`, а не объявлен рядом
|
|
55
|
+
с компонентом. Переносить и переименовывать его нельзя — это публичный API `TableBasic`
|
|
56
|
+
и breaking change. Правки внутри интерфейса, не меняющие его тип (например JSDoc на
|
|
57
|
+
`children`, как у остальных трёх интерфейсов семейства), допустимы — это техдолг,
|
|
58
|
+
который закрывается вместе с задачей по `TableBasic`.
|
|
154
59
|
|
|
155
|
-
|
|
156
|
-
место слева, выталкивая `Controls` вправо.
|
|
60
|
+
---
|
|
157
61
|
|
|
158
|
-
|
|
62
|
+
## Дизайн-токены
|
|
159
63
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
| `children` | `ReactNode` | — | Обычно `<Button>...</Button>`-группа. |
|
|
163
|
-
| `className` | `string` | — | Мержится через `clsx`. |
|
|
164
|
-
| `...HTMLDivAttributes` | — | — | Стандартные. |
|
|
165
|
-
|
|
166
|
-
Класс `.footerDescriptionControls`:
|
|
167
|
-
```less
|
|
168
|
-
margin-left: auto;
|
|
169
|
-
white-space: nowrap;
|
|
170
|
-
padding-left: 24px;
|
|
171
|
-
```
|
|
64
|
+
Компонент не использует CSS-переменные дизайн-токенов: цвета и типографику задают вложенные
|
|
65
|
+
компоненты (`Text`, `Button`, `Link`) и контейнер-родитель.
|
|
172
66
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
67
|
+
Раскладка задаётся литеральными значениями в `styles/Footer.module.less`:
|
|
68
|
+
отступ `padding-left: 24px` у `Controls` на десктопе и компенсирующие отступы `16px`
|
|
69
|
+
между кнопками при переносе на мобильных.
|
|
176
70
|
|
|
177
71
|
---
|
|
178
72
|
|
|
179
|
-
##
|
|
180
|
-
|
|
181
|
-
### Корень `Footer` — "прозрачный" контейнер
|
|
182
|
-
|
|
183
|
-
```tsx
|
|
184
|
-
<div {...rest} data-tx={process.env.npm_package_version} ref={ref}>
|
|
185
|
-
{children}
|
|
186
|
-
</div>
|
|
187
|
-
```
|
|
73
|
+
## Инварианты
|
|
188
74
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
`
|
|
192
|
-
`className
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
margin-top: 16px;
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
.footerDescriptionContent + .footerDescriptionControls {
|
|
211
|
-
margin-top: 0; // если Content есть — полагаемся на его высоту
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
```
|
|
75
|
+
- `forwardRef<HTMLDivElement>` на всех четырёх компонентах — не убирать. Ref всегда указывает
|
|
76
|
+
на корневой `<div>`.
|
|
77
|
+
- Корневой элемент — `<div>`; у `Footer` он без собственного класса, у остальных — с одним
|
|
78
|
+
классом из `styles/Footer.module.less` плюс `className` потребителя через `clsx`.
|
|
79
|
+
- `Footer` собран через `Object.assign(forwardRef(...), { Description })`,
|
|
80
|
+
`FooterDescription` — через `Object.assign(forwardRef(...), { Content, Controls })`.
|
|
81
|
+
Статические свойства сохранять: на них опирается `FooterPage` (`Page.Footer.Description`).
|
|
82
|
+
- `data-tx={process.env.npm_package_version}` на корневом элементе `Footer` — маркер версии
|
|
83
|
+
библиотеки, ставится после `...rest`, чтобы потребитель его не перетирал.
|
|
84
|
+
- `displayName` — `"Footer"`, `"FooterDescription"`, `"FooterDescriptionContent"`,
|
|
85
|
+
`"FooterDescriptionControls"`. Не менять.
|
|
86
|
+
- Экспорты `Footer`, `IFooterProps`, `FooterDescription`, `IFooterDescriptionProps`,
|
|
87
|
+
`FooterDescriptionContent`, `IFooterDescriptionContentProps`, `FooterDescriptionControls`
|
|
88
|
+
идут в barrel `src/components/Footer/index.ts` — сохранять.
|
|
89
|
+
- `IFooterDescriptionControlsProps` живёт в `Table/TableBasic/types` и экспортируется оттуда —
|
|
90
|
+
сюда не переносить.
|
|
91
|
+
- Перенос кнопок под контент на ширине экрана до `@screen-sm-max` (767px) — часть визуального
|
|
92
|
+
контракта, покрыт скриншотами на viewport `xs`.
|
|
215
93
|
|
|
216
|
-
|
|
217
|
-
- Переносится на новую строку (flex-wrap).
|
|
218
|
-
- `padding-left: 0` — убирает отступ (строка уже новая).
|
|
219
|
-
- `white-space: normal` — кнопки могут переноситься, если места мало.
|
|
220
|
-
- **`margin-top/-left: -16px` + `button > margin: 16px`** — трюк:
|
|
221
|
-
компенсирует отступы Button'а, чтобы визуально gap между кнопками
|
|
222
|
-
оставался 16px, но внешние края выравнивались к краю контейнера.
|
|
223
|
-
- **`Content + Controls { margin-top: 0 }`** — когда Content есть,
|
|
224
|
-
использует его нижний отступ; когда Controls стоит одна (без Content),
|
|
225
|
-
применяется полноценный -16px для верхнего смещения.
|
|
226
|
-
|
|
227
|
-
### `.footer` класс в медиа — orphan
|
|
228
|
-
|
|
229
|
-
```less
|
|
230
|
-
@media (max-width: @screen-sm-max) {
|
|
231
|
-
.footer { padding: 16px 0; }
|
|
232
|
-
}
|
|
233
|
-
```
|
|
94
|
+
---
|
|
234
95
|
|
|
235
|
-
|
|
236
|
-
`className={styles.footer}`. Legacy-остаток. Не удалять без
|
|
237
|
-
подтверждения, что нигде не импортируется напрямую через module-import.
|
|
96
|
+
## Accessibility
|
|
238
97
|
|
|
239
|
-
|
|
98
|
+
Структурный контейнер без собственного интерактивного поведения и ARIA-ролей. Семантику задаёт
|
|
99
|
+
потребитель через проброшенные атрибуты (`role="contentinfo"`, `aria-label` и т.п.).
|
|
100
|
+
Интерактивность обеспечивают вложенные кнопки и ссылки внутри `Footer.Description.Controls` —
|
|
101
|
+
порядок фокуса совпадает с порядком в DOM.
|
|
240
102
|
|
|
241
|
-
|
|
242
|
-
import { IFooterDescriptionControlsProps } from "@sberbusiness/triplex-next/components/Table/TableBasic/types";
|
|
243
|
-
```
|
|
103
|
+
---
|
|
244
104
|
|
|
245
|
-
|
|
246
|
-
используется `FooterDescriptionControls`. Исторический артефакт. Не
|
|
247
|
-
дублировать, не переносить без согласованного обновления Table.
|
|
248
|
-
`Table` импортирует этот же тип и разметку для своего Table-Footer.
|
|
105
|
+
## Связанные компоненты
|
|
249
106
|
|
|
250
|
-
|
|
107
|
+
- `FooterPage` — футер страницы (`Page.Footer`); рендерит `Footer` внутри себя, наследует
|
|
108
|
+
`IFooterProps` и реэкспортирует `Footer.Description` как `Page.Footer.Description`.
|
|
109
|
+
- `TableBasic` — владелец типа `IFooterDescriptionControlsProps`, который используют
|
|
110
|
+
`FooterDescriptionControls`.
|
|
111
|
+
- `FooterDescription` (`Footer.Description`) — основная часть футера: строка с контентом
|
|
112
|
+
и кнопками, `justify-content: space-between`. Тривиальная обёртка (className + spread + ref),
|
|
113
|
+
отдельного AI.md нет.
|
|
114
|
+
- `FooterDescriptionContent` (`Footer.Description.Content`) — контентная область,
|
|
115
|
+
`flex-grow: 1`. Тривиальная обёртка, отдельного AI.md нет.
|
|
116
|
+
- `FooterDescriptionControls` (`Footer.Description.Controls`) — область кнопок действий,
|
|
117
|
+
прижата вправо. Тривиальная обёртка, отдельного AI.md нет.
|
|
251
118
|
|
|
252
|
-
|
|
253
|
-
export interface IFooterProps extends React.HTMLAttributes<HTMLDivElement> {}
|
|
254
|
-
```
|
|
119
|
+
---
|
|
255
120
|
|
|
256
|
-
|
|
257
|
-
сознательно: интерфейсы существуют как "именованные точки", чтобы
|
|
258
|
-
можно было в будущем добавить пропсы без breaking change, а также
|
|
259
|
-
чтобы TS отображал именно `IFooterDescriptionProps` в hover'ах.
|
|
121
|
+
## Stories
|
|
260
122
|
|
|
261
|
-
|
|
123
|
+
Основные истории: `stories/Footer/Footer.stories.tsx`
|
|
124
|
+
Файлы примеров: `stories/Footer/examples/`
|
|
262
125
|
|
|
263
|
-
|
|
126
|
+
Playground не создаётся — у компонента нет настраиваемых props.
|
|
264
127
|
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
`Footer.Description.Controls`. Не превращать в children-API.
|
|
271
|
-
- **`Description` использует flex `space-between` + `align-items: center`**
|
|
272
|
-
— desktop. Не менять на grid (сломает mobile wrap).
|
|
273
|
-
- **`Content` с `flex-grow: 1; margin-right: auto`** — занимает место,
|
|
274
|
-
выталкивает `Controls`.
|
|
275
|
-
- **`Controls` с `margin-left: auto; white-space: nowrap; padding-left: 24px`**
|
|
276
|
-
— правый край, кнопки в одну строку.
|
|
277
|
-
- **Mobile (`max-width: @screen-sm-max`)** — `flex-wrap: wrap`, Content
|
|
278
|
-
на 100%, Controls на новой строке с Button-margin-компенсацией.
|
|
279
|
-
Не менять без обновления Button'а.
|
|
280
|
-
- **`.footer` в медиа-селекторе — orphan**. Не использовать; не
|
|
281
|
-
удалять без grep'а потребителей.
|
|
282
|
-
- **`IFooterDescriptionControlsProps` — импорт из `Table/TableBasic/types`**,
|
|
283
|
-
не дублировать локально.
|
|
284
|
-
- **`forwardRef`** — на всех 4 компонентах.
|
|
128
|
+
| Story | Example file | Что демонстрирует |
|
|
129
|
+
|---|---|---|
|
|
130
|
+
| `Default` | `Default.tsx` | Минимальный футер: контент и две кнопки |
|
|
131
|
+
| `Layouts` | `Layouts.tsx` | Варианты наполнения: контент и кнопки, только контент, только кнопки, длинный контент |
|
|
132
|
+
| `Example` | `Example.tsx` | Production-like композиция: футер внутри `Island` с ссылкой и тремя кнопками |
|
|
285
133
|
|
|
286
134
|
---
|
|
287
135
|
|
|
288
|
-
##
|
|
136
|
+
## История изменений
|
|
289
137
|
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
`<Footer role="contentinfo">` или оборачивание во внешний `<footer>`.
|
|
294
|
-
- **Нет `role="toolbar"` на Controls** — группа кнопок не анонсируется
|
|
295
|
-
как toolbar. Если нужно — потребитель добавляет через `role`/`aria-label`.
|
|
296
|
-
- **Tab-навигация** — естественная (от Content к Controls). Mobile
|
|
297
|
-
сохраняет tab-order (flex-wrap не меняет DOM-порядок).
|
|
298
|
-
- **Focus ring** — на дочерних `Button`/`Link`, сам Footer не focusable.
|
|
138
|
+
| Дата | Изменение |
|
|
139
|
+
|---|---|
|
|
140
|
+
| 2026-08-25 | Создан документ. AI-рефакторинг (JSDoc на `children`, удалён мёртвый CSS-класс `.footer`), unit-тесты на все четыре компонента, stories по modern pattern. |
|
|
299
141
|
|
|
300
142
|
---
|
|
301
143
|
|
|
302
|
-
##
|
|
144
|
+
## Примеры использования
|
|
303
145
|
|
|
304
|
-
|
|
305
|
-
(`Button`, `Link`, `Typography`). Footer — только layout.
|
|
146
|
+
### Default
|
|
306
147
|
|
|
307
|
-
|
|
148
|
+
`stories/Footer/examples/Default.tsx`
|
|
308
149
|
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
150
|
+
```tsx
|
|
151
|
+
import React from "react";
|
|
152
|
+
import { Footer, Button, EButtonTheme, EComponentSize, Text, ETextSize } from "@sberbusiness/triplex-next";
|
|
153
|
+
|
|
154
|
+
export const Default = () => (
|
|
155
|
+
<div style={{ maxWidth: "720px" }}>
|
|
156
|
+
<Footer>
|
|
157
|
+
<Footer.Description>
|
|
158
|
+
<Footer.Description.Content>
|
|
159
|
+
<Text size={ETextSize.B3}>Контент футера</Text>
|
|
160
|
+
</Footer.Description.Content>
|
|
161
|
+
<Footer.Description.Controls>
|
|
162
|
+
<Button size={EComponentSize.MD} theme={EButtonTheme.SECONDARY}>
|
|
163
|
+
Отмена
|
|
164
|
+
</Button>
|
|
165
|
+
<Button size={EComponentSize.MD} theme={EButtonTheme.GENERAL}>
|
|
166
|
+
Сохранить
|
|
167
|
+
</Button>
|
|
168
|
+
</Footer.Description.Controls>
|
|
169
|
+
</Footer.Description>
|
|
170
|
+
</Footer>
|
|
171
|
+
</div>
|
|
172
|
+
);
|
|
173
|
+
```
|
|
321
174
|
|
|
322
|
-
|
|
175
|
+
### Layouts
|
|
323
176
|
|
|
324
|
-
|
|
177
|
+
`stories/Footer/examples/Layouts.tsx`
|
|
325
178
|
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
179
|
+
```tsx
|
|
180
|
+
import React from "react";
|
|
181
|
+
import { Footer, Button, EButtonTheme, EComponentSize, Text, ETextSize } from "@sberbusiness/triplex-next";
|
|
182
|
+
|
|
183
|
+
export const Layouts = () => (
|
|
184
|
+
<div style={{ display: "flex", flexDirection: "column", gap: "24px", maxWidth: "720px" }}>
|
|
185
|
+
<div>
|
|
186
|
+
<div style={{ marginBottom: "8px", fontSize: "16px", fontWeight: 700 }}>Контент и кнопки</div>
|
|
187
|
+
<Footer>
|
|
188
|
+
<Footer.Description>
|
|
189
|
+
<Footer.Description.Content>
|
|
190
|
+
<Text size={ETextSize.B3}>Контент футера</Text>
|
|
191
|
+
</Footer.Description.Content>
|
|
192
|
+
<Footer.Description.Controls>
|
|
193
|
+
<Button size={EComponentSize.MD} theme={EButtonTheme.SECONDARY}>
|
|
194
|
+
Отмена
|
|
195
|
+
</Button>
|
|
196
|
+
<Button size={EComponentSize.MD} theme={EButtonTheme.GENERAL}>
|
|
197
|
+
Сохранить
|
|
198
|
+
</Button>
|
|
199
|
+
</Footer.Description.Controls>
|
|
200
|
+
</Footer.Description>
|
|
201
|
+
</Footer>
|
|
202
|
+
</div>
|
|
203
|
+
<div>
|
|
204
|
+
<div style={{ marginBottom: "8px", fontSize: "16px", fontWeight: 700 }}>Только контент</div>
|
|
205
|
+
<Footer>
|
|
206
|
+
<Footer.Description>
|
|
207
|
+
<Footer.Description.Content>
|
|
208
|
+
<Text size={ETextSize.B3}>Контент футера без управляющих элементов</Text>
|
|
209
|
+
</Footer.Description.Content>
|
|
210
|
+
</Footer.Description>
|
|
211
|
+
</Footer>
|
|
212
|
+
</div>
|
|
213
|
+
<div>
|
|
214
|
+
<div style={{ marginBottom: "8px", fontSize: "16px", fontWeight: 700 }}>Только кнопки</div>
|
|
215
|
+
<Footer>
|
|
216
|
+
<Footer.Description>
|
|
217
|
+
<Footer.Description.Controls>
|
|
218
|
+
<Button size={EComponentSize.MD} theme={EButtonTheme.SECONDARY}>
|
|
219
|
+
Отмена
|
|
220
|
+
</Button>
|
|
221
|
+
<Button size={EComponentSize.MD} theme={EButtonTheme.GENERAL}>
|
|
222
|
+
Сохранить
|
|
223
|
+
</Button>
|
|
224
|
+
</Footer.Description.Controls>
|
|
225
|
+
</Footer.Description>
|
|
226
|
+
</Footer>
|
|
227
|
+
</div>
|
|
228
|
+
<div>
|
|
229
|
+
<div style={{ marginBottom: "8px", fontSize: "16px", fontWeight: 700 }}>Длинный контент</div>
|
|
230
|
+
<Footer>
|
|
231
|
+
<Footer.Description>
|
|
232
|
+
<Footer.Description.Content>
|
|
233
|
+
<Text size={ETextSize.B3}>
|
|
234
|
+
Нажимая кнопку «Отправить», вы соглашаетесь с условиями обслуживания и подтверждаете, что
|
|
235
|
+
данные в документе проверены и заполнены корректно.
|
|
236
|
+
</Text>
|
|
237
|
+
</Footer.Description.Content>
|
|
238
|
+
<Footer.Description.Controls>
|
|
239
|
+
<Button size={EComponentSize.MD} theme={EButtonTheme.SECONDARY}>
|
|
240
|
+
Отмена
|
|
241
|
+
</Button>
|
|
242
|
+
<Button size={EComponentSize.MD} theme={EButtonTheme.GENERAL}>
|
|
243
|
+
Отправить
|
|
244
|
+
</Button>
|
|
245
|
+
</Footer.Description.Controls>
|
|
246
|
+
</Footer.Description>
|
|
247
|
+
</Footer>
|
|
248
|
+
</div>
|
|
249
|
+
</div>
|
|
250
|
+
);
|
|
251
|
+
```
|
|
329
252
|
|
|
330
|
-
|
|
331
|
-
имеют базовый showcase).
|
|
253
|
+
### Example
|
|
332
254
|
|
|
333
|
-
|
|
255
|
+
`stories/Footer/examples/Example.tsx`
|
|
334
256
|
|
|
335
|
-
|
|
257
|
+
```tsx
|
|
258
|
+
import React from "react";
|
|
259
|
+
import {
|
|
260
|
+
Footer,
|
|
261
|
+
Island,
|
|
262
|
+
EIslandType,
|
|
263
|
+
Button,
|
|
264
|
+
EButtonTheme,
|
|
265
|
+
EComponentSize,
|
|
266
|
+
Link,
|
|
267
|
+
Text,
|
|
268
|
+
ETextSize,
|
|
269
|
+
} from "@sberbusiness/triplex-next";
|
|
270
|
+
|
|
271
|
+
export const Example = () => (
|
|
272
|
+
<Island type={EIslandType.TYPE_1} size={EComponentSize.MD} style={{ maxWidth: "720px" }}>
|
|
273
|
+
<Footer>
|
|
274
|
+
<Footer.Description>
|
|
275
|
+
<Footer.Description.Content>
|
|
276
|
+
<Text size={ETextSize.B3}>
|
|
277
|
+
Отправляя документ, вы соглашаетесь с <Link href="#">условиями обслуживания</Link>.
|
|
278
|
+
</Text>
|
|
279
|
+
</Footer.Description.Content>
|
|
280
|
+
<Footer.Description.Controls>
|
|
281
|
+
<Button size={EComponentSize.MD} theme={EButtonTheme.SECONDARY}>
|
|
282
|
+
Отмена
|
|
283
|
+
</Button>
|
|
284
|
+
<Button size={EComponentSize.MD} theme={EButtonTheme.SECONDARY}>
|
|
285
|
+
Сохранить черновик
|
|
286
|
+
</Button>
|
|
287
|
+
<Button size={EComponentSize.MD} theme={EButtonTheme.GENERAL}>
|
|
288
|
+
Отправить
|
|
289
|
+
</Button>
|
|
290
|
+
</Footer.Description.Controls>
|
|
291
|
+
</Footer.Description>
|
|
292
|
+
</Footer>
|
|
293
|
+
</Island>
|
|
294
|
+
);
|
|
295
|
+
```
|
|
336
296
|
|
|
337
|
-
| Дата | Изменение |
|
|
338
|
-
|---|---|
|
|
339
|
-
| 2026-04-18 | Создан документ |
|
|
@@ -49,6 +49,7 @@ version: "1.0"
|
|
|
49
49
|
| `size` | `EComponentSize` | `EComponentSize.MD` | Скругление, внутренние отступы карточки и отступы между Header / Body / Footer |
|
|
50
50
|
| `loading` | `boolean` | `false` | Показывает `LoaderScreen` поверх контента карточки |
|
|
51
51
|
| `loaderScreenProps` | `ILoaderScreenMiddleProps` | `undefined` | Props лоадера: `description`, `controls`, `className` и остальные атрибуты `<div>`. `type` задаёт Island (`middle`) |
|
|
52
|
+
| `withoutPaddings` | `boolean` | `false` | Убирает внутренние отступы карточки. Скругление и отступы между Header / Body / Footer от `size` сохраняются |
|
|
52
53
|
|
|
53
54
|
Компонент расширяет `React.HTMLAttributes<HTMLDivElement>` — все стандартные атрибуты `<div>`
|
|
54
55
|
(`className`, `style`, `role`, `aria-*`, `data-*`, обработчики событий) попадают на корневой элемент.
|
|
@@ -238,11 +239,12 @@ Island — неинтерактивный контейнер: не выстав
|
|
|
238
239
|
|
|
239
240
|
| Story | Example file | Что демонстрирует |
|
|
240
241
|
|---|---|---|
|
|
241
|
-
| `Playground` | — | Интерактивный контроль `type`, `size`, `loading` и состава (Header / Body / Footer) |
|
|
242
|
+
| `Playground` | — | Интерактивный контроль `type`, `size`, `loading`, `withoutPaddings` и состава (Header / Body / Footer) |
|
|
242
243
|
| `Default` | `DefaultExample.tsx` | Минимальная карточка: Header + Body + Footer |
|
|
243
244
|
| `Types` | `TypesExample.tsx` | Все значения `EIslandType` рядом |
|
|
244
245
|
| `Sizes` | `SizesExample.tsx` | Размеры SM / MD / LG: скругление, паддинги, отступы между частями |
|
|
245
246
|
| `Loading` | `Loading.tsx` | `loading`: `LoaderScreen` поверх контента карточки |
|
|
247
|
+
| `WithoutPaddings` | `WithoutPaddings.tsx` | `withoutPaddings` во всех размерах: внутренние отступы убраны, скругление и отступы между Header / Body / Footer сохраняются |
|
|
246
248
|
|
|
247
249
|
Файлы примеров с постфиксом `Example` — локальный legacy-паттерн папки; новые примеры называются
|
|
248
250
|
по имени story (`Loading.tsx`).
|
|
@@ -253,6 +255,7 @@ Island — неинтерактивный контейнер: не выстав
|
|
|
253
255
|
|
|
254
256
|
| Дата | Изменение |
|
|
255
257
|
|---|---|
|
|
258
|
+
| 2026-08-24 | Добавлено свойство `withoutPaddings` — отключает внутренние отступы карточки. Добавлена story `WithoutPaddings`. |
|
|
256
259
|
| 2026-08-11 | Prop состояния загрузки переименован `isLoading` → `loading` — по преобладающей в библиотеке конвенции boolean-props без префикса `is` (`loading` у `Button`, `List`, `Dropdown`, `Suggest`, `Table`). Prop ещё не выпускался, поэтому breaking change нет; `Omit` в `IModalWindowBodyProps` обновлён на `"loading"`. Поведение не изменилось. |
|
|
257
260
|
| 2026-08-06 | `related` приведён к правилу `docs/ai/CONTEXT.md` → «Как заполнять `related` в AI.md»: убраны потребители (`BodyPage`, `HeaderPage`, `FooterPage`, `Confirm`), `ModalWindowBody` заменён родителем `ModalWindow`, добавлен `LoaderScreen`. Раздел «Связанные компоненты» разбит по типам связи. Добавлено состояние загрузки: props `isLoading` и `loaderScreenProps` — при `isLoading` поверх контента карточки рендерится `LoaderScreen` типа `middle`. Подложка наследует скругление карточки, `z-index` понижен до локального. `ModalWindowBody` эти props не наследует (`Omit`) — его тело скроллируется, лоадер там задаётся на `ModalWindowContent`. Добавлены story `Loading` и unit-тесты. Остальной публичный API не изменён. |
|
|
258
261
|
| 2026-08-04 | Создан документ. AI-рефакторинг: JSDoc на props, значениях `EIslandType` и субкомпонентах, `displayName` у `IslandHeader` / `IslandBody` / `IslandFooter`, unit-тесты на все типы и размеры, части острова и `mapTypeToClassName`. Исправлено: `className` в `IslandHeader` и `IslandFooter` больше не затирает базовый класс компонента; побочный отступ в `IslandAccordion` погашен в стилях аккордеона, вид библиотечных компонентов не изменился. Публичный API не изменён. |
|
|
@@ -375,3 +378,35 @@ export const Loading = () => (
|
|
|
375
378
|
);
|
|
376
379
|
```
|
|
377
380
|
|
|
381
|
+
### WithoutPaddings
|
|
382
|
+
|
|
383
|
+
`stories/Island/examples/WithoutPaddings.tsx`
|
|
384
|
+
|
|
385
|
+
```tsx
|
|
386
|
+
import React from "react";
|
|
387
|
+
import { Island, EIslandType, EComponentSize } from "@sberbusiness/triplex-next";
|
|
388
|
+
|
|
389
|
+
const SIZES = Object.values(EComponentSize);
|
|
390
|
+
|
|
391
|
+
export const WithoutPaddings = () => (
|
|
392
|
+
<div
|
|
393
|
+
style={{
|
|
394
|
+
display: "grid",
|
|
395
|
+
gap: 16,
|
|
396
|
+
gridTemplateColumns: "repeat(auto-fit, minmax(260px, 1fr))",
|
|
397
|
+
}}
|
|
398
|
+
>
|
|
399
|
+
{SIZES.map((size) => (
|
|
400
|
+
<div key={size}>
|
|
401
|
+
<div style={{ marginBottom: "8px", fontSize: "16px", fontWeight: "700" }}>{size.toUpperCase()}</div>
|
|
402
|
+
<Island type={EIslandType.TYPE_1} size={size} withoutPaddings>
|
|
403
|
+
<Island.Header>Header content</Island.Header>
|
|
404
|
+
<Island.Body>Body content</Island.Body>
|
|
405
|
+
<Island.Footer>Footer content</Island.Footer>
|
|
406
|
+
</Island>
|
|
407
|
+
</div>
|
|
408
|
+
))}
|
|
409
|
+
</div>
|
|
410
|
+
);
|
|
411
|
+
```
|
|
412
|
+
|