@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.
Files changed (85) hide show
  1. package/README.md +7 -6
  2. package/bundle/components/AlertContext.md +11 -8
  3. package/bundle/components/AlertProcess.md +16 -12
  4. package/bundle/components/Badge.md +6 -3
  5. package/bundle/components/BodyPage.md +72 -4
  6. package/bundle/components/Button.md +46 -43
  7. package/bundle/components/ButtonDropdownExtended.md +3 -2
  8. package/bundle/components/ButtonIcon.md +7 -4
  9. package/bundle/components/Calendar.md +62 -59
  10. package/bundle/components/Caption.md +26 -23
  11. package/bundle/components/Checkbox.md +32 -29
  12. package/bundle/components/CheckboxTreeExtended.md +9 -5
  13. package/bundle/components/Chip.md +44 -41
  14. package/bundle/components/CodeText.md +26 -23
  15. package/bundle/components/Col.md +1 -2
  16. package/bundle/components/CollapsibleTree.md +8 -5
  17. package/bundle/components/CollapsibleTreeExtended.md +6 -1
  18. package/bundle/components/DatePickerExtended.md +409 -262
  19. package/bundle/components/Dropdown.md +33 -28
  20. package/bundle/components/EmptyView.md +12 -5
  21. package/bundle/components/ExpandAnimation.md +263 -218
  22. package/bundle/components/Footer.md +235 -278
  23. package/bundle/components/FooterPage.md +6 -2
  24. package/bundle/components/FormField.md +44 -41
  25. package/bundle/components/FormGroup.md +192 -52
  26. package/bundle/components/Header.md +491 -211
  27. package/bundle/components/HeaderPage.md +6 -2
  28. package/bundle/components/ImageGallery.md +33 -34
  29. package/bundle/components/ImageGalleryExtended.md +33 -34
  30. package/bundle/components/Island.md +52 -14
  31. package/bundle/components/LightBox.md +25 -18
  32. package/bundle/components/Link.md +211 -96
  33. package/bundle/components/ListActionItem.md +7 -4
  34. package/bundle/components/ListItem.md +11 -8
  35. package/bundle/components/ListItemControlsButton.md +16 -13
  36. package/bundle/components/ListItemControlsButtonDropdown.md +9 -6
  37. package/bundle/components/ListItemSelectable.md +7 -4
  38. package/bundle/components/ListMasterFooter.md +8 -5
  39. package/bundle/components/ListMasterHeader.md +8 -5
  40. package/bundle/components/ListSortableItem.md +11 -8
  41. package/bundle/components/ListTableItem.md +7 -4
  42. package/bundle/components/LoaderMiddle.md +7 -4
  43. package/bundle/components/LoaderScreen.md +11 -8
  44. package/bundle/components/LoaderSmall.md +7 -4
  45. package/bundle/components/Marker.md +184 -69
  46. package/bundle/components/MarkerStatus.md +206 -88
  47. package/bundle/components/MaskedField.md +2 -4
  48. package/bundle/components/MasterTable.md +602 -0
  49. package/bundle/components/ModalWindow.md +7 -4
  50. package/bundle/components/MultiselectField.md +2183 -132
  51. package/bundle/components/Notification.md +12 -9
  52. package/bundle/components/Overlay.md +33 -5
  53. package/bundle/components/Page.md +2 -2
  54. package/bundle/components/Pagination.md +27 -21
  55. package/bundle/components/Row.md +1 -1
  56. package/bundle/components/SelectExtendedField.md +3 -3
  57. package/bundle/components/SelectField.md +466 -148
  58. package/bundle/components/SliderExtended.md +39 -36
  59. package/bundle/components/SmallInput.md +194 -51
  60. package/bundle/components/Suggest.md +535 -99
  61. package/bundle/components/SwipeableArea.md +428 -79
  62. package/bundle/components/TableBasic.md +2302 -0
  63. package/bundle/components/TabsExtended.md +24 -21
  64. package/bundle/components/Tag.md +263 -78
  65. package/bundle/components/Text.md +28 -25
  66. package/bundle/components/TextField.md +3 -4
  67. package/bundle/components/ThemeProvider.md +50 -1
  68. package/bundle/components/Title.md +26 -23
  69. package/bundle/components/Tooltip.md +24 -21
  70. package/bundle/components/TopOverlay.md +368 -89
  71. package/bundle/components/TreeView.md +343 -166
  72. package/bundle/components/TreeViewNode.md +436 -0
  73. package/bundle/guides/codestyle.md +3 -0
  74. package/bundle/guides/commits.md +106 -26
  75. package/bundle/guides/context.md +84 -12
  76. package/bundle/guides/guidelines.md +321 -0
  77. package/bundle/guides/template.md +22 -12
  78. package/bundle/manifest.json +54 -20
  79. package/bundle/release-notes/1.44.0.mdx +113 -0
  80. package/bundle/release-notes/1.45.0.mdx +124 -0
  81. package/bundle/release-notes/1.46.0.mdx +7 -0
  82. package/bundle/tokens.json +6362 -0
  83. package/dist/index.js +177 -28
  84. package/dist/index.js.map +1 -1
  85. 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
- - --triplex-next-Tabs-Type1_Background
7
- - --triplex-next-Tabs-Type2_Background
8
- - --triplex-next-Tabs-Type1_Tab_Background_Default
9
- - --triplex-next-Tabs-Type2_Tab_Background_Default
10
- - --triplex-next-Tabs-Type1_Tab_Background_Hover
11
- - --triplex-next-Tabs-Type2_Tab_Background_Hover
12
- - --triplex-next-Tabs-Type1_Tab_Background_Selected
13
- - --triplex-next-Tabs-Type2_Tab_Background_Selected
14
- - --triplex-next-Tabs-Tab_BorderColor_Default
15
- - --triplex-next-Tabs-Tab_BorderColor_Focus
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
- --triplex-next-Tabs-Type1_Background
95
- --triplex-next-Tabs-Type2_Background
96
- --triplex-next-Tabs-Type1_Tab_Background_Default
97
- --triplex-next-Tabs-Type2_Tab_Background_Default
98
- --triplex-next-Tabs-Type1_Tab_Background_Hover
99
- --triplex-next-Tabs-Type2_Tab_Background_Hover
100
- --triplex-next-Tabs-Type1_Tab_Background_Selected
101
- --triplex-next-Tabs-Type2_Tab_Background_Selected
102
- --triplex-next-Tabs-Tab_BorderColor_Default
103
- --triplex-next-Tabs-Tab_BorderColor_Focus
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
- Собственного префикса `--triplex-next-TabsExtended-*` у компонента нет: переименование токенов `Tabs` ломает оба компонента сразу.
109
+ Собственной группы токенов `TabsExtended` нет: переименование токенов группы `Tabs` ломает оба компонента сразу.
107
110
 
108
111
  ---
109
112
 
@@ -1,10 +1,9 @@
1
1
  ---
2
2
  component: Tag
3
- category: Data Display
4
- figma-node: ""
5
- figma-file: ""
6
- related: [TagColor, TagGroup, ButtonIcon]
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
- Структура: `<span>` с `Text` контентом + опциональная кнопка редактирования
18
- (`ButtonIcon` с edit-иконкой) + всегда кнопка удаления (`ButtonIcon` с
19
- cross-иконкой). Иконки масштабируются по `size` (16/20/24).
15
+ Тег — компактная плашка с выбранным значением параметра и кнопками управления им: удалением
16
+ и, опционально, редактированием. Типичное место — строка применённых фильтров или список выбранных
17
+ в форме значений, где пользователь должен видеть выбор и уметь его снять.
20
18
 
21
- Используй когда: нужно показать выбранное значение со встроенной возможностью
22
- удалить или редактировать. Для цветной маркировки (categorical labels) —
23
- `TagColor`. Для управления коллекцией тегов — `TagGroup`.
19
+ Используй когда: значение выбрано пользователем и его нужно показать вместе с возможностью убрать
20
+ или изменить.
21
+ Не используй когда: нужна неинтерактивная цветная метка статуса — это `TagColor`, у него нет кнопок,
22
+ но есть `status`. Нужен интерактивный элемент выбора фильтра (открывает выпадающий список,
23
+ хранит выбор) — это семейство `Chip`.
24
24
 
25
25
  ---
26
26
 
27
- ## Файловая структура
27
+ ## Варианты и props
28
28
 
29
- ```text
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
- ## Публичный API
36
+ ### Опциональные props
41
37
 
42
- ### `ITagProps`
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
- ```ts
45
- extends HTMLAttributes<HTMLSpanElement>
46
- ```
47
+ Остальные props — стандартные атрибуты `span` (`ITagProps extends React.HTMLAttributes<HTMLSpanElement>`),
48
+ уходят на корневой элемент через `...restProps`.
47
49
 
48
- | Prop | Тип | Default | Описание |
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
- Иконки — `paletteIndex={5}` (приглушённая палитра).
52
+ Две кнопки живут по разным правилам, и это легко перепутать:
69
53
 
70
- ---
54
+ - кнопка **редактирования** рендерится только при переданном `onEdit`;
55
+ - кнопка **удаления** рендерится всегда, даже без `onRemove` — тогда клик по ней просто ничего
56
+ не делает.
71
57
 
72
- ## Поведение
58
+ ### Порядок обработчиков клика
73
59
 
74
- ### Edit-кнопка
60
+ `onClick` внутри `editButtonProps` / `removeButtonProps` не заменяет `onEdit` / `onRemove`,
61
+ а вызывается **после** него: компонент вынимает `onClick` из этих props и вешает на кнопку
62
+ собственный обработчик, который сначала зовёт колбэк тега, потом пользовательский `onClick`.
75
63
 
76
- - Рендерится **только** если передан `onEdit`.
77
- - `onClick` объединяет `onEdit(id)` + `editButtonProps.onClick(event)`.
64
+ ---
78
65
 
79
- ### Remove-кнопка
66
+ ## Дизайн-токены
80
67
 
81
- - Рендерится **всегда** (даже без `onRemove`).
82
- - `onClick` вызывает `onRemove?.(id)` (опционально) + `removeButtonProps.onClick(event)`.
83
- - Если `onRemove` не передан — кнопка остаётся видимой, но клик ничего не делает (кроме `removeButtonProps.onClick`).
68
+ Переопределяются через `ThemeProvider` (prop `tokens`) — см. `ThemeProvider-ai.md` →
69
+ «Как переопределять токены». Значения по умолчанию — `src/components/DesignTokens/components/Tag.ts`.
84
70
 
85
- ### Disabled
71
+ ```text
72
+ Tag.Background
73
+ ```
86
74
 
87
- - `Text type = DISABLED`.
88
- - `ButtonIcon disabled` — обе кнопки.
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
- - **`forwardRef<HTMLSpanElement>`** — не убирать.
95
- - **`size` обязателен** — нет default'а; передавать всегда.
96
- - **Remove-кнопка всегда в DOM** — даже без `onRemove`. Если нужно скрыть — `display:none` через `removeButtonProps.style` (или собственная обёртка); поведение `Tag` это не поддерживает напрямую.
97
- - **`onEdit` определяет видимость edit-кнопки** — единственный механизм. `editButtonProps` без `onEdit` не отрендерит кнопку.
98
- - **`id` прокидывается ТОЛЬКО в колбэки** (`onEdit`/`onRemove`), не в DOM. Если нужен HTML id — через `restProps`.
99
- - **Иконки `paletteIndex={5}`** — намеренно. Менять только координированно с дизайн-системой.
100
- - **`Text` size маппится через `sizeToTextSizeMap`**, иконки — через `sizeTo{Edit,Remove}IconMap`. Все три должны обновляться синхронно при добавлении нового размера.
101
- - **Корень — `<span>`**, не `<div>` — чтобы тег был inline-friendly.
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
- - Корневой `<span>` без явной ARIA-роли — потребитель должен задать смысл через `aria-label` или родительский контекст (`TagGroup`).
108
- - Edit/Remove кнопки — `<button>` через `ButtonIcon`; добавлять `aria-label` через `editButtonProps`/`removeButtonProps` (например, `aria-label="Удалить тег Москва"`).
109
- - `disabled` отключает кнопки (`aria-disabled` + `disabled` атрибут от `ButtonIcon`).
110
- - Иконки декоративные — содержание описывается через `aria-label` кнопки.
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
- - `TagColor` — категориальные цветные теги (без edit/remove).
117
- - `TagGroup` — контейнер для коллекции тегов (с overflow).
118
- - `ButtonIcon` — кнопки edit/remove.
119
- - `Typography.Text` — текст внутри.
120
- - `@sberbusiness/icons-next` — `EditStrokeSrvIcon{16,20,24}`, `CrossStrokeSrvIcon{16,20,24}`.
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
- Примеры: `stories/Tag/examples/`
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-04-18 | Создан документ |
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
- - --triplex-next-Typography-Primary_Color
7
- - --triplex-next-Typography-PrimaryInvert_Color
8
- - --triplex-next-Typography-Complementary_Color
9
- - --triplex-next-Typography-ComplementaryInvert_Color
10
- - --triplex-next-Typography-Secondary_Color
11
- - --triplex-next-Typography-SecondaryInvert_Color
12
- - --triplex-next-Typography-Tertiary_Color
13
- - --triplex-next-Typography-TertiaryInvert_Color
14
- - --triplex-next-Typography-Disabled_Color
15
- - --triplex-next-Typography-DisabledInvert_Color
16
- - --triplex-next-Typography-Brand_Color
17
- - --triplex-next-Typography-BrandInvert_Color
18
- - --triplex-next-Typography-Info_Color
19
- - --triplex-next-Typography-InfoInvert_Color
20
- - --triplex-next-Typography-Success_Color
21
- - --triplex-next-Typography-SuccessInvert_Color
22
- - --triplex-next-Typography-Warning_Color
23
- - --triplex-next-Typography-WarningInvert_Color
24
- - --triplex-next-Typography-Error_Color
25
- - --triplex-next-Typography-ErrorInvert_Color
26
- - --triplex-next-Typography-System_Color
27
- - --triplex-next-Typography-SystemInvert_Color
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
- Цвета — только через CSS-переменные группы Typography (общие для всего семейства, см. frontmatter):
77
+ Переопределяются через `ThemeProvider` (prop `tokens`) — см. `ThemeProvider-ai.md` →
78
+ «Как переопределять токены». Значения по умолчанию — `src/components/DesignTokens/components/Typography.ts`.
79
+
80
+ Цвета — только через токены группы `Typography` (общие для всего семейства, см. frontmatter):
78
81
 
79
82
  ```text
80
- --triplex-next-Typography-{Type}_Color
81
- --triplex-next-Typography-{Type}Invert_Color
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
- Собственных CSS-токенов и стилей нет. Внешний вид полностью наследуется от семейства `FormField` (токены `--triplex-next-FormField-*` описаны в стилях `src/components/FormField/styles/`).
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
- - Barrel `index.ts` экспортирует `TextField` и `MaskedField` — состав экспортов не менять. `TextFieldBase` намеренно НЕ экспортируется — приватная база.
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`. На нём построены `TextField` и `MaskedField`. Описан здесь, отдельного AI.md не имеет.
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