@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.
Files changed (73) hide show
  1. package/README.md +10 -0
  2. package/bundle/components/AlertContext.md +268 -0
  3. package/bundle/components/BodyPage.md +186 -0
  4. package/bundle/components/Button.md +93 -85
  5. package/bundle/components/ButtonDropdown.md +36 -70
  6. package/bundle/components/ButtonDropdownExtended.md +422 -0
  7. package/bundle/components/ButtonIcon.md +41 -48
  8. package/bundle/components/Caption.md +291 -0
  9. package/bundle/components/Checkbox.md +43 -122
  10. package/bundle/components/CheckboxXGroup.md +109 -46
  11. package/bundle/components/CheckboxYGroup.md +77 -49
  12. package/bundle/components/CodeText.md +197 -0
  13. package/bundle/components/Col.md +311 -162
  14. package/bundle/components/CollapsibleTree.md +584 -0
  15. package/bundle/components/CollapsibleTreeExtended.md +422 -0
  16. package/bundle/components/Dropdown.md +748 -346
  17. package/bundle/components/EmptyView.md +14 -15
  18. package/bundle/components/FooterPage.md +203 -0
  19. package/bundle/components/Gap.md +115 -57
  20. package/bundle/components/HeaderPage.md +226 -0
  21. package/bundle/components/HelpBox.md +45 -84
  22. package/bundle/components/ImageGallery.md +423 -0
  23. package/bundle/components/ImageGalleryExtended.md +606 -0
  24. package/bundle/components/LightBox.md +2252 -233
  25. package/bundle/components/List.md +216 -183
  26. package/bundle/components/ListActionItem.md +157 -0
  27. package/bundle/components/ListItem.md +276 -0
  28. package/bundle/components/ListItemControlsButton.md +103 -0
  29. package/bundle/components/ListItemControlsButtonDropdown.md +107 -0
  30. package/bundle/components/ListItemSelectable.md +99 -0
  31. package/bundle/components/ListItemTable.md +390 -0
  32. package/bundle/components/ListMaster.md +876 -156
  33. package/bundle/components/ListMasterFooter.md +80 -0
  34. package/bundle/components/ListMasterHeader.md +86 -0
  35. package/bundle/components/ListSortable.md +153 -0
  36. package/bundle/components/ListSortableItem.md +175 -0
  37. package/bundle/components/ListTableItem.md +391 -0
  38. package/bundle/components/ModalWindow.md +427 -237
  39. package/bundle/components/MonthYearField.md +145 -109
  40. package/bundle/components/Notification.md +625 -155
  41. package/bundle/components/Overlay.md +271 -170
  42. package/bundle/components/Page.md +284 -186
  43. package/bundle/components/Pagination.md +206 -229
  44. package/bundle/components/Portal.md +131 -67
  45. package/bundle/components/Row.md +171 -69
  46. package/bundle/components/Text.md +320 -0
  47. package/bundle/components/TextField.md +364 -97
  48. package/bundle/components/Title.md +296 -0
  49. package/bundle/guides/codestyle.md +38 -11
  50. package/bundle/guides/commits.md +119 -26
  51. package/bundle/guides/context.md +34 -30
  52. package/bundle/guides/stories.md +110 -40
  53. package/bundle/guides/template.md +3 -7
  54. package/bundle/guides/tests.md +48 -2
  55. package/bundle/manifest.json +275 -30
  56. package/bundle/release-notes/1.26.0.mdx +33 -2
  57. package/bundle/release-notes/1.27.0.mdx +43 -0
  58. package/bundle/release-notes/1.28.0.mdx +25 -0
  59. package/bundle/release-notes/1.29.0.mdx +47 -0
  60. package/bundle/release-notes/1.30.0.mdx +56 -0
  61. package/bundle/release-notes/1.31.0.mdx +52 -0
  62. package/bundle/release-notes/1.32.0.mdx +35 -0
  63. package/bundle/release-notes/1.33.0.mdx +61 -0
  64. package/bundle/release-notes/1.34.0.mdx +35 -0
  65. package/bundle/release-notes/1.35.0.mdx +21 -0
  66. package/bundle/release-notes/1.35.1.mdx +11 -0
  67. package/bundle/release-notes/1.36.0.mdx +21 -0
  68. package/bundle/release-notes/1.37.0.mdx +71 -0
  69. package/bundle/release-notes/1.38.0.mdx +36 -0
  70. package/bundle/release-notes/1.39.0.mdx +66 -0
  71. package/bundle/release-notes/1.40.0.mdx +27 -0
  72. package/bundle/release-notes/1.41.0.mdx +7 -0
  73. 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,334 @@ 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-07-20 | Вертикальные padding изменены: 24px (было 32px) для desktop, 8px (было 16px) для mobile — через `@page-padding-desktop-y` / `@page-padding-mobile-y`. |
124
+ | 2026-06-24 | Создан документ. AI-рефакторинг (JSDoc на компоненте и `IPageProps`), unit-тесты (className-merge, статические части), миграция stories на modern pattern. |
217
125
 
218
126
  ---
219
127
 
220
- ## Дизайн-токены
128
+ ## Примеры использования
221
129
 
222
- Нет собственных. Цвета/spacing — от `Island`, `Header`, `Body`, `Footer`. CSS-переменные `--r-top` / `--r-bottom` — управляющие, не токены.
130
+ ### Default
223
131
 
224
- ---
132
+ `stories/Page/Page/examples/Default.tsx`
225
133
 
226
- ## Связанные компоненты
134
+ ```tsx
135
+ import React from "react";
136
+ import {
137
+ Page,
138
+ EHeaderPageType,
139
+ EBodyPageType,
140
+ EFooterPageType,
141
+ Button,
142
+ EButtonTheme,
143
+ EComponentSize,
144
+ Title,
145
+ Text,
146
+ ETitleSize,
147
+ ETextSize,
148
+ EFontType,
149
+ Gap,
150
+ } from "@sberbusiness/triplex-next";
151
+
152
+ export const Default = () => (
153
+ <Page>
154
+ <Page.Header type={EHeaderPageType.FIRST}>
155
+ <Page.Header.Title>
156
+ <Page.Header.Title.Content>
157
+ <Title tag="h1" size={ETitleSize.H1}>
158
+ Title text
159
+ </Title>
160
+ <Gap size={8} />
161
+ <Text tag="div" size={ETextSize.B3} type={EFontType.SECONDARY}>
162
+ Optional description about the page
163
+ </Text>
164
+ </Page.Header.Title.Content>
165
+ <Page.Header.Title.Controls>
166
+ <Button theme={EButtonTheme.SECONDARY} size={EComponentSize.MD}>
167
+ Button text
168
+ </Button>
169
+ <Button theme={EButtonTheme.GENERAL} size={EComponentSize.MD}>
170
+ Button text
171
+ </Button>
172
+ </Page.Header.Title.Controls>
173
+ </Page.Header.Title>
174
+ </Page.Header>
175
+
176
+ <Page.Body type={EBodyPageType.SECOND}>
177
+ <Text tag="div" size={ETextSize.B3}>
178
+ Page content
179
+ </Text>
180
+ </Page.Body>
181
+
182
+ <Page.Footer type={EFooterPageType.FIRST}>
183
+ <Page.Footer.Description>
184
+ <Page.Footer.Description.Content>
185
+ <Text size={ETextSize.B3}>Footer page text</Text>
186
+ </Page.Footer.Description.Content>
187
+ <Page.Footer.Description.Controls>
188
+ <Button size={EComponentSize.MD} theme={EButtonTheme.SECONDARY}>
189
+ Button text
190
+ </Button>
191
+ <Button size={EComponentSize.MD} theme={EButtonTheme.GENERAL}>
192
+ Button text
193
+ </Button>
194
+ </Page.Footer.Description.Controls>
195
+ </Page.Footer.Description>
196
+ </Page.Footer>
197
+ </Page>
198
+ );
199
+ ```
227
200
 
228
- - `Header`, `Body`, `Footer` — нижележащие компоненты (FIRST оборачивает в Island).
229
- - `Island` (TYPE_1) — карточка-обёртка для FIRST.
230
- - `LightBox` — типичный контекст для `type=SECOND` и `sticky`.
231
- - `Spoiler` — потребитель ResizeObserver (срабатывание sticky-corner при раскрытии).
201
+ ### WithIslands
232
202
 
233
- ---
203
+ `stories/Page/Page/examples/WithIslands.tsx`
234
204
 
235
- ## Stories
205
+ ```tsx
206
+ import React from "react";
207
+ import {
208
+ Page,
209
+ EHeaderPageType,
210
+ EBodyPageType,
211
+ EFooterPageType,
212
+ Button,
213
+ EButtonTheme,
214
+ EComponentSize,
215
+ Title,
216
+ Text,
217
+ ETitleSize,
218
+ ETextSize,
219
+ EFontType,
220
+ Gap,
221
+ } from "@sberbusiness/triplex-next";
222
+
223
+ // Header, Body и Footer типа FIRST — каждый блок оборачивается в Island (карточку). Используется в LightBox.
224
+ export const WithIslands = () => (
225
+ <Page>
226
+ <Page.Header type={EHeaderPageType.FIRST}>
227
+ <Page.Header.Title>
228
+ <Page.Header.Title.Content>
229
+ <Title tag="h1" size={ETitleSize.H1}>
230
+ Title text
231
+ </Title>
232
+ <Gap size={8} />
233
+ <Text tag="div" size={ETextSize.B3} type={EFontType.SECONDARY}>
234
+ Optional description about the page
235
+ </Text>
236
+ </Page.Header.Title.Content>
237
+ <Page.Header.Title.Controls>
238
+ <Button theme={EButtonTheme.SECONDARY} size={EComponentSize.MD}>
239
+ Button text
240
+ </Button>
241
+ <Button theme={EButtonTheme.GENERAL} size={EComponentSize.MD}>
242
+ Button text
243
+ </Button>
244
+ </Page.Header.Title.Controls>
245
+ </Page.Header.Title>
246
+ </Page.Header>
247
+
248
+ <Page.Body type={EBodyPageType.FIRST}>
249
+ <Text tag="div" size={ETextSize.B3}>
250
+ Page content
251
+ </Text>
252
+ </Page.Body>
253
+
254
+ <Page.Footer type={EFooterPageType.FIRST}>
255
+ <Page.Footer.Description>
256
+ <Page.Footer.Description.Content>
257
+ <Text size={ETextSize.B3}>Footer page text</Text>
258
+ </Page.Footer.Description.Content>
259
+ <Page.Footer.Description.Controls>
260
+ <Button size={EComponentSize.MD} theme={EButtonTheme.SECONDARY}>
261
+ Button text
262
+ </Button>
263
+ <Button size={EComponentSize.MD} theme={EButtonTheme.GENERAL}>
264
+ Button text
265
+ </Button>
266
+ </Page.Footer.Description.Controls>
267
+ </Page.Footer.Description>
268
+ </Page.Footer>
269
+ </Page>
270
+ );
271
+ ```
236
272
 
237
- `stories/Page/Page.stories.tsx`
238
- Примеры: `stories/Page/examples/`
273
+ ### WithoutIslands
239
274
 
240
- ---
275
+ `stories/Page/Page/examples/WithoutIslands.tsx`
241
276
 
242
- ## История изменений
277
+ ```tsx
278
+ import React from "react";
279
+ import {
280
+ Page,
281
+ EHeaderPageType,
282
+ EBodyPageType,
283
+ EFooterPageType,
284
+ Button,
285
+ EButtonTheme,
286
+ EComponentSize,
287
+ Title,
288
+ Text,
289
+ ETitleSize,
290
+ ETextSize,
291
+ EFontType,
292
+ Gap,
293
+ } from "@sberbusiness/triplex-next";
294
+
295
+ // Header, Body и Footer типа SECOND — без Island (без карточек). Используется в layout, а не в LightBox.
296
+ export const WithoutIslands = () => (
297
+ <Page>
298
+ <Page.Header type={EHeaderPageType.SECOND}>
299
+ <Page.Header.Title>
300
+ <Page.Header.Title.Content>
301
+ <Title tag="h1" size={ETitleSize.H1}>
302
+ Title text
303
+ </Title>
304
+ <Gap size={8} />
305
+ <Text tag="div" size={ETextSize.B3} type={EFontType.SECONDARY}>
306
+ Optional description about the page
307
+ </Text>
308
+ </Page.Header.Title.Content>
309
+ <Page.Header.Title.Controls>
310
+ <Button theme={EButtonTheme.SECONDARY_LIGHT} size={EComponentSize.MD}>
311
+ Button text
312
+ </Button>
313
+ <Button theme={EButtonTheme.GENERAL} size={EComponentSize.MD}>
314
+ Button text
315
+ </Button>
316
+ </Page.Header.Title.Controls>
317
+ </Page.Header.Title>
318
+ </Page.Header>
319
+
320
+ <Page.Body type={EBodyPageType.SECOND}>
321
+ <Text tag="div" size={ETextSize.B3}>
322
+ Page content
323
+ </Text>
324
+ </Page.Body>
325
+
326
+ <Page.Footer type={EFooterPageType.SECOND}>
327
+ <Page.Footer.Description>
328
+ <Page.Footer.Description.Content>
329
+ <Text size={ETextSize.B3}>Footer page text</Text>
330
+ </Page.Footer.Description.Content>
331
+ <Page.Footer.Description.Controls>
332
+ <Button size={EComponentSize.MD} theme={EButtonTheme.SECONDARY_LIGHT}>
333
+ Button text
334
+ </Button>
335
+ <Button size={EComponentSize.MD} theme={EButtonTheme.GENERAL}>
336
+ Button text
337
+ </Button>
338
+ </Page.Footer.Description.Controls>
339
+ </Page.Footer.Description>
340
+ </Page.Footer>
341
+ </Page>
342
+ );
343
+ ```
243
344
 
244
- | Дата | Изменение |
245
- |---|---|
246
- | 2026-04-18 | Создан документ |