@clevertask/react-sortable-tree 0.0.6 → 0.0.7
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 +250 -91
- package/dist/SortableTree/SortableTree.d.ts +2 -4
- package/dist/SortableTree/components/TreeItem/TreeItem.d.ts +16 -6
- package/dist/SortableTree/components/TreeItem/index.d.ts +1 -0
- package/dist/SortableTree/components/TreeItemStructure/index.d.ts +19 -0
- package/dist/SortableTree/components/index.d.ts +3 -0
- package/dist/SortableTree/createSortableTreeGlobalStyles.d.ts +8 -0
- package/dist/SortableTree/index.d.ts +3 -0
- package/dist/SortableTree/types.d.ts +9 -11
- package/dist/SortableTree/utilities.d.ts +4 -4
- package/dist/react-sortable-tree.js +2355 -1371
- package/dist/react-sortable-tree.js.map +1 -1
- package/package.json +21 -20
- /package/dist/{style.css → react-sortable-tree.css} +0 -0
package/README.md
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
# @clevertask/react-sortable-tree
|
|
2
2
|
|
|
3
|
-
A customizable React component for rendering and managing tree structures with drag-and-drop functionality.
|
|
3
|
+
A customizable React component for rendering and managing tree structures with drag-and-drop functionality. Built on top of the [dnd-kit sortable tree example](https://github.com/clauderic/dnd-kit/blob/master/stories/3%20-%20Examples/Tree/SortableTree.tsx).
|
|
4
|
+
|
|
5
|
+
This library is currently focused on **custom item rendering** and **type-safe tree structures**. A more detailed API and feature set will be released in a future major version with support for virtualization and multi-selection.
|
|
6
|
+
|
|
7
|
+
---
|
|
4
8
|
|
|
5
9
|
## Table of Contents
|
|
6
10
|
|
|
@@ -8,54 +12,193 @@ A customizable React component for rendering and managing tree structures with d
|
|
|
8
12
|
- [Usage](#usage)
|
|
9
13
|
- [Props](#props)
|
|
10
14
|
- [Types](#types)
|
|
11
|
-
- [TreeItem](#treeitem)
|
|
12
|
-
- [TreeItems](#treeitems)
|
|
13
15
|
- [Helper Functions](#helper-functions)
|
|
14
|
-
- [getItemById](#getItemById)
|
|
15
|
-
- [removeItemById](#removeitembyid)
|
|
16
|
-
- [setTreeItemProperties](#settreeitemproperties)
|
|
17
16
|
- [Roadmap](#roadmap)
|
|
18
|
-
- [Release Process](#release-process)
|
|
19
17
|
- [License](#license)
|
|
20
18
|
|
|
19
|
+
---
|
|
20
|
+
|
|
21
21
|
## Installation
|
|
22
22
|
|
|
23
23
|
```bash
|
|
24
24
|
npm install @clevertask/react-sortable-tree
|
|
25
25
|
```
|
|
26
26
|
|
|
27
|
+
---
|
|
28
|
+
|
|
27
29
|
## Usage
|
|
28
30
|
|
|
31
|
+
### 1. Define your custom tree item type if needed
|
|
32
|
+
|
|
33
|
+
```ts
|
|
34
|
+
type CustomTreeItem = TreeItem<{
|
|
35
|
+
metadata?: Record<string, any>;
|
|
36
|
+
icon?: string;
|
|
37
|
+
}>;
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Otherwise, the component will use the default [tree item type](#types).
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
### 2. Create your custom item component
|
|
45
|
+
|
|
46
|
+
This is the basic structure you can start with:
|
|
47
|
+
|
|
29
48
|
```tsx
|
|
30
|
-
import
|
|
31
|
-
|
|
32
|
-
|
|
49
|
+
import {
|
|
50
|
+
RenderItemProps,
|
|
51
|
+
TreeItemStructure,
|
|
52
|
+
createSortableTreeGlobalStyles,
|
|
53
|
+
RenderItemProps,
|
|
54
|
+
} from '@clevertask/react-sortable-tree';
|
|
55
|
+
|
|
56
|
+
export const TreeItem = ({ treeItem, collapsed, onCollapse, ...rest }: RenderItemProps) => {
|
|
57
|
+
<TreeItemStructure {...rest}>
|
|
58
|
+
<button {...dragListeners}>Drag me</button>
|
|
59
|
+
{onCollapse && <button onClick={onCollapse}>{collapsed ? 'Expand' : 'Collapse'}</button>}
|
|
60
|
+
|
|
61
|
+
<h5>{treeItem.label}</h5>
|
|
62
|
+
|
|
63
|
+
<button onClick={() => openItemInfoModal(treeItem.id)}>Show treeItem info</button>
|
|
64
|
+
</TreeItemStructure>;
|
|
65
|
+
};
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
This is a real-world example using Radix:
|
|
33
69
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
70
|
+
```tsx
|
|
71
|
+
import {
|
|
72
|
+
RenderItemProps,
|
|
73
|
+
TreeItemStructure,
|
|
74
|
+
createSortableTreeGlobalStyles,
|
|
75
|
+
TreeItem as TTreeItem,
|
|
76
|
+
} from '@clevertask/react-sortable-tree';
|
|
77
|
+
import {
|
|
78
|
+
DragHandleDots2Icon,
|
|
79
|
+
ChevronRightIcon,
|
|
80
|
+
ChevronDownIcon,
|
|
81
|
+
TrashIcon,
|
|
82
|
+
PlusIcon,
|
|
83
|
+
} from '@radix-ui/react-icons';
|
|
84
|
+
import { Flex, Button, Text, Box } from '@radix-ui/themes';
|
|
85
|
+
import { CustomTreeItem } from '.';
|
|
86
|
+
|
|
87
|
+
export const TreeItem = ({
|
|
88
|
+
treeItem,
|
|
89
|
+
dragListeners,
|
|
90
|
+
onCollapse,
|
|
91
|
+
collapsed,
|
|
92
|
+
onClickAddNestedItemButton,
|
|
93
|
+
onClickItemRemoveButton,
|
|
94
|
+
onItemClick,
|
|
95
|
+
...rest
|
|
96
|
+
}: RenderItemProps<CustomTreeItem> & {
|
|
97
|
+
onClickAddNestedItemButton: (id: string) => void;
|
|
98
|
+
onClickItemRemoveButton: (id: string) => void;
|
|
99
|
+
onItemClick: (id: string) => void;
|
|
100
|
+
}) => {
|
|
101
|
+
const useSortableTreeGlobalStyles = createSortableTreeGlobalStyles({
|
|
102
|
+
indicatorColor: 'var(--orange-7)',
|
|
103
|
+
indicatorBorderColor: 'var(--orange-7)',
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
useSortableTreeGlobalStyles();
|
|
39
107
|
|
|
40
108
|
return (
|
|
41
|
-
<
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
109
|
+
<TreeItemStructure
|
|
110
|
+
{...rest}
|
|
111
|
+
asDropZone={Box}
|
|
112
|
+
asDraggableItem={Box}
|
|
113
|
+
draggableItemStyle={{
|
|
114
|
+
display: 'flex',
|
|
115
|
+
justifyContent: 'space-between',
|
|
116
|
+
padding: '1rem',
|
|
117
|
+
border: '1px solid var(--gray-3)',
|
|
118
|
+
background: 'var(--color-background)',
|
|
119
|
+
}}
|
|
120
|
+
>
|
|
121
|
+
<Flex align="center" gap="5" direction="row">
|
|
122
|
+
<Button color="gray" variant="ghost" {...dragListeners}>
|
|
123
|
+
<DragHandleDots2Icon />
|
|
124
|
+
</Button>
|
|
125
|
+
|
|
126
|
+
{onCollapse && (
|
|
127
|
+
<Button color="gray" variant="ghost" onClick={onCollapse}>
|
|
128
|
+
{collapsed ?
|
|
129
|
+
<ChevronRightIcon />
|
|
130
|
+
: <ChevronDownIcon />}
|
|
131
|
+
</Button>
|
|
132
|
+
)}
|
|
133
|
+
|
|
134
|
+
<Text style={{ cursor: 'pointer' }} onClick={() => onItemClick(treeItem.id)}>
|
|
135
|
+
{treeItem.label} {treeItem.metadata.foo}
|
|
136
|
+
</Text>
|
|
137
|
+
</Flex>
|
|
138
|
+
|
|
139
|
+
<Flex align="center" gap="3" direction="row">
|
|
140
|
+
<Button variant="ghost" color="red" onClick={() => onClickItemRemoveButton(treeItem.id)}>
|
|
141
|
+
<TrashIcon />
|
|
142
|
+
</Button>
|
|
143
|
+
<Button
|
|
144
|
+
variant="ghost"
|
|
145
|
+
color="gray"
|
|
146
|
+
onClick={() => onClickAddNestedItemButton(treeItem.id)}
|
|
147
|
+
>
|
|
148
|
+
<PlusIcon />
|
|
149
|
+
</Button>
|
|
150
|
+
</Flex>
|
|
151
|
+
</TreeItemStructure>
|
|
49
152
|
);
|
|
50
|
-
}
|
|
153
|
+
};
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
The `<TreeItemStructure/>` appends the dataSlots (for CSS styles), dropzone, and drag item container listeners and refs so you don't have to do it from scratch, but it's possible making your custom tree items without that component.
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
### 3. Use the `SortableTree` with your custom item
|
|
161
|
+
|
|
162
|
+
```tsx
|
|
163
|
+
import React, { useState } from 'react';
|
|
164
|
+
import { TreeItems, SortableTree } from '@clevertask/react-sortable-tree';
|
|
165
|
+
type CustomTreeItem = TreeItem<{ metadata?: Record<string, string> }>;
|
|
166
|
+
|
|
167
|
+
const [items, setItems] = useState<TreeItems<CustomTreeItem>>([
|
|
168
|
+
{ id: '1', label: 'Item 1', children: [] },
|
|
169
|
+
{
|
|
170
|
+
id: '2',
|
|
171
|
+
label: 'Item 2',
|
|
172
|
+
children: [{ id: '3', label: 'Item 2.1', children: [] }],
|
|
173
|
+
metadata: { foo: 'foo' },
|
|
174
|
+
},
|
|
175
|
+
]);
|
|
176
|
+
|
|
177
|
+
<SortableTree<CustomTreeItem>
|
|
178
|
+
isCollapsible
|
|
179
|
+
showDropIndicator
|
|
180
|
+
items={items}
|
|
181
|
+
setItems={setItems}
|
|
182
|
+
renderItem={(props: RenderItemProps<CustomTreeItem>) => (
|
|
183
|
+
<TreeItem
|
|
184
|
+
{...props}
|
|
185
|
+
onClickAddNestedItemButton={onClickAddNestedItemButton}
|
|
186
|
+
onClickItemRemoveButton={onClickItemRemoveButton}
|
|
187
|
+
onItemClick={onItemClick}
|
|
188
|
+
/>
|
|
189
|
+
)}
|
|
190
|
+
/>;
|
|
51
191
|
```
|
|
52
192
|
|
|
193
|
+
---
|
|
194
|
+
|
|
53
195
|
## Props
|
|
54
196
|
|
|
55
197
|
| Prop | Type | Default | Description |
|
|
56
198
|
| ------------------------- | --------------------------------------------------------------- | ----------- | -------------------------------------------------------------------------------------------------------------------- |
|
|
57
|
-
| `items` | `TreeItems
|
|
58
|
-
| `setItems` | `
|
|
199
|
+
| `items` | `TreeItems<T>` | Required | The array of tree items to be rendered. |
|
|
200
|
+
| `setItems` | `(items: TreeItems<T>) => void` | Required | Callback function called when the tree items array changes. |
|
|
201
|
+
| `renderItem` | `(props: RenderItemProps<T>) => React.ReactNode` | Required | Function to render each tree item. |
|
|
59
202
|
| `indentationWidth` | `number` | `undefined` | The indentation width for children elements. |
|
|
60
203
|
| `isCollapsible` | `boolean` | `false` | Determines if tree items can be collapsed/expanded. |
|
|
61
204
|
| `onLazyLoadChildren` | `(id: UniqueIdentifier, isExpanding: boolean) => Promise<void>` | `undefined` | Callback for lazy loading child items when a parent is expanded. Useful for getting child items from an API endpoint |
|
|
@@ -67,106 +210,122 @@ function App() {
|
|
|
67
210
|
| `onDragEnd` | `(result: DropResult) => void` | `undefined` | Callback function called when a drag operation ends. |
|
|
68
211
|
| `onItemClick` | `(id: UniqueIdentifier) => void` | `undefined` | Callback function called when an item in the tree is clicked. |
|
|
69
212
|
|
|
213
|
+
---
|
|
214
|
+
|
|
70
215
|
## Types
|
|
71
216
|
|
|
72
217
|
### TreeItem
|
|
73
218
|
|
|
74
|
-
```
|
|
75
|
-
type TreeItem = {
|
|
219
|
+
```ts
|
|
220
|
+
type TreeItem<ExtraProps = unknown> = {
|
|
76
221
|
id: UniqueIdentifier;
|
|
77
222
|
label: string;
|
|
78
|
-
children: TreeItem[];
|
|
223
|
+
children: TreeItem<ExtraProps>[];
|
|
79
224
|
collapsed?: boolean;
|
|
80
225
|
canFetchChildren?: boolean;
|
|
81
226
|
disableDragging?: boolean;
|
|
82
|
-
|
|
83
|
-
};
|
|
227
|
+
} & ExtraProps;
|
|
84
228
|
```
|
|
85
229
|
|
|
86
230
|
### TreeItems
|
|
87
231
|
|
|
88
|
-
```
|
|
89
|
-
type TreeItems = TreeItem[];
|
|
232
|
+
```ts
|
|
233
|
+
type TreeItems<T = TreeItem> = T[];
|
|
90
234
|
```
|
|
91
235
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
236
|
+
### TreeStructureProps
|
|
237
|
+
|
|
238
|
+
```ts
|
|
239
|
+
export interface TreeItemStructureProps {
|
|
240
|
+
dropZoneRef: (element: HTMLElement | null) => void;
|
|
241
|
+
draggableItemRef: React.Ref<any>;
|
|
242
|
+
dropZoneStyle?: React.CSSProperties;
|
|
243
|
+
draggableItemStyle?: React.CSSProperties;
|
|
244
|
+
classNames?: {
|
|
245
|
+
dropZone?: string;
|
|
246
|
+
draggableItem?: string;
|
|
247
|
+
};
|
|
248
|
+
asDropZone?: React.ElementType;
|
|
249
|
+
asDraggableItem?: React.ElementType;
|
|
250
|
+
draggableItemProps?: Record<string, any>;
|
|
251
|
+
children?: React.ReactNode;
|
|
252
|
+
dataSlots: {
|
|
253
|
+
dropZone: Record<string, string | boolean | undefined>;
|
|
254
|
+
draggableItem: Record<string, string>;
|
|
255
|
+
};
|
|
256
|
+
}
|
|
98
257
|
```
|
|
99
258
|
|
|
100
|
-
|
|
259
|
+
### RenderItemProps
|
|
260
|
+
|
|
261
|
+
```ts
|
|
262
|
+
export interface RenderItemProps<T extends TTreeItem = TTreeItem>
|
|
263
|
+
extends Pick<
|
|
264
|
+
TreeItemStructureProps,
|
|
265
|
+
'classNames' | 'dropZoneStyle' | 'dropZoneRef' | 'draggableItemRef'
|
|
266
|
+
>,
|
|
267
|
+
Pick<
|
|
268
|
+
Props,
|
|
269
|
+
| 'onCollapse'
|
|
270
|
+
| 'childCount'
|
|
271
|
+
| 'clone'
|
|
272
|
+
| 'ghost'
|
|
273
|
+
| 'indicator'
|
|
274
|
+
| 'disableSelection'
|
|
275
|
+
| 'disableInteraction'
|
|
276
|
+
| 'collapsed'
|
|
277
|
+
> {
|
|
278
|
+
dragListeners?: any;
|
|
279
|
+
treeItem: T;
|
|
280
|
+
dataSlots: {
|
|
281
|
+
dropZone: Record<string, string | boolean | undefined>;
|
|
282
|
+
draggableItem: Record<string, string>;
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
```
|
|
101
286
|
|
|
102
|
-
|
|
287
|
+
---
|
|
103
288
|
|
|
104
|
-
|
|
105
|
-
const item = getItemById(items, '1');
|
|
106
|
-
```
|
|
289
|
+
## Helper Functions
|
|
107
290
|
|
|
108
|
-
###
|
|
291
|
+
### getItemById
|
|
109
292
|
|
|
110
|
-
```
|
|
111
|
-
function
|
|
293
|
+
```ts
|
|
294
|
+
function getItemById<T extends TreeItem>(items: TreeItems<T>, id: UniqueIdentifier): T | undefined;
|
|
112
295
|
```
|
|
113
296
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
Usage example:
|
|
297
|
+
### removeItemById
|
|
117
298
|
|
|
118
|
-
```
|
|
119
|
-
|
|
120
|
-
|
|
299
|
+
```ts
|
|
300
|
+
function removeItemById<T extends TreeItem>(
|
|
301
|
+
items: TreeItems<T>,
|
|
302
|
+
id: UniqueIdentifier,
|
|
303
|
+
): TreeItems<T>;
|
|
121
304
|
```
|
|
122
305
|
|
|
123
306
|
### setTreeItemProperties
|
|
124
307
|
|
|
125
|
-
```
|
|
126
|
-
function setTreeItemProperties(
|
|
127
|
-
items: TreeItems
|
|
308
|
+
```ts
|
|
309
|
+
function setTreeItemProperties<T extends TreeItem>(
|
|
310
|
+
items: TreeItems<T>,
|
|
128
311
|
id: UniqueIdentifier,
|
|
129
|
-
setter: (value:
|
|
130
|
-
): TreeItems
|
|
312
|
+
setter: (value: T) => Partial<T>,
|
|
313
|
+
): TreeItems<T>;
|
|
131
314
|
```
|
|
132
315
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
Usage example:
|
|
136
|
-
|
|
137
|
-
```typescript
|
|
138
|
-
setItems((items) => {
|
|
139
|
-
return setTreeItemProperties(items, '123', (item) => ({
|
|
140
|
-
label: 'New Label',
|
|
141
|
-
collapsed: !item.collapsed,
|
|
142
|
-
}));
|
|
143
|
-
});
|
|
144
|
-
```
|
|
316
|
+
---
|
|
145
317
|
|
|
146
318
|
## Roadmap
|
|
147
319
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
-
|
|
151
|
-
-
|
|
152
|
-
-
|
|
153
|
-
-
|
|
154
|
-
-
|
|
155
|
-
- **E2E tests**: It will ensure this component's working as expected.
|
|
156
|
-
|
|
157
|
-
We're excited about these upcoming features and welcome any feedback or contributions from the community. If you have any suggestions or would like to contribute to any of these features, please open an issue or submit a pull request on our GitHub repository.
|
|
158
|
-
|
|
159
|
-
## Release Process
|
|
160
|
-
|
|
161
|
-
This package is automatically published to npm when a new release is created on GitHub. To create a new release:
|
|
162
|
-
|
|
163
|
-
1. Update the version in `package.json` according to semantic versioning rules.
|
|
164
|
-
2. Commit the version change: `git commit -am "Bump version to x.x.x"`
|
|
165
|
-
3. Create a new tag: `git tag vx.x.x`
|
|
166
|
-
4. Push the changes and the tag: `git push && git push --tags`
|
|
167
|
-
5. Go to the GitHub repository and create a new release, selecting the tag you just created.
|
|
320
|
+
- ✅ Custom item rendering (done!)
|
|
321
|
+
- 🔜 Virtualization for large trees
|
|
322
|
+
- 🔜 Multi-selection support
|
|
323
|
+
- 🔜 Drag multiple items
|
|
324
|
+
- 🔜 Keyboard navigation
|
|
325
|
+
- 🔜 API usage example
|
|
326
|
+
- 🔜 E2E tests
|
|
168
327
|
|
|
169
|
-
|
|
328
|
+
---
|
|
170
329
|
|
|
171
330
|
## License
|
|
172
331
|
|
|
@@ -1,4 +1,2 @@
|
|
|
1
|
-
import { SortableTreeProps } from './types';
|
|
2
|
-
declare
|
|
3
|
-
export declare const SortableTree: import('react').MemoExoticComponent<typeof PrivateSortableTree>;
|
|
4
|
-
export {};
|
|
1
|
+
import { SortableTreeProps, TreeItem } from './types';
|
|
2
|
+
export declare const SortableTree: <T extends TreeItem = TreeItem>(props: SortableTreeProps<T>) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
import { default as React, HTMLAttributes } from 'react';
|
|
2
|
-
|
|
2
|
+
import { TreeItemStructureProps } from '../TreeItemStructure';
|
|
3
|
+
import { TreeItem as TTreeItem } from '../../types';
|
|
4
|
+
export interface RenderItemProps<T extends TTreeItem = TTreeItem> extends Pick<TreeItemStructureProps, 'classNames' | 'dropZoneStyle' | 'dropZoneRef' | 'draggableItemRef'>, Pick<Props, 'onCollapse' | 'childCount' | 'clone' | 'ghost' | 'indicator' | 'disableSelection' | 'disableInteraction' | 'collapsed'> {
|
|
5
|
+
dragListeners?: any;
|
|
6
|
+
treeItem: T;
|
|
7
|
+
dataSlots: {
|
|
8
|
+
dropZone: Record<string, string | boolean | undefined>;
|
|
9
|
+
draggableItem: Record<string, string>;
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
export interface Props<T extends TTreeItem = TTreeItem> extends Omit<HTMLAttributes<HTMLLIElement>, 'id'> {
|
|
3
13
|
childCount?: number;
|
|
4
14
|
clone?: boolean;
|
|
5
15
|
collapsed?: boolean;
|
|
@@ -11,13 +21,13 @@ export interface Props extends Omit<HTMLAttributes<HTMLLIElement>, 'id'> {
|
|
|
11
21
|
handleProps?: any;
|
|
12
22
|
indicator?: boolean;
|
|
13
23
|
indentationWidth: number;
|
|
14
|
-
value:
|
|
24
|
+
value: T;
|
|
15
25
|
onCollapse?(): void;
|
|
16
26
|
onRemove?(): void;
|
|
17
27
|
onAdd?(): void;
|
|
18
28
|
onLabelClick?(): void;
|
|
19
|
-
wrapperRef
|
|
20
|
-
|
|
29
|
+
wrapperRef: RenderItemProps<T>['dropZoneRef'];
|
|
30
|
+
renderItem?: (props: RenderItemProps<T>) => React.ReactNode;
|
|
21
31
|
}
|
|
22
|
-
export declare const _TreeItem: React.ForwardRefExoticComponent<Props & React.RefAttributes<HTMLDivElement>>;
|
|
23
|
-
export declare const TreeItem: React.
|
|
32
|
+
export declare const _TreeItem: React.ForwardRefExoticComponent<Props<import('../..').BaseTreeItem<unknown>> & React.RefAttributes<HTMLDivElement>>;
|
|
33
|
+
export declare const TreeItem: React.NamedExoticComponent<Props<import('../..').BaseTreeItem<unknown>> & React.RefAttributes<HTMLDivElement>>;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export interface TreeItemStructureProps {
|
|
2
|
+
dropZoneRef: (element: HTMLElement | null) => void;
|
|
3
|
+
draggableItemRef: React.Ref<any>;
|
|
4
|
+
dropZoneStyle?: React.CSSProperties;
|
|
5
|
+
draggableItemStyle?: React.CSSProperties;
|
|
6
|
+
classNames?: {
|
|
7
|
+
dropZone?: string;
|
|
8
|
+
draggableItem?: string;
|
|
9
|
+
};
|
|
10
|
+
asDropZone?: React.ElementType;
|
|
11
|
+
asDraggableItem?: React.ElementType;
|
|
12
|
+
draggableItemProps?: Record<string, any>;
|
|
13
|
+
children?: React.ReactNode;
|
|
14
|
+
dataSlots: {
|
|
15
|
+
dropZone: Record<string, string | boolean | undefined>;
|
|
16
|
+
draggableItem: Record<string, string>;
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
export declare const TreeItemStructure: ({ dropZoneRef, draggableItemRef, dropZoneStyle, draggableItemStyle, classNames, asDropZone: DropZoneComponent, asDraggableItem: DraggableComponent, draggableItemProps, children, dataSlots, }: TreeItemStructureProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
type SortableTreeStyleOptions = {
|
|
2
|
+
indicatorColor?: string;
|
|
3
|
+
indicatorBorderColor?: string;
|
|
4
|
+
indicatorDotColor?: string;
|
|
5
|
+
dragBoxShadow?: string;
|
|
6
|
+
};
|
|
7
|
+
export declare const createSortableTreeGlobalStyles: (options?: SortableTreeStyleOptions) => () => void;
|
|
8
|
+
export {};
|
|
@@ -1,3 +1,6 @@
|
|
|
1
1
|
export * from './types';
|
|
2
2
|
export { SortableTree } from './SortableTree';
|
|
3
|
+
export { TreeItemStructure } from './components';
|
|
4
|
+
export type { TreeItemStructureProps, RenderItemProps } from './components';
|
|
3
5
|
export { setTreeItemProperties, removeItemById, getItemById } from './utilities';
|
|
6
|
+
export { createSortableTreeGlobalStyles } from './createSortableTreeGlobalStyles';
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { MutableRefObject } from 'react';
|
|
2
2
|
import { UniqueIdentifier } from '@dnd-kit/core';
|
|
3
|
+
import { Props } from './components/TreeItem/TreeItem';
|
|
4
|
+
export type TreeItem<ExtraProps = unknown> = BaseTreeItem & ExtraProps;
|
|
3
5
|
/**
|
|
4
6
|
* Represents an item in the tree structure.
|
|
5
7
|
*/
|
|
6
|
-
export type
|
|
8
|
+
export type BaseTreeItem<ExtraProps = unknown> = {
|
|
7
9
|
/**
|
|
8
10
|
* Unique identifier for the item. Can be a string or number.
|
|
9
11
|
*/
|
|
@@ -15,7 +17,7 @@ export type TreeItem = {
|
|
|
15
17
|
/**
|
|
16
18
|
* An array of child TreeItems. If empty, the item is a leaf node.
|
|
17
19
|
*/
|
|
18
|
-
children: TreeItem[];
|
|
20
|
+
children: TreeItem<ExtraProps>[];
|
|
19
21
|
/**
|
|
20
22
|
* Determines whether the item's children are initially collapsed.
|
|
21
23
|
* @default false
|
|
@@ -34,12 +36,8 @@ export type TreeItem = {
|
|
|
34
36
|
* @default false
|
|
35
37
|
*/
|
|
36
38
|
disableDragging?: boolean;
|
|
37
|
-
/**
|
|
38
|
-
* Any additional custom properties can be added here.
|
|
39
|
-
*/
|
|
40
|
-
[key: string]: any;
|
|
41
39
|
};
|
|
42
|
-
export type TreeItems = TreeItem[];
|
|
40
|
+
export type TreeItems<ExtraProps = unknown> = TreeItem<ExtraProps>[];
|
|
43
41
|
export interface FlattenedItem extends TreeItem {
|
|
44
42
|
parentId: UniqueIdentifier | null;
|
|
45
43
|
depth: number;
|
|
@@ -52,7 +50,7 @@ export type SensorContext = MutableRefObject<{
|
|
|
52
50
|
/**
|
|
53
51
|
* Props for the SortableTree component.
|
|
54
52
|
*/
|
|
55
|
-
export interface SortableTreeProps {
|
|
53
|
+
export interface SortableTreeProps<T extends TreeItem = TreeItem> {
|
|
56
54
|
/**
|
|
57
55
|
* A control that lets you add the indentation width for children elements
|
|
58
56
|
*/
|
|
@@ -60,12 +58,12 @@ export interface SortableTreeProps {
|
|
|
60
58
|
/**
|
|
61
59
|
* The array of tree items to be rendered.
|
|
62
60
|
*/
|
|
63
|
-
items: TreeItems
|
|
61
|
+
items: TreeItems<T>;
|
|
64
62
|
/**
|
|
65
63
|
* Callback function called when the tree structure changes.
|
|
66
64
|
* @param items - The updated array of tree items.
|
|
67
65
|
*/
|
|
68
|
-
setItems: React.Dispatch<React.SetStateAction<TreeItems
|
|
66
|
+
setItems: React.Dispatch<React.SetStateAction<TreeItems<T>>>;
|
|
69
67
|
/**
|
|
70
68
|
* Determines if tree items can be collapsed/expanded.
|
|
71
69
|
* @default false
|
|
@@ -119,7 +117,7 @@ export interface SortableTreeProps {
|
|
|
119
117
|
* @param item
|
|
120
118
|
* @returns
|
|
121
119
|
*/
|
|
122
|
-
renderItem?:
|
|
120
|
+
renderItem?: Props<T>['renderItem'];
|
|
123
121
|
}
|
|
124
122
|
/**
|
|
125
123
|
* Represents the result of a drag operation in the tree.
|
|
@@ -9,16 +9,16 @@ export declare function getProjection(items: FlattenedItem[], activeId: UniqueId
|
|
|
9
9
|
};
|
|
10
10
|
export declare function flattenTree(items: TreeItems): FlattenedItem[];
|
|
11
11
|
export declare function buildTree(flattenedItems: FlattenedItem[]): TreeItems;
|
|
12
|
-
export declare function findItem(items: TreeItem[], itemId: UniqueIdentifier):
|
|
12
|
+
export declare function findItem(items: TreeItem[], itemId: UniqueIdentifier): import('./types').BaseTreeItem<unknown> | undefined;
|
|
13
13
|
export declare function findItemDeep(items: TreeItems, itemId: UniqueIdentifier): TreeItem | undefined;
|
|
14
|
-
export declare function removeItemById(items: TreeItems
|
|
15
|
-
export declare function setTreeItemProperties(items: TreeItems
|
|
14
|
+
export declare function removeItemById<T extends TreeItem>(items: TreeItems<T>, id: UniqueIdentifier): TreeItems<T>;
|
|
15
|
+
export declare function setTreeItemProperties<T extends TreeItem>(items: TreeItems<T>, id: UniqueIdentifier, setter: (value: T) => Partial<T>): TreeItems<T>;
|
|
16
16
|
/**
|
|
17
17
|
* Retrieves a tree item by its unique identifier.
|
|
18
18
|
* @param structure The current tree items array
|
|
19
19
|
* @param id The unique identifier of the item to retrieve.
|
|
20
20
|
* @returns The tree item if found, undefined otherwise.
|
|
21
21
|
*/
|
|
22
|
-
export declare function getItemById(items: TreeItems
|
|
22
|
+
export declare function getItemById<T extends TreeItem>(items: TreeItems<T>, id: UniqueIdentifier): TreeItem<T> | undefined;
|
|
23
23
|
export declare function getChildCount(treeStructure: TreeItems, id: UniqueIdentifier): number;
|
|
24
24
|
export declare function removeChildrenOf(items: FlattenedItem[], ids: UniqueIdentifier[]): FlattenedItem[];
|