@sberbusiness/triplex-next-mcp-server 1.43.0-beta → 1.45.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 +16 -12
- package/bundle/components/Badge.md +6 -3
- package/bundle/components/BodyPage.md +72 -4
- 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/Checkbox.md +32 -29
- package/bundle/components/CheckboxTreeExtended.md +9 -5
- package/bundle/components/Chip.md +44 -41
- package/bundle/components/CodeText.md +26 -23
- package/bundle/components/Col.md +1 -2
- package/bundle/components/CollapsibleTree.md +8 -5
- package/bundle/components/CollapsibleTreeExtended.md +6 -1
- package/bundle/components/DatePickerExtended.md +409 -262
- package/bundle/components/Dropdown.md +33 -28
- package/bundle/components/EmptyView.md +12 -5
- package/bundle/components/ExpandAnimation.md +263 -218
- package/bundle/components/Footer.md +235 -278
- package/bundle/components/FooterPage.md +6 -2
- package/bundle/components/FormField.md +44 -41
- package/bundle/components/FormGroup.md +192 -52
- package/bundle/components/Header.md +491 -211
- package/bundle/components/HeaderPage.md +6 -2
- package/bundle/components/ImageGallery.md +33 -34
- package/bundle/components/ImageGalleryExtended.md +33 -34
- package/bundle/components/Island.md +52 -14
- package/bundle/components/LightBox.md +25 -18
- 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 +2 -4
- package/bundle/components/MasterTable.md +602 -0
- package/bundle/components/ModalWindow.md +7 -4
- package/bundle/components/MultiselectField.md +2183 -132
- package/bundle/components/Notification.md +12 -9
- package/bundle/components/Overlay.md +33 -5
- package/bundle/components/Page.md +2 -2
- package/bundle/components/Pagination.md +27 -21
- 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 +2302 -0
- package/bundle/components/TabsExtended.md +24 -21
- package/bundle/components/Tag.md +263 -78
- 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 +368 -89
- package/bundle/components/TreeView.md +343 -166
- package/bundle/components/TreeViewNode.md +436 -0
- package/bundle/guides/codestyle.md +3 -0
- package/bundle/guides/commits.md +106 -26
- 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 +54 -20
- package/bundle/release-notes/1.44.0.mdx +113 -0
- package/bundle/release-notes/1.45.0.mdx +124 -0
- package/bundle/release-notes/1.46.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
|
@@ -3,16 +3,16 @@ component: TabsExtended
|
|
|
3
3
|
category: Tabs
|
|
4
4
|
related: [Tabs, TabsLine, Badge, Text]
|
|
5
5
|
tokens:
|
|
6
|
-
-
|
|
7
|
-
-
|
|
8
|
-
-
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
-
|
|
6
|
+
- Tabs.Type1_Background
|
|
7
|
+
- Tabs.Type2_Background
|
|
8
|
+
- Tabs.Type1_Tab_Background_Default
|
|
9
|
+
- Tabs.Type2_Tab_Background_Default
|
|
10
|
+
- Tabs.Type1_Tab_Background_Hover
|
|
11
|
+
- Tabs.Type2_Tab_Background_Hover
|
|
12
|
+
- Tabs.Type1_Tab_Background_Selected
|
|
13
|
+
- Tabs.Type2_Tab_Background_Selected
|
|
14
|
+
- Tabs.Tab_BorderColor_Default
|
|
15
|
+
- Tabs.Tab_BorderColor_Focus
|
|
16
16
|
stories: stories/TabsExtended/TabsExtended.stories.tsx
|
|
17
17
|
version: "1.0"
|
|
18
18
|
---
|
|
@@ -88,22 +88,25 @@ version: "1.0"
|
|
|
88
88
|
|
|
89
89
|
## Дизайн-токены
|
|
90
90
|
|
|
91
|
+
Переопределяются через `ThemeProvider` (prop `tokens`) — см. `ThemeProvider-ai.md` →
|
|
92
|
+
«Как переопределять токены». Значения по умолчанию — `src/components/DesignTokens/components/Tabs.ts`.
|
|
93
|
+
|
|
91
94
|
Компонент использует токены семейства `Tabs` — они общие с `Tabs`:
|
|
92
95
|
|
|
93
96
|
```text
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
97
|
+
Tabs.Type1_Background
|
|
98
|
+
Tabs.Type2_Background
|
|
99
|
+
Tabs.Type1_Tab_Background_Default
|
|
100
|
+
Tabs.Type2_Tab_Background_Default
|
|
101
|
+
Tabs.Type1_Tab_Background_Hover
|
|
102
|
+
Tabs.Type2_Tab_Background_Hover
|
|
103
|
+
Tabs.Type1_Tab_Background_Selected
|
|
104
|
+
Tabs.Type2_Tab_Background_Selected
|
|
105
|
+
Tabs.Tab_BorderColor_Default
|
|
106
|
+
Tabs.Tab_BorderColor_Focus
|
|
104
107
|
```
|
|
105
108
|
|
|
106
|
-
|
|
109
|
+
Собственной группы токенов `TabsExtended` нет: переименование токенов группы `Tabs` ломает оба компонента сразу.
|
|
107
110
|
|
|
108
111
|
---
|
|
109
112
|
|
package/bundle/components/Tag.md
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
---
|
|
2
2
|
component: Tag
|
|
3
|
-
category:
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
tokens: []
|
|
3
|
+
category: Tag
|
|
4
|
+
related: [TagGroup, TagColor, ButtonIcon, Text]
|
|
5
|
+
tokens:
|
|
6
|
+
- Tag.Background
|
|
8
7
|
stories: stories/Tag/Tag.stories.tsx
|
|
9
8
|
version: "1.0"
|
|
10
9
|
---
|
|
@@ -13,118 +12,153 @@ version: "1.0"
|
|
|
13
12
|
|
|
14
13
|
## Назначение
|
|
15
14
|
|
|
16
|
-
Тег
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
cross-иконкой). Иконки масштабируются по `size` (16/20/24).
|
|
15
|
+
Тег — компактная плашка с выбранным значением параметра и кнопками управления им: удалением
|
|
16
|
+
и, опционально, редактированием. Типичное место — строка применённых фильтров или список выбранных
|
|
17
|
+
в форме значений, где пользователь должен видеть выбор и уметь его снять.
|
|
20
18
|
|
|
21
|
-
Используй когда: нужно показать
|
|
22
|
-
|
|
23
|
-
|
|
19
|
+
Используй когда: значение выбрано пользователем и его нужно показать вместе с возможностью убрать
|
|
20
|
+
или изменить.
|
|
21
|
+
Не используй когда: нужна неинтерактивная цветная метка статуса — это `TagColor`, у него нет кнопок,
|
|
22
|
+
но есть `status`. Нужен интерактивный элемент выбора фильтра (открывает выпадающий список,
|
|
23
|
+
хранит выбор) — это семейство `Chip`.
|
|
24
24
|
|
|
25
25
|
---
|
|
26
26
|
|
|
27
|
-
##
|
|
27
|
+
## Варианты и props
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
src/components/Tag/
|
|
31
|
-
├── Tag.tsx # forwardRef<HTMLSpanElement, ITagProps>
|
|
32
|
-
├── types.ts # ITagProps
|
|
33
|
-
├── styles/Tag.module.less
|
|
34
|
-
├── __tests__/
|
|
35
|
-
└── index.ts
|
|
36
|
-
```
|
|
29
|
+
### Обязательные props
|
|
37
30
|
|
|
38
|
-
|
|
31
|
+
| Prop | Тип | Описание |
|
|
32
|
+
|---|---|---|
|
|
33
|
+
| `id` | `string` | Идентификатор тега. Рендерится атрибутом `id` на корневом `<span>` и уходит аргументом в `onEdit` и `onRemove` — по нему потребитель понимает, какой тег группы изменили. Значение должно быть уникальным в пределах документа |
|
|
34
|
+
| `size` | `EComponentSize` | Размер: SM (высота 20px) / MD (28px) / LG (32px). Задаёт высоту, внутренние отступы, размер текста (`ETextSize.B4` / `B3` / `B2`) и размер иконок (16 / 20 / 24) |
|
|
39
35
|
|
|
40
|
-
|
|
36
|
+
### Опциональные props
|
|
41
37
|
|
|
42
|
-
|
|
38
|
+
| Prop | Тип | По умолчанию | Описание |
|
|
39
|
+
|---|---|---|---|
|
|
40
|
+
| `children` | `React.ReactNode` | — | Контент тега. Рендерится внутри `Text`, длинный текст обрезается многоточием |
|
|
41
|
+
| `disabled` | `boolean` | `false` | Текст переключается на `EFontType.DISABLED`, обе кнопки получают `disabled` — но своё значение в `editButtonProps` / `removeButtonProps` его перекрывает |
|
|
42
|
+
| `onEdit` | `(id: string) => void` | — | Колбэк редактирования. **Управляет наличием кнопки редактирования** — без него кнопка не рендерится |
|
|
43
|
+
| `onRemove` | `(id: string) => void` | — | Колбэк удаления. На наличие кнопки удаления НЕ влияет — она рендерится всегда |
|
|
44
|
+
| `editButtonProps` | `IButtonIconProps` | — | Props кнопки редактирования. Здесь потребитель задаёт `aria-label` |
|
|
45
|
+
| `removeButtonProps` | `IButtonIconProps` | — | Props кнопки удаления. Здесь потребитель задаёт `aria-label` |
|
|
43
46
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
```
|
|
47
|
+
Остальные props — стандартные атрибуты `span` (`ITagProps extends React.HTMLAttributes<HTMLSpanElement>`),
|
|
48
|
+
уходят на корневой элемент через `...restProps`.
|
|
47
49
|
|
|
48
|
-
|
|
49
|
-
|---|---|---|---|
|
|
50
|
-
| `id` | `string` | — | Уникальный id; передаётся в `onEdit(id)` / `onRemove(id)`. |
|
|
51
|
-
| `size` | `EComponentSize` | — | **Обязателен** (нет default'а). Маппится на размер иконки и текста. |
|
|
52
|
-
| `disabled?` | `boolean` | — | Disabled-состояние; влияет на цвет текста (`EFontType.DISABLED`) и `disabled` обеих кнопок. |
|
|
53
|
-
| `onEdit?` | `(id: string) => void` | — | Если передан — рендерится edit-кнопка. |
|
|
54
|
-
| `onRemove?` | `(id: string) => void` | — | Колбэк удаления; **remove-кнопка рендерится всегда**. |
|
|
55
|
-
| `editButtonProps?` | `IButtonIconProps` | — | HTML/aria-атрибуты для edit-кнопки (объединяется с `onClick`). |
|
|
56
|
-
| `removeButtonProps?` | `IButtonIconProps` | — | HTML/aria-атрибуты для remove-кнопки. |
|
|
57
|
-
| `children` | `ReactNode` | — | Содержимое (текст тега). |
|
|
58
|
-
| `...HTMLAttributes<HTMLSpanElement>` | — | — | На корневой `<span>`. |
|
|
59
|
-
|
|
60
|
-
### Размер → иконка/текст
|
|
61
|
-
|
|
62
|
-
| `size` | Edit/Remove иконка | Text size |
|
|
63
|
-
|---|---|---|
|
|
64
|
-
| `SM` | `*StrokeSrvIcon16` | `B4` |
|
|
65
|
-
| `MD` | `*StrokeSrvIcon20` | `B3` |
|
|
66
|
-
| `LG` | `*StrokeSrvIcon24` | `B2` |
|
|
50
|
+
### Асимметрия кнопок
|
|
67
51
|
|
|
68
|
-
|
|
52
|
+
Две кнопки живут по разным правилам, и это легко перепутать:
|
|
69
53
|
|
|
70
|
-
|
|
54
|
+
- кнопка **редактирования** рендерится только при переданном `onEdit`;
|
|
55
|
+
- кнопка **удаления** рендерится всегда, даже без `onRemove` — тогда клик по ней просто ничего
|
|
56
|
+
не делает.
|
|
71
57
|
|
|
72
|
-
|
|
58
|
+
### Порядок обработчиков клика
|
|
73
59
|
|
|
74
|
-
|
|
60
|
+
`onClick` внутри `editButtonProps` / `removeButtonProps` не заменяет `onEdit` / `onRemove`,
|
|
61
|
+
а вызывается **после** него: компонент вынимает `onClick` из этих props и вешает на кнопку
|
|
62
|
+
собственный обработчик, который сначала зовёт колбэк тега, потом пользовательский `onClick`.
|
|
75
63
|
|
|
76
|
-
|
|
77
|
-
- `onClick` объединяет `onEdit(id)` + `editButtonProps.onClick(event)`.
|
|
64
|
+
---
|
|
78
65
|
|
|
79
|
-
|
|
66
|
+
## Дизайн-токены
|
|
80
67
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
- Если `onRemove` не передан — кнопка остаётся видимой, но клик ничего не делает (кроме `removeButtonProps.onClick`).
|
|
68
|
+
Переопределяются через `ThemeProvider` (prop `tokens`) — см. `ThemeProvider-ai.md` →
|
|
69
|
+
«Как переопределять токены». Значения по умолчанию — `src/components/DesignTokens/components/Tag.ts`.
|
|
84
70
|
|
|
85
|
-
|
|
71
|
+
```text
|
|
72
|
+
Tag.Background
|
|
73
|
+
```
|
|
86
74
|
|
|
87
|
-
|
|
88
|
-
-
|
|
75
|
+
Единственный собственный токен — фон плашки. Цвет текста задаёт `Text` через токены типографики
|
|
76
|
+
(`Typography-Primary_Color` / `Typography-Disabled_Color`), цвет иконок — палитра
|
|
77
|
+
`@sberbusiness/icons-next` (`paletteIndex={5}`), кольцо фокуса кнопок — `ButtonIcon`
|
|
78
|
+
(`Button-Icon_Shadow_Focus`).
|
|
79
|
+
|
|
80
|
+
Размерные значения (высоты 20/28/32px, отступы, `border-radius: 4px`, `gap: 2px`) заданы литералами
|
|
81
|
+
в `styles/Tag.module.less` — они специфичны для компонента.
|
|
89
82
|
|
|
90
83
|
---
|
|
91
84
|
|
|
92
85
|
## Инварианты
|
|
93
86
|
|
|
94
|
-
-
|
|
95
|
-
-
|
|
96
|
-
|
|
97
|
-
-
|
|
98
|
-
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
87
|
+
- `forwardRef<HTMLSpanElement>` — не убирать. Ref всегда указывает на корневой `<span>`.
|
|
88
|
+
- Корневой элемент — `<span>` (тег инлайновый, встаёт в строку текста и в `TagGroup`).
|
|
89
|
+
Менять на `div` нельзя.
|
|
90
|
+
- `displayName` — `"Tag"`. Не менять.
|
|
91
|
+
- `id` рендерится атрибутом на корневом `<span>` и одновременно служит бизнес-идентификатором
|
|
92
|
+
в `onEdit` / `onRemove`. Prop обязательный, поэтому идентификатор попадает в DOM у всех
|
|
93
|
+
потребителей: значение должно быть уникальным в пределах документа. Если бизнес-идентификатор
|
|
94
|
+
уже используется другим элементом страницы (типовой случай — тег выбранного значения и опция
|
|
95
|
+
списка в `MultiselectField`), тегу нужен свой префикс.
|
|
96
|
+
- Кнопка удаления рендерится безусловно, вне зависимости от `onRemove` — менять на условный
|
|
97
|
+
рендер нельзя без согласования, это изменит вёрстку у потребителей, не передающих `onRemove`.
|
|
98
|
+
- Порядок в DOM: текст → кнопка редактирования → кнопка удаления. Он же задаёт порядок фокуса,
|
|
99
|
+
на него опираются скриншот-тесты.
|
|
100
|
+
- Собственный `onClick` тега на кнопках всегда вызывается раньше пользовательского
|
|
101
|
+
`onClick` из `*ButtonProps`.
|
|
102
|
+
- Компонент не хардкодит текстовые строки: `aria-label` / `title` кнопок задаёт потребитель.
|
|
103
|
+
Библиотека мультиязычная.
|
|
104
|
+
- Экспорты `Tag` и `ITagProps` идут в barrel `src/components/Tag/index.ts` — сохранять.
|
|
105
|
+
- Ширина ограничена контейнером (`max-width: 100%`), текст обрезается многоточием
|
|
106
|
+
(`.content` с `overflow: hidden`, `text-overflow: ellipsis`, `min-width: 0`) — часть
|
|
107
|
+
визуального контракта, покрыта stories `WithOverflow` и `VisualTests`.
|
|
102
108
|
|
|
103
109
|
---
|
|
104
110
|
|
|
105
111
|
## Accessibility
|
|
106
112
|
|
|
107
|
-
-
|
|
108
|
-
|
|
109
|
-
- `
|
|
110
|
-
|
|
113
|
+
- Собственной ARIA-роли у тега нет: корневой `<span>` — контейнер. Роль группы задаёт `TagGroup`
|
|
114
|
+
(`role="group"`).
|
|
115
|
+
- Кнопки — `ButtonIcon` без текстового контента, поэтому **доступное имя обязан задать
|
|
116
|
+
потребитель**: `editButtonProps={{ "aria-label": "..." }}` и
|
|
117
|
+
`removeButtonProps={{ "aria-label": "..." }}`. Без них кнопки остаются безымянными
|
|
118
|
+
для скринридера. Компонент не подставляет умолчание намеренно — строки на конкретном языке
|
|
119
|
+
внутри библиотеки запрещены.
|
|
120
|
+
- Клавиатура: собственных обработчиков у тега нет, работает нативная семантика `<button>`
|
|
121
|
+
(Tab / Enter / Space). Порядок фокуса совпадает с порядком в DOM: сначала редактирование,
|
|
122
|
+
затем удаление.
|
|
123
|
+
- Кольцо фокуса рисует `ButtonIcon` через `:focus-visible`, то есть только при переходе
|
|
124
|
+
с клавиатуры.
|
|
125
|
+
- При `disabled` обе кнопки получают нативный `disabled` и выпадают из порядка фокуса,
|
|
126
|
+
колбэки не вызываются. `disabled` спредится до `editButtonProps` / `removeButtonProps`,
|
|
127
|
+
поэтому собственное значение в них перекрывает состояние тега — в отличие от `onClick`,
|
|
128
|
+
который тег вынимает из props принудительно.
|
|
111
129
|
|
|
112
130
|
---
|
|
113
131
|
|
|
114
132
|
## Связанные компоненты
|
|
115
133
|
|
|
116
|
-
- `
|
|
117
|
-
|
|
118
|
-
- `
|
|
119
|
-
|
|
120
|
-
|
|
134
|
+
- `TagGroup` — контейнер группы тегов (`role="group"`), задаёт раскладку и переносы;
|
|
135
|
+
собственный `size` передаётся ему отдельно, теги внутри свой `size` получают сами.
|
|
136
|
+
- `TagColor` — визуально похожая плашка, но неинтерактивная: без кнопок, зато со `status`
|
|
137
|
+
(`DEFAULT` / `SUCCESS` / `INFO` / `WARNING` / `ERROR`). Берётся, когда нужна метка состояния,
|
|
138
|
+
а не снимаемое значение.
|
|
139
|
+
- `ButtonIcon` — рендерится внутри как кнопка редактирования и удаления; от него тег получает
|
|
140
|
+
форму, состояние `disabled` и стили фокуса. Все props из `editButtonProps` / `removeButtonProps`
|
|
141
|
+
уходят именно на него.
|
|
142
|
+
- `Text` — рендерит контент тега; тег выбирает `size` (`ETextSize`) и `type` (`EFontType`)
|
|
143
|
+
по своим `size` и `disabled`.
|
|
121
144
|
|
|
122
145
|
---
|
|
123
146
|
|
|
124
147
|
## Stories
|
|
125
148
|
|
|
126
149
|
Основные истории: `stories/Tag/Tag.stories.tsx`
|
|
127
|
-
|
|
150
|
+
Файлы примеров: `stories/Tag/examples/`
|
|
151
|
+
|
|
152
|
+
| Story | Example file | Что демонстрирует |
|
|
153
|
+
|---|---|---|
|
|
154
|
+
| `Playground` | `Playground.tsx` | Интерактивный контроль `children`, `size`, `disabled` и наличия кнопки редактирования |
|
|
155
|
+
| `Default` | `Default.tsx` | Минимальный тег: контент и кнопка удаления |
|
|
156
|
+
| `Editable` | `Editable.tsx` | Тег с кнопкой редактирования — появляется вместе с `onEdit` |
|
|
157
|
+
| `Sizes` | `Sizes.tsx` | Размеры SM / MD / LG |
|
|
158
|
+
| `Disabled` | `Disabled.tsx` | Отключенное состояние: приглушённый текст и заблокированные кнопки |
|
|
159
|
+
| `WithCustomButtonProps` | `WithCustomButtonProps.tsx` | `editButtonProps` / `removeButtonProps`: `title`, `aria-label` и собственный `onClick` |
|
|
160
|
+
| `WithOverflow` | `WithOverflow.tsx` | Обрезка длинного контента многоточием по ширине контейнера |
|
|
161
|
+
| `VisualTests` | `VisualTests.tsx` | Матрица размеров и состояний плюс кольцо фокуса кнопки — для скриншот-тестов |
|
|
128
162
|
|
|
129
163
|
---
|
|
130
164
|
|
|
@@ -132,4 +166,155 @@ extends HTMLAttributes<HTMLSpanElement>
|
|
|
132
166
|
|
|
133
167
|
| Дата | Изменение |
|
|
134
168
|
|---|---|
|
|
135
|
-
| 2026-
|
|
169
|
+
| 2026-08-27 | `id` пробрасывается атрибутом на корневой `<span>` — раньше деструктурировался из props и в DOM не попадал (ломающее изменение). |
|
|
170
|
+
| 2026-08-26 | Создан документ. AI-рефакторинг (`displayName`, снят лишний `useCallback` с render-функций, константы приведены к UPPER_SNAKE_CASE, JSDoc на props), расширены unit-тесты, stories переведены на modern pattern. |
|
|
171
|
+
|
|
172
|
+
---
|
|
173
|
+
|
|
174
|
+
## Примеры использования
|
|
175
|
+
|
|
176
|
+
### Default
|
|
177
|
+
|
|
178
|
+
`stories/Tag/examples/Default.tsx`
|
|
179
|
+
|
|
180
|
+
```tsx
|
|
181
|
+
import React from "react";
|
|
182
|
+
import { Tag, EComponentSize } from "@sberbusiness/triplex-next";
|
|
183
|
+
|
|
184
|
+
export const Default = () => (
|
|
185
|
+
<Tag id="default-tag" size={EComponentSize.LG} onRemove={() => {}} removeButtonProps={{ "aria-label": "Удалить" }}>
|
|
186
|
+
Selected value
|
|
187
|
+
</Tag>
|
|
188
|
+
);
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### Editable
|
|
192
|
+
|
|
193
|
+
`stories/Tag/examples/Editable.tsx`
|
|
194
|
+
|
|
195
|
+
```tsx
|
|
196
|
+
import React from "react";
|
|
197
|
+
import { Tag, EComponentSize } from "@sberbusiness/triplex-next";
|
|
198
|
+
|
|
199
|
+
export const Editable = () => (
|
|
200
|
+
<Tag
|
|
201
|
+
id="editable-tag"
|
|
202
|
+
size={EComponentSize.LG}
|
|
203
|
+
onEdit={() => {}}
|
|
204
|
+
onRemove={() => {}}
|
|
205
|
+
editButtonProps={{ "aria-label": "Редактировать" }}
|
|
206
|
+
removeButtonProps={{ "aria-label": "Удалить" }}
|
|
207
|
+
>
|
|
208
|
+
Selected value
|
|
209
|
+
</Tag>
|
|
210
|
+
);
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
### Sizes
|
|
214
|
+
|
|
215
|
+
`stories/Tag/examples/Sizes.tsx`
|
|
216
|
+
|
|
217
|
+
```tsx
|
|
218
|
+
import React from "react";
|
|
219
|
+
import { Tag, EComponentSize } from "@sberbusiness/triplex-next";
|
|
220
|
+
|
|
221
|
+
const SIZES = Object.values(EComponentSize);
|
|
222
|
+
|
|
223
|
+
export const Sizes = () => (
|
|
224
|
+
<div style={{ display: "flex", flexDirection: "column", gap: 16 }}>
|
|
225
|
+
{SIZES.map((size) => (
|
|
226
|
+
<div key={size}>
|
|
227
|
+
<div style={{ marginBottom: 8, fontSize: 16, fontWeight: 700 }}>{size.toUpperCase()}</div>
|
|
228
|
+
<Tag
|
|
229
|
+
id={`${size}-tag`}
|
|
230
|
+
size={size}
|
|
231
|
+
onEdit={() => {}}
|
|
232
|
+
onRemove={() => {}}
|
|
233
|
+
editButtonProps={{ "aria-label": "Редактировать" }}
|
|
234
|
+
removeButtonProps={{ "aria-label": "Удалить" }}
|
|
235
|
+
>
|
|
236
|
+
Selected value
|
|
237
|
+
</Tag>
|
|
238
|
+
</div>
|
|
239
|
+
))}
|
|
240
|
+
</div>
|
|
241
|
+
);
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
### Disabled
|
|
245
|
+
|
|
246
|
+
`stories/Tag/examples/Disabled.tsx`
|
|
247
|
+
|
|
248
|
+
```tsx
|
|
249
|
+
import React from "react";
|
|
250
|
+
import { Tag, EComponentSize } from "@sberbusiness/triplex-next";
|
|
251
|
+
|
|
252
|
+
export const Disabled = () => (
|
|
253
|
+
<Tag
|
|
254
|
+
id="disabled-tag"
|
|
255
|
+
size={EComponentSize.LG}
|
|
256
|
+
disabled
|
|
257
|
+
onEdit={() => {}}
|
|
258
|
+
onRemove={() => {}}
|
|
259
|
+
editButtonProps={{ "aria-label": "Редактировать" }}
|
|
260
|
+
removeButtonProps={{ "aria-label": "Удалить" }}
|
|
261
|
+
>
|
|
262
|
+
Selected value
|
|
263
|
+
</Tag>
|
|
264
|
+
);
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
### WithCustomButtonProps
|
|
268
|
+
|
|
269
|
+
`stories/Tag/examples/WithCustomButtonProps.tsx`
|
|
270
|
+
|
|
271
|
+
```tsx
|
|
272
|
+
import React from "react";
|
|
273
|
+
import { Tag, EComponentSize } from "@sberbusiness/triplex-next";
|
|
274
|
+
|
|
275
|
+
export const WithCustomButtonProps = () => (
|
|
276
|
+
<Tag
|
|
277
|
+
id="custom-props-tag"
|
|
278
|
+
size={EComponentSize.LG}
|
|
279
|
+
onEdit={() => {}}
|
|
280
|
+
onRemove={() => {}}
|
|
281
|
+
editButtonProps={{
|
|
282
|
+
title: "Редактировать тег",
|
|
283
|
+
"aria-label": "Редактировать тег",
|
|
284
|
+
onClick: () => {},
|
|
285
|
+
}}
|
|
286
|
+
removeButtonProps={{
|
|
287
|
+
title: "Удалить тег",
|
|
288
|
+
"aria-label": "Удалить тег",
|
|
289
|
+
onClick: () => {},
|
|
290
|
+
}}
|
|
291
|
+
>
|
|
292
|
+
Selected value
|
|
293
|
+
</Tag>
|
|
294
|
+
);
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
### WithOverflow
|
|
298
|
+
|
|
299
|
+
`stories/Tag/examples/WithOverflow.tsx`
|
|
300
|
+
|
|
301
|
+
```tsx
|
|
302
|
+
import React from "react";
|
|
303
|
+
import { Tag, EComponentSize } from "@sberbusiness/triplex-next";
|
|
304
|
+
|
|
305
|
+
export const WithOverflow = () => (
|
|
306
|
+
<div style={{ maxWidth: 440 }}>
|
|
307
|
+
<Tag
|
|
308
|
+
id="long-tag"
|
|
309
|
+
size={EComponentSize.LG}
|
|
310
|
+
onEdit={() => {}}
|
|
311
|
+
onRemove={() => {}}
|
|
312
|
+
editButtonProps={{ "aria-label": "Редактировать" }}
|
|
313
|
+
removeButtonProps={{ "aria-label": "Удалить" }}
|
|
314
|
+
>
|
|
315
|
+
Very long tag text that should be truncated with ellipsis
|
|
316
|
+
</Tag>
|
|
317
|
+
</div>
|
|
318
|
+
);
|
|
319
|
+
```
|
|
320
|
+
|
|
@@ -3,28 +3,28 @@ component: Text
|
|
|
3
3
|
category: Typography
|
|
4
4
|
related: [Title, Caption, CodeText]
|
|
5
5
|
tokens:
|
|
6
|
-
-
|
|
7
|
-
-
|
|
8
|
-
-
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
-
|
|
18
|
-
-
|
|
19
|
-
-
|
|
20
|
-
-
|
|
21
|
-
-
|
|
22
|
-
-
|
|
23
|
-
-
|
|
24
|
-
-
|
|
25
|
-
-
|
|
26
|
-
-
|
|
27
|
-
-
|
|
6
|
+
- Typography.Primary_Color
|
|
7
|
+
- Typography.PrimaryInvert_Color
|
|
8
|
+
- Typography.Complementary_Color
|
|
9
|
+
- Typography.ComplementaryInvert_Color
|
|
10
|
+
- Typography.Secondary_Color
|
|
11
|
+
- Typography.SecondaryInvert_Color
|
|
12
|
+
- Typography.Tertiary_Color
|
|
13
|
+
- Typography.TertiaryInvert_Color
|
|
14
|
+
- Typography.Disabled_Color
|
|
15
|
+
- Typography.DisabledInvert_Color
|
|
16
|
+
- Typography.Brand_Color
|
|
17
|
+
- Typography.BrandInvert_Color
|
|
18
|
+
- Typography.Info_Color
|
|
19
|
+
- Typography.InfoInvert_Color
|
|
20
|
+
- Typography.Success_Color
|
|
21
|
+
- Typography.SuccessInvert_Color
|
|
22
|
+
- Typography.Warning_Color
|
|
23
|
+
- Typography.WarningInvert_Color
|
|
24
|
+
- Typography.Error_Color
|
|
25
|
+
- Typography.ErrorInvert_Color
|
|
26
|
+
- Typography.System_Color
|
|
27
|
+
- Typography.SystemInvert_Color
|
|
28
28
|
stories: stories/Typography/Text.stories.tsx
|
|
29
29
|
version: "1.0"
|
|
30
30
|
---
|
|
@@ -74,11 +74,14 @@ version: "1.0"
|
|
|
74
74
|
|
|
75
75
|
## Дизайн-токены
|
|
76
76
|
|
|
77
|
-
|
|
77
|
+
Переопределяются через `ThemeProvider` (prop `tokens`) — см. `ThemeProvider-ai.md` →
|
|
78
|
+
«Как переопределять токены». Значения по умолчанию — `src/components/DesignTokens/components/Typography.ts`.
|
|
79
|
+
|
|
80
|
+
Цвета — только через токены группы `Typography` (общие для всего семейства, см. frontmatter):
|
|
78
81
|
|
|
79
82
|
```text
|
|
80
|
-
|
|
81
|
-
|
|
83
|
+
Typography.{Type}_Color
|
|
84
|
+
Typography.{Type}Invert_Color
|
|
82
85
|
```
|
|
83
86
|
|
|
84
87
|
где `{Type}` ∈ Primary, Complementary, Secondary, Tertiary, Disabled, Brand, Info, Success, Warning, Error, System.
|
|
@@ -54,7 +54,7 @@ version: "1.0"
|
|
|
54
54
|
|
|
55
55
|
## Дизайн-токены
|
|
56
56
|
|
|
57
|
-
Собственных
|
|
57
|
+
Собственных токенов и стилей нет. Внешний вид полностью наследуется от семейства `FormField` (группа токенов `FormField`, стили — `src/components/FormField/styles/`).
|
|
58
58
|
|
|
59
59
|
---
|
|
60
60
|
|
|
@@ -62,7 +62,7 @@ version: "1.0"
|
|
|
62
62
|
|
|
63
63
|
- `forwardRef` на `TextField` и `TextFieldBase` — не убирать. Внешний `ref` указывает на корневой `<div>` `FormField`; ref на сам input — только через `inputProps.ref`.
|
|
64
64
|
- Публичный API (`ITextFieldProps`: `inputProps` + `label`/`prefix`/`postfix`/`description`/`counter` + унаследованные `size`/`status`/`active`) — изменение имён/типов/значений enum — breaking change.
|
|
65
|
-
-
|
|
65
|
+
- `TextFieldBase` намеренно НЕ экспортируется — приватная база.
|
|
66
66
|
- Известное ограничение контракта: `inputProps.ref` типизирован как `React.RefObject<HTMLInputElement>` (не `React.Ref`), callback-ref формально не проходит по типам. Исправление — breaking change, требует отдельной задачи.
|
|
67
67
|
- Уникальный `id` для связки label↔input генерируется через `lodash uniqueId` в `FormFieldInput` — не заменять на `useId` (React 17 совместимость через release-0).
|
|
68
68
|
- `description || counter` рендерятся в общем блоке `FormFieldDescription` — не разносить по отдельным блокам (изменит DOM и скриншоты).
|
|
@@ -80,8 +80,7 @@ version: "1.0"
|
|
|
80
80
|
|
|
81
81
|
## Связанные компоненты
|
|
82
82
|
|
|
83
|
-
- `TextFieldBase` (внутренний, не в barrel) — базовая раскладка `FormGroup`/`FormField` + слоты `prefix`/`children`/`label`/`postfix` и блок `description`/`counter`.
|
|
84
|
-
- `MaskedField` — сосед по папке: то же самое, но с `FormFieldMaskedInput` (ввод по маске) через prop `maskedInputProps`. Документируется отдельно.
|
|
83
|
+
- `TextFieldBase` (внутренний, не в barrel) — базовая раскладка `FormGroup`/`FormField` + слоты `prefix`/`children`/`label`/`postfix` и блок `description`/`counter`. Описан здесь, отдельного AI.md не имеет.
|
|
85
84
|
- `FormField` / `FormFieldInput` и слоты семейства — низкоуровневые строительные блоки; используются напрямую, когда нужна нестандартная композиция.
|
|
86
85
|
- `FormGroup` — контейнер вертикальной раскладки поля и описания.
|
|
87
86
|
- `FormFieldClear` — кнопка очистки, передаётся в `postfix`.
|
|
@@ -65,7 +65,55 @@ version: "1.0"
|
|
|
65
65
|
```
|
|
66
66
|
|
|
67
67
|
Версия в имени переменной — версия пакета с точками, заменёнными на дефисы
|
|
68
|
-
(см. `DesignTokenUtils.getCSSVariableByTokenGroup`).
|
|
68
|
+
(см. `DesignTokenUtils.getCSSVariableByTokenGroup`). Из-за версии эти имена нельзя
|
|
69
|
+
использовать в коде потребителя — они меняются каждый релиз. Публичный способ
|
|
70
|
+
поменять оформление — prop `tokens`.
|
|
71
|
+
|
|
72
|
+
### Как переопределять токены
|
|
73
|
+
|
|
74
|
+
Путь токена — `{Группа}.{Токен}`. Объект `tokens` плоский: группы лежат на верхнем
|
|
75
|
+
уровне, вложенности `core` / `components` в API нет.
|
|
76
|
+
|
|
77
|
+
```tsx
|
|
78
|
+
import {useRef} from "react";
|
|
79
|
+
import {ThemeProvider, ETriplexNextTheme} from "@sberbusiness/triplex-next";
|
|
80
|
+
|
|
81
|
+
// tokens сравнивается по ссылке — объект вынесен из рендера, иначе <style> пересобирается
|
|
82
|
+
// на каждый рендер.
|
|
83
|
+
const TOKENS = {
|
|
84
|
+
// core-токен: палитра, меняется сразу для всех компонентов, которые на неё ссылаются
|
|
85
|
+
ColorBrand: {50: {value: "#1D6BF3"}},
|
|
86
|
+
// компонентный токен: значением или ссылкой на core-токен
|
|
87
|
+
Calendar: {
|
|
88
|
+
Background: {value: "#FFFFFF"},
|
|
89
|
+
View_Item_Background_Selected_Default: {ref: "ColorBrand.50"},
|
|
90
|
+
},
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
const App = () => {
|
|
94
|
+
const scopeRef = useRef<HTMLDivElement>(null);
|
|
95
|
+
|
|
96
|
+
return (
|
|
97
|
+
<ThemeProvider theme={ETriplexNextTheme.LIGHT} tokens={TOKENS} scopeRef={scopeRef}>
|
|
98
|
+
<div ref={scopeRef}>…</div>
|
|
99
|
+
</ThemeProvider>
|
|
100
|
+
);
|
|
101
|
+
};
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Правила:
|
|
105
|
+
|
|
106
|
+
- значение задаётся либо `{value: "<css>"}`, либо `{ref: "<Группа>.<Токен>"}`;
|
|
107
|
+
- `ref` указывает **только на core-токен**: тип ссылок генерируется из `DesignTokensCore`
|
|
108
|
+
(`scripts/generateRefTokensTypes.ts`), ссылка на компонентный токен не скомпилируется;
|
|
109
|
+
- одним объектом можно переопределить сколько угодно групп — и core, и компонентные;
|
|
110
|
+
- переопределения мерджатся поверх токенов темы (`defaultsDeep`), тема при этом
|
|
111
|
+
продолжает действовать: то, что не переопределено, берётся из неё;
|
|
112
|
+
- действуют внутри `scopeRef`; вложенные `ThemeProvider` переопределяют друг друга.
|
|
113
|
+
|
|
114
|
+
Где смотреть значения по умолчанию: `src/components/DesignTokens/DesignTokensCore.ts`
|
|
115
|
+
(палитра) и `src/components/DesignTokens/components/{Группа}.ts` (пара «светлая /
|
|
116
|
+
тёмная тема» для каждого компонентного токена).
|
|
69
117
|
|
|
70
118
|
---
|
|
71
119
|
|
|
@@ -145,6 +193,7 @@ version: "1.0"
|
|
|
145
193
|
|---|---|
|
|
146
194
|
| 2026-08-05 | Создан документ. AI-рефакторинг: JSDoc на props и экспортах, ключ тега стилей вынесен в хелпер, упрощён эффект `ThemeProviderView`, добавлены unit-тесты `ThemeProviderView` и `useToken`, stories переведены на modern pattern |
|
|
147
195
|
| 2026-08-05 | `related` сокращён до `useToken`. Удалён неактуальный комментарий про относительный импорт в `ThemeProviderView` |
|
|
196
|
+
| 2026-08-31 | Добавлен раздел «Как переопределять токены»: путь `{Группа}.{Токен}`, плоская форма prop `tokens`, `value` / `ref` |
|
|
148
197
|
|
|
149
198
|
---
|
|
150
199
|
|