@etsoo/react 1.8.46 → 1.8.48
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/lib/cjs/index.d.ts +0 -1
- package/lib/cjs/index.js +0 -1
- package/lib/mjs/index.d.ts +0 -1
- package/lib/mjs/index.js +0 -1
- package/package.json +1 -3
- package/src/index.ts +0 -1
- package/lib/cjs/components/DnDList.d.ts +0 -74
- package/lib/cjs/components/DnDList.js +0 -136
- package/lib/mjs/components/DnDList.d.ts +0 -74
- package/lib/mjs/components/DnDList.js +0 -130
- package/src/components/DnDList.tsx +0 -306
package/lib/cjs/index.d.ts
CHANGED
|
@@ -2,7 +2,6 @@ export * from "./app/CoreConstants";
|
|
|
2
2
|
export * from "./app/EventWatcher";
|
|
3
3
|
export * from "./app/InputDialogProps";
|
|
4
4
|
export * from "./app/ReactUtils";
|
|
5
|
-
export * from "./components/DnDList";
|
|
6
5
|
export * from "./components/DynamicRouter";
|
|
7
6
|
export * from "./components/GridColumn";
|
|
8
7
|
export * from "./components/GridLoader";
|
package/lib/cjs/index.js
CHANGED
|
@@ -20,7 +20,6 @@ __exportStar(require("./app/EventWatcher"), exports);
|
|
|
20
20
|
__exportStar(require("./app/InputDialogProps"), exports);
|
|
21
21
|
__exportStar(require("./app/ReactUtils"), exports);
|
|
22
22
|
// components
|
|
23
|
-
__exportStar(require("./components/DnDList"), exports);
|
|
24
23
|
__exportStar(require("./components/DynamicRouter"), exports);
|
|
25
24
|
__exportStar(require("./components/GridColumn"), exports);
|
|
26
25
|
__exportStar(require("./components/GridLoader"), exports);
|
package/lib/mjs/index.d.ts
CHANGED
|
@@ -2,7 +2,6 @@ export * from "./app/CoreConstants";
|
|
|
2
2
|
export * from "./app/EventWatcher";
|
|
3
3
|
export * from "./app/InputDialogProps";
|
|
4
4
|
export * from "./app/ReactUtils";
|
|
5
|
-
export * from "./components/DnDList";
|
|
6
5
|
export * from "./components/DynamicRouter";
|
|
7
6
|
export * from "./components/GridColumn";
|
|
8
7
|
export * from "./components/GridLoader";
|
package/lib/mjs/index.js
CHANGED
|
@@ -4,7 +4,6 @@ export * from "./app/EventWatcher";
|
|
|
4
4
|
export * from "./app/InputDialogProps";
|
|
5
5
|
export * from "./app/ReactUtils";
|
|
6
6
|
// components
|
|
7
|
-
export * from "./components/DnDList";
|
|
8
7
|
export * from "./components/DynamicRouter";
|
|
9
8
|
export * from "./components/GridColumn";
|
|
10
9
|
export * from "./components/GridLoader";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@etsoo/react",
|
|
3
|
-
"version": "1.8.
|
|
3
|
+
"version": "1.8.48",
|
|
4
4
|
"description": "TypeScript ReactJs UI Independent Framework",
|
|
5
5
|
"main": "lib/cjs/index.js",
|
|
6
6
|
"module": "lib/mjs/index.js",
|
|
@@ -35,8 +35,6 @@
|
|
|
35
35
|
},
|
|
36
36
|
"homepage": "https://github.com/ETSOO/AppReact#readme",
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@dnd-kit/core": "^6.3.1",
|
|
39
|
-
"@dnd-kit/sortable": "^10.0.0",
|
|
40
38
|
"@emotion/css": "^11.13.5",
|
|
41
39
|
"@emotion/react": "^11.14.0",
|
|
42
40
|
"@emotion/styled": "^11.14.0",
|
package/src/index.ts
CHANGED
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
import { UniqueIdentifier } from "@dnd-kit/core";
|
|
2
|
-
import { DataTypes } from "@etsoo/shared";
|
|
3
|
-
import React, { CSSProperties } from "react";
|
|
4
|
-
/**
|
|
5
|
-
* DnD list forward ref
|
|
6
|
-
*/
|
|
7
|
-
export interface DnDListRef<D extends object> {
|
|
8
|
-
/**
|
|
9
|
-
* Add item
|
|
10
|
-
* @param item New item
|
|
11
|
-
*/
|
|
12
|
-
addItem(item: D): void;
|
|
13
|
-
/**
|
|
14
|
-
* Add items
|
|
15
|
-
* @param items items
|
|
16
|
-
*/
|
|
17
|
-
addItems(items: D[]): void;
|
|
18
|
-
/**
|
|
19
|
-
* Delete item
|
|
20
|
-
* @param index Item index
|
|
21
|
-
*/
|
|
22
|
-
deleteItem(index: number): void;
|
|
23
|
-
/**
|
|
24
|
-
* Edit item
|
|
25
|
-
* @param newItem New item
|
|
26
|
-
* @param index Index
|
|
27
|
-
*/
|
|
28
|
-
editItem(newItem: D, index: number): boolean;
|
|
29
|
-
}
|
|
30
|
-
/**
|
|
31
|
-
* DnD sortable list properties
|
|
32
|
-
*/
|
|
33
|
-
export interface DnDListPros<D extends object, K extends DataTypes.Keys<D>> {
|
|
34
|
-
/**
|
|
35
|
-
* Get list item style callback
|
|
36
|
-
*/
|
|
37
|
-
getItemStyle: (index: number, isDragging: boolean) => CSSProperties;
|
|
38
|
-
/**
|
|
39
|
-
* Item renderer
|
|
40
|
-
*/
|
|
41
|
-
itemRenderer: (item: D, index: number, nodeRef: React.ComponentProps<any>, actionNodeRef: React.ComponentProps<any>) => React.ReactElement;
|
|
42
|
-
/**
|
|
43
|
-
* List items
|
|
44
|
-
*/
|
|
45
|
-
items: D[];
|
|
46
|
-
/**
|
|
47
|
-
* Unique key field
|
|
48
|
-
*/
|
|
49
|
-
keyField: K;
|
|
50
|
-
/**
|
|
51
|
-
* Label field
|
|
52
|
-
*/
|
|
53
|
-
labelField: K;
|
|
54
|
-
/**
|
|
55
|
-
* Methods ref
|
|
56
|
-
*/
|
|
57
|
-
mRef?: React.Ref<DnDListRef<D>>;
|
|
58
|
-
/**
|
|
59
|
-
* Data change handler
|
|
60
|
-
*/
|
|
61
|
-
onChange?: (items: D[]) => void;
|
|
62
|
-
/**
|
|
63
|
-
* Drag end handler
|
|
64
|
-
*/
|
|
65
|
-
onDragEnd?: (items: D[]) => void;
|
|
66
|
-
}
|
|
67
|
-
/**
|
|
68
|
-
* DnD (Drag and Drop) sortable list
|
|
69
|
-
* @param props Props
|
|
70
|
-
* @returns Component
|
|
71
|
-
*/
|
|
72
|
-
export declare function DnDList<D extends {
|
|
73
|
-
id: UniqueIdentifier;
|
|
74
|
-
}, K extends DataTypes.Keys<D, UniqueIdentifier> = DataTypes.Keys<D, UniqueIdentifier>>(props: DnDListPros<D, K>): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,136 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.DnDList = DnDList;
|
|
7
|
-
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
8
|
-
const core_1 = require("@dnd-kit/core");
|
|
9
|
-
const sortable_1 = require("@dnd-kit/sortable");
|
|
10
|
-
const utilities_1 = require("@dnd-kit/utilities");
|
|
11
|
-
const react_1 = __importDefault(require("react"));
|
|
12
|
-
function SortableItem(props) {
|
|
13
|
-
// Destruct
|
|
14
|
-
const { id, itemRenderer, style = {} } = props;
|
|
15
|
-
// Use sortable
|
|
16
|
-
const { attributes, listeners, setNodeRef, transform, transition, setActivatorNodeRef } = (0, sortable_1.useSortable)({ id });
|
|
17
|
-
const allStyle = {
|
|
18
|
-
...style,
|
|
19
|
-
transform: utilities_1.CSS.Transform.toString(transform),
|
|
20
|
-
transition
|
|
21
|
-
};
|
|
22
|
-
const nodeRef = {
|
|
23
|
-
style: allStyle,
|
|
24
|
-
ref: setNodeRef,
|
|
25
|
-
...attributes
|
|
26
|
-
};
|
|
27
|
-
const actionNodeRef = {
|
|
28
|
-
...listeners,
|
|
29
|
-
ref: setActivatorNodeRef
|
|
30
|
-
};
|
|
31
|
-
return itemRenderer(nodeRef, actionNodeRef);
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* DnD (Drag and Drop) sortable list
|
|
35
|
-
* @param props Props
|
|
36
|
-
* @returns Component
|
|
37
|
-
*/
|
|
38
|
-
function DnDList(props) {
|
|
39
|
-
// Destruct
|
|
40
|
-
const { getItemStyle, keyField, itemRenderer, labelField, mRef, onChange, onDragEnd } = props;
|
|
41
|
-
// States
|
|
42
|
-
const [items, setItems] = react_1.default.useState([]);
|
|
43
|
-
const [activeId, setActiveId] = react_1.default.useState();
|
|
44
|
-
const changeItems = (newItems) => {
|
|
45
|
-
// Possible to alter items with the handler
|
|
46
|
-
if (onChange)
|
|
47
|
-
onChange(newItems);
|
|
48
|
-
// Update state
|
|
49
|
-
setItems(newItems);
|
|
50
|
-
};
|
|
51
|
-
// Drag event handlers
|
|
52
|
-
function handleDragStart(event) {
|
|
53
|
-
const { active } = event;
|
|
54
|
-
setActiveId(active.id);
|
|
55
|
-
}
|
|
56
|
-
function handleDragEnd(event) {
|
|
57
|
-
const { active, over } = event;
|
|
58
|
-
if (over && active.id !== over.id) {
|
|
59
|
-
// Indices
|
|
60
|
-
const oldIndex = items.findIndex((item) => item.id === active.id);
|
|
61
|
-
const newIndex = items.findIndex((item) => item.id === over.id);
|
|
62
|
-
// Clone
|
|
63
|
-
const newItems = [...items];
|
|
64
|
-
// Removed item
|
|
65
|
-
const [removed] = newItems.splice(oldIndex, 1);
|
|
66
|
-
// Insert to the destination index
|
|
67
|
-
newItems.splice(newIndex, 0, removed);
|
|
68
|
-
changeItems(newItems);
|
|
69
|
-
// Drag end handler
|
|
70
|
-
if (onDragEnd)
|
|
71
|
-
onDragEnd(newItems);
|
|
72
|
-
}
|
|
73
|
-
setActiveId(undefined);
|
|
74
|
-
}
|
|
75
|
-
// Methods
|
|
76
|
-
react_1.default.useImperativeHandle(mRef, () => {
|
|
77
|
-
return {
|
|
78
|
-
addItem(newItem) {
|
|
79
|
-
// Existence check
|
|
80
|
-
if (items.some((item) => item[labelField] === newItem[labelField])) {
|
|
81
|
-
return false;
|
|
82
|
-
}
|
|
83
|
-
// Clone
|
|
84
|
-
const newItems = [newItem, ...items];
|
|
85
|
-
// Update the state
|
|
86
|
-
changeItems(newItems);
|
|
87
|
-
return true;
|
|
88
|
-
},
|
|
89
|
-
addItems(inputItems) {
|
|
90
|
-
// Clone
|
|
91
|
-
const newItems = [...items];
|
|
92
|
-
// Insert items
|
|
93
|
-
inputItems.forEach((newItem) => {
|
|
94
|
-
// Existence check
|
|
95
|
-
if (newItems.some((item) => item[labelField] === newItem[labelField])) {
|
|
96
|
-
return;
|
|
97
|
-
}
|
|
98
|
-
newItems.push(newItem);
|
|
99
|
-
});
|
|
100
|
-
// Update the state
|
|
101
|
-
changeItems(newItems);
|
|
102
|
-
return newItems.length - items.length;
|
|
103
|
-
},
|
|
104
|
-
editItem(newItem, index) {
|
|
105
|
-
// Existence check
|
|
106
|
-
const newIndex = items.findIndex((item) => item[labelField] === newItem[labelField]);
|
|
107
|
-
if (newIndex >= 0 && newIndex !== index) {
|
|
108
|
-
// Label field is the same with a different item
|
|
109
|
-
return false;
|
|
110
|
-
}
|
|
111
|
-
// Clone
|
|
112
|
-
const newItems = [...items];
|
|
113
|
-
// Remove the item
|
|
114
|
-
newItems.splice(index, 1, newItem);
|
|
115
|
-
// Update the state
|
|
116
|
-
changeItems(newItems);
|
|
117
|
-
return true;
|
|
118
|
-
},
|
|
119
|
-
deleteItem(index) {
|
|
120
|
-
// Clone
|
|
121
|
-
const newItems = [...items];
|
|
122
|
-
// Remove the item
|
|
123
|
-
newItems.splice(index, 1);
|
|
124
|
-
// Update the state
|
|
125
|
-
changeItems(newItems);
|
|
126
|
-
}
|
|
127
|
-
};
|
|
128
|
-
}, [items]);
|
|
129
|
-
react_1.default.useEffect(() => {
|
|
130
|
-
setItems(props.items);
|
|
131
|
-
}, [props.items]);
|
|
132
|
-
return ((0, jsx_runtime_1.jsx)(core_1.DndContext, { onDragStart: handleDragStart, onDragEnd: handleDragEnd, children: (0, jsx_runtime_1.jsx)(sortable_1.SortableContext, { items: items, strategy: sortable_1.verticalListSortingStrategy, children: items.map((item, index) => {
|
|
133
|
-
const id = item[keyField];
|
|
134
|
-
return ((0, jsx_runtime_1.jsx)(SortableItem, { id: id, style: getItemStyle(index, id === activeId), itemRenderer: (nodeRef, actionNodeRef) => itemRenderer(item, index, nodeRef, actionNodeRef) }, id));
|
|
135
|
-
}) }) }));
|
|
136
|
-
}
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
import { UniqueIdentifier } from "@dnd-kit/core";
|
|
2
|
-
import { DataTypes } from "@etsoo/shared";
|
|
3
|
-
import React, { CSSProperties } from "react";
|
|
4
|
-
/**
|
|
5
|
-
* DnD list forward ref
|
|
6
|
-
*/
|
|
7
|
-
export interface DnDListRef<D extends object> {
|
|
8
|
-
/**
|
|
9
|
-
* Add item
|
|
10
|
-
* @param item New item
|
|
11
|
-
*/
|
|
12
|
-
addItem(item: D): void;
|
|
13
|
-
/**
|
|
14
|
-
* Add items
|
|
15
|
-
* @param items items
|
|
16
|
-
*/
|
|
17
|
-
addItems(items: D[]): void;
|
|
18
|
-
/**
|
|
19
|
-
* Delete item
|
|
20
|
-
* @param index Item index
|
|
21
|
-
*/
|
|
22
|
-
deleteItem(index: number): void;
|
|
23
|
-
/**
|
|
24
|
-
* Edit item
|
|
25
|
-
* @param newItem New item
|
|
26
|
-
* @param index Index
|
|
27
|
-
*/
|
|
28
|
-
editItem(newItem: D, index: number): boolean;
|
|
29
|
-
}
|
|
30
|
-
/**
|
|
31
|
-
* DnD sortable list properties
|
|
32
|
-
*/
|
|
33
|
-
export interface DnDListPros<D extends object, K extends DataTypes.Keys<D>> {
|
|
34
|
-
/**
|
|
35
|
-
* Get list item style callback
|
|
36
|
-
*/
|
|
37
|
-
getItemStyle: (index: number, isDragging: boolean) => CSSProperties;
|
|
38
|
-
/**
|
|
39
|
-
* Item renderer
|
|
40
|
-
*/
|
|
41
|
-
itemRenderer: (item: D, index: number, nodeRef: React.ComponentProps<any>, actionNodeRef: React.ComponentProps<any>) => React.ReactElement;
|
|
42
|
-
/**
|
|
43
|
-
* List items
|
|
44
|
-
*/
|
|
45
|
-
items: D[];
|
|
46
|
-
/**
|
|
47
|
-
* Unique key field
|
|
48
|
-
*/
|
|
49
|
-
keyField: K;
|
|
50
|
-
/**
|
|
51
|
-
* Label field
|
|
52
|
-
*/
|
|
53
|
-
labelField: K;
|
|
54
|
-
/**
|
|
55
|
-
* Methods ref
|
|
56
|
-
*/
|
|
57
|
-
mRef?: React.Ref<DnDListRef<D>>;
|
|
58
|
-
/**
|
|
59
|
-
* Data change handler
|
|
60
|
-
*/
|
|
61
|
-
onChange?: (items: D[]) => void;
|
|
62
|
-
/**
|
|
63
|
-
* Drag end handler
|
|
64
|
-
*/
|
|
65
|
-
onDragEnd?: (items: D[]) => void;
|
|
66
|
-
}
|
|
67
|
-
/**
|
|
68
|
-
* DnD (Drag and Drop) sortable list
|
|
69
|
-
* @param props Props
|
|
70
|
-
* @returns Component
|
|
71
|
-
*/
|
|
72
|
-
export declare function DnDList<D extends {
|
|
73
|
-
id: UniqueIdentifier;
|
|
74
|
-
}, K extends DataTypes.Keys<D, UniqueIdentifier> = DataTypes.Keys<D, UniqueIdentifier>>(props: DnDListPros<D, K>): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,130 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { DndContext } from "@dnd-kit/core";
|
|
3
|
-
import { SortableContext, useSortable, verticalListSortingStrategy } from "@dnd-kit/sortable";
|
|
4
|
-
import { CSS } from "@dnd-kit/utilities";
|
|
5
|
-
import React from "react";
|
|
6
|
-
function SortableItem(props) {
|
|
7
|
-
// Destruct
|
|
8
|
-
const { id, itemRenderer, style = {} } = props;
|
|
9
|
-
// Use sortable
|
|
10
|
-
const { attributes, listeners, setNodeRef, transform, transition, setActivatorNodeRef } = useSortable({ id });
|
|
11
|
-
const allStyle = {
|
|
12
|
-
...style,
|
|
13
|
-
transform: CSS.Transform.toString(transform),
|
|
14
|
-
transition
|
|
15
|
-
};
|
|
16
|
-
const nodeRef = {
|
|
17
|
-
style: allStyle,
|
|
18
|
-
ref: setNodeRef,
|
|
19
|
-
...attributes
|
|
20
|
-
};
|
|
21
|
-
const actionNodeRef = {
|
|
22
|
-
...listeners,
|
|
23
|
-
ref: setActivatorNodeRef
|
|
24
|
-
};
|
|
25
|
-
return itemRenderer(nodeRef, actionNodeRef);
|
|
26
|
-
}
|
|
27
|
-
/**
|
|
28
|
-
* DnD (Drag and Drop) sortable list
|
|
29
|
-
* @param props Props
|
|
30
|
-
* @returns Component
|
|
31
|
-
*/
|
|
32
|
-
export function DnDList(props) {
|
|
33
|
-
// Destruct
|
|
34
|
-
const { getItemStyle, keyField, itemRenderer, labelField, mRef, onChange, onDragEnd } = props;
|
|
35
|
-
// States
|
|
36
|
-
const [items, setItems] = React.useState([]);
|
|
37
|
-
const [activeId, setActiveId] = React.useState();
|
|
38
|
-
const changeItems = (newItems) => {
|
|
39
|
-
// Possible to alter items with the handler
|
|
40
|
-
if (onChange)
|
|
41
|
-
onChange(newItems);
|
|
42
|
-
// Update state
|
|
43
|
-
setItems(newItems);
|
|
44
|
-
};
|
|
45
|
-
// Drag event handlers
|
|
46
|
-
function handleDragStart(event) {
|
|
47
|
-
const { active } = event;
|
|
48
|
-
setActiveId(active.id);
|
|
49
|
-
}
|
|
50
|
-
function handleDragEnd(event) {
|
|
51
|
-
const { active, over } = event;
|
|
52
|
-
if (over && active.id !== over.id) {
|
|
53
|
-
// Indices
|
|
54
|
-
const oldIndex = items.findIndex((item) => item.id === active.id);
|
|
55
|
-
const newIndex = items.findIndex((item) => item.id === over.id);
|
|
56
|
-
// Clone
|
|
57
|
-
const newItems = [...items];
|
|
58
|
-
// Removed item
|
|
59
|
-
const [removed] = newItems.splice(oldIndex, 1);
|
|
60
|
-
// Insert to the destination index
|
|
61
|
-
newItems.splice(newIndex, 0, removed);
|
|
62
|
-
changeItems(newItems);
|
|
63
|
-
// Drag end handler
|
|
64
|
-
if (onDragEnd)
|
|
65
|
-
onDragEnd(newItems);
|
|
66
|
-
}
|
|
67
|
-
setActiveId(undefined);
|
|
68
|
-
}
|
|
69
|
-
// Methods
|
|
70
|
-
React.useImperativeHandle(mRef, () => {
|
|
71
|
-
return {
|
|
72
|
-
addItem(newItem) {
|
|
73
|
-
// Existence check
|
|
74
|
-
if (items.some((item) => item[labelField] === newItem[labelField])) {
|
|
75
|
-
return false;
|
|
76
|
-
}
|
|
77
|
-
// Clone
|
|
78
|
-
const newItems = [newItem, ...items];
|
|
79
|
-
// Update the state
|
|
80
|
-
changeItems(newItems);
|
|
81
|
-
return true;
|
|
82
|
-
},
|
|
83
|
-
addItems(inputItems) {
|
|
84
|
-
// Clone
|
|
85
|
-
const newItems = [...items];
|
|
86
|
-
// Insert items
|
|
87
|
-
inputItems.forEach((newItem) => {
|
|
88
|
-
// Existence check
|
|
89
|
-
if (newItems.some((item) => item[labelField] === newItem[labelField])) {
|
|
90
|
-
return;
|
|
91
|
-
}
|
|
92
|
-
newItems.push(newItem);
|
|
93
|
-
});
|
|
94
|
-
// Update the state
|
|
95
|
-
changeItems(newItems);
|
|
96
|
-
return newItems.length - items.length;
|
|
97
|
-
},
|
|
98
|
-
editItem(newItem, index) {
|
|
99
|
-
// Existence check
|
|
100
|
-
const newIndex = items.findIndex((item) => item[labelField] === newItem[labelField]);
|
|
101
|
-
if (newIndex >= 0 && newIndex !== index) {
|
|
102
|
-
// Label field is the same with a different item
|
|
103
|
-
return false;
|
|
104
|
-
}
|
|
105
|
-
// Clone
|
|
106
|
-
const newItems = [...items];
|
|
107
|
-
// Remove the item
|
|
108
|
-
newItems.splice(index, 1, newItem);
|
|
109
|
-
// Update the state
|
|
110
|
-
changeItems(newItems);
|
|
111
|
-
return true;
|
|
112
|
-
},
|
|
113
|
-
deleteItem(index) {
|
|
114
|
-
// Clone
|
|
115
|
-
const newItems = [...items];
|
|
116
|
-
// Remove the item
|
|
117
|
-
newItems.splice(index, 1);
|
|
118
|
-
// Update the state
|
|
119
|
-
changeItems(newItems);
|
|
120
|
-
}
|
|
121
|
-
};
|
|
122
|
-
}, [items]);
|
|
123
|
-
React.useEffect(() => {
|
|
124
|
-
setItems(props.items);
|
|
125
|
-
}, [props.items]);
|
|
126
|
-
return (_jsx(DndContext, { onDragStart: handleDragStart, onDragEnd: handleDragEnd, children: _jsx(SortableContext, { items: items, strategy: verticalListSortingStrategy, children: items.map((item, index) => {
|
|
127
|
-
const id = item[keyField];
|
|
128
|
-
return (_jsx(SortableItem, { id: id, style: getItemStyle(index, id === activeId), itemRenderer: (nodeRef, actionNodeRef) => itemRenderer(item, index, nodeRef, actionNodeRef) }, id));
|
|
129
|
-
}) }) }));
|
|
130
|
-
}
|
|
@@ -1,306 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
DndContext,
|
|
3
|
-
DragEndEvent,
|
|
4
|
-
DragStartEvent,
|
|
5
|
-
UniqueIdentifier
|
|
6
|
-
} from "@dnd-kit/core";
|
|
7
|
-
import {
|
|
8
|
-
SortableContext,
|
|
9
|
-
useSortable,
|
|
10
|
-
verticalListSortingStrategy
|
|
11
|
-
} from "@dnd-kit/sortable";
|
|
12
|
-
import { CSS } from "@dnd-kit/utilities";
|
|
13
|
-
import { DataTypes } from "@etsoo/shared";
|
|
14
|
-
import React, { CSSProperties } from "react";
|
|
15
|
-
|
|
16
|
-
function SortableItem(props: {
|
|
17
|
-
id: UniqueIdentifier;
|
|
18
|
-
itemRenderer: (
|
|
19
|
-
nodeRef: React.ComponentProps<any>,
|
|
20
|
-
actionNodeRef: React.ComponentProps<any>
|
|
21
|
-
) => React.ReactElement;
|
|
22
|
-
style?: React.CSSProperties;
|
|
23
|
-
}) {
|
|
24
|
-
// Destruct
|
|
25
|
-
const { id, itemRenderer, style = {} } = props;
|
|
26
|
-
|
|
27
|
-
// Use sortable
|
|
28
|
-
const {
|
|
29
|
-
attributes,
|
|
30
|
-
listeners,
|
|
31
|
-
setNodeRef,
|
|
32
|
-
transform,
|
|
33
|
-
transition,
|
|
34
|
-
setActivatorNodeRef
|
|
35
|
-
} = useSortable({ id });
|
|
36
|
-
|
|
37
|
-
const allStyle = {
|
|
38
|
-
...style,
|
|
39
|
-
transform: CSS.Transform.toString(transform),
|
|
40
|
-
transition
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
const nodeRef = {
|
|
44
|
-
style: allStyle,
|
|
45
|
-
ref: setNodeRef,
|
|
46
|
-
...attributes
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
const actionNodeRef = {
|
|
50
|
-
...listeners,
|
|
51
|
-
ref: setActivatorNodeRef
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
return itemRenderer(nodeRef, actionNodeRef);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* DnD list forward ref
|
|
59
|
-
*/
|
|
60
|
-
export interface DnDListRef<D extends object> {
|
|
61
|
-
/**
|
|
62
|
-
* Add item
|
|
63
|
-
* @param item New item
|
|
64
|
-
*/
|
|
65
|
-
addItem(item: D): void;
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* Add items
|
|
69
|
-
* @param items items
|
|
70
|
-
*/
|
|
71
|
-
addItems(items: D[]): void;
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* Delete item
|
|
75
|
-
* @param index Item index
|
|
76
|
-
*/
|
|
77
|
-
deleteItem(index: number): void;
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* Edit item
|
|
81
|
-
* @param newItem New item
|
|
82
|
-
* @param index Index
|
|
83
|
-
*/
|
|
84
|
-
editItem(newItem: D, index: number): boolean;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* DnD sortable list properties
|
|
89
|
-
*/
|
|
90
|
-
export interface DnDListPros<D extends object, K extends DataTypes.Keys<D>> {
|
|
91
|
-
/**
|
|
92
|
-
* Get list item style callback
|
|
93
|
-
*/
|
|
94
|
-
getItemStyle: (index: number, isDragging: boolean) => CSSProperties;
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* Item renderer
|
|
98
|
-
*/
|
|
99
|
-
itemRenderer: (
|
|
100
|
-
item: D,
|
|
101
|
-
index: number,
|
|
102
|
-
nodeRef: React.ComponentProps<any>,
|
|
103
|
-
actionNodeRef: React.ComponentProps<any>
|
|
104
|
-
) => React.ReactElement;
|
|
105
|
-
|
|
106
|
-
/**
|
|
107
|
-
* List items
|
|
108
|
-
*/
|
|
109
|
-
items: D[];
|
|
110
|
-
|
|
111
|
-
/**
|
|
112
|
-
* Unique key field
|
|
113
|
-
*/
|
|
114
|
-
keyField: K;
|
|
115
|
-
|
|
116
|
-
/**
|
|
117
|
-
* Label field
|
|
118
|
-
*/
|
|
119
|
-
labelField: K;
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
* Methods ref
|
|
123
|
-
*/
|
|
124
|
-
mRef?: React.Ref<DnDListRef<D>>;
|
|
125
|
-
|
|
126
|
-
/**
|
|
127
|
-
* Data change handler
|
|
128
|
-
*/
|
|
129
|
-
onChange?: (items: D[]) => void;
|
|
130
|
-
|
|
131
|
-
/**
|
|
132
|
-
* Drag end handler
|
|
133
|
-
*/
|
|
134
|
-
onDragEnd?: (items: D[]) => void;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
/**
|
|
138
|
-
* DnD (Drag and Drop) sortable list
|
|
139
|
-
* @param props Props
|
|
140
|
-
* @returns Component
|
|
141
|
-
*/
|
|
142
|
-
export function DnDList<
|
|
143
|
-
D extends { id: UniqueIdentifier },
|
|
144
|
-
K extends DataTypes.Keys<D, UniqueIdentifier> = DataTypes.Keys<
|
|
145
|
-
D,
|
|
146
|
-
UniqueIdentifier
|
|
147
|
-
>
|
|
148
|
-
>(props: DnDListPros<D, K>) {
|
|
149
|
-
// Destruct
|
|
150
|
-
const {
|
|
151
|
-
getItemStyle,
|
|
152
|
-
keyField,
|
|
153
|
-
itemRenderer,
|
|
154
|
-
labelField,
|
|
155
|
-
mRef,
|
|
156
|
-
onChange,
|
|
157
|
-
onDragEnd
|
|
158
|
-
} = props;
|
|
159
|
-
|
|
160
|
-
// States
|
|
161
|
-
const [items, setItems] = React.useState<D[]>([]);
|
|
162
|
-
const [activeId, setActiveId] = React.useState<UniqueIdentifier>();
|
|
163
|
-
|
|
164
|
-
const changeItems = (newItems: D[]) => {
|
|
165
|
-
// Possible to alter items with the handler
|
|
166
|
-
if (onChange) onChange(newItems);
|
|
167
|
-
|
|
168
|
-
// Update state
|
|
169
|
-
setItems(newItems);
|
|
170
|
-
};
|
|
171
|
-
|
|
172
|
-
// Drag event handlers
|
|
173
|
-
function handleDragStart(event: DragStartEvent) {
|
|
174
|
-
const { active } = event;
|
|
175
|
-
setActiveId(active.id);
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
function handleDragEnd(event: DragEndEvent) {
|
|
179
|
-
const { active, over } = event;
|
|
180
|
-
|
|
181
|
-
if (over && active.id !== over.id) {
|
|
182
|
-
// Indices
|
|
183
|
-
const oldIndex = items.findIndex((item) => item.id === active.id);
|
|
184
|
-
const newIndex = items.findIndex((item) => item.id === over.id);
|
|
185
|
-
|
|
186
|
-
// Clone
|
|
187
|
-
const newItems = [...items];
|
|
188
|
-
|
|
189
|
-
// Removed item
|
|
190
|
-
const [removed] = newItems.splice(oldIndex, 1);
|
|
191
|
-
|
|
192
|
-
// Insert to the destination index
|
|
193
|
-
newItems.splice(newIndex, 0, removed);
|
|
194
|
-
|
|
195
|
-
changeItems(newItems);
|
|
196
|
-
|
|
197
|
-
// Drag end handler
|
|
198
|
-
if (onDragEnd) onDragEnd(newItems);
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
setActiveId(undefined);
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
// Methods
|
|
205
|
-
React.useImperativeHandle(
|
|
206
|
-
mRef,
|
|
207
|
-
() => {
|
|
208
|
-
return {
|
|
209
|
-
addItem(newItem: D) {
|
|
210
|
-
// Existence check
|
|
211
|
-
if (items.some((item) => item[labelField] === newItem[labelField])) {
|
|
212
|
-
return false;
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
// Clone
|
|
216
|
-
const newItems = [newItem, ...items];
|
|
217
|
-
|
|
218
|
-
// Update the state
|
|
219
|
-
changeItems(newItems);
|
|
220
|
-
|
|
221
|
-
return true;
|
|
222
|
-
},
|
|
223
|
-
|
|
224
|
-
addItems(inputItems: D[]) {
|
|
225
|
-
// Clone
|
|
226
|
-
const newItems = [...items];
|
|
227
|
-
|
|
228
|
-
// Insert items
|
|
229
|
-
inputItems.forEach((newItem) => {
|
|
230
|
-
// Existence check
|
|
231
|
-
if (
|
|
232
|
-
newItems.some((item) => item[labelField] === newItem[labelField])
|
|
233
|
-
) {
|
|
234
|
-
return;
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
newItems.push(newItem);
|
|
238
|
-
});
|
|
239
|
-
|
|
240
|
-
// Update the state
|
|
241
|
-
changeItems(newItems);
|
|
242
|
-
|
|
243
|
-
return newItems.length - items.length;
|
|
244
|
-
},
|
|
245
|
-
|
|
246
|
-
editItem(newItem: D, index: number) {
|
|
247
|
-
// Existence check
|
|
248
|
-
const newIndex = items.findIndex(
|
|
249
|
-
(item) => item[labelField] === newItem[labelField]
|
|
250
|
-
);
|
|
251
|
-
if (newIndex >= 0 && newIndex !== index) {
|
|
252
|
-
// Label field is the same with a different item
|
|
253
|
-
return false;
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
// Clone
|
|
257
|
-
const newItems = [...items];
|
|
258
|
-
|
|
259
|
-
// Remove the item
|
|
260
|
-
newItems.splice(index, 1, newItem);
|
|
261
|
-
|
|
262
|
-
// Update the state
|
|
263
|
-
changeItems(newItems);
|
|
264
|
-
|
|
265
|
-
return true;
|
|
266
|
-
},
|
|
267
|
-
|
|
268
|
-
deleteItem(index: number) {
|
|
269
|
-
// Clone
|
|
270
|
-
const newItems = [...items];
|
|
271
|
-
|
|
272
|
-
// Remove the item
|
|
273
|
-
newItems.splice(index, 1);
|
|
274
|
-
|
|
275
|
-
// Update the state
|
|
276
|
-
changeItems(newItems);
|
|
277
|
-
}
|
|
278
|
-
};
|
|
279
|
-
},
|
|
280
|
-
[items]
|
|
281
|
-
);
|
|
282
|
-
|
|
283
|
-
React.useEffect(() => {
|
|
284
|
-
setItems(props.items);
|
|
285
|
-
}, [props.items]);
|
|
286
|
-
|
|
287
|
-
return (
|
|
288
|
-
<DndContext onDragStart={handleDragStart} onDragEnd={handleDragEnd}>
|
|
289
|
-
<SortableContext items={items} strategy={verticalListSortingStrategy}>
|
|
290
|
-
{items.map((item, index) => {
|
|
291
|
-
const id = item[keyField] as unknown as UniqueIdentifier;
|
|
292
|
-
return (
|
|
293
|
-
<SortableItem
|
|
294
|
-
id={id}
|
|
295
|
-
key={id}
|
|
296
|
-
style={getItemStyle(index, id === activeId)}
|
|
297
|
-
itemRenderer={(nodeRef, actionNodeRef) =>
|
|
298
|
-
itemRenderer(item, index, nodeRef, actionNodeRef)
|
|
299
|
-
}
|
|
300
|
-
/>
|
|
301
|
-
);
|
|
302
|
-
})}
|
|
303
|
-
</SortableContext>
|
|
304
|
-
</DndContext>
|
|
305
|
-
);
|
|
306
|
-
}
|