@dxos/react-ui-mosaic 0.3.3-main.006ca4d
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/LICENSE +8 -0
- package/README.md +45 -0
- package/dist/lib/browser/index.mjs +596 -0
- package/dist/lib/browser/index.mjs.map +7 -0
- package/dist/lib/browser/meta.json +1 -0
- package/dist/types/src/index.d.ts +2 -0
- package/dist/types/src/index.d.ts.map +1 -0
- package/dist/types/src/mosaic/Container.d.ts +65 -0
- package/dist/types/src/mosaic/Container.d.ts.map +1 -0
- package/dist/types/src/mosaic/Debug.d.ts +9 -0
- package/dist/types/src/mosaic/Debug.d.ts.map +1 -0
- package/dist/types/src/mosaic/DefaultComponent.d.ts +4 -0
- package/dist/types/src/mosaic/DefaultComponent.d.ts.map +1 -0
- package/dist/types/src/mosaic/DragOverlay.d.ts +11 -0
- package/dist/types/src/mosaic/DragOverlay.d.ts.map +1 -0
- package/dist/types/src/mosaic/Mosaic.d.ts +32 -0
- package/dist/types/src/mosaic/Mosaic.d.ts.map +1 -0
- package/dist/types/src/mosaic/Root.d.ts +24 -0
- package/dist/types/src/mosaic/Root.d.ts.map +1 -0
- package/dist/types/src/mosaic/SortableContext.d.ts +14 -0
- package/dist/types/src/mosaic/SortableContext.d.ts.map +1 -0
- package/dist/types/src/mosaic/Tile.d.ts +41 -0
- package/dist/types/src/mosaic/Tile.d.ts.map +1 -0
- package/dist/types/src/mosaic/hooks/index.d.ts +5 -0
- package/dist/types/src/mosaic/hooks/index.d.ts.map +1 -0
- package/dist/types/src/mosaic/hooks/useContainer.d.ts +4 -0
- package/dist/types/src/mosaic/hooks/useContainer.d.ts.map +1 -0
- package/dist/types/src/mosaic/hooks/useItemsWithPreview.d.ts +10 -0
- package/dist/types/src/mosaic/hooks/useItemsWithPreview.d.ts.map +1 -0
- package/dist/types/src/mosaic/hooks/useMosaic.d.ts +2 -0
- package/dist/types/src/mosaic/hooks/useMosaic.d.ts.map +1 -0
- package/dist/types/src/mosaic/hooks/useSortedItems.d.ts +6 -0
- package/dist/types/src/mosaic/hooks/useSortedItems.d.ts.map +1 -0
- package/dist/types/src/mosaic/index.d.ts +5 -0
- package/dist/types/src/mosaic/index.d.ts.map +1 -0
- package/dist/types/src/mosaic/types.d.ts +9 -0
- package/dist/types/src/mosaic/types.d.ts.map +1 -0
- package/dist/types/src/mosaic/util/data.d.ts +3 -0
- package/dist/types/src/mosaic/util/data.d.ts.map +1 -0
- package/dist/types/src/mosaic/util/index.d.ts +4 -0
- package/dist/types/src/mosaic/util/index.d.ts.map +1 -0
- package/dist/types/src/mosaic/util/path.d.ts +14 -0
- package/dist/types/src/mosaic/util/path.d.ts.map +1 -0
- package/dist/types/src/mosaic/util/path.test.d.ts +2 -0
- package/dist/types/src/mosaic/util/path.test.d.ts.map +1 -0
- package/dist/types/src/mosaic/util/styles.d.ts +3 -0
- package/dist/types/src/mosaic/util/styles.d.ts.map +1 -0
- package/dist/types/src/testing/Cards.d.ts +10 -0
- package/dist/types/src/testing/Cards.d.ts.map +1 -0
- package/dist/types/src/testing/decorators.d.ts +4 -0
- package/dist/types/src/testing/decorators.d.ts.map +1 -0
- package/dist/types/src/testing/generator.d.ts +43 -0
- package/dist/types/src/testing/generator.d.ts.map +1 -0
- package/dist/types/src/testing/index.d.ts +5 -0
- package/dist/types/src/testing/index.d.ts.map +1 -0
- package/dist/types/src/testing/next-fractional-index.d.ts +5 -0
- package/dist/types/src/testing/next-fractional-index.d.ts.map +1 -0
- package/dist/types/src/views/Demo/Demo.stories.d.ts +13 -0
- package/dist/types/src/views/Demo/Demo.stories.d.ts.map +1 -0
- package/dist/types/src/views/Demo/Echo.stories.d.ts +12 -0
- package/dist/types/src/views/Demo/Echo.stories.d.ts.map +1 -0
- package/dist/types/src/views/Grid/Grid.d.ts +30 -0
- package/dist/types/src/views/Grid/Grid.d.ts.map +1 -0
- package/dist/types/src/views/Grid/Grid.stories.d.ts +13 -0
- package/dist/types/src/views/Grid/Grid.stories.d.ts.map +1 -0
- package/dist/types/src/views/Grid/index.d.ts +3 -0
- package/dist/types/src/views/Grid/index.d.ts.map +1 -0
- package/dist/types/src/views/Grid/layout.d.ts +27 -0
- package/dist/types/src/views/Grid/layout.d.ts.map +1 -0
- package/dist/types/src/views/Grid/testing.d.ts +10 -0
- package/dist/types/src/views/Grid/testing.d.ts.map +1 -0
- package/dist/types/src/views/Kanban/Echo.stories.d.ts +18 -0
- package/dist/types/src/views/Kanban/Echo.stories.d.ts.map +1 -0
- package/dist/types/src/views/Kanban/Kanban.d.ts +11 -0
- package/dist/types/src/views/Kanban/Kanban.d.ts.map +1 -0
- package/dist/types/src/views/Kanban/Kanban.stories.d.ts +28 -0
- package/dist/types/src/views/Kanban/Kanban.stories.d.ts.map +1 -0
- package/dist/types/src/views/Kanban/index.d.ts +2 -0
- package/dist/types/src/views/Kanban/index.d.ts.map +1 -0
- package/dist/types/src/views/Kanban/testing.d.ts +20 -0
- package/dist/types/src/views/Kanban/testing.d.ts.map +1 -0
- package/dist/types/src/views/Stack/Columns.stories.d.ts +34 -0
- package/dist/types/src/views/Stack/Columns.stories.d.ts.map +1 -0
- package/dist/types/src/views/Stack/Stack.d.ts +9 -0
- package/dist/types/src/views/Stack/Stack.d.ts.map +1 -0
- package/dist/types/src/views/Stack/Stack.stories.d.ts +39 -0
- package/dist/types/src/views/Stack/Stack.stories.d.ts.map +1 -0
- package/dist/types/src/views/Stack/index.d.ts +2 -0
- package/dist/types/src/views/Stack/index.d.ts.map +1 -0
- package/dist/types/src/views/Stack/testing.d.ts +9 -0
- package/dist/types/src/views/Stack/testing.d.ts.map +1 -0
- package/dist/types/src/views/Tree/Graph.stories.d.ts +21 -0
- package/dist/types/src/views/Tree/Graph.stories.d.ts.map +1 -0
- package/dist/types/src/views/Tree/Tree.d.ts +13 -0
- package/dist/types/src/views/Tree/Tree.d.ts.map +1 -0
- package/dist/types/src/views/Tree/Tree.stories.d.ts +41 -0
- package/dist/types/src/views/Tree/Tree.stories.d.ts.map +1 -0
- package/dist/types/src/views/Tree/index.d.ts +2 -0
- package/dist/types/src/views/Tree/index.d.ts.map +1 -0
- package/dist/types/src/views/Tree/testing.d.ts +15 -0
- package/dist/types/src/views/Tree/testing.d.ts.map +1 -0
- package/dist/types/src/views/index.d.ts +5 -0
- package/dist/types/src/views/index.d.ts.map +1 -0
- package/package.json +67 -0
- package/src/index.ts +5 -0
- package/src/mosaic/Container.tsx +137 -0
- package/src/mosaic/Debug.tsx +24 -0
- package/src/mosaic/DefaultComponent.tsx +26 -0
- package/src/mosaic/DragOverlay.tsx +136 -0
- package/src/mosaic/Mosaic.ts +84 -0
- package/src/mosaic/Root.tsx +255 -0
- package/src/mosaic/SortableContext.tsx +60 -0
- package/src/mosaic/Tile.tsx +189 -0
- package/src/mosaic/hooks/index.ts +8 -0
- package/src/mosaic/hooks/useContainer.ts +16 -0
- package/src/mosaic/hooks/useItemsWithPreview.ts +64 -0
- package/src/mosaic/hooks/useMosaic.ts +11 -0
- package/src/mosaic/hooks/useSortedItems.ts +14 -0
- package/src/mosaic/index.ts +9 -0
- package/src/mosaic/types.ts +13 -0
- package/src/mosaic/util/data.ts +19 -0
- package/src/mosaic/util/index.ts +7 -0
- package/src/mosaic/util/path.test.ts +26 -0
- package/src/mosaic/util/path.ts +21 -0
- package/src/mosaic/util/styles.ts +10 -0
- package/src/testing/Cards.tsx +88 -0
- package/src/testing/decorators.tsx +20 -0
- package/src/testing/generator.ts +135 -0
- package/src/testing/index.ts +9 -0
- package/src/testing/next-fractional-index.ts +36 -0
- package/src/views/Demo/Demo.stories.tsx +79 -0
- package/src/views/Demo/Echo.stories.tsx +74 -0
- package/src/views/Grid/Grid.stories.tsx +48 -0
- package/src/views/Grid/Grid.tsx +248 -0
- package/src/views/Grid/index.ts +7 -0
- package/src/views/Grid/layout.ts +42 -0
- package/src/views/Grid/testing.tsx +91 -0
- package/src/views/Kanban/Echo.stories.tsx +67 -0
- package/src/views/Kanban/Kanban.stories.tsx +48 -0
- package/src/views/Kanban/Kanban.tsx +139 -0
- package/src/views/Kanban/index.ts +5 -0
- package/src/views/Kanban/testing.tsx +231 -0
- package/src/views/Stack/Columns.stories.tsx +61 -0
- package/src/views/Stack/Stack.stories.tsx +62 -0
- package/src/views/Stack/Stack.tsx +58 -0
- package/src/views/Stack/index.ts +5 -0
- package/src/views/Stack/testing.tsx +77 -0
- package/src/views/Tree/Graph.stories.tsx +36 -0
- package/src/views/Tree/Tree.stories.tsx +92 -0
- package/src/views/Tree/Tree.tsx +128 -0
- package/src/views/Tree/index.ts +5 -0
- package/src/views/Tree/testing.tsx +156 -0
- package/src/views/index.ts +8 -0
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2023 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import React, { forwardRef } from 'react';
|
|
6
|
+
|
|
7
|
+
import { Card, Tree as TreeComponent, TreeItem as TreeItemComponent } from '@dxos/react-ui';
|
|
8
|
+
import { dropRing, mx } from '@dxos/react-ui-theme';
|
|
9
|
+
|
|
10
|
+
import {
|
|
11
|
+
type MosaicContainerProps,
|
|
12
|
+
Mosaic,
|
|
13
|
+
type MosaicDataItem,
|
|
14
|
+
type MosaicTileComponent,
|
|
15
|
+
useContainer,
|
|
16
|
+
useMosaic,
|
|
17
|
+
Path,
|
|
18
|
+
useSortedItems,
|
|
19
|
+
type MosaicCompareDataItem,
|
|
20
|
+
} from '../../mosaic';
|
|
21
|
+
|
|
22
|
+
// TODO(burdon): Tree data model that provides a pure abstraction of the plugin Graph.
|
|
23
|
+
// - The Tree (like Stack, Grid) is a high level container that assembles Radix style DXOS UI components from a model.
|
|
24
|
+
// - Models in general should be easily mapped from the Graph and/or ECHO queries.
|
|
25
|
+
// - See: https://master--5fc05e08a4a65d0021ae0bf2.chromatic.com/?path=/story/examples-tree-sortable--basic-setup
|
|
26
|
+
|
|
27
|
+
export type TreeProps<TData extends MosaicDataItem = TreeData> = MosaicContainerProps<TData, number> & {
|
|
28
|
+
items?: TData[];
|
|
29
|
+
debug?: boolean;
|
|
30
|
+
compare?: MosaicCompareDataItem;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export type TreeData = {
|
|
34
|
+
id: string;
|
|
35
|
+
label?: string; // TODO(burdon): Provide adapter.
|
|
36
|
+
children: TreeData[];
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
// TODO(burdon): Make generic (and forwardRef).
|
|
40
|
+
export const Tree = ({ id, Component = TreeItem, onOver, onDrop, items = [], debug, compare }: TreeProps) => {
|
|
41
|
+
return (
|
|
42
|
+
<Mosaic.Container
|
|
43
|
+
{...{
|
|
44
|
+
id,
|
|
45
|
+
debug,
|
|
46
|
+
Component,
|
|
47
|
+
onOver,
|
|
48
|
+
onDrop,
|
|
49
|
+
compare,
|
|
50
|
+
}}
|
|
51
|
+
>
|
|
52
|
+
<TreeRoot items={items} />
|
|
53
|
+
</Mosaic.Container>
|
|
54
|
+
);
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
const TreeRoot = ({ items }: { items: TreeData[] }) => {
|
|
58
|
+
const { id, Component } = useContainer();
|
|
59
|
+
const sortedItems = useSortedItems(items);
|
|
60
|
+
|
|
61
|
+
return (
|
|
62
|
+
<TreeComponent.Root classNames='flex flex-col'>
|
|
63
|
+
<Mosaic.SortableContext id={id} items={sortedItems} direction='vertical'>
|
|
64
|
+
{sortedItems.map((item, index) => (
|
|
65
|
+
<TreeItemComponent.Root key={item.id} collapsible defaultOpen>
|
|
66
|
+
<Mosaic.SortableTile item={item} path={id} position={index} Component={Component!} />
|
|
67
|
+
</TreeItemComponent.Root>
|
|
68
|
+
))}
|
|
69
|
+
</Mosaic.SortableContext>
|
|
70
|
+
</TreeComponent.Root>
|
|
71
|
+
);
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Pure component that is used by the mosaic overlay.
|
|
76
|
+
*/
|
|
77
|
+
const TreeItem: MosaicTileComponent<TreeData> = forwardRef(
|
|
78
|
+
({ path, draggableStyle, draggableProps, item, operation, active, isOver, isDragging, className }, forwardedRef) => {
|
|
79
|
+
return (
|
|
80
|
+
<div
|
|
81
|
+
ref={forwardedRef}
|
|
82
|
+
style={draggableStyle}
|
|
83
|
+
className={mx(
|
|
84
|
+
'flex flex-col rounded',
|
|
85
|
+
className,
|
|
86
|
+
(active === 'rearrange' || active === 'origin') && 'opacity-0',
|
|
87
|
+
active === 'destination' && 'opacity-20',
|
|
88
|
+
isOver && dropRing,
|
|
89
|
+
)}
|
|
90
|
+
>
|
|
91
|
+
<Card.Header>
|
|
92
|
+
<Card.DragHandle {...draggableProps} />
|
|
93
|
+
<Card.Title title={item.label ?? path} classNames='truncate' />
|
|
94
|
+
</Card.Header>
|
|
95
|
+
|
|
96
|
+
{!active && item.children && <TreeBranch path={path} items={item.children} />}
|
|
97
|
+
</div>
|
|
98
|
+
);
|
|
99
|
+
},
|
|
100
|
+
);
|
|
101
|
+
|
|
102
|
+
const TreeBranch = ({ path, items }: { path: string; items: TreeData[] }) => {
|
|
103
|
+
const { operation, overItem } = useMosaic();
|
|
104
|
+
const { Component } = useContainer();
|
|
105
|
+
const sortedItems = useSortedItems(items);
|
|
106
|
+
|
|
107
|
+
return (
|
|
108
|
+
<TreeItemComponent.Body className='pis-4'>
|
|
109
|
+
<Mosaic.SortableContext id={path} items={sortedItems} direction='vertical'>
|
|
110
|
+
{sortedItems.map((child, index) => (
|
|
111
|
+
<TreeComponent.Branch key={child.id}>
|
|
112
|
+
<TreeItemComponent.Root collapsible defaultOpen>
|
|
113
|
+
<Mosaic.SortableTile
|
|
114
|
+
item={child}
|
|
115
|
+
path={path}
|
|
116
|
+
position={index}
|
|
117
|
+
Component={Component!}
|
|
118
|
+
isOver={
|
|
119
|
+
overItem?.path === Path.create(path, child.id) && (operation === 'adopt' || operation === 'copy')
|
|
120
|
+
}
|
|
121
|
+
/>
|
|
122
|
+
</TreeItemComponent.Root>
|
|
123
|
+
</TreeComponent.Branch>
|
|
124
|
+
))}
|
|
125
|
+
</Mosaic.SortableContext>
|
|
126
|
+
</TreeItemComponent.Body>
|
|
127
|
+
);
|
|
128
|
+
};
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2023 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { faker } from '@faker-js/faker';
|
|
6
|
+
import React, { useCallback, useState } from 'react';
|
|
7
|
+
|
|
8
|
+
import { type Graph, GraphBuilder, type Node } from '@braneframe/plugin-graph';
|
|
9
|
+
import { buildGraph } from '@braneframe/plugin-graph/testing';
|
|
10
|
+
import { arrayMove } from '@dxos/util';
|
|
11
|
+
|
|
12
|
+
import { Tree, type TreeData, type TreeProps } from './Tree';
|
|
13
|
+
import { type MosaicDropEvent, type MosaicMoveEvent, Path } from '../../mosaic';
|
|
14
|
+
import { TestObjectGenerator, nextRearrangeIndex } from '../../testing';
|
|
15
|
+
|
|
16
|
+
const fake = faker.helpers.fake;
|
|
17
|
+
|
|
18
|
+
export type DemoTreeProps = TreeProps & {
|
|
19
|
+
initialItems?: TreeData[];
|
|
20
|
+
types?: string[];
|
|
21
|
+
debug?: boolean;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export const DemoTree = ({ id = 'tree', initialItems, types, debug }: DemoTreeProps) => {
|
|
25
|
+
const [items, setItems] = useState<TreeData[]>(
|
|
26
|
+
initialItems ??
|
|
27
|
+
(() => {
|
|
28
|
+
const generator = new TestObjectGenerator({ types });
|
|
29
|
+
return Array.from({ length: 4 }).map(() => {
|
|
30
|
+
const item = generator.createObject();
|
|
31
|
+
return {
|
|
32
|
+
// TODO(wittjosiah): Object id isn't included in spread data.
|
|
33
|
+
id: item.id,
|
|
34
|
+
...item,
|
|
35
|
+
label: item.title,
|
|
36
|
+
children: Array.from({ length: 3 }).map(() => {
|
|
37
|
+
const item = generator.createObject();
|
|
38
|
+
return {
|
|
39
|
+
id: item.id,
|
|
40
|
+
...item,
|
|
41
|
+
label: item.title,
|
|
42
|
+
children: [],
|
|
43
|
+
};
|
|
44
|
+
}),
|
|
45
|
+
};
|
|
46
|
+
});
|
|
47
|
+
}),
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
const handleOver = useCallback(({ active, over }: MosaicMoveEvent<number>) => {
|
|
51
|
+
return !(active.path === id && over.path !== id) ? 'adopt' : 'reject';
|
|
52
|
+
}, []);
|
|
53
|
+
|
|
54
|
+
// NOTE: Does not handle deep operations.
|
|
55
|
+
const handleDrop = useCallback(
|
|
56
|
+
({ active, over }: MosaicDropEvent<number>) => {
|
|
57
|
+
if (active.path === Path.create(id, active.item.id)) {
|
|
58
|
+
setItems((items) => {
|
|
59
|
+
const activeIndex = items.findIndex((item) => item.id === active.item.id);
|
|
60
|
+
const overIndex = items.findIndex((item) => item.id === over.item.id);
|
|
61
|
+
return [...arrayMove(items, activeIndex, overIndex)];
|
|
62
|
+
});
|
|
63
|
+
} else {
|
|
64
|
+
setItems((items) =>
|
|
65
|
+
items.map((item) => {
|
|
66
|
+
const children = [...item.children];
|
|
67
|
+
if (Path.last(Path.parent(active.path)) === item.id) {
|
|
68
|
+
children.splice(active.position!, 1);
|
|
69
|
+
}
|
|
70
|
+
if (Path.last(Path.parent(over.path)) === item.id) {
|
|
71
|
+
children.splice(over.position!, 0, active.item as TreeData);
|
|
72
|
+
}
|
|
73
|
+
return { ...item, children };
|
|
74
|
+
}),
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
[items],
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
return <Tree id={id} items={items} onOver={handleOver} onDrop={handleDrop} />;
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
export const createGraph = () => {
|
|
85
|
+
const content = [...Array(2)].map((_, i) => ({
|
|
86
|
+
id: faker.string.hexadecimal({ length: 4 }).slice(2).toUpperCase(),
|
|
87
|
+
label: fake('{{commerce.productMaterial}} {{animal.cat}}'),
|
|
88
|
+
description: fake('{{commerce.productDescription}}'),
|
|
89
|
+
properties: { index: `a${i}` },
|
|
90
|
+
children: [...Array(2)].map((_, j) => ({
|
|
91
|
+
id: faker.string.hexadecimal({ length: 4 }).slice(2).toUpperCase(),
|
|
92
|
+
label: fake('{{commerce.productMaterial}} {{animal.cat}}'),
|
|
93
|
+
description: fake('{{commerce.productDescription}}'),
|
|
94
|
+
properties: { index: `a${j}` },
|
|
95
|
+
children: [...Array(2)].map((_, k) => ({
|
|
96
|
+
id: faker.string.hexadecimal({ length: 4 }).slice(2).toUpperCase(),
|
|
97
|
+
label: fake('{{commerce.productMaterial}} {{animal.cat}}'),
|
|
98
|
+
description: fake('{{commerce.productDescription}}'),
|
|
99
|
+
properties: { index: `a${k}` },
|
|
100
|
+
})),
|
|
101
|
+
})),
|
|
102
|
+
}));
|
|
103
|
+
|
|
104
|
+
return buildGraph(new GraphBuilder().build(), 'tree', content);
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
const graphNodeCompare = (a: Node, b: Node) => {
|
|
108
|
+
if (a.properties.index && b.properties.index) {
|
|
109
|
+
if (a.properties.index < b.properties.index) {
|
|
110
|
+
return -1;
|
|
111
|
+
} else if (a.properties.index > b.properties.index) {
|
|
112
|
+
return 1;
|
|
113
|
+
}
|
|
114
|
+
return 0;
|
|
115
|
+
}
|
|
116
|
+
return 0;
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
export const GraphTree = ({ id, graph = createGraph(), debug }: { id: string; graph?: Graph; debug: boolean }) => {
|
|
120
|
+
// TODO(wittjosiah): This graph does not handle order currently.
|
|
121
|
+
const handleDrop = ({ operation, active, over }: MosaicDropEvent<number>) => {
|
|
122
|
+
// Moving within the tree.
|
|
123
|
+
if (Path.hasDescendent(id, active.path) && Path.hasDescendent(id, over.path)) {
|
|
124
|
+
const activeNode = graph.findNode(active.item.id);
|
|
125
|
+
const overNode = graph.findNode(over.item.id);
|
|
126
|
+
const activeParent = activeNode?.parent;
|
|
127
|
+
const overParent = overNode?.parent;
|
|
128
|
+
if (
|
|
129
|
+
activeNode &&
|
|
130
|
+
overNode &&
|
|
131
|
+
activeParent &&
|
|
132
|
+
overParent &&
|
|
133
|
+
activeParent.id === overParent.id &&
|
|
134
|
+
activeNode.id !== overNode.id &&
|
|
135
|
+
operation === 'rearrange'
|
|
136
|
+
) {
|
|
137
|
+
// This is a rearrange operation
|
|
138
|
+
const nextIndex = nextRearrangeIndex(activeParent.children.sort(graphNodeCompare), activeNode.id, overNode.id);
|
|
139
|
+
activeNode.properties.index = nextIndex ?? 'a0';
|
|
140
|
+
} else if (activeNode && activeParent && overParent && operation === 'adopt') {
|
|
141
|
+
activeParent.removeNode(active.item.id);
|
|
142
|
+
overNode.addNode('tree', { ...activeNode });
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
return (
|
|
148
|
+
<Tree
|
|
149
|
+
id={id}
|
|
150
|
+
items={graph.root.children as TreeData[]}
|
|
151
|
+
onDrop={handleDrop}
|
|
152
|
+
debug={debug}
|
|
153
|
+
compare={graphNodeCompare}
|
|
154
|
+
/>
|
|
155
|
+
);
|
|
156
|
+
};
|