@etsoo/react 1.4.8 → 1.4.12
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/mu/DnDList.d.ts +5 -1
- package/lib/mu/DnDList.js +18 -7
- package/lib/mu/TooltipClick.js +1 -1
- package/package.json +3 -3
- package/src/mu/DnDList.tsx +28 -7
- package/src/mu/TooltipClick.tsx +3 -0
package/lib/mu/DnDList.d.ts
CHANGED
|
@@ -36,10 +36,14 @@ export interface DnDListProps<D extends {}, E extends React.ElementType> {
|
|
|
36
36
|
* Data change handler
|
|
37
37
|
*/
|
|
38
38
|
onChange?: (items: D[]) => void;
|
|
39
|
+
/**
|
|
40
|
+
* Drag end handler
|
|
41
|
+
*/
|
|
42
|
+
onDragEnd?: (items: D[]) => void;
|
|
39
43
|
/**
|
|
40
44
|
* Top and bottom sides renderer
|
|
41
45
|
*/
|
|
42
|
-
sideRenderer?: (top: boolean, addItem: (item: D) => boolean, addItems: (items: D[]) => number) => React.ReactNode;
|
|
46
|
+
sideRenderer?: (top: boolean, addItem: (item: D) => boolean, addItems: (items: D[]) => number, reloadItems: () => void) => React.ReactNode;
|
|
43
47
|
/**
|
|
44
48
|
* Name for hidden form input
|
|
45
49
|
*/
|
package/lib/mu/DnDList.js
CHANGED
|
@@ -9,7 +9,7 @@ import { DragDropContext, Draggable, Droppable } from 'react-beautiful-dnd';
|
|
|
9
9
|
*/
|
|
10
10
|
export function DnDList(props) {
|
|
11
11
|
// Destruct
|
|
12
|
-
const { children, Component = 'div', componentProps, getItemStyle = (_isDragging) => ({}), getListStyle = () => undefined, labelField, loadData, name, onChange, sideRenderer } = props;
|
|
12
|
+
const { children, Component = 'div', componentProps, getItemStyle = (_isDragging) => ({}), getListStyle = () => undefined, labelField, loadData, name, onChange, onDragEnd, sideRenderer } = props;
|
|
13
13
|
// State
|
|
14
14
|
const [items, setItems] = React.useState([]);
|
|
15
15
|
const changeItems = (items) => {
|
|
@@ -20,7 +20,7 @@ export function DnDList(props) {
|
|
|
20
20
|
setItems(items);
|
|
21
21
|
};
|
|
22
22
|
// Drag end handler
|
|
23
|
-
const
|
|
23
|
+
const onDragEndLocal = (result) => {
|
|
24
24
|
// Dropped outside the list
|
|
25
25
|
if (!result.destination) {
|
|
26
26
|
return;
|
|
@@ -33,6 +33,9 @@ export function DnDList(props) {
|
|
|
33
33
|
newItems.splice(result.destination.index, 0, removed);
|
|
34
34
|
// Update the state
|
|
35
35
|
changeItems(newItems);
|
|
36
|
+
// Drag end handler
|
|
37
|
+
if (onDragEnd)
|
|
38
|
+
onDragEnd(newItems);
|
|
36
39
|
};
|
|
37
40
|
// Add item
|
|
38
41
|
const addItem = (newItem) => {
|
|
@@ -49,7 +52,9 @@ export function DnDList(props) {
|
|
|
49
52
|
// Edit item
|
|
50
53
|
const editItem = (newItem, index) => {
|
|
51
54
|
// Existence check
|
|
52
|
-
|
|
55
|
+
const newIndex = items.findIndex((item) => item[labelField] === newItem[labelField]);
|
|
56
|
+
if (newIndex >= 0 && newIndex != index) {
|
|
57
|
+
// Label field is the same with a different item
|
|
53
58
|
return false;
|
|
54
59
|
}
|
|
55
60
|
// Clone
|
|
@@ -85,15 +90,20 @@ export function DnDList(props) {
|
|
|
85
90
|
// Update the state
|
|
86
91
|
changeItems(newItems);
|
|
87
92
|
};
|
|
88
|
-
|
|
93
|
+
// Reload items
|
|
94
|
+
const reloadItems = () => {
|
|
89
95
|
// Load data
|
|
90
96
|
loadData(name).then((items) => setItems(items));
|
|
97
|
+
};
|
|
98
|
+
React.useEffect(() => {
|
|
99
|
+
// Load data
|
|
100
|
+
reloadItems();
|
|
91
101
|
}, [name]);
|
|
92
102
|
// Layout
|
|
93
103
|
return (React.createElement(React.Fragment, null,
|
|
94
|
-
sideRenderer && sideRenderer(true, addItem, addItems),
|
|
104
|
+
sideRenderer && sideRenderer(true, addItem, addItems, reloadItems),
|
|
95
105
|
React.createElement(Component, { ...componentProps },
|
|
96
|
-
React.createElement(DragDropContext, { onDragEnd:
|
|
106
|
+
React.createElement(DragDropContext, { onDragEnd: onDragEndLocal },
|
|
97
107
|
React.createElement(Droppable, { droppableId: name }, (provided, snapshot) => (React.createElement("div", { ...provided.droppableProps, ref: provided.innerRef, style: getListStyle(snapshot.isDraggingOver) },
|
|
98
108
|
items.map((item, index) => {
|
|
99
109
|
// Id
|
|
@@ -108,5 +118,6 @@ export function DnDList(props) {
|
|
|
108
118
|
} }, children(item, index, deleteItem, editItem)))));
|
|
109
119
|
}),
|
|
110
120
|
provided.placeholder))))),
|
|
111
|
-
sideRenderer &&
|
|
121
|
+
sideRenderer &&
|
|
122
|
+
sideRenderer(false, addItem, addItems, reloadItems)));
|
|
112
123
|
}
|
package/lib/mu/TooltipClick.js
CHANGED
|
@@ -42,5 +42,5 @@ export function TooltipClick(props) {
|
|
|
42
42
|
setOpen(false);
|
|
43
43
|
if (onClose)
|
|
44
44
|
onClose(event);
|
|
45
|
-
}, title: localTitle, open: open, disableFocusListener: true, disableTouchListener: true, disableHoverListener: disableHoverListener, ...rest }, children(openTooltip))));
|
|
45
|
+
}, title: localTitle, open: open, disableFocusListener: true, disableTouchListener: true, disableHoverListener: disableHoverListener, onMouseOver: disableHoverListener ? undefined : () => setOpen(true), ...rest }, children(openTooltip))));
|
|
46
46
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@etsoo/react",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.12",
|
|
4
4
|
"description": "TypeScript ReactJs framework",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"types": "lib/index.d.ts",
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
"@emotion/react": "^11.7.1",
|
|
51
51
|
"@emotion/style": "^0.8.0",
|
|
52
52
|
"@emotion/styled": "^11.6.0",
|
|
53
|
-
"@etsoo/appscript": "^1.2.
|
|
53
|
+
"@etsoo/appscript": "^1.2.20",
|
|
54
54
|
"@etsoo/notificationbase": "^1.1.0",
|
|
55
55
|
"@etsoo/shared": "^1.1.0",
|
|
56
56
|
"@mui/icons-material": "^5.2.5",
|
|
@@ -89,7 +89,7 @@
|
|
|
89
89
|
"eslint-config-airbnb-base": "^15.0.0",
|
|
90
90
|
"eslint-plugin-import": "^2.25.4",
|
|
91
91
|
"eslint-plugin-react": "^7.28.0",
|
|
92
|
-
"jest": "^27.4.
|
|
92
|
+
"jest": "^27.4.7",
|
|
93
93
|
"react-test-renderer": "^17.0.2",
|
|
94
94
|
"ts-jest": "^27.1.2",
|
|
95
95
|
"typescript": "^4.5.4"
|
package/src/mu/DnDList.tsx
CHANGED
|
@@ -57,13 +57,19 @@ export interface DnDListProps<D extends {}, E extends React.ElementType> {
|
|
|
57
57
|
*/
|
|
58
58
|
onChange?: (items: D[]) => void;
|
|
59
59
|
|
|
60
|
+
/**
|
|
61
|
+
* Drag end handler
|
|
62
|
+
*/
|
|
63
|
+
onDragEnd?: (items: D[]) => void;
|
|
64
|
+
|
|
60
65
|
/**
|
|
61
66
|
* Top and bottom sides renderer
|
|
62
67
|
*/
|
|
63
68
|
sideRenderer?: (
|
|
64
69
|
top: boolean,
|
|
65
70
|
addItem: (item: D) => boolean,
|
|
66
|
-
addItems: (items: D[]) => number
|
|
71
|
+
addItems: (items: D[]) => number,
|
|
72
|
+
reloadItems: () => void
|
|
67
73
|
) => React.ReactNode;
|
|
68
74
|
|
|
69
75
|
/**
|
|
@@ -93,6 +99,7 @@ export function DnDList<
|
|
|
93
99
|
loadData,
|
|
94
100
|
name,
|
|
95
101
|
onChange,
|
|
102
|
+
onDragEnd,
|
|
96
103
|
sideRenderer
|
|
97
104
|
} = props;
|
|
98
105
|
|
|
@@ -108,7 +115,7 @@ export function DnDList<
|
|
|
108
115
|
};
|
|
109
116
|
|
|
110
117
|
// Drag end handler
|
|
111
|
-
const
|
|
118
|
+
const onDragEndLocal = (result: DropResult) => {
|
|
112
119
|
// Dropped outside the list
|
|
113
120
|
if (!result.destination) {
|
|
114
121
|
return;
|
|
@@ -125,6 +132,9 @@ export function DnDList<
|
|
|
125
132
|
|
|
126
133
|
// Update the state
|
|
127
134
|
changeItems(newItems);
|
|
135
|
+
|
|
136
|
+
// Drag end handler
|
|
137
|
+
if (onDragEnd) onDragEnd(newItems);
|
|
128
138
|
};
|
|
129
139
|
|
|
130
140
|
// Add item
|
|
@@ -146,7 +156,11 @@ export function DnDList<
|
|
|
146
156
|
// Edit item
|
|
147
157
|
const editItem = (newItem: D, index: number) => {
|
|
148
158
|
// Existence check
|
|
149
|
-
|
|
159
|
+
const newIndex = items.findIndex(
|
|
160
|
+
(item) => item[labelField] === newItem[labelField]
|
|
161
|
+
);
|
|
162
|
+
if (newIndex >= 0 && newIndex != index) {
|
|
163
|
+
// Label field is the same with a different item
|
|
150
164
|
return false;
|
|
151
165
|
}
|
|
152
166
|
|
|
@@ -197,17 +211,23 @@ export function DnDList<
|
|
|
197
211
|
changeItems(newItems);
|
|
198
212
|
};
|
|
199
213
|
|
|
200
|
-
|
|
214
|
+
// Reload items
|
|
215
|
+
const reloadItems = () => {
|
|
201
216
|
// Load data
|
|
202
217
|
loadData(name).then((items) => setItems(items));
|
|
218
|
+
};
|
|
219
|
+
|
|
220
|
+
React.useEffect(() => {
|
|
221
|
+
// Load data
|
|
222
|
+
reloadItems();
|
|
203
223
|
}, [name]);
|
|
204
224
|
|
|
205
225
|
// Layout
|
|
206
226
|
return (
|
|
207
227
|
<React.Fragment>
|
|
208
|
-
{sideRenderer && sideRenderer(true, addItem, addItems)}
|
|
228
|
+
{sideRenderer && sideRenderer(true, addItem, addItems, reloadItems)}
|
|
209
229
|
<Component {...componentProps}>
|
|
210
|
-
<DragDropContext onDragEnd={
|
|
230
|
+
<DragDropContext onDragEnd={onDragEndLocal}>
|
|
211
231
|
<Droppable droppableId={name}>
|
|
212
232
|
{(provided, snapshot) => (
|
|
213
233
|
<div
|
|
@@ -261,7 +281,8 @@ export function DnDList<
|
|
|
261
281
|
</Droppable>
|
|
262
282
|
</DragDropContext>
|
|
263
283
|
</Component>
|
|
264
|
-
{sideRenderer &&
|
|
284
|
+
{sideRenderer &&
|
|
285
|
+
sideRenderer(false, addItem, addItems, reloadItems)}
|
|
265
286
|
</React.Fragment>
|
|
266
287
|
);
|
|
267
288
|
}
|
package/src/mu/TooltipClick.tsx
CHANGED
|
@@ -81,6 +81,9 @@ export function TooltipClick(props: TooltipClickProps) {
|
|
|
81
81
|
disableFocusListener
|
|
82
82
|
disableTouchListener
|
|
83
83
|
disableHoverListener={disableHoverListener}
|
|
84
|
+
onMouseOver={
|
|
85
|
+
disableHoverListener ? undefined : () => setOpen(true)
|
|
86
|
+
}
|
|
84
87
|
{...rest}
|
|
85
88
|
>
|
|
86
89
|
{children(openTooltip)}
|