@sberbusiness/triplex-next-mcp-server 1.44.0-beta → 1.46.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/README.md +7 -6
- package/bundle/components/AlertContext.md +11 -8
- package/bundle/components/AlertProcess.md +13 -10
- package/bundle/components/Badge.md +6 -3
- package/bundle/components/Button.md +46 -43
- package/bundle/components/ButtonDropdownExtended.md +3 -2
- package/bundle/components/ButtonIcon.md +7 -4
- package/bundle/components/Calendar.md +62 -59
- package/bundle/components/Caption.md +26 -23
- package/bundle/components/CardAction.md +615 -0
- package/bundle/components/Checkbox.md +32 -29
- package/bundle/components/CheckboxTreeExtended.md +9 -5
- package/bundle/components/Chip.md +51 -47
- package/bundle/components/ChipMonthYearPicker.md +344 -0
- package/bundle/components/ChipMultiselect.md +1251 -0
- package/bundle/components/ChipOptions.md +329 -0
- package/bundle/components/ChipSort.md +333 -0
- package/bundle/components/ChipSuggest.md +587 -0
- package/bundle/components/CodeText.md +26 -23
- package/bundle/components/Col.md +1 -2
- package/bundle/components/CollapsibleTree.md +8 -5
- package/bundle/components/DateField.md +222 -303
- package/bundle/components/DatePickerExtended.md +3 -1
- package/bundle/components/Dropdown.md +33 -28
- package/bundle/components/EmptyView.md +12 -5
- package/bundle/components/FooterPage.md +6 -2
- package/bundle/components/FormField.md +47 -42
- package/bundle/components/FormGroup.md +192 -52
- package/bundle/components/Header.md +491 -211
- package/bundle/components/HeaderPage.md +6 -2
- package/bundle/components/HelpBox.md +7 -1
- package/bundle/components/ImageGallery.md +33 -34
- package/bundle/components/ImageGalleryExtended.md +33 -34
- package/bundle/components/Island.md +16 -13
- package/bundle/components/IslandAccordion.md +443 -152
- package/bundle/components/IslandWidget.md +622 -157
- package/bundle/components/LightBox.md +14 -12
- package/bundle/components/Link.md +211 -96
- package/bundle/components/ListActionItem.md +7 -4
- package/bundle/components/ListItem.md +11 -8
- package/bundle/components/ListItemControlsButton.md +16 -13
- package/bundle/components/ListItemControlsButtonDropdown.md +9 -6
- package/bundle/components/ListItemSelectable.md +7 -4
- package/bundle/components/ListMasterFooter.md +8 -5
- package/bundle/components/ListMasterHeader.md +8 -5
- package/bundle/components/ListSortableItem.md +11 -8
- package/bundle/components/ListTableItem.md +7 -4
- package/bundle/components/LoaderMiddle.md +7 -4
- package/bundle/components/LoaderScreen.md +11 -8
- package/bundle/components/LoaderSmall.md +7 -4
- package/bundle/components/Marker.md +184 -69
- package/bundle/components/MarkerStatus.md +206 -88
- package/bundle/components/MaskedField.md +4 -5
- package/bundle/components/MasterTable.md +602 -0
- package/bundle/components/ModalWindow.md +7 -4
- package/bundle/components/MonthYearField.md +3 -1
- package/bundle/components/MultiselectField.md +2183 -132
- package/bundle/components/Notification.md +12 -9
- package/bundle/components/Overlay.md +9 -4
- package/bundle/components/Page.md +2 -2
- package/bundle/components/Pagination.md +15 -8
- package/bundle/components/Row.md +1 -1
- package/bundle/components/SelectExtendedField.md +3 -3
- package/bundle/components/SelectField.md +466 -148
- package/bundle/components/SliderExtended.md +39 -36
- package/bundle/components/SmallInput.md +194 -51
- package/bundle/components/Suggest.md +535 -99
- package/bundle/components/SwipeableArea.md +428 -79
- package/bundle/components/TableBasic.md +19 -11
- package/bundle/components/TabsExtended.md +24 -21
- package/bundle/components/Tag.md +6 -2
- package/bundle/components/Text.md +28 -25
- package/bundle/components/TextField.md +3 -4
- package/bundle/components/ThemeProvider.md +50 -1
- package/bundle/components/Title.md +26 -23
- package/bundle/components/Tooltip.md +24 -21
- package/bundle/components/TopOverlay.md +7 -4
- package/bundle/guides/codestyle.md +3 -0
- package/bundle/guides/context.md +84 -12
- package/bundle/guides/guidelines.md +321 -0
- package/bundle/guides/template.md +22 -12
- package/bundle/manifest.json +75 -17
- package/bundle/release-notes/1.45.0.mdx +117 -0
- package/bundle/release-notes/1.46.0.mdx +66 -0
- package/bundle/release-notes/1.47.0.mdx +7 -0
- package/bundle/tokens.json +6362 -0
- package/dist/index.js +177 -28
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
component: DatePickerExtended
|
|
3
3
|
category: Date components
|
|
4
|
-
related: [Calendar, Dropdown, DateField, MonthYearField, ChipDatePicker]
|
|
4
|
+
related: [Calendar, Dropdown, DateField, MonthYearField, ChipDatePicker, ChipMonthYearPicker]
|
|
5
5
|
tokens: []
|
|
6
6
|
stories: stories/DatePickerExtended/DatePickerExtended.stories.tsx
|
|
7
7
|
version: "1.0"
|
|
@@ -97,6 +97,7 @@ version: "1.0"
|
|
|
97
97
|
- `DateField` — поле ввода даты; передаёт `dropdownTargetRef` и открывает календарь из `DateFieldTarget` через контекст.
|
|
98
98
|
- `MonthYearField` — выбор месяца и года; конфигурирует `pickType={ECalendarPickType.MONTH_YEAR}`.
|
|
99
99
|
- `ChipDatePicker` — чип-фильтр с календарём; открывает дропдаун из `ChipDatePickerTarget` через контекст.
|
|
100
|
+
- `ChipMonthYearPicker` — чип-фильтр с выбором месяца (`pickType` фиксирован в `MONTH_YEAR`); открывает дропдаун из `ChipMonthYearPickerTarget` через контекст.
|
|
100
101
|
- `DatePickerExtendedContext` — контекст открытости дропдауна для целевого элемента. Экспортируется из barrel вместе с типом `IDatePickerExtendedContext`, отдельного AI.md не имеет.
|
|
101
102
|
|
|
102
103
|
Внутренние части (в barrel не экспортируются, отдельного AI.md не имеют):
|
|
@@ -130,6 +131,7 @@ version: "1.0"
|
|
|
130
131
|
|
|
131
132
|
| Дата | Изменение |
|
|
132
133
|
|---|---|
|
|
134
|
+
| 2026-09-07 | В потребители базы добавлен `ChipMonthYearPicker` (чип-фильтр с `pickType` `MONTH_YEAR`) |
|
|
133
135
|
| 2026-08-24 | `DatePickerExtendedContext` и `IDatePickerExtendedContext` экспортируются из barrel — целевой элемент можно написать снаружи библиотеки. `adaptiveMode` исключён из `IDatePickerExtendedProps` (ломающее изменение, затрагивает также `DateField`, `MonthYearField`, `ChipDatePicker`) |
|
|
134
136
|
| 2026-08-20 | Создан документ. AI-рефакторинг, unit-тесты (`__tests__/DatePickerExtended.test.tsx`), stories по modern pattern. Исправлено: `yesterdayButtonProps` / `tomorrowButtonProps` пробрасываются в `Calendar`, `adaptiveMode` больше не попадает в DOM |
|
|
135
137
|
|
|
@@ -3,19 +3,21 @@ component: Dropdown
|
|
|
3
3
|
category: Dropdown
|
|
4
4
|
related: [ButtonDropdown, ButtonDropdownExtended, Portal, MobileView, OverlayBase, SelectField, SelectExtendedField, SuggestField, MultiselectField, TabsLine]
|
|
5
5
|
tokens:
|
|
6
|
-
-
|
|
7
|
-
-
|
|
8
|
-
-
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
-
|
|
18
|
-
-
|
|
6
|
+
- Dropdown.Background
|
|
7
|
+
- Dropdown.Shadow
|
|
8
|
+
- DropdownList.Color
|
|
9
|
+
- DropdownList.Background_Default
|
|
10
|
+
- DropdownList.Background_Active
|
|
11
|
+
- DropdownList.Background_Selected
|
|
12
|
+
- DropdownMobile.Backdrop
|
|
13
|
+
- DropdownMobile.Header_Background
|
|
14
|
+
- DropdownMobile.Content_Background
|
|
15
|
+
- DropdownMobile.Footer_Background
|
|
16
|
+
- DropdownMobile.Border_Color
|
|
17
|
+
- DropdownMobileList.Active_Background
|
|
18
|
+
- DropdownMobileList.Selected_Background
|
|
19
|
+
- FormField.Input_Color_Default
|
|
20
|
+
- FormField.Placeholder_Color
|
|
19
21
|
stories: stories/Dropdown/Dropdown.stories.tsx
|
|
20
22
|
version: "1.0"
|
|
21
23
|
---
|
|
@@ -92,23 +94,26 @@ version: "1.0"
|
|
|
92
94
|
|
|
93
95
|
## Дизайн-токены
|
|
94
96
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
97
|
+
Переопределяются через `ThemeProvider` (prop `tokens`) — см. `ThemeProvider-ai.md` →
|
|
98
|
+
«Как переопределять токены». Значения по умолчанию — файлы групп `Dropdown`, `DropdownList`, `DropdownMobile`, `DropdownMobileList` в `src/components/DesignTokens/components/`.
|
|
99
|
+
|
|
100
|
+
```text
|
|
101
|
+
Dropdown.Background
|
|
102
|
+
Dropdown.Shadow
|
|
103
|
+
DropdownList.Color
|
|
104
|
+
DropdownList.Background_Default
|
|
105
|
+
DropdownList.Background_Active
|
|
106
|
+
DropdownList.Background_Selected
|
|
107
|
+
DropdownMobile.Backdrop
|
|
108
|
+
DropdownMobile.Header_Background
|
|
109
|
+
DropdownMobile.Content_Background
|
|
110
|
+
DropdownMobile.Footer_Background
|
|
111
|
+
DropdownMobile.Border_Color
|
|
112
|
+
DropdownMobileList.Active_Background
|
|
113
|
+
DropdownMobileList.Selected_Background
|
|
109
114
|
```
|
|
110
115
|
|
|
111
|
-
`DropdownMobileInput` дополнительно использует токены поля ввода:
|
|
116
|
+
`DropdownMobileInput` дополнительно использует токены поля ввода: `FormField.Input_Color_Default`, `FormField.Placeholder_Color`.
|
|
112
117
|
|
|
113
118
|
---
|
|
114
119
|
|
|
@@ -3,8 +3,8 @@ component: EmptyView
|
|
|
3
3
|
category: Feedback
|
|
4
4
|
related: [Button]
|
|
5
5
|
tokens:
|
|
6
|
-
-
|
|
7
|
-
-
|
|
6
|
+
- Typography.Primary_Color
|
|
7
|
+
- Typography.Secondary_Color
|
|
8
8
|
stories: stories/EmptyView/EmptyView.stories.tsx
|
|
9
9
|
version: "1.0"
|
|
10
10
|
---
|
|
@@ -47,10 +47,16 @@ version: "1.0"
|
|
|
47
47
|
|
|
48
48
|
## Дизайн-токены
|
|
49
49
|
|
|
50
|
+
Переопределяются через `ThemeProvider` (prop `tokens`) — см. `ThemeProvider-ai.md` →
|
|
51
|
+
«Как переопределять токены». Значения по умолчанию — `src/components/DesignTokens/components/Typography.ts`.
|
|
52
|
+
|
|
53
|
+
```text
|
|
54
|
+
Typography.Primary_Color (title, description без title)
|
|
55
|
+
Typography.Secondary_Color (description с title, caption)
|
|
50
56
|
```
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
57
|
+
|
|
58
|
+
Собственных токенов у компонента нет: цвета приходят от вложенных `Title` и `Text`,
|
|
59
|
+
в `styles/EmptyView.module.less` заданы только отступы и выравнивание.
|
|
54
60
|
|
|
55
61
|
---
|
|
56
62
|
|
|
@@ -96,6 +102,7 @@ version: "1.0"
|
|
|
96
102
|
|---|---|
|
|
97
103
|
| 2026-04-09 | Создан компонент и документ. |
|
|
98
104
|
| 2026-04-27 | Приведён в соответствие с `docs/ai/template-ai.md`: добавлена колонка `Example file`, переименована подсекция «Поведение описания» в «Ограничения по темам». |
|
|
105
|
+
| 2026-08-31 | Заголовок всегда рендерится как `Title` с `ETitleSize.H3` и `EFontWeightTitle.MEDIUM`: убран `TITLE_CONFIG`, типографика `title` больше не зависит от `size`. |
|
|
99
106
|
|
|
100
107
|
---
|
|
101
108
|
|
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
component: FooterPage
|
|
3
3
|
category: Page
|
|
4
4
|
related: [Page, HeaderPage, BodyPage, Footer, Island, LightBox]
|
|
5
|
-
tokens:
|
|
5
|
+
tokens:
|
|
6
|
+
- FooterPage.StickyShadow
|
|
6
7
|
stories: stories/Page/FooterPage/FooterPage.stories.tsx
|
|
7
8
|
version: "1.0"
|
|
8
9
|
---
|
|
@@ -51,9 +52,12 @@ version: "1.0"
|
|
|
51
52
|
|
|
52
53
|
## Дизайн-токены
|
|
53
54
|
|
|
55
|
+
Переопределяются через `ThemeProvider` (prop `tokens`) — см. `ThemeProvider-ai.md` →
|
|
56
|
+
«Как переопределять токены». Значения по умолчанию — `src/components/DesignTokens/components/FooterPage.ts`.
|
|
57
|
+
|
|
54
58
|
| Токен | Назначение |
|
|
55
59
|
|---|---|
|
|
56
|
-
|
|
|
60
|
+
| `FooterPage.StickyShadow` | Тень прилипшего футера (когда `sticky` и футер коснулся нижней границы, `data-stuck="true"`). |
|
|
57
61
|
|
|
58
62
|
Внешний вид карточки наследуется от `Island` (`EIslandType.TYPE_1`). Радиус нижних углов при
|
|
59
63
|
прилипании плавно обнуляется через CSS-переменную `--r-bottom` (управляется хуком
|
|
@@ -3,26 +3,26 @@ component: FormField
|
|
|
3
3
|
category: FormField
|
|
4
4
|
related: [FormFieldLabel, FormFieldInput, FormFieldTextarea, FormFieldTarget, FormFieldMaskedInput, FormFieldPrefix, FormFieldPostfix, FormFieldClear, FormFieldDescription, FormFieldCounter, FormGroup, TextField, TextareaField, MaskedField, SelectField, SuggestField, DateField]
|
|
5
5
|
tokens:
|
|
6
|
-
-
|
|
7
|
-
-
|
|
8
|
-
-
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
-
|
|
18
|
-
-
|
|
19
|
-
-
|
|
20
|
-
-
|
|
21
|
-
-
|
|
22
|
-
-
|
|
23
|
-
-
|
|
24
|
-
-
|
|
25
|
-
-
|
|
6
|
+
- FormField.Background_Default
|
|
7
|
+
- FormField.Background_Hover
|
|
8
|
+
- FormField.Background_Active
|
|
9
|
+
- FormField.Background_Disabled
|
|
10
|
+
- FormField.Background_Error
|
|
11
|
+
- FormField.Background_Error_Hover
|
|
12
|
+
- FormField.Background_Warning
|
|
13
|
+
- FormField.Background_Warning_Hover
|
|
14
|
+
- FormField.Shadow_Default
|
|
15
|
+
- FormField.Shadow_Active
|
|
16
|
+
- FormField.Shadow_Error_Active
|
|
17
|
+
- FormField.Shadow_Warning_Active
|
|
18
|
+
- FormField.Input_Color_Default
|
|
19
|
+
- FormField.Input_Color_Disabled
|
|
20
|
+
- FormField.Label_Color_Default
|
|
21
|
+
- FormField.Label_Color_Disabled
|
|
22
|
+
- FormField.Placeholder_Color
|
|
23
|
+
- FormField.Target_Color_Default
|
|
24
|
+
- FormField.Target_Color_Disabled
|
|
25
|
+
- FormField.Target_PlaceholderColor_Default
|
|
26
26
|
stories: stories/FormField/FormField.stories.tsx
|
|
27
27
|
version: "1.0"
|
|
28
28
|
---
|
|
@@ -69,27 +69,30 @@ version: "1.0"
|
|
|
69
69
|
|
|
70
70
|
## Дизайн-токены
|
|
71
71
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
72
|
+
Переопределяются через `ThemeProvider` (prop `tokens`) — см. `ThemeProvider-ai.md` →
|
|
73
|
+
«Как переопределять токены». Значения по умолчанию — `src/components/DesignTokens/components/FormField.ts`.
|
|
74
|
+
|
|
75
|
+
```text
|
|
76
|
+
FormField.Background_Default
|
|
77
|
+
FormField.Background_Hover
|
|
78
|
+
FormField.Background_Active
|
|
79
|
+
FormField.Background_Disabled
|
|
80
|
+
FormField.Background_Error
|
|
81
|
+
FormField.Background_Error_Hover
|
|
82
|
+
FormField.Background_Warning
|
|
83
|
+
FormField.Background_Warning_Hover
|
|
84
|
+
FormField.Shadow_Default
|
|
85
|
+
FormField.Shadow_Active
|
|
86
|
+
FormField.Shadow_Error_Active
|
|
87
|
+
FormField.Shadow_Warning_Active
|
|
88
|
+
FormField.Input_Color_Default
|
|
89
|
+
FormField.Input_Color_Disabled
|
|
90
|
+
FormField.Label_Color_Default
|
|
91
|
+
FormField.Label_Color_Disabled
|
|
92
|
+
FormField.Placeholder_Color
|
|
93
|
+
FormField.Target_Color_Default
|
|
94
|
+
FormField.Target_Color_Disabled
|
|
95
|
+
FormField.Target_PlaceholderColor_Default
|
|
93
96
|
```
|
|
94
97
|
|
|
95
98
|
---
|
|
@@ -123,7 +126,7 @@ version: "1.0"
|
|
|
123
126
|
|
|
124
127
|
- `FormFieldLabel` — плавающий лейбл; поднимается над полем, когда поле заполнено или активно (можно форсировать props `floating`).
|
|
125
128
|
- `FormFieldInput` — однострочный ввод; поддерживает render-prop `render` для подмены инпута с сохранением стилизации.
|
|
126
|
-
- `FormFieldTextarea` — многострочный ввод.
|
|
129
|
+
- `FormFieldTextarea` — многострочный ввод. Высота по размеру задана как `min-height`.
|
|
127
130
|
- `FormFieldMaskedInput` — маскированный ввод на базе `react-text-mask`; содержит пресеты масок (`FormFieldMaskedInput.presets`).
|
|
128
131
|
- `FormFieldTarget` — нередактируемое значение с `placeholder`, используется select-подобными полями.
|
|
129
132
|
- `FormFieldPrefix` / `FormFieldPostfix` — контейнеры слева/справа; их измеренная ширина становится внутренним отступом поля. Общая логика измерения и проброса ref вынесена во внутренний хук `components/useFormFieldAffixWidth.ts` (в barrel не экспортируется).
|
|
@@ -163,6 +166,8 @@ version: "1.0"
|
|
|
163
166
|
| 2026-07-31 | AI-рефакторинг распространён на субкомпоненты `FormFieldInput`, `FormFieldLabel`, `FormFieldPrefix`, `FormFieldPostfix`, `FormFieldClear`, `FormFieldDescription`, `FormFieldCounter`: JSDoc с указанием значений по умолчанию, дедупликация `FormFieldPrefix` / `FormFieldPostfix` через внутренний хук `useFormFieldAffixWidth`, общий `setForwardedRef` в `components/utils.ts`, unit-тесты. Публичный API не изменён. `FormFieldTextarea`, `FormFieldTarget` и `FormFieldMaskedInput` намеренно не затронуты — их покрывают задачи `TextareaField`, `SelectField` и `MaskedField`. |
|
|
164
167
|
| 2026-07-31 | Исправлено: `className` у `FormFieldDescription` и `FormFieldCounter` затирал базовый класс — теперь объединяется через `clsx`. Изменение наблюдаемого поведения, зафиксировано в release notes 1.41.0. |
|
|
165
168
|
| 2026-08-03 | Ломающее изменение: `statusToClassNameMap` убран из публичного barrel и переименован во внутреннюю константу `STATUS_TO_CLASS_NAME_MAP`. Зафиксировано в release notes 1.41.0. |
|
|
169
|
+
| 2026-09-04 | Исправлено: у `FormFieldTextarea` фиксированная `height` для размеров `sm` / `md` / `lg` заменена на `min-height`. |
|
|
170
|
+
| 2026-09-09 | Исправлено: значение с кодом страны раскладывалось по маске телефона со сдвигом и теряло последнюю цифру. Нормализация номера вынесена в `normalizePhoneText` и применяется и к внешнему `value`, и к слою с маской |
|
|
166
171
|
|
|
167
172
|
---
|
|
168
173
|
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
---
|
|
2
2
|
component: FormGroup
|
|
3
|
-
category:
|
|
4
|
-
|
|
5
|
-
figma-file: ""
|
|
6
|
-
related: [FormField, TextField, SelectField, HelpBox, Alert]
|
|
3
|
+
category: FormField
|
|
4
|
+
related: [FormField, TextField, MaskedField]
|
|
7
5
|
tokens: []
|
|
8
|
-
stories:
|
|
6
|
+
stories: stories/FormGroup/FormGroup.stories.tsx
|
|
9
7
|
version: "1.0"
|
|
10
8
|
---
|
|
11
9
|
|
|
@@ -13,87 +11,229 @@ version: "1.0"
|
|
|
13
11
|
|
|
14
12
|
## Назначение
|
|
15
13
|
|
|
16
|
-
|
|
17
|
-
`
|
|
18
|
-
|
|
19
|
-
точка в DOM для data-атрибутов и семантики формы.
|
|
14
|
+
Контейнер формы: объединяет поле ввода с относящимися к нему элементами — `FormField`,
|
|
15
|
+
`FormFieldDescription`, `HelpBox`, `AlertContext` — в один блок. Части передаются декларативно
|
|
16
|
+
через `children`, поэтому каждой можно задать свои props и data-атрибуты.
|
|
20
17
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
18
|
+
Рендерит один `div` без собственных классов, стилей и отступов: расстояния между частями
|
|
19
|
+
задают сами части (`FormFieldDescription`, `Gap`), а не группа.
|
|
20
|
+
|
|
21
|
+
Используй когда: поле нужно показать вместе с описанием, счётчиком, текстом ошибки,
|
|
22
|
+
подсказкой или сообщением `AlertContext`, и эти элементы должны читаться как одна логическая
|
|
23
|
+
группа формы.
|
|
24
|
+
Не используй когда: достаточно готовой обёртки над полем — `TextField`, `TextareaField`,
|
|
25
|
+
`MaskedField`, `AmountField` уже собирают `FormGroup` + `FormField` внутри себя, и снаружи
|
|
26
|
+
их в `FormGroup` заворачивать не нужно.
|
|
24
27
|
|
|
25
28
|
---
|
|
26
29
|
|
|
27
|
-
##
|
|
30
|
+
## Варианты и props
|
|
28
31
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
```
|
|
32
|
+
Настраиваемых props у компонента нет: он принимает `children` и стандартные атрибуты `div`.
|
|
33
|
+
Внутренний `IFormGroupProps` расширяет `React.HTMLAttributes<HTMLDivElement>`:
|
|
34
|
+
все стандартные атрибуты `div` (включая `className`, `style`, `id`, `role`, `aria-*`, `data-*`
|
|
35
|
+
и обработчики событий) уходят через `...rest` на корневой элемент.
|
|
34
36
|
|
|
35
|
-
|
|
36
|
-
stories типовых полей, где `FormGroup` иногда обёрнут вокруг формы.
|
|
37
|
+
### Опциональные props
|
|
37
38
|
|
|
38
|
-
|
|
39
|
+
| Prop | Тип | По умолчанию | Описание |
|
|
40
|
+
| ---------- | ----------------- | ------------ | -------------------------------------------------------------------------- |
|
|
41
|
+
| `children` | `React.ReactNode` | — | Части группы: поле ввода и относящиеся к нему подсказки и сообщения. |
|
|
39
42
|
|
|
40
|
-
|
|
43
|
+
Поскольку настраиваемых props нет, у компонента нет story `Playground`.
|
|
41
44
|
|
|
42
|
-
|
|
45
|
+
---
|
|
43
46
|
|
|
44
|
-
|
|
45
|
-
|---|---|---|
|
|
46
|
-
| `children` | `ReactNode` | Обычно несколько `FormField`/`Alert`/`HelpBox`. |
|
|
47
|
-
| `className`, `style`, `...HTMLDivAttributes` | — | Стандартные. |
|
|
47
|
+
## Дизайн-токены
|
|
48
48
|
|
|
49
|
-
|
|
50
|
-
|
|
49
|
+
Собственных CSS-переменных нет — у компонента нет файла стилей. Внешний вид группы
|
|
50
|
+
целиком определяют вложенные компоненты.
|
|
51
51
|
|
|
52
52
|
---
|
|
53
53
|
|
|
54
54
|
## Инварианты
|
|
55
55
|
|
|
56
|
-
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
56
|
+
- `forwardRef<HTMLDivElement>` — не убирать. Ref указывает на корневой `div` — тот же
|
|
57
|
+
элемент, который получает `className` и `...rest`.
|
|
58
|
+
- Корневой элемент — ровно один `div`, а `children` рендерятся в него напрямую, без
|
|
59
|
+
промежуточных обёрток. Уровень вложенности виден потребителям в DOM и в их CSS-селекторах,
|
|
60
|
+
поэтому добавление обёртки — наблюдаемое изменение и требует записи в release notes.
|
|
61
|
+
- Компонент не задаёт собственных классов и отступов. Появление здесь `margin`/`gap`
|
|
62
|
+
сдвинет вёрстку всех форм в библиотеке и у потребителей: `FormGroup` используется внутри
|
|
63
|
+
`TextFieldBase` (а через него — во всех полях, построенных на нём: `TextField`,
|
|
64
|
+
`MaskedField`, `TextareaField`, `AmountField`, `NumberField`, `SuggestField`) и в
|
|
65
|
+
`SMSFieldInput`.
|
|
66
|
+
- `displayName = "FormGroup"` — не менять.
|
|
67
|
+
- Экспорт `FormGroup` идёт в barrel `src/components/FormGroup/index.ts` и далее в корневой
|
|
68
|
+
`src/components/index.ts` — сохранять. `IFormGroupProps` наружу не экспортируется; добавление
|
|
69
|
+
этого экспорта — расширение публичного API, отдельное решение владельца.
|
|
61
70
|
|
|
62
71
|
---
|
|
63
72
|
|
|
64
73
|
## Accessibility
|
|
65
74
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
- Fieldset-семантика (`<fieldset>` + `<legend>`) не используется;
|
|
70
|
-
FormGroup не пытается её эмулировать.
|
|
71
|
-
|
|
72
|
-
---
|
|
73
|
-
|
|
74
|
-
## Дизайн-токены
|
|
75
|
+
Собственного a11y-поведения нет: это структурный контейнер без роли и без интерактивности.
|
|
76
|
+
Семантику задаёт потребитель через проброшенные атрибуты — например `role="group"` вместе с
|
|
77
|
+
`aria-labelledby`, если группа должна объявляться скринридером как единое целое.
|
|
75
78
|
|
|
76
|
-
|
|
79
|
+
Лейбл связывается с полем внутри `FormField`: `FormFieldLabel` берёт `htmlFor` из `targetId`
|
|
80
|
+
в `FormFieldContext`. Описание автоматически не связывается — `aria-describedby` на элементе
|
|
81
|
+
ввода (как и `aria-invalid` для ошибки) задаёт потребитель, см. `FormField-ai.md`. `FormGroup`
|
|
82
|
+
не участвует ни в том, ни в другом.
|
|
77
83
|
|
|
78
84
|
---
|
|
79
85
|
|
|
80
86
|
## Связанные компоненты
|
|
81
87
|
|
|
82
|
-
- `FormField` — основной
|
|
83
|
-
|
|
84
|
-
- `
|
|
88
|
+
- `FormField` — само поле ввода; основной ребёнок группы. О `FormGroup` не знает и на нём
|
|
89
|
+
не построен: это `FormField` кладут внутрь группы, а не наоборот.
|
|
90
|
+
- `FormFieldDescription` (часть семейства `FormField`) — описание, текст ошибки и счётчик
|
|
91
|
+
под полем; второй типичный ребёнок группы, отступ от поля задаёт сам (`padding-top`).
|
|
92
|
+
- `TextField`, `MaskedField` — готовые однострочные поля; компактная альтернатива ручной
|
|
93
|
+
сборке `FormGroup` + `FormField`. Внутри они уже используют `FormGroup` (через
|
|
94
|
+
`TextFieldBase`), поэтому оборачивать их в него ещё раз не нужно.
|
|
95
|
+
- `HelpBox`, `AlertContext` — подсказка и сообщение, которые кладут в группу рядом с полем.
|
|
85
96
|
|
|
86
97
|
---
|
|
87
98
|
|
|
88
99
|
## Stories
|
|
89
100
|
|
|
90
|
-
|
|
91
|
-
|
|
101
|
+
Основные истории: `stories/FormGroup/FormGroup.stories.tsx`
|
|
102
|
+
Файлы примеров: `stories/FormGroup/examples/`
|
|
103
|
+
|
|
104
|
+
| Story | Example file | Что демонстрирует |
|
|
105
|
+
| ------------- | ----------------- | ------------------------------------------------------------------------------------- |
|
|
106
|
+
| `Default` | `Default.tsx` | Минимальная группа: поле с лейблом и описанием под ним |
|
|
107
|
+
| `Example` | `Example.tsx` | Production-like форма: поле с описанием и поле с ошибкой плюс `AlertContext` в группе |
|
|
108
|
+
| `VisualTests` | `VisualTests.tsx` | Варианты наполнения: только поле, поле с описанием, ошибка, группа с `AlertContext`, поле с `HelpBox` |
|
|
109
|
+
|
|
110
|
+
### Почему stories участвуют в скриншот-тестах
|
|
111
|
+
|
|
112
|
+
Своей разметки у `FormGroup` нет, поэтому baseline'ы (`__screenshots__/formgroup--*`)
|
|
113
|
+
фиксируют не саму группу, а композицию её частей: `FormField`, `FormFieldDescription`,
|
|
114
|
+
`AlertContext`, `HelpBox`. Формально это близко к случаю «компонент без визуального
|
|
115
|
+
интерфейса» из `stories-guide.md` § «Скриншот-тесты», где набор исключают целиком через
|
|
116
|
+
`testRunner: { skip: true }`. Здесь решено baseline'ы держать: они страхуют типовые
|
|
117
|
+
композиции форм, которые потребители копируют из примеров. Обратная сторона — перекраска
|
|
118
|
+
`FormField` или `AlertContext` роняет визуальные тесты `FormGroup` и требует перегенерации;
|
|
119
|
+
это ожидаемо, а не регрессия группы. Отсутствие лишней обёртки вокруг `children` проверяет
|
|
120
|
+
unit-тест, а не скриншот.
|
|
92
121
|
|
|
93
122
|
---
|
|
94
123
|
|
|
95
124
|
## История изменений
|
|
96
125
|
|
|
97
|
-
| Дата
|
|
98
|
-
|
|
99
|
-
| 2026-
|
|
126
|
+
| Дата | Изменение |
|
|
127
|
+
| ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
128
|
+
| 2026-08-28 | Создан документ. AI-рефакторинг (уточнён JSDoc компонента, `children` задокументирован явно), добавлены unit-тесты и stories в modern pattern. Публичный API не менялся. |
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
## Примеры использования
|
|
133
|
+
|
|
134
|
+
### Default
|
|
135
|
+
|
|
136
|
+
`stories/FormGroup/examples/Default.tsx`
|
|
137
|
+
|
|
138
|
+
```tsx
|
|
139
|
+
import React, { useState } from "react";
|
|
140
|
+
import {
|
|
141
|
+
EFontType,
|
|
142
|
+
ETextSize,
|
|
143
|
+
FormField,
|
|
144
|
+
FormFieldDescription,
|
|
145
|
+
FormFieldInput,
|
|
146
|
+
FormFieldLabel,
|
|
147
|
+
FormGroup,
|
|
148
|
+
Text,
|
|
149
|
+
} from "@sberbusiness/triplex-next";
|
|
150
|
+
|
|
151
|
+
export const Default = () => {
|
|
152
|
+
const [value, setValue] = useState("");
|
|
153
|
+
|
|
154
|
+
return (
|
|
155
|
+
<div style={{ maxWidth: "300px" }}>
|
|
156
|
+
<FormGroup>
|
|
157
|
+
<FormField>
|
|
158
|
+
<FormFieldLabel>Название поля</FormFieldLabel>
|
|
159
|
+
<FormFieldInput value={value} onChange={(event) => setValue(event.target.value)} />
|
|
160
|
+
</FormField>
|
|
161
|
+
<FormFieldDescription>
|
|
162
|
+
<Text tag="div" size={ETextSize.B4} type={EFontType.SECONDARY}>
|
|
163
|
+
Описание поля
|
|
164
|
+
</Text>
|
|
165
|
+
</FormFieldDescription>
|
|
166
|
+
</FormGroup>
|
|
167
|
+
</div>
|
|
168
|
+
);
|
|
169
|
+
};
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### Example
|
|
173
|
+
|
|
174
|
+
`stories/FormGroup/examples/Example.tsx`
|
|
175
|
+
|
|
176
|
+
```tsx
|
|
177
|
+
import React, { useState } from "react";
|
|
178
|
+
import {
|
|
179
|
+
AlertContext,
|
|
180
|
+
EAlertType,
|
|
181
|
+
EFontType,
|
|
182
|
+
EFormFieldStatus,
|
|
183
|
+
ETextSize,
|
|
184
|
+
FormField,
|
|
185
|
+
FormFieldDescription,
|
|
186
|
+
FormFieldInput,
|
|
187
|
+
FormFieldLabel,
|
|
188
|
+
FormGroup,
|
|
189
|
+
Gap,
|
|
190
|
+
Text,
|
|
191
|
+
} from "@sberbusiness/triplex-next";
|
|
192
|
+
|
|
193
|
+
export const Example = () => {
|
|
194
|
+
const [account, setAccount] = useState("40702810400000012345");
|
|
195
|
+
const [amount, setAmount] = useState("");
|
|
196
|
+
|
|
197
|
+
return (
|
|
198
|
+
<div style={{ maxWidth: "360px" }}>
|
|
199
|
+
<FormGroup>
|
|
200
|
+
<FormField>
|
|
201
|
+
<FormFieldLabel>Счёт списания</FormFieldLabel>
|
|
202
|
+
<FormFieldInput value={account} onChange={(event) => setAccount(event.target.value)} />
|
|
203
|
+
</FormField>
|
|
204
|
+
<FormFieldDescription>
|
|
205
|
+
<Text tag="div" size={ETextSize.B4} type={EFontType.SECONDARY}>
|
|
206
|
+
Доступно 125 000,00 ₽
|
|
207
|
+
</Text>
|
|
208
|
+
</FormFieldDescription>
|
|
209
|
+
</FormGroup>
|
|
210
|
+
|
|
211
|
+
<Gap size={24} />
|
|
212
|
+
|
|
213
|
+
<FormGroup>
|
|
214
|
+
<FormField status={EFormFieldStatus.ERROR}>
|
|
215
|
+
<FormFieldLabel>Сумма платежа</FormFieldLabel>
|
|
216
|
+
<FormFieldInput
|
|
217
|
+
value={amount}
|
|
218
|
+
onChange={(event) => setAmount(event.target.value)}
|
|
219
|
+
aria-invalid
|
|
220
|
+
aria-describedby="amount-error"
|
|
221
|
+
/>
|
|
222
|
+
</FormField>
|
|
223
|
+
<FormFieldDescription id="amount-error">
|
|
224
|
+
<Text tag="div" size={ETextSize.B4} type={EFontType.ERROR}>
|
|
225
|
+
Укажите сумму платежа
|
|
226
|
+
</Text>
|
|
227
|
+
</FormFieldDescription>
|
|
228
|
+
|
|
229
|
+
<Gap size={8} />
|
|
230
|
+
|
|
231
|
+
<AlertContext type={EAlertType.INFO}>
|
|
232
|
+
Платёж на сумму более 150 000 ₽ уходит в банк на подтверждение.
|
|
233
|
+
</AlertContext>
|
|
234
|
+
</FormGroup>
|
|
235
|
+
</div>
|
|
236
|
+
);
|
|
237
|
+
};
|
|
238
|
+
```
|
|
239
|
+
|