@sberbusiness/triplex-next-mcp-server 1.46.0-beta → 1.48.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.
Files changed (48) hide show
  1. package/README.md +7 -7
  2. package/bundle/components/AmountField.md +222 -323
  3. package/bundle/components/Avatar.md +138 -146
  4. package/bundle/components/CardStatic.md +402 -0
  5. package/bundle/components/CheckboxTree.md +157 -215
  6. package/bundle/components/CheckboxTreeExtended.md +7 -7
  7. package/bundle/components/ChipGroup.md +1 -1
  8. package/bundle/components/ChipMonthYearPicker.md +4 -4
  9. package/bundle/components/ChipSuggest.md +7 -6
  10. package/bundle/components/CollapsibleTree.md +8 -4
  11. package/bundle/components/CollapsibleTreeExtended.md +8 -6
  12. package/bundle/components/Confirm.md +346 -281
  13. package/bundle/components/DateRange.md +351 -210
  14. package/bundle/components/FooterPage.md +1 -0
  15. package/bundle/components/FormField.md +11 -4
  16. package/bundle/components/FormGroup.md +3 -2
  17. package/bundle/components/LightBox.md +8 -0
  18. package/bundle/components/ListMaster.md +2 -2
  19. package/bundle/components/ListTableItem.md +6 -6
  20. package/bundle/components/MonthYearField.md +15 -4
  21. package/bundle/components/Slider.md +389 -97
  22. package/bundle/components/SliderRange.md +486 -105
  23. package/bundle/components/StatusTracker.md +386 -94
  24. package/bundle/components/Stepper.md +355 -102
  25. package/bundle/components/StepperExtended.md +633 -0
  26. package/bundle/components/SuggestField.md +1049 -96
  27. package/bundle/components/SwipeableArea.md +7 -7
  28. package/bundle/components/Tabs.md +265 -92
  29. package/bundle/components/TabsExtended.md +18 -18
  30. package/bundle/components/TabsLine.md +301 -127
  31. package/bundle/components/TagColor.md +187 -66
  32. package/bundle/components/TagGroup.md +184 -48
  33. package/bundle/components/TextareaField.md +278 -70
  34. package/bundle/components/TopOverlay.md +17 -1
  35. package/bundle/components/TreeView.md +16 -7
  36. package/bundle/components/TriggerClickOnKeyDownEvent.md +277 -0
  37. package/bundle/components/UploadZone.md +318 -0
  38. package/bundle/guides/codestyle.md +16 -1
  39. package/bundle/guides/commits.md +47 -1
  40. package/bundle/guides/tests.md +23 -2
  41. package/bundle/manifest.json +48 -21
  42. package/bundle/release-notes/1.47.0.mdx +115 -0
  43. package/bundle/release-notes/1.48.0.mdx +68 -0
  44. package/bundle/release-notes/1.49.0.mdx +7 -0
  45. package/bundle/tokens.json +3 -3
  46. package/dist/index.js +220 -6
  47. package/dist/index.js.map +1 -1
  48. package/package.json +1 -1
@@ -62,7 +62,7 @@ version: "1.0"
62
62
  - Горизонтальные внутренние отступы корневого `div` задаются инлайн-стилем из ширин префикса и постфикса (`paddingLeft: prefixWidth`, `paddingRight: postfixWidth`). Значение по умолчанию — `TARGET_PADDING_X_DEFAULT` (12px); `FormFieldPrefix` / `FormFieldPostfix` измеряют себя через `ResizeObserver` и обновляют его. Пользовательский `style` мерджится последним и может переопределить отступы.
63
63
  - Класс `filled` выставляется, когда вложенный элемент ввода сообщил о наличии значения. Для `FormFieldInput` / `FormFieldTextarea` это включает браузерное автозаполнение (ловится через CSS-анимационные хуки `autofill-applied-hook` / `autofill-cancelled-hook`), для `FormFieldTarget` — наличие `children`.
64
64
  - Кнопка `FormFieldClear` показывается стилями только при `filled` и hover/активном состоянии непустого и не заблокированного поля, а также при собственном фокусе (`:focus`) — чтобы кнопка оставалась видимой при клавиатурной навигации.
65
- - Идентификаторы генерируются субкомпонентами (`uniqueId` из `lodash-es`, не `React.useId` — код должен оставаться совместимым с React 17) и попадают в контекст как `targetId` / `labelId`; на них опирается связка `label[htmlFor]` ↔ элемент ввода.
65
+ - Идентификаторы генерируются субкомпонентами (`uniqueId` из `lodash-es`, не `React.useId` — код должен оставаться совместимым с React 17) и попадают в контекст как `targetId` / `labelId`; на них опирается связка лейбла и поля. `targetId` публикуют только labelable-элементы (`FormFieldInput`, `FormFieldTextarea`, а также `FormFieldMaskedInput` — он рендерит `FormFieldInput` внутри себя через `render`); `FormFieldTarget` его не публикует — см. Accessibility.
66
66
  - Вне `FormField` субкомпоненты используют `initialFormFieldContext`, где `filled: true` — это осознанный временный фикс для `DropdownMobileHeader`, а сеттеры являются no-op.
67
67
 
68
68
  ---
@@ -104,9 +104,10 @@ FormField.Target_PlaceholderColor_Default
104
104
  - Barrel `src/components/FormField/index.ts` реэкспортирует `enums`, `types`, `components` и сам `FormField` — состав экспортов не сокращать. Маппинг статуса на класс (`STATUS_TO_CLASS_NAME_MAP`) — внутренняя константа модуля и в barrel не входит.
105
105
  - `FormFieldContext` и `FormFieldDescriptionContext` в barrel не входят: это внутренний механизм семейства, но на нём завязаны все субкомпоненты — менять форму значения контекста без правки субкомпонентов нельзя.
106
106
  - Классы `formField`, `filled`, `active`, `error`, `warning`, `disabled`, а также `sm` / `md` / `lg` проверяются unit-тестами и используются в вложенных селекторах стилей семейства.
107
+ - `disabled` исключён из props элементов ввода (`IFormFieldInputProps`, `IFormFieldTextareaProps`, `IFormFieldMaskedInputProps` — через `Omit`): блокировка задаётся только `status={EFormFieldStatus.DISABLED}`, иначе переданное значение молча перетиралось бы внутренним.
107
108
  - Генерация id — через `uniqueId` (`lodash-es`), без `React.useId`: ветка `release-0` собирается на React 17.
108
109
  - `FormFieldDescription` и `FormFieldCounter` объявлены как `React.FC` без `forwardRef` — осознанное историческое отличие от остальных субкомпонентов. Добавление ref расширяет публичный API; решение владельца — оставить как есть.
109
- - Внутренние утилиты семейства (`components/utils.ts` — `isFilled`, `setForwardedRef`; `components/useFormFieldAffixWidth.ts`) намеренно не попадают в barrel `components/index.ts`.
110
+ - Внутренние утилиты семейства (`components/utils.ts` — `isFilled`; `components/useFormFieldAffixWidth.ts`) намеренно не попадают в barrel `components/index.ts`. Общий `setForwardedRef` вынесен в `src/helpers/setForwardedRef.ts` и импортируется относительным путём.
110
111
  - Компонент не рендерит собственных подписей и текстов — библиотека мультиязычная.
111
112
 
112
113
  ---
@@ -114,9 +115,11 @@ FormField.Target_PlaceholderColor_Default
114
115
  ## Accessibility
115
116
 
116
117
  - Корневой элемент — обычный `div` без роли: семантику даёт вложенный нативный `input` / `textarea`.
117
- - Связка лейбла и поля: `FormFieldLabel` получает `htmlFor={targetId}` из контекста, элемент ввода — сгенерированный `id`. Поэтому `screen.getByLabelText(...)` находит поле, а клик по лейблу фокусирует ввод.
118
+ - Связка лейбла и поля: когда в поле есть labelable-элемент, `FormFieldLabel` рендерит `<label htmlFor={targetId}>`, а элемент ввода — сгенерированный `id`. Поэтому `screen.getByLabelText(...)` находит поле.
118
119
  - `FormFieldTarget` (нередактируемое значение, например для select-подобных полей) получает `tabIndex={0}`, `aria-labelledby={labelId}` и `aria-disabled`; при `status = DISABLED` — `tabIndex={-1}`.
119
- - При `status = DISABLED` вложенные `input` / `textarea` получают нативный `disabled`, то есть выпадают из таб-порядка.
120
+ - `FormFieldTarget` намеренно **не** публикует свой `id` как `targetId`: это `<div>`, а не labelable-элемент, и `label[htmlFor]` на него ссылаться не может. В таких полях `FormFieldLabel` рендерит `<span>`, а не `<label>` — несвязанный `<label>` браузер тоже считает ошибкой разметки. Имя полю даёт `aria-labelledby` на `FormFieldTarget`, поэтому `screen.getByLabelText(...)` продолжает находить поле.
121
+ - Следствие выбора тега по контексту: `targetId` публикуется в `useLayoutEffect`, поэтому в полях с labelable-элементом лейбл на первом рендере — `<span>`, а после layout-эффекта DOM-узел заменяется на `<label>`. Замена происходит до отрисовки и визуально незаметна, но ref на `FormFieldLabel` вызывается для обоих узлов.
122
+ - При `status = DISABLED` вложенные `input` / `textarea` получают нативный `disabled`, то есть выпадают из таб-порядка. Передать `disabled` мимо статуса нельзя — атрибут исключён из props элементов ввода.
120
123
  - Плейсхолдер маски в `FormFieldMaskedInput` рендерится с `aria-hidden="true"` — скринридер читает только реальное значение input.
121
124
  - Текст описания (`FormFieldDescription`) визуально связан с полем, но не связывается автоматически через `aria-describedby` — при необходимости потребитель передаёт `aria-describedby` элементу ввода сам.
122
125
 
@@ -168,6 +171,10 @@ FormField.Target_PlaceholderColor_Default
168
171
  | 2026-08-03 | Ломающее изменение: `statusToClassNameMap` убран из публичного barrel и переименован во внутреннюю константу `STATUS_TO_CLASS_NAME_MAP`. Зафиксировано в release notes 1.41.0. |
169
172
  | 2026-09-04 | Исправлено: у `FormFieldTextarea` фиксированная `height` для размеров `sm` / `md` / `lg` заменена на `min-height`. |
170
173
  | 2026-09-09 | Исправлено: значение с кодом страны раскладывалось по маске телефона со сдвигом и теряло последнюю цифру. Нормализация номера вынесена в `normalizePhoneText` и применяется и к внешнему `value`, и к слою с маской |
174
+ | 2026-09-16 | Исправлено: `FormFieldTarget` больше не публикует свой `id` как `targetId`, а `FormFieldLabel` рендерит `<span>` вместо `<label>`, когда в поле нет labelable-элемента. Ref `FormFieldLabel` типизирован как `HTMLElement`, props — как `React.HTMLAttributes<HTMLElement>`. Доступное имя по-прежнему даёт `aria-labelledby`. |
175
+ | 2026-09-16 | Исправлено: `FormFieldInput` и `FormFieldTextarea` очищают `targetId` при размонтировании — иначе после замены элемента ввода на `FormFieldTarget` лейбл сохранял `htmlFor` с `id` удалённого элемента. |
176
+ | 2026-09-17 | Ломающее изменение: `disabled` убран из `IFormFieldTextareaProps` через `Omit` — так же, как он уже был убран у `FormFieldInput` и `FormFieldMaskedInput`. Поведение не менялось (статус перетирал переданное значение и раньше), но передача `disabled` в props теперь ошибка компиляции. Правка по ревью PR #629, зафиксирована в release notes 1.47.0 |
177
+ | 2026-09-23 | Исправлено: при смене `status` на `EFormFieldStatus.DISABLED`, пока вложенный элемент ввода в фокусе, `FormField` теперь явно сбрасывает состояние `focused` в `useLayoutEffect`. |
171
178
 
172
179
  ---
173
180
 
@@ -76,8 +76,9 @@ version: "1.0"
76
76
  Семантику задаёт потребитель через проброшенные атрибуты — например `role="group"` вместе с
77
77
  `aria-labelledby`, если группа должна объявляться скринридером как единое целое.
78
78
 
79
- Лейбл связывается с полем внутри `FormField`: `FormFieldLabel` берёт `htmlFor` из `targetId`
80
- в `FormFieldContext`. Описание автоматически не связывается — `aria-describedby` на элементе
79
+ Лейбл связывается с полем внутри `FormField`: в полях с элементом ввода `FormFieldLabel` берёт
80
+ `htmlFor` из `targetId` в `FormFieldContext`, в select-подобных — связь даёт `aria-labelledby`
81
+ на `FormFieldTarget` (см. `FormField-ai.md`). Описание автоматически не связывается — `aria-describedby` на элементе
81
82
  ввода (как и `aria-invalid` для ошибки) задаёт потребитель, см. `FormField-ai.md`. `FormGroup`
82
83
  не участвует ни в том, ни в другом.
83
84
 
@@ -101,6 +101,13 @@ LightBox.SideOverlay_Background
101
101
  css-переменную `--lightBox-scroll-width`, которую вычитают из ширины оверлеев. Ширины размеров
102
102
  (`664/864/1064/1264`) заданы LESS-константами `@lightBox-content-max-width-*`.
103
103
 
104
+ Боковые отступы контента лайтбокса (`@lightBoxContentPaddingX`, 80px — место под кнопки
105
+ вперёд/назад, на экранах до 1024px включительно 0) публикуются css-переменной
106
+ `--lightBox-content-padding-x` на `.lightBoxContent`. По ней потомки выравниваются с колонкой
107
+ страницы — так это делает обёртка `TopOverlay`. Переменная объявлена именно на `.lightBoxContent`,
108
+ поэтому вне его поддерева (например в `LightBox.SideOverlay` — он сиблинг `LightBox.Content`,
109
+ а не его потомок) она не видна, и читающие её стили получают фолбэк 0.
110
+
104
111
  ---
105
112
 
106
113
  ## Инварианты
@@ -202,6 +209,7 @@ css-переменную `--lightBox-scroll-width`, которую вычита
202
209
 
203
210
  | Дата | Изменение |
204
211
  |---|---|
212
+ | 2026-09-21 | Боковые отступы `.lightBoxContent` вынесены в css-переменную `--lightBox-content-padding-x` (константа `@lightBoxContentPaddingX`). Нужна, чтобы `TopOverlay` выравнивался по колонке контента |
205
213
  | 2026-07-22 | Создан документ (Phase 1 AI-Ready). В том же изменении — AI-рефакторинг: JSDoc на props, общий `LightBoxArrow` для Prev/Next, хук `useLightBoxSidebarVisibility` для сайдбаров, устранение eslint-подавлений; публичный API не менялся |
206
214
  | 2026-07-22 | Добавлен `export` к props-интерфейсам `ILightBoxControlsProps`, `ILightBoxCloseProps`, `ILightBoxPrevProps`, `ILightBoxNextProps`, `ILightBoxSideOverlayLoaderProps` (аддитивно, для консистентности с остальными интерфейсами компонента) |
207
215
  | 2026-07-22 | Багфиксы по ревью PR #474: клавиатурные триггеры контролов целятся в видимую кнопку (стрелки не работали на desktop, Esc — на mobile); таймер-хак блокировки скролла заменён счётчиком смонтированных лайтбоксов; `LightBoxViewManager` снимает классы mount-ноды при размонтировании последнего менеджера |
@@ -628,13 +628,13 @@ export const Default = () => {
628
628
  controlButtons={
629
629
  <>
630
630
  <ListItemControlsButton
631
- icon={<AttachmentStrokeSrvIcon20 paletteIndex={5} />}
631
+ icon={<AttachmentStrokeSrvIcon20 paletteIndex={0} />}
632
632
  >
633
633
  Скачать
634
634
  </ListItemControlsButton>
635
635
 
636
636
  <ListItemControlsButtonDropdown
637
- icon={<DotshorizontalStrokeSrvIcon20 paletteIndex={5} />}
637
+ icon={<DotshorizontalStrokeSrvIcon20 paletteIndex={0} />}
638
638
  options={itemActions}
639
639
  >
640
640
  Действия
@@ -156,11 +156,11 @@ export const Default = () => {
156
156
  onClickItem={() => {}}
157
157
  controlButtons={
158
158
  <>
159
- <ListItemControlsButton icon={<AttachmentStrokeSrvIcon20 paletteIndex={5} />}>
159
+ <ListItemControlsButton icon={<AttachmentStrokeSrvIcon20 paletteIndex={0} />}>
160
160
  Скачать
161
161
  </ListItemControlsButton>
162
162
  <ListItemControlsButtonDropdown
163
- icon={<DotshorizontalStrokeSrvIcon20 paletteIndex={5} />}
163
+ icon={<DotshorizontalStrokeSrvIcon20 paletteIndex={0} />}
164
164
  options={options}
165
165
  >
166
166
  Действия
@@ -245,11 +245,11 @@ export const Selectable = () => {
245
245
  onClickItem={() => console.log("Клик по карточке.")}
246
246
  controlButtons={
247
247
  <>
248
- <ListItemControlsButton icon={<AttachmentStrokeSrvIcon20 paletteIndex={5} />}>
248
+ <ListItemControlsButton icon={<AttachmentStrokeSrvIcon20 paletteIndex={0} />}>
249
249
  Скачать
250
250
  </ListItemControlsButton>
251
251
  <ListItemControlsButtonDropdown
252
- icon={<DotshorizontalStrokeSrvIcon20 paletteIndex={5} />}
252
+ icon={<DotshorizontalStrokeSrvIcon20 paletteIndex={0} />}
253
253
  options={options}
254
254
  >
255
255
  Действия
@@ -354,11 +354,11 @@ export const WithSwipeEmulation = () => {
354
354
  onClickItem={() => console.log("Клик по карточке.")}
355
355
  controlButtons={
356
356
  <>
357
- <ListItemControlsButton icon={<AttachmentStrokeSrvIcon20 paletteIndex={5} />}>
357
+ <ListItemControlsButton icon={<AttachmentStrokeSrvIcon20 paletteIndex={0} />}>
358
358
  Скачать
359
359
  </ListItemControlsButton>
360
360
  <ListItemControlsButtonDropdown
361
- icon={<DotshorizontalStrokeSrvIcon20 paletteIndex={5} />}
361
+ icon={<DotshorizontalStrokeSrvIcon20 paletteIndex={0} />}
362
362
  options={options}
363
363
  >
364
364
  Действия
@@ -61,7 +61,6 @@ version: "1.0"
61
61
  - `forwardRef` на компоненте — не убирать. Ref пробрасывается в `DatePickerExtended` (корневой DOM-элемент — элемент `DatePickerExtended`).
62
62
  - Публичный API (`IMonthYearFieldProps`: `value`, `onChange`, `onClear`, `targetProps`, `placeholder` + унаследованные `size`/`status`/`label` и props `DatePickerExtended`) — изменение имён/типов/значений — breaking change.
63
63
  - Поле read-only по контракту — не делать его редактируемым без обсуждения (компонент не имеет логики валидации клавиатурного ввода).
64
- - Отображаемый формат `"MMM YYYY"` зафиксирован в `inputMonthYearFormat`; менять его — визуальный breaking change для потребителей.
65
64
  - Sync-эффект в `MonthYearField.tsx` (`useEffect` по `[value, format, limitRange]` с `eslint-disable react-hooks/exhaustive-deps`) — намеренная синхронизация derived-стейта `pickerValues` с внешним `value`. Не переписывать без анализа поведения: сравнение идёт по `inputString`, чтобы не сбрасывать стейт при эквивалентных значениях.
66
65
  - Внутренние символы `MonthYearPickerUtils` (`utils.ts`), `MonthYearFieldContext`, `MonthYearFieldTarget` не экспортируются через barrel — это приватные детали реализации.
67
66
 
@@ -130,7 +129,7 @@ export const DefaultExample = () => {
130
129
 
131
130
  return (
132
131
  <div style={{ maxWidth: 300 }}>
133
- <MonthYearField value={value} placeholder="мм.гггг" label="Label" onChange={setValue} />
132
+ <MonthYearField value={value} placeholder="Select to proceed" label="Label" onChange={setValue} />
134
133
  </div>
135
134
  );
136
135
  };
@@ -154,7 +153,13 @@ const SizeItem = ({ size }: ISizeItemProps) => {
154
153
  return (
155
154
  <div style={{ maxWidth: 300 }}>
156
155
  <div style={{ marginBottom: 8, fontSize: 16, fontWeight: 700 }}>{size.toUpperCase()}</div>
157
- <MonthYearField size={size} value={value} label="Label" placeholder="мм.гггг" onChange={setValue} />
156
+ <MonthYearField
157
+ size={size}
158
+ value={value}
159
+ label="Label"
160
+ placeholder="Select to proceed"
161
+ onChange={setValue}
162
+ />
158
163
  </div>
159
164
  );
160
165
  };
@@ -188,7 +193,13 @@ const StatusItem = ({ status }: IStatusItemProps) => {
188
193
  return (
189
194
  <div style={{ maxWidth: 300 }}>
190
195
  <div style={{ marginBottom: 8, fontSize: 16, fontWeight: 700 }}>{status.toUpperCase()}</div>
191
- <MonthYearField status={status} value={value} label="Label" placeholder="мм.гггг" onChange={setValue} />
196
+ <MonthYearField
197
+ status={status}
198
+ value={value}
199
+ label="Label"
200
+ placeholder="Select to proceed"
201
+ onChange={setValue}
202
+ />
192
203
  </div>
193
204
  );
194
205
  };