@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.
- package/README.md +124 -0
- package/bundle/.gitkeep +0 -0
- package/bundle/components/AbstractTree.md +198 -0
- package/bundle/components/AccordionBase.md +227 -0
- package/bundle/components/Alert.md +317 -0
- package/bundle/components/Amount.md +225 -0
- package/bundle/components/AmountField.md +289 -0
- package/bundle/components/Avatar.md +209 -0
- package/bundle/components/Badge.md +277 -0
- package/bundle/components/Body.md +167 -0
- package/bundle/components/Button.md +230 -0
- package/bundle/components/ButtonDropdown.md +159 -0
- package/bundle/components/ButtonIcon.md +122 -0
- package/bundle/components/Calendar.md +445 -0
- package/bundle/components/Card.md +374 -0
- package/bundle/components/CarouselExtended.md +250 -0
- package/bundle/components/Checkbox.md +126 -0
- package/bundle/components/CheckboxTree.md +280 -0
- package/bundle/components/CheckboxTreeExtended.md +321 -0
- package/bundle/components/CheckboxXGroup.md +68 -0
- package/bundle/components/CheckboxYGroup.md +67 -0
- package/bundle/components/Chip.md +404 -0
- package/bundle/components/ChipGroup.md +179 -0
- package/bundle/components/Col.md +221 -0
- package/bundle/components/CollapsableTree.md +255 -0
- package/bundle/components/Confirm.md +343 -0
- package/bundle/components/DateField.md +371 -0
- package/bundle/components/DatePickerExtended.md +342 -0
- package/bundle/components/DateRange.md +275 -0
- package/bundle/components/DesignTokens.md +385 -0
- package/bundle/components/Divider.md +196 -0
- package/bundle/components/DocumentNumberEdit.md +280 -0
- package/bundle/components/Dropdown.md +433 -0
- package/bundle/components/Ellipsis.md +208 -0
- package/bundle/components/EmptyView.md +99 -0
- package/bundle/components/ExpandAnimation.md +281 -0
- package/bundle/components/Footer.md +339 -0
- package/bundle/components/FormField.md +326 -0
- package/bundle/components/FormGroup.md +99 -0
- package/bundle/components/Gap.md +113 -0
- package/bundle/components/Header.md +280 -0
- package/bundle/components/HelpBox.md +154 -0
- package/bundle/components/IconWrapper.md +145 -0
- package/bundle/components/Island.md +197 -0
- package/bundle/components/IslandAccordion.md +230 -0
- package/bundle/components/IslandWidget.md +233 -0
- package/bundle/components/KeyDownListener.md +157 -0
- package/bundle/components/LightBox.md +322 -0
- package/bundle/components/Link.md +161 -0
- package/bundle/components/List.md +247 -0
- package/bundle/components/ListMaster.md +204 -0
- package/bundle/components/Loader.md +161 -0
- package/bundle/components/LoaderScreen.md +134 -0
- package/bundle/components/Marker.md +127 -0
- package/bundle/components/MarkerStatus.md +148 -0
- package/bundle/components/MediaWidth.md +169 -0
- package/bundle/components/MobileView.md +120 -0
- package/bundle/components/ModalWindow.md +308 -0
- package/bundle/components/MonthYearField.md +168 -0
- package/bundle/components/MultiselectField.md +213 -0
- package/bundle/components/Notification.md +233 -0
- package/bundle/components/NumberField.md +178 -0
- package/bundle/components/OrderedList.md +169 -0
- package/bundle/components/Overlay.md +237 -0
- package/bundle/components/Page.md +246 -0
- package/bundle/components/Pagination.md +298 -0
- package/bundle/components/Portal.md +119 -0
- package/bundle/components/Radio.md +174 -0
- package/bundle/components/Row.md +125 -0
- package/bundle/components/SMSField.md +160 -0
- package/bundle/components/SegmentedControl.md +235 -0
- package/bundle/components/SelectExtendedField.md +322 -0
- package/bundle/components/SelectField.md +213 -0
- package/bundle/components/Skeleton.md +129 -0
- package/bundle/components/Slider.md +157 -0
- package/bundle/components/SliderExtended.md +210 -0
- package/bundle/components/SliderRange.md +160 -0
- package/bundle/components/SmallInput.md +101 -0
- package/bundle/components/Spoiler.md +121 -0
- package/bundle/components/StatusTracker.md +151 -0
- package/bundle/components/Step.md +121 -0
- package/bundle/components/Stepper.md +163 -0
- package/bundle/components/Suggest.md +160 -0
- package/bundle/components/SuggestField.md +157 -0
- package/bundle/components/SwipeableArea.md +144 -0
- package/bundle/components/Table.md +199 -0
- package/bundle/components/Tabs.md +152 -0
- package/bundle/components/TabsExtended.md +273 -0
- package/bundle/components/TabsLine.md +189 -0
- package/bundle/components/Tag.md +135 -0
- package/bundle/components/TagColor.md +121 -0
- package/bundle/components/TagGroup.md +100 -0
- package/bundle/components/TextField.md +152 -0
- package/bundle/components/TextareaField.md +124 -0
- package/bundle/components/ThemeProvider.md +181 -0
- package/bundle/components/Tooltip.md +254 -0
- package/bundle/components/TopOverlay.md +145 -0
- package/bundle/components/TreeView.md +224 -0
- package/bundle/components/Triggers.md +121 -0
- package/bundle/guides/codestyle.md +205 -0
- package/bundle/guides/commits.md +166 -0
- package/bundle/guides/context.md +277 -0
- package/bundle/guides/stories.md +618 -0
- package/bundle/guides/template.md +154 -0
- package/bundle/guides/tests.md +301 -0
- package/bundle/icons.json +4156 -0
- package/bundle/manifest.json +796 -0
- package/bundle/release-notes/1.1.0.mdx +26 -0
- package/bundle/release-notes/1.1.1.mdx +14 -0
- package/bundle/release-notes/1.10.0.mdx +43 -0
- package/bundle/release-notes/1.11.0.mdx +19 -0
- package/bundle/release-notes/1.12.0.mdx +21 -0
- package/bundle/release-notes/1.13.0.mdx +43 -0
- package/bundle/release-notes/1.14.0.mdx +29 -0
- package/bundle/release-notes/1.15.0.mdx +56 -0
- package/bundle/release-notes/1.16.0.mdx +55 -0
- package/bundle/release-notes/1.17.0.mdx +15 -0
- package/bundle/release-notes/1.18.0.mdx +24 -0
- package/bundle/release-notes/1.19.0.mdx +48 -0
- package/bundle/release-notes/1.19.1.mdx +9 -0
- package/bundle/release-notes/1.2.0.mdx +80 -0
- package/bundle/release-notes/1.20.0.mdx +48 -0
- package/bundle/release-notes/1.21.0.mdx +66 -0
- package/bundle/release-notes/1.22.0.mdx +75 -0
- package/bundle/release-notes/1.23.0.mdx +50 -0
- package/bundle/release-notes/1.24.0.mdx +59 -0
- package/bundle/release-notes/1.25.0.mdx +52 -0
- package/bundle/release-notes/1.26.0.mdx +11 -0
- package/bundle/release-notes/1.3.0.mdx +21 -0
- package/bundle/release-notes/1.4.0.mdx +37 -0
- package/bundle/release-notes/1.5.0.mdx +24 -0
- package/bundle/release-notes/1.6.0.mdx +37 -0
- package/bundle/release-notes/1.6.1.mdx +11 -0
- package/bundle/release-notes/1.7.0.mdx +29 -0
- package/bundle/release-notes/1.8.0.mdx +38 -0
- package/bundle/release-notes/1.9.0.mdx +28 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +324 -0
- package/dist/index.js.map +1 -0
- package/package.json +51 -0
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
---
|
|
2
|
+
component: FormGroup
|
|
3
|
+
category: Forms
|
|
4
|
+
figma-node: ""
|
|
5
|
+
figma-file: ""
|
|
6
|
+
related: [FormField, TextField, SelectField, HelpBox, Alert]
|
|
7
|
+
tokens: []
|
|
8
|
+
stories: ""
|
|
9
|
+
version: "1.0"
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# FormGroup
|
|
13
|
+
|
|
14
|
+
## Назначение
|
|
15
|
+
|
|
16
|
+
Разметочная обёртка-`<div>` для группировки элементов формы (`FormField`,
|
|
17
|
+
`HelpBox`, `Alert`, `Description`). Сама по себе **не добавляет стилей** —
|
|
18
|
+
только прокидывает `ref` и все `HTMLDivAttributes`. Смысл — именованная
|
|
19
|
+
точка в DOM для data-атрибутов и семантики формы.
|
|
20
|
+
|
|
21
|
+
Используй когда: нужно сгруппировать несколько полей логически (блок "контакты",
|
|
22
|
+
"адрес") и иметь стабильный wrapper под `data-*`/`aria-*`.
|
|
23
|
+
Не используй как: общий flex-контейнер — возьми `Row`/`Col`.
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Файловая структура
|
|
28
|
+
|
|
29
|
+
```text
|
|
30
|
+
src/components/FormGroup/
|
|
31
|
+
├── FormGroup.tsx # forwardRef, <div>, passthrough props
|
|
32
|
+
└── index.ts # export * from "./FormGroup"
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Нет styles, нет tests, нет stories. Демонстрируется опосредованно через
|
|
36
|
+
stories типовых полей, где `FormGroup` иногда обёрнут вокруг формы.
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## Варианты и props
|
|
41
|
+
|
|
42
|
+
### `IFormGroupProps extends React.HTMLAttributes<HTMLDivElement>`
|
|
43
|
+
|
|
44
|
+
| Prop | Тип | Описание |
|
|
45
|
+
|---|---|---|
|
|
46
|
+
| `children` | `ReactNode` | Обычно несколько `FormField`/`Alert`/`HelpBox`. |
|
|
47
|
+
| `className`, `style`, `...HTMLDivAttributes` | — | Стандартные. |
|
|
48
|
+
|
|
49
|
+
Интерфейс объявлен **локально, не экспортирован**. Если понадобится
|
|
50
|
+
расширить props — сначала экспортировать интерфейс.
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## Инварианты
|
|
55
|
+
|
|
56
|
+
- **`forwardRef`** — есть, не убирать.
|
|
57
|
+
- **Без собственных классов/стилей** — осознанно. Если добавить flex/padding,
|
|
58
|
+
сломается большинство существующих интеграций, где вёрстку задают потомки.
|
|
59
|
+
- Все атрибуты прокидываются на корневой `<div>` через spread — включая
|
|
60
|
+
`className`/`style`. Потребитель сам задаёт лейаут.
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## Accessibility
|
|
65
|
+
|
|
66
|
+
- `<div>` без ARIA-роли. Если группа полей должна объявляться как
|
|
67
|
+
`role="group"`/`role="radiogroup"` — потребитель передаёт `role` и
|
|
68
|
+
`aria-labelledby`/`aria-label` через `...rest`.
|
|
69
|
+
- Fieldset-семантика (`<fieldset>` + `<legend>`) не используется;
|
|
70
|
+
FormGroup не пытается её эмулировать.
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## Дизайн-токены
|
|
75
|
+
|
|
76
|
+
Нет.
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## Связанные компоненты
|
|
81
|
+
|
|
82
|
+
- `FormField` — основной контент внутри FormGroup.
|
|
83
|
+
- `HelpBox`, `Alert` — вспомогательные элементы формы.
|
|
84
|
+
- `Row`, `Col`, `Gap` — предпочтительны, если нужен layout, а не именованная группа.
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
## Stories
|
|
89
|
+
|
|
90
|
+
Нет собственных stories. Используется в примерах `TextField`, `SelectField`,
|
|
91
|
+
`SelectExtendedField`, `FormField`.
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## История изменений
|
|
96
|
+
|
|
97
|
+
| Дата | Изменение |
|
|
98
|
+
|---|---|
|
|
99
|
+
| 2026-04-18 | Создан документ |
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
---
|
|
2
|
+
component: Gap
|
|
3
|
+
category: Layout
|
|
4
|
+
figma-node: ""
|
|
5
|
+
figma-file: ""
|
|
6
|
+
related: [Row, Col, Divider]
|
|
7
|
+
tokens: []
|
|
8
|
+
stories: stories/Gap/Gap.stories.tsx
|
|
9
|
+
version: "1.0"
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Gap
|
|
13
|
+
|
|
14
|
+
## Назначение
|
|
15
|
+
|
|
16
|
+
Вертикальный разделитель-пустота: пустой `<div>` фиксированной высоты для
|
|
17
|
+
отступа между блоками по вертикали. Принципиально ограничен дискретным
|
|
18
|
+
набором размеров из дизайн-системы.
|
|
19
|
+
|
|
20
|
+
Используй когда: нужен вертикальный spacer, а переиспользовать margin/padding
|
|
21
|
+
родителя неудобно (например, между двумя независимыми секциями).
|
|
22
|
+
Не используй когда: можешь задать отступ через `gap` flex-контейнера или
|
|
23
|
+
margin соседа — это семантически предпочтительнее.
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Файловая структура
|
|
28
|
+
|
|
29
|
+
```text
|
|
30
|
+
src/components/Gap/
|
|
31
|
+
├── Gap.tsx # forwardRef, <div role="presentation">, height из size
|
|
32
|
+
├── index.ts # Barrel
|
|
33
|
+
└── __tests__/Gap.test.tsx
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## Варианты и props
|
|
39
|
+
|
|
40
|
+
### `IGapProps extends Omit<HTMLAttributes<HTMLDivElement>, "children">`
|
|
41
|
+
|
|
42
|
+
| Prop | Тип | Обязателен | Описание |
|
|
43
|
+
|---|---|---|---|
|
|
44
|
+
| `size` | `TGapSize` | Да | Высота в пикселях. **Разрешённые значения строго**: `4 \| 8 \| 12 \| 16 \| 24 \| 32 \| 64 \| 128`. |
|
|
45
|
+
| `className`, `style`, `...HTMLDivAttributes` | — | — | `style.height` перезаписывается через `${size}px`. |
|
|
46
|
+
|
|
47
|
+
`children` специально исключён — Gap это пустой разделитель.
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## Ключевые особенности реализации
|
|
52
|
+
|
|
53
|
+
Реализация — одна строка JSX:
|
|
54
|
+
```tsx
|
|
55
|
+
<div style={{ height: `${size}px`, ...style }} role="presentation" {...restProps} ref={ref} />
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
- `role="presentation"` — скринридер игнорирует элемент.
|
|
59
|
+
- `style={{ height, ...style }}` — позволяет перекрыть `height` через props, но порядок такой, что `style` из props идёт **после** и может затереть высоту. Это поведение сохранить (намеренная свобода для кастомных кейсов).
|
|
60
|
+
- Нет собственного `className`/стилей — только inline height.
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## Инварианты
|
|
65
|
+
|
|
66
|
+
- **`TGapSize` union** — публичный API. Добавлять новые значения можно, существующие
|
|
67
|
+
(4/8/12/16/24/32/64/128) удалять нельзя (breaking change).
|
|
68
|
+
- **`forwardRef`** — не убирать.
|
|
69
|
+
- **`role="presentation"`** — не менять без причины (a11y-контракт: spacer не объявляется).
|
|
70
|
+
- **Вертикальный (`height`) только**. Для горизонтального spacing используй `gap`
|
|
71
|
+
flex-контейнера или `Col`. Не добавляй prop `direction`, пока не появится явный запрос.
|
|
72
|
+
- **Без `children`** — тип `Omit<..., "children">` запрещает передачу через TS.
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
## Accessibility
|
|
77
|
+
|
|
78
|
+
- `role="presentation"` — элемент скрыт от скринридеров.
|
|
79
|
+
- Tab-навигация через Gap не проходит (нет фокусируемых детей).
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## Дизайн-токены
|
|
84
|
+
|
|
85
|
+
Нет. Размеры заданы литералами в `TGapSize` — это часть контракта, а не CSS-токены.
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## Связанные компоненты
|
|
90
|
+
|
|
91
|
+
- `Row` / `Col` — обычно предпочтительнее, если есть полноценный flex-layout.
|
|
92
|
+
- `Divider` — визуальный разделитель (с линией), а не пустой отступ.
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
## Stories
|
|
97
|
+
|
|
98
|
+
`stories/Gap/Gap.stories.tsx`
|
|
99
|
+
Примеры: `stories/Gap/examples/`
|
|
100
|
+
|
|
101
|
+
| Story | Example file | Что демонстрирует |
|
|
102
|
+
|---|---|---|
|
|
103
|
+
| `Playground` | — | Интерактивный выбор `size`. |
|
|
104
|
+
| `Default` | `DefaultExample.tsx` | Базовое использование. |
|
|
105
|
+
| `Sizes` | `SizesExample.tsx` | Все значения `TGapSize`. |
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## История изменений
|
|
110
|
+
|
|
111
|
+
| Дата | Изменение |
|
|
112
|
+
|---|---|
|
|
113
|
+
| 2026-04-18 | Создан документ |
|
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
---
|
|
2
|
+
component: Header
|
|
3
|
+
category: Layout
|
|
4
|
+
figma-node: ""
|
|
5
|
+
figma-file: ""
|
|
6
|
+
related: [Page, Footer, Tabs, Button]
|
|
7
|
+
tokens: []
|
|
8
|
+
stories: stories/Page/HeaderPage.stories.tsx
|
|
9
|
+
version: "1.0"
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Header
|
|
13
|
+
|
|
14
|
+
## Назначение
|
|
15
|
+
|
|
16
|
+
Разметочный заголовок страницы/контейнера. **Compound с тремя уровнями
|
|
17
|
+
композиции:** `Header.Title` (заголовок + действия), `Header.Tabs` (вкладки +
|
|
18
|
+
действия) и `Header.Subhead` (произвольный подзаголовок). Плюс отдельный
|
|
19
|
+
layout-слот `Header.LayoutSidebar` для размещения контента рядом с сайдбаром.
|
|
20
|
+
|
|
21
|
+
Используй когда: нужен типовой верхний блок страницы с заголовком, табами
|
|
22
|
+
и действиями (паттерн "Title + Controls" + "Tabs + Controls" + Subheader).
|
|
23
|
+
Корневой `Header` не задаёт стилей — только прокидывает `data-tx` на корневой
|
|
24
|
+
`<div>`; вся вёрстка приходит от уровней.
|
|
25
|
+
|
|
26
|
+
Не используй как: универсальный `<header>`-тег. Потребитель сам решает,
|
|
27
|
+
оборачивать ли во внешний semantic-элемент.
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## Файловая структура
|
|
32
|
+
|
|
33
|
+
```text
|
|
34
|
+
src/components/Header/
|
|
35
|
+
├── Header.tsx # Корень compound, Object.assign уровней
|
|
36
|
+
├── index.ts # Barrel: Header + все под-компоненты
|
|
37
|
+
├── components/
|
|
38
|
+
│ ├── HeaderTitle/
|
|
39
|
+
│ │ ├── HeaderTitle.tsx # Object.assign → Content/Controls
|
|
40
|
+
│ │ ├── HeaderTitleContent.tsx
|
|
41
|
+
│ │ └── HeaderTitleControls.tsx
|
|
42
|
+
│ ├── HeaderTabs/
|
|
43
|
+
│ │ ├── HeaderTabs.tsx # Object.assign → Content/Controls
|
|
44
|
+
│ │ ├── HeaderTabsContent.tsx
|
|
45
|
+
│ │ └── HeaderTabsControls.tsx
|
|
46
|
+
│ ├── HeaderSubheader/
|
|
47
|
+
│ │ └── HeaderSubheader.tsx # withoutPaddings prop
|
|
48
|
+
│ └── HeaderLayoutSidebar/
|
|
49
|
+
│ ├── HeaderLayoutSidebar.tsx # Object.assign → Content/Sidebar
|
|
50
|
+
│ ├── HeaderLayoutSidebarContent.tsx
|
|
51
|
+
│ └── HeaderLayoutSidebarSidebar.tsx
|
|
52
|
+
└── styles/
|
|
53
|
+
├── HeaderTitle.module.less
|
|
54
|
+
├── HeaderTabs.module.less
|
|
55
|
+
├── HeaderSubheader.module.less
|
|
56
|
+
└── HeaderLayoutSidebar.module.less
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Нет собственных `__tests__` в репозитории (проверяется через visual tests
|
|
60
|
+
Page/Header). Нет собственных stories — демонстрация в `stories/Page/HeaderPage.stories.tsx`.
|
|
61
|
+
|
|
62
|
+
Экспорт в `Page`: `Page.Header` = этот же `Header`.
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## Compound-структура
|
|
67
|
+
|
|
68
|
+
```tsx
|
|
69
|
+
<Header>
|
|
70
|
+
<Header.Title>
|
|
71
|
+
<Header.Title.Content>Название страницы</Header.Title.Content>
|
|
72
|
+
<Header.Title.Controls>
|
|
73
|
+
<Button>Действие</Button>
|
|
74
|
+
</Header.Title.Controls>
|
|
75
|
+
</Header.Title>
|
|
76
|
+
|
|
77
|
+
<Header.Tabs>
|
|
78
|
+
<Header.Tabs.Content>
|
|
79
|
+
<TabsLine ... />
|
|
80
|
+
</Header.Tabs.Content>
|
|
81
|
+
<Header.Tabs.Controls>
|
|
82
|
+
<Button>Кнопка у табов</Button>
|
|
83
|
+
</Header.Tabs.Controls>
|
|
84
|
+
</Header.Tabs>
|
|
85
|
+
|
|
86
|
+
<Header.Subhead>Любой произвольный контент</Header.Subhead>
|
|
87
|
+
</Header>
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
**Альтернативный layout с сайдбаром:**
|
|
91
|
+
|
|
92
|
+
```tsx
|
|
93
|
+
<Header>
|
|
94
|
+
<Header.LayoutSidebar>
|
|
95
|
+
<Header.LayoutSidebar.Content>
|
|
96
|
+
<Header.Title>...</Header.Title>
|
|
97
|
+
<Header.Tabs>...</Header.Tabs>
|
|
98
|
+
</Header.LayoutSidebar.Content>
|
|
99
|
+
<Header.LayoutSidebar.Sidebar>
|
|
100
|
+
{/* десктоп-only сайдбар */}
|
|
101
|
+
</Header.LayoutSidebar.Sidebar>
|
|
102
|
+
</Header.LayoutSidebar>
|
|
103
|
+
</Header>
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Все компоненты compound'а также **экспортируются напрямую через barrel**
|
|
107
|
+
(`HeaderTitle`, `HeaderTabs`, `HeaderSubheader`, `HeaderLayoutSidebar` и их
|
|
108
|
+
под-компоненты). Обычно предпочтительна запись через точку (`Header.Title.Content`).
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
## Варианты и props
|
|
113
|
+
|
|
114
|
+
### Header — `IHeaderProps extends HTMLAttributes<HTMLDivElement>`
|
|
115
|
+
|
|
116
|
+
| Prop | Тип | Default | Описание |
|
|
117
|
+
|---|---|---|---|
|
|
118
|
+
| `children` | `ReactNode` | — | Обычно `Header.Title`/`Tabs`/`Subhead` или `Header.LayoutSidebar`. |
|
|
119
|
+
| `className`, `style`, `...HTMLDivAttributes` | — | — | Стандартные. |
|
|
120
|
+
|
|
121
|
+
Корневой `Header` — "прозрачный" `<div>` с `data-tx`. Без собственных CSS-классов.
|
|
122
|
+
|
|
123
|
+
### Header.Title — `IHeaderTitleProps extends HTMLAttributes<HTMLDivElement>`
|
|
124
|
+
|
|
125
|
+
`.headerTitle`: `display: flex; justify-content: space-between;`
|
|
126
|
+
|
|
127
|
+
### Header.Title.Content — `IHeaderTitleContentProps`
|
|
128
|
+
|
|
129
|
+
Имеет два класса: `.headerTitleContent` (локальный) и `.global-HeaderTitleContent`
|
|
130
|
+
(глобальный селектор `min-width: 0` для корректного переноса контента внутри flex).
|
|
131
|
+
|
|
132
|
+
### Header.Title.Controls — `IHeaderTitleControlsProps`
|
|
133
|
+
|
|
134
|
+
`.headerTitleControls`: `flex-shrink: 0; white-space: nowrap; padding-left: 24px;`
|
|
135
|
+
+ `.global-HeaderTitleControls { min-width: 0; }`
|
|
136
|
+
|
|
137
|
+
### Header.Tabs / Tabs.Content / Tabs.Controls
|
|
138
|
+
|
|
139
|
+
Симметрично Title: flex space-between, Content растягивается (`flex-grow: 1`),
|
|
140
|
+
Controls — фикс. Аналогичный mobile wrap.
|
|
141
|
+
|
|
142
|
+
### Header.Subhead — `IHeaderSubheaderProps`
|
|
143
|
+
|
|
144
|
+
| Prop | Тип | Default | Описание |
|
|
145
|
+
|---|---|---|---|
|
|
146
|
+
| `withoutPaddings` | `boolean` | `false` | Убирает `padding: 24px 0`. |
|
|
147
|
+
|
|
148
|
+
### Header.LayoutSidebar / .Content / .Sidebar
|
|
149
|
+
|
|
150
|
+
`.headerLayoutSidebar`: `display: flex; justify-content: space-between;`.
|
|
151
|
+
`Content` — `flex-grow: 1; min-width: 1px`. **`Sidebar` на mobile (`max-width: @screen-sm-max`) скрывается** (`display: none`).
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
## Ключевые особенности реализации
|
|
156
|
+
|
|
157
|
+
### Mobile wrap (Title и Tabs)
|
|
158
|
+
|
|
159
|
+
```less
|
|
160
|
+
@media (max-width: @screen-sm-max) {
|
|
161
|
+
.headerTitle { flex-wrap: wrap; }
|
|
162
|
+
.headerTitleContent { width: 100%; }
|
|
163
|
+
.headerTitleControls {
|
|
164
|
+
padding-left: 0;
|
|
165
|
+
white-space: normal;
|
|
166
|
+
flex-shrink: initial;
|
|
167
|
+
margin-left: -16px; // компенсация Button margin
|
|
168
|
+
> button, > [class*="buttonDropdown"] {
|
|
169
|
+
margin-left: 16px;
|
|
170
|
+
margin-top: 16px;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
Controls переносится на новую строку, отступы между кнопками задаются
|
|
177
|
+
через `margin: 16px` на `<button>` + компенсация `-16px` на контейнере.
|
|
178
|
+
Этот же паттерн использован в `Footer`. Не менять без обновления Button'а.
|
|
179
|
+
|
|
180
|
+
### Глобальные классы `global-HeaderTitleContent` / `global-HeaderTitleControls`
|
|
181
|
+
|
|
182
|
+
```less
|
|
183
|
+
.global-HeaderTitleContent { min-width: 0; }
|
|
184
|
+
.global-HeaderTitleControls { min-width: 0; }
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
Необходимы, чтобы внутренние flex-дети корректно сжимались. Имена с
|
|
188
|
+
префиксом `global-` — это CSS-Modules escape hatch, класс не переименовывается
|
|
189
|
+
при компиляции. Используется для того, чтобы **потребитель мог
|
|
190
|
+
перекрыть стили через глобальный селектор**. Не удалять.
|
|
191
|
+
|
|
192
|
+
### `.headerLink + .headerTitle { padding-top: 0 }` — orphan-селектор
|
|
193
|
+
|
|
194
|
+
Селектор присутствует в `HeaderTitle.module.less`, но класс `headerLink`
|
|
195
|
+
в самом компоненте не используется. Legacy, затачивался под кейс, где
|
|
196
|
+
над Title стоит ссылка "назад". Если встретится — удалять только после
|
|
197
|
+
поиска потребителей.
|
|
198
|
+
|
|
199
|
+
### Sidebar скрыт на mobile
|
|
200
|
+
|
|
201
|
+
`HeaderLayoutSidebarSidebar` на `max-width: @screen-sm-max` получает
|
|
202
|
+
`display: none`. Это осознанное решение (сайдбар редко влезает на мобиле).
|
|
203
|
+
Потребителю нужно учитывать это при дублировании контента сайдбара в
|
|
204
|
+
`HeaderSubhead` для mobile.
|
|
205
|
+
|
|
206
|
+
### Все компоненты — `forwardRef`
|
|
207
|
+
|
|
208
|
+
Включая уровни. Ref идёт на корневой `<div>` каждого слоя.
|
|
209
|
+
|
|
210
|
+
---
|
|
211
|
+
|
|
212
|
+
## Инварианты
|
|
213
|
+
|
|
214
|
+
- **Corневой `Header` минимален**: `<div>` + `data-tx`, без стилей. Не
|
|
215
|
+
добавлять padding — это сломает существующие интеграции, где padding
|
|
216
|
+
задаётся Page/Subhead.
|
|
217
|
+
- **Compound через `Object.assign`** — `Header.Title.Content`,
|
|
218
|
+
`Header.Tabs.Controls`, `Header.LayoutSidebar.Sidebar`. Не заменять на children-API.
|
|
219
|
+
- **Barrel `index.ts`** экспортирует все под-компоненты отдельно. Не удалять
|
|
220
|
+
прямые экспорты (`HeaderTitleContent` и т.д.) — ими пользуются потребители.
|
|
221
|
+
- **Имена `global-HeaderTitle*`** — CSS-Modules escape hatch. Не переименовывать.
|
|
222
|
+
- **Mobile wrap стили** ожидают `<button>` с `margin: 16px`. Не менять
|
|
223
|
+
селекторы `> button` и компенсацию `-16px` без согласования с Button.
|
|
224
|
+
- **Sidebar `display: none` на mobile** — контракт с потребителем. Нельзя
|
|
225
|
+
автоматически дублировать контент сайдбара; решение оставлено за консьюмером.
|
|
226
|
+
- **`forwardRef`** на всех уровнях.
|
|
227
|
+
|
|
228
|
+
---
|
|
229
|
+
|
|
230
|
+
## Accessibility
|
|
231
|
+
|
|
232
|
+
- Все уровни — `<div>` без ARIA-ролей. **Нет автосемантики `<header>`**;
|
|
233
|
+
потребитель сам оборачивает или передаёт `role="banner"` на корневой Header.
|
|
234
|
+
- `HeaderTitleContent` не рендерит `<h1>`/`<h2>` — потребитель передаёт
|
|
235
|
+
нужный заголовок внутрь. Это осознанно: уровень заголовка зависит от контекста.
|
|
236
|
+
- `HeaderTabsContent` обычно содержит `TabsLine`/`Tabs` — они сами управляют ARIA.
|
|
237
|
+
- Tab-навигация — через интерактивные потомки (Buttons/Tabs). Сам Header не focusable.
|
|
238
|
+
|
|
239
|
+
---
|
|
240
|
+
|
|
241
|
+
## Дизайн-токены
|
|
242
|
+
|
|
243
|
+
Нет собственных. Все цвета/тени приходят от дочерних компонентов
|
|
244
|
+
(`Button`, `TabsLine`, `Typography`).
|
|
245
|
+
|
|
246
|
+
---
|
|
247
|
+
|
|
248
|
+
## Связанные компоненты
|
|
249
|
+
|
|
250
|
+
- `Page` — типовой контейнер страницы, экспортирует `Page.Header` = этот `Header`.
|
|
251
|
+
- `Footer` — парный элемент, такая же mobile wrap-логика в `Controls`.
|
|
252
|
+
- `TabsLine` / `Tabs` — типичный контент `HeaderTabsContent`.
|
|
253
|
+
- `Button` / `ButtonDropdown` — ожидаемые дети `Controls` (mobile стили
|
|
254
|
+
рассчитаны на их margin).
|
|
255
|
+
- `DocumentNumberEdit` — используется в `Header.Title.Content` для кейсов с
|
|
256
|
+
редактируемым номером документа.
|
|
257
|
+
|
|
258
|
+
---
|
|
259
|
+
|
|
260
|
+
## Stories
|
|
261
|
+
|
|
262
|
+
**Нет собственных stories.** Демонстрация через
|
|
263
|
+
`stories/Page/HeaderPage.stories.tsx` (регистрируется как
|
|
264
|
+
`Components/HeaderPage`):
|
|
265
|
+
|
|
266
|
+
- `Basic` — базовое использование.
|
|
267
|
+
- `TypeSecond` — альтернативная раскладка.
|
|
268
|
+
- `WithLinkInTitle` — ссылка "назад" над заголовком.
|
|
269
|
+
- `DocumentNumberEdit` — редактируемый номер документа в Title.
|
|
270
|
+
- `WithTabsAndControls` — Title + Tabs + Controls.
|
|
271
|
+
- `WithSubheader` — с Subhead.
|
|
272
|
+
- `LayoutWithSidebar` — `HeaderLayoutSidebar`.
|
|
273
|
+
|
|
274
|
+
---
|
|
275
|
+
|
|
276
|
+
## История изменений
|
|
277
|
+
|
|
278
|
+
| Дата | Изменение |
|
|
279
|
+
|---|---|
|
|
280
|
+
| 2026-04-18 | Создан документ |
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
---
|
|
2
|
+
component: HelpBox
|
|
3
|
+
category: HelpBox
|
|
4
|
+
figma-node: ""
|
|
5
|
+
figma-file: ""
|
|
6
|
+
related: [Tooltip, ButtonIcon, MobileView, FocusTrap]
|
|
7
|
+
tokens: []
|
|
8
|
+
stories: stories/HelpBox/HelpBox.stories.tsx
|
|
9
|
+
version: "1.0"
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# HelpBox
|
|
13
|
+
|
|
14
|
+
## Назначение
|
|
15
|
+
|
|
16
|
+
Иконка "?" (`QuestioncircleFilledSrvIcon16`) с всплывающей подсказкой (Tooltip).
|
|
17
|
+
Объединяет ButtonIcon-триггер, Tooltip и FocusTrap в одном компоненте.
|
|
18
|
+
|
|
19
|
+
Используй когда: нужна контекстная подсказка рядом с элементом интерфейса.
|
|
20
|
+
Не используй когда: нужен полноценный попап с формой или сложным контентом — используй Dropdown или Modal.
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Файловая структура
|
|
25
|
+
|
|
26
|
+
```text
|
|
27
|
+
src/components/HelpBox/
|
|
28
|
+
├── HelpBox.tsx # Основной компонент
|
|
29
|
+
├── index.ts # Barrel export
|
|
30
|
+
├── styles/
|
|
31
|
+
│ └── HelpBox.module.less # Минимальные стили (position, vertical-align)
|
|
32
|
+
└── __tests__/
|
|
33
|
+
└── HelpBox.test.tsx # Unit-тесты
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## Варианты и props
|
|
39
|
+
|
|
40
|
+
### Обязательные props
|
|
41
|
+
|
|
42
|
+
| Prop | Тип | Описание |
|
|
43
|
+
|---|---|---|
|
|
44
|
+
| `tooltipSize` | `ETooltipSize` | Размер тултипа: `SM` или `LG` |
|
|
45
|
+
| `children` | `React.ReactNode` | Контент тела подсказки |
|
|
46
|
+
|
|
47
|
+
### Опциональные props
|
|
48
|
+
|
|
49
|
+
| Prop | Тип | По умолчанию | Описание |
|
|
50
|
+
|---|---|---|---|
|
|
51
|
+
| `isOpen` | `boolean` | `undefined` | Управляемое состояние открытия тултипа |
|
|
52
|
+
| `toggle` | `(open: boolean) => void` | — | Callback при открытии/закрытии |
|
|
53
|
+
| `onShow` | `(node: HTMLDivElement) => void` | — | Callback при появлении тултипа в DOM |
|
|
54
|
+
| `preferPlace` | `ETooltipPreferPlace` | — | Предпочтительное расположение: `ABOVE`, `BELOW`, `LEFT`, `RIGHT` |
|
|
55
|
+
| `mobileHeaderContent` | `React.ReactNode` | — | Контент заголовка в мобильной версии тултипа |
|
|
56
|
+
| `focusTrapProps` | `FocusTrapProps` | — | Свойства `focus-trap-react` для ловушки фокуса |
|
|
57
|
+
| `tooltipAriaAttributes` | `TAriaHTMLAttributes` | — | Aria-атрибуты, пробрасываемые в Tooltip-контейнер |
|
|
58
|
+
| `tooltipDataAttributes` | `TDataHTMLAttributes` | — | Data-атрибуты, пробрасываемые в Tooltip-контейнер |
|
|
59
|
+
| `iconProps` | `ISingleColorIconProps` | — | Свойства иконки вопроса (например, `paletteIndex`) |
|
|
60
|
+
| `tooltipXButtonProps` | `ITooltipXButtonProps` | — | Свойства кнопки закрытия Tooltip (включая `aria-label`) |
|
|
61
|
+
| `className` | `string` | — | CSS-класс, пробрасывается на кнопку-триггер |
|
|
62
|
+
| `...rest` | `React.HTMLAttributes<HTMLButtonElement>` | — | Все стандартные атрибуты `<button>`, включая `aria-label`, пробрасываются на кнопку-триггер |
|
|
63
|
+
|
|
64
|
+
### Controlled / Uncontrolled
|
|
65
|
+
|
|
66
|
+
- **Uncontrolled** (по умолчанию): `isOpen` не передан — компонент сам управляет `openState`.
|
|
67
|
+
- **Controlled**: передай `isOpen` + `toggle` — компонент не меняет внутреннее состояние.
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## Ключевые особенности реализации
|
|
72
|
+
|
|
73
|
+
### Композиция внутренних компонентов
|
|
74
|
+
|
|
75
|
+
HelpBox — обёртка над несколькими внутренними компонентами:
|
|
76
|
+
- `ButtonIcon` (shape=CIRCLE) — кнопка-триггер с иконкой `QuestioncircleFilledSrvIcon16`
|
|
77
|
+
- `Tooltip` (toggleType="hover", role="dialog") — всплывающая подсказка
|
|
78
|
+
- `FocusTrap` (только desktop, через `MobileView`) — ловушка фокуса при открытом тултипе
|
|
79
|
+
- `TooltipMobileHeader` — заголовок мобильной версии (рендерится только при наличии `mobileHeaderContent`)
|
|
80
|
+
|
|
81
|
+
### FocusTrap
|
|
82
|
+
|
|
83
|
+
Ловушка фокуса активируется только на desktop (через `MobileView` fallback). При открытии:
|
|
84
|
+
- `initialFocus` — элемент Tooltip (по ID)
|
|
85
|
+
- `clickOutsideDeactivates: true` — клик за пределами закрывает
|
|
86
|
+
- `preventScroll: true`
|
|
87
|
+
|
|
88
|
+
Потребитель может расширить настройки через `focusTrapProps.focusTrapOptions`.
|
|
89
|
+
|
|
90
|
+
### Ref forwarding
|
|
91
|
+
|
|
92
|
+
`forwardRef` пробрасывает ref на внутренний `ButtonIcon` (кнопку-триггер). Внутренний `buttonRef` используется для позиционирования Tooltip через `targetRef`.
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
## Accessibility
|
|
97
|
+
|
|
98
|
+
- Кнопка-триггер — нативный `<button>` через `ButtonIcon`, shape `CIRCLE`.
|
|
99
|
+
- **`aria-label` триггера** — не захардкожен. Потребитель **обязан** передать `aria-label` через `...rest` (например, `aria-label="Подсказка"`). Библиотека мультиязычная, текст не хардкодится.
|
|
100
|
+
- **`aria-label` кнопки закрытия** — передаётся через `tooltipXButtonProps={{ "aria-label": "Закрыть" }}`. Потребитель **обязан** указать значение на своём языке.
|
|
101
|
+
- Tooltip открывается с `role="dialog"`, `tabIndex={-1}`.
|
|
102
|
+
- FocusTrap удерживает фокус внутри открытого тултипа на desktop.
|
|
103
|
+
- `tooltipAriaAttributes` позволяет добавить aria-атрибуты к контейнеру Tooltip.
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## Дизайн-токены
|
|
108
|
+
|
|
109
|
+
Компонент не использует собственных CSS-переменных. Все визуальные стили наследуются от `ButtonIcon` и `Tooltip`.
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## Инварианты
|
|
114
|
+
|
|
115
|
+
- **`forwardRef`** — обязателен, не убирать.
|
|
116
|
+
- **`IHelpBoxProps` интерфейс** — экспортируемый, часть публичного API.
|
|
117
|
+
- **`tooltipSize` prop** — обязательный, не делать optional.
|
|
118
|
+
- **Barrel export в `index.ts`** — не удалять.
|
|
119
|
+
- **`toggleType="hover"`** — Tooltip реагирует на наведение, не менять без согласования.
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
## Связанные компоненты
|
|
124
|
+
|
|
125
|
+
- `Tooltip` (`src/components/Tooltip/`) — всплывающая подсказка, основной визуальный элемент
|
|
126
|
+
- `ButtonIcon` (`src/components/Button/ButtonIcon.tsx`) — кнопка-триггер
|
|
127
|
+
- `MobileView` (`src/components/MobileView/`) — переключение desktop/mobile поведения
|
|
128
|
+
- `FocusTrap` (npm: `focus-trap-react`) — ловушка фокуса для desktop
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
## Stories
|
|
133
|
+
|
|
134
|
+
`stories/HelpBox/HelpBox.stories.tsx`
|
|
135
|
+
Файлы примеров: `stories/HelpBox/examples/`
|
|
136
|
+
|
|
137
|
+
| Story | Example file | Что демонстрирует |
|
|
138
|
+
|---|---|---|
|
|
139
|
+
| `Playground` | — | Интерактивный контроль всех props (inline в `*.stories.tsx`) |
|
|
140
|
+
| `Default` | `DefaultExample.tsx` | Минимальное использование |
|
|
141
|
+
| `Sizes` | `SizesExample.tsx` | Размеры тултипа SM / LG |
|
|
142
|
+
| `Placement` | `PlacementExample.tsx` | Расположение: above, below, left, right |
|
|
143
|
+
| `WithMobileHeader` | `WithMobileHeaderExample.tsx` | Мобильный заголовок |
|
|
144
|
+
| `Controlled` | `ControlledExample.tsx` | Управляемое состояние (isOpen + toggle) |
|
|
145
|
+
| `ChangeIconProps` | `ChangeIconPropsExample.tsx` | Кастомизация иконки через iconProps |
|
|
146
|
+
| `VisualTests` | — | Скриншот-тест с открытым тултипом (inline в `*.stories.tsx`) |
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
## История изменений
|
|
151
|
+
|
|
152
|
+
| Дата | Изменение |
|
|
153
|
+
|---|---|
|
|
154
|
+
| 2026-04-08 | Создан документ. Добавлен `forwardRef`. |
|