@sberbusiness/triplex-next-mcp-server 0.24.0-beta2 → 0.36.0-beta0
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 +10 -0
- package/bundle/components/BodyPage.md +186 -0
- package/bundle/components/Button.md +90 -85
- package/bundle/components/ButtonDropdown.md +28 -70
- package/bundle/components/ButtonIcon.md +35 -48
- package/bundle/components/Checkbox.md +43 -122
- package/bundle/components/CheckboxXGroup.md +109 -46
- package/bundle/components/CheckboxYGroup.md +77 -49
- package/bundle/components/CollapsibleTree.md +581 -0
- package/bundle/components/CollapsibleTreeExtended.md +418 -0
- package/bundle/components/EmptyView.md +14 -15
- package/bundle/components/FooterPage.md +203 -0
- package/bundle/components/Gap.md +115 -57
- package/bundle/components/HeaderPage.md +226 -0
- package/bundle/components/HelpBox.md +45 -84
- package/bundle/components/ImageGallery.md +423 -0
- package/bundle/components/ImageGalleryExtended.md +606 -0
- package/bundle/components/List.md +194 -186
- package/bundle/components/ListItem.md +251 -0
- package/bundle/components/ListItemControlsButton.md +103 -0
- package/bundle/components/ListItemControlsButtonDropdown.md +107 -0
- package/bundle/components/ListItemSelectable.md +99 -0
- package/bundle/components/ListItemTable.md +390 -0
- package/bundle/components/ListMaster.md +877 -156
- package/bundle/components/ListMasterFooter.md +80 -0
- package/bundle/components/ListMasterHeader.md +86 -0
- package/bundle/components/ListSortable.md +153 -0
- package/bundle/components/ListSortableItem.md +175 -0
- package/bundle/components/ModalWindow.md +427 -237
- package/bundle/components/MonthYearField.md +145 -109
- package/bundle/components/Notification.md +625 -155
- package/bundle/components/Overlay.md +271 -170
- package/bundle/components/Page.md +283 -186
- package/bundle/components/Pagination.md +206 -229
- package/bundle/guides/codestyle.md +38 -11
- package/bundle/guides/commits.md +1 -2
- package/bundle/guides/context.md +34 -30
- package/bundle/guides/stories.md +110 -40
- package/bundle/guides/template.md +3 -7
- package/bundle/guides/tests.md +6 -2
- package/bundle/manifest.json +194 -24
- package/bundle/release-notes/1.26.0.mdx +33 -2
- package/bundle/release-notes/1.27.0.mdx +43 -0
- package/bundle/release-notes/1.28.0.mdx +25 -0
- package/bundle/release-notes/1.29.0.mdx +47 -0
- package/bundle/release-notes/1.30.0.mdx +56 -0
- package/bundle/release-notes/1.31.0.mdx +52 -0
- package/bundle/release-notes/1.32.0.mdx +35 -0
- package/bundle/release-notes/1.33.0.mdx +61 -0
- package/bundle/release-notes/1.34.0.mdx +35 -0
- package/bundle/release-notes/1.35.0.mdx +21 -0
- package/bundle/release-notes/1.35.1.mdx +11 -0
- package/bundle/release-notes/1.36.0.mdx +21 -0
- package/bundle/release-notes/1.37.0.mdx +30 -0
- package/package.json +1 -1
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
component: List
|
|
3
|
-
category:
|
|
4
|
-
|
|
5
|
-
figma-file: ""
|
|
6
|
-
related: [ListMaster, Table, TreeView, Checkbox, LoaderScreen]
|
|
3
|
+
category: List
|
|
4
|
+
related: [ListSortable, ListItem, ListEmptyState, ListItemLoading, LoaderScreen]
|
|
7
5
|
tokens: []
|
|
8
6
|
stories: stories/List/List.stories.tsx
|
|
9
7
|
version: "1.0"
|
|
@@ -13,235 +11,245 @@ version: "1.0"
|
|
|
13
11
|
|
|
14
12
|
## Назначение
|
|
15
13
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
на уровне списка.
|
|
14
|
+
Контейнер `<ul>` для набора элементов списка. Управляет состоянием загрузки
|
|
15
|
+
через prop `loading` (показывает overlay-спиннер `LoaderScreen` поверх
|
|
16
|
+
содержимого).
|
|
20
17
|
|
|
21
|
-
Используй когда: нужен
|
|
22
|
-
|
|
23
|
-
для древовидных — `TreeView`, для master-detail интерфейсов — `ListMaster`.
|
|
24
|
-
|
|
25
|
-
---
|
|
26
|
-
|
|
27
|
-
## Файловая структура
|
|
28
|
-
|
|
29
|
-
```text
|
|
30
|
-
src/components/List/
|
|
31
|
-
├── List.tsx # <ul>, loading-overlay
|
|
32
|
-
├── ListSortable.tsx # DnD обёртка (dnd-kit)
|
|
33
|
-
├── index.ts # Barrel всех слотов
|
|
34
|
-
├── components/
|
|
35
|
-
│ ├── ListItem.tsx # <li> + Provider ListItemContext
|
|
36
|
-
│ ├── ListItemContext.ts # { selected, setSelected }
|
|
37
|
-
│ ├── ListItemContent.tsx # Основной контент строки
|
|
38
|
-
│ ├── ListItemControls.tsx # Правый блок кнопок
|
|
39
|
-
│ ├── ListItemControlsButton.tsx # Стилизованная кнопка в Controls
|
|
40
|
-
│ ├── ListItemControlsButtonDropdown.tsx # Кнопка с выпадающим меню
|
|
41
|
-
│ ├── ListItemSelectable.tsx # Обёртка с Checkbox, пишет selected в Context
|
|
42
|
-
│ ├── ListItemTable.tsx # Табличный вид строки
|
|
43
|
-
│ ├── ListItemTailLeft.tsx # Левый хвост (иконка, аватар)
|
|
44
|
-
│ ├── ListItemTailRight.tsx # Правый хвост
|
|
45
|
-
│ ├── ListItemLoading.tsx # Placeholder-строка при loading
|
|
46
|
-
│ ├── ListEmptyState.tsx # Пустое состояние
|
|
47
|
-
│ ├── ListSortableItem.tsx # <li> с useSortable (DnD)
|
|
48
|
-
│ ├── ListSortableItemControls.tsx # DnD-handle control (drag)
|
|
49
|
-
│ └── ListSortableItemTarget.tsx # Цель сортировки
|
|
50
|
-
└── styles/*.module.less
|
|
51
|
-
```
|
|
18
|
+
Используй `List` когда: нужен стандартный список с произвольным контентом.
|
|
19
|
+
Используй `ListSortable` когда: нужна сортировка элементов через drag-and-drop.
|
|
52
20
|
|
|
53
21
|
---
|
|
54
22
|
|
|
55
23
|
## Варианты и props
|
|
56
24
|
|
|
57
|
-
###
|
|
25
|
+
### Опциональные props
|
|
58
26
|
|
|
59
|
-
| Prop | Тип |
|
|
27
|
+
| Prop | Тип | По умолчанию | Описание |
|
|
60
28
|
|---|---|---|---|
|
|
61
|
-
| `loading` | `boolean` |
|
|
62
|
-
|
|
|
29
|
+
| `loading` | `boolean` | `false` | Показывает `LoaderScreen` поверх содержимого. Используется при обновлении текущего списка новыми данными (например, после применения фильтра) |
|
|
30
|
+
| `children` | `React.ReactNode` | — | Элементы списка (обычно `<ListItem>` или `<ListItemTable>`) |
|
|
31
|
+
| `...HTMLUListElementAttributes` | — | — | Все стандартные атрибуты `<ul>` |
|
|
63
32
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
Создаёт собственный `ListItemContext` с `{ selected, setSelected }`. Подкомпоненты (`ListItemSelectable`) пишут в него.
|
|
67
|
-
|
|
68
|
-
### ListItemSelectable — `IListItemSelectableProps extends Omit<HTMLDivAttributes, "onSelect">`
|
|
69
|
-
|
|
70
|
-
| Prop | Тип | Обязателен | Описание |
|
|
71
|
-
|---|---|---|---|
|
|
72
|
-
| `selected` | `boolean` | Да | Управляемое состояние выбора. |
|
|
73
|
-
| `onSelect` | `(selected: boolean) => void` | Да | Callback при изменении. |
|
|
74
|
-
|
|
75
|
-
- Внутри — `<Checkbox>` + `useEffect(() => setSelected(selected))` — синхронизирует с `ListItemContext`, чтобы сиблинги (например, стили строки) могли реагировать на выбор.
|
|
76
|
-
- `<span className={styles.checkboxLabelClickArea} />` — растягивающаяся область клика (не только на чекбокс).
|
|
77
|
-
|
|
78
|
-
### ListItemContent — базовый слот для текста/описания строки.
|
|
79
|
-
|
|
80
|
-
### ListItemControls / ListItemControlsButton / …ButtonDropdown
|
|
33
|
+
---
|
|
81
34
|
|
|
82
|
-
|
|
83
|
-
|---|---|
|
|
84
|
-
| `ListItemControls` | Контейнер для кнопок справа. |
|
|
85
|
-
| `ListItemControlsButton` | Стилизованная кнопка-иконка. |
|
|
86
|
-
| `ListItemControlsButtonDropdown` | Кнопка + вложенное выпадающее меню. |
|
|
35
|
+
## Инварианты
|
|
87
36
|
|
|
88
|
-
|
|
37
|
+
- **`forwardRef`** — обязателен, target — `HTMLUListElement`. Не убирать.
|
|
38
|
+
- **Корневой элемент `<ul>`** — не менять. Семантика списка важна для accessibility.
|
|
39
|
+
- `loading` — overlay-стратегия (содержимое не размонтируется), не путать с `ListItemLoading` (отдельный элемент-спиннер для пагинации).
|
|
40
|
+
- **`.listLoaderScreen` — `z-index: @z-index-step`**. Понижает z-index относительно глобального `@z-index-loader-screen` у `LoaderScreen`, чтобы спиннер перекрывал только содержимое списка, а не `LightBox` / `ModalWindow`. Не повышать без проверки наложения на модальные слои.
|
|
89
41
|
|
|
90
|
-
|
|
42
|
+
---
|
|
91
43
|
|
|
92
|
-
|
|
44
|
+
## Связанные компоненты
|
|
93
45
|
|
|
94
|
-
|
|
46
|
+
- `ListItem` — базовый элемент списка, провайдер контекста для `selected`-состояния.
|
|
47
|
+
- `ListSortable` — тот же `<ul>`, но с DnD-обвязкой через `@dnd-kit`.
|
|
48
|
+
- `ListEmptyState` — отображается вместо элементов, когда данных нет (например, после фильтра).
|
|
49
|
+
- `ListItemLoading` — элемент-спиннер для подгрузки следующей страницы (пагинация).
|
|
50
|
+
- `LoaderScreen` — используется внутри `List` для состояния `loading`.
|
|
95
51
|
|
|
96
|
-
|
|
52
|
+
---
|
|
97
53
|
|
|
98
|
-
|
|
54
|
+
## Stories
|
|
99
55
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
| `items` | `T[]` | Да | Массив элементов, у каждого должно быть поле `id`. |
|
|
103
|
-
| `onItemsChange` | `(items: T[]) => void` | Да | Callback после перестановки. |
|
|
104
|
-
| `...IListProps` | — | — | Проброс на `<List>`. |
|
|
56
|
+
Основные истории: `stories/List/List.stories.tsx`
|
|
57
|
+
Файлы примеров: `stories/List/examples/List/`
|
|
105
58
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
59
|
+
| Story | Example file | Что демонстрирует |
|
|
60
|
+
|---|---|---|
|
|
61
|
+
| `Playground` | `Playground.tsx` | Интерактивный контроль `loading` |
|
|
62
|
+
| `Default` | `Default.tsx` | Базовый список |
|
|
63
|
+
| `Loading` | `Loading.tsx` | Состояние загрузки (overlay) |
|
|
64
|
+
| `EmptyState` | `EmptyState.tsx` | Использование `ListEmptyState` |
|
|
65
|
+
| `Virtualized` | `Virtualized.tsx` | Виртуализированный список (большие наборы данных) |
|
|
66
|
+
| `Sortable` | `Sortable.tsx` | DnD-сортировка через `ListSortable` + `ListSortableItem` |
|
|
67
|
+
| `SortableWithInteractiveElements` | `SortableWithInteractiveElements.tsx` | DnD с интерактивными элементами внутри строк (`data-draggable="false"`) |
|
|
109
68
|
|
|
110
|
-
|
|
69
|
+
---
|
|
111
70
|
|
|
112
|
-
|
|
113
|
-
|---|---|---|---|
|
|
114
|
-
| `id` | `string` | Да | Уникальный идентификатор, должен совпадать с `items[i].id`. |
|
|
115
|
-
| `disabled` | `boolean` | Нет | Блокирует drag. |
|
|
116
|
-
| `children` | `ReactNode \| (provideProps) => ReactNode` | — | **Render-props или обычные children**. Provide-props: `{ dragging, disabled, listeners, setActivatorNodeRef }`. |
|
|
71
|
+
## История изменений
|
|
117
72
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
-
|
|
73
|
+
| Дата | Изменение |
|
|
74
|
+
|---|---|
|
|
75
|
+
| 2026-04-29 | Создан документ |
|
|
76
|
+
| 2026-06-17 | `List.module.less`: локальный `z-index: @z-index-step` на `.listLoaderScreen` — исправлено перекрытие `LoaderScreen` поверх `LightBox` / `ModalWindow` |
|
|
121
77
|
|
|
122
78
|
---
|
|
123
79
|
|
|
124
|
-
##
|
|
80
|
+
## Примеры использования
|
|
125
81
|
|
|
126
|
-
###
|
|
127
|
-
|
|
128
|
-
```ts
|
|
129
|
-
while (element !== null) {
|
|
130
|
-
if (element.dataset?.draggable === "false") return false;
|
|
131
|
-
element = element.parentElement;
|
|
132
|
-
}
|
|
133
|
-
```
|
|
82
|
+
### Default
|
|
134
83
|
|
|
135
|
-
|
|
136
|
-
- `MouseSensor`: игнорирует правую кнопку (`button === 2`).
|
|
137
|
-
- `TouchSensor`: игнорирует мультитач (`touches.length > 1`).
|
|
138
|
-
|
|
139
|
-
### `ListItemContext` — связь выбора и стилей сиблингов
|
|
84
|
+
`stories/List/examples/List/Default.tsx`
|
|
140
85
|
|
|
141
86
|
```tsx
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
87
|
+
import React from "react";
|
|
88
|
+
import { List, ListItem } from "@sberbusiness/triplex-next";
|
|
89
|
+
|
|
90
|
+
export const Default = () => (
|
|
91
|
+
<div style={{ width: "500px" }}>
|
|
92
|
+
<List>
|
|
93
|
+
<ListItem>Элемент списка</ListItem>
|
|
94
|
+
<ListItem>Элемент списка</ListItem>
|
|
95
|
+
<ListItem>Элемент списка</ListItem>
|
|
96
|
+
</List>
|
|
97
|
+
</div>
|
|
98
|
+
);
|
|
145
99
|
```
|
|
146
100
|
|
|
147
|
-
|
|
148
|
-
- Другие подкомпоненты (например, `ListItemContent`) могут подписаться и изменить стиль.
|
|
149
|
-
- **Паттерн "выбор известен всей строке"** — без prop-drilling.
|
|
101
|
+
### Loading
|
|
150
102
|
|
|
151
|
-
|
|
103
|
+
`stories/List/examples/List/Loading.tsx`
|
|
152
104
|
|
|
153
105
|
```tsx
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
106
|
+
import React from "react";
|
|
107
|
+
import { List, ListItem } from "@sberbusiness/triplex-next";
|
|
108
|
+
|
|
109
|
+
export const Loading = () => (
|
|
110
|
+
<div style={{ width: "150px" }}>
|
|
111
|
+
<List loading>
|
|
112
|
+
<ListItem>Элемент списка</ListItem>
|
|
113
|
+
<ListItem>Элемент списка</ListItem>
|
|
114
|
+
<ListItem>Элемент списка</ListItem>
|
|
115
|
+
<ListItem>Элемент списка</ListItem>
|
|
116
|
+
<ListItem>Элемент списка</ListItem>
|
|
117
|
+
<ListItem>Элемент списка</ListItem>
|
|
118
|
+
</List>
|
|
119
|
+
</div>
|
|
120
|
+
);
|
|
158
121
|
```
|
|
159
122
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
### `data-tx={process.env.npm_package_version}` на `<ul>` и `<li>`
|
|
163
|
-
|
|
164
|
-
Версия библиотеки в DOM для отладки. Сохранять при изменениях.
|
|
123
|
+
### EmptyState
|
|
165
124
|
|
|
166
|
-
|
|
125
|
+
`stories/List/examples/List/EmptyState.tsx`
|
|
167
126
|
|
|
168
|
-
```
|
|
169
|
-
|
|
127
|
+
```tsx
|
|
128
|
+
import React from "react";
|
|
129
|
+
import {
|
|
130
|
+
Button,
|
|
131
|
+
EButtonTheme,
|
|
132
|
+
EComponentSize,
|
|
133
|
+
EFontWeightTitle,
|
|
134
|
+
ETextSize,
|
|
135
|
+
ETitleSize,
|
|
136
|
+
Gap,
|
|
137
|
+
ListEmptyState,
|
|
138
|
+
Text,
|
|
139
|
+
Title,
|
|
140
|
+
} from "@sberbusiness/triplex-next";
|
|
141
|
+
import { EmptytableSysIcon96 } from "@sberbusiness/icons-next";
|
|
142
|
+
|
|
143
|
+
export const EmptyState = () => (
|
|
144
|
+
<ListEmptyState>
|
|
145
|
+
<div style={{ display: "flex", justifyContent: "center" }}>
|
|
146
|
+
<EmptytableSysIcon96 />
|
|
147
|
+
</div>
|
|
148
|
+
|
|
149
|
+
<Gap size={16} />
|
|
150
|
+
|
|
151
|
+
<Title size={ETitleSize.H3} weight={EFontWeightTitle.REGULAR}>
|
|
152
|
+
Title text
|
|
153
|
+
</Title>
|
|
154
|
+
|
|
155
|
+
<Gap size={8} />
|
|
156
|
+
|
|
157
|
+
<Text size={ETextSize.B3}>Нет данных, но можно предложить какие-то действия для заполнения таблицы.</Text>
|
|
158
|
+
|
|
159
|
+
<Gap size={24} />
|
|
160
|
+
|
|
161
|
+
<Button theme={EButtonTheme.SECONDARY} size={EComponentSize.SM}>
|
|
162
|
+
Button Name
|
|
163
|
+
</Button>
|
|
164
|
+
<Button theme={EButtonTheme.GENERAL} size={EComponentSize.SM}>
|
|
165
|
+
Button Name
|
|
166
|
+
</Button>
|
|
167
|
+
</ListEmptyState>
|
|
168
|
+
);
|
|
170
169
|
```
|
|
171
170
|
|
|
172
|
-
|
|
171
|
+
### Virtualized
|
|
173
172
|
|
|
174
|
-
|
|
173
|
+
`stories/List/examples/List/Virtualized.tsx`
|
|
175
174
|
|
|
176
175
|
```tsx
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
176
|
+
import React from "react";
|
|
177
|
+
import { FixedSizeList } from "react-window";
|
|
178
|
+
import { List, ListItem } from "@sberbusiness/triplex-next";
|
|
179
|
+
|
|
180
|
+
const itemData = Array.from({ length: 100 }).map((_, index) => `List item ${index}`);
|
|
181
|
+
|
|
182
|
+
export const Virtualized = () => (
|
|
183
|
+
<FixedSizeList
|
|
184
|
+
itemData={itemData}
|
|
185
|
+
itemCount={itemData.length}
|
|
186
|
+
itemSize={20}
|
|
187
|
+
width="100%"
|
|
188
|
+
height={200}
|
|
189
|
+
innerElementType={List}
|
|
190
|
+
>
|
|
191
|
+
{({ data, index, style }) => <ListItem style={style}>{data[index]}</ListItem>}
|
|
192
|
+
</FixedSizeList>
|
|
193
|
+
);
|
|
187
194
|
```
|
|
188
195
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
---
|
|
192
|
-
|
|
193
|
-
## Инварианты
|
|
194
|
-
|
|
195
|
-
- **`<ul>` + `<li>`** семантика — не заменять на `<div>`.
|
|
196
|
-
- **`ListItemContext` shape** (`selected`, `setSelected`) — публичная точка расширения для сторонних кастомных подкомпонентов.
|
|
197
|
-
- **`data-draggable="false"`** — атрибут-escape-hatch для ListSortable. Потребители в product-коде могут опираться на него, не менять семантику.
|
|
198
|
-
- **`ListSortable` требует `items[].id: string`** — id как в React key, так и в dnd-kit. Переход на number/symbol — breaking.
|
|
199
|
-
- **`arrayMove` от dnd-kit** — не собственная реализация. При смене DnD-библиотеки переписать.
|
|
200
|
-
- **`IListSortableItemProps.children` — `ReactNode` или функция** — публичный render-props API.
|
|
201
|
-
- **`LoaderScreen` внутри `<ul>`** — визуальное решение, не менять без согласования.
|
|
202
|
-
- **ForwardRef** на всех компонентах; `ListSortable` — generic через `as <T>(props) => ...` cast.
|
|
203
|
-
- **`Object.assign` на `ListSortableItem` → `Target`** — сохранить.
|
|
204
|
-
|
|
205
|
-
---
|
|
196
|
+
### Sortable
|
|
206
197
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
- Семантика списка `<ul>`/`<li>` — правильная. Screen reader'ы объявляют "list, N items".
|
|
210
|
-
- `ListItemSelectable` — `<Checkbox>` внутри: нативная клавиатурная навигация, label через расширяющую clickable-область.
|
|
211
|
-
- `ListItemControlsButton` / `ListItemControlsButtonDropdown` — проверь, что `aria-label` проставлен (иконки без текста).
|
|
212
|
-
- **DnD не доступен с клавиатуры** из коробки (dnd-kit поддерживает `KeyboardSensor`, но здесь не подключён). Known debt.
|
|
213
|
-
- Loader'овый overlay скрывает контент — добавь `aria-busy="true"` на `<ul>` через `...rest` на время загрузки.
|
|
214
|
-
|
|
215
|
-
---
|
|
216
|
-
|
|
217
|
-
## Дизайн-токены
|
|
218
|
-
|
|
219
|
-
Нет прямых — визуал строки зависит от подкомпонентов (`ListItemSelectable`, `ListItemControls` используют собственные стили в `styles/*.module.less`).
|
|
220
|
-
|
|
221
|
-
---
|
|
198
|
+
`stories/List/examples/List/Sortable.tsx`
|
|
222
199
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
200
|
+
```tsx
|
|
201
|
+
import React, { useState } from "react";
|
|
202
|
+
import { ListSortable, ListSortableItem } from "@sberbusiness/triplex-next";
|
|
203
|
+
|
|
204
|
+
export const Sortable = () => {
|
|
205
|
+
const [items, setItems] = useState(
|
|
206
|
+
Array.from({ length: 10 }, (_, index) => ({ id: `list-sortable-item-0-${index}`, index })),
|
|
207
|
+
);
|
|
208
|
+
|
|
209
|
+
return (
|
|
210
|
+
<ListSortable items={items} onItemsChange={setItems}>
|
|
211
|
+
{items.map(({ id, index }) => (
|
|
212
|
+
<ListSortableItem key={id} id={id}>
|
|
213
|
+
{({ listeners, dragging, setActivatorNodeRef }) => (
|
|
214
|
+
<ListSortableItem.Target {...listeners} dragging={dragging} ref={setActivatorNodeRef}>
|
|
215
|
+
List item {index}
|
|
216
|
+
</ListSortableItem.Target>
|
|
217
|
+
)}
|
|
218
|
+
</ListSortableItem>
|
|
219
|
+
))}
|
|
220
|
+
</ListSortable>
|
|
221
|
+
);
|
|
222
|
+
};
|
|
223
|
+
```
|
|
235
224
|
|
|
236
|
-
|
|
237
|
-
- `stories/List/ListItem.stories.tsx`
|
|
238
|
-
- `stories/List/ListItemControls.stories.tsx`
|
|
239
|
-
- Примеры: `stories/List/examples/`
|
|
225
|
+
### SortableWithInteractiveElements
|
|
240
226
|
|
|
241
|
-
|
|
227
|
+
`stories/List/examples/List/SortableWithInteractiveElements.tsx`
|
|
242
228
|
|
|
243
|
-
|
|
229
|
+
```tsx
|
|
230
|
+
import React, { useState } from "react";
|
|
231
|
+
import { Checkbox, ListSortable, ListSortableItem, ListSortableItemControls } from "@sberbusiness/triplex-next";
|
|
232
|
+
|
|
233
|
+
export const SortableWithInteractiveElements = () => {
|
|
234
|
+
const [items, setItems] = useState(
|
|
235
|
+
Array.from({ length: 10 }, (_, index) => ({ id: `list-sortable-item-1-${index}`, index })),
|
|
236
|
+
);
|
|
237
|
+
|
|
238
|
+
return (
|
|
239
|
+
<ListSortable items={items} onItemsChange={setItems}>
|
|
240
|
+
{items.map(({ id, index }) => (
|
|
241
|
+
<ListSortableItem key={id} id={id}>
|
|
242
|
+
{({ listeners, dragging, setActivatorNodeRef }) => (
|
|
243
|
+
<ListSortableItem.Target {...listeners} dragging={dragging} ref={setActivatorNodeRef}>
|
|
244
|
+
<ListSortableItemControls>
|
|
245
|
+
<Checkbox>List item {index}</Checkbox>
|
|
246
|
+
</ListSortableItemControls>
|
|
247
|
+
</ListSortableItem.Target>
|
|
248
|
+
)}
|
|
249
|
+
</ListSortableItem>
|
|
250
|
+
))}
|
|
251
|
+
</ListSortable>
|
|
252
|
+
);
|
|
253
|
+
};
|
|
254
|
+
```
|
|
244
255
|
|
|
245
|
-
| Дата | Изменение |
|
|
246
|
-
|---|---|
|
|
247
|
-
| 2026-04-18 | Создан документ |
|