@sberbusiness/triplex-next-mcp-server 0.24.0-beta2 → 0.36.0-beta0

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 (55) hide show
  1. package/README.md +10 -0
  2. package/bundle/components/BodyPage.md +186 -0
  3. package/bundle/components/Button.md +90 -85
  4. package/bundle/components/ButtonDropdown.md +28 -70
  5. package/bundle/components/ButtonIcon.md +35 -48
  6. package/bundle/components/Checkbox.md +43 -122
  7. package/bundle/components/CheckboxXGroup.md +109 -46
  8. package/bundle/components/CheckboxYGroup.md +77 -49
  9. package/bundle/components/CollapsibleTree.md +581 -0
  10. package/bundle/components/CollapsibleTreeExtended.md +418 -0
  11. package/bundle/components/EmptyView.md +14 -15
  12. package/bundle/components/FooterPage.md +203 -0
  13. package/bundle/components/Gap.md +115 -57
  14. package/bundle/components/HeaderPage.md +226 -0
  15. package/bundle/components/HelpBox.md +45 -84
  16. package/bundle/components/ImageGallery.md +423 -0
  17. package/bundle/components/ImageGalleryExtended.md +606 -0
  18. package/bundle/components/List.md +194 -186
  19. package/bundle/components/ListItem.md +251 -0
  20. package/bundle/components/ListItemControlsButton.md +103 -0
  21. package/bundle/components/ListItemControlsButtonDropdown.md +107 -0
  22. package/bundle/components/ListItemSelectable.md +99 -0
  23. package/bundle/components/ListItemTable.md +390 -0
  24. package/bundle/components/ListMaster.md +877 -156
  25. package/bundle/components/ListMasterFooter.md +80 -0
  26. package/bundle/components/ListMasterHeader.md +86 -0
  27. package/bundle/components/ListSortable.md +153 -0
  28. package/bundle/components/ListSortableItem.md +175 -0
  29. package/bundle/components/ModalWindow.md +427 -237
  30. package/bundle/components/MonthYearField.md +145 -109
  31. package/bundle/components/Notification.md +625 -155
  32. package/bundle/components/Overlay.md +271 -170
  33. package/bundle/components/Page.md +283 -186
  34. package/bundle/components/Pagination.md +206 -229
  35. package/bundle/guides/codestyle.md +38 -11
  36. package/bundle/guides/commits.md +1 -2
  37. package/bundle/guides/context.md +34 -30
  38. package/bundle/guides/stories.md +110 -40
  39. package/bundle/guides/template.md +3 -7
  40. package/bundle/guides/tests.md +6 -2
  41. package/bundle/manifest.json +194 -24
  42. package/bundle/release-notes/1.26.0.mdx +33 -2
  43. package/bundle/release-notes/1.27.0.mdx +43 -0
  44. package/bundle/release-notes/1.28.0.mdx +25 -0
  45. package/bundle/release-notes/1.29.0.mdx +47 -0
  46. package/bundle/release-notes/1.30.0.mdx +56 -0
  47. package/bundle/release-notes/1.31.0.mdx +52 -0
  48. package/bundle/release-notes/1.32.0.mdx +35 -0
  49. package/bundle/release-notes/1.33.0.mdx +61 -0
  50. package/bundle/release-notes/1.34.0.mdx +35 -0
  51. package/bundle/release-notes/1.35.0.mdx +21 -0
  52. package/bundle/release-notes/1.35.1.mdx +11 -0
  53. package/bundle/release-notes/1.36.0.mdx +21 -0
  54. package/bundle/release-notes/1.37.0.mdx +30 -0
  55. package/package.json +1 -1
@@ -1,11 +1,9 @@
1
1
  ---
2
2
  component: Page
3
- category: Layout
4
- figma-node: ""
5
- figma-file: ""
6
- related: [Header, Body, Footer, Island, LightBox, Spoiler]
3
+ category: Page
4
+ related: [HeaderPage, BodyPage, FooterPage, Island, LightBox]
7
5
  tokens: []
8
- stories: stories/Page/Page.stories.tsx
6
+ stories: stories/Page/Page/Page.stories.tsx
9
7
  version: "1.0"
10
8
  ---
11
9
 
@@ -13,234 +11,333 @@ version: "1.0"
13
11
 
14
12
  ## Назначение
15
13
 
16
- Layout-компонент **страницы**: контейнер `<div class="global-page">` +
17
- три compound-слота `Header`, `Body`, `Footer`, каждый из которых
18
- существует в **двух типах**:
14
+ Каркас страницы. Вертикальный flex-контейнер (`<div>`), в который вкладываются только составные
15
+ части: `Page.Header` (HeaderPage), `Page.Body` (BodyPage) и `Page.Footer` (FooterPage). Сам `Page`
16
+ не задаёт визуальный стиль контента — он лишь раскладывает части по вертикали и задаёт внешние
17
+ отступы страницы.
19
18
 
20
- - **`FIRST`** — заворачивает контент в `Island` (карточка с фоном,
21
- скруглением, padding'ом). Используется для типичной layout'ной
22
- страницы.
23
- - **`SECOND`** — оставляет «голый» Header/Body/Footer без `Island` —
24
- для случаев, когда фон/обёртка управляется внешним контейнером
25
- (например, `LightBox`).
26
-
27
- Дополнительно `HeaderPage` / `FooterPage` поддерживают **`sticky`** —
28
- sticky-позиционирование с **плавным обнулением скруглений углов** при
29
- прилипании (через `useStickyCornerRadius`).
30
-
31
- Используй когда: компонуешь страницу из секций. Если нужен только
32
- header / footer без всей структуры — используй `Header`/`Footer`/`Body`
33
- напрямую.
34
-
35
- ---
36
-
37
- ## Файловая структура
38
-
39
- ```text
40
- src/components/Page/
41
- ├── Page.tsx # forwardRef + Object.assign({Header, Body, Footer})
42
- ├── components/
43
- │ ├── HeaderPage.tsx # forwardRef; FIRST=Island+Header, SECOND=Header
44
- │ ├── BodyPage.tsx # forwardRef; FIRST=Island+Body, SECOND=Body
45
- │ ├── FooterPage.tsx # forwardRef; FIRST=Island+Footer, SECOND=Footer
46
- │ ├── enums.ts # EHeaderPageType / EBodyPageType / EFooterPageType / EBodyPageVerticalMargin
47
- │ └── useStickyCornerRadius.ts # rAF-анимация corner-radius при sticky-прилипании
48
- ├── styles/Page.module.less + BodyPage.module.less
49
- ├── index.ts # Barrel: Page + enums
50
- └── __tests__/
51
- ```
52
-
53
- ---
54
-
55
- ## Compound-структура
56
-
57
- ```tsx
58
- <Page>
59
- <Page.Header type={EHeaderPageType.FIRST} sticky size={EComponentSize.MD}>
60
- <Page.Header.Title>Заголовок</Page.Header.Title>
61
- <Page.Header.Subhead>Подзаголовок</Page.Header.Subhead>
62
- <Page.Header.Tabs>...</Page.Header.Tabs>
63
- </Page.Header>
64
- <Page.Body type={EBodyPageType.FIRST} verticalMargin={EBodyPageVerticalMargin.LARGE}>
65
- Контент
66
- </Page.Body>
67
- <Page.Footer type={EFooterPageType.FIRST} sticky>
68
- <Page.Footer.Description>Подпись</Page.Footer.Description>
69
- <Button>Действие</Button>
70
- </Page.Footer>
71
- </Page>
72
- ```
73
-
74
- `HeaderPage.Title/Subhead/Tabs/LayoutSidebar` — **реэкспорты** `Header.*`. То же — `FooterPage.Description = Footer.Description`.
19
+ Используй когда: нужен типовой каркас страницы — заголовок сверху, контент по центру, футер снизу.
20
+ Чаще всего применяется как содержимое `LightBox`.
21
+ Не используй когда: нужен отдельный блок (карточка, заголовок) без полного каркаса — используй
22
+ `Island`, `Page.Header`/`Page.Body`/`Page.Footer` по отдельности или иной контейнер.
75
23
 
76
24
  ---
77
25
 
78
26
  ## Варианты и props
79
27
 
80
- ### Page — `IPageProps extends HTMLAttributes<HTMLDivElement>`
28
+ Собственных props у `Page` нет — интерфейс `IPageProps` пуст и расширяет
29
+ `React.HTMLAttributes<HTMLDivElement>`. Вся настройка внешнего вида задаётся через типы дочерних
30
+ частей (`type` у `Page.Header` / `Page.Body` / `Page.Footer`), а не через props самого `Page`.
31
+
32
+ ### Props
81
33
 
82
34
  | Prop | Тип | Описание |
83
35
  |---|---|---|
84
- | `...HTMLAttributes` | — | На корневой `<div>`. |
85
- | `children` | `ReactNode` | Только Header / Body / Footer (контракт). |
86
-
87
- CSS-классы: `styles.page` + **`styles["global-page"]`** (последний — публичный, для глобальных стилей вне модуля).
36
+ | `className` | `string` | Дополнительный класс на корневой `<div>`. Мерджится через `clsx` после базовых классов. |
37
+ | `children` | `React.ReactNode` | Составные части страницы: `Page.Header`, `Page.Body`, `Page.Footer`. |
38
+ | `...rest` | `React.HTMLAttributes<HTMLDivElement>` | Любые стандартные HTML-атрибуты `<div>` пробрасываются на корневой элемент. |
88
39
 
89
- ### HeaderPage — `IHeaderPageTypeFirstProps | IHeaderPageTypeSecondProps`
40
+ ### Статические свойства (составные части)
90
41
 
91
- | Prop | FIRST | SECOND | Default | Описание |
92
- |---|---|---|---|---|
93
- | `type` | `EHeaderPageType.FIRST` | `EHeaderPageType.SECOND` | — (обязателен) | Discriminator. |
94
- | `sticky` | `boolean` | `never` | — | Sticky к верху. **Только FIRST** и **только внутри LightBox** (по комментарию). |
95
- | `size` | `EComponentSize` | `never` | — | Размер `Island`. **Только FIRST**. |
96
- | `...IHeaderProps` | — | — | — | От `Header`. |
97
-
98
- - FIRST: `<Island type=TYPE_1 size={size}><Header /></Island>`.
99
- - SECOND: `<Header className={headerPageTypeSecond} />`.
100
- - Slots: **`HeaderPage.Title / Subhead / Tabs / LayoutSidebar`** = реэкспорты `Header.*`.
101
-
102
- ### BodyPage — `IBodyPageTypeFirstProps | IBodyPageTypeSecondProps`
103
-
104
- | Prop | FIRST | SECOND | Default | Описание |
105
- |---|---|---|---|---|
106
- | `type` | `EBodyPageType.FIRST` | `EBodyPageType.SECOND` | — | Discriminator. |
107
- | `size` | `EComponentSize` | `never` | — | Размер `Island`. Только FIRST. |
108
- | `verticalMargin` | `EBodyPageVerticalMargin` | (то же) | `LARGE` | `LARGE` = 24px, `SMALL` = 16px. В LightBox — `SMALL`. |
109
- | `...IBodyProps` | — | — | — | От `Body`. |
110
-
111
- ### FooterPage — `IFooterPageTypeFirstProps | IFooterPageTypeSecondProps`
42
+ | Свойство | Компонент | Назначение |
43
+ |---|---|---|
44
+ | `Page.Header` | `HeaderPage` | Заголовок страницы. |
45
+ | `Page.Body` | `BodyPage` | Тело страницы с основным контентом. |
46
+ | `Page.Footer` | `FooterPage` | Футер страницы с действиями. |
112
47
 
113
- | Prop | FIRST | SECOND | Default | Описание |
114
- |---|---|---|---|---|
115
- | `type` | `EFooterPageType.FIRST` | `EFooterPageType.SECOND` | — | Discriminator. |
116
- | `sticky` | `boolean` | `never` | — | Sticky к низу. **Только FIRST внутри LightBox** (по комментарию). |
117
- | `size` | `EComponentSize` | `never` | — | Размер `Island`. Только FIRST. |
118
- | `...IFooterProps` | — | — | — | От `Footer`. |
48
+ ### Типы частей
119
49
 
120
- - Slots: **`FooterPage.Description`** = `Footer.Description`.
50
+ Каждая часть бывает двух типов (`type`):
121
51
 
122
- ### Enums
52
+ - `FIRST` — часть оборачивается в `Island` (карточку с белым фоном и тенью). Применяется в `LightBox`.
53
+ - `SECOND` — часть без карточки (без фона). Применяется в обычном layout.
123
54
 
124
- - `EHeaderPageType.FIRST | SECOND`
125
- - `EBodyPageType.FIRST | SECOND`
126
- - `EFooterPageType.FIRST | SECOND`
127
- - `EBodyPageVerticalMargin.LARGE` (24px) | `SMALL` (16px)
55
+ Детали props частей — в их собственных AI.md: `HeaderPage-ai.md`, `BodyPage-ai.md`, `FooterPage-ai.md`.
128
56
 
129
57
  ---
130
58
 
131
- ## Ключевые особенности реализации
132
-
133
- ### `useStickyCornerRadius(ref, edge, isEnabled)`
134
-
135
- ```ts
136
- useEffect(() => {
137
- // Подписка на scroll/resize/transitionend ближайшего scroll-родителя.
138
- // ResizeObserver на всех предках до scroller.
139
- // На каждом frame: вычисляем расстояние до edge → r = clamp(0, 24, dist).
140
- // Пишем в --r-top / --r-bottom (CSS-var) и dataset.stuck = "true" если r ≤ 0.5.
141
- }, [ref, edge, isEnabled]);
142
- ```
143
-
144
- - **Нативный sticky** + **анимированный corner-radius**:
145
- - Когда элемент далеко от прилипшей границы → `--r-top: 24px`.
146
- - При прилипании → `--r-top: 0px` плавно (через rAF).
147
- - `data-stuck="true"` — для подключения тени через CSS.
148
- - **`getScrollParent`**: ищет ближайший `overflowY: auto/scroll/overlay`. Default — `window`.
149
- - **`ResizeObserver`** на ВСЕХ предках до scroller — нужен для случая, когда `Spoiler` раскрывается без scroll-события, но меняет высоту контента.
150
- - **`transitionend` listener** — обновление при завершении анимации `lightBoxSideOverlayContent` (cross-component contract по className!).
151
- - **`setTimeout(initialize, 100)`** — задержка для совместимости с открытием LightBox (без задержки анимация не работает).
152
- - **Жёсткие зависимости**: ref, edge, isEnabled — пересоздание подписки при изменении.
153
-
154
- ### CSS-переменные `--r-top`, `--r-bottom`
155
-
156
- - Публичный контракт: устанавливаются JS, читаются в LESS (`border-radius: var(--r-top, 24px) var(--r-top, 24px) 0 0` или подобное).
157
- - При `isEnabled=false` или unmount — переменная удаляется через `style.removeProperty`.
59
+ ## Дизайн-токены
158
60
 
159
- ### Cross-component className-зависимость: `lightBoxSideOverlayContent`
61
+ Собственных CSS-переменных дизайн-токенов у `Page` нет. Внешние отступы и брейкпоинты заданы
62
+ LESS-переменными в `styles/Page.module.less` (`@page-padding-*`, `@screen-sm-max`). Sticky-стили
63
+ для прилипающих Header/Footer (классы `.headerPageTypeFirst.sticky`, `.footerPageTypeFirst.sticky`)
64
+ используют токены соответствующих компонентов (`--triplex-next-HeaderPage-StickyShadow`,
65
+ `--triplex-next-FooterPage-StickyShadow`) — они описаны в AI.md этих компонентов.
160
66
 
161
- ```ts
162
- event.target.classList.contains("lightBoxSideOverlayContent")
163
- ```
67
+ ---
164
68
 
165
- - Hardcoded substring matching на className из `LightBox` package. **При переименовании в LightBox — sticky-corner для page внутри SideOverlay перестанет реагировать на анимацию**. Тех-долг.
69
+ ## Инварианты
166
70
 
167
- ### `setIslandRef` — мерж forwardRef + локального ref
71
+ - `forwardRef<HTMLDivElement>` — не убирать. Ref всегда указывает на корневой `<div>`.
72
+ - `displayName = "Page"` — не менять.
73
+ - `Page` собран через `Object.assign(forwardRef(...), { Body, Header, Footer })` — статические
74
+ свойства `Header` / `Body` / `Footer` должны сохраняться.
75
+ - Корневые классы `page` и `global-page` на корневом `<div>` — не переименовывать (используются
76
+ в стилях, в т.ч. в sticky-селекторах `.global-LB-more-media-point-0`).
77
+ - Экспорты `Page`, `IPageProps` идут в barrel `src/components/Page/index.ts` — сохранять.
78
+ Там же реэкспортируются части и их enum'ы (`EHeaderPageType`, `EFooterPageType`, `EBodyPageType`,
79
+ `EBodyPageVerticalMargin`).
168
80
 
169
- ```ts
170
- const setIslandRef = (instance) => {
171
- islandRef.current = instance;
172
- if (typeof ref === "function") ref(instance);
173
- else if (ref) ref.current = instance;
174
- };
175
- ```
81
+ ---
176
82
 
177
- - Стандартный паттерн merge. Используется в HeaderPage и FooterPage.
83
+ ## Accessibility
178
84
 
179
- ### Discriminated union по `type`
85
+ Особого a11y-поведения нет — это структурный контейнер без интерактивности и без хардкода
86
+ aria-атрибутов. Семантику задаёт потребитель через проброшенные HTML-атрибуты (`...rest`).
87
+ Интерактивность обеспечивают вложенные элементы внутри `Page.Header` / `Page.Footer`
88
+ (кнопки, ссылки, табы).
180
89
 
181
- - TypeScript обеспечивает: `sticky` / `size` доступны только при `FIRST`. При `SECOND` — `never`.
182
- - Discriminator обязателен на потребителе: `<Page.Header type={EHeaderPageType.FIRST} ...>`.
90
+ ---
183
91
 
184
- ### `Island type=TYPE_1` — фиксирован
92
+ ## Связанные компоненты
185
93
 
186
- - При `FIRST` Island всегда `TYPE_1` (нельзя сменить на `TYPE_2`).
94
+ - `HeaderPage` (`Page.Header`), `BodyPage` (`Page.Body`), `FooterPage` (`Page.Footer`) — составные
95
+ части страницы. Каждая имеет собственный AI.md.
96
+ - `Island` — карточка-обёртка для частей типа `FIRST`.
97
+ - `LightBox` — типичное место использования `Page`.
187
98
 
188
- ### `Page.tsx` — `global-page` className
99
+ ---
189
100
 
190
- - Кроме CSS-Modules класса `styles.page` добавляется `styles["global-page"]` (это композитный класс, не глобальный селектор `:global` — но имя зарезервированное). Используется для cross-component хуков.
101
+ ## Stories
191
102
 
192
- ---
103
+ Основные истории: `stories/Page/Page/Page.stories.tsx`
104
+ Файлы примеров: `stories/Page/Page/examples/`
193
105
 
194
- ## Инварианты
106
+ | Story | Example file | Что демонстрирует |
107
+ |---|---|---|
108
+ | `Playground` | `Playground.tsx` | Интерактивный контроль типов `Page.Header` / `Page.Footer` и `verticalMargin` у `Page.Body` |
109
+ | `Default` | `Default.tsx` | Базовая страница: header FIRST, body SECOND, footer FIRST (типичная Page для LightBox) |
110
+ | `WithIslands` | `WithIslands.tsx` | Все части типа FIRST — острова (карточки); для LightBox |
111
+ | `WithoutIslands` | `WithoutIslands.tsx` | Все части типа SECOND — без островов; для layout |
195
112
 
196
- - **Page может содержать только Header / Body / Footer** (контракт документации; типы шире).
197
- - **Discriminated union по `type`** — `EHeaderPageType.FIRST | SECOND` (то же для Body/Footer). Несовместимо с runtime-вычисляемым type без cast'а.
198
- - **`sticky` — только FIRST**, и **только внутри LightBox** (по комментарию в коде; вне LightBox поведение не специфицировано).
199
- - **`useStickyCornerRadius`** жёстко завязан на:
200
- - className `lightBoxSideOverlayContent` (cross-package contract).
201
- - CSS-переменные `--r-top` / `--r-bottom` (публичный контракт со стилями).
202
- - **`maxRadius = 24`** — захардкожен в JS.
203
- - **`Island type=TYPE_1`** при FIRST — фиксирован.
204
- - **`verticalMargin` default `LARGE` (24px)**, в LightBox — `SMALL` (16px).
205
- - **HeaderPage slots = `Header.*`** (Title/Subhead/Tabs/LayoutSidebar) — реэкспорты, не свои реализации.
206
- - **FooterPage slots = `Footer.Description`** — реэкспорт.
207
- - **ForwardRef** на всех уровнях.
208
- - **`global-page` className** на Page — публичное имя.
113
+ `Default`, `WithIslands` и `WithoutIslands` участвуют в скриншот-тестах (покрывают
114
+ комбинации типов `FIRST` / `SECOND` у частей). `Playground` интерактивен и исключён
115
+ (`testRunner: { skip: true }`).
209
116
 
210
117
  ---
211
118
 
212
- ## Accessibility
119
+ ## История изменений
213
120
 
214
- - Базовая семантика наследуется от `Header`, `Body`, `Footer` (заголовки h1/h2 — внутри `Header.Title`).
215
- - `Page` сам — нейтральный `<div>`, не landmark. Если нужен `<main>` — потребитель должен обернуть/передать `role`.
216
- - Sticky-поведение — клавиатурно нормально (sticky == native CSS), screen readers видят корректный flow.
121
+ | Дата | Изменение |
122
+ |---|---|
123
+ | 2026-06-24 | Создан документ. AI-рефакторинг (JSDoc на компоненте и `IPageProps`), unit-тесты (className-merge, статические части), миграция stories на modern pattern. |
217
124
 
218
125
  ---
219
126
 
220
- ## Дизайн-токены
127
+ ## Примеры использования
221
128
 
222
- Нет собственных. Цвета/spacing — от `Island`, `Header`, `Body`, `Footer`. CSS-переменные `--r-top` / `--r-bottom` — управляющие, не токены.
129
+ ### Default
223
130
 
224
- ---
131
+ `stories/Page/Page/examples/Default.tsx`
225
132
 
226
- ## Связанные компоненты
133
+ ```tsx
134
+ import React from "react";
135
+ import {
136
+ Page,
137
+ EHeaderPageType,
138
+ EBodyPageType,
139
+ EFooterPageType,
140
+ Button,
141
+ EButtonTheme,
142
+ EComponentSize,
143
+ Title,
144
+ Text,
145
+ ETitleSize,
146
+ ETextSize,
147
+ EFontType,
148
+ Gap,
149
+ } from "@sberbusiness/triplex-next";
150
+
151
+ export const Default = () => (
152
+ <Page>
153
+ <Page.Header type={EHeaderPageType.FIRST}>
154
+ <Page.Header.Title>
155
+ <Page.Header.Title.Content>
156
+ <Title tag="h1" size={ETitleSize.H1}>
157
+ Title text
158
+ </Title>
159
+ <Gap size={8} />
160
+ <Text tag="div" size={ETextSize.B3} type={EFontType.SECONDARY}>
161
+ Optional description about the page
162
+ </Text>
163
+ </Page.Header.Title.Content>
164
+ <Page.Header.Title.Controls>
165
+ <Button theme={EButtonTheme.SECONDARY} size={EComponentSize.MD}>
166
+ Button text
167
+ </Button>
168
+ <Button theme={EButtonTheme.GENERAL} size={EComponentSize.MD}>
169
+ Button text
170
+ </Button>
171
+ </Page.Header.Title.Controls>
172
+ </Page.Header.Title>
173
+ </Page.Header>
174
+
175
+ <Page.Body type={EBodyPageType.SECOND}>
176
+ <Text tag="div" size={ETextSize.B3}>
177
+ Page content
178
+ </Text>
179
+ </Page.Body>
180
+
181
+ <Page.Footer type={EFooterPageType.FIRST}>
182
+ <Page.Footer.Description>
183
+ <Page.Footer.Description.Content>
184
+ <Text size={ETextSize.B3}>Footer page text</Text>
185
+ </Page.Footer.Description.Content>
186
+ <Page.Footer.Description.Controls>
187
+ <Button size={EComponentSize.MD} theme={EButtonTheme.SECONDARY}>
188
+ Button text
189
+ </Button>
190
+ <Button size={EComponentSize.MD} theme={EButtonTheme.GENERAL}>
191
+ Button text
192
+ </Button>
193
+ </Page.Footer.Description.Controls>
194
+ </Page.Footer.Description>
195
+ </Page.Footer>
196
+ </Page>
197
+ );
198
+ ```
227
199
 
228
- - `Header`, `Body`, `Footer` — нижележащие компоненты (FIRST оборачивает в Island).
229
- - `Island` (TYPE_1) — карточка-обёртка для FIRST.
230
- - `LightBox` — типичный контекст для `type=SECOND` и `sticky`.
231
- - `Spoiler` — потребитель ResizeObserver (срабатывание sticky-corner при раскрытии).
200
+ ### WithIslands
232
201
 
233
- ---
202
+ `stories/Page/Page/examples/WithIslands.tsx`
234
203
 
235
- ## Stories
204
+ ```tsx
205
+ import React from "react";
206
+ import {
207
+ Page,
208
+ EHeaderPageType,
209
+ EBodyPageType,
210
+ EFooterPageType,
211
+ Button,
212
+ EButtonTheme,
213
+ EComponentSize,
214
+ Title,
215
+ Text,
216
+ ETitleSize,
217
+ ETextSize,
218
+ EFontType,
219
+ Gap,
220
+ } from "@sberbusiness/triplex-next";
221
+
222
+ // Header, Body и Footer типа FIRST — каждый блок оборачивается в Island (карточку). Используется в LightBox.
223
+ export const WithIslands = () => (
224
+ <Page>
225
+ <Page.Header type={EHeaderPageType.FIRST}>
226
+ <Page.Header.Title>
227
+ <Page.Header.Title.Content>
228
+ <Title tag="h1" size={ETitleSize.H1}>
229
+ Title text
230
+ </Title>
231
+ <Gap size={8} />
232
+ <Text tag="div" size={ETextSize.B3} type={EFontType.SECONDARY}>
233
+ Optional description about the page
234
+ </Text>
235
+ </Page.Header.Title.Content>
236
+ <Page.Header.Title.Controls>
237
+ <Button theme={EButtonTheme.SECONDARY} size={EComponentSize.MD}>
238
+ Button text
239
+ </Button>
240
+ <Button theme={EButtonTheme.GENERAL} size={EComponentSize.MD}>
241
+ Button text
242
+ </Button>
243
+ </Page.Header.Title.Controls>
244
+ </Page.Header.Title>
245
+ </Page.Header>
246
+
247
+ <Page.Body type={EBodyPageType.FIRST}>
248
+ <Text tag="div" size={ETextSize.B3}>
249
+ Page content
250
+ </Text>
251
+ </Page.Body>
252
+
253
+ <Page.Footer type={EFooterPageType.FIRST}>
254
+ <Page.Footer.Description>
255
+ <Page.Footer.Description.Content>
256
+ <Text size={ETextSize.B3}>Footer page text</Text>
257
+ </Page.Footer.Description.Content>
258
+ <Page.Footer.Description.Controls>
259
+ <Button size={EComponentSize.MD} theme={EButtonTheme.SECONDARY}>
260
+ Button text
261
+ </Button>
262
+ <Button size={EComponentSize.MD} theme={EButtonTheme.GENERAL}>
263
+ Button text
264
+ </Button>
265
+ </Page.Footer.Description.Controls>
266
+ </Page.Footer.Description>
267
+ </Page.Footer>
268
+ </Page>
269
+ );
270
+ ```
236
271
 
237
- `stories/Page/Page.stories.tsx`
238
- Примеры: `stories/Page/examples/`
272
+ ### WithoutIslands
239
273
 
240
- ---
274
+ `stories/Page/Page/examples/WithoutIslands.tsx`
241
275
 
242
- ## История изменений
276
+ ```tsx
277
+ import React from "react";
278
+ import {
279
+ Page,
280
+ EHeaderPageType,
281
+ EBodyPageType,
282
+ EFooterPageType,
283
+ Button,
284
+ EButtonTheme,
285
+ EComponentSize,
286
+ Title,
287
+ Text,
288
+ ETitleSize,
289
+ ETextSize,
290
+ EFontType,
291
+ Gap,
292
+ } from "@sberbusiness/triplex-next";
293
+
294
+ // Header, Body и Footer типа SECOND — без Island (без карточек). Используется в layout, а не в LightBox.
295
+ export const WithoutIslands = () => (
296
+ <Page>
297
+ <Page.Header type={EHeaderPageType.SECOND}>
298
+ <Page.Header.Title>
299
+ <Page.Header.Title.Content>
300
+ <Title tag="h1" size={ETitleSize.H1}>
301
+ Title text
302
+ </Title>
303
+ <Gap size={8} />
304
+ <Text tag="div" size={ETextSize.B3} type={EFontType.SECONDARY}>
305
+ Optional description about the page
306
+ </Text>
307
+ </Page.Header.Title.Content>
308
+ <Page.Header.Title.Controls>
309
+ <Button theme={EButtonTheme.SECONDARY_LIGHT} size={EComponentSize.MD}>
310
+ Button text
311
+ </Button>
312
+ <Button theme={EButtonTheme.GENERAL} size={EComponentSize.MD}>
313
+ Button text
314
+ </Button>
315
+ </Page.Header.Title.Controls>
316
+ </Page.Header.Title>
317
+ </Page.Header>
318
+
319
+ <Page.Body type={EBodyPageType.SECOND}>
320
+ <Text tag="div" size={ETextSize.B3}>
321
+ Page content
322
+ </Text>
323
+ </Page.Body>
324
+
325
+ <Page.Footer type={EFooterPageType.SECOND}>
326
+ <Page.Footer.Description>
327
+ <Page.Footer.Description.Content>
328
+ <Text size={ETextSize.B3}>Footer page text</Text>
329
+ </Page.Footer.Description.Content>
330
+ <Page.Footer.Description.Controls>
331
+ <Button size={EComponentSize.MD} theme={EButtonTheme.SECONDARY_LIGHT}>
332
+ Button text
333
+ </Button>
334
+ <Button size={EComponentSize.MD} theme={EButtonTheme.GENERAL}>
335
+ Button text
336
+ </Button>
337
+ </Page.Footer.Description.Controls>
338
+ </Page.Footer.Description>
339
+ </Page.Footer>
340
+ </Page>
341
+ );
342
+ ```
243
343
 
244
- | Дата | Изменение |
245
- |---|---|
246
- | 2026-04-18 | Создан документ |