@sberbusiness/triplex-next-mcp-server 1.41.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.
- package/bundle/components/AlertProcess.md +460 -0
- package/bundle/components/Amount.md +145 -169
- package/bundle/components/Badge.md +155 -219
- package/bundle/components/Body.md +108 -116
- package/bundle/components/Button.md +1 -0
- package/bundle/components/CarouselExtended.md +355 -194
- package/bundle/components/Checkbox.md +7 -1
- package/bundle/components/CheckboxTreeExtended.md +149 -248
- package/bundle/components/CheckboxXGroup.md +2 -0
- package/bundle/components/CheckboxYGroup.md +7 -2
- package/bundle/components/ChipGroup.md +195 -126
- package/bundle/components/ComposedKeyDownListener.md +323 -0
- package/bundle/components/FooterPage.md +2 -1
- package/bundle/components/HeaderPage.md +2 -1
- package/bundle/components/Island.md +100 -12
- package/bundle/components/KeyDownListener.md +11 -72
- package/bundle/components/LightBox.md +6 -0
- package/bundle/components/LoaderSmall.md +230 -0
- package/bundle/components/MaskedField.md +481 -0
- package/bundle/components/MediaWidth.md +252 -108
- package/bundle/components/MobileView.md +192 -68
- package/bundle/components/ModalWindow.md +3 -1
- package/bundle/components/Notification.md +21 -3
- package/bundle/components/Page.md +3 -1
- package/bundle/components/Pagination.md +20 -0
- package/bundle/components/SelectExtendedField.md +691 -236
- package/bundle/components/SliderExtended.md +358 -222
- package/bundle/components/TabsExtended.md +380 -194
- package/bundle/components/UnorderedList.md +254 -0
- package/bundle/components/UnorderedListExtended.md +255 -0
- package/bundle/components/WindowResizeListener.md +249 -0
- package/bundle/guides/commits.md +66 -3
- package/bundle/guides/context.md +26 -0
- package/bundle/guides/stories.md +3 -1
- package/bundle/guides/template.md +1 -1
- package/bundle/manifest.json +64 -21
- package/bundle/release-notes/1.41.1.mdx +18 -0
- package/bundle/release-notes/1.42.0.mdx +81 -0
- package/bundle/release-notes/1.43.0.mdx +94 -0
- package/bundle/release-notes/1.44.0.mdx +7 -0
- package/package.json +1 -1
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
---
|
|
2
2
|
component: MediaWidth
|
|
3
|
-
category:
|
|
4
|
-
|
|
5
|
-
figma-file: ""
|
|
6
|
-
related: [MobileView, IslandWidget]
|
|
3
|
+
category: MediaWidth
|
|
4
|
+
related: [MediaMinWidth, MediaMaxWidth, MediaBetweenWidth, useMatchMedia, MobileView, WindowResizeListener]
|
|
7
5
|
tokens: []
|
|
8
|
-
stories:
|
|
6
|
+
stories: stories/MediaWidth/MediaWidth.stories.tsx
|
|
9
7
|
version: "1.0"
|
|
10
8
|
---
|
|
11
9
|
|
|
@@ -13,157 +11,303 @@ version: "1.0"
|
|
|
13
11
|
|
|
14
12
|
## Назначение
|
|
15
13
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
14
|
+
Сервисный headless-компонент адаптивности и точка входа в семейство `MediaWidth`.
|
|
15
|
+
Рендерит `children`, когда ширина окна браузера попадает в диапазон, заданный
|
|
16
|
+
`minWidth` и/или `maxWidth`, и `fallback` — во всех остальных случаях.
|
|
17
|
+
Собственной разметки не добавляет: в DOM попадает ровно тот элемент, который
|
|
18
|
+
выбран по медиа-запросу.
|
|
19
|
+
|
|
20
|
+
Сам подписку на медиа-запрос не выполняет — по набору переданных props делегирует
|
|
21
|
+
рендер в `MediaBetweenWidth`, `MediaMinWidth` или `MediaMaxWidth`, а те уже
|
|
22
|
+
используют `useMatchMedia`.
|
|
23
|
+
|
|
24
|
+
Используй когда: на определённой ширине окна нужно отрендерить **другое дерево**
|
|
25
|
+
компонентов, а не просто другие стили — мобильный вариант дропдауна вместо
|
|
26
|
+
десктопного, список вместо таблицы, компактная панель вместо развёрнутой.
|
|
27
|
+
|
|
28
|
+
Не используй когда:
|
|
29
|
+
- Разница между ширинами чисто визуальная (отступы, шрифт, раскладка) — это
|
|
30
|
+
дешевле и надёжнее решается медиа-запросом в `*.module.less`, без
|
|
31
|
+
перемонтирования поддерева.
|
|
32
|
+
- Граница — мобильная (`<768px`): для этого есть `MobileView`, частный случай с
|
|
33
|
+
`maxWidth={EScreenWidth.SM_MAX}`.
|
|
34
|
+
- Нужно булево значение для props или условной разметки вокруг, а не выбор между
|
|
35
|
+
двумя готовыми элементами — используй хук `useMatchMedia` (или `useMobileView`
|
|
36
|
+
для мобильной границы).
|
|
39
37
|
|
|
40
38
|
---
|
|
41
39
|
|
|
42
40
|
## Варианты и props
|
|
43
41
|
|
|
44
|
-
###
|
|
42
|
+
### Обязательные props
|
|
45
43
|
|
|
46
|
-
| Prop | Тип |
|
|
47
|
-
|
|
48
|
-
| `children` | `ReactElement \| null` |
|
|
49
|
-
| `fallback` | `ReactElement \| null` |
|
|
50
|
-
| `minWidth` | `EScreenWidth` | Нет | Нижняя граница. |
|
|
51
|
-
| `maxWidth` | `EScreenWidth` | Нет | Верхняя граница. |
|
|
44
|
+
| Prop | Тип | Описание |
|
|
45
|
+
|---|---|---|
|
|
46
|
+
| `children` | `React.ReactElement \| null` | Элемент для ширины внутри диапазона. `null` — внутри диапазона не рендерится ничего |
|
|
47
|
+
| `fallback` | `React.ReactElement \| null` | Элемент для ширины вне диапазона. Обязателен: prop без значения по умолчанию, для «ничего» передаётся явный `null` |
|
|
52
48
|
|
|
53
|
-
|
|
54
|
-
- `minWidth && maxWidth` → `MediaBetweenWidth`
|
|
55
|
-
- `minWidth` → `MediaMinWidth`
|
|
56
|
-
- `maxWidth` → `MediaMaxWidth`
|
|
57
|
-
- Ни один — возвращает `fallback`.
|
|
49
|
+
### Опциональные props
|
|
58
50
|
|
|
59
|
-
|
|
51
|
+
| Prop | Тип | По умолчанию | Описание |
|
|
52
|
+
|---|---|---|---|
|
|
53
|
+
| `minWidth` | `EScreenWidth` | — | Нижняя граница диапазона, включительно |
|
|
54
|
+
| `maxWidth` | `EScreenWidth` | — | Верхняя граница диапазона, включительно |
|
|
55
|
+
|
|
56
|
+
### Как комбинация props выбирает реализацию
|
|
57
|
+
|
|
58
|
+
| Переданы | Делегирует в | Медиа-запрос |
|
|
59
|
+
|---|---|---|
|
|
60
|
+
| `minWidth` и `maxWidth` | `MediaBetweenWidth` | `(max-width: {maxWidth}) and (min-width: {minWidth})` |
|
|
61
|
+
| только `minWidth` | `MediaMinWidth` | `(min-width: {minWidth})` |
|
|
62
|
+
| только `maxWidth` | `MediaMaxWidth` | `(max-width: {maxWidth})` |
|
|
63
|
+
| ничего | — | запрос не строится, `window.matchMedia` не вызывается |
|
|
64
|
+
|
|
65
|
+
### Особенности поведения
|
|
66
|
+
|
|
67
|
+
- **Без `minWidth` и `maxWidth` всегда рендерится `fallback`, а `children` — никогда.**
|
|
68
|
+
Это штатное поведение, а не деградация: ветка «нет ограничений» трактуется как
|
|
69
|
+
«условие не выполнено». Story `Fallback` фиксирует его специально. Если ширины
|
|
70
|
+
приходят из props потребителя и могут быть `undefined` — учитывай, что
|
|
71
|
+
«ограничений нет» здесь означает «показать `fallback`».
|
|
72
|
+
- **Границы включительные.** Значения `EScreenWidth` подобраны парами
|
|
73
|
+
(`XS_MAX = 575px` / `SM_MIN = 576px`, `SM_MAX = 767px` / `MD_MIN = 768px` и
|
|
74
|
+
т.д.), поэтому в `minWidth` передаётся `*_MIN`, в `maxWidth` — `*_MAX`. Так
|
|
75
|
+
соседние диапазоны стыкуются без перекрытия и без «дыр» в один пиксель.
|
|
76
|
+
- **Согласованность `minWidth` и `maxWidth` не проверяется.** Если `minWidth`
|
|
77
|
+
больше `maxWidth`, запрос просто никогда не сматчится и всегда будет рендериться
|
|
78
|
+
`fallback` — ни предупреждения, ни ошибки не будет.
|
|
79
|
+
- **Ветки взаимоисключающие.** При пересечении границы одна ветка размонтируется,
|
|
80
|
+
вторая монтируется: локальный state, фокус, значения неконтролируемых полей и
|
|
81
|
+
текущие анимации внутри поддерева теряются. Состояние, которое должно
|
|
82
|
+
переживать смену ширины, храни выше `MediaWidth` (или передавай его как props
|
|
83
|
+
в обе ветки).
|
|
84
|
+
- Значение медиа-запроса читается синхронно на первом рендере (`useMatchMedia`
|
|
85
|
+
вызывает `window.matchMedia` в инициализаторе `useState`), поэтому «мигания»
|
|
86
|
+
неправильной ветки на первом кадре нет.
|
|
87
|
+
- Пересчёт при ресайзе идёт по событию `change` у `MediaQueryList`, а не по
|
|
88
|
+
`resize` окна — слушатель снимается при размонтировании и переподписывается при
|
|
89
|
+
смене строки запроса.
|
|
90
|
+
- **Компонент не SSR-safe:** `window.matchMedia` вызывается на первом рендере.
|
|
91
|
+
Это поведение унаследовано от `useMatchMedia` и общее для всего семейства.
|
|
60
92
|
|
|
61
|
-
|
|
93
|
+
---
|
|
62
94
|
|
|
63
|
-
|
|
95
|
+
## Дизайн-токены
|
|
64
96
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
| `initial` | Начальное значение до первого рендера — критично для SSR/первого кадра. |
|
|
97
|
+
Собственных стилей и CSS-переменных нет — компонент не рендерит разметку.
|
|
98
|
+
Границы диапазонов задаются enum `EScreenWidth` (`src/helpers/breakpoints.ts`),
|
|
99
|
+
согласованным с LESS-переменными брейкпоинтов.
|
|
69
100
|
|
|
70
|
-
|
|
101
|
+
---
|
|
71
102
|
|
|
72
|
-
|
|
103
|
+
## Инварианты
|
|
73
104
|
|
|
74
|
-
|
|
105
|
+
- **Без `forwardRef` — осознанное исключение** из общего правила библиотеки:
|
|
106
|
+
компонент не рендерит собственный host-элемент, форвардить `ref` некуда.
|
|
107
|
+
Не добавлять и не убирать без отдельного решения — это публичный контракт.
|
|
108
|
+
- **Интерфейс props называется `IMediaProps`, а не `IMediaWidthProps`.**
|
|
109
|
+
Рассинхрон с именем компонента исторический, интерфейс экспортируется из
|
|
110
|
+
barrel — переименование будет breaking change. Не «чинить» походя: только
|
|
111
|
+
отдельным решением с записью в release notes.
|
|
112
|
+
- **Имена и типы props `children`, `minWidth`, `maxWidth`, `fallback`** —
|
|
113
|
+
публичное API, не менять. `fallback` остаётся обязательным: сделать его
|
|
114
|
+
опциональным можно только осознанно, это меняет контракт у потребителей.
|
|
115
|
+
- **Значения `EScreenWidth`** — публичное API и общая сетка дизайн-системы. Не
|
|
116
|
+
хардкодить пиксели в props и не заводить локальные брейкпоинты.
|
|
117
|
+
- **Делегирование в `MediaBetweenWidth` / `MediaMinWidth` / `MediaMaxWidth`** —
|
|
118
|
+
не инлайнить `useMatchMedia` в `MediaWidth.tsx`. Строки медиа-запросов живут
|
|
119
|
+
в трёх реализациях, и это единственное место, где они собираются.
|
|
120
|
+
- **Порядок веток в `if`/`else` значим:** проверка «оба props» идёт первой,
|
|
121
|
+
иначе комбинация `minWidth + maxWidth` схлопнулась бы до одной границы.
|
|
122
|
+
- **Barrel `src/components/MediaWidth/index.ts`** экспортирует все четыре
|
|
123
|
+
компонента и `useMatchMedia` — состав экспортов не сокращать.
|
|
124
|
+
- Реализация остаётся React 17-совместимой (без `useId`,
|
|
125
|
+
`useSyncExternalStore` и прочих React 18-only API): код синхронизируется
|
|
126
|
+
в `release-0`.
|
|
127
|
+
- **Fallback на устаревшие `addListener` / `removeListener`** в `useMatchMedia` —
|
|
128
|
+
это поддержка старых браузеров, где `MediaQueryList` не наследует `EventTarget`
|
|
129
|
+
и не имеет `addEventListener` (Safari < 14). К React 17 и синхронизации
|
|
130
|
+
в `release-0` он отношения не имеет: удалять его вместе с React 17-совместимостью
|
|
131
|
+
нельзя — это наблюдаемая регрессия у потребителей.
|
|
75
132
|
|
|
76
133
|
---
|
|
77
134
|
|
|
78
|
-
##
|
|
135
|
+
## Accessibility
|
|
79
136
|
|
|
80
|
-
|
|
137
|
+
- Собственной ARIA-семантики нет — компонент прозрачен для accessibility-дерева.
|
|
138
|
+
- Невыбранная ветка **не рендерится в DOM**, а не скрывается визуально: скринридер
|
|
139
|
+
и последовательность табуляции видят только актуальный вариант. Дублирования
|
|
140
|
+
контента для ассистивных технологий не возникает, но и «широкая» разметка на
|
|
141
|
+
узком экране недоступна.
|
|
142
|
+
- Смена ветки при ресайзе удаляет из DOM сфокусированный элемент — фокус
|
|
143
|
+
переходит на `<body>`. Если это критично (открытый оверлей, форма), верни
|
|
144
|
+
фокус явно на стороне потребителя.
|
|
145
|
+
- Медиа-запрос завязан на ширину окна, а не на тип ввода: на десктопе с узким
|
|
146
|
+
окном тоже рендерится «мобильная» ветка. Не завязывай на `MediaWidth` наличие
|
|
147
|
+
touch-специфичных обработчиков как единственного способа взаимодействия.
|
|
81
148
|
|
|
82
|
-
|
|
83
|
-
children: React.ReactElement | null;
|
|
84
|
-
fallback: React.ReactElement | null;
|
|
85
|
-
```
|
|
149
|
+
---
|
|
86
150
|
|
|
87
|
-
|
|
88
|
-
- **Render-props стиль "if/else"**, не "return null if mismatch".
|
|
151
|
+
## Связанные компоненты
|
|
89
152
|
|
|
90
|
-
|
|
153
|
+
Все три реализации живут в той же папке, экспортируются из того же barrel и
|
|
154
|
+
собственного AI.md не имеют — их контракт описан здесь.
|
|
155
|
+
|
|
156
|
+
> **Объём AI-рефакторинга.** В рамках TRI-58 отрефакторен только `MediaWidth.tsx`:
|
|
157
|
+
> соседние реализации и `useMatchMedia` были вне scope задачи. В их JSDoc
|
|
158
|
+
> остаются недочёты (опечатка «ширина экран» в `MediaMaxWidth` / `MediaMinWidth` /
|
|
159
|
+
> `MediaBetweenWidth`, `@param initial` без соответствующего параметра
|
|
160
|
+
> в `useMatchMedia`) — семейство ещё не вычищено целиком, это отдельная задача.
|
|
161
|
+
> Туда же — тест на fallback `addListener` / `removeListener`: инвариант ниже
|
|
162
|
+
> запрещает его удалять, но ни один тест эту ветку не исполняет (во всех моках
|
|
163
|
+
> `MediaQueryList` есть `addEventListener`).
|
|
164
|
+
|
|
165
|
+
- `MediaBetweenWidth` (`src/components/MediaWidth/MediaBetweenWidth.tsx`) —
|
|
166
|
+
диапазон между двумя границами. Props: `minWidth` и `maxWidth` **обязательные**,
|
|
167
|
+
плюс `children` и `fallback`. Интерфейс `IMediaBetweenWidthProps`.
|
|
168
|
+
- `MediaMinWidth` (`src/components/MediaWidth/MediaMinWidth.tsx`) — только нижняя
|
|
169
|
+
граница, `minWidth` обязателен. Интерфейс `IMediaMinWidthProps`.
|
|
170
|
+
- `MediaMaxWidth` (`src/components/MediaWidth/MediaMaxWidth.tsx`) — только верхняя
|
|
171
|
+
граница, `maxWidth` обязателен. Интерфейс `IMediaMaxWidthProps`.
|
|
172
|
+
- `useMatchMedia` (`src/components/MediaWidth/useMatchMedia.ts`) — хук подписки на
|
|
173
|
+
произвольный медиа-запрос, основа всего семейства. Принимает строку запроса,
|
|
174
|
+
возвращает `boolean`. Годится и для не-ширинных запросов: `CarouselButton`
|
|
175
|
+
использует его с `(pointer: coarse)`.
|
|
176
|
+
- `MobileView` (`src/components/MobileView/`) — частный случай `MediaWidth` с
|
|
177
|
+
`maxWidth={EScreenWidth.SM_MAX}`, со своим AI.md. Для мобильной границы
|
|
178
|
+
используется он, а не `MediaWidth` напрямую.
|
|
179
|
+
- `WindowResizeListener` (`src/components/WindowResizeListener/`) — альтернатива
|
|
180
|
+
для императивного случая: даёт колбэк на поток событий `resize`, а не рендерит
|
|
181
|
+
ветку по медиа-запросу. Правило выбора: нужно **что-то показать** на
|
|
182
|
+
определённой ширине — `MediaWidth`; нужно **что-то посчитать/сделать** на
|
|
183
|
+
ресайз — `WindowResizeListener`.
|
|
184
|
+
|
|
185
|
+
Разница между `MediaWidth` и тремя реализациями: у `MediaWidth` обе границы
|
|
186
|
+
опциональны и выбор реализации делается за потребителя; у реализаций
|
|
187
|
+
соответствующие границы обязательны. Прямое использование реализации оправдано,
|
|
188
|
+
когда набор границ известен статически и «пустая» комбинация невозможна по
|
|
189
|
+
построению.
|
|
190
|
+
|
|
191
|
+
### Потребители внутри библиотеки
|
|
192
|
+
|
|
193
|
+
Компонентом `MediaWidth`: `MobileView` (и, транзитивно, все его потребители).
|
|
194
|
+
Хуком `useMatchMedia`: `CarouselButton`, `useMobileView`.
|
|
195
|
+
|
|
196
|
+
В unit-тестах потребителей ветка задаётся подменой `window.matchMedia` (как в
|
|
197
|
+
`MediaWidth.test.tsx` и `Dropdown.test.tsx`) либо мокированием модуля
|
|
198
|
+
`useMatchMedia` (как в `IslandWidget.test.tsx`).
|
|
91
199
|
|
|
92
|
-
|
|
93
|
-
useMatchMedia(`(min-width: ${minWidth})`, window.innerWidth >= parseInt(minWidth));
|
|
94
|
-
```
|
|
200
|
+
---
|
|
95
201
|
|
|
96
|
-
|
|
97
|
-
- Потребители в SSR должны оборачивать в ClientOnly или подавать `false`/`true` безопасный default через свой wrapper.
|
|
202
|
+
## Stories
|
|
98
203
|
|
|
99
|
-
|
|
204
|
+
Основные истории: `stories/MediaWidth/MediaWidth.stories.tsx`
|
|
205
|
+
Файлы примеров: `stories/MediaWidth/examples/`
|
|
100
206
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
207
|
+
| Story | Example file | Что демонстрирует |
|
|
208
|
+
|---|---|---|
|
|
209
|
+
| `Playground` | — | Интерактивный подбор `minWidth` / `maxWidth`, включая значение `undefined` |
|
|
210
|
+
| `Default` | `DefaultExample.tsx` | Обе границы: контент виден в диапазоне 768px–1199px |
|
|
211
|
+
| `MinWidth` | `MinWidthExample.tsx` | Только нижняя граница: контент от 768px и шире |
|
|
212
|
+
| `MaxWidth` | `MaxWidthExample.tsx` | Только верхняя граница: контент до 1199px включительно |
|
|
213
|
+
| `Fallback` | `FallbackExample.tsx` | Без границ: всегда рендерится `fallback` |
|
|
214
|
+
| `Example: MobileView` | `MobileViewExample.tsx` | Связь общего случая с частным — `MobileView` вместо ручной мобильной границы |
|
|
104
215
|
|
|
105
|
-
|
|
106
|
-
-
|
|
216
|
+
Скриншот-тестами покрыта только story `Example: MobileView` (baseline
|
|
217
|
+
`mediawidth--mobile-view-story--xs.png` и `--xl.png`): на viewport `xs` (575px)
|
|
218
|
+
рендерится мобильная ветка, на `xl` (1200px) — `fallback`. Остальные stories
|
|
219
|
+
помечены `testRunner: { skip: true }` — их результат целиком определяется
|
|
220
|
+
шириной viewport и уже проверяется этой парой скриншотов.
|
|
107
221
|
|
|
108
|
-
|
|
222
|
+
---
|
|
223
|
+
|
|
224
|
+
## История изменений
|
|
109
225
|
|
|
110
|
-
|
|
226
|
+
| Дата | Изменение |
|
|
227
|
+
|---|---|
|
|
228
|
+
| 2026-08-18 | TRI-104: в `related` и «Связанные компоненты» добавлен `WindowResizeListener` — обратная сторона симметричной связи-альтернативы. Код и публичный API не затронуты. |
|
|
229
|
+
| 2026-08-11 | Создан документ. AI-рефакторинг (TRI-58): `displayName` у `MediaWidth`, исправлены опечатки и дополнен JSDoc props и компонента, unit-тесты расширены с 7 до 19 кейсов (проверяются строки медиа-запросов, выбор реализации, `null`-ветки, переподписка и отписка). Публичный API не изменён (props, `IMediaProps`, barrel-экспорты; `forwardRef` по-прежнему осознанно отсутствует). |
|
|
111
230
|
|
|
112
|
-
|
|
231
|
+
---
|
|
113
232
|
|
|
114
|
-
|
|
115
|
-
`(max-width: ${maxWidth}) and (min-width: ${minWidth})`
|
|
116
|
-
```
|
|
233
|
+
## Примеры использования
|
|
117
234
|
|
|
118
|
-
|
|
235
|
+
### Default
|
|
119
236
|
|
|
120
|
-
|
|
237
|
+
`stories/MediaWidth/examples/DefaultExample.tsx`
|
|
121
238
|
|
|
122
|
-
|
|
239
|
+
```tsx
|
|
240
|
+
import React from "react";
|
|
241
|
+
import { MediaWidth, EScreenWidth } from "@sberbusiness/triplex-next";
|
|
123
242
|
|
|
124
|
-
|
|
243
|
+
export const DefaultExample = () => (
|
|
244
|
+
<MediaWidth
|
|
245
|
+
minWidth={EScreenWidth.MD_MIN}
|
|
246
|
+
maxWidth={EScreenWidth.LG_MAX}
|
|
247
|
+
fallback={<div>Fallback: ширина экрана за пределами диапазона 768px–1199px</div>}
|
|
248
|
+
>
|
|
249
|
+
<div>Контент виден только на экранах шириной от 768px до 1199px включительно</div>
|
|
250
|
+
</MediaWidth>
|
|
251
|
+
);
|
|
252
|
+
```
|
|
125
253
|
|
|
126
|
-
|
|
254
|
+
### MinWidth
|
|
127
255
|
|
|
128
|
-
|
|
129
|
-
- **`EScreenWidth` как тип `minWidth`/`maxWidth`** — потребители завязаны на брейкпоинты библиотеки; произвольные строки не принимаются.
|
|
130
|
-
- **`useMatchMedia(initial)` аргумент обязателен** — отсутствие initial ломает SSR-совместимость (которая и так условная).
|
|
131
|
-
- **`window.innerWidth` в initial** — legacy-approach. Не вставлять в SSR-контекст без защиты.
|
|
132
|
-
- **`addEventListener("change")`** — современный API; не переключать на deprecated `addListener`.
|
|
133
|
-
- **`MediaWidth` без границ → `fallback`** — документированное поведение, не менять.
|
|
256
|
+
`stories/MediaWidth/examples/MinWidthExample.tsx`
|
|
134
257
|
|
|
135
|
-
|
|
258
|
+
```tsx
|
|
259
|
+
import React from "react";
|
|
260
|
+
import { MediaWidth, EScreenWidth } from "@sberbusiness/triplex-next";
|
|
136
261
|
|
|
137
|
-
|
|
262
|
+
export const MinWidthExample = () => (
|
|
263
|
+
<MediaWidth minWidth={EScreenWidth.MD_MIN} fallback={<div>Fallback: ширина экрана менее 768px</div>}>
|
|
264
|
+
<div>Контент виден на экранах шириной 768px и более</div>
|
|
265
|
+
</MediaWidth>
|
|
266
|
+
);
|
|
267
|
+
```
|
|
138
268
|
|
|
139
|
-
|
|
140
|
-
- Предпочитай CSS `@media` + `display: none` там, где возможно: DOM стабилен, скринридеры видят весь контент (если это желаемое поведение) или выбираешь, какой показать через `aria-hidden`.
|
|
141
|
-
- Используй `MediaWidth`/`MobileView` только тогда, когда действительно нужно **разное дерево React'а** (разные компоненты, не CSS-вариации).
|
|
269
|
+
### MaxWidth
|
|
142
270
|
|
|
143
|
-
|
|
271
|
+
`stories/MediaWidth/examples/MaxWidthExample.tsx`
|
|
144
272
|
|
|
145
|
-
|
|
273
|
+
```tsx
|
|
274
|
+
import React from "react";
|
|
275
|
+
import { MediaWidth, EScreenWidth } from "@sberbusiness/triplex-next";
|
|
146
276
|
|
|
147
|
-
|
|
277
|
+
export const MaxWidthExample = () => (
|
|
278
|
+
<MediaWidth maxWidth={EScreenWidth.LG_MAX} fallback={<div>Fallback: ширина экрана более 1199px</div>}>
|
|
279
|
+
<div>Контент виден на экранах шириной до 1199px включительно</div>
|
|
280
|
+
</MediaWidth>
|
|
281
|
+
);
|
|
282
|
+
```
|
|
148
283
|
|
|
149
|
-
|
|
284
|
+
### Fallback
|
|
150
285
|
|
|
151
|
-
|
|
286
|
+
`stories/MediaWidth/examples/FallbackExample.tsx`
|
|
152
287
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
288
|
+
```tsx
|
|
289
|
+
import React from "react";
|
|
290
|
+
import { MediaWidth } from "@sberbusiness/triplex-next";
|
|
156
291
|
|
|
157
|
-
|
|
292
|
+
export const FallbackExample = () => (
|
|
293
|
+
<MediaWidth fallback={<div>Fallback отображается всегда, если не заданы minWidth и maxWidth</div>}>
|
|
294
|
+
{null}
|
|
295
|
+
</MediaWidth>
|
|
296
|
+
);
|
|
297
|
+
```
|
|
158
298
|
|
|
159
|
-
|
|
299
|
+
### Example: MobileView
|
|
160
300
|
|
|
161
|
-
|
|
301
|
+
`stories/MediaWidth/examples/MobileViewExample.tsx`
|
|
162
302
|
|
|
163
|
-
|
|
303
|
+
```tsx
|
|
304
|
+
import React from "react";
|
|
305
|
+
import { MobileView } from "@sberbusiness/triplex-next";
|
|
164
306
|
|
|
165
|
-
|
|
307
|
+
export const MobileViewExample = () => (
|
|
308
|
+
<MobileView fallback={<div>Десктоп: ширина экрана 768px и более</div>}>
|
|
309
|
+
<div>Мобильный: ширина экрана менее 768px</div>
|
|
310
|
+
</MobileView>
|
|
311
|
+
);
|
|
312
|
+
```
|
|
166
313
|
|
|
167
|
-
| Дата | Изменение |
|
|
168
|
-
|---|---|
|
|
169
|
-
| 2026-04-18 | Создан документ |
|