@sberbusiness/triplex-next-mcp-server 1.45.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.
- package/README.md +7 -7
- package/bundle/components/AmountField.md +222 -323
- package/bundle/components/Avatar.md +138 -146
- package/bundle/components/CardAction.md +615 -0
- package/bundle/components/CardStatic.md +402 -0
- package/bundle/components/CheckboxTree.md +157 -215
- package/bundle/components/CheckboxTreeExtended.md +7 -7
- package/bundle/components/Chip.md +7 -6
- package/bundle/components/ChipGroup.md +1 -1
- 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 +588 -0
- package/bundle/components/CollapsibleTree.md +8 -4
- package/bundle/components/CollapsibleTreeExtended.md +8 -6
- package/bundle/components/Confirm.md +346 -281
- package/bundle/components/DateField.md +222 -303
- package/bundle/components/DatePickerExtended.md +3 -1
- package/bundle/components/DateRange.md +351 -210
- package/bundle/components/FooterPage.md +1 -0
- package/bundle/components/FormField.md +14 -5
- package/bundle/components/FormGroup.md +3 -2
- package/bundle/components/HelpBox.md +7 -1
- package/bundle/components/IslandAccordion.md +443 -152
- package/bundle/components/IslandWidget.md +622 -157
- package/bundle/components/LightBox.md +8 -0
- package/bundle/components/ListMaster.md +2 -2
- package/bundle/components/ListTableItem.md +6 -6
- package/bundle/components/MaskedField.md +2 -1
- package/bundle/components/MonthYearField.md +18 -5
- package/bundle/components/Slider.md +389 -97
- package/bundle/components/SliderRange.md +486 -105
- package/bundle/components/StatusTracker.md +386 -94
- package/bundle/components/Stepper.md +355 -102
- package/bundle/components/StepperExtended.md +633 -0
- package/bundle/components/SuggestField.md +1049 -96
- package/bundle/components/SwipeableArea.md +7 -7
- package/bundle/components/Tabs.md +265 -92
- package/bundle/components/TabsExtended.md +18 -18
- package/bundle/components/TabsLine.md +301 -127
- package/bundle/components/TagColor.md +187 -66
- package/bundle/components/TagGroup.md +184 -48
- package/bundle/components/TextareaField.md +278 -70
- package/bundle/components/TopOverlay.md +17 -1
- package/bundle/components/TreeView.md +16 -7
- package/bundle/components/TriggerClickOnKeyDownEvent.md +277 -0
- package/bundle/components/UploadZone.md +318 -0
- package/bundle/guides/codestyle.md +16 -1
- package/bundle/guides/commits.md +47 -1
- package/bundle/guides/tests.md +23 -2
- package/bundle/manifest.json +92 -24
- package/bundle/release-notes/1.46.0.mdx +59 -0
- package/bundle/release-notes/1.47.0.mdx +122 -0
- package/bundle/release-notes/1.48.0.mdx +68 -0
- package/bundle/release-notes/1.49.0.mdx +7 -0
- package/bundle/tokens.json +3 -3
- package/dist/index.js +220 -6
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
---
|
|
2
2
|
component: StatusTracker
|
|
3
|
-
category:
|
|
4
|
-
|
|
5
|
-
figma-file: ""
|
|
6
|
-
related: [MarkerStatus, Alert, Card]
|
|
3
|
+
category: Feedback
|
|
4
|
+
related: [MarkerStatus, AlertProcess, Amount, Button]
|
|
7
5
|
tokens:
|
|
8
|
-
-
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
-
|
|
6
|
+
- StatusTracker.Background
|
|
7
|
+
- StatusTracker.Border_Color
|
|
8
|
+
- StatusTracker.Draft_Background
|
|
9
|
+
- StatusTracker.Draft_Color
|
|
10
|
+
- StatusTracker.Waiting_Background
|
|
11
|
+
- StatusTracker.Waiting_Color
|
|
12
|
+
- StatusTracker.Warning_Background
|
|
13
|
+
- StatusTracker.Rejected_Background
|
|
14
|
+
- StatusTracker.Rejected_Color
|
|
15
|
+
- StatusTracker.Approved_Background
|
|
16
|
+
- StatusTracker.Approved_Color
|
|
17
17
|
stories: stories/StatusTracker/StatusTracker.stories.tsx
|
|
18
18
|
version: "1.0"
|
|
19
19
|
---
|
|
@@ -22,125 +22,209 @@ version: "1.0"
|
|
|
22
22
|
|
|
23
23
|
## Назначение
|
|
24
24
|
|
|
25
|
-
Карточка статуса
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
Карточка статуса документа: на фоне — декоративное цветное пятно, кодирующее `type`,
|
|
26
|
+
поверх него — композиция из блоков `Media`, `Header`, `Body` и `Footer`. Типичное место —
|
|
27
|
+
экран одного документа (платёжное поручение, заявка) после отправки в банк: иконка статуса,
|
|
28
|
+
сумма, текущее состояние обработки и действия над документом.
|
|
28
29
|
|
|
29
|
-
Используй когда:
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
Используй когда: нужен крупный итоговый экран состояния одного объекта — «документ в обработке»,
|
|
31
|
+
«отклонён банком», «исполнен» — с суммой, пояснением и действиями.
|
|
32
|
+
|
|
33
|
+
Не используй когда:
|
|
34
|
+
|
|
35
|
+
- Статус показывается в строке списка или таблицы — там нужен компактный `MarkerStatus`,
|
|
36
|
+
`Marker` или `TagColor`, а не карточка на всю высоту контейнера.
|
|
37
|
+
- Нужно сообщение внутри формы или страницы — возьми `AlertProcess` / `AlertContext`.
|
|
38
|
+
`StatusTracker` — самостоятельный экран, а не врезка.
|
|
39
|
+
- Нужен контейнер общего назначения с заголовком и контентом — это `Island` или `CardStatic`.
|
|
40
|
+
- Нужно показать прогресс из нескольких шагов — это `Stepper` / `Step`.
|
|
32
41
|
|
|
33
42
|
---
|
|
34
43
|
|
|
35
|
-
##
|
|
44
|
+
## Варианты и props
|
|
36
45
|
|
|
37
|
-
|
|
38
|
-
src/components/StatusTracker/
|
|
39
|
-
├── StatusTracker.tsx # корневой + композиция (Media/Header/Body/Footer)
|
|
40
|
-
├── enums.ts # EStatusTrackerType, EStatusTrackerVerticalAlign
|
|
41
|
-
├── components/
|
|
42
|
-
│ ├── StatusTrackerMedia.tsx
|
|
43
|
-
│ ├── StatusTrackerHeader.tsx # + Title, Sum, Description
|
|
44
|
-
│ ├── StatusTrackerBody.tsx # + Alert, Status
|
|
45
|
-
│ ├── StatusTrackerFooter.tsx # + Button, Description
|
|
46
|
-
│ ├── StatusTrackerTitle.tsx
|
|
47
|
-
│ ├── StatusTrackerSum.tsx
|
|
48
|
-
│ ├── StatusTrackerDescription.tsx
|
|
49
|
-
│ ├── StatusTrackerStatus.tsx
|
|
50
|
-
│ ├── StatusTrackerAlert.tsx
|
|
51
|
-
│ └── StatusTrackerButton.tsx
|
|
52
|
-
├── styles/
|
|
53
|
-
└── index.ts
|
|
54
|
-
```
|
|
46
|
+
### Обязательные props
|
|
55
47
|
|
|
56
|
-
|
|
48
|
+
| Prop | Тип | Описание |
|
|
49
|
+
|---|---|---|
|
|
50
|
+
| `type` | `EStatusTrackerType` | Тип статуса документа: `DRAFT` / `WAITING` / `WARNING` / `REJECTED` / `APPROVED`. Влияет **только** на цвет декоративного фона — ни иконку, ни текст, ни набор блоков компонент по нему не подставляет |
|
|
57
51
|
|
|
58
|
-
|
|
52
|
+
### Опциональные props
|
|
59
53
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
<StatusTracker.Header.Title>...</Title>
|
|
65
|
-
<StatusTracker.Header.Sum>...</Sum>
|
|
66
|
-
<StatusTracker.Header.Description>...</Description>
|
|
67
|
-
</StatusTracker.Header>
|
|
68
|
-
<StatusTracker.Body>
|
|
69
|
-
<StatusTracker.Body.Status>...</Status>
|
|
70
|
-
<StatusTracker.Body.Alert>...</Alert>
|
|
71
|
-
</StatusTracker.Body>
|
|
72
|
-
<StatusTracker.Footer>
|
|
73
|
-
<StatusTracker.Footer.Button>...</Button>
|
|
74
|
-
<StatusTracker.Footer.Description>...</Description>
|
|
75
|
-
</StatusTracker.Footer>
|
|
76
|
-
</StatusTracker>
|
|
77
|
-
```
|
|
54
|
+
| Prop | Тип | По умолчанию | Описание |
|
|
55
|
+
|---|---|---|---|
|
|
56
|
+
| `verticalAlign` | `EStatusTrackerVerticalAlign` | `EStatusTrackerVerticalAlign.TOP` | Выравнивание контента внутри карточки: `TOP` / `MIDDLE` / `BOTTOM`. Заметно, только когда контейнер выше содержимого |
|
|
57
|
+
| `children` | `React.ReactNode` | — | Блоки `StatusTracker.Media`, `.Header`, `.Body`, `.Footer` в любом сочетании и порядке |
|
|
78
58
|
|
|
79
|
-
|
|
59
|
+
Остальные props — стандартные атрибуты `div`
|
|
60
|
+
(`IStatusTrackerProps extends React.HTMLAttributes<HTMLDivElement>`), уходят на корневой
|
|
61
|
+
элемент через `...rest`.
|
|
80
62
|
|
|
81
|
-
|
|
63
|
+
### Состав компонента
|
|
82
64
|
|
|
83
|
-
|
|
65
|
+
Публичный API — составной: субкомпоненты доступны и статическими свойствами, и отдельными
|
|
66
|
+
экспортами — кроме `StatusTrackerAlert`, `StatusTrackerStatus` и `StatusTrackerStatusGroup`:
|
|
67
|
+
они доступны только статическими свойствами, из barrel `index.ts` их нет.
|
|
84
68
|
|
|
85
|
-
|
|
69
|
+
**Известное ограничение, не замысел.** Интерфейс `IStatusTrackerStatusGroup` не экспортируется
|
|
70
|
+
ниоткуда, поэтому типизировать обёртку над `StatusTracker.Body.StatusGroup` потребителю нечем.
|
|
71
|
+
Добавление трёх экспортов аддитивно и не ломающее — уместно отдельной задачей, как это уже
|
|
72
|
+
сделали в 1.48.0 для `IUploadZoneProps`.
|
|
86
73
|
|
|
87
|
-
|
|
|
74
|
+
| Составной путь | Компонент | Корневой DOM | Своё, сверх `className` + `...rest` |
|
|
88
75
|
|---|---|---|---|
|
|
89
|
-
| `
|
|
90
|
-
| `
|
|
91
|
-
|
|
|
76
|
+
| `StatusTracker.Media` | `StatusTrackerMedia` | `div` | — контейнер под статусную иконку размера 84 |
|
|
77
|
+
| `StatusTracker.Header` | `StatusTrackerHeader` | `div` | — |
|
|
78
|
+
| `StatusTracker.Header.Title` | `StatusTrackerTitle` | `h3` (`Title` size H3, BOLD) | — |
|
|
79
|
+
| `StatusTracker.Header.Sum` | `StatusTrackerSum` | `h1` (`Title` size H1, SEMIBOLD) | `amountProps: IAmountProps` — обязательный, уходит в `Amount` как есть |
|
|
80
|
+
| `StatusTracker.Header.Description` | `StatusTrackerDescription` | `span` (`Text` B3, SECONDARY) | — |
|
|
81
|
+
| `StatusTracker.Body` | `StatusTrackerBody` | `div` | — |
|
|
82
|
+
| `StatusTracker.Body.Status` | `StatusTrackerStatus` | `div` (`MarkerStatus`) | принимает `IMarkerStatusProps` целиком (`status` обязателен) |
|
|
83
|
+
| `StatusTracker.Body.StatusGroup` | `StatusTrackerStatusGroup` | `div` | — колонка из нескольких `Status`, центрируется целиком |
|
|
84
|
+
| `StatusTracker.Body.Alert` | `StatusTrackerAlert` | `div` (`AlertProcess`) | принимает `IAlertProcessProps` целиком (`type` обязателен); оборачивает `children` в `Text` B3 |
|
|
85
|
+
| `StatusTracker.Footer` | `StatusTrackerFooter` | `div` | — |
|
|
86
|
+
| `StatusTracker.Footer.Button` | `StatusTrackerButton` | `button` (`Button`) | `Exclude<TButtonProps, IButtonLinkProps>`; `block` проставляется принудительно |
|
|
87
|
+
| `StatusTracker.Footer.Description` | `StatusTrackerDescription` | `span` | тот же компонент, что и в `Header` |
|
|
88
|
+
|
|
89
|
+
Блоки необязательны: карточка валидна и с одним `Media`. Порядок блоков в DOM = порядок
|
|
90
|
+
в JSX — компонент не сортирует `children` и не проверяет их тип.
|
|
91
|
+
|
|
92
|
+
### Что компонент не делает сам
|
|
93
|
+
|
|
94
|
+
- Не выбирает иконку по `type` — `Media` заполняет потребитель (`WaitStsIcon84`,
|
|
95
|
+
`WarningStsIcon84`, `ErrorStsIcon84`, `SuccessStsIcon84` из `@sberbusiness/icons-next`).
|
|
96
|
+
- Не связывает `type` со `status` у `Body.Status` и с `type` у `Body.Alert` — это три
|
|
97
|
+
независимых значения, согласованность на стороне потребителя.
|
|
98
|
+
- Не задаёт себе размеры: `width: 100%`, `height: 100%`, `min-height` 318px (258px на `≤ sm`).
|
|
99
|
+
Ширину и высоту определяет контейнер.
|
|
92
100
|
|
|
93
|
-
|
|
101
|
+
---
|
|
94
102
|
|
|
95
|
-
|
|
96
|
-
|---|---|
|
|
97
|
-
| `DRAFT` | Нейтральный draft-фон (`--StatusTracker-Draft_Background`). В `typeToClassNameMap` **не маппится** — цветная метка не рендерится (background остаётся базовым). |
|
|
98
|
-
| `WAITING` | Жёлто-серый. |
|
|
99
|
-
| `WARNING` | Оранжевый (только background). |
|
|
100
|
-
| `REJECTED` | Красный. |
|
|
101
|
-
| `APPROVED` | Зелёный. |
|
|
103
|
+
## Дизайн-токены
|
|
102
104
|
|
|
103
|
-
|
|
105
|
+
Переопределяются через `ThemeProvider` (prop `tokens`) — см. `ThemeProvider-ai.md` →
|
|
106
|
+
«Как переопределять токены». Значения по умолчанию — `src/components/DesignTokens/components/StatusTracker.ts`.
|
|
104
107
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
108
|
+
```text
|
|
109
|
+
StatusTracker.Background
|
|
110
|
+
StatusTracker.Border_Color
|
|
111
|
+
StatusTracker.Draft_Background
|
|
112
|
+
StatusTracker.Draft_Color
|
|
113
|
+
StatusTracker.Waiting_Background
|
|
114
|
+
StatusTracker.Waiting_Color
|
|
115
|
+
StatusTracker.Warning_Background
|
|
116
|
+
StatusTracker.Rejected_Background
|
|
117
|
+
StatusTracker.Rejected_Color
|
|
118
|
+
StatusTracker.Approved_Background
|
|
119
|
+
StatusTracker.Approved_Color
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Декоративный фон собран из двух слоёв-эллипсов: `statusTrackerBackground` (размытие
|
|
123
|
+
`blur(50px)`) берёт токен `*_Background`, `statusTrackerColor` поверх него — токен `*_Color`.
|
|
124
|
+
|
|
125
|
+
Набор токенов асимметричен: у `WARNING` собственного `Warning_Color` нет — оба слоя
|
|
126
|
+
используют `Warning_Background`. Это не опечатка в стилях, а текущее состояние палитры;
|
|
127
|
+
если понадобится развести слои, токен придётся добавить и в
|
|
128
|
+
`DesignTokens/components/StatusTracker.ts`, и в LESS.
|
|
129
|
+
|
|
130
|
+
Токены `Draft_*` и `Waiting_*` по умолчанию ссылаются на одну и ту же палитру, поэтому
|
|
131
|
+
`DRAFT` и `WAITING` выглядят одинаково. Токены при этом раздельные — потребитель может
|
|
132
|
+
развести их темой, и схлопывать их в один нельзя.
|
|
110
133
|
|
|
111
134
|
---
|
|
112
135
|
|
|
113
136
|
## Инварианты
|
|
114
137
|
|
|
115
|
-
-
|
|
116
|
-
|
|
117
|
-
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
138
|
+
- `forwardRef<HTMLDivElement>` на `StatusTracker` — не убирать. Ref указывает на корневой
|
|
139
|
+
`statusTrackerWrapper`, а не на внутренний контейнер контента.
|
|
140
|
+
- Трёхслойная разметка обязательна: `statusTrackerWrapper` (рамка, фон, `overflow: hidden`)
|
|
141
|
+
→ `statusTrackerBackground` + вложенный `statusTrackerColor` (декоративные эллипсы,
|
|
142
|
+
`position: absolute`) → `statusTracker` (контент, `z-index: 1`). Схлопывание слоёв ломает
|
|
143
|
+
и градиент, и обрезку эллипсов по скруглению карточки.
|
|
144
|
+
- Класс типа (`draft` / `waiting` / …) ставится **на оба** декоративных слоя. Если поставить
|
|
145
|
+
только на один, половина фона останется без цвета.
|
|
146
|
+
- `key={type}` на `statusTrackerBackground` заставляет React пересоздавать узел при смене
|
|
147
|
+
типа. Поведение наблюдаемое (сброс состояния DOM-узла), поэтому снимать его без
|
|
148
|
+
обсуждения не нужно.
|
|
149
|
+
- Значения `EStatusTrackerType` (`"draft"` / `"waiting"` / `"warning"` / `"rejected"` /
|
|
150
|
+
`"approved"`) совпадают с именами CSS-классов в `StatusTracker.module.less` и с префиксами
|
|
151
|
+
токенов `StatusTracker.*`. Переименование значения enum ломает три места сразу.
|
|
152
|
+
- `EStatusTrackerVerticalAlign.TOP` намеренно отсутствует в `VERTICAL_ALIGN_TO_CLASS_NAME_MAP`:
|
|
153
|
+
это выравнивание по умолчанию и своего класса не имеет. Мапа объявлена как `Partial<Record<…>>`
|
|
154
|
+
именно поэтому.
|
|
155
|
+
- `StatusTracker.Footer.Button` получает `block` по умолчанию — кнопки футера занимают всю
|
|
156
|
+
ширину карточки. Это не жёсткий инвариант: `block` проставлен до `...rest`, поэтому
|
|
157
|
+
`<StatusTracker.Footer.Button block={false}>` отключает блочный режим. Тема `LINK` исключена
|
|
158
|
+
из типа props (`Exclude<TButtonProps, IButtonLinkProps>`), потому что блочный режим для неё
|
|
159
|
+
недоступен.
|
|
160
|
+
- `StatusTrackerAlert` оборачивает `children` в `Text` размера B3. Передавать внутрь
|
|
161
|
+
собственный `Text`/`Title` не нужно — получится вложенная типографика.
|
|
162
|
+
- Селектор `.statusTrackerChild:empty { padding: 0 }` схлопывает отступы у пустых блоков —
|
|
163
|
+
пустой `Header` не оставляет дыру в макете.
|
|
164
|
+
- Barrel `src/components/StatusTracker/index.ts` экспортирует `StatusTracker`, оба enum'а и
|
|
165
|
+
субкомпоненты `Header`, `Footer`, `Title`, `Description`, `Media`, `Sum`, `Body`, `Button` —
|
|
166
|
+
сохранять.
|
|
167
|
+
- Имена интерфейсов `StatusTrackerMediaProps` (без префикса `I`) и `IStatusTrackerStatusGroup`
|
|
168
|
+
(без суффикса `Props`) расходятся с конвенцией `codestyle.md`. Это публичные имена —
|
|
169
|
+
переименование возможно только как согласованный breaking change.
|
|
170
|
+
- `displayName` проставлены у всех субкомпонентов и совпадают с именами компонентов —
|
|
171
|
+
проверяются unit-тестом.
|
|
172
|
+
- У `Title`, `Sum` и `Description` дженерик ref-а — `HTMLElement`, хотя фактический тег
|
|
173
|
+
всегда `h3`, `h1` и `span` соответственно. Шире он намеренно: сужение до
|
|
174
|
+
`HTMLHeadingElement` / `HTMLSpanElement` — изменение публичного типа, требующее
|
|
175
|
+
согласования. Если сужать, то до выхода 1.48.0.
|
|
121
176
|
|
|
122
177
|
---
|
|
123
178
|
|
|
124
179
|
## Accessibility
|
|
125
180
|
|
|
126
|
-
-
|
|
127
|
-
|
|
128
|
-
-
|
|
181
|
+
- Собственной ARIA-роли и обработчиков клавиатуры у компонента нет: `StatusTracker` и все
|
|
182
|
+
блоки-контейнеры — неинтерактивные `div`, в порядок фокуса не попадают.
|
|
183
|
+
- Интерактивен только `StatusTracker.Footer.Button` — это обычный `Button` со своей
|
|
184
|
+
семантикой и фокусом.
|
|
185
|
+
- Цвет фона — декоративный и **не должен быть единственным носителем смысла**: статус
|
|
186
|
+
обязан читаться текстом (`Body.Status`, `Header.Title`). Скринридер градиент не озвучит.
|
|
187
|
+
- Иконка в `Media` — тоже декоративная. Если она несёт смысл, потребитель сам задаёт
|
|
188
|
+
`aria-label` / `role="img"` на иконке.
|
|
189
|
+
- Заголовки рендерятся как `h3` (`Header.Title`) и `h1` (`Header.Sum`) — порядок уровней
|
|
190
|
+
в разметке страницы обратный. Изменить уровень заголовка через публичный API нельзя:
|
|
191
|
+
`IStatusTrackerTitleProps` и `IStatusTrackerSumProps` — это `React.HTMLAttributes`,
|
|
192
|
+
prop'а `tag` в них нет, хотя внутренняя типографика (`Title`) его поддерживает.
|
|
193
|
+
- Компонент не хардкодит текстовые строки: содержимое и любые `aria-*` задаёт потребитель,
|
|
194
|
+
библиотека мультиязычная. Любые `aria-*` проходят через `...rest` на корневой `div`.
|
|
129
195
|
|
|
130
196
|
---
|
|
131
197
|
|
|
132
198
|
## Связанные компоненты
|
|
133
199
|
|
|
134
|
-
- `MarkerStatus` —
|
|
135
|
-
|
|
136
|
-
- `
|
|
200
|
+
- `MarkerStatus` — рендерится внутри `StatusTracker.Body.Status`, принимает его props целиком.
|
|
201
|
+
Он же — замена всему `StatusTracker`, когда статус нужен компактной строкой в списке.
|
|
202
|
+
- `AlertProcess` — рендерится внутри `StatusTracker.Body.Alert`, принимает его props целиком
|
|
203
|
+
(включая `closable` / `onClose`).
|
|
204
|
+
- `Amount` — рендерится внутри `StatusTracker.Header.Sum`, настраивается через `amountProps`.
|
|
205
|
+
- `Button` — рендерится внутри `StatusTracker.Footer.Button` с принудительным `block`.
|
|
206
|
+
- `Title` и `Text` (`Typography`) — типографика `Title`, `Sum` и `Description`; размеры
|
|
207
|
+
и начертания зашиты в субкомпонентах и через props не настраиваются.
|
|
137
208
|
|
|
138
209
|
---
|
|
139
210
|
|
|
140
211
|
## Stories
|
|
141
212
|
|
|
142
213
|
Основные истории: `stories/StatusTracker/StatusTracker.stories.tsx`
|
|
143
|
-
|
|
214
|
+
Файлы примеров: `stories/StatusTracker/examples/`
|
|
215
|
+
|
|
216
|
+
| Story | Example file | Что демонстрирует |
|
|
217
|
+
|---|---|---|
|
|
218
|
+
| `Playground` | `Playground.tsx` | Интерактивный контроль `type` и `verticalAlign` на полной композиции |
|
|
219
|
+
| `Default` | `Default.tsx` | Минимальная карточка: `type` + `Media` + `Header` |
|
|
220
|
+
| `Types` | `Types.tsx` | Все пять значений `EStatusTrackerType` |
|
|
221
|
+
| `VerticalAlign` | `VerticalAlign.tsx` | `TOP` / `MIDDLE` / `BOTTOM` в контейнере выше содержимого |
|
|
222
|
+
| `WithMediaOnly` | `WithMediaOnly.tsx` | Краевой случай: карточка из одного блока `Media` |
|
|
223
|
+
| `Example` | `Example.tsx` | Production-like композиция: медиа, сумма, группа статусов, предупреждение, футер |
|
|
224
|
+
| `VisualTests` | `VisualTests.tsx` | Широкий родитель, выравнивание `BOTTOM` и `StatusGroup` с закрываемым `Alert` — для скриншот-тестов |
|
|
225
|
+
|
|
226
|
+
Story ID участвуют в именах baseline-скриншотов (`statustracker--types--xs.png` и т. п.),
|
|
227
|
+
поэтому переименование story требует перегенерации baseline и удаления осиротевших файлов.
|
|
144
228
|
|
|
145
229
|
---
|
|
146
230
|
|
|
@@ -148,4 +232,212 @@ src/components/StatusTracker/
|
|
|
148
232
|
|
|
149
233
|
| Дата | Изменение |
|
|
150
234
|
|---|---|
|
|
151
|
-
| 2026-
|
|
235
|
+
| 2026-09-25 | Создан документ. AI-рефакторинг: JSDoc на всех публичных props, `forwardRef` у субкомпонентов `Media`, `Title`, `Description`, `Sum`, `Alert`, `Status`, `Button` и `displayName` у них же, кроме `Button` (у него он уже был), исправлен JSDoc `StatusTrackerTitle`. Unit-тесты расширены (`StatusTrackerStatusGroup`, проброс ref, `displayName`). Stories переведены на modern pattern с `examples/` и дополнены `Types`, `Example`, `VisualTests`. |
|
|
236
|
+
|
|
237
|
+
---
|
|
238
|
+
|
|
239
|
+
## Примеры использования
|
|
240
|
+
|
|
241
|
+
### Default
|
|
242
|
+
|
|
243
|
+
`stories/StatusTracker/examples/Default.tsx`
|
|
244
|
+
|
|
245
|
+
```tsx
|
|
246
|
+
import React from "react";
|
|
247
|
+
import { StatusTracker, EStatusTrackerType } from "@sberbusiness/triplex-next";
|
|
248
|
+
import { WaitStsIcon84 } from "@sberbusiness/icons-next";
|
|
249
|
+
|
|
250
|
+
export const Default = () => (
|
|
251
|
+
// StatusTracker занимает всю ширину и высоту родителя — задайте их на контейнере.
|
|
252
|
+
<div style={{ maxWidth: 372, padding: 24, background: "#E9EDF1" }}>
|
|
253
|
+
<StatusTracker type={EStatusTrackerType.WAITING}>
|
|
254
|
+
<StatusTracker.Media>
|
|
255
|
+
<WaitStsIcon84 />
|
|
256
|
+
</StatusTracker.Media>
|
|
257
|
+
<StatusTracker.Header>
|
|
258
|
+
<StatusTracker.Header.Title>Документ в обработке</StatusTracker.Header.Title>
|
|
259
|
+
<StatusTracker.Header.Description>
|
|
260
|
+
Документ ожидает ответ от банка. Обычно обработка занимает несколько минут.
|
|
261
|
+
</StatusTracker.Header.Description>
|
|
262
|
+
</StatusTracker.Header>
|
|
263
|
+
</StatusTracker>
|
|
264
|
+
</div>
|
|
265
|
+
);
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
### Types
|
|
269
|
+
|
|
270
|
+
`stories/StatusTracker/examples/Types.tsx`
|
|
271
|
+
|
|
272
|
+
```tsx
|
|
273
|
+
import React from "react";
|
|
274
|
+
import { StatusTracker, EStatusTrackerType, EMarkerStatus, EComponentSize } from "@sberbusiness/triplex-next";
|
|
275
|
+
import { WaitStsIcon84, WarningStsIcon84, ErrorStsIcon84, SuccessStsIcon84 } from "@sberbusiness/icons-next";
|
|
276
|
+
|
|
277
|
+
/** Иконка и подпись статуса для каждого типа статус-трекера. */
|
|
278
|
+
const TYPE_TO_CONTENT_MAP: Record<EStatusTrackerType, { icon: React.ReactNode; status: EMarkerStatus; text: string }> =
|
|
279
|
+
{
|
|
280
|
+
[EStatusTrackerType.DRAFT]: {
|
|
281
|
+
icon: <WaitStsIcon84 />,
|
|
282
|
+
status: EMarkerStatus.WAITING,
|
|
283
|
+
text: "Черновик",
|
|
284
|
+
},
|
|
285
|
+
[EStatusTrackerType.WAITING]: {
|
|
286
|
+
icon: <WaitStsIcon84 />,
|
|
287
|
+
status: EMarkerStatus.WAITING,
|
|
288
|
+
text: "В обработке",
|
|
289
|
+
},
|
|
290
|
+
[EStatusTrackerType.WARNING]: {
|
|
291
|
+
icon: <WarningStsIcon84 />,
|
|
292
|
+
status: EMarkerStatus.WARNING,
|
|
293
|
+
text: "Требуется исправление",
|
|
294
|
+
},
|
|
295
|
+
[EStatusTrackerType.REJECTED]: {
|
|
296
|
+
icon: <ErrorStsIcon84 />,
|
|
297
|
+
status: EMarkerStatus.ERROR,
|
|
298
|
+
text: "Отклонён банком",
|
|
299
|
+
},
|
|
300
|
+
[EStatusTrackerType.APPROVED]: {
|
|
301
|
+
icon: <SuccessStsIcon84 />,
|
|
302
|
+
status: EMarkerStatus.SUCCESS,
|
|
303
|
+
text: "Исполнен",
|
|
304
|
+
},
|
|
305
|
+
};
|
|
306
|
+
|
|
307
|
+
const TYPES = Object.values(EStatusTrackerType);
|
|
308
|
+
|
|
309
|
+
export const Types = () => (
|
|
310
|
+
<div style={{ display: "flex", flexWrap: "wrap", gap: 24 }}>
|
|
311
|
+
{TYPES.map((type) => (
|
|
312
|
+
<div key={type} style={{ width: 320 }}>
|
|
313
|
+
<div style={{ marginBottom: 8, fontSize: 16, fontWeight: 700 }}>{type.toUpperCase()}</div>
|
|
314
|
+
<div style={{ padding: 24, background: "#E9EDF1" }}>
|
|
315
|
+
<StatusTracker type={type}>
|
|
316
|
+
<StatusTracker.Media>{TYPE_TO_CONTENT_MAP[type].icon}</StatusTracker.Media>
|
|
317
|
+
<StatusTracker.Body>
|
|
318
|
+
<StatusTracker.Body.Status
|
|
319
|
+
status={TYPE_TO_CONTENT_MAP[type].status}
|
|
320
|
+
size={EComponentSize.LG}
|
|
321
|
+
>
|
|
322
|
+
{TYPE_TO_CONTENT_MAP[type].text}
|
|
323
|
+
</StatusTracker.Body.Status>
|
|
324
|
+
</StatusTracker.Body>
|
|
325
|
+
</StatusTracker>
|
|
326
|
+
</div>
|
|
327
|
+
</div>
|
|
328
|
+
))}
|
|
329
|
+
</div>
|
|
330
|
+
);
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
### VerticalAlign
|
|
334
|
+
|
|
335
|
+
`stories/StatusTracker/examples/VerticalAlign.tsx`
|
|
336
|
+
|
|
337
|
+
```tsx
|
|
338
|
+
import React from "react";
|
|
339
|
+
import { StatusTracker, EStatusTrackerType, EStatusTrackerVerticalAlign } from "@sberbusiness/triplex-next";
|
|
340
|
+
|
|
341
|
+
const VERTICAL_ALIGNS = Object.values(EStatusTrackerVerticalAlign);
|
|
342
|
+
|
|
343
|
+
export const VerticalAlign = () => (
|
|
344
|
+
<div style={{ display: "flex", flexWrap: "wrap", gap: 24 }}>
|
|
345
|
+
{VERTICAL_ALIGNS.map((verticalAlign) => (
|
|
346
|
+
<div key={verticalAlign} style={{ width: 320 }}>
|
|
347
|
+
<div style={{ marginBottom: 8, fontSize: 16, fontWeight: 700 }}>{verticalAlign.toUpperCase()}</div>
|
|
348
|
+
{/* Контейнер выше содержимого карточки — только так видно разницу выравниваний. */}
|
|
349
|
+
<div style={{ height: 420, padding: 24, background: "#E9EDF1" }}>
|
|
350
|
+
<StatusTracker type={EStatusTrackerType.DRAFT} verticalAlign={verticalAlign}>
|
|
351
|
+
<StatusTracker.Header>
|
|
352
|
+
<StatusTracker.Header.Title>Черновик документа</StatusTracker.Header.Title>
|
|
353
|
+
<StatusTracker.Header.Description>
|
|
354
|
+
Документ создан без ошибок и ещё не отправлен в банк.
|
|
355
|
+
</StatusTracker.Header.Description>
|
|
356
|
+
</StatusTracker.Header>
|
|
357
|
+
</StatusTracker>
|
|
358
|
+
</div>
|
|
359
|
+
</div>
|
|
360
|
+
))}
|
|
361
|
+
</div>
|
|
362
|
+
);
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
### WithMediaOnly
|
|
366
|
+
|
|
367
|
+
`stories/StatusTracker/examples/WithMediaOnly.tsx`
|
|
368
|
+
|
|
369
|
+
```tsx
|
|
370
|
+
import React from "react";
|
|
371
|
+
import { StatusTracker, EStatusTrackerType, EStatusTrackerVerticalAlign } from "@sberbusiness/triplex-next";
|
|
372
|
+
import { WaitStsIcon84 } from "@sberbusiness/icons-next";
|
|
373
|
+
|
|
374
|
+
export const WithMediaOnly = () => (
|
|
375
|
+
<div style={{ maxWidth: 372, padding: 24, background: "#E9EDF1" }}>
|
|
376
|
+
<StatusTracker type={EStatusTrackerType.WARNING} verticalAlign={EStatusTrackerVerticalAlign.MIDDLE}>
|
|
377
|
+
<StatusTracker.Media>
|
|
378
|
+
<WaitStsIcon84 />
|
|
379
|
+
</StatusTracker.Media>
|
|
380
|
+
</StatusTracker>
|
|
381
|
+
</div>
|
|
382
|
+
);
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
### Example
|
|
386
|
+
|
|
387
|
+
`stories/StatusTracker/examples/Example.tsx`
|
|
388
|
+
|
|
389
|
+
```tsx
|
|
390
|
+
import React from "react";
|
|
391
|
+
import {
|
|
392
|
+
StatusTracker,
|
|
393
|
+
EStatusTrackerType,
|
|
394
|
+
EStatusTrackerVerticalAlign,
|
|
395
|
+
EMarkerStatus,
|
|
396
|
+
EComponentSize,
|
|
397
|
+
EAlertType,
|
|
398
|
+
EButtonTheme,
|
|
399
|
+
} from "@sberbusiness/triplex-next";
|
|
400
|
+
import { WarningStsIcon84 } from "@sberbusiness/icons-next";
|
|
401
|
+
|
|
402
|
+
export const Example = () => (
|
|
403
|
+
<div style={{ maxWidth: 372, padding: 24, background: "#E9EDF1" }}>
|
|
404
|
+
<StatusTracker type={EStatusTrackerType.WARNING} verticalAlign={EStatusTrackerVerticalAlign.TOP}>
|
|
405
|
+
<StatusTracker.Media>
|
|
406
|
+
<WarningStsIcon84 />
|
|
407
|
+
</StatusTracker.Media>
|
|
408
|
+
<StatusTracker.Header>
|
|
409
|
+
<StatusTracker.Header.Title>Платёжное поручение № 122</StatusTracker.Header.Title>
|
|
410
|
+
<StatusTracker.Header.Sum amountProps={{ value: "123747.123", currency: "₽" }} />
|
|
411
|
+
<StatusTracker.Header.Description>
|
|
412
|
+
ООО «Ромашка», счёт 40702810×××××××××123
|
|
413
|
+
</StatusTracker.Header.Description>
|
|
414
|
+
</StatusTracker.Header>
|
|
415
|
+
<StatusTracker.Body>
|
|
416
|
+
<StatusTracker.Body.StatusGroup>
|
|
417
|
+
<StatusTracker.Body.Status status={EMarkerStatus.WARNING} size={EComponentSize.LG}>
|
|
418
|
+
Требуется исправление
|
|
419
|
+
</StatusTracker.Body.Status>
|
|
420
|
+
<StatusTracker.Body.Status status={EMarkerStatus.WAITING} size={EComponentSize.LG}>
|
|
421
|
+
Не отправлено в банк
|
|
422
|
+
</StatusTracker.Body.Status>
|
|
423
|
+
</StatusTracker.Body.StatusGroup>
|
|
424
|
+
<StatusTracker.Body.Alert type={EAlertType.WARNING} closable onClose={() => {}}>
|
|
425
|
+
Проверьте назначение платежа: банк вернул документ на доработку.
|
|
426
|
+
</StatusTracker.Body.Alert>
|
|
427
|
+
</StatusTracker.Body>
|
|
428
|
+
<StatusTracker.Footer>
|
|
429
|
+
<StatusTracker.Footer.Button theme={EButtonTheme.GENERAL} size={EComponentSize.MD} onClick={() => {}}>
|
|
430
|
+
Исправить
|
|
431
|
+
</StatusTracker.Footer.Button>
|
|
432
|
+
<StatusTracker.Footer.Button theme={EButtonTheme.SECONDARY} size={EComponentSize.MD} onClick={() => {}}>
|
|
433
|
+
Удалить документ
|
|
434
|
+
</StatusTracker.Footer.Button>
|
|
435
|
+
<StatusTracker.Footer.Description>
|
|
436
|
+
После исправления документ нужно отправить в банк повторно.
|
|
437
|
+
</StatusTracker.Footer.Description>
|
|
438
|
+
</StatusTracker.Footer>
|
|
439
|
+
</StatusTracker>
|
|
440
|
+
</div>
|
|
441
|
+
);
|
|
442
|
+
```
|
|
443
|
+
|