@etsoo/react 1.5.60 → 1.5.63
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/index.d.ts +0 -1
- package/lib/index.js +0 -1
- package/lib/mu/OptionGroup.js +1 -1
- package/lib/mu/ScrollerListEx.js +1 -1
- package/lib/mu/TableEx.js +1 -1
- package/package.json +1 -2
- package/src/index.ts +0 -1
- package/src/mu/OptionGroup.tsx +1 -1
- package/src/mu/ScrollerListEx.tsx +1 -1
- package/src/mu/TableEx.tsx +1 -1
- package/lib/mu/DnDList.d.ts +0 -93
- package/lib/mu/DnDList.js +0 -128
- package/src/mu/DnDList.tsx +0 -338
package/lib/index.d.ts
CHANGED
|
@@ -42,7 +42,6 @@ export * from './mu/CustomFabProps';
|
|
|
42
42
|
export * from './mu/DataGridEx';
|
|
43
43
|
export * from './mu/DataGridRenderers';
|
|
44
44
|
export * from './mu/DialogButton';
|
|
45
|
-
export * from './mu/DnDList';
|
|
46
45
|
export * from './mu/DraggablePaperComponent';
|
|
47
46
|
export * from './mu/EmailInput';
|
|
48
47
|
export * from './mu/FabBox';
|
package/lib/index.js
CHANGED
|
@@ -45,7 +45,6 @@ export * from './mu/CustomFabProps';
|
|
|
45
45
|
export * from './mu/DataGridEx';
|
|
46
46
|
export * from './mu/DataGridRenderers';
|
|
47
47
|
export * from './mu/DialogButton';
|
|
48
|
-
export * from './mu/DnDList';
|
|
49
48
|
export * from './mu/DraggablePaperComponent';
|
|
50
49
|
export * from './mu/EmailInput';
|
|
51
50
|
export * from './mu/FabBox';
|
package/lib/mu/OptionGroup.js
CHANGED
|
@@ -12,7 +12,7 @@ export function OptionGroup(props) {
|
|
|
12
12
|
// Get option value
|
|
13
13
|
// D type should be the source id type
|
|
14
14
|
const getOptionValue = (option) => {
|
|
15
|
-
const value = DataTypes.
|
|
15
|
+
const value = DataTypes.getValue(option, idField);
|
|
16
16
|
if (value == null)
|
|
17
17
|
return null;
|
|
18
18
|
return value;
|
package/lib/mu/ScrollerListEx.js
CHANGED
|
@@ -112,7 +112,7 @@ export function ScrollerListEx(props) {
|
|
|
112
112
|
return selected;
|
|
113
113
|
};
|
|
114
114
|
// Destruct
|
|
115
|
-
const { alternatingColors = [undefined, undefined], className, idField = 'id', innerItemRenderer, itemSize, itemKey = (index, data) => { var _a; return (_a = DataTypes.
|
|
115
|
+
const { alternatingColors = [undefined, undefined], className, idField = 'id', innerItemRenderer, itemSize, itemKey = (index, data) => { var _a; return (_a = DataTypes.getValue(data, idField)) !== null && _a !== void 0 ? _a : index; }, itemRenderer = (itemProps) => {
|
|
116
116
|
const [itemHeight, space, margins] = calculateItemSize(itemProps.index);
|
|
117
117
|
return defaultItemRenderer({
|
|
118
118
|
itemHeight,
|
package/lib/mu/TableEx.js
CHANGED
|
@@ -229,7 +229,7 @@ export function TableEx(props) {
|
|
|
229
229
|
? rows[rowIndex]
|
|
230
230
|
: undefined;
|
|
231
231
|
// Row id field value
|
|
232
|
-
const rowId = (_a = DataTypes.
|
|
232
|
+
const rowId = (_a = DataTypes.getValue(row, idField)) !== null && _a !== void 0 ? _a : rowIndex;
|
|
233
233
|
// Selected or not
|
|
234
234
|
const isItemSelected = selectable
|
|
235
235
|
? selectedItems.some((item) => item[idField] === rowId)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@etsoo/react",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.63",
|
|
4
4
|
"description": "TypeScript ReactJs framework",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"types": "lib/index.d.ts",
|
|
@@ -46,7 +46,6 @@
|
|
|
46
46
|
},
|
|
47
47
|
"homepage": "https://github.com/ETSOO/AppReact#readme",
|
|
48
48
|
"dependencies": {
|
|
49
|
-
"@dnd-kit/core": "^6.0.5",
|
|
50
49
|
"@emotion/css": "^11.10.0",
|
|
51
50
|
"@emotion/react": "^11.10.0",
|
|
52
51
|
"@emotion/styled": "^11.10.0",
|
package/src/index.ts
CHANGED
|
@@ -49,7 +49,6 @@ export * from './mu/CustomFabProps';
|
|
|
49
49
|
export * from './mu/DataGridEx';
|
|
50
50
|
export * from './mu/DataGridRenderers';
|
|
51
51
|
export * from './mu/DialogButton';
|
|
52
|
-
export * from './mu/DnDList';
|
|
53
52
|
export * from './mu/DraggablePaperComponent';
|
|
54
53
|
export * from './mu/EmailInput';
|
|
55
54
|
export * from './mu/FabBox';
|
package/src/mu/OptionGroup.tsx
CHANGED
|
@@ -104,7 +104,7 @@ export function OptionGroup<
|
|
|
104
104
|
// Get option value
|
|
105
105
|
// D type should be the source id type
|
|
106
106
|
const getOptionValue = (option: T): D | null => {
|
|
107
|
-
const value = DataTypes.
|
|
107
|
+
const value = DataTypes.getValue(option, idField);
|
|
108
108
|
if (value == null) return null;
|
|
109
109
|
return value as D;
|
|
110
110
|
};
|
|
@@ -299,7 +299,7 @@ export function ScrollerListEx<T extends Record<string, unknown>>(
|
|
|
299
299
|
innerItemRenderer,
|
|
300
300
|
itemSize,
|
|
301
301
|
itemKey = (index: number, data: T) =>
|
|
302
|
-
DataTypes.
|
|
302
|
+
DataTypes.getValue(data, idField) ?? index,
|
|
303
303
|
itemRenderer = (itemProps) => {
|
|
304
304
|
const [itemHeight, space, margins] = calculateItemSize(
|
|
305
305
|
itemProps.index
|
package/src/mu/TableEx.tsx
CHANGED
|
@@ -441,7 +441,7 @@ export function TableEx<T extends Record<string, unknown>>(
|
|
|
441
441
|
|
|
442
442
|
// Row id field value
|
|
443
443
|
const rowId =
|
|
444
|
-
DataTypes.
|
|
444
|
+
DataTypes.getValue(row, idField) ?? rowIndex;
|
|
445
445
|
|
|
446
446
|
// Selected or not
|
|
447
447
|
const isItemSelected = selectable
|
package/lib/mu/DnDList.d.ts
DELETED
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
import { UniqueIdentifier } from '@dnd-kit/core';
|
|
2
|
-
import React, { CSSProperties } from 'react';
|
|
3
|
-
/**
|
|
4
|
-
* DnD list item props
|
|
5
|
-
*/
|
|
6
|
-
export interface DnDItemProps<D extends {}> {
|
|
7
|
-
/**
|
|
8
|
-
* Unique id
|
|
9
|
-
*/
|
|
10
|
-
id: UniqueIdentifier;
|
|
11
|
-
/**
|
|
12
|
-
* Children
|
|
13
|
-
*/
|
|
14
|
-
children: React.ReactNode;
|
|
15
|
-
/**
|
|
16
|
-
* Item data
|
|
17
|
-
*/
|
|
18
|
-
data?: D;
|
|
19
|
-
/**
|
|
20
|
-
* Disabled or not
|
|
21
|
-
*/
|
|
22
|
-
disabled?: boolean;
|
|
23
|
-
/**
|
|
24
|
-
* Inline style
|
|
25
|
-
*/
|
|
26
|
-
style?: CSSProperties;
|
|
27
|
-
}
|
|
28
|
-
/**
|
|
29
|
-
* DnD list item
|
|
30
|
-
* @param props Props
|
|
31
|
-
*/
|
|
32
|
-
export declare function DnDItem<D extends {}>(props: DnDItemProps<D>): JSX.Element;
|
|
33
|
-
/**
|
|
34
|
-
* DnD list props
|
|
35
|
-
*/
|
|
36
|
-
export interface DnDListProps<D extends {}, E extends React.ElementType> {
|
|
37
|
-
/**
|
|
38
|
-
* Item renderer
|
|
39
|
-
*/
|
|
40
|
-
children: (item: D, index: number, deleteItem: (index: number) => void, editItem: (newItem: D, index: number) => boolean) => React.ReactNode;
|
|
41
|
-
/**
|
|
42
|
-
* List container component
|
|
43
|
-
* https://javascript.plainenglish.io/building-a-polymorphic-component-in-react-and-typescript-d9f236950af4
|
|
44
|
-
*/
|
|
45
|
-
Component?: E;
|
|
46
|
-
/**
|
|
47
|
-
* List container props
|
|
48
|
-
*/
|
|
49
|
-
componentProps?: React.ComponentProps<E>;
|
|
50
|
-
/**
|
|
51
|
-
* List disabled
|
|
52
|
-
*/
|
|
53
|
-
disabled?: boolean;
|
|
54
|
-
/**
|
|
55
|
-
* Get list item style callback
|
|
56
|
-
*/
|
|
57
|
-
getItemStyle?: (isDragging: boolean, index: number) => CSSProperties;
|
|
58
|
-
/**
|
|
59
|
-
* Get list style callback
|
|
60
|
-
*/
|
|
61
|
-
getListStyle?: (isDraggingOver: boolean) => CSSProperties;
|
|
62
|
-
/**
|
|
63
|
-
* Label field
|
|
64
|
-
*/
|
|
65
|
-
labelField: string & keyof D;
|
|
66
|
-
/**
|
|
67
|
-
* Load data
|
|
68
|
-
*/
|
|
69
|
-
loadData: (name: string) => PromiseLike<D[]>;
|
|
70
|
-
/**
|
|
71
|
-
* Data change handler
|
|
72
|
-
*/
|
|
73
|
-
onChange?: (items: D[]) => void;
|
|
74
|
-
/**
|
|
75
|
-
* Drag end handler
|
|
76
|
-
*/
|
|
77
|
-
onDragEnd?: (items: D[]) => void;
|
|
78
|
-
/**
|
|
79
|
-
* Top and bottom sides renderer
|
|
80
|
-
*/
|
|
81
|
-
sideRenderer?: (top: boolean, addItem: (item: D) => boolean, addItems: (items: D[]) => number, reloadItems: () => void) => React.ReactNode;
|
|
82
|
-
/**
|
|
83
|
-
* Name for hidden form input
|
|
84
|
-
*/
|
|
85
|
-
name: string;
|
|
86
|
-
}
|
|
87
|
-
/**
|
|
88
|
-
* Drag and drop list
|
|
89
|
-
* https://github.com/atlassian/react-beautiful-dnd
|
|
90
|
-
* @param props Props
|
|
91
|
-
* @returns Component
|
|
92
|
-
*/
|
|
93
|
-
export declare function DnDList<D extends {}, E extends React.ElementType = React.ElementType>(props: DnDListProps<D, E>): JSX.Element;
|
package/lib/mu/DnDList.js
DELETED
|
@@ -1,128 +0,0 @@
|
|
|
1
|
-
import { DndContext, DragOverlay, useDraggable } from '@dnd-kit/core';
|
|
2
|
-
import { DataTypes } from '@etsoo/shared';
|
|
3
|
-
import React from 'react';
|
|
4
|
-
/**
|
|
5
|
-
* DnD list item
|
|
6
|
-
* @param props Props
|
|
7
|
-
*/
|
|
8
|
-
export function DnDItem(props) {
|
|
9
|
-
const { children, style, ...rest } = props;
|
|
10
|
-
const { attributes, listeners, setNodeRef } = useDraggable(rest);
|
|
11
|
-
return (React.createElement("div", { style: style, ref: setNodeRef, ...listeners, ...attributes }, children));
|
|
12
|
-
}
|
|
13
|
-
/**
|
|
14
|
-
* Drag and drop list
|
|
15
|
-
* https://github.com/atlassian/react-beautiful-dnd
|
|
16
|
-
* @param props Props
|
|
17
|
-
* @returns Component
|
|
18
|
-
*/
|
|
19
|
-
export function DnDList(props) {
|
|
20
|
-
// Destruct
|
|
21
|
-
const { children, Component = 'div', componentProps, disabled = false, getItemStyle = (_isDragging) => ({}), getListStyle = () => undefined, labelField, loadData, name, onChange, onDragEnd, sideRenderer } = props;
|
|
22
|
-
// State
|
|
23
|
-
const [items, setItems] = React.useState([]);
|
|
24
|
-
const changeItems = (items) => {
|
|
25
|
-
// Possible to alter items with the handler
|
|
26
|
-
if (onChange)
|
|
27
|
-
onChange(items);
|
|
28
|
-
// Update state
|
|
29
|
-
setItems(items);
|
|
30
|
-
};
|
|
31
|
-
// Drag end handler
|
|
32
|
-
const onDragEndLocal = (result) => {
|
|
33
|
-
// Clone
|
|
34
|
-
const newItems = [...items];
|
|
35
|
-
console.log(result);
|
|
36
|
-
// Removed item
|
|
37
|
-
// const [removed] = newItems.splice(result.source.index, 1);
|
|
38
|
-
// Insert to the destination index
|
|
39
|
-
// newItems.splice(result.destination.index, 0, removed);
|
|
40
|
-
// Update the state
|
|
41
|
-
changeItems(newItems);
|
|
42
|
-
// Drag end handler
|
|
43
|
-
if (onDragEnd)
|
|
44
|
-
onDragEnd(newItems);
|
|
45
|
-
};
|
|
46
|
-
// Add item
|
|
47
|
-
const addItem = (newItem) => {
|
|
48
|
-
// Existence check
|
|
49
|
-
if (items.some((item) => item[labelField] === newItem[labelField])) {
|
|
50
|
-
return false;
|
|
51
|
-
}
|
|
52
|
-
// Clone
|
|
53
|
-
const newItems = [newItem, ...items];
|
|
54
|
-
// Update the state
|
|
55
|
-
changeItems(newItems);
|
|
56
|
-
return true;
|
|
57
|
-
};
|
|
58
|
-
// Edit item
|
|
59
|
-
const editItem = (newItem, index) => {
|
|
60
|
-
// Existence check
|
|
61
|
-
const newIndex = items.findIndex((item) => item[labelField] === newItem[labelField]);
|
|
62
|
-
if (newIndex >= 0 && newIndex != index) {
|
|
63
|
-
// Label field is the same with a different item
|
|
64
|
-
return false;
|
|
65
|
-
}
|
|
66
|
-
// Clone
|
|
67
|
-
const newItems = [...items];
|
|
68
|
-
// Remove the item
|
|
69
|
-
newItems.splice(index, 1, newItem);
|
|
70
|
-
// Update the state
|
|
71
|
-
changeItems(newItems);
|
|
72
|
-
return true;
|
|
73
|
-
};
|
|
74
|
-
// Add items
|
|
75
|
-
const addItems = (inputItems) => {
|
|
76
|
-
// Clone
|
|
77
|
-
const newItems = [...items];
|
|
78
|
-
// Insert items
|
|
79
|
-
inputItems.forEach((newItem) => {
|
|
80
|
-
// Existence check
|
|
81
|
-
if (newItems.some((item) => item[labelField] == newItem[labelField])) {
|
|
82
|
-
return;
|
|
83
|
-
}
|
|
84
|
-
newItems.push(newItem);
|
|
85
|
-
});
|
|
86
|
-
// Update the state
|
|
87
|
-
changeItems(newItems);
|
|
88
|
-
return newItems.length - items.length;
|
|
89
|
-
};
|
|
90
|
-
// Delete item
|
|
91
|
-
const deleteItem = (index) => {
|
|
92
|
-
// Clone
|
|
93
|
-
const newItems = [...items];
|
|
94
|
-
// Remove the item
|
|
95
|
-
newItems.splice(index, 1);
|
|
96
|
-
// Update the state
|
|
97
|
-
changeItems(newItems);
|
|
98
|
-
};
|
|
99
|
-
// Reload items
|
|
100
|
-
const reloadItems = () => {
|
|
101
|
-
// Load data
|
|
102
|
-
loadData(name).then((items) => setItems(items));
|
|
103
|
-
};
|
|
104
|
-
React.useEffect(() => {
|
|
105
|
-
// Load data
|
|
106
|
-
reloadItems();
|
|
107
|
-
}, [name]);
|
|
108
|
-
// Layout
|
|
109
|
-
return (React.createElement(React.Fragment, null,
|
|
110
|
-
sideRenderer && sideRenderer(true, addItem, addItems, reloadItems),
|
|
111
|
-
React.createElement(Component, { ...componentProps }, disabled ? (React.createElement("div", { style: getListStyle(false) }, items.map((item, index) => {
|
|
112
|
-
// Id
|
|
113
|
-
const id = DataTypes.convert(item[labelField], 'string');
|
|
114
|
-
if (id == null)
|
|
115
|
-
return;
|
|
116
|
-
return (React.createElement("div", { key: id, style: getItemStyle(false, index) }, children(item, index, deleteItem, editItem)));
|
|
117
|
-
}))) : (React.createElement(DndContext, { onDragEnd: onDragEndLocal },
|
|
118
|
-
items.map((item, index) => {
|
|
119
|
-
// Id
|
|
120
|
-
const id = DataTypes.convert(item[labelField], 'string');
|
|
121
|
-
if (id == null)
|
|
122
|
-
return;
|
|
123
|
-
return (React.createElement(DnDItem, { id: id, key: id, data: item, "data-index": index, style: getItemStyle(false, index) }, children(item, index, deleteItem, editItem)));
|
|
124
|
-
}),
|
|
125
|
-
React.createElement(DragOverlay, null)))),
|
|
126
|
-
sideRenderer &&
|
|
127
|
-
sideRenderer(false, addItem, addItems, reloadItems)));
|
|
128
|
-
}
|
package/src/mu/DnDList.tsx
DELETED
|
@@ -1,338 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
DndContext,
|
|
3
|
-
DragEndEvent,
|
|
4
|
-
DragOverlay,
|
|
5
|
-
UniqueIdentifier,
|
|
6
|
-
useDraggable
|
|
7
|
-
} from '@dnd-kit/core';
|
|
8
|
-
import { DataTypes } from '@etsoo/shared';
|
|
9
|
-
import React, { CSSProperties } from 'react';
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* DnD list item props
|
|
13
|
-
*/
|
|
14
|
-
export interface DnDItemProps<D extends {}> {
|
|
15
|
-
/**
|
|
16
|
-
* Unique id
|
|
17
|
-
*/
|
|
18
|
-
id: UniqueIdentifier;
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Children
|
|
22
|
-
*/
|
|
23
|
-
children: React.ReactNode;
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Item data
|
|
27
|
-
*/
|
|
28
|
-
data?: D;
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Disabled or not
|
|
32
|
-
*/
|
|
33
|
-
disabled?: boolean;
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Inline style
|
|
37
|
-
*/
|
|
38
|
-
style?: CSSProperties;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* DnD list item
|
|
43
|
-
* @param props Props
|
|
44
|
-
*/
|
|
45
|
-
export function DnDItem<D extends {}>(props: DnDItemProps<D>) {
|
|
46
|
-
const { children, style, ...rest } = props;
|
|
47
|
-
const { attributes, listeners, setNodeRef } = useDraggable(rest);
|
|
48
|
-
return (
|
|
49
|
-
<div style={style} ref={setNodeRef} {...listeners} {...attributes}>
|
|
50
|
-
{children}
|
|
51
|
-
</div>
|
|
52
|
-
);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* DnD list props
|
|
57
|
-
*/
|
|
58
|
-
export interface DnDListProps<D extends {}, E extends React.ElementType> {
|
|
59
|
-
/**
|
|
60
|
-
* Item renderer
|
|
61
|
-
*/
|
|
62
|
-
children: (
|
|
63
|
-
item: D,
|
|
64
|
-
index: number,
|
|
65
|
-
deleteItem: (index: number) => void,
|
|
66
|
-
editItem: (newItem: D, index: number) => boolean
|
|
67
|
-
) => React.ReactNode;
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* List container component
|
|
71
|
-
* https://javascript.plainenglish.io/building-a-polymorphic-component-in-react-and-typescript-d9f236950af4
|
|
72
|
-
*/
|
|
73
|
-
Component?: E;
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* List container props
|
|
77
|
-
*/
|
|
78
|
-
componentProps?: React.ComponentProps<E>;
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* List disabled
|
|
82
|
-
*/
|
|
83
|
-
disabled?: boolean;
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* Get list item style callback
|
|
87
|
-
*/
|
|
88
|
-
getItemStyle?: (isDragging: boolean, index: number) => CSSProperties;
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* Get list style callback
|
|
92
|
-
*/
|
|
93
|
-
getListStyle?: (isDraggingOver: boolean) => CSSProperties;
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
* Label field
|
|
97
|
-
*/
|
|
98
|
-
labelField: string & keyof D;
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* Load data
|
|
102
|
-
*/
|
|
103
|
-
loadData: (name: string) => PromiseLike<D[]>;
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* Data change handler
|
|
107
|
-
*/
|
|
108
|
-
onChange?: (items: D[]) => void;
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
* Drag end handler
|
|
112
|
-
*/
|
|
113
|
-
onDragEnd?: (items: D[]) => void;
|
|
114
|
-
|
|
115
|
-
/**
|
|
116
|
-
* Top and bottom sides renderer
|
|
117
|
-
*/
|
|
118
|
-
sideRenderer?: (
|
|
119
|
-
top: boolean,
|
|
120
|
-
addItem: (item: D) => boolean,
|
|
121
|
-
addItems: (items: D[]) => number,
|
|
122
|
-
reloadItems: () => void
|
|
123
|
-
) => React.ReactNode;
|
|
124
|
-
|
|
125
|
-
/**
|
|
126
|
-
* Name for hidden form input
|
|
127
|
-
*/
|
|
128
|
-
name: string;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
/**
|
|
132
|
-
* Drag and drop list
|
|
133
|
-
* https://github.com/atlassian/react-beautiful-dnd
|
|
134
|
-
* @param props Props
|
|
135
|
-
* @returns Component
|
|
136
|
-
*/
|
|
137
|
-
export function DnDList<
|
|
138
|
-
D extends {},
|
|
139
|
-
E extends React.ElementType = React.ElementType
|
|
140
|
-
>(props: DnDListProps<D, E>) {
|
|
141
|
-
// Destruct
|
|
142
|
-
const {
|
|
143
|
-
children,
|
|
144
|
-
Component = 'div',
|
|
145
|
-
componentProps,
|
|
146
|
-
disabled = false,
|
|
147
|
-
getItemStyle = (_isDragging) => ({}),
|
|
148
|
-
getListStyle = () => undefined,
|
|
149
|
-
labelField,
|
|
150
|
-
loadData,
|
|
151
|
-
name,
|
|
152
|
-
onChange,
|
|
153
|
-
onDragEnd,
|
|
154
|
-
sideRenderer
|
|
155
|
-
} = props;
|
|
156
|
-
|
|
157
|
-
// State
|
|
158
|
-
const [items, setItems] = React.useState<D[]>([]);
|
|
159
|
-
|
|
160
|
-
const changeItems = (items: D[]) => {
|
|
161
|
-
// Possible to alter items with the handler
|
|
162
|
-
if (onChange) onChange(items);
|
|
163
|
-
|
|
164
|
-
// Update state
|
|
165
|
-
setItems(items);
|
|
166
|
-
};
|
|
167
|
-
|
|
168
|
-
// Drag end handler
|
|
169
|
-
const onDragEndLocal = (result: DragEndEvent) => {
|
|
170
|
-
// Clone
|
|
171
|
-
const newItems = [...items];
|
|
172
|
-
|
|
173
|
-
console.log(result);
|
|
174
|
-
|
|
175
|
-
// Removed item
|
|
176
|
-
// const [removed] = newItems.splice(result.source.index, 1);
|
|
177
|
-
|
|
178
|
-
// Insert to the destination index
|
|
179
|
-
// newItems.splice(result.destination.index, 0, removed);
|
|
180
|
-
|
|
181
|
-
// Update the state
|
|
182
|
-
changeItems(newItems);
|
|
183
|
-
|
|
184
|
-
// Drag end handler
|
|
185
|
-
if (onDragEnd) onDragEnd(newItems);
|
|
186
|
-
};
|
|
187
|
-
|
|
188
|
-
// Add item
|
|
189
|
-
const addItem = (newItem: D) => {
|
|
190
|
-
// Existence check
|
|
191
|
-
if (items.some((item) => item[labelField] === newItem[labelField])) {
|
|
192
|
-
return false;
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
// Clone
|
|
196
|
-
const newItems = [newItem, ...items];
|
|
197
|
-
|
|
198
|
-
// Update the state
|
|
199
|
-
changeItems(newItems);
|
|
200
|
-
|
|
201
|
-
return true;
|
|
202
|
-
};
|
|
203
|
-
|
|
204
|
-
// Edit item
|
|
205
|
-
const editItem = (newItem: D, index: number) => {
|
|
206
|
-
// Existence check
|
|
207
|
-
const newIndex = items.findIndex(
|
|
208
|
-
(item) => item[labelField] === newItem[labelField]
|
|
209
|
-
);
|
|
210
|
-
if (newIndex >= 0 && newIndex != index) {
|
|
211
|
-
// Label field is the same with a different item
|
|
212
|
-
return false;
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
// Clone
|
|
216
|
-
const newItems = [...items];
|
|
217
|
-
|
|
218
|
-
// Remove the item
|
|
219
|
-
newItems.splice(index, 1, newItem);
|
|
220
|
-
|
|
221
|
-
// Update the state
|
|
222
|
-
changeItems(newItems);
|
|
223
|
-
|
|
224
|
-
return true;
|
|
225
|
-
};
|
|
226
|
-
|
|
227
|
-
// Add items
|
|
228
|
-
const addItems = (inputItems: D[]) => {
|
|
229
|
-
// Clone
|
|
230
|
-
const newItems = [...items];
|
|
231
|
-
|
|
232
|
-
// Insert items
|
|
233
|
-
inputItems.forEach((newItem) => {
|
|
234
|
-
// Existence check
|
|
235
|
-
if (
|
|
236
|
-
newItems.some((item) => item[labelField] == newItem[labelField])
|
|
237
|
-
) {
|
|
238
|
-
return;
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
newItems.push(newItem);
|
|
242
|
-
});
|
|
243
|
-
|
|
244
|
-
// Update the state
|
|
245
|
-
changeItems(newItems);
|
|
246
|
-
|
|
247
|
-
return newItems.length - items.length;
|
|
248
|
-
};
|
|
249
|
-
|
|
250
|
-
// Delete item
|
|
251
|
-
const deleteItem = (index: number) => {
|
|
252
|
-
// Clone
|
|
253
|
-
const newItems = [...items];
|
|
254
|
-
|
|
255
|
-
// Remove the item
|
|
256
|
-
newItems.splice(index, 1);
|
|
257
|
-
|
|
258
|
-
// Update the state
|
|
259
|
-
changeItems(newItems);
|
|
260
|
-
};
|
|
261
|
-
|
|
262
|
-
// Reload items
|
|
263
|
-
const reloadItems = () => {
|
|
264
|
-
// Load data
|
|
265
|
-
loadData(name).then((items) => setItems(items));
|
|
266
|
-
};
|
|
267
|
-
|
|
268
|
-
React.useEffect(() => {
|
|
269
|
-
// Load data
|
|
270
|
-
reloadItems();
|
|
271
|
-
}, [name]);
|
|
272
|
-
|
|
273
|
-
// Layout
|
|
274
|
-
return (
|
|
275
|
-
<React.Fragment>
|
|
276
|
-
{sideRenderer && sideRenderer(true, addItem, addItems, reloadItems)}
|
|
277
|
-
<Component {...componentProps}>
|
|
278
|
-
{disabled ? (
|
|
279
|
-
<div style={getListStyle(false)}>
|
|
280
|
-
{items.map((item, index) => {
|
|
281
|
-
// Id
|
|
282
|
-
const id = DataTypes.convert(
|
|
283
|
-
item[labelField],
|
|
284
|
-
'string'
|
|
285
|
-
);
|
|
286
|
-
if (id == null) return;
|
|
287
|
-
|
|
288
|
-
return (
|
|
289
|
-
<div
|
|
290
|
-
key={id}
|
|
291
|
-
style={getItemStyle(false, index)}
|
|
292
|
-
>
|
|
293
|
-
{children(
|
|
294
|
-
item,
|
|
295
|
-
index,
|
|
296
|
-
deleteItem,
|
|
297
|
-
editItem
|
|
298
|
-
)}
|
|
299
|
-
</div>
|
|
300
|
-
);
|
|
301
|
-
})}
|
|
302
|
-
</div>
|
|
303
|
-
) : (
|
|
304
|
-
<DndContext onDragEnd={onDragEndLocal}>
|
|
305
|
-
{items.map((item, index) => {
|
|
306
|
-
// Id
|
|
307
|
-
const id = DataTypes.convert(
|
|
308
|
-
item[labelField],
|
|
309
|
-
'string'
|
|
310
|
-
);
|
|
311
|
-
if (id == null) return;
|
|
312
|
-
|
|
313
|
-
return (
|
|
314
|
-
<DnDItem<D>
|
|
315
|
-
id={id}
|
|
316
|
-
key={id}
|
|
317
|
-
data={item}
|
|
318
|
-
data-index={index}
|
|
319
|
-
style={getItemStyle(false, index)}
|
|
320
|
-
>
|
|
321
|
-
{children(
|
|
322
|
-
item,
|
|
323
|
-
index,
|
|
324
|
-
deleteItem,
|
|
325
|
-
editItem
|
|
326
|
-
)}
|
|
327
|
-
</DnDItem>
|
|
328
|
-
);
|
|
329
|
-
})}
|
|
330
|
-
<DragOverlay></DragOverlay>
|
|
331
|
-
</DndContext>
|
|
332
|
-
)}
|
|
333
|
-
</Component>
|
|
334
|
-
{sideRenderer &&
|
|
335
|
-
sideRenderer(false, addItem, addItems, reloadItems)}
|
|
336
|
-
</React.Fragment>
|
|
337
|
-
);
|
|
338
|
-
}
|