@sberbusiness/triplex-next-mcp-server 0.24.0-beta1

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 (140) hide show
  1. package/README.md +124 -0
  2. package/bundle/.gitkeep +0 -0
  3. package/bundle/components/AbstractTree.md +198 -0
  4. package/bundle/components/AccordionBase.md +227 -0
  5. package/bundle/components/Alert.md +317 -0
  6. package/bundle/components/Amount.md +225 -0
  7. package/bundle/components/AmountField.md +289 -0
  8. package/bundle/components/Avatar.md +209 -0
  9. package/bundle/components/Badge.md +277 -0
  10. package/bundle/components/Body.md +167 -0
  11. package/bundle/components/Button.md +230 -0
  12. package/bundle/components/ButtonDropdown.md +159 -0
  13. package/bundle/components/ButtonIcon.md +122 -0
  14. package/bundle/components/Calendar.md +445 -0
  15. package/bundle/components/Card.md +374 -0
  16. package/bundle/components/CarouselExtended.md +250 -0
  17. package/bundle/components/Checkbox.md +126 -0
  18. package/bundle/components/CheckboxTree.md +280 -0
  19. package/bundle/components/CheckboxTreeExtended.md +321 -0
  20. package/bundle/components/CheckboxXGroup.md +68 -0
  21. package/bundle/components/CheckboxYGroup.md +67 -0
  22. package/bundle/components/Chip.md +404 -0
  23. package/bundle/components/ChipGroup.md +179 -0
  24. package/bundle/components/Col.md +221 -0
  25. package/bundle/components/CollapsableTree.md +255 -0
  26. package/bundle/components/Confirm.md +343 -0
  27. package/bundle/components/DateField.md +371 -0
  28. package/bundle/components/DatePickerExtended.md +342 -0
  29. package/bundle/components/DateRange.md +275 -0
  30. package/bundle/components/DesignTokens.md +385 -0
  31. package/bundle/components/Divider.md +196 -0
  32. package/bundle/components/DocumentNumberEdit.md +280 -0
  33. package/bundle/components/Dropdown.md +433 -0
  34. package/bundle/components/Ellipsis.md +208 -0
  35. package/bundle/components/EmptyView.md +99 -0
  36. package/bundle/components/ExpandAnimation.md +281 -0
  37. package/bundle/components/Footer.md +339 -0
  38. package/bundle/components/FormField.md +326 -0
  39. package/bundle/components/FormGroup.md +99 -0
  40. package/bundle/components/Gap.md +113 -0
  41. package/bundle/components/Header.md +280 -0
  42. package/bundle/components/HelpBox.md +154 -0
  43. package/bundle/components/IconWrapper.md +145 -0
  44. package/bundle/components/Island.md +197 -0
  45. package/bundle/components/IslandAccordion.md +230 -0
  46. package/bundle/components/IslandWidget.md +233 -0
  47. package/bundle/components/KeyDownListener.md +157 -0
  48. package/bundle/components/LightBox.md +322 -0
  49. package/bundle/components/Link.md +161 -0
  50. package/bundle/components/List.md +247 -0
  51. package/bundle/components/ListMaster.md +204 -0
  52. package/bundle/components/Loader.md +161 -0
  53. package/bundle/components/LoaderScreen.md +134 -0
  54. package/bundle/components/Marker.md +127 -0
  55. package/bundle/components/MarkerStatus.md +148 -0
  56. package/bundle/components/MediaWidth.md +169 -0
  57. package/bundle/components/MobileView.md +120 -0
  58. package/bundle/components/ModalWindow.md +308 -0
  59. package/bundle/components/MonthYearField.md +168 -0
  60. package/bundle/components/MultiselectField.md +213 -0
  61. package/bundle/components/Notification.md +233 -0
  62. package/bundle/components/NumberField.md +178 -0
  63. package/bundle/components/OrderedList.md +169 -0
  64. package/bundle/components/Overlay.md +237 -0
  65. package/bundle/components/Page.md +246 -0
  66. package/bundle/components/Pagination.md +298 -0
  67. package/bundle/components/Portal.md +119 -0
  68. package/bundle/components/Radio.md +174 -0
  69. package/bundle/components/Row.md +125 -0
  70. package/bundle/components/SMSField.md +160 -0
  71. package/bundle/components/SegmentedControl.md +235 -0
  72. package/bundle/components/SelectExtendedField.md +322 -0
  73. package/bundle/components/SelectField.md +213 -0
  74. package/bundle/components/Skeleton.md +129 -0
  75. package/bundle/components/Slider.md +157 -0
  76. package/bundle/components/SliderExtended.md +210 -0
  77. package/bundle/components/SliderRange.md +160 -0
  78. package/bundle/components/SmallInput.md +101 -0
  79. package/bundle/components/Spoiler.md +121 -0
  80. package/bundle/components/StatusTracker.md +151 -0
  81. package/bundle/components/Step.md +121 -0
  82. package/bundle/components/Stepper.md +163 -0
  83. package/bundle/components/Suggest.md +160 -0
  84. package/bundle/components/SuggestField.md +157 -0
  85. package/bundle/components/SwipeableArea.md +144 -0
  86. package/bundle/components/Table.md +199 -0
  87. package/bundle/components/Tabs.md +152 -0
  88. package/bundle/components/TabsExtended.md +273 -0
  89. package/bundle/components/TabsLine.md +189 -0
  90. package/bundle/components/Tag.md +135 -0
  91. package/bundle/components/TagColor.md +121 -0
  92. package/bundle/components/TagGroup.md +100 -0
  93. package/bundle/components/TextField.md +152 -0
  94. package/bundle/components/TextareaField.md +124 -0
  95. package/bundle/components/ThemeProvider.md +181 -0
  96. package/bundle/components/Tooltip.md +254 -0
  97. package/bundle/components/TopOverlay.md +145 -0
  98. package/bundle/components/TreeView.md +224 -0
  99. package/bundle/components/Triggers.md +121 -0
  100. package/bundle/guides/codestyle.md +205 -0
  101. package/bundle/guides/commits.md +166 -0
  102. package/bundle/guides/context.md +277 -0
  103. package/bundle/guides/stories.md +618 -0
  104. package/bundle/guides/template.md +154 -0
  105. package/bundle/guides/tests.md +301 -0
  106. package/bundle/icons.json +4156 -0
  107. package/bundle/manifest.json +796 -0
  108. package/bundle/release-notes/1.1.0.mdx +26 -0
  109. package/bundle/release-notes/1.1.1.mdx +14 -0
  110. package/bundle/release-notes/1.10.0.mdx +43 -0
  111. package/bundle/release-notes/1.11.0.mdx +19 -0
  112. package/bundle/release-notes/1.12.0.mdx +21 -0
  113. package/bundle/release-notes/1.13.0.mdx +43 -0
  114. package/bundle/release-notes/1.14.0.mdx +29 -0
  115. package/bundle/release-notes/1.15.0.mdx +56 -0
  116. package/bundle/release-notes/1.16.0.mdx +55 -0
  117. package/bundle/release-notes/1.17.0.mdx +15 -0
  118. package/bundle/release-notes/1.18.0.mdx +24 -0
  119. package/bundle/release-notes/1.19.0.mdx +48 -0
  120. package/bundle/release-notes/1.19.1.mdx +9 -0
  121. package/bundle/release-notes/1.2.0.mdx +80 -0
  122. package/bundle/release-notes/1.20.0.mdx +48 -0
  123. package/bundle/release-notes/1.21.0.mdx +66 -0
  124. package/bundle/release-notes/1.22.0.mdx +75 -0
  125. package/bundle/release-notes/1.23.0.mdx +50 -0
  126. package/bundle/release-notes/1.24.0.mdx +59 -0
  127. package/bundle/release-notes/1.25.0.mdx +52 -0
  128. package/bundle/release-notes/1.26.0.mdx +11 -0
  129. package/bundle/release-notes/1.3.0.mdx +21 -0
  130. package/bundle/release-notes/1.4.0.mdx +37 -0
  131. package/bundle/release-notes/1.5.0.mdx +24 -0
  132. package/bundle/release-notes/1.6.0.mdx +37 -0
  133. package/bundle/release-notes/1.6.1.mdx +11 -0
  134. package/bundle/release-notes/1.7.0.mdx +29 -0
  135. package/bundle/release-notes/1.8.0.mdx +38 -0
  136. package/bundle/release-notes/1.9.0.mdx +28 -0
  137. package/dist/index.d.ts +2 -0
  138. package/dist/index.js +324 -0
  139. package/dist/index.js.map +1 -0
  140. package/package.json +51 -0
@@ -0,0 +1,134 @@
1
+ ---
2
+ component: LoaderScreen
3
+ category: Feedback
4
+ figma-node: ""
5
+ figma-file: ""
6
+ related: [Loader, Skeleton, LightBox, List]
7
+ tokens: []
8
+ stories: stories/Loaders/LoaderScreen
9
+ version: "1.0"
10
+ ---
11
+
12
+ # LoaderScreen
13
+
14
+ ## Назначение
15
+
16
+ Контейнер-оверлей, рендерящий `LoaderSmall` или `LoaderMiddle` с полупрозрачным
17
+ бэкдропом — поверх блока/экрана, пока идёт загрузка. Centered по `flexbox`
18
+ внутри относительно расположенного родителя (наружный элемент должен иметь
19
+ `position: relative` или быть самим "экраном").
20
+
21
+ Используй когда: нужно закрыть контент оверлеем на время загрузки
22
+ (в Island'е, Modal'е, Content-wrapper'е). Для inline-спиннера в кнопке —
23
+ `LoaderSmall` напрямую. Для skeleton-загрузки известной структуры — `Skeleton`.
24
+
25
+ ---
26
+
27
+ ## Файловая структура
28
+
29
+ ```text
30
+ src/components/LoaderScreen/
31
+ ├── LoaderScreen.tsx # FC, <div> + lоадер
32
+ ├── index.ts # Barrel
33
+ ├── styles/LoaderScreen.module.less
34
+ └── __tests__/LoaderScreen.test.tsx
35
+ ```
36
+
37
+ ---
38
+
39
+ ## Варианты и props
40
+
41
+ ### `ILoaderScreenProps extends HTMLAttributes<HTMLDivElement>`
42
+
43
+ | Prop | Тип | Default | Описание |
44
+ |---|---|---|---|
45
+ | `type` | `"small" \| "middle"` | — (обязателен) | Тип лоадера внутри. `small` — LoaderSmall, `middle` — LoaderMiddle. |
46
+ | `theme` | `ELoaderSmallTheme` | `BRAND` | Только для `type="small"`. Игнорируется для `middle`. |
47
+ | `size` | `EComponentSize` | `MD` | Только для `type="small"`. Игнорируется для `middle`. |
48
+ | `className`, `...HTMLDivAttributes` | — | — | Стандартные. |
49
+
50
+ **`type` — строковый литерал**, не enum. Публичный API. Не смешивать с `ELoaderSmallTheme`.
51
+
52
+ ---
53
+
54
+ ## Ключевые особенности реализации
55
+
56
+ ### Два backdrop-класса по типу
57
+
58
+ ```tsx
59
+ {
60
+ [styles.loaderSmallBackdrop]: type === "small",
61
+ [styles.loaderMiddleBackdrop]: type === "middle",
62
+ }
63
+ ```
64
+
65
+ - **`loaderSmallBackdrop`** и **`loaderMiddleBackdrop`** задают разную прозрачность/цвет бэкдропа. Middle обычно более явный (полноценный overlay), Small — лёгкий полупрозрачный.
66
+
67
+ ### Middle обёрнут в дополнительный `<div>`
68
+
69
+ ```tsx
70
+ <div className={styles.loaderMiddleBackground}>
71
+ <LoaderMiddle />
72
+ </div>
73
+ ```
74
+
75
+ Внутренний `background`-wrapper — для "карточки" вокруг точек LoaderMiddle.
76
+ LoaderSmall — просто инлайн-элемент по центру.
77
+
78
+ ### Игнорирование `theme`/`size` для `type="middle"`
79
+
80
+ `LoaderMiddle` API-less, так что `theme` и `size` принимаются, но не
81
+ используются при `type === "middle"`. Не выкидывать их — потребители
82
+ могут переключать `type` динамически без очистки props.
83
+
84
+ ### Не forwardRef
85
+
86
+ Компонент — `React.FC`, не `forwardRef`. Это отступление от общего правила
87
+ библиотеки (`forwardRef обязателен`). Известный legacy-момент; для нового
88
+ API-использования нужен ref — оборачивай снаружи.
89
+
90
+ ---
91
+
92
+ ## Инварианты
93
+
94
+ - **`type: "small" | "middle"`** — строковый литерал. Не заменять на enum без breaking-change.
95
+ - **`theme` / `size` применяются только при `type="small"`** — не разворачивать на `middle` без изменения Loader.
96
+ - **`FC`, без forwardRef** — технический долг. Исправлять — breaking (меняется тип).
97
+ - **Centered через flex внутри оверлея** — родитель должен иметь `position: relative` (или LoaderScreen должен использоваться на фоне самостоятельного блока).
98
+ - **Бэкдроп встроен в LoaderScreen** — отдельно менять прозрачность нельзя, только переопределением CSS-переменной/через `className`.
99
+
100
+ ---
101
+
102
+ ## Accessibility
103
+
104
+ - `role="status"` и `aria-label="loading"` приходят от вложенных `LoaderSmall`/`LoaderMiddle` — LoaderScreen сам ARIA-атрибутов не добавляет.
105
+ - `<div>`-оверлей **не блокирует клики** по контенту под ним — потребитель должен либо расположить LoaderScreen над блоком с `pointer-events`, либо использовать его в модалках/LightBox, где фокус и клики уже контролируются.
106
+ - Для правильной семантики при глобальной загрузке — ставь `aria-busy="true"` на родительский контейнер.
107
+
108
+ ---
109
+
110
+ ## Дизайн-токены
111
+
112
+ Нет публичных переменных — цвета бэкдропа в `styles/LoaderScreen.module.less`.
113
+
114
+ ---
115
+
116
+ ## Связанные компоненты
117
+
118
+ - `Loader` (`LoaderSmall`, `LoaderMiddle`) — вложенные компоненты.
119
+ - `ELoaderSmallTheme`, `EComponentSize` — enum'ы пропсов.
120
+ - `List`, `LightBox`, `ModalWindow` — типовые потребители (оверлей над контентом).
121
+
122
+ ---
123
+
124
+ ## Stories
125
+
126
+ `stories/Loaders/LoaderScreen/` — stories для обоих типов.
127
+
128
+ ---
129
+
130
+ ## История изменений
131
+
132
+ | Дата | Изменение |
133
+ |---|---|
134
+ | 2026-04-18 | Создан документ |
@@ -0,0 +1,127 @@
1
+ ---
2
+ component: Marker
3
+ category: Feedback
4
+ figma-node: ""
5
+ figma-file: ""
6
+ related: [MarkerStatus, Badge, TagColor]
7
+ tokens: []
8
+ stories: ""
9
+ version: "1.0"
10
+ ---
11
+
12
+ # Marker
13
+
14
+ ## Назначение
15
+
16
+ Тонкая обёртка над `Badge.Dot` — цветной кружок-статус (success/error/
17
+ warning/waiting). Содержательно это **именованный preset цвета** для точки,
18
+ чтобы не передавать `palette`-атрибут каждый раз.
19
+
20
+ Используй когда: нужен компактный индикатор статуса (в строке таблицы,
21
+ заголовке, рядом с меткой) и выбор из фиксированной 4-статусной палитры
22
+ семантики. Для статуса с подписью — `MarkerStatus`. Для кастомного цвета —
23
+ `Badge.Dot` напрямую.
24
+
25
+ ---
26
+
27
+ ## Файловая структура
28
+
29
+ ```text
30
+ src/components/Marker/
31
+ ├── Marker.tsx # FC, обёртка над Badge.Dot
32
+ ├── enums.ts # EMarkerStatus (SUCCESS/ERROR/WARNING/WAITING)
33
+ ├── utils.ts # statusToClassNameMap — публичная, используется MarkerStatus
34
+ ├── styles/Marker.module.less # Цвета статусов
35
+ └── index.ts # Barrel
36
+ ```
37
+
38
+ ---
39
+
40
+ ## Варианты и props
41
+
42
+ ### `IMarkerProps extends IBadgeDotProps`
43
+
44
+ | Prop | Тип | Обязателен | Описание |
45
+ |---|---|---|---|
46
+ | `status` | `EMarkerStatus` | Да | Семантический статус (цвет). |
47
+ | `...IBadgeDotProps` | — | — | Все props `Badge.Dot` (size, className, прочие). |
48
+
49
+ ### EMarkerStatus
50
+
51
+ ```ts
52
+ enum EMarkerStatus {
53
+ SUCCESS = "success",
54
+ ERROR = "error",
55
+ WARNING = "warning",
56
+ WAITING = "waiting",
57
+ }
58
+ ```
59
+
60
+ Четыре фиксированных статуса. Расширение — breaking change.
61
+
62
+ ---
63
+
64
+ ## Ключевые особенности реализации
65
+
66
+ ### Реализация — одна строка
67
+
68
+ ```tsx
69
+ <Badge.Dot className={clsx(styles.marker, statusToClassNameMap[status], className)} {...rest} />
70
+ ```
71
+
72
+ - Поверх `Badge.Dot` накладывается класс `.marker` + один из `.success/.error/.warning/.waiting` из `Marker.module.less`, которые переопределяют цвета у точки.
73
+ - Все остальные props `Badge.Dot` (включая `size`, `style`) прокидываются как есть.
74
+
75
+ ### `statusToClassNameMap` — экспортируемая утилита
76
+
77
+ ```ts
78
+ export const statusToClassNameMap = { [EMarkerStatus.SUCCESS]: styles.success, ... };
79
+ ```
80
+
81
+ - **Экспортируется для переиспользования в `MarkerStatus`** (который применяет те же классы к своему контейнеру для окраски текста/описания).
82
+ - Если добавляешь статус — обязательно обнови `utils.ts` и LESS-стили, и проверь, что `MarkerStatus` тоже подтягивает новый класс.
83
+
84
+ ---
85
+
86
+ ## Инварианты
87
+
88
+ - **`EMarkerStatus`** (4 значения) — публичный API. Расширение — breaking.
89
+ - **`Marker = Badge.Dot + className`** — тонкая обёртка; избегать добавления своих props, которые размажут семантику со `Badge`.
90
+ - **`statusToClassNameMap`** экспортируется из `utils.ts` — `MarkerStatus` зависит от неё. Не менять shape.
91
+ - **`size` приходит от `Badge.Dot`** (через `IBadgeDotProps`), а не кастомизируется Marker'ом.
92
+ - **FC, не forwardRef** — ref прокидывается `Badge.Dot` внутри? Проверь перед изменением.
93
+
94
+ ---
95
+
96
+ ## Accessibility
97
+
98
+ - `Badge.Dot` по умолчанию — декоративный элемент без ARIA. Для анонсирования статуса скринридером потребитель должен добавить `aria-label` через `...rest` или сопроводить текстом рядом.
99
+ - `MarkerStatus` уже выводит текстовый статус — там a11y закрыт.
100
+
101
+ ---
102
+
103
+ ## Дизайн-токены
104
+
105
+ Цвета статусов заданы в `styles/Marker.module.less` (не через CSS-переменные). Для новой темы статусов — переопределяй в LESS.
106
+
107
+ ---
108
+
109
+ ## Связанные компоненты
110
+
111
+ - `Badge` / `Badge.Dot` — основа.
112
+ - `MarkerStatus` — Marker + текст + описание, использует тот же `statusToClassNameMap`.
113
+ - `TagColor` — альтернатива для статуса с подписью внутри "пилюли".
114
+
115
+ ---
116
+
117
+ ## Stories
118
+
119
+ Нет отдельных — только через `MarkerStatus.stories.tsx` (там показаны все 4 статуса).
120
+
121
+ ---
122
+
123
+ ## История изменений
124
+
125
+ | Дата | Изменение |
126
+ |---|---|
127
+ | 2026-04-18 | Создан документ |
@@ -0,0 +1,148 @@
1
+ ---
2
+ component: MarkerStatus
3
+ category: Feedback
4
+ figma-node: ""
5
+ figma-file: ""
6
+ related: [Marker, Badge, Typography]
7
+ tokens: []
8
+ stories: stories/MarkerStatus/MarkerStatus.stories.tsx
9
+ version: "1.0"
10
+ ---
11
+
12
+ # MarkerStatus
13
+
14
+ ## Назначение
15
+
16
+ Статус-блок: цветная точка (`Marker`) + заголовок (`children`) + опциональное
17
+ описание. Окрашивает **текст заголовка/описания** цветом статуса через
18
+ общий `statusToClassNameMap` (из `Marker/utils`). Два размера — MD / LG.
19
+
20
+ Используй когда: нужна компактная семантическая индикация состояния с
21
+ подписью (успех операции, ошибка, pending). Для просто точки без текста —
22
+ `Marker`. Для статуса-пилюли с фоном — `TagColor`.
23
+
24
+ ---
25
+
26
+ ## Файловая структура
27
+
28
+ ```text
29
+ src/components/MarkerStatus/
30
+ ├── MarkerStatus.tsx # FC, div + Marker + Text/Caption
31
+ ├── index.ts # Barrel
32
+ ├── styles/MarkerStatus.module.less # Цвета текста по статусу, размерные варианты
33
+ └── __tests__/MarkerStatus.test.tsx
34
+ ```
35
+
36
+ ---
37
+
38
+ ## Варианты и props
39
+
40
+ ### `IMarkerStatusProps extends HTMLAttributes<HTMLDivElement>`
41
+
42
+ | Prop | Тип | Default | Описание |
43
+ |---|---|---|---|
44
+ | `status` | `EMarkerStatus` (`SUCCESS`/`ERROR`/`WARNING`/`WAITING`) | — | Обязателен. Цвет точки и текста. |
45
+ | `children` | `ReactNode` | — | Заголовок (основной текст статуса). Рендерится в `Text size=B4` (MD) / `B3` (LG). |
46
+ | `description` | `ReactNode` | — | Доп. описание под заголовком. MD — `Caption C1 SECONDARY`; LG — `Text B4 SECONDARY`. |
47
+ | `size` | `EComponentSize.MD \| EComponentSize.LG` | `MD` | **Ограниченный enum-subset** — нет `SM`. |
48
+
49
+ ---
50
+
51
+ ## Ключевые особенности реализации
52
+
53
+ ### Размер = `EComponentSize.MD | EComponentSize.LG`
54
+
55
+ ```ts
56
+ size?: EComponentSize.MD | EComponentSize.LG;
57
+ ```
58
+
59
+ - **SM запрещён на уровне типа**. Если передать `SM` — TS ошибка. Для runtime-значения — визуал не определён.
60
+ - Если появится требование SM — добавить маппинги `sizeToClassNameMap`, `markerStatusSizeToTextSizeMap` и LESS-стиль.
61
+
62
+ ### `size` пробрасывается в `Marker` (Badge.Dot)
63
+
64
+ ```tsx
65
+ <Marker status={status} size={size} />
66
+ ```
67
+
68
+ - Marker получает `size` через `...IBadgeDotProps` — `Badge.Dot` сам определяет, как размер влияет на диаметр точки.
69
+
70
+ ### Маппинг размера → typography-размер
71
+
72
+ ```ts
73
+ const markerStatusSizeToTextSizeMap = {
74
+ [EComponentSize.MD]: ETextSize.B4,
75
+ [EComponentSize.LG]: ETextSize.B3,
76
+ };
77
+ ```
78
+
79
+ - MD → B4, LG → B3. Публичный контракт (визуальная спецификация).
80
+
81
+ ### `description` — разный компонент по размеру
82
+
83
+ ```tsx
84
+ size === EComponentSize.MD
85
+ ? <Caption size={C1} type={SECONDARY}>{description}</Caption>
86
+ : <Text size={B4} type={SECONDARY}>{description}</Text>
87
+ ```
88
+
89
+ - **MD → Caption (C1)**, **LG → Text (B4 SECONDARY)**. Меньшая строка (Caption) в меньшем размере.
90
+ - `type=SECONDARY` — приглушённый цвет.
91
+
92
+ ### Цвет текста — через `statusToClassNameMap` из Marker/utils
93
+
94
+ ```tsx
95
+ <div className={clsx(styles.markerStatus, sizeToClassNameMap[size], statusToClassNameMap[status], className)}>
96
+ ```
97
+
98
+ - **Переиспользование** CSS-Modules класса из `Marker/styles` — заложена **кросс-файловая зависимость**: `Marker/utils.ts` импортирует `Marker.module.less`. Если стили MarkerStatus переопределяют цвет текста, то они опираются на то, что корневой класс `.success/.error/...` уже задан.
99
+
100
+ ---
101
+
102
+ ## Инварианты
103
+
104
+ - **`status` обязателен** — без него семантика теряется.
105
+ - **`size: MD | LG`** — тип-ограниченный subset `EComponentSize`. Расширение — breaking для потребителей, проверяющих тип.
106
+ - **Маппинг размера → typography** (B4/B3 для заголовка; C1/B4 для описания) — зафиксирован в коде, публичная визуальная спецификация.
107
+ - **Использует `Marker/utils.statusToClassNameMap`** — изменение shape в Marker сломает MarkerStatus.
108
+ - **FC, не forwardRef** — ref вовне не прокидывается. Legacy.
109
+ - **`data-tx={npm_package_version}`** — маркер версии. Сохранять.
110
+
111
+ ---
112
+
113
+ ## Accessibility
114
+
115
+ - `<div>` — без ARIA-роли. Статус должен читаться скринридером через **текст в children**. Не полагайся только на цвет.
116
+ - Если children тоже визуально отражает статус (например, "Ошибка"), и нужна дополнительная семантика — добавь `role="status"` через `...rest` или оборачивай MarkerStatus в live region.
117
+ - Цвет текста — только как визуальный акцент. WCAG-контраст контролируется токенами `SECONDARY`/статус-цветами; при кастомных темах — проверить.
118
+
119
+ ---
120
+
121
+ ## Дизайн-токены
122
+
123
+ Нет публичных переменных компонента; цвета текста статусов заданы в
124
+ `styles/MarkerStatus.module.less`. Цвет точки — через `Marker`.
125
+
126
+ ---
127
+
128
+ ## Связанные компоненты
129
+
130
+ - `Marker` — цветная точка; то же `EMarkerStatus` и `statusToClassNameMap`.
131
+ - `Badge.Dot` — база для Marker.
132
+ - `Typography` (`Text`, `Caption`) — для заголовка и описания.
133
+ - `TagColor` — альтернатива с фоном-пилюлей.
134
+
135
+ ---
136
+
137
+ ## Stories
138
+
139
+ `stories/MarkerStatus/MarkerStatus.stories.tsx`
140
+ Примеры: `stories/MarkerStatus/examples/`
141
+
142
+ ---
143
+
144
+ ## История изменений
145
+
146
+ | Дата | Изменение |
147
+ |---|---|
148
+ | 2026-04-18 | Создан документ |
@@ -0,0 +1,169 @@
1
+ ---
2
+ component: MediaWidth
3
+ category: Utilities
4
+ figma-node: ""
5
+ figma-file: ""
6
+ related: [MobileView, IslandWidget]
7
+ tokens: []
8
+ stories: ""
9
+ version: "1.0"
10
+ ---
11
+
12
+ # MediaWidth
13
+
14
+ ## Назначение
15
+
16
+ Набор компонентов + хук для условного рендеринга по ширине окна:
17
+ - **`useMatchMedia(query, initial)`** — хук, обёртка над `window.matchMedia` с live-обновлением через `change`-listener.
18
+ - **`MediaMinWidth` / `MediaMaxWidth` / `MediaBetweenWidth`** — рендерят `children` / `fallback` по результату media-query.
19
+ - **`MediaWidth`** — универсальная обёртка; по наличию `minWidth`/`maxWidth` выбирает нужный из трёх.
20
+
21
+ Используй когда: нужно рендерить разный UI на разных брейкпоинтах.
22
+ Для бинарного "mobile vs desktop" — `MobileView`. Для стилей — CSS `@media`
23
+ напрямую (без JS-условия).
24
+
25
+ ---
26
+
27
+ ## Файловая структура
28
+
29
+ ```text
30
+ src/components/MediaWidth/
31
+ ├── MediaWidth.tsx # Компонент-диспетчер
32
+ ├── MediaMinWidth.tsx # min-width only
33
+ ├── MediaMaxWidth.tsx # max-width only
34
+ ├── MediaBetweenWidth.tsx # between min and max
35
+ ├── useMatchMedia.ts # Хук
36
+ ├── index.ts # Barrel (все 4 компонента + хук)
37
+ └── __tests__/
38
+ ```
39
+
40
+ ---
41
+
42
+ ## Варианты и props
43
+
44
+ ### MediaWidth — `IMediaProps`
45
+
46
+ | Prop | Тип | Обязателен | Описание |
47
+ |---|---|---|---|
48
+ | `children` | `ReactElement \| null` | Да | Элемент рендерится при совпадении с media-query. |
49
+ | `fallback` | `ReactElement \| null` | Да | Рендерится, если не совпало. |
50
+ | `minWidth` | `EScreenWidth` | Нет | Нижняя граница. |
51
+ | `maxWidth` | `EScreenWidth` | Нет | Верхняя граница. |
52
+
53
+ Логика выбора:
54
+ - `minWidth && maxWidth` → `MediaBetweenWidth`
55
+ - `minWidth` → `MediaMinWidth`
56
+ - `maxWidth` → `MediaMaxWidth`
57
+ - Ни один — возвращает `fallback`.
58
+
59
+ ### MediaMinWidth / MediaMaxWidth / MediaBetweenWidth
60
+
61
+ Аналогичные props (`children`, `fallback`, соответствующие `min`/`max`).
62
+
63
+ ### useMatchMedia — `(query: string, initial: boolean) => boolean`
64
+
65
+ | Параметр | Описание |
66
+ |---|---|
67
+ | `query` | Полный media-query (например, `"(max-width: 767px)"`). |
68
+ | `initial` | Начальное значение до первого рендера — критично для SSR/первого кадра. |
69
+
70
+ Возвращает `true`, если query совпадает. Подписывается на `change`, возвращает актуальное значение.
71
+
72
+ ### EScreenWidth (из `@sberbusiness/triplex-next/helpers/breakpoints`)
73
+
74
+ Breakpoint-значения: `XS_MAX`, `SM_MIN`, `SM_MAX`, `MD_MIN`, `MD_MAX`, `LG_MIN`, `LG_MAX`, `XL_MIN`, и т.д. (строковые — в px). Используются как значения `minWidth`/`maxWidth`.
75
+
76
+ ---
77
+
78
+ ## Ключевые особенности реализации
79
+
80
+ ### `children` / `fallback` обязательны — нет "пустого рендера"
81
+
82
+ ```ts
83
+ children: React.ReactElement | null;
84
+ fallback: React.ReactElement | null;
85
+ ```
86
+
87
+ - Оба slot'а должны быть заданы (даже если один — `null`). Не `children?: ReactNode`.
88
+ - **Render-props стиль "if/else"**, не "return null if mismatch".
89
+
90
+ ### `window.innerWidth` на первом рендере — НЕ SSR-safe
91
+
92
+ ```ts
93
+ useMatchMedia(`(min-width: ${minWidth})`, window.innerWidth >= parseInt(minWidth));
94
+ ```
95
+
96
+ - `window.innerWidth` в initial-аргументе выполняется **при рендере**, не в `useEffect` — упадёт на SSR.
97
+ - Потребители в SSR должны оборачивать в ClientOnly или подавать `false`/`true` безопасный default через свой wrapper.
98
+
99
+ ### `useMatchMedia` — `addEventListener("change")`, не deprecated `addListener`
100
+
101
+ ```ts
102
+ mediaQueryList.addEventListener("change", handleChangeMatches);
103
+ ```
104
+
105
+ - Современный API. Safari 13.1+, Chrome 76+ — ок.
106
+ - **Legacy `addListener` не используется** — если нужна поддержка старых Safari, нужен polyfill.
107
+
108
+ ### `useEffect` зависит только от `query`
109
+
110
+ Колбэк `handleChangeMatches` всегда зовёт `setMatches(event.matches)` — `initial` игнорируется после первого рендера.
111
+
112
+ ### `MediaBetweenWidth` query — AND двух conditions
113
+
114
+ ```ts
115
+ `(max-width: ${maxWidth}) and (min-width: ${minWidth})`
116
+ ```
117
+
118
+ Оба условия должны выполняться. `between` — это **пересечение**.
119
+
120
+ ### `MediaWidth` — не "матчит всё" по умолчанию
121
+
122
+ Если ни `minWidth`, ни `maxWidth` не переданы — возвращает `fallback`. Это неочевидно: потребители могут ожидать, что пустая media-query рендерит `children`. Потому всегда **передавай хотя бы одну границу**.
123
+
124
+ ---
125
+
126
+ ## Инварианты
127
+
128
+ - **`children` и `fallback` — обязательные `ReactElement | null`**, не `ReactNode`. Не менять на optional.
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`** — документированное поведение, не менять.
134
+
135
+ ---
136
+
137
+ ## Accessibility
138
+
139
+ - JS-условный рендеринг → **содержимое DOM меняется на брейкпоинте**. При переключении фокуса/viewport/скринридера это может вызвать нежелательный повторный анонс.
140
+ - Предпочитай CSS `@media` + `display: none` там, где возможно: DOM стабилен, скринридеры видят весь контент (если это желаемое поведение) или выбираешь, какой показать через `aria-hidden`.
141
+ - Используй `MediaWidth`/`MobileView` только тогда, когда действительно нужно **разное дерево React'а** (разные компоненты, не CSS-вариации).
142
+
143
+ ---
144
+
145
+ ## Дизайн-токены
146
+
147
+ Нет. Брейкпоинты — `EScreenWidth` (строковые px).
148
+
149
+ ---
150
+
151
+ ## Связанные компоненты
152
+
153
+ - `MobileView` — частный случай (mobile vs desktop), use-case определён.
154
+ - `IslandWidget` — использует `useMatchMedia` для адаптивного сворачивания.
155
+ - `helpers/breakpoints.EScreenWidth` — источник брейкпоинтов.
156
+
157
+ ---
158
+
159
+ ## Stories
160
+
161
+ Нет. Компонент утилитарный; покрытие в тестах и через потребителей.
162
+
163
+ ---
164
+
165
+ ## История изменений
166
+
167
+ | Дата | Изменение |
168
+ |---|---|
169
+ | 2026-04-18 | Создан документ |