@sberbusiness/triplex-next-mcp-server 1.42.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.
Files changed (35) hide show
  1. package/bundle/components/AlertProcess.md +3 -2
  2. package/bundle/components/BodyPage.md +72 -4
  3. package/bundle/components/Button.md +1 -0
  4. package/bundle/components/Checkbox.md +7 -1
  5. package/bundle/components/CheckboxTreeExtended.md +149 -248
  6. package/bundle/components/CheckboxXGroup.md +2 -0
  7. package/bundle/components/CheckboxYGroup.md +7 -2
  8. package/bundle/components/ChipGroup.md +195 -126
  9. package/bundle/components/CollapsibleTreeExtended.md +6 -1
  10. package/bundle/components/DatePickerExtended.md +409 -262
  11. package/bundle/components/ExpandAnimation.md +263 -218
  12. package/bundle/components/Footer.md +235 -278
  13. package/bundle/components/Island.md +36 -1
  14. package/bundle/components/LightBox.md +14 -3
  15. package/bundle/components/MediaWidth.md +7 -1
  16. package/bundle/components/Notification.md +21 -3
  17. package/bundle/components/Overlay.md +24 -1
  18. package/bundle/components/Pagination.md +12 -13
  19. package/bundle/components/SliderExtended.md +358 -222
  20. package/bundle/components/TableBasic.md +2294 -0
  21. package/bundle/components/TabsExtended.md +380 -194
  22. package/bundle/components/Tag.md +259 -78
  23. package/bundle/components/TopOverlay.md +366 -90
  24. package/bundle/components/TreeView.md +343 -166
  25. package/bundle/components/TreeViewNode.md +436 -0
  26. package/bundle/components/UnorderedList.md +254 -0
  27. package/bundle/components/UnorderedListExtended.md +255 -0
  28. package/bundle/components/WindowResizeListener.md +249 -0
  29. package/bundle/guides/commits.md +121 -15
  30. package/bundle/guides/stories.md +1 -1
  31. package/bundle/manifest.json +46 -20
  32. package/bundle/release-notes/1.43.0.mdx +87 -0
  33. package/bundle/release-notes/1.44.0.mdx +120 -0
  34. package/bundle/release-notes/1.45.0.mdx +7 -0
  35. package/package.json +1 -1
@@ -1,11 +1,9 @@
1
1
  ---
2
2
  component: Footer
3
- category: Layout
4
- figma-node: ""
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
- кнопками действий. **Compound-компонент**: корневой `Footer` — тонкая
18
- обёртка-`<div>` с `data-tx`; основная логика разметки — в
19
- `Footer.Description` (flex-контейнер) + его под-компоненты
20
- `Footer.Description.Content` (растяжимый контент слева) и
21
- `Footer.Description.Controls` (фиксированная группа кнопок справа).
14
+ Контейнер нижнего блока — контент и управляющие элементы (кнопки, ссылки) внизу карточки,
15
+ страницы или таблицы. Собственной визуальной оболочки не имеет: не рисует фон, рамку и отступы,
16
+ только даёт разметку и раскладку через составной `Footer.Description`.
22
17
 
23
- Типовой кейс: нижняя часть формы/LightBox'а/страницы, где слева —
24
- пояснение или статус, справа — действия (`Сохранить`, `Отменить`).
25
- На мобильных устройствах Controls переносится на следующую строку.
18
+ Наполнение строится тремя частями:
26
19
 
27
- Используй когда: нужна стандартизированная разметка подвала
28
- "контент + действия" с корректным мобильным wrap-поведением и
29
- отступами, согласованными с `Button` (компенсация margin'ами).
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
- ```text
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
- ### Footer — `IFooterProps extends React.HTMLAttributes<HTMLDivElement>`
34
+ Собственных props нет. `IFooterProps` расширяет `React.HTMLAttributes<HTMLDivElement>`:
35
+ принимаются `children`, `className` и любые HTML-атрибуты div, всё уходит на корневой элемент
36
+ через `...rest`. То же верно для `FooterDescription`, `FooterDescriptionContent`
37
+ и `FooterDescriptionControls`.
116
38
 
117
- | Prop | Тип | Default | Описание |
118
- |---|---|---|---|
119
- | `children` | `ReactNode` | — | Обычно ровно один `Footer.Description`. |
120
- | `className`, `style`, `...HTMLDivAttributes` | — | — | Стандартные. |
39
+ ### Обязательные props
121
40
 
122
- **Корневой `Footer` — минимальный**: не добавляет flex/padding, только
123
- data-tx. Никаких собственных классов. Все визуальные свойства —
124
- в `Description`.
41
+ Обязательных props нет.
125
42
 
126
- ### FooterDescription — `IFooterDescriptionProps extends React.HTMLAttributes<HTMLDivElement>`
43
+ ### Опциональные props
127
44
 
128
- | Prop | Тип | Default | Описание |
45
+ | Prop | Тип | По умолчанию | Описание |
129
46
  |---|---|---|---|
130
- | `children` | `ReactNode` | — | Обычно `Content` + `Controls` или только `Controls`. |
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
- ### FooterDescriptionContent — `IFooterDescriptionContentProps extends React.HTMLAttributes<HTMLDivElement>`
49
+ ### Ограничения
142
50
 
143
- | Prop | Тип | Default | Описание |
144
- |---|---|---|---|
145
- | `children` | `ReactNode` | — | Текст/описание/статус. |
146
- | `className` | `string` | — | Мержится через `clsx`. |
147
- | `...HTMLDivAttributes` | — | — | Стандартные. |
148
-
149
- Класс `.footerDescriptionContent`:
150
- ```less
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
- **`margin-right: auto`** + `flex-grow: 1` — занимает всё свободное
156
- место слева, выталкивая `Controls` вправо.
60
+ ---
157
61
 
158
- ### FooterDescriptionControls — `IFooterDescriptionControlsProps extends React.HTMLAttributes<HTMLDivElement>`
62
+ ## Дизайн-токены
159
63
 
160
- | Prop | Тип | Default | Описание |
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
- **`white-space: nowrap`** — не даёт кнопкам переноситься на новую строку
174
- внутри Controls (на desktop). **`padding-left: 24px`** — минимальный
175
- gap между Content и Controls.
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
- Без класса, без padding. Смысл — только как "маркер" (data-tx) и
190
- стабильная точка для ref потребителя. Визуальная логика делегирована
191
- `Description`. Если потребитель хочет padding/border — добавляет через
192
- `className`/`style` в props.
193
-
194
- ### Mobile wrap — `flex-wrap: wrap` + перераскладка Controls
195
-
196
- ```less
197
- @media (max-width: @screen-sm-max) {
198
- .footerDescription { flex-wrap: wrap; align-items: normal; }
199
- .footerDescriptionContent { width: 100%; }
200
- .footerDescriptionControls {
201
- padding-left: 0;
202
- white-space: normal; // разрешаем перенос на mobile
203
- margin-top: -16px; // компенсация Button margin
204
- margin-left: -16px;
205
- > button {
206
- margin-left: 16px;
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
- **На mobile Controls:**
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
- **Этот класс объявлен, но НЕ применяется** — в `Footer.tsx` нет
236
- `className={styles.footer}`. Legacy-остаток. Не удалять без
237
- подтверждения, что нигде не импортируется напрямую через module-import.
96
+ ## Accessibility
238
97
 
239
- ### `IFooterDescriptionControlsProps` — кросс-модульный тип
98
+ Структурный контейнер без собственного интерактивного поведения и ARIA-ролей. Семантику задаёт
99
+ потребитель через проброшенные атрибуты (`role="contentinfo"`, `aria-label` и т.п.).
100
+ Интерактивность обеспечивают вложенные кнопки и ссылки внутри `Footer.Description.Controls` —
101
+ порядок фокуса совпадает с порядком в DOM.
240
102
 
241
- ```ts
242
- import { IFooterDescriptionControlsProps } from "@sberbusiness/triplex-next/components/Table/TableBasic/types";
243
- ```
103
+ ---
244
104
 
245
- Тип живёт в `src/components/Table/TableBasic/types.ts`, но
246
- используется `FooterDescriptionControls`. Исторический артефакт. Не
247
- дублировать, не переносить без согласованного обновления Table.
248
- `Table` импортирует этот же тип и разметку для своего Table-Footer.
105
+ ## Связанные компоненты
249
106
 
250
- ### `React.HTMLAttributes<HTMLDivElement>` — пустое extension
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
- ```ts
253
- export interface IFooterProps extends React.HTMLAttributes<HTMLDivElement> {}
254
- ```
119
+ ---
255
120
 
256
- Все 4 Props-интерфейса — пустые extensions HTML-атрибутов. Это
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
- - **`Footer` — минимальный контейнер**: только data-tx, без собственных
266
- стилей. Не добавлять padding/border в компонент — оставить на
267
- потребителя.
268
- - **`data-tx`** — только на корневом `Footer`, не на под-компонентах.
269
- - **Compound через `Object.assign`** — `Footer.Description.Content`,
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
- ## Accessibility
136
+ ## История изменений
289
137
 
290
- - **`<div>`-контейнеры** — семантика не задаётся (нет `<footer>`-тега).
291
- Потребитель должен выбрать корректный semantic-элемент сам, передав
292
- нужные ARIA-роли через `...rest`. Для "подвала страницы" ожидается
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
- - `Page` (`src/components/Page`) — типичный контейнер, где используется
312
- Footer как подвал страницы (см. `stories/Page/FooterPage.stories.tsx`).
313
- - `Header` (`src/components/Header`) — верхняя часть страницы, парная
314
- к Footer.
315
- - `LightBox`/`ModalWindow`/`SideOverlay` — часто имеют Footer в нижней
316
- части модалки с action-buttons.
317
- - `Button` — основной дочерний элемент в `Controls`. Mobile-стили
318
- специально рассчитаны на отступы Button'а (`margin: 16px` compensation).
319
- - `Table`/`TableBasic` — переиспользует `IFooterDescriptionControlsProps`
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
- ## Stories
177
+ `stories/Footer/examples/Layouts.tsx`
325
178
 
326
- **Нет собственных stories.** Footer демонстрируется через:
327
- - `stories/Page/FooterPage.stories.tsx` — в составе страницы.
328
- - Stories Table/LightBox/ModalWindow — как часть layout'а модалок.
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
- Добавление своих stories — AI-Ready debt (подобные примитивы обычно
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
+