@sberbusiness/triplex-next-mcp-server 1.41.0-beta → 1.43.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/bundle/components/AlertProcess.md +460 -0
- package/bundle/components/Amount.md +145 -169
- package/bundle/components/Badge.md +155 -219
- package/bundle/components/Body.md +108 -116
- package/bundle/components/Button.md +1 -0
- package/bundle/components/CarouselExtended.md +355 -194
- package/bundle/components/Checkbox.md +7 -1
- package/bundle/components/CheckboxTreeExtended.md +149 -248
- package/bundle/components/CheckboxXGroup.md +2 -0
- package/bundle/components/CheckboxYGroup.md +7 -2
- package/bundle/components/ChipGroup.md +195 -126
- package/bundle/components/ComposedKeyDownListener.md +323 -0
- package/bundle/components/FooterPage.md +2 -1
- package/bundle/components/HeaderPage.md +2 -1
- package/bundle/components/Island.md +100 -12
- package/bundle/components/KeyDownListener.md +11 -72
- package/bundle/components/LightBox.md +6 -0
- package/bundle/components/LoaderSmall.md +230 -0
- package/bundle/components/MaskedField.md +481 -0
- package/bundle/components/MediaWidth.md +252 -108
- package/bundle/components/MobileView.md +192 -68
- package/bundle/components/ModalWindow.md +3 -1
- package/bundle/components/Notification.md +21 -3
- package/bundle/components/Page.md +3 -1
- package/bundle/components/Pagination.md +20 -0
- package/bundle/components/SelectExtendedField.md +691 -236
- package/bundle/components/SliderExtended.md +358 -222
- package/bundle/components/TabsExtended.md +380 -194
- package/bundle/components/UnorderedList.md +254 -0
- package/bundle/components/UnorderedListExtended.md +255 -0
- package/bundle/components/WindowResizeListener.md +249 -0
- package/bundle/guides/commits.md +66 -3
- package/bundle/guides/context.md +26 -0
- package/bundle/guides/stories.md +3 -1
- package/bundle/guides/template.md +1 -1
- package/bundle/manifest.json +64 -21
- package/bundle/release-notes/1.41.1.mdx +18 -0
- package/bundle/release-notes/1.42.0.mdx +81 -0
- package/bundle/release-notes/1.43.0.mdx +94 -0
- package/bundle/release-notes/1.44.0.mdx +7 -0
- package/package.json +1 -1
|
@@ -48,13 +48,15 @@ version: "1.0"
|
|
|
48
48
|
| `bulk` | `boolean` | `false` | Влияет на отображаемую иконку (используется bulk-иконка). Видимость checkmark всё равно определяется состоянием `checked`. |
|
|
49
49
|
| `size` | `EComponentSize` | `EComponentSize.MD` | Размер: `SM` / `MD` / `LG`. |
|
|
50
50
|
| `children` | `React.ReactNode` | — | Контент лейбла рядом с чекбоксом. Если `children` нет — класс `.nonempty` не применяется. |
|
|
51
|
-
| `labelAttributes` | `React.LabelHTMLAttributes<HTMLLabelElement>` | — | Дополнительные HTML-атрибуты для корневого `<label>` (например, `className`, `onFocus`). |
|
|
51
|
+
| `labelAttributes` | `React.LabelHTMLAttributes<HTMLLabelElement>` | — | Дополнительные HTML-атрибуты для корневого `<label>` (например, `className`, `onFocus`). `labelAttributes.className` объединяется с `className` компонента, а не заменяет его. |
|
|
52
52
|
| `...inputAttributes` | `Omit<React.InputHTMLAttributes<HTMLInputElement>, "type" \| "size">` | — | Все стандартные атрибуты `<input type="checkbox">` (включая `name`, `onChange`, `aria-label` и т.д.). |
|
|
53
53
|
|
|
54
54
|
### Ограничения использования
|
|
55
55
|
|
|
56
56
|
- DOM-структура фиксирована: корневой `<label>` → `<input type="checkbox">` → декоративные `<span>` / `<svg>` для отрисовки фона и галочки.
|
|
57
57
|
- `ref` прокидывается на внутренний `<input type="checkbox">`.
|
|
58
|
+
- `className` попадает на корневой `<label>`, все остальные props (`...inputAttributes`) — на `<input>`.
|
|
59
|
+
- Размер задаёт классы только на `<label>`: внутренние элементы (`input`, фон, галочка) стилизуются от него как потомки.
|
|
58
60
|
|
|
59
61
|
---
|
|
60
62
|
|
|
@@ -84,6 +86,7 @@ version: "1.0"
|
|
|
84
86
|
- `forwardRef` на компоненте обязателен и должен указывать на `<input>`.
|
|
85
87
|
- Корневой DOM-элемент компонента — `<label>`, внутри которого находится `<input>`.
|
|
86
88
|
- `className` и `size` — публичные части внешнего контрактного API: не менять семантику без согласования.
|
|
89
|
+
- Ховер-стили объявляются только внутри `@media (hover: hover)`: на тач-устройствах браузер эмулирует `:hover` при тапе и не снимает его, из-за чего чекбокс залипал бы в состоянии ховера.
|
|
87
90
|
|
|
88
91
|
---
|
|
89
92
|
|
|
@@ -113,6 +116,7 @@ version: "1.0"
|
|
|
113
116
|
| `Playground` | `PlaygroundExample.tsx` | Интерактивный контроль основных props |
|
|
114
117
|
| `Default` | `DefaultExample.tsx` | Минимальное использование |
|
|
115
118
|
| `Sizes` | `SizesExample.tsx` | Размеры `SM` / `MD` / `LG` |
|
|
119
|
+
| `VisualTests` | `VisualTestsExample.tsx` | Состояния для visual regression: размеры `SM` / `MD` / `LG` в `checked` и `checked bulk` |
|
|
116
120
|
|
|
117
121
|
---
|
|
118
122
|
|
|
@@ -122,6 +126,8 @@ version: "1.0"
|
|
|
122
126
|
|---|---|
|
|
123
127
|
| 2026-04-16 | Приведение `Checkbox` к AI-ready: соблюдены правила `docs/ai/codestyle.md`, добавлена AI-документация и unit-тест на передачу `className` корневому `label`. |
|
|
124
128
|
| 2026-04-27 | Приведён в соответствие с `docs/ai/template-ai.md`: убрана секция «Ключевые особенности реализации» (содержимое перенесено в `Ограничения использования`), переставлены секции (Accessibility после Инвариантов), добавлена колонка `Example file`. |
|
|
129
|
+
| 2026-08-14 | AI-рефакторинг: выбор иконки галочки через компонент-переменную вместо render-функции, с `<input>` убран не влияющий на стили класс размера, JSDoc на props дополнен дефолтами, расширено unit-покрытие (размеры, `bulk`, `labelAttributes`, `onChange`, `disabled`). |
|
|
130
|
+
| 2026-08-20 | Исправлено залипание ховера на тач-устройствах: правила `:hover` в `Checkbox.module.less` обёрнуты в `@media (hover: hover)`. |
|
|
125
131
|
|
|
126
132
|
---
|
|
127
133
|
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
---
|
|
2
2
|
component: CheckboxTreeExtended
|
|
3
3
|
category: Inputs
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
tokens: []
|
|
4
|
+
related: [CheckboxTree, CollapsibleTreeExtended, Checkbox]
|
|
5
|
+
tokens:
|
|
6
|
+
- --triplex-next-Checkbox-BorderColor_Focus
|
|
8
7
|
stories: stories/CheckboxTreeExtended/CheckboxTreeExtended.stories.tsx
|
|
9
8
|
version: "1.0"
|
|
10
9
|
---
|
|
@@ -13,304 +12,203 @@ version: "1.0"
|
|
|
13
12
|
|
|
14
13
|
## Назначение
|
|
15
14
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
Низкоуровневое декларативное дерево чекбоксов. Обёртка над
|
|
16
|
+
`CollapsibleTreeExtended` (и, соответственно, над `TreeView`), которая задаёт
|
|
17
|
+
разметку и отступы веток, а размер чекбоксов раздаёт через контекст.
|
|
19
18
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
`
|
|
23
|
-
|
|
19
|
+
Дерево описывается вручную, узел за узлом: каждый узел — это
|
|
20
|
+
`CheckboxTreeExtended.Node` с render-функцией `checkbox`, а вложенные узлы
|
|
21
|
+
передаются в `children`. Состояние чекбоксов (`checked`, `bulk`) целиком на
|
|
22
|
+
стороне потребителя — компонент ничего не хранит и не пересчитывает.
|
|
24
23
|
|
|
25
|
-
|
|
26
|
-
(
|
|
27
|
-
|
|
28
|
-
отложенный фичер.
|
|
24
|
+
Используй когда: нужна своя структура данных или своя логика связи родитель ↔
|
|
25
|
+
потомки (частичный выбор, ленивая загрузка ветки, произвольный контент рядом
|
|
26
|
+
с чекбоксом), либо дерево строится из уже готовой разметки.
|
|
29
27
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
`CheckboxTree`.
|
|
34
|
-
|
|
35
|
-
---
|
|
36
|
-
|
|
37
|
-
## Файловая структура
|
|
38
|
-
|
|
39
|
-
```text
|
|
40
|
-
src/components/CheckboxTreeExtended/
|
|
41
|
-
├── CheckboxTreeExtended.tsx # React.FC (SFC-интерфейс) + compound Node/Checkbox
|
|
42
|
-
├── CheckboxTreeExtendedContext.ts # Контекст: {size}
|
|
43
|
-
├── isStaticCheckboxTreeExtended.ts # const = true, временный feature-flag
|
|
44
|
-
├── index.ts # Barrel
|
|
45
|
-
├── styles/CheckboxTreeExtended.module.less
|
|
46
|
-
└── components/
|
|
47
|
-
├── CheckboxTreeExtendedNode.tsx # FC, обёртка CollapsableTree.Node
|
|
48
|
-
├── CheckboxTreeExtendedCheckbox.tsx # FC, обёртка Checkbox + фокус-менеджмент
|
|
49
|
-
└── CheckboxTreeExtendedArrow.tsx # class Component, стрелка разворачивания (сейчас скрыта)
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
Особенности:
|
|
53
|
-
- **`ICheckboxTreeExtendedSFC`** — кастомный интерфейс FC с `Checkbox` и
|
|
54
|
-
`Node` как свойствами. Присваиваются статически после объявления.
|
|
55
|
-
- **`isStaticCheckboxTreeExtended`** — хардкод-константа, временно
|
|
56
|
-
выключающая сворачивание. **Удалить вместе с файлом**, когда фича будет
|
|
57
|
-
реализована. Пока что из-за `true` много веток кода идут по "всегда
|
|
58
|
-
раскрытой" логике.
|
|
59
|
-
- **`useMatchMedia`** — адаптивный размер: на экранах `<= SM_MAX` размер
|
|
60
|
-
форсируется в `MD` независимо от пропса.
|
|
28
|
+
Не используй когда: достаточно передать массив чекбоксов и получить готовую
|
|
29
|
+
логику каскадного выбора — для этого есть `CheckboxTree`, обёртка поверх этого
|
|
30
|
+
компонента.
|
|
61
31
|
|
|
62
32
|
---
|
|
63
33
|
|
|
64
34
|
## Варианты и props
|
|
65
35
|
|
|
66
|
-
###
|
|
67
|
-
|
|
68
|
-
| Prop | Тип | Default | Описание |
|
|
69
|
-
|---|---|---|---|
|
|
70
|
-
| `size` | `EComponentSize` | `MD` | Размер чекбоксов в дереве (SM/MD/LG). На мобильных (`<= SM_MAX`) перезаписывается на MD. |
|
|
71
|
-
| `className` | `string` | — | Добавочный класс. |
|
|
72
|
-
| `...ICollapsableTreeProps` | — | — | Наследует все пропы CollapsableTree (включая children, navigation). |
|
|
36
|
+
### `CheckboxTreeExtended`
|
|
73
37
|
|
|
74
|
-
|
|
38
|
+
Наследует `ICollapsibleTreeExtendedProps` (то есть все атрибуты `<ul>`).
|
|
75
39
|
|
|
76
|
-
| Prop | Тип |
|
|
40
|
+
| Prop | Тип | По умолчанию | Описание |
|
|
77
41
|
|---|---|---|---|
|
|
78
|
-
| `
|
|
79
|
-
| `
|
|
80
|
-
| `
|
|
81
|
-
| `opened` | `boolean` | Нет | Контролируемое раскрытие. Игнорируется при `isStaticCheckboxTreeExtended=true`. |
|
|
82
|
-
| `prevNodeId` / `nextNodeId` | `string` | Нет | ID соседних нод того же уровня для arrow-навигации. |
|
|
83
|
-
| `...CollapsableTreeNodeProps` | — | — | Всё остальное (кроме `children`/`renderHeader`/`renderBody`). |
|
|
84
|
-
|
|
85
|
-
### `CheckboxTreeExtended.Checkbox` — `ICheckboxTreeExtendedCheckboxProps extends ICheckboxProps`
|
|
86
|
-
|
|
87
|
-
Тонкая обёртка над `Checkbox` с дополнениями:
|
|
88
|
-
|
|
89
|
-
| Prop | Тип | Описание |
|
|
90
|
-
|---|---|---|
|
|
91
|
-
| `active` | `boolean` | Клавиатурный фокус на ноде → автоматически `.focus()` на input. |
|
|
92
|
-
| `opened` | `boolean` | Используется в типах, визуально сейчас не задействовано. |
|
|
93
|
-
| `size` | — | **НЕ передаётся через props**. Подтягивается из контекста CheckboxTreeExtendedContext. |
|
|
94
|
-
| `labelAttributes` | `ICheckboxProps["labelAttributes"]` | Расширяется — добавляется `onFocus` для `stopPropagation`. |
|
|
95
|
-
| `...ICheckboxProps` | — | Все остальные пропы базового Checkbox (checked, bulk, onChange, labelAttributes etc.). |
|
|
96
|
-
|
|
97
|
-
### `ICheckboxTreeExtendedCheckboxProvideProps`
|
|
98
|
-
|
|
99
|
-
Что приходит в `checkbox`-render-функцию:
|
|
100
|
-
|
|
101
|
-
```ts
|
|
102
|
-
interface ICheckboxTreeExtendedCheckboxProvideProps {
|
|
103
|
-
active?: boolean; // нода активна (keyboard nav)
|
|
104
|
-
opened?: boolean; // нода раскрыта (сейчас всегда true)
|
|
105
|
-
}
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
---
|
|
109
|
-
|
|
110
|
-
## Ключевые особенности реализации
|
|
111
|
-
|
|
112
|
-
### `useMatchMedia` для адаптивного size
|
|
113
|
-
|
|
114
|
-
```ts
|
|
115
|
-
const adaptive = useMatchMedia(
|
|
116
|
-
`(max-width: ${EScreenWidth.SM_MAX})`,
|
|
117
|
-
window.innerWidth <= parseInt(EScreenWidth.SM_MAX),
|
|
118
|
-
);
|
|
119
|
-
|
|
120
|
-
<CheckboxTreeExtendedContext.Provider value={{ size: adaptive ? EComponentSize.MD : size }}>
|
|
121
|
-
```
|
|
122
|
-
|
|
123
|
-
На мобильных контекст форсирует MD — игнорирует `size`, переданный в пропы.
|
|
124
|
-
Это UX-решение: маленькие чекбоксы на тач-экране неудобны. **Не убирать**
|
|
125
|
-
без дизайн-ревью.
|
|
42
|
+
| `size` | `EComponentSize` | `EComponentSize.MD` | Размер чекбоксов и вертикальных отступов веток. Раздаётся через контекст, в атрибуты DOM не попадает |
|
|
43
|
+
| `children` | `React.ReactNode` | — | Узлы `CheckboxTreeExtended.Node` |
|
|
44
|
+
| `className` | `string` | — | Мерджится с собственным классом корневого `<ul>` |
|
|
126
45
|
|
|
127
|
-
`
|
|
128
|
-
|
|
46
|
+
Составные части: `CheckboxTreeExtended.Node` (`CheckboxTreeExtendedNode`) и
|
|
47
|
+
`CheckboxTreeExtended.Checkbox` (`CheckboxTreeExtendedCheckbox`).
|
|
129
48
|
|
|
130
|
-
###
|
|
49
|
+
### `CheckboxTreeExtended.Node`
|
|
131
50
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
51
|
+
Наследует `ICollapsibleTreeExtendedNodeProps` без `children`, `renderBody`,
|
|
52
|
+
`renderHeader` — заголовок и тело узла формирует сам компонент. Тип props
|
|
53
|
+
экспортируется как `ICheckboxTreeExtendedNodeProps` — им типизируют
|
|
54
|
+
собственную обёртку узла.
|
|
136
55
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
2. `CheckboxTreeExtendedCheckbox`:
|
|
147
|
-
- `!isStaticCheckboxTreeExtended && event.stopPropagation()` — не гасит
|
|
148
|
-
focus bubbling в статичном режиме (ARR-у arrow активна, она сама управляет).
|
|
149
|
-
|
|
150
|
-
**TODO из кода: удалить файл + константу, когда сворачивание будет готово.**
|
|
151
|
-
До этого любой PR с "давайте сделаем сворачивание" должен **убрать оба места
|
|
152
|
-
использования**, не просто поменять на `false`.
|
|
153
|
-
|
|
154
|
-
### `handleHeaderMouseDown` — предотвращение фокуса на контейнер
|
|
155
|
-
|
|
156
|
-
```ts
|
|
157
|
-
if (event.target === event.currentTarget) {
|
|
158
|
-
event.preventDefault();
|
|
159
|
-
}
|
|
160
|
-
```
|
|
161
|
-
|
|
162
|
-
Когда клик по области заголовка **сбоку от чекбокса** (а не по самому
|
|
163
|
-
чекбоксу), браузер иначе дал бы фокус контейнеру. Это сбивало бы ARIA
|
|
164
|
-
(фокус должен быть на input). `preventDefault` блокирует это. Проверка
|
|
165
|
-
`target === currentTarget` — фокус блокируется только для прямых кликов в
|
|
166
|
-
контейнер, не для вложенных.
|
|
167
|
-
|
|
168
|
-
### `useEffect` — auto-focus при `active: true`
|
|
169
|
-
|
|
170
|
-
```ts
|
|
171
|
-
useEffect(() => {
|
|
172
|
-
if (!active) return;
|
|
173
|
-
if (!document.activeElement?.contains(checkboxNode.current as Node)) {
|
|
174
|
-
checkboxNode.current?.focus();
|
|
175
|
-
}
|
|
176
|
-
}, [active]);
|
|
177
|
-
```
|
|
56
|
+
| Prop | Тип | По умолчанию | Описание |
|
|
57
|
+
|---|---|---|---|
|
|
58
|
+
| `id` | `string` | — | Обязательный идентификатор узла в дереве |
|
|
59
|
+
| `checkbox` | `(props: ICheckboxTreeExtendedCheckboxProvideProps) => JSX.Element` | — | Render-функция чекбокса узла. Обязательна |
|
|
60
|
+
| `children` | `React.ReactNode` | — | Вложенные `CheckboxTreeExtended.Node` |
|
|
61
|
+
| `opened` | `boolean` | — | Игнорируется, пока дерево статично (см. «Инварианты») |
|
|
62
|
+
| `className` | `string` | — | Мерджится с собственным классом узла `<li>` |
|
|
63
|
+
| `prevNodeId` / `nextNodeId` | `string` | — | Порядок узлов для клавиатурной навигации `TreeView` |
|
|
178
64
|
|
|
179
|
-
|
|
180
|
-
CollapsableTree), автоматически фокусируется input. Условие
|
|
181
|
-
`!document.activeElement?.contains(...)` — защита от зацикливания focus,
|
|
182
|
-
если уже внутри.
|
|
65
|
+
`ICheckboxTreeExtendedCheckboxProvideProps` — то, что узел передаёт в `checkbox`:
|
|
183
66
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
`
|
|
67
|
+
| Поле | Описание |
|
|
68
|
+
|---|---|
|
|
69
|
+
| `active` | Узел активен при перемещении по дереву с клавиатуры. Нужен, чтобы чекбокс забрал фокус |
|
|
70
|
+
| `opened` | Узел раскрыт. Пока дерево статично — всегда `true` |
|
|
187
71
|
|
|
188
|
-
|
|
72
|
+
Эти props положено разворачивать прямо в `CheckboxTreeExtended.Checkbox`
|
|
73
|
+
(`checkbox={(props) => <CheckboxTreeExtended.Checkbox {...props} …>}`) — сам
|
|
74
|
+
чекбокс их обрабатывает и в DOM не пропускает.
|
|
189
75
|
|
|
190
|
-
|
|
191
|
-
!isStaticCheckboxTreeExtended && event.stopPropagation();
|
|
192
|
-
```
|
|
76
|
+
### `CheckboxTreeExtended.Checkbox`
|
|
193
77
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
78
|
+
Обёртка над `Checkbox`: добавляет классы дерева, забирает `size` из контекста и
|
|
79
|
+
переводит на себя фокус, когда узел стал активным при навигации с клавиатуры.
|
|
80
|
+
Принимает все props `Checkbox` (`checked`, `bulk`, `onChange`, `disabled`,
|
|
81
|
+
`labelAttributes`, `children` …) плюс служебные `active` и `opened` из
|
|
82
|
+
render-функции узла.
|
|
197
83
|
|
|
198
|
-
|
|
84
|
+
`size`, переданный явно, перекрывает размер из контекста — так сделано намеренно
|
|
85
|
+
(spread props идёт после), но в дереве это не нужно и ломает единый ритм.
|
|
199
86
|
|
|
200
|
-
|
|
201
|
-
при `active: true` (аналог `useEffect` в checkbox). Имеет `tabIndex={-1}` —
|
|
202
|
-
фокус не приходит tab'ом, только программно через active.
|
|
203
|
-
|
|
204
|
-
Клавиатура:
|
|
205
|
-
- `ArrowRight` → toggle(true) (раскрыть)
|
|
206
|
-
- `ArrowLeft` → toggle(false) (свернуть)
|
|
207
|
-
- `Enter`/`Space` → toggle(!opened)
|
|
87
|
+
---
|
|
208
88
|
|
|
209
|
-
|
|
89
|
+
## Дизайн-токены
|
|
210
90
|
|
|
211
|
-
|
|
91
|
+
Собственных токенов компонент не вводит. Единственная CSS-переменная в стилях —
|
|
92
|
+
у стрелки раскрытия (см. «Инварианты», сейчас не отрисовывается):
|
|
212
93
|
|
|
213
|
-
```ts
|
|
214
|
-
const sizeToClassNameMap = createSizeToClassNameMap(styles);
|
|
215
94
|
```
|
|
216
|
-
|
|
217
|
-
Применяется к `.checkboxTreeExtendedNodeHeader` → класс `.sm/.md/.lg`, от
|
|
218
|
-
которого зависит `margin-bottom` и мобильный padding.
|
|
219
|
-
|
|
220
|
-
### CSS `:has(.sm)` для глубины отступа
|
|
221
|
-
|
|
222
|
-
```less
|
|
223
|
-
.checkboxTreeExtendedNode:has(.sm) { margin-left: 16px; }
|
|
224
|
-
.checkboxTreeExtendedNode:has(.md),
|
|
225
|
-
.checkboxTreeExtendedNode:has(.lg) { margin-left: 24px; }
|
|
95
|
+
--triplex-next-Checkbox-BorderColor_Focus
|
|
226
96
|
```
|
|
227
97
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
98
|
+
Размеры и цвета самих чекбоксов приходят из `Checkbox`, вертикальные отступы
|
|
99
|
+
задаются размером узла (`sm` — 8px, `md` / `lg` — 12px), отступ вложенной ветки
|
|
100
|
+
— 16px для `sm` и 24px для `md` / `lg`.
|
|
231
101
|
|
|
232
102
|
---
|
|
233
103
|
|
|
234
104
|
## Инварианты
|
|
235
105
|
|
|
236
|
-
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
- **`
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
-
|
|
250
|
-
`
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
- **`
|
|
255
|
-
|
|
256
|
-
-
|
|
257
|
-
|
|
106
|
+
- **Дерево статично.** Флаг `isStaticCheckboxTreeExtended = true`
|
|
107
|
+
(`isStaticCheckboxTreeExtended.ts`) принудительно раскрывает все узлы и
|
|
108
|
+
прячет стрелку раскрытия: `opened` на узле игнорируется, в `checkbox`
|
|
109
|
+
всегда приходит `opened: true`, `CheckboxTreeExtendedArrow` не
|
|
110
|
+
отрисовывается. Файл и обе ветки кода намеренно оставлены — по TODO флаг
|
|
111
|
+
снимут, когда сворачиваемое дерево станет стандартом. Не удаляй ветки
|
|
112
|
+
`!isStaticCheckboxTreeExtended` как «мёртвый код».
|
|
113
|
+
- **`forwardRef` нет ни у одной части** — `CheckboxTreeExtended`,
|
|
114
|
+
`.Node` и `.Checkbox` объявлены как `React.FC`. Это осознанно и повторяет
|
|
115
|
+
`CollapsibleTreeExtended`: под капотом class-компоненты `TreeView` /
|
|
116
|
+
`TreeViewNode` с собственной работой с DOM. Добавление `forwardRef` меняет
|
|
117
|
+
форму экспортируемого `ICheckboxTreeExtendedSFC` — это отдельное решение
|
|
118
|
+
мейнтейнера, а не рефакторинг.
|
|
119
|
+
- **Публичный API** — имена `ICheckboxTreeExtendedProps`,
|
|
120
|
+
`ICheckboxTreeExtendedSFC`, `ICheckboxTreeExtendedCheckboxProvideProps`,
|
|
121
|
+
`ICheckboxTreeExtendedNodeProps`,
|
|
122
|
+
статические `Checkbox` / `Node` и barrel-экспорты `index.ts` менять нельзя:
|
|
123
|
+
на них опирается `CheckboxTree`, а также stories `Chips` и `MultiselectField`.
|
|
124
|
+
- **`size` раздаётся только через контекст** `CheckboxTreeExtendedContext`. Не
|
|
125
|
+
прокидывай его пропом по дереву — узлы и чекбоксы читают контекст сами.
|
|
126
|
+
- **В мобильном представлении размер всегда `MD`** (`useMobileView`), чтобы
|
|
127
|
+
область нажатия оставалась достаточной. Значение `size` при этом не
|
|
128
|
+
«запоминается» — оно возвращается при выходе из мобильного представления.
|
|
129
|
+
- **Содержимое узла — только через `checkbox` и `children`.** `renderHeader` /
|
|
130
|
+
`renderBody` у `CollapsibleTreeExtended.Node` заняты и исключены из типа.
|
|
131
|
+
- **Корневой DOM** — `<ul role="tree">` от `TreeView`, узлы — `<li>`.
|
|
258
132
|
|
|
259
133
|
---
|
|
260
134
|
|
|
261
|
-
##
|
|
135
|
+
## Известные ограничения
|
|
262
136
|
|
|
263
|
-
-
|
|
264
|
-
|
|
265
|
-
- Чекбокс внутри — стандартный (`<input type="checkbox">`), получает
|
|
266
|
-
`aria-checked` и `aria-checked="mixed"` для bulk.
|
|
267
|
-
- **Клавиатура (CollapsableTree)**:
|
|
268
|
-
- Arrow Up/Down — навигация между нодами через prev/nextNodeId.
|
|
269
|
-
- Focus на input при активации ноды.
|
|
270
|
-
- **Клавиатура (CheckboxTreeExtendedArrow)** — зарезервирована, но не
|
|
271
|
-
активна в static-режиме.
|
|
272
|
-
- **Mobile**: padding 16px вокруг дерева, увеличенная область клика
|
|
273
|
-
на label (padding-top/bottom 16px) — тач-таргеты.
|
|
274
|
-
- Структура: `.checkboxTreeExtendedNodeHeader` — flex-контейнер с
|
|
275
|
-
чекбоксом и (будущей) стрелкой.
|
|
137
|
+
Найдено при AI-рефакторинге (TRI-23). Оставлено намеренно — не «чини» их
|
|
138
|
+
походя, по каждому пункту есть решение.
|
|
276
139
|
|
|
277
|
-
|
|
140
|
+
- **`CheckboxTreeExtendedArrow` разбирает клавиши через `event.keyCode`**
|
|
141
|
+
(`EVENT_KEY_CODES`) — устаревший API. Миграция на `event.key` относится ко
|
|
142
|
+
всему семейству `TreeView`.
|
|
143
|
+
- **`<li> cannot appear as a descendant of <li>`** — предупреждение React на
|
|
144
|
+
первом рендере вложенных узлов. `<ul role="group">` (`TreeViewGroup`)
|
|
145
|
+
отрисовывается только при `hasChildNodes`, а он берётся из
|
|
146
|
+
`abstractNode.getChildren()`, который наполняется, когда дочерние узлы уже
|
|
147
|
+
смонтировались. Лечится только в `TreeView` и задевает всё семейство
|
|
148
|
+
(`CollapsibleTree`, `CollapsibleTreeExtended`, `CheckboxTree`,
|
|
149
|
+
`CheckboxTreeExtended`), поэтому по решению ревьюера оставлено как есть.
|
|
150
|
+
См. «Accessibility».
|
|
278
151
|
|
|
279
|
-
|
|
152
|
+
---
|
|
280
153
|
|
|
281
|
-
|
|
282
|
-
(включая `--triplex-next-Checkbox-BorderColor_Focus` для стрелки).
|
|
154
|
+
## Accessibility
|
|
283
155
|
|
|
284
|
-
|
|
285
|
-
|
|
156
|
+
- Семантику и клавиатурную навигацию (стрелки, Home/End, перемещение по узлам)
|
|
157
|
+
обеспечивает `TreeView`. Компонент добавляет к ней только передачу фокуса.
|
|
158
|
+
- **Фокус при навигации с клавиатуры.** Узел сообщает в render-функцию
|
|
159
|
+
`active`; `CheckboxTreeExtended.Checkbox` по этому флагу вызывает
|
|
160
|
+
`focus()` на `<input>`. Правило ровно одно: фокус берётся, когда `active`
|
|
161
|
+
и текущий `document.activeElement` **не содержит** чекбокс. Mount и update
|
|
162
|
+
эффект не различает — при монтировании активного узла фокус не уезжает
|
|
163
|
+
только потому, что `activeElement` по умолчанию `<body>`, а
|
|
164
|
+
`body.contains(input)` истинно; если в этот момент фокус стоит на
|
|
165
|
+
постороннем элементе, чекбокс заберёт его сразу на маунте. У стрелки
|
|
166
|
+
поведение другое — там guard через `prevActive` даёт настоящий
|
|
167
|
+
mount-иммунитет (фокус только на переходе `active` false → true). Когда
|
|
168
|
+
флаг статичности снимут, у узлов с детьми фокус вместо чекбокса будет
|
|
169
|
+
получать стрелка раскрытия.
|
|
170
|
+
- **Клик мимо чекбокса не наводит фокус**: `mousedown` по самому контейнеру
|
|
171
|
+
заголовка (а не по label/чекбоксу) отменяется через `preventDefault`.
|
|
172
|
+
- Подпись чекбокса — `children` у `CheckboxTreeExtended.Checkbox`, она же
|
|
173
|
+
связывает `<label>` и `<input>`. Для чекбокса без видимой подписи
|
|
174
|
+
`aria-label` передаёт потребитель — библиотека мультиязычная.
|
|
175
|
+
- Стрелка раскрытия (пока не отрисовывается) — `role="button"`,
|
|
176
|
+
`tabIndex={-1}`, обрабатывает `ArrowRight` / `ArrowLeft` (раскрыть /
|
|
177
|
+
свернуть) и `Enter` / `Space` (инвертировать). Фокус она берёт в `useEffect`
|
|
178
|
+
(пассивная фаза, после отрисовки), а не в layout-фазе, как было у прежнего
|
|
179
|
+
class-компонента, — так же, как это делает `CheckboxTreeExtended.Checkbox`.
|
|
180
|
+
- Известное ограничение семейства: на первом рендере вложенные `<li>` попадают
|
|
181
|
+
внутрь родительского `<li>` без обёртки `<ul role="group">` — `TreeView`
|
|
182
|
+
добавляет группу только после регистрации дочерних узлов. Поведение общее с
|
|
183
|
+
`CollapsibleTreeExtended`, лечится на уровне `TreeView`.
|
|
286
184
|
|
|
287
185
|
---
|
|
288
186
|
|
|
289
187
|
## Связанные компоненты
|
|
290
188
|
|
|
291
|
-
- `CheckboxTree` (`src/components/CheckboxTree`) —
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
- `
|
|
298
|
-
|
|
299
|
-
- `
|
|
300
|
-
|
|
189
|
+
- `CheckboxTree` (`src/components/CheckboxTree`) — обёртка верхнего уровня:
|
|
190
|
+
принимает массив `ICheckboxTreeCheckboxData` и сама пересчитывает `checked` /
|
|
191
|
+
`bulk` вверх и вниз по дереву. Если своя структура данных не нужна — бери её.
|
|
192
|
+
- `CollapsibleTreeExtended` (`src/components/CollapsibleTreeExtended`) —
|
|
193
|
+
нижний слой: узлы, accordion-логика и семантика дерева от `TreeView`.
|
|
194
|
+
`ICheckboxTreeExtendedProps` наследует `ICollapsibleTreeExtendedProps`.
|
|
195
|
+
- `Checkbox` (`src/components/Checkbox`) — сам чекбокс; `CheckboxTreeExtended.Checkbox`
|
|
196
|
+
добавляет к нему только классы дерева, размер из контекста и работу с фокусом.
|
|
197
|
+
- `CheckboxTreeExtendedArrow` — внутренняя стрелка раскрытия ветки, из barrel не
|
|
198
|
+
экспортируется и сейчас не отрисовывается (см. «Инварианты»).
|
|
301
199
|
|
|
302
200
|
---
|
|
303
201
|
|
|
304
202
|
## Stories
|
|
305
203
|
|
|
306
|
-
`stories/CheckboxTreeExtended/CheckboxTreeExtended.stories.tsx`
|
|
204
|
+
Основные истории: `stories/CheckboxTreeExtended/CheckboxTreeExtended.stories.tsx`
|
|
307
205
|
Файлы примеров: `stories/CheckboxTreeExtended/examples/`
|
|
308
206
|
|
|
309
207
|
| Story | Example file | Что демонстрирует |
|
|
310
208
|
|---|---|---|
|
|
311
|
-
| `Playground` | `PlaygroundExample.tsx` | Интерактивный контроль `size`
|
|
312
|
-
| `Default` | `DefaultExample.tsx` |
|
|
313
|
-
| `Sizes` | `SizesExample.tsx` |
|
|
209
|
+
| `Playground` | `PlaygroundExample.tsx` | Интерактивный контроль `size` |
|
|
210
|
+
| `Default` | `DefaultExample.tsx` | Дерево из двух веток с вложенным узлом, состояние чекбоксов в `useState` потребителя |
|
|
211
|
+
| `Sizes` | `SizesExample.tsx` | Размеры SM / MD / LG рядом |
|
|
314
212
|
|
|
315
213
|
---
|
|
316
214
|
|
|
@@ -318,7 +216,10 @@ margin). Кандидат на токенизацию.
|
|
|
318
216
|
|
|
319
217
|
| Дата | Изменение |
|
|
320
218
|
|---|---|
|
|
321
|
-
| 2026-
|
|
219
|
+
| 2026-08-17 | Создан документ. Проведён AI-рефакторинг: JSDoc на props, `CheckboxTreeExtendedArrow` переведён с class-компонента на FC, добавлен `displayName` у `CheckboxTreeExtendedNode`, класс состояния раскрытия узла берётся из CSS-модуля; добавлены unit-тесты на все части компонента |
|
|
220
|
+
| 2026-08-17 | `className` у `CheckboxTreeExtended.Node` больше не затирает собственный класс узла — классы мерджатся через `clsx` (правка по ревью PR #535) |
|
|
221
|
+
| 2026-08-17 | Убран мёртвый селектор `.checkboxTreeCheckbox` из мобильной медиа-выборки (рабочие `> span` и `> svg` оставлены), `.caretIconWrapper:focus` заменён на `:focus-visible` (правки по ревью PR #535) |
|
|
222
|
+
| 2026-08-17 | `ICheckboxTreeExtendedNodeProps` экспортируется — тип уходит в barrel и становится частью публичного API (решение владельца по ревью PR #535) |
|
|
322
223
|
|
|
323
224
|
---
|
|
324
225
|
|
|
@@ -36,6 +36,7 @@ version: "1.0"
|
|
|
36
36
|
|
|
37
37
|
- Корневой элемент — `<div role="group">`, разметка построена на `inline-flex` и `flex-flow: row wrap`.
|
|
38
38
|
- `indent` управляет применением LESS-класса `indent-{n}` и задаёт отрицательные/положительные маргины для выравнивания сетки.
|
|
39
|
+
- Положительные маргины навешиваются селектором `.indent-{n} .label`, то есть только на потомков с корневым классом `Checkbox`. Для произвольных children (текст, свой контрол, обёртка без `Checkbox` внутри) отступ не применится, а отрицательные маргины контейнера останутся — контент выедет за границы группы.
|
|
39
40
|
|
|
40
41
|
---
|
|
41
42
|
|
|
@@ -86,6 +87,7 @@ version: "1.0"
|
|
|
86
87
|
|---|---|
|
|
87
88
|
| 2026-04-16 | Приведение `CheckboxXGroup` к AI-ready: добавлен `forwardRef`, типизирован `children`, созданы AI-документ и инварианты. |
|
|
88
89
|
| 2026-04-27 | Приведён в соответствие с `docs/ai/template-ai.md`: убрана секция «Ключевые особенности реализации» (содержимое перенесено в `Ограничения использования`), переставлены секции, добавлена колонка `Example file` и пустой раздел `Дизайн-токены`. |
|
|
90
|
+
| 2026-08-18 | AI-рефакторинг: JSDoc на props и компоненте, комментарий про кросс-модульный класс `.label` в LESS, добавлены unit-тесты `__tests__/CheckboxXGroup.test.tsx`. Публичный API не изменён. |
|
|
89
91
|
|
|
90
92
|
---
|
|
91
93
|
|
|
@@ -28,12 +28,16 @@ version: "1.0"
|
|
|
28
28
|
|
|
29
29
|
| Prop | Тип | По умолчанию | Описание |
|
|
30
30
|
|---|---|---|---|
|
|
31
|
-
| `children` | `React.ReactNode` | — | Внутри обычно рендерятся `Checkbox`
|
|
32
|
-
| `...divAttributes` | `React.HTMLAttributes<HTMLDivElement>` | — |
|
|
31
|
+
| `children` | `React.ReactNode` | — | Внутри обычно рендерятся `Checkbox`. Компоненты, оборачивающие `Checkbox`, тоже допустимы, но обёртка вокруг каждого `Checkbox` разрывает соседство `label`-ов и вертикальный отступ пропадает — см. «Ограничения использования». |
|
|
32
|
+
| `...divAttributes` | `Omit<React.HTMLAttributes<HTMLDivElement>, "role">` | — | Стандартные HTML-атрибуты для корневого элемента, кроме `role`: роль всегда `group`. |
|
|
33
33
|
|
|
34
34
|
### Ограничения использования
|
|
35
35
|
|
|
36
36
|
- Корневой элемент — `<div role="group">`, разметка построена на `inline-flex` и `flex-flow: column wrap`.
|
|
37
|
+
- Вертикальный отступ задаётся правилами вида `.checkboxYGroup .label.md + .label.md` (потомковый + соседний комбинатор), поэтому его получают только соседние `label`-элементы `Checkbox` одного размера — на любой глубине вложенности внутри группы. Для произвольных children (текст, свой контрол, обёртка без `Checkbox` внутри) отступ не применится.
|
|
38
|
+
- Обёртка вокруг каждого `Checkbox` (`<Wrapper><Checkbox /></Wrapper>` × 2) разрывает соседство `label`-ов — отступ пропадает. Два `Checkbox` внутри одной общей обёртки отступ, наоборот, получат, хотя прямыми детьми группы не являются.
|
|
39
|
+
- На мобильном брейкпоинте величина внутреннего отступа одинакова для всех размеров, но правила те же — отступ по-прежнему применяется только между соседями одного размера.
|
|
40
|
+
- Там же (`@screen-sm-max`) группа дополнительно получает собственный внешний отступ `margin: 14px 16px` — на десктопе своих внешних отступов у неё нет.
|
|
37
41
|
|
|
38
42
|
---
|
|
39
43
|
|
|
@@ -82,6 +86,7 @@ version: "1.0"
|
|
|
82
86
|
|---|---|
|
|
83
87
|
| 2026-04-16 | Приведение `CheckboxYGroup` к AI-ready: добавлен `forwardRef`, типизирован `children`, созданы AI-документ и инварианты. |
|
|
84
88
|
| 2026-04-27 | Приведён в соответствие с `docs/ai/template-ai.md`: убрана секция «Ключевые особенности реализации» (содержимое перенесено в `Ограничения использования`), переставлены секции, добавлена колонка `Example file` и пустой раздел `Дизайн-токены`. |
|
|
89
|
+
| 2026-08-19 | AI-рефакторинг: JSDoc на props и компоненте, комментарий про кросс-модульные классы `.label`/`.sm`/`.md`/`.lg` в LESS, добавлены unit-тесты `__tests__/CheckboxYGroup.test.tsx`. Публичный API не изменён. |
|
|
85
90
|
|
|
86
91
|
---
|
|
87
92
|
|