@sberbusiness/triplex-next-mcp-server 1.42.0-beta → 1.43.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.
@@ -0,0 +1,249 @@
1
+ ---
2
+ component: WindowResizeListener
3
+ category: WindowResizeListener
4
+ related: [MediaWidth]
5
+ tokens: []
6
+ stories: stories/WindowResizeListener/WindowResizeListener.stories.tsx
7
+ version: "1.0"
8
+ ---
9
+
10
+ # WindowResizeListener
11
+
12
+ ## Назначение
13
+
14
+ Сервисный headless-компонент. Пока смонтирован, слушает событие `resize` на
15
+ `window` и вызывает `onResize`, но не чаще, чем раз в `throttleDelay`
16
+ миллисекунд. Собственной разметки не рендерит: `children` выводятся как есть,
17
+ без обёртки; без `children` не рендерит ничего.
18
+
19
+ Используй когда: при изменении размеров окна нужно выполнить императивное
20
+ действие — пересчитать размеры/отступы по замеренному DOM, перепозиционировать
21
+ оверлей, сбросить кэш измерений.
22
+
23
+ Не используй когда:
24
+ - Нужно отрендерить **другое дерево** компонентов на другой ширине — для этого
25
+ есть `MediaWidth` / `MobileView`, они слушают `MediaQueryList`, а не поток
26
+ событий `resize`.
27
+ - Нужно булево значение «широкий/узкий экран» для props или условной разметки —
28
+ используй `useMatchMedia` (`src/components/MediaWidth/useMatchMedia.ts`) или
29
+ `useMobileView`.
30
+ - Отслеживать нужно размер конкретного элемента, а не окна — окно может не
31
+ меняться, а элемент — да (открылась панель, изменился контент). Для этого в
32
+ библиотеке используется `useResizeDetector` из `react-resize-detector`
33
+ (пример — `LightBoxContent`).
34
+ - Разница чисто визуальная (отступы, шрифт, раскладка) — это дешевле решается
35
+ медиа-запросом в `*.module.less`, без JS-обработчика на каждое событие.
36
+
37
+ ---
38
+
39
+ ## Варианты и props
40
+
41
+ ### Обязательные props
42
+
43
+ | Prop | Тип | Описание |
44
+ |---|---|---|
45
+ | `onResize` | `(event: UIEvent) => void` | Вызывается на `resize` окна. Получает нативный `UIEvent` (не React SyntheticEvent). Полезной нагрузки в событии нет — актуальные размеры читаются из `window.innerWidth` / `innerHeight` или замером DOM |
46
+
47
+ ### Опциональные props
48
+
49
+ | Prop | Тип | По умолчанию | Описание |
50
+ |---|---|---|---|
51
+ | `throttleDelay` | `number` | `100` | Минимальный интервал между вызовами `onResize`, в миллисекундах |
52
+ | `children` | `React.ReactNode` | — | Рендерится как есть. Компонент не оборачивает содержимое и никак на него не влияет — вложение нужно только для читаемости кода |
53
+
54
+ ### Особенности поведения
55
+
56
+ - Слушатель навешивается в `useEffect`, поэтому `window` не трогается во время
57
+ рендера — компонент **SSR-safe** (в отличие от семейства `MediaWidth`, которое
58
+ вызывает `window.matchMedia` на первом рендере).
59
+ - Троттлинг — `throttle` из `lodash-es` с настройками по умолчанию:
60
+ **leading + trailing**. Первое событие серии обрабатывается синхронно, все
61
+ последующие внутри окна схлопываются в один отложенный вызов в конце окна.
62
+ Одиночное событие даёт ровно один вызов; если внутри окна пришли ещё события,
63
+ в конце окна добавляется trailing-вызов.
64
+ - **Обработчик и задержка входят в зависимости эффекта.** При смене ссылки
65
+ `onResize` или значения `throttleDelay` слушатель снимается и навешивается
66
+ заново, а троттлинг начинается с чистого листа (новое leading-окно). Если
67
+ передать инлайновую стрелку, переподписка будет происходить на **каждый
68
+ рендер**, и троттлинг фактически перестанет ограничивать частоту вызовов.
69
+ Оборачивай обработчик в `useCallback` (или храни его вне компонента).
70
+ - При размонтировании слушатель снимается, а отложенный trailing-вызов
71
+ отменяется через `cancel()` — `removeEventListener` сам по себе его
72
+ не отменяет, и колбэк сработал бы уже после размонтирования.
73
+ - Компонент не вызывает `preventDefault` / `stopPropagation` (событие `resize`
74
+ не отменяемо) и не подмешивает в `onResize` собственные данные о размерах.
75
+ - Несколько смонтированных `WindowResizeListener` работают независимо, каждый со
76
+ своим окном троттлинга.
77
+
78
+ ---
79
+
80
+ ## Дизайн-токены
81
+
82
+ Собственных стилей и CSS-переменных нет — компонент не рендерит разметку.
83
+
84
+ ---
85
+
86
+ ## Инварианты
87
+
88
+ - **Без `forwardRef` — осознанное исключение** из общего правила библиотеки:
89
+ компонент не рендерит собственный host-элемент, форвардить `ref` некуда. Не
90
+ добавлять и не убирать без отдельного решения.
91
+ - **Имена и типы props `children`, `onResize`, `throttleDelay`** и значение по
92
+ умолчанию `throttleDelay = 100` — публичное API, не менять. Интерфейс
93
+ `IWindowResizeListenerProps` экспортируется из barrel — переименование будет
94
+ breaking change.
95
+ - **`return children ?? null`** — falsy-`children` (`0`, `""`) осознанно
96
+ рендерятся; `??`, а не `||` (у соседнего `KeyDownListener` обратная
97
+ договорённость — там `||`). Возврат `null` вместо `undefined` нужен для React
98
+ 17: там компонент, вернувший `undefined`, роняет рендер.
99
+ - **Зависимости эффекта `[onResize, throttleDelay]`** — не «оптимизировать»
100
+ переносом обработчика в `ref`: сейчас смена обработчика сбрасывает окно
101
+ троттлинга, и это наблюдаемое поведение у потребителей.
102
+ - **`throttledResize.cancel()` в cleanup** — не удалять: без него отложенный вызов
103
+ срабатывает после размонтирования (тест `cancels the pending trailing call on
104
+ unmount`).
105
+ - Реализация остаётся React 17-совместимой (без `useId`,
106
+ `useSyncExternalStore` и прочих React 18-only API): код синхронизируется
107
+ в `release-0`.
108
+
109
+ ---
110
+
111
+ ## Accessibility
112
+
113
+ - Собственной ARIA-семантики нет — компонент прозрачен для accessibility-дерева
114
+ и не рендерит фокусируемых элементов.
115
+ - `resize` окна возникает и при зуме страницы, и при появлении экранной
116
+ клавиатуры на мобильных. Обработчик не должен перебрасывать фокус или
117
+ сбрасывать состояние формы — для пользователя, увеличившего масштаб, это
118
+ выглядит как потеря контекста.
119
+
120
+ ---
121
+
122
+ ## Связанные компоненты
123
+
124
+ - `MediaWidth` (`src/components/MediaWidth/`) — альтернатива для декларативного
125
+ случая: рендерит одну из двух веток по медиа-запросу, а не даёт колбэк на поток
126
+ событий. Там же `useMatchMedia` (булево значение для условной разметки) и
127
+ `MobileView` (частный случай мобильной границы). Правило выбора: нужно
128
+ **что-то посчитать/сделать** на ресайз — `WindowResizeListener`; нужно
129
+ **что-то показать** на определённой ширине — `MediaWidth`.
130
+ - `KeyDownListener` (`src/components/KeyDownListener/`) — headless-слушатель того
131
+ же покроя, но для `keydown` на `window`. Похожий контракт по `children` (рендер
132
+ как есть, без обёртки); отличие — обработка falsy-`children`, см. «Инварианты».
133
+
134
+ ### Потребители внутри библиотеки
135
+
136
+ - `LightBoxContent` (`src/components/LightBox/LightBoxContent.tsx`) — пересчёт
137
+ верхнего отступа контента при изменении размеров окна. Обработчик
138
+ (`updateStyleWithTimeout`) обёрнут в `useCallback`, поэтому переподписки на
139
+ каждый рендер не происходит. Слушатель размеров самого контента там сделан
140
+ отдельно, через `useResizeDetector`.
141
+
142
+ В unit-тестах потребителей компонент удобно мокать целиком — как в
143
+ `src/components/LightBox/__tests__/LightBoxContent.test.tsx`.
144
+
145
+ ---
146
+
147
+ ## Stories
148
+
149
+ Основные истории: `stories/WindowResizeListener/WindowResizeListener.stories.tsx`
150
+ Файлы примеров: `stories/WindowResizeListener/examples/`
151
+
152
+ | Story | Example file | Что демонстрирует |
153
+ |---|---|---|
154
+ | `Playground` | `Playground.tsx` | Интерактивный подбор `throttleDelay`, счётчик срабатываний `onResize` и текущая ширина окна |
155
+ | `Default` | `Default.tsx` | Минимальный пример: обработчик в `useCallback` читает `window.innerWidth` / `innerHeight` |
156
+ | `ThrottleDelay` | `ThrottleDelay.tsx` | Два слушателя с разной задержкой (100 мс и 1000 мс) и их счётчики вызовов |
157
+
158
+ Набор целиком исключён из скриншот-тестов (`testRunner: { skip: true }` в `meta`):
159
+ собственной разметки компонент не рендерит, на скриншот попадала бы только
160
+ обвязка примеров. Baseline-файлов в `__screenshots__/` для этого набора быть не
161
+ должно. Поведение слушателя покрыто unit-тестами.
162
+
163
+ ---
164
+
165
+ ## История изменений
166
+
167
+ | Дата | Изменение |
168
+ |---|---|
169
+ | 2026-08-18 | Создан документ. AI-рефакторинг (TRI-104): JSDoc на props и компоненте, интерфейс `IWindowResizeListenerProps` стал экспортируемым (аддитивно), `return children ?? null` вместо `return children` (React 17-safe), убрано лишнее опциональное обращение `cancel?.()`, добавлены unit-тесты (10 кейсов: рендер `children`, троттлинг с дефолтной и заданной задержкой, отписка и отмена trailing-вызова при размонтировании, переподписка при смене `onResize` / `throttleDelay`) и набор stories по modern pattern. Публичный API не изменён (имена и типы props, дефолт `throttleDelay = 100`, barrel-экспорты; `forwardRef` по-прежнему осознанно отсутствует). |
170
+
171
+ ---
172
+
173
+ ## Примеры использования
174
+
175
+ ### Default
176
+
177
+ `stories/WindowResizeListener/examples/Default.tsx`
178
+
179
+ ```tsx
180
+ import React, { useCallback, useState } from "react";
181
+ import { WindowResizeListener } from "@sberbusiness/triplex-next";
182
+
183
+ const getWindowSize = () =>
184
+ typeof window === "undefined" ? { width: 0, height: 0 } : { width: window.innerWidth, height: window.innerHeight };
185
+
186
+ export const Default = () => {
187
+ // При рендере на сервере window недоступен — стартовое значение берётся только в браузере.
188
+ const [windowSize, setWindowSize] = useState(getWindowSize);
189
+
190
+ // Стабильная ссылка на обработчик: при её смене слушатель переподписывается заново.
191
+ const handleResize = useCallback(() => {
192
+ setWindowSize(getWindowSize());
193
+ }, []);
194
+
195
+ return (
196
+ <WindowResizeListener onResize={handleResize}>
197
+ <div style={{ display: "flex", flexDirection: "column", gap: "16px", maxWidth: "400px" }}>
198
+ <div>Измените размер окна браузера, чтобы обновить значения.</div>
199
+ <div style={{ border: "1px dashed rgb(125, 131, 138)", borderRadius: "4px", padding: "16px" }}>
200
+ Размер окна: {windowSize.width} × {windowSize.height}
201
+ </div>
202
+ </div>
203
+ </WindowResizeListener>
204
+ );
205
+ };
206
+ ```
207
+
208
+ ### ThrottleDelay
209
+
210
+ `stories/WindowResizeListener/examples/ThrottleDelay.tsx`
211
+
212
+ ```tsx
213
+ import React, { useCallback, useState } from "react";
214
+ import { WindowResizeListener } from "@sberbusiness/triplex-next";
215
+
216
+ interface IResizeCounterProps {
217
+ throttleDelay: number;
218
+ }
219
+
220
+ const ResizeCounter = ({ throttleDelay }: IResizeCounterProps) => {
221
+ const [resizeCount, setResizeCount] = useState(0);
222
+
223
+ const handleResize = useCallback(() => {
224
+ setResizeCount((prevCount) => prevCount + 1);
225
+ }, []);
226
+
227
+ return (
228
+ <WindowResizeListener onResize={handleResize} throttleDelay={throttleDelay}>
229
+ <div>
230
+ <div style={{ marginBottom: "8px", fontSize: "16px", fontWeight: "700" }}>
231
+ throttleDelay: {throttleDelay}ms
232
+ </div>
233
+ <div style={{ border: "1px dashed rgb(125, 131, 138)", borderRadius: "4px", padding: "16px" }}>
234
+ Срабатываний onResize: {resizeCount}
235
+ </div>
236
+ </div>
237
+ </WindowResizeListener>
238
+ );
239
+ };
240
+
241
+ export const ThrottleDelay = () => (
242
+ <div style={{ display: "flex", flexDirection: "column", gap: "16px", maxWidth: "400px" }}>
243
+ <div>Измените размер окна браузера — чем больше задержка, тем реже вызывается обработчик.</div>
244
+ <ResizeCounter throttleDelay={100} />
245
+ <ResizeCounter throttleDelay={1000} />
246
+ </div>
247
+ );
248
+ ```
249
+
@@ -203,6 +203,32 @@ fi
203
203
  - Действия в Linear выполняются от сессии разработчика — бот на них
204
204
  не распространяется.
205
205
 
206
+ ### Облачные сессии: подмена токена прокси
207
+
208
+ В облачных сессиях (routines на claude.ai) запросы к `api.github.com`
209
+ идут **не** с `TRIPLEX_BOT_GH_TOKEN`: egress-прокси подменяет авторизацию
210
+ на токен GitHub App `claude` (user-to-server, identity — аккаунт
211
+ разработчика). Паттерн выше при этом не ломается — просто действующие
212
+ права определяет прокси, а не PAT. Как распознать:
213
+
214
+ - `gh api user` возвращает аккаунт разработчика, хотя в env лежит токен
215
+ бота;
216
+ - текст 403 — «Resource not accessible by **integration**» или «not
217
+ permitted for this session type / through this proxy» (у fine-grained
218
+ PAT было бы «…by personal access token»).
219
+
220
+ Что прокси **разрешает** из облака: push в ветки, создание и мерж PR,
221
+ комментарии, чтение Actions, диспатч нерелизных workflow (например,
222
+ `visual-update.yml` — подтверждено прогонами). Что **запрещает** (зонд
223
+ TRI-117, 2026-08-14): создание релизов, диспатч `release.yml`,
224
+ `repository_dispatch`, создание, push и удаление тегов, удаление веток —
225
+ блокируется публикация релизов любым маршрутом. Поэтому публикация релизов из
226
+ облака невозможна — облачный прогон готовит релиз и передаёт публикацию
227
+ человеку (см. `.agents/skills/release-auto/SKILL.md`). Диагностический
228
+ зонд права на диспатч: POST на
229
+ `actions/workflows/release.yml/dispatches` с несуществующим `ref` —
230
+ `422 No ref found` означает «право есть», `403` — «нет».
231
+
206
232
  ---
207
233
 
208
234
  ## PR-воркфлоу
@@ -180,7 +180,7 @@ Playground показывает только те props, которые реал
180
180
 
181
181
  ### Когда не создавать Playground
182
182
 
183
- Если у компонента нет настраиваемых props (только `children` и стандартные HTML-атрибуты), Playground не создаётся — нечего класть в Controls. Типичный случай: контейнер-обёртка вроде `ListItem`, `ListItemControls`, `ChipGroup`.
183
+ Если у компонента нет настраиваемых props (только `children` и стандартные HTML-атрибуты), Playground не создаётся — нечего класть в Controls. Типичный случай: контейнер-обёртка вроде `ListItem`, `ListItemControls`.
184
184
 
185
185
  В этом случае:
186
186
 
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
- "triplexVersion": "1.42.0",
4
- "generatedAt": "2026-08-14T12:59:51.290Z",
3
+ "triplexVersion": "1.43.0",
4
+ "generatedAt": "2026-08-21T12:41:11.790Z",
5
5
  "components": [
6
6
  {
7
7
  "name": "AbstractTree",
@@ -138,7 +138,7 @@
138
138
  },
139
139
  {
140
140
  "name": "CheckboxTreeExtended",
141
- "path": "src/components/CheckboxTreeExtended/CheckboxTreeExtended-AI.md",
141
+ "path": "src/components/CheckboxTreeExtended/CheckboxTreeExtended-ai.md",
142
142
  "file": "components/CheckboxTreeExtended.md",
143
143
  "ai_ready": true
144
144
  },
@@ -162,7 +162,7 @@
162
162
  },
163
163
  {
164
164
  "name": "ChipGroup",
165
- "path": "src/components/ChipGroup/ChipGroup-AI.md",
165
+ "path": "src/components/ChipGroup/ChipGroup-ai.md",
166
166
  "file": "components/ChipGroup.md",
167
167
  "ai_ready": true
168
168
  },
@@ -608,7 +608,7 @@
608
608
  },
609
609
  {
610
610
  "name": "SliderExtended",
611
- "path": "src/components/SliderExtended/SliderExtended-AI.md",
611
+ "path": "src/components/SliderExtended/SliderExtended-ai.md",
612
612
  "file": "components/SliderExtended.md",
613
613
  "ai_ready": true
614
614
  },
@@ -686,7 +686,7 @@
686
686
  },
687
687
  {
688
688
  "name": "TabsExtended",
689
- "path": "src/components/TabsExtended/TabsExtended-AI.md",
689
+ "path": "src/components/TabsExtended/TabsExtended-ai.md",
690
690
  "file": "components/TabsExtended.md",
691
691
  "ai_ready": true
692
692
  },
@@ -777,10 +777,15 @@
777
777
  },
778
778
  {
779
779
  "name": "UnorderedList",
780
- "path": "src/components/UnorderedList",
781
- "file": null,
782
- "ai_ready": false,
783
- "storiesPath": "stories/UnorderedList.stories.tsx"
780
+ "path": "src/components/UnorderedList/UnorderedList-ai.md",
781
+ "file": "components/UnorderedList.md",
782
+ "ai_ready": true
783
+ },
784
+ {
785
+ "name": "UnorderedListExtended",
786
+ "path": "src/components/UnorderedListExtended/UnorderedListExtended-ai.md",
787
+ "file": "components/UnorderedListExtended.md",
788
+ "ai_ready": true
784
789
  },
785
790
  {
786
791
  "name": "UploadZone",
@@ -791,10 +796,9 @@
791
796
  },
792
797
  {
793
798
  "name": "WindowResizeListener",
794
- "path": "src/components/WindowResizeListener",
795
- "file": null,
796
- "ai_ready": false,
797
- "storiesPath": null
799
+ "path": "src/components/WindowResizeListener/WindowResizeListener-ai.md",
800
+ "file": "components/WindowResizeListener.md",
801
+ "ai_ready": true
798
802
  },
799
803
  {
800
804
  "name": "ListItemTable",
@@ -1052,6 +1056,11 @@
1052
1056
  "file": "release-notes/1.43.0.mdx",
1053
1057
  "path": "stories/release-notes/v1/1.43.0.mdx"
1054
1058
  },
1059
+ {
1060
+ "version": "1.44.0",
1061
+ "file": "release-notes/1.44.0.mdx",
1062
+ "path": "stories/release-notes/v1/1.44.0.mdx"
1063
+ },
1055
1064
  {
1056
1065
  "version": "1.5.0",
1057
1066
  "file": "release-notes/1.5.0.mdx",
@@ -4,4 +4,91 @@ import { Meta, Title, Heading } from "@storybook/addon-docs/blocks";
4
4
 
5
5
  <Title>v1.43.0</Title>
6
6
 
7
+ <Heading>Новые компоненты</Heading>
8
+
9
+ **UnorderedListExtended**
10
+
11
+ - Расширенный маркированный список с типизированными элементами, пользовательскими маркерами, составным API и поддержкой `ref`.
12
+
13
+ <Heading>Ломающие изменения</Heading>
14
+
15
+ **Notification**
16
+
17
+ - Body.List: Удалено свойство `values`, теперь элементы списка необходимо передавать через свойство `items`.
18
+
19
+ **UnorderedList**
20
+
21
+ - Компонент полностью переведен на data-driven подход и больше не принимает `children`, теперь элементы списка необходимо передавать через свойство `items`.
22
+
7
23
  <Heading>Изменения</Heading>
24
+
25
+ **Button**
26
+
27
+ - Исправлен баг, когда короткий текст в кнопке не центрировался.
28
+ - Убраны горизонтальные отступы у `EButtonTheme.LINK`.
29
+
30
+ **Checkbox**
31
+
32
+ - Проведён AI-рефакторинг.
33
+ - Исправлен баг, когда на тач-устройствах чекбокс залипал в состоянии ховера после тапа.
34
+
35
+ **CheckboxTreeExtended**
36
+
37
+ - Добавлено: экспортируется тип `ICheckboxTreeExtendedNodeProps` — теперь свойства `CheckboxTreeExtended.Node` можно использовать для типизации собственной обёртки узла.
38
+ - Исправлено: `className`, переданный в `CheckboxTreeExtended.Node`, больше не затирает собственный класс узла. Раньше вместе с ним пропадали отступы вложенной ветки — теперь классы объединяются.
39
+ - Проведён AI-рефакторинг, добавлен `displayName` у `CheckboxTreeExtended.Node`. Из разметки заголовка узла пропал глобальный класс `opened` — внешний вид не изменился.
40
+
41
+ **CheckboxXGroup**
42
+
43
+ - Проведён AI-рефакторинг.
44
+
45
+ **CheckboxYGroup**
46
+
47
+ - Проведён AI-рефакторинг.
48
+
49
+ **Chip**
50
+
51
+ - Изменен цвет токена `Chip.Background_Disabled` в темной теме.
52
+
53
+ **ChipGroup**
54
+
55
+ - Проведён AI-рефакторинг.
56
+
57
+ **LightBox**
58
+
59
+ - Исправлен баг, когда в состоянии `loading` `LightBox.TopOverlay` перекрывался `LoaderScreen`.
60
+
61
+ **SliderExtended**
62
+
63
+ - Добавлено: `SliderExtended` и его части (`Dot`, `Mark`, `Marks`, `Rail`, `Track`, `Tooltip`) пробрасывают `ref` на свой корневой элемент — тот же, что получает `className` и `...rest` (у `Tooltip` — обёртка подсказки).
64
+ - Исправлено: `className`, переданный в `SliderExtended` и `SliderExtended.Tooltip`, больше не затирает собственные классы элемента — раньше вместе с пользовательским классом пропадали размер и оформление. Затрагивает также `className` у `Slider` и `SliderRange`: он уходит на корневой элемент `SliderExtended`.
65
+ - Исправлено: `style`, переданный в `SliderExtended.Dot`, `SliderExtended.Track` и `SliderExtended.Mark`, больше не отбрасывается. Внутреннее позиционирование (`left`, `right`) по-прежнему приоритетно.
66
+ - Исправлено: `onClick`, переданный в `SliderExtended.Rail`, больше не отменяет перемещение ползунка по клику на полосу — вызываются оба обработчика.
67
+ - Изменено: слайдер отрисовывается сразу на первом рендере. Раньше шаги вычислялись в layout-эффекте, и первый кадр был пустым.
68
+ - Исправлено: если во время перетаскивания курсор уходил далеко за пределы полосы, ползунок прыгал в её противоположный конец. Теперь он остаётся на крайнем шаге.
69
+ - Исправлено: клик по полосе или по метке, когда ни один `SliderExtended.Dot` не отрисован, больше не выбрасывает исключение.
70
+ - Исправлено: при `min`, равном `max`, позиция ползунка больше не вычисляется как `NaN`.
71
+ - Добавлено: `displayName` у `SliderExtended.Tooltip`.
72
+ - Проведён AI-рефакторинг.
73
+
74
+ **StatusTracker**
75
+
76
+ - Минимальная высота изменена для десктоп экранов и добавлена для мобильных экранов.
77
+
78
+ **TabsExtended**
79
+
80
+ - Добавлено: `TabsExtended`, `TabsExtended.Content`, `TabsExtended.Content.TabsWrapper` и `TabsExtended.Content.DropdownWrapper` пробрасывают `ref` — раньше они были объявлены как `React.FC`. Ref указывает на тот же элемент, что получает `className` и `...rest`: у `TabsWrapper` это отображаемый контейнер табов, у `DropdownWrapper` — контейнер выпадающего списка.
81
+ - Исправлено: в `dropdownItemsIds` больше не попадают `null`. Дочерний элемент `TabsWrapper` без атрибута таба — например, `TabButton`, положенный напрямую, без `Tab`, — при нехватке ширины уезжал в render-prop `DropdownWrapper` как `null` и в одиночку раскрывал пустой Dropdown.
82
+ - Проведён AI-рефакторинг, добавлен `displayName`.
83
+
84
+ **UnorderedList**
85
+
86
+ - Элементы списка теперь поддерживают свойства `TTextProps` для гибкого управления стилями и параметрами текста.
87
+ - Для элементов списка добавлено свойство `marker` для кастомного отображения иконок и произвольных маркеров.
88
+ - Исправлено: маркер элемента центрируется по первой строке текста при любом размере типографики. Раньше вертикальные отступы маркера были рассчитаны на строку 20px (`B2`/`B3`), из-за чего на `B1` маркер смещался на 2px вверх, а на `B4` — на 2px вниз, и элемент `B4` занимал лишние 4px по высоте. Правка сделана в `UnorderedListExtended` и затрагивает оба списка.
89
+ - Проведён AI-рефакторинг. Публичный API и разметка не изменились.
90
+
91
+ **WindowResizeListener**
92
+
93
+ - Добавлено: интерфейс `IWindowResizeListenerProps` теперь экспортируется.
94
+ - Проведён AI-рефакторинг.
@@ -0,0 +1,7 @@
1
+ import { Meta, Title, Heading } from "@storybook/addon-docs/blocks";
2
+
3
+ <Meta title="release-notes/v1/1.44.0" />
4
+
5
+ <Title>v1.44.0</Title>
6
+
7
+ <Heading>Изменения</Heading>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sberbusiness/triplex-next-mcp-server",
3
- "version": "1.42.0-beta",
3
+ "version": "1.43.0-beta",
4
4
  "description": "MCP-сервер для дизайн-системы Triplex. Предоставляет AI-агентам документацию компонентов, дизайн-токены и примеры использования.",
5
5
  "author": "СберБизнес",
6
6
  "license": "MIT",