@sberbusiness/triplex-next-mcp-server 1.40.0-beta → 1.42.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 (36) hide show
  1. package/bundle/components/AlertProcess.md +460 -0
  2. package/bundle/components/Amount.md +145 -169
  3. package/bundle/components/Badge.md +155 -219
  4. package/bundle/components/Body.md +108 -116
  5. package/bundle/components/Calendar.md +183 -368
  6. package/bundle/components/CarouselExtended.md +355 -194
  7. package/bundle/components/Chip.md +310 -314
  8. package/bundle/components/ComposedKeyDownListener.md +323 -0
  9. package/bundle/components/FooterPage.md +2 -1
  10. package/bundle/components/FormField.md +468 -232
  11. package/bundle/components/HeaderPage.md +2 -1
  12. package/bundle/components/IconWrapper.md +142 -89
  13. package/bundle/components/Island.md +303 -123
  14. package/bundle/components/KeyDownListener.md +152 -100
  15. package/bundle/components/LoaderMiddle.md +265 -0
  16. package/bundle/components/LoaderScreen.md +178 -81
  17. package/bundle/components/LoaderSmall.md +230 -0
  18. package/bundle/components/MaskedField.md +481 -0
  19. package/bundle/components/MediaWidth.md +246 -108
  20. package/bundle/components/MobileView.md +192 -68
  21. package/bundle/components/ModalWindow.md +3 -1
  22. package/bundle/components/Page.md +3 -1
  23. package/bundle/components/Pagination.md +20 -0
  24. package/bundle/components/SelectExtendedField.md +691 -236
  25. package/bundle/components/ThemeProvider.md +305 -117
  26. package/bundle/components/Tooltip.md +421 -181
  27. package/bundle/guides/commits.md +54 -9
  28. package/bundle/guides/context.md +26 -0
  29. package/bundle/guides/stories.md +2 -0
  30. package/bundle/guides/template.md +1 -1
  31. package/bundle/manifest.json +63 -18
  32. package/bundle/release-notes/1.41.0.mdx +76 -0
  33. package/bundle/release-notes/1.41.1.mdx +18 -0
  34. package/bundle/release-notes/1.42.0.mdx +88 -0
  35. package/bundle/release-notes/1.43.0.mdx +7 -0
  36. package/package.json +1 -1
@@ -1,9 +1,7 @@
1
1
  ---
2
2
  component: Island
3
3
  category: Layout
4
- figma-node: ""
5
- figma-file: ""
6
- related: [IslandAccordion, IslandWidget, Card, Page]
4
+ related: [IslandAccordion, IslandWidget, LoaderScreen, ModalWindow]
7
5
  tokens:
8
6
  - --triplex-next-Island-Type1_Background
9
7
  - --triplex-next-Island-Type1_Shadow
@@ -19,179 +17,361 @@ version: "1.0"
19
17
 
20
18
  ## Назначение
21
19
 
22
- Карточка-"остров" — контейнер со скруглениями, фоном и тенью. **Compound-компонент**
23
- с тремя дочерними слотами: `Island.Header`, `Island.Body`, `Island.Footer`.
24
- Имеет три визуальных типа (`TYPE_1` / `TYPE_2` / `TYPE_3`) — отличаются
25
- цветом фона и тенью — и три размера (`SM`/`MD`/`LG`) — отличаются
26
- радиусом, padding'ом и межблочным margin'ом.
20
+ Базовый контейнер-карточка библиотеки: `<div>` с фоном, тенью, скруглением и внутренними
21
+ отступами. Собственной логики не имеет — задаёт поверхность, на которой лежит контент,
22
+ вертикальные отступы между своими частями `Island.Header`, `Island.Body`, `Island.Footer` и
23
+ состояние загрузки (`loading`), в котором поверх контента показывается `LoaderScreen`.
27
24
 
28
- Используй когда: нужна базовая карточка с заголовком, контентом и футером.
29
- Для аккордеона предпочитай `IslandAccordion`, для виджета с иконкой —
30
- `IslandWidget`.
25
+ Используй когда: контент нужно визуально выделить карточкой на фоне страницы — блок страницы
26
+ (`BodyPage`, `HeaderPage`, `FooterPage`), диалог подтверждения (`Confirm`), элемент аккордеона
27
+ (`IslandAccordion`), виджет (`IslandWidget`).
28
+
29
+ Не используй когда:
30
+ - Нужна интерактивность (клик по карточке, раскрытие, удаление) — Island не кнопка и не
31
+ управляет состоянием. Возьми `IslandAccordion` (раскрывающиеся элементы) или `IslandWidget`
32
+ (виджет со сворачиванием в адаптиве), либо положи интерактивный элемент внутрь Island.
33
+ - Нужен только отступ или сетка без визуальной карточки — возьми `Gap`, `Row`/`Col`.
34
+ - Нужен overlay/модальное окно — возьми `ModalWindow`, `LightBox`, `LightBoxSideOverlay`.
31
35
 
32
36
  ---
33
37
 
34
- ## Файловая структура
35
-
36
- ```text
37
- src/components/Island/
38
- ├── Island.tsx # Object.assign → Body/Header/Footer
39
- ├── enums.ts # EIslandType (TYPE_1/TYPE_2/TYPE_3)
40
- ├── utils.ts # mapTypeToClassName(type) → styles.type1/2/3
41
- ├── index.ts # Barrel
42
- ├── components/
43
- │ ├── IslandHeader.tsx # <div .islandHeader>
44
- │ ├── IslandBody.tsx # <div .islandBody>
45
- │ └── IslandFooter.tsx # <div .islandFooter>
46
- └── styles/
47
- ├── Island.module.less # Типы, размеры, mobile-ресайз
48
- ├── IslandHeader.module.less
49
- ├── IslandBody.module.less
50
- └── IslandFooter.module.less
51
- ```
38
+ ## Варианты и props
39
+
40
+ ### Обязательные props
41
+
42
+ Обязательных props нет — `<Island>` рендерится с типом `TYPE_1` и размером `MD`.
43
+
44
+ ### Опциональные props
45
+
46
+ | Prop | Тип | По умолчанию | Описание |
47
+ |---|---|---|---|
48
+ | `type` | `EIslandType` | `EIslandType.TYPE_1` | Визуальный тип. Влияет только на фон и тень, на размеры — нет |
49
+ | `size` | `EComponentSize` | `EComponentSize.MD` | Скругление, внутренние отступы карточки и отступы между Header / Body / Footer |
50
+ | `loading` | `boolean` | `false` | Показывает `LoaderScreen` поверх контента карточки |
51
+ | `loaderScreenProps` | `ILoaderScreenMiddleProps` | `undefined` | Props лоадера: `description`, `controls`, `className` и остальные атрибуты `<div>`. `type` задаёт Island (`middle`) |
52
+
53
+ Компонент расширяет `React.HTMLAttributes<HTMLDivElement>` — все стандартные атрибуты `<div>`
54
+ (`className`, `style`, `role`, `aria-*`, `data-*`, обработчики событий) попадают на корневой элемент.
55
+
56
+ ### Состояние загрузки
57
+
58
+ При `loading` последним потомком карточки рендерится `<LoaderScreen type="middle">` — абсолютно
59
+ спозиционированный по всей карточке (`inset: 0` от padding-box, то есть включая внутренние отступы)
60
+ блок с полупрозрачной подложкой и спиннером по центру.
61
+
62
+ - **Контент остаётся в DOM** — он не размонтируется, только перекрывается подложкой. Форма под
63
+ лоадером остаётся заполненной и фокусируемой: лоадер не блокирует клавиатуру и не ставит
64
+ `inert`/`aria-hidden`. Если ввод нужно запретить, потребитель сам дизейблит контролы.
65
+ - **Скругление подложки — `border-radius: inherit`**, поэтому лоадер повторяет скругление карточки
66
+ при любом `size` и в адаптиве. Дублировать значения по размерам не нужно.
67
+ - **`z-index` лоадера внутри Island — `@z-index-step` (100), а не `@z-index-loader-screen` (10100)**
68
+ из его собственных стилей: правило `.island .islandLoaderScreen` перебивает базовое по
69
+ специфичности. Подложка перекрывает контент карточки, но не глобальные оверлеи (`Dropdown`,
70
+ `ModalWindow`, `Tooltip`), лежащие над ней. Тот же приём — у `List` и `TableBasic`.
71
+ - **Лоадер идёт после `Island.Footer`**, поэтому селекторы отступов между частями
72
+ (`.islandBody + .islandFooter` и т.п.) он не ломает.
73
+ - **Карточка не должна скроллиться.** Лоадер позиционируется абсолютно и растягивается по padding-box
74
+ карточки. Если потребитель задал Island `overflow: auto`/`scroll`, подложка окажется в
75
+ scrollable-overflow: она перекроет только область, видимую в начале прокрутки, и уедет вверх
76
+ вместе с контентом. Для скроллируемой области состояние загрузки вешают на нескроллируемого
77
+ родителя.
78
+ - **В `ModalWindowBody` этих props нет** — `IModalWindowBodyProps` объявлен как
79
+ `Omit<IIslandProps, "loading" | "loaderScreenProps">` ровно по причине выше: тело модалки
80
+ скроллируется (`overflow: auto`). Состояние загрузки модального окна задаётся одноимёнными props
81
+ `ModalWindowContent` — он не скроллится и перекрывает окно целиком.
82
+
83
+ ### Размеры
84
+
85
+ | `size` | `border-radius` | `padding` | Отступ между частями | Адаптив (`max-width: @screen-sm-max`) |
86
+ |---|---|---|---|---|
87
+ | `SM` | 16px | 16px | 8px | без изменений |
88
+ | `MD` | 24px | 24px | 12px | схлопывается до 16px / 16px |
89
+ | `LG` | 32px | 32px | 16px | схлопывается до 24px / 24px |
90
+
91
+ Отступ между частями схлопыванию в адаптиве не подвергается — меняются только скругление и padding.
92
+
93
+ ### Составные части
94
+
95
+ `Island.Header`, `Island.Body`, `Island.Footer` (они же `IslandHeader`, `IslandBody`,
96
+ `IslandFooter` из barrel) — тривиальные `<div>`-обёртки: `className + ...rest + forwardRef`,
97
+ собственных props нет. Их единственная задача — нести класс, по которому Island расставляет
98
+ вертикальные отступы. Использовать их все необязательно: у карточки может быть только Body.
99
+
100
+ ### Ограничения
101
+
102
+ - **Части должны идти соседними элементами в порядке Header → Body → Footer.**
103
+ Отступы задаются смежными селекторами (`.islandHeader + .islandBody`,
104
+ `.islandHeader + .islandFooter`, `.islandBody + .islandFooter`) внутри классов размера.
105
+ Обёртка вокруг части, чужой элемент между частями или другой порядок ломают отступы.
106
+ Пример из библиотеки: `IslandAccordion` оборачивает `Island.Body` и `Island.Footer` в
107
+ `ExpandAnimation`, поэтому `.islandHeader + .islandBody` там не срабатывает и отступ между
108
+ шапкой и телом задаётся собственными паддингами аккордеона; тело и подвал при этом остаются
109
+ соседями внутри одной обёртки, так что `.islandBody + .islandFooter` сработал бы — аккордеон
110
+ гасит его явно (`margin-top: 0 !important` у `.footer` в `IslandAccordion.module.less`),
111
+ потому что владеет своей схемой отступов.
112
+ - **Отступы даёт только родительский Island.** Отрендеренный отдельно `IslandBody` — просто `<div>`.
113
+ - **`className`, переданный в часть, дополняет базовый класс, а не заменяет его** (с 1.41.0).
114
+ Часть остаётся под селекторами отступов Island и сохраняет `position: relative` из своего
115
+ LESS-модуля. Потребителю, которому нужна собственная вёрстка внутри карточки, придётся гасить
116
+ `margin-top` с достаточной специфичностью: правило Island — четыре класса
117
+ (`.island.md .islandBody + .islandFooter`), поэтому в самой библиотеке для этого используется
118
+ `!important` (см. `IslandAccordion.module.less`), а не цепочка селекторов.
119
+ - **Вложенный Island:** правила отступов написаны через потомка (`.island.md .islandHeader + .islandBody`),
120
+ поэтому части вложенной карточки попадают и под селекторы внешней. Специфичность у правил всех
121
+ размеров одинаковая, так что при разных `size` побеждает правило, которое ниже в
122
+ `Island.module.less` (порядок в файле — `sm` → `md` → `lg`), а не ближайший родитель.
52
123
 
53
124
  ---
54
125
 
55
- ## Compound-структура
126
+ ## Дизайн-токены
56
127
 
57
- ```tsx
58
- <Island type={EIslandType.TYPE_1} size={EComponentSize.MD}>
59
- <Island.Header>Заголовок</Island.Header>
60
- <Island.Body>Основной контент</Island.Body>
61
- <Island.Footer>
62
- <Button>Действие</Button>
63
- </Island.Footer>
64
- </Island>
65
128
  ```
66
-
67
- Все три слота опциональны. Отступы между ними задаются смежным CSS-селектором
68
- на корне:
69
- ```less
70
- .islandHeader + .islandBody,
71
- .islandHeader + .islandFooter,
72
- .islandBody + .islandFooter { margin-top: <size>; }
129
+ --triplex-next-Island-Type1_Background
130
+ --triplex-next-Island-Type1_Shadow
131
+ --triplex-next-Island-Type2_Background
132
+ --triplex-next-Island-Type2_Shadow
133
+ --triplex-next-Island-Type3_Background
134
+ --triplex-next-Island-Type3_Shadow
73
135
  ```
74
- Размер зазора меняется со `size` (8/12/16 px).
136
+
137
+ Значения задаются в `src/components/DesignTokens/components/Island.ts`. `Type1_Shadow` и
138
+ `Type3_Shadow` — `none`, `Type2_Shadow` — внутренняя рамка `0 0 0 1px … inset`. Скругления и
139
+ отступы токенами не описываются, они заданы литералами в `styles/Island.module.less`.
75
140
 
76
141
  ---
77
142
 
78
- ## Варианты и props
143
+ ## Инварианты
79
144
 
80
- ### Island — `IIslandProps extends HTMLAttributes<HTMLDivElement>`
145
+ - **`forwardRef`** — обязателен у `Island` и всех трёх частей, `ref` идёт на корневой `<div>`.
146
+ - **Корневой элемент — `<div>`** у Island и у каждой части. Смена тега меняет дефолтный
147
+ `display` и семантику, то есть ломает вёрстку потребителей (селекторы отступов
148
+ класс-базированные и тег не проверяют).
149
+ - **Имена CSS-классов `islandHeader` / `islandBody` / `islandFooter` совпадают в четырёх
150
+ LESS-модулях намеренно.** `scripts/generate-scoped-name.ts` хеширует класс по
151
+ `имя папки компонента + имя класса + версия библиотеки`, поэтому `.islandHeader` в
152
+ `styles/Island.module.less` и в `styles/IslandHeader.module.less` дают один и тот же хеш —
153
+ на этом и держатся селекторы отступов. Следствия:
154
+ - файлы частей и их стили нельзя выносить из `src/components/Island/`;
155
+ - переименовывать класс можно только одновременно во всех модулях, где он встречается.
156
+ - **У классов `.islandHeader` / `.islandBody` / `.islandFooter` должно оставаться хотя бы одно
157
+ CSS-свойство** (сейчас `position: relative` / `display: block`), иначе класс не попадёт в сборку
158
+ и отступы перестанут работать. В LESS-файлах об этом есть комментарии — не удаляй.
159
+ - **Публичный API:** `Island`, `IslandHeader`, `IslandBody`, `IslandFooter`, `EIslandType`,
160
+ `IIslandProps`, `IIslandHeaderProps`, `IIslandBodyProps`, `IIslandFooterProps` экспортируются из
161
+ `src/components/Island/index.ts`. Значения `EIslandType` — строки `type_1` / `type_2` / `type_3`.
162
+ - **Части типизированы через `React.HTMLProps<HTMLDivElement>`** (не `HTMLAttributes`). Сужение
163
+ типа — breaking change для потребителей.
164
+ - **`mapTypeToClassName` (`utils.ts`) — внутренняя утилита**, в barrel не экспортируется.
81
165
 
82
- | Prop | Тип | Default | Описание |
83
- |---|---|---|---|
84
- | `type` | `EIslandType` | `TYPE_1` | Визуальный тип (цвет фона + тень). |
85
- | `size` | `EComponentSize` | `MD` | Размер — влияет на padding и border-radius. |
86
- | `className`, `style`, `...HTMLDivAttributes` | — | — | Стандартные. |
166
+ ---
87
167
 
88
- ### EIslandType
168
+ ## Accessibility
89
169
 
90
- | Значение | Токены |
91
- |---|---|
92
- | `TYPE_1` | `--triplex-next-Island-Type1_Background` + `Type1_Shadow` |
93
- | `TYPE_2` | `...Type2...` |
94
- | `TYPE_3` | `...Type3...` |
170
+ Island — неинтерактивный контейнер: не выставляет роль, не управляет фокусом и не обрабатывает
171
+ клавиатуру. Всё это задаёт потребитель через spread — например, `Confirm` передаёт
172
+ `role="dialog"` и `aria-modal="true"`, `IslandAccordion` кладёт внутрь `Island.Header` собственную
173
+ `<button>` с `aria-expanded` / `aria-controls`.
95
174
 
96
- ### Размеры
175
+ Состояние `loading` тоже не объявляется автоматически: `LoaderScreen` приносит внутрь только
176
+ `role="status"` от `LoaderMiddle`. Если загрузку карточки должен озвучивать скринридер, потребитель
177
+ передаёт `aria-busy="true"` в `Island` — как и у `Button` с prop `loading`.
97
178
 
98
- | Size | Desktop (≥ sm+1) | Mobile (≤ @screen-sm-max) | Gap между слотами |
99
- |---|---|---|---|
100
- | `SM` | radius 16, padding 16 | radius 16, padding 16 | 8 |
101
- | `MD` | radius 24, padding 24 | radius 16, padding 16 | 12 |
102
- | `LG` | radius 32, padding 32 | radius 24, padding 24 | 16 |
179
+ Важно: `Island.Header` — это `<div>`, а не заголовок. Если нужен семантический заголовок карточки,
180
+ положи внутрь `Title` с нужным тегом или собственный `<h*>`. Текстовые строки компонент не
181
+ хардкодит (библиотека мультиязычная).
103
182
 
104
- На mobile `MD` уменьшается до SM-параметров; `LG` — до размеров близких к MD. Это сохранить при добавлении новых размеров.
183
+ ---
105
184
 
106
- ### Дочерние — `IIslandHeaderProps`, `IIslandBodyProps`, `IIslandFooterProps`
185
+ ## Связанные компоненты
107
186
 
108
- Все extends `React.HTMLProps<HTMLDivElement>` (не `HTMLAttributes` — заметь разницу: `HTMLProps` шире, включает DOM-специфичные проп'ы вроде `form`, `crossOrigin`). Интерфейсы пустые, просто именованные alias'ы.
187
+ ### Альтернативы (в `related`)
109
188
 
110
- `IslandBody` merge'ит `className` через `clsx` — можно передавать свой класс.
189
+ - `IslandAccordion` — раскрывающиеся элементы. Строит на Island; `IslandAccordionFooter`
190
+ оборачивает `Island.Footer` и передаёт в него свой `className`. Опирается на хрупкую деталь:
191
+ гасит отступ Island через `margin-top: 0 !important`, поэтому правка селекторов отступов ломает
192
+ его молча.
193
+ - `IslandWidget` — виджет со сворачиванием в адаптиве; использует Island как контейнер, но своими
194
+ Header / Body / Footer, а не частями Island.
111
195
 
112
- **`IslandHeader` / `IslandFooter`** — НЕ merge'ят `className` из props (баг-или-легаси): `clsx(styles.islandHeader)` без пропагации `className`. **Если нужно передать свой класс — исправляй компонент.** Не полагайся на это поведение.
196
+ ### Контракты (в `related`)
113
197
 
114
- ---
198
+ - `LoaderScreen` — экран загрузки, который Island рендерит при `loading` (всегда `type="middle"`).
199
+ Настраивается через `loaderScreenProps` (`ILoaderScreenMiddleProps`).
200
+ - `ModalWindow` — `IModalWindowBodyProps` наследует `IIslandProps` через
201
+ `Omit<IIslandProps, "loading" | "loaderScreenProps">`, поэтому `type` и `size` в
202
+ `ModalWindowBody` доступны, а состояние загрузки — нет: тело модалки скроллируется, лоадер
203
+ задаётся на `ModalWindowContent`. Своего AI.md у `ModalWindowBody` нет — он описан в
204
+ `ModalWindow-ai.md`. Он же — направление из «Не используй когда», если нужен overlay, а не
205
+ карточка в потоке.
115
206
 
116
- ## Ключевые особенности реализации
207
+ ### Другие направления из «Не используй когда» (в `related` не входят)
117
208
 
118
- ### Compound через `Object.assign`
209
+ Отводы в другой класс задач — промах такого масштаба виден из «Назначения», ссылка не нужна.
119
210
 
120
- ```tsx
121
- export const Island = Object.assign(
122
- React.forwardRef<HTMLDivElement, IIslandProps>(...),
123
- { Body: IslandBody, Header: IslandHeader, Footer: IslandFooter },
124
- );
125
- ```
211
+ - `LightBox`, `LightBoxSideOverlay` — если нужен overlay, а не карточка в потоке. У
212
+ `LightBoxSideOverlay` своего AI.md нет, смотри `LightBox`.
213
+ - `Gap`, `Row`, `Col` — если нужен только отступ или сетка без визуальной карточки.
126
214
 
127
- ### Margin между слотами — через смежный селектор
215
+ ### Части Island (своего AI.md не имеют)
128
216
 
129
- Отступы между Header/Body/Footer заданы на корне Island, а не на самих слотах. Это значит:
130
- - если пропустить Body и написать `<Header /><Footer />` — между ними всё равно сработает `margin-top`.
131
- - если вставить произвольный контент между слотами — смежный селектор не сработает, и придётся выставлять отступ вручную.
217
+ - `IslandHeader` (`components/IslandHeader.tsx`, он же `Island.Header`) — шапка карточки.
218
+ Тривиальная `<div>`-обёртка без собственных props.
219
+ - `IslandBody` (`components/IslandBody.tsx`, он же `Island.Body`) — основное содержимое.
220
+ Тривиальная `<div>`-обёртка без собственных props.
221
+ - `IslandFooter` (`components/IslandFooter.tsx`, он же `Island.Footer`) — подвал карточки.
222
+ Тривиальная `<div>`-обёртка без собственных props.
132
223
 
133
- ### Mobile resize
224
+ ### Потребители (в `related` не входят — ссылка стоит с их стороны)
134
225
 
135
- `@media (max-width: @screen-sm-max)` перекрывает padding/radius для всех размеров — карточка визуально уменьшается на мобильных. Это поведение реализует автоматическую адаптивность без дополнительных пропсов.
226
+ - `BodyPage`, `HeaderPage`, `FooterPage` — оборачивают контент страницы в Island с `TYPE_1`, если
227
+ их тип `FIRST`.
228
+ - `Confirm` — диалог подтверждения на Island `TYPE_1` с `Island.Body` внутри. Наследует интерфейс:
229
+ `IConfirmProps extends IIslandProps` (`Confirm/Confirm.tsx:11`), поэтому добавление prop в Island
230
+ меняет публичный API `Confirm` без правок в его коде.
136
231
 
137
- ### `IslandHeader` / `IslandFooter` игнорируют `className`
232
+ ---
138
233
 
139
- В отличие от `IslandBody`, они не мержат `className`. Это по факту баг/неполная реализация, но изменение может затронуть потребителей — не исправлять без согласования.
234
+ ## Stories
140
235
 
141
- ---
236
+ Основные истории: `stories/Island/Island.stories.tsx`
237
+ Файлы примеров: `stories/Island/examples/`
142
238
 
143
- ## Инварианты
239
+ | Story | Example file | Что демонстрирует |
240
+ |---|---|---|
241
+ | `Playground` | — | Интерактивный контроль `type`, `size`, `loading` и состава (Header / Body / Footer) |
242
+ | `Default` | `DefaultExample.tsx` | Минимальная карточка: Header + Body + Footer |
243
+ | `Types` | `TypesExample.tsx` | Все значения `EIslandType` рядом |
244
+ | `Sizes` | `SizesExample.tsx` | Размеры SM / MD / LG: скругление, паддинги, отступы между частями |
245
+ | `Loading` | `Loading.tsx` | `loading`: `LoaderScreen` поверх контента карточки |
144
246
 
145
- - **`EIslandType` значения `TYPE_1`/`TYPE_2`/`TYPE_3`** — публичный API. Не переименовывать.
146
- - **Compound через `Object.assign`** — `Island.Header`, `Island.Body`, `Island.Footer`. Barrel также экспортирует `IslandHeader`/`IslandBody`/`IslandFooter` напрямую.
147
- - **Margin-логика через `+`-селектор** — изменение на gap-flex сломает существующие интеграции (padding/layout рассчитаны на margin-top).
148
- - **`forwardRef`** — на всех четырёх компонентах.
149
- - **Дефолт `type=TYPE_1`, `size=MD`** — не менять.
150
- - **`HTMLProps<HTMLDivElement>`** (не `HTMLAttributes`) в интерфейсах слотов — сохранить, если потребитель опирается на расширенные атрибуты.
247
+ Файлы примеров с постфиксом `Example` — локальный legacy-паттерн папки; новые примеры называются
248
+ по имени story (`Loading.tsx`).
151
249
 
152
250
  ---
153
251
 
154
- ## Accessibility
252
+ ## История изменений
155
253
 
156
- - `<div>`-контейнеры, без ARIA-ролей. Если остров используется как диалог/секция/регион — потребитель передаёт `role` и `aria-label` через `...rest`.
157
- - `IslandHeader` — не `<header>`/`<h*>`; потребитель сам передаёт нужные семантические теги/заголовки внутрь.
158
- - Tab-навигация — через интерактивные дети.
254
+ | Дата | Изменение |
255
+ |---|---|
256
+ | 2026-08-11 | Prop состояния загрузки переименован `isLoading` → `loading` — по преобладающей в библиотеке конвенции boolean-props без префикса `is` (`loading` у `Button`, `List`, `Dropdown`, `Suggest`, `Table`). Prop ещё не выпускался, поэтому breaking change нет; `Omit` в `IModalWindowBodyProps` обновлён на `"loading"`. Поведение не изменилось. |
257
+ | 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
+ | 2026-08-04 | Создан документ. AI-рефакторинг: JSDoc на props, значениях `EIslandType` и субкомпонентах, `displayName` у `IslandHeader` / `IslandBody` / `IslandFooter`, unit-тесты на все типы и размеры, части острова и `mapTypeToClassName`. Исправлено: `className` в `IslandHeader` и `IslandFooter` больше не затирает базовый класс компонента; побочный отступ в `IslandAccordion` погашен в стилях аккордеона, вид библиотечных компонентов не изменился. Публичный API не изменён. |
159
259
 
160
260
  ---
161
261
 
162
- ## Дизайн-токены
262
+ ## Примеры использования
163
263
 
164
- ```
165
- --triplex-next-Island-Type1_Background
166
- --triplex-next-Island-Type1_Shadow
167
- --triplex-next-Island-Type2_Background
168
- --triplex-next-Island-Type2_Shadow
169
- --triplex-next-Island-Type3_Background
170
- --triplex-next-Island-Type3_Shadow
264
+ ### Default
265
+
266
+ `stories/Island/examples/DefaultExample.tsx`
267
+
268
+ ```tsx
269
+ import React from "react";
270
+ import { Island, EIslandType, EComponentSize } from "@sberbusiness/triplex-next";
271
+
272
+ export const DefaultExample = () => (
273
+ <div style={{ maxWidth: 360 }}>
274
+ <Island type={EIslandType.TYPE_1} size={EComponentSize.MD}>
275
+ <Island.Header>Island Header</Island.Header>
276
+ <Island.Body>Island Body</Island.Body>
277
+ <Island.Footer>Island Footer</Island.Footer>
278
+ </Island>
279
+ </div>
280
+ );
171
281
  ```
172
282
 
173
- Размеры (`16/24/32` px) и gap'ы (`8/12/16` px) заданы литералами.
283
+ ### Types
174
284
 
175
- ---
285
+ `stories/Island/examples/TypesExample.tsx`
176
286
 
177
- ## Связанные компоненты
287
+ ```tsx
288
+ import React from "react";
289
+ import { Island, EIslandType } from "@sberbusiness/triplex-next";
290
+
291
+ export const TypesExample = () => (
292
+ <div
293
+ style={{
294
+ display: "grid",
295
+ gap: 16,
296
+ gridTemplateColumns: "repeat(auto-fit, minmax(260px, 1fr))",
297
+ }}
298
+ >
299
+ <div>
300
+ <div style={{ marginBottom: "8px", fontSize: "16px", fontWeight: "700" }}>TYPE_1</div>
301
+ <Island type={EIslandType.TYPE_1}>
302
+ <Island.Header>Header content</Island.Header>
303
+ <Island.Body>Body content</Island.Body>
304
+ <Island.Footer>Footer content</Island.Footer>
305
+ </Island>
306
+ </div>
307
+ <div>
308
+ <div style={{ marginBottom: "8px", fontSize: "16px", fontWeight: "700" }}>TYPE_2</div>
309
+ <Island type={EIslandType.TYPE_2}>
310
+ <Island.Header>Header content</Island.Header>
311
+ <Island.Body>Body content</Island.Body>
312
+ <Island.Footer>Footer content</Island.Footer>
313
+ </Island>
314
+ </div>
315
+ <div>
316
+ <div style={{ marginBottom: "8px", fontSize: "16px", fontWeight: "700" }}>TYPE_3</div>
317
+ <Island type={EIslandType.TYPE_3}>
318
+ <Island.Header>Header content</Island.Header>
319
+ <Island.Body>Body content</Island.Body>
320
+ <Island.Footer>Footer content</Island.Footer>
321
+ </Island>
322
+ </div>
323
+ </div>
324
+ );
325
+ ```
178
326
 
179
- - `IslandAccordion` — остров с раскрытием (содержит `hoverable` chevron-иконку).
180
- - `IslandWidget` — остров-виджет с иконкой и действиями.
181
- - `Card` — другая карточная абстракция (интерактивная, с hover-состояниями).
182
- - `Page` — типовой контейнер страницы, часто содержит Island'ы.
327
+ ### Sizes
183
328
 
184
- ---
329
+ `stories/Island/examples/SizesExample.tsx`
185
330
 
186
- ## Stories
331
+ ```tsx
332
+ import React from "react";
333
+ import { Island, EIslandType, EComponentSize } from "@sberbusiness/triplex-next";
334
+
335
+ const SIZES = Object.values(EComponentSize);
336
+
337
+ export const SizesExample = () => (
338
+ <div
339
+ style={{
340
+ display: "grid",
341
+ gap: 16,
342
+ gridTemplateColumns: "repeat(auto-fit, minmax(260px, 1fr))",
343
+ }}
344
+ >
345
+ {SIZES.map((size) => (
346
+ <div key={size}>
347
+ <div style={{ marginBottom: "8px", fontSize: "16px", fontWeight: "700" }}>{size.toUpperCase()}</div>
348
+ <Island type={EIslandType.TYPE_1} size={size}>
349
+ <Island.Header>Header content</Island.Header>
350
+ <Island.Body>Body content</Island.Body>
351
+ <Island.Footer>Footer content</Island.Footer>
352
+ </Island>
353
+ </div>
354
+ ))}
355
+ </div>
356
+ );
357
+ ```
187
358
 
188
- `stories/Island/Island.stories.tsx`
189
- Примеры: `stories/Island/examples/`
359
+ ### Loading
190
360
 
191
- ---
361
+ `stories/Island/examples/Loading.tsx`
192
362
 
193
- ## История изменений
363
+ ```tsx
364
+ import React from "react";
365
+ import { Island, EIslandType, EComponentSize } from "@sberbusiness/triplex-next";
366
+
367
+ export const Loading = () => (
368
+ <div style={{ maxWidth: 360 }}>
369
+ <Island type={EIslandType.TYPE_1} size={EComponentSize.MD} loading>
370
+ <Island.Header>Island Header</Island.Header>
371
+ <Island.Body>Island Body</Island.Body>
372
+ <Island.Footer>Island Footer</Island.Footer>
373
+ </Island>
374
+ </div>
375
+ );
376
+ ```
194
377
 
195
- | Дата | Изменение |
196
- |---|---|
197
- | 2026-04-18 | Создан документ |