@gravity-ui/dashkit 8.8.0 → 8.8.1-beta.1
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/build/cjs/components/GridLayout/GridLayout.d.ts +8 -2
- package/build/cjs/components/GridLayout/GridLayout.js +104 -23
- package/build/cjs/components/GridLayout/ReactGridLayout.js +178 -25
- package/build/cjs/hocs/withContext.js +24 -6
- package/build/esm/components/GridLayout/GridLayout.d.ts +8 -2
- package/build/esm/components/GridLayout/GridLayout.js +104 -23
- package/build/esm/components/GridLayout/ReactGridLayout.js +179 -26
- package/build/esm/hocs/withContext.js +24 -6
- package/package.json +1 -1
|
@@ -5,6 +5,8 @@ export default class GridLayout extends React.PureComponent<any, any, any> {
|
|
|
5
5
|
state: {
|
|
6
6
|
isDragging: boolean;
|
|
7
7
|
isPageHidden: boolean;
|
|
8
|
+
currentDraggingElement: null;
|
|
9
|
+
draggedOverGroup: null;
|
|
8
10
|
};
|
|
9
11
|
componentDidMount(): void;
|
|
10
12
|
componentDidUpdate(): void;
|
|
@@ -36,10 +38,14 @@ export default class GridLayout extends React.PureComponent<any, any, any> {
|
|
|
36
38
|
getMemoForwardRefCallback: (refIndex: any) => any;
|
|
37
39
|
mergeGroupsLayout(group: any, newLayout: any, temporaryItem: any): any;
|
|
38
40
|
reloadItems(): void;
|
|
39
|
-
|
|
41
|
+
_onDragStart: (group: any, _newLayout: any, layoutItem: any) => void;
|
|
42
|
+
_onResizeStart: () => void;
|
|
43
|
+
_onDragExit: () => void;
|
|
40
44
|
_onStop: (group: any, newLayout: any) => void;
|
|
41
|
-
|
|
45
|
+
_onSharedDrop: (targetGroup: any, newLayout: any, tempItem: any) => void;
|
|
46
|
+
_onExternalDrop: (group: any, newLayout: any, item: any, e: any) => void;
|
|
42
47
|
_onDrop: (group: any, newLayout: any, item: any, e: any) => false | undefined;
|
|
48
|
+
_onDropDragOver: (group: any, e: any) => any;
|
|
43
49
|
renderTemporaryPlaceholder(): JSX.Element | null;
|
|
44
50
|
renderGroup(group: any, renderLayout: any, renderItems: any, offset: number | undefined, groupGridProperties: any): JSX.Element;
|
|
45
51
|
render(): any;
|
|
@@ -56,17 +56,18 @@ class GridLayout extends react_1.default.PureComponent {
|
|
|
56
56
|
};
|
|
57
57
|
this.getMemoGroupCallbacks = (group) => {
|
|
58
58
|
if (!this._memoCallbacksForGroups[group]) {
|
|
59
|
-
const
|
|
59
|
+
const onDragStart = this._onDragStart.bind(this, group);
|
|
60
60
|
const onStop = this._onStop.bind(this, group);
|
|
61
61
|
const onDrop = this._onDrop.bind(this, group);
|
|
62
62
|
const onDropDragOver = this._onDropDragOver.bind(this, group);
|
|
63
|
+
const onDragExit = this._onDragExit.bind(this, group);
|
|
63
64
|
this._memoCallbacksForGroups[group] = {
|
|
64
|
-
onDragStart
|
|
65
|
-
onResizeStart: onStart,
|
|
65
|
+
onDragStart,
|
|
66
66
|
onDragStop: onStop,
|
|
67
67
|
onResizeStop: onStop,
|
|
68
|
-
onDrop
|
|
68
|
+
onDrop,
|
|
69
69
|
onDropDragOver,
|
|
70
|
+
onDragExit,
|
|
70
71
|
};
|
|
71
72
|
}
|
|
72
73
|
return this._memoCallbacksForGroups[group];
|
|
@@ -93,48 +94,128 @@ class GridLayout extends react_1.default.PureComponent {
|
|
|
93
94
|
}
|
|
94
95
|
return this._memoForwardedPluginRef[refIndex];
|
|
95
96
|
};
|
|
96
|
-
this.
|
|
97
|
+
this._onDragStart = (group, _newLayout, layoutItem) => {
|
|
97
98
|
if (this.temporaryLayout)
|
|
98
99
|
return;
|
|
99
|
-
this.
|
|
100
|
+
if (this.context.dragOverPlugin) {
|
|
101
|
+
this.setState({ isDragging: true });
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
let currentDraggingElement = this.state.currentDraggingElement;
|
|
105
|
+
if (!currentDraggingElement) {
|
|
106
|
+
const _id = layoutItem.i;
|
|
107
|
+
const item = this.context.config.items.find(({ id }) => id === _id);
|
|
108
|
+
currentDraggingElement = [group, layoutItem, item];
|
|
109
|
+
}
|
|
110
|
+
this.setState({
|
|
111
|
+
isDragging: true,
|
|
112
|
+
currentDraggingElement,
|
|
113
|
+
draggedOverGroup: group,
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
this._onResizeStart = () => {
|
|
118
|
+
this.setState({
|
|
119
|
+
isDragging: true,
|
|
120
|
+
});
|
|
121
|
+
};
|
|
122
|
+
this._onDragExit = () => {
|
|
123
|
+
this.setState({
|
|
124
|
+
draggedOverGroup: null,
|
|
125
|
+
});
|
|
100
126
|
};
|
|
101
127
|
this._onStop = (group, newLayout) => {
|
|
102
128
|
const { layoutChange, onDrop, temporaryLayout } = this.context;
|
|
129
|
+
const { draggedOverGroup, currentDraggingElement } = this.state;
|
|
130
|
+
if (currentDraggingElement &&
|
|
131
|
+
draggedOverGroup !== null &&
|
|
132
|
+
draggedOverGroup !== currentDraggingElement[0]) {
|
|
133
|
+
// Skipping layout update when change event called for source grid
|
|
134
|
+
// and waiting _onDrop
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
103
137
|
const groupedLayout = this.mergeGroupsLayout(group, newLayout);
|
|
138
|
+
this.setState({
|
|
139
|
+
isDragging: false,
|
|
140
|
+
currentDraggingElement: null,
|
|
141
|
+
draggedOverGroup: null,
|
|
142
|
+
});
|
|
104
143
|
if (temporaryLayout) {
|
|
105
144
|
onDrop === null || onDrop === void 0 ? void 0 : onDrop(groupedLayout, groupedLayout.find(({ i }) => i === constants_1.TEMPORARY_ITEM_ID));
|
|
106
145
|
}
|
|
107
146
|
else {
|
|
108
147
|
layoutChange(groupedLayout);
|
|
109
148
|
}
|
|
110
|
-
this.setState({ isDragging: false });
|
|
111
149
|
};
|
|
112
|
-
this.
|
|
113
|
-
const {
|
|
114
|
-
|
|
115
|
-
|
|
150
|
+
this._onSharedDrop = (targetGroup, newLayout, tempItem) => {
|
|
151
|
+
const { currentDraggingElement } = this.state;
|
|
152
|
+
const { layoutChange } = this.context;
|
|
153
|
+
if (!currentDraggingElement) {
|
|
154
|
+
return;
|
|
116
155
|
}
|
|
117
|
-
const
|
|
118
|
-
|
|
156
|
+
const [, sourceItem] = currentDraggingElement;
|
|
157
|
+
const groupedLayout = this.mergeGroupsLayout(targetGroup, newLayout, tempItem).map((item) => {
|
|
158
|
+
if (item.i === sourceItem.i) {
|
|
159
|
+
const copy = Object.assign({}, tempItem);
|
|
160
|
+
delete copy.parent;
|
|
161
|
+
if (targetGroup !== constants_1.DEFAULT_GROUP) {
|
|
162
|
+
copy.parent = targetGroup;
|
|
163
|
+
}
|
|
164
|
+
copy.i = sourceItem.i;
|
|
165
|
+
return copy;
|
|
166
|
+
}
|
|
167
|
+
return item;
|
|
168
|
+
});
|
|
169
|
+
this.setState({
|
|
170
|
+
isDragging: false,
|
|
171
|
+
currentDraggingElement: null,
|
|
172
|
+
draggedOverGroup: null,
|
|
173
|
+
});
|
|
174
|
+
layoutChange(groupedLayout);
|
|
175
|
+
};
|
|
176
|
+
this._onExternalDrop = (group, newLayout, item, e) => {
|
|
177
|
+
const { onDrop } = this.context;
|
|
178
|
+
if (group !== constants_1.DEFAULT_GROUP) {
|
|
179
|
+
item.parent = group;
|
|
180
|
+
}
|
|
181
|
+
const groupedLayout = this.mergeGroupsLayout(group, newLayout, item);
|
|
182
|
+
this.setState({ isDragging: false });
|
|
183
|
+
onDrop === null || onDrop === void 0 ? void 0 : onDrop(groupedLayout, item, e);
|
|
119
184
|
};
|
|
120
185
|
this._onDrop = (group, newLayout, item, e) => {
|
|
121
|
-
if (!item) {
|
|
186
|
+
if (!item || !this.context.editMode) {
|
|
122
187
|
return false;
|
|
123
188
|
}
|
|
124
|
-
const {
|
|
125
|
-
if (
|
|
189
|
+
const { draggedOverGroup, currentDraggingElement } = this.state;
|
|
190
|
+
if (currentDraggingElement && draggedOverGroup === group) {
|
|
191
|
+
this._onSharedDrop(group, newLayout, item);
|
|
192
|
+
}
|
|
193
|
+
else {
|
|
194
|
+
this._onExternalDrop(group, newLayout, item, e);
|
|
195
|
+
}
|
|
196
|
+
};
|
|
197
|
+
this._onDropDragOver = (group, e) => {
|
|
198
|
+
const { editMode, dragOverPlugin, onDropDragOver } = this.context;
|
|
199
|
+
const { currentDraggingElement } = this.state;
|
|
200
|
+
if (!editMode || (!dragOverPlugin && !currentDraggingElement)) {
|
|
126
201
|
return false;
|
|
127
202
|
}
|
|
128
|
-
|
|
129
|
-
|
|
203
|
+
const { properties, layout } = this.getLayoutAndPropsByGroup(group);
|
|
204
|
+
if (currentDraggingElement) {
|
|
205
|
+
const [, { h, w, i }, { type }] = currentDraggingElement;
|
|
206
|
+
return onDropDragOver(e, properties, layout, { h, w, i, type });
|
|
130
207
|
}
|
|
131
|
-
|
|
132
|
-
|
|
208
|
+
if (dragOverPlugin) {
|
|
209
|
+
return onDropDragOver(e, properties, layout);
|
|
210
|
+
}
|
|
211
|
+
return false;
|
|
133
212
|
};
|
|
134
213
|
this.pluginsRefs = [];
|
|
135
214
|
this.state = {
|
|
136
215
|
isDragging: false,
|
|
137
216
|
isPageHidden: false,
|
|
217
|
+
currentDraggingElement: null,
|
|
218
|
+
draggedOverGroup: null,
|
|
138
219
|
};
|
|
139
220
|
}
|
|
140
221
|
componentDidMount() {
|
|
@@ -201,6 +282,7 @@ class GridLayout extends react_1.default.PureComponent {
|
|
|
201
282
|
}
|
|
202
283
|
renderGroup(group, renderLayout, renderItems, offset = 0, groupGridProperties) {
|
|
203
284
|
const { registerManager, editMode, noOverlay, focusable, draggableHandleClassName, outerDnDEnable, } = this.context;
|
|
285
|
+
const { currentDraggingElement } = this.state;
|
|
204
286
|
const properties = groupGridProperties
|
|
205
287
|
? groupGridProperties(Object.assign({}, registerManager.gridLayout))
|
|
206
288
|
: registerManager.gridLayout;
|
|
@@ -209,13 +291,12 @@ class GridLayout extends react_1.default.PureComponent {
|
|
|
209
291
|
compactType = 'horizontal';
|
|
210
292
|
}
|
|
211
293
|
const { callbacks, layout } = this.getMemoGroupProps(group, renderLayout, properties);
|
|
212
|
-
|
|
294
|
+
const hasSharedDragItem = Boolean(currentDraggingElement && currentDraggingElement[0] !== group);
|
|
295
|
+
return (react_1.default.createElement(ReactGridLayout_1.Layout, Object.assign({}, properties, { compactType: compactType, layout: layout, key: `group_${group}`, isDraggable: editMode, isResizable: editMode, onResizeStart: this._onResizeStart, onDragStart: callbacks.onDragStart, onDragStop: callbacks.onDragStop, onResizeStop: callbacks.onResizeStop, onDragExit: callbacks.onDragExit, onDropDragOver: callbacks.onDropDragOver, onDrop: callbacks.onDrop, hasSharedDragItem: hasSharedDragItem }, (draggableHandleClassName
|
|
213
296
|
? { draggableHandle: `.${draggableHandleClassName}` }
|
|
214
297
|
: null), (outerDnDEnable
|
|
215
298
|
? {
|
|
216
299
|
isDroppable: true,
|
|
217
|
-
onDropDragOver: callbacks.onDropDragOver,
|
|
218
|
-
onDrop: callbacks.onDrop,
|
|
219
300
|
}
|
|
220
301
|
: null), { draggableCancel: `.${constants_1.OVERLAY_CONTROLS_CLASS_NAME}` }),
|
|
221
302
|
renderItems.map((item, i) => {
|
|
@@ -5,62 +5,215 @@ const tslib_1 = require("tslib");
|
|
|
5
5
|
const react_1 = tslib_1.__importDefault(require("react"));
|
|
6
6
|
const react_grid_layout_1 = tslib_1.__importStar(require("react-grid-layout"));
|
|
7
7
|
const constants_1 = require("../../constants");
|
|
8
|
+
const { compact, compactType } = react_grid_layout_1.utils;
|
|
9
|
+
// pointer-events disabled to make mouse events be able to passthrought
|
|
10
|
+
// while dragging element out of the grid the mouse positioned over grid item
|
|
11
|
+
// so there is only two ways to get it, calculate rect or just give browser make his work
|
|
12
|
+
const DRAGGING_PLACEHOLDER_STYLE = { pointerEvents: 'none' };
|
|
13
|
+
// when shared element is dragged over another group we still creating placeholder for it
|
|
14
|
+
// cause react-grid-layout is havely dependent on this element
|
|
15
|
+
// while in future there will be some wey not to create dummy div and hide it with opacity
|
|
16
|
+
// this hack is all what i've got now
|
|
17
|
+
const DRAGGING_PLACEHOLDER_HIDDEN_STYLE = Object.assign(Object.assign({}, DRAGGING_PLACEHOLDER_STYLE), { opacity: 0 });
|
|
8
18
|
class DragOverLayout extends react_grid_layout_1.default {
|
|
9
19
|
constructor(...args) {
|
|
10
20
|
super(...args);
|
|
11
|
-
this.
|
|
21
|
+
this._isMouseOver = true;
|
|
22
|
+
this._savedDragoutState = null;
|
|
23
|
+
// Reset placeholder when item dragged from outside
|
|
24
|
+
this.resetExternalPlaceholder = () => {
|
|
12
25
|
if (this.dragEnterCounter) {
|
|
13
26
|
this.dragEnterCounter = 0;
|
|
14
27
|
this.removeDroppingPlaceholder();
|
|
15
28
|
}
|
|
16
29
|
};
|
|
30
|
+
// Hide placeholder when element is dragged out
|
|
31
|
+
this.hideLocalPlaceholder = (i) => {
|
|
32
|
+
const { layout } = this.state;
|
|
33
|
+
const { cols } = this.props;
|
|
34
|
+
const savedLayout = layout.map((item) => (Object.assign({}, item)));
|
|
35
|
+
let hiddenElement;
|
|
36
|
+
const newLayout = compact(layout.filter((item) => {
|
|
37
|
+
if (item.i === i) {
|
|
38
|
+
hiddenElement = item;
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
return true;
|
|
42
|
+
}), compactType(this.props), cols);
|
|
43
|
+
if (hiddenElement) {
|
|
44
|
+
newLayout.push(hiddenElement);
|
|
45
|
+
}
|
|
46
|
+
this.setState({
|
|
47
|
+
activeDrag: null,
|
|
48
|
+
layout: newLayout,
|
|
49
|
+
});
|
|
50
|
+
this.resetExternalPlaceholder();
|
|
51
|
+
return { layout: savedLayout, id: hiddenElement.i };
|
|
52
|
+
};
|
|
53
|
+
this.extendedOnDrag = (i, x, y, sintEv) => {
|
|
54
|
+
if (!this._isMouseOver) {
|
|
55
|
+
if (!this._savedDragoutState) {
|
|
56
|
+
this._savedDragoutState = this.hideLocalPlaceholder(i);
|
|
57
|
+
}
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
// parent onDrag will show new placeholder again
|
|
61
|
+
this.parentOnDrag(i, x, y, sintEv);
|
|
62
|
+
};
|
|
63
|
+
this.extendedOnDragStop = (i, x, y, sintEv) => {
|
|
64
|
+
// Restoring layout if item was dropped outside of the grid and wasn't captured
|
|
65
|
+
if (this._savedDragoutState) {
|
|
66
|
+
const savedLayout = this._savedDragoutState.layout;
|
|
67
|
+
const l = react_grid_layout_1.utils.getLayoutItem(savedLayout, i);
|
|
68
|
+
// Create placeholder (display only)
|
|
69
|
+
const placeholder = {
|
|
70
|
+
w: l.w,
|
|
71
|
+
h: l.h,
|
|
72
|
+
x: l.x,
|
|
73
|
+
y: l.y,
|
|
74
|
+
placeholder: true,
|
|
75
|
+
i: i,
|
|
76
|
+
};
|
|
77
|
+
this.setState({
|
|
78
|
+
layout: savedLayout,
|
|
79
|
+
activeDrag: placeholder,
|
|
80
|
+
}, () => {
|
|
81
|
+
this.parentOnDragStop(i, x, y, sintEv);
|
|
82
|
+
});
|
|
83
|
+
this._savedDragoutState = null;
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
this.parentOnDragStop(i, x, y, sintEv);
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
this.extendedOnDragEnter = (...args) => {
|
|
90
|
+
this._isMouseOver = true;
|
|
91
|
+
this.parentOnDragEnter(...args);
|
|
92
|
+
};
|
|
93
|
+
this.extendedOnDragLeave = (...args) => {
|
|
94
|
+
var _a, _b;
|
|
95
|
+
this._isMouseOver = false;
|
|
96
|
+
this.parentOnDragLeave(...args);
|
|
97
|
+
(_b = (_a = this.props).onDragExit) === null || _b === void 0 ? void 0 : _b.call(_a);
|
|
98
|
+
};
|
|
99
|
+
// Proxy mouse events -> drag methods for dnd between groups
|
|
100
|
+
this.mouseEnterHandler = (e) => {
|
|
101
|
+
this._isMouseOver = true;
|
|
102
|
+
if (this.props.hasSharedDragItem) {
|
|
103
|
+
this.parentOnDragEnter(e);
|
|
104
|
+
}
|
|
105
|
+
};
|
|
17
106
|
this.mouseLeaveHandler = (e) => {
|
|
18
|
-
var _a;
|
|
19
|
-
|
|
20
|
-
if (
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
rect.right <= e.clientX) {
|
|
24
|
-
this.dragReset();
|
|
107
|
+
var _a, _b;
|
|
108
|
+
this._isMouseOver = false;
|
|
109
|
+
if (this.props.hasSharedDragItem) {
|
|
110
|
+
this.parentOnDragLeave(e);
|
|
111
|
+
(_b = (_a = this.props).onDragExit) === null || _b === void 0 ? void 0 : _b.call(_a);
|
|
25
112
|
}
|
|
26
113
|
};
|
|
27
|
-
this.
|
|
28
|
-
|
|
29
|
-
this.
|
|
30
|
-
|
|
114
|
+
this.mouseMoveHandler = (e) => {
|
|
115
|
+
this._isMouseOver = true;
|
|
116
|
+
if (this.props.hasSharedDragItem) {
|
|
117
|
+
this.onDragOver(e);
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
this.mouseUpHandler = (e) => {
|
|
121
|
+
var _a, _b;
|
|
122
|
+
this._isMouseOver = true;
|
|
123
|
+
if (this.props.hasSharedDragItem) {
|
|
124
|
+
e.preventDefault();
|
|
125
|
+
const { droppingItem } = this.props;
|
|
126
|
+
const { layout } = this.state;
|
|
127
|
+
const item = layout.find((l) => l.i === droppingItem.i);
|
|
128
|
+
// reset dragEnter counter on drop
|
|
129
|
+
this.resetExternalPlaceholder();
|
|
130
|
+
(_b = (_a = this.props).onDrop) === null || _b === void 0 ? void 0 : _b.call(_a, layout, item, e);
|
|
131
|
+
}
|
|
31
132
|
};
|
|
133
|
+
this.parentOnDrag = this.onDrag;
|
|
134
|
+
this.onDrag = this.extendedOnDrag;
|
|
135
|
+
this.parentOnDragStop = this.onDragStop;
|
|
136
|
+
this.onDragStop = this.extendedOnDragStop;
|
|
137
|
+
this.parentOnDragEnter = this.onDragEnter;
|
|
138
|
+
this.onDragEnter = this.extendedOnDragEnter;
|
|
139
|
+
this.parentOnDragLeave = this.onDragLeave;
|
|
140
|
+
this.onDragLeave = this.extendedOnDragLeave;
|
|
32
141
|
}
|
|
33
142
|
componentDidMount() {
|
|
34
143
|
var _a;
|
|
35
144
|
(_a = super.componentDidMount) === null || _a === void 0 ? void 0 : _a.call(this);
|
|
36
|
-
window
|
|
145
|
+
// If cursor is moved out of the window there is a bug
|
|
146
|
+
// which leaves placeholder element in grid, this action needed to reset this state
|
|
147
|
+
window.addEventListener('dragend', this.resetExternalPlaceholder);
|
|
148
|
+
const innerElement = this.getInnerElement();
|
|
149
|
+
if (innerElement) {
|
|
150
|
+
innerElement.addEventListener('mouseup', this.mouseUpHandler);
|
|
151
|
+
innerElement.addEventListener('mouseenter', this.mouseEnterHandler);
|
|
152
|
+
innerElement.addEventListener('mouseleave', this.mouseLeaveHandler);
|
|
153
|
+
innerElement.addEventListener('mousemove', this.mouseMoveHandler);
|
|
154
|
+
}
|
|
37
155
|
}
|
|
38
156
|
componentWillUnmount() {
|
|
39
|
-
window.removeEventListener('dragend', this.
|
|
157
|
+
window.removeEventListener('dragend', this.resetExternalPlaceholder);
|
|
158
|
+
const innerElement = this.getInnerElement();
|
|
159
|
+
if (innerElement) {
|
|
160
|
+
innerElement.removeEventListener('mouseup', this.mouseUpHandler);
|
|
161
|
+
innerElement.removeEventListener('mouseenter', this.mouseEnterHandler);
|
|
162
|
+
innerElement.removeEventListener('mouseleave', this.mouseLeaveHandler);
|
|
163
|
+
innerElement.removeEventListener('mousemove', this.mouseMoveHandler);
|
|
164
|
+
}
|
|
165
|
+
// Resetting instance props
|
|
166
|
+
this._savedDragoutState = null;
|
|
40
167
|
}
|
|
168
|
+
// react-grid-layout doens't calculate it's height when last element is removed
|
|
169
|
+
// and just keeps the previous value
|
|
170
|
+
// so for autosize to work in that case we are resetting it's height value
|
|
41
171
|
containerHeight() {
|
|
42
172
|
if (this.props.autoSize && this.state.layout.length === 0) {
|
|
43
|
-
return
|
|
173
|
+
return;
|
|
44
174
|
}
|
|
175
|
+
// eslint-disable-next-line consistent-return
|
|
45
176
|
return super.containerHeight();
|
|
46
177
|
}
|
|
47
|
-
|
|
178
|
+
// innerRef is passed by WithProvider without this wrapper there are only
|
|
179
|
+
// * findDOMNode - deprecated
|
|
180
|
+
// * rewrite whole ReactGridLayout.render method
|
|
181
|
+
// so in that case don't try to use this class on it's own
|
|
182
|
+
// or pass innerRef: React.MutableRef as it's not optional prop
|
|
183
|
+
getInnerElement() {
|
|
48
184
|
var _a;
|
|
185
|
+
return ((_a = this.props.innerRef) === null || _a === void 0 ? void 0 : _a.current) || null;
|
|
186
|
+
}
|
|
187
|
+
// Drop item from outside gets 0,0 droppingPosition
|
|
188
|
+
// centering cursor on newly creted grid item
|
|
189
|
+
// And cause grid-layout using it's own GridItem to make it look
|
|
190
|
+
// like overlay adding className
|
|
191
|
+
processGridItem(child, isDroppingItem) {
|
|
192
|
+
var _a, _b, _c;
|
|
49
193
|
const gridItem = (_a = super.processGridItem) === null || _a === void 0 ? void 0 : _a.call(this, child, isDroppingItem);
|
|
194
|
+
if (!gridItem) {
|
|
195
|
+
return gridItem;
|
|
196
|
+
}
|
|
197
|
+
const { props: itemProps } = gridItem;
|
|
50
198
|
if (isDroppingItem) {
|
|
51
|
-
|
|
52
|
-
// centering cursor on newly creted grid item
|
|
53
|
-
// And cause grid-layout using it's own GridItem to make it look
|
|
54
|
-
// like overlay adding className
|
|
55
|
-
if (!gridItem)
|
|
56
|
-
return null;
|
|
57
|
-
const { props } = gridItem;
|
|
58
|
-
const { containerWidth, cols, w, h, rowHeight, margin, transformScale } = props;
|
|
199
|
+
const { containerWidth, cols, w, h, rowHeight, margin, transformScale, droppingPosition, } = itemProps;
|
|
59
200
|
const leftOffset = (((containerWidth / cols) * w) / 2 || 0) * transformScale;
|
|
60
201
|
const topOffset = ((h * rowHeight + (h - 1) * margin[1]) / 2 || 0) * transformScale;
|
|
202
|
+
const dragStyles = this.props.hasSharedDragItem
|
|
203
|
+
? DRAGGING_PLACEHOLDER_HIDDEN_STYLE
|
|
204
|
+
: DRAGGING_PLACEHOLDER_STYLE;
|
|
205
|
+
// React.cloneElement is just cleaner then copy-paste whole processGridItem method
|
|
61
206
|
return react_1.default.cloneElement(gridItem, {
|
|
207
|
+
style: itemProps.style ? Object.assign(Object.assign({}, itemProps.style), dragStyles) : dragStyles,
|
|
62
208
|
className: constants_1.OVERLAY_CLASS_NAME,
|
|
63
|
-
droppingPosition: Object.assign(Object.assign({},
|
|
209
|
+
droppingPosition: Object.assign(Object.assign({}, droppingPosition), { left: droppingPosition.left - leftOffset, top: droppingPosition.top - topOffset }),
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
else if (itemProps.i === ((_b = this.state.activeDrag) === null || _b === void 0 ? void 0 : _b.i) ||
|
|
213
|
+
itemProps.i === ((_c = this._savedDragoutState) === null || _c === void 0 ? void 0 : _c.id)) {
|
|
214
|
+
const dragStyles = DRAGGING_PLACEHOLDER_STYLE;
|
|
215
|
+
return react_1.default.cloneElement(gridItem, {
|
|
216
|
+
style: itemProps.style ? Object.assign(Object.assign({}, itemProps.style), dragStyles) : dragStyles,
|
|
64
217
|
});
|
|
65
218
|
}
|
|
66
219
|
return gridItem;
|
|
@@ -32,7 +32,7 @@ function useMemoStateContext(props) {
|
|
|
32
32
|
(0, isEqual_1.default)(groups, props.groups))) {
|
|
33
33
|
props.onChange({ config, itemsStateAndParams, groups });
|
|
34
34
|
}
|
|
35
|
-
}, [props.config, props.itemsStateAndParams, props.onChange]);
|
|
35
|
+
}, [props.config, props.groups, props.itemsStateAndParams, props.onChange]);
|
|
36
36
|
// каллбэк вызывающийся при изменение лэйаута сетки, первым аргументом приходит актуальный конфиг лэйаута,
|
|
37
37
|
// т.е. если на текущей сетке есть виджеты, с активированной опцией автовысоты, их параметр "h" будет
|
|
38
38
|
// "подстроенный"; чтобы, для сохранения в сторе "ушли" значения без учёта подстройки (как если бы у этих
|
|
@@ -40,7 +40,17 @@ function useMemoStateContext(props) {
|
|
|
40
40
|
const onLayoutChange = react_1.default.useCallback((layout) => {
|
|
41
41
|
const currentInnerLayout = layout.map((item) => {
|
|
42
42
|
if (item.i in originalLayouts.current) {
|
|
43
|
-
|
|
43
|
+
// eslint-disable-next-line no-unused-vars
|
|
44
|
+
const _a = originalLayouts.current[item.i], { parent } = _a, originalCopy = tslib_1.__rest(_a, ["parent"]);
|
|
45
|
+
// Updating original if parent has changed and saving copy as original
|
|
46
|
+
// or leaving default
|
|
47
|
+
if (item.parent) {
|
|
48
|
+
originalCopy.parent = item.parent;
|
|
49
|
+
}
|
|
50
|
+
originalCopy.w = item.w;
|
|
51
|
+
originalCopy.x = item.x;
|
|
52
|
+
originalCopy.y = item.y;
|
|
53
|
+
return originalCopy;
|
|
44
54
|
}
|
|
45
55
|
else {
|
|
46
56
|
return Object.assign({}, item);
|
|
@@ -237,16 +247,24 @@ function useMemoStateContext(props) {
|
|
|
237
247
|
return null;
|
|
238
248
|
}
|
|
239
249
|
}, [dragProps, props.registerManager]);
|
|
240
|
-
const onDropDragOver = react_1.default.useCallback((_e, gridProps, groupLayout) => {
|
|
250
|
+
const onDropDragOver = react_1.default.useCallback((_e, gridProps, groupLayout, sharedItem) => {
|
|
241
251
|
if (temporaryLayout) {
|
|
242
252
|
resetTemporaryLayout();
|
|
243
253
|
return false;
|
|
244
254
|
}
|
|
245
|
-
|
|
255
|
+
let defaultLayout;
|
|
256
|
+
if (sharedItem) {
|
|
257
|
+
const { type, h, w } = sharedItem;
|
|
258
|
+
const _defaults = props.registerManager.getItem(type);
|
|
259
|
+
defaultLayout = _defaults ? Object.assign(Object.assign({}, _defaults.defaultLayout), { h, w }) : { h, w };
|
|
260
|
+
}
|
|
261
|
+
else if (dragOverPlugin) {
|
|
262
|
+
defaultLayout = dragOverPlugin.defaultLayout;
|
|
263
|
+
}
|
|
264
|
+
else {
|
|
246
265
|
return false;
|
|
247
266
|
}
|
|
248
267
|
let maxW = gridProps.cols;
|
|
249
|
-
const { defaultLayout } = dragOverPlugin;
|
|
250
268
|
const maxH = Math.min(gridProps.maxRows || Infinity, defaultLayout.maxH || Infinity);
|
|
251
269
|
if (gridProps.compactType === common_1.COMPACT_TYPE_HORIZONTAL_NOWRAP) {
|
|
252
270
|
maxW = groupLayout.reduce((memo, item) => memo - item.w, gridProps.cols);
|
|
@@ -257,7 +275,7 @@ function useMemoStateContext(props) {
|
|
|
257
275
|
maxH < defaultLayout.minH) {
|
|
258
276
|
return false;
|
|
259
277
|
}
|
|
260
|
-
const { h = (defaultLayout === null || defaultLayout === void 0 ? void 0 : defaultLayout.h) || common_1.DEFAULT_WIDGET_HEIGHT, w = (defaultLayout === null || defaultLayout === void 0 ? void 0 : defaultLayout.w) || common_1.DEFAULT_WIDGET_WIDTH, } = dragProps.layout || {};
|
|
278
|
+
const { h = (defaultLayout === null || defaultLayout === void 0 ? void 0 : defaultLayout.h) || common_1.DEFAULT_WIDGET_HEIGHT, w = (defaultLayout === null || defaultLayout === void 0 ? void 0 : defaultLayout.w) || common_1.DEFAULT_WIDGET_WIDTH, } = (dragProps === null || dragProps === void 0 ? void 0 : dragProps.layout) || {};
|
|
261
279
|
return {
|
|
262
280
|
h: maxH ? Math.min(h, maxH) : h,
|
|
263
281
|
w: maxW ? Math.min(w, maxW) : w,
|
|
@@ -5,6 +5,8 @@ export default class GridLayout extends React.PureComponent<any, any, any> {
|
|
|
5
5
|
state: {
|
|
6
6
|
isDragging: boolean;
|
|
7
7
|
isPageHidden: boolean;
|
|
8
|
+
currentDraggingElement: null;
|
|
9
|
+
draggedOverGroup: null;
|
|
8
10
|
};
|
|
9
11
|
componentDidMount(): void;
|
|
10
12
|
componentDidUpdate(): void;
|
|
@@ -36,10 +38,14 @@ export default class GridLayout extends React.PureComponent<any, any, any> {
|
|
|
36
38
|
getMemoForwardRefCallback: (refIndex: any) => any;
|
|
37
39
|
mergeGroupsLayout(group: any, newLayout: any, temporaryItem: any): any;
|
|
38
40
|
reloadItems(): void;
|
|
39
|
-
|
|
41
|
+
_onDragStart: (group: any, _newLayout: any, layoutItem: any) => void;
|
|
42
|
+
_onResizeStart: () => void;
|
|
43
|
+
_onDragExit: () => void;
|
|
40
44
|
_onStop: (group: any, newLayout: any) => void;
|
|
41
|
-
|
|
45
|
+
_onSharedDrop: (targetGroup: any, newLayout: any, tempItem: any) => void;
|
|
46
|
+
_onExternalDrop: (group: any, newLayout: any, item: any, e: any) => void;
|
|
42
47
|
_onDrop: (group: any, newLayout: any, item: any, e: any) => false | undefined;
|
|
48
|
+
_onDropDragOver: (group: any, e: any) => any;
|
|
43
49
|
renderTemporaryPlaceholder(): JSX.Element | null;
|
|
44
50
|
renderGroup(group: any, renderLayout: any, renderItems: any, offset: number | undefined, groupGridProperties: any): JSX.Element;
|
|
45
51
|
render(): any;
|
|
@@ -53,17 +53,18 @@ class GridLayout extends React.PureComponent {
|
|
|
53
53
|
};
|
|
54
54
|
this.getMemoGroupCallbacks = (group) => {
|
|
55
55
|
if (!this._memoCallbacksForGroups[group]) {
|
|
56
|
-
const
|
|
56
|
+
const onDragStart = this._onDragStart.bind(this, group);
|
|
57
57
|
const onStop = this._onStop.bind(this, group);
|
|
58
58
|
const onDrop = this._onDrop.bind(this, group);
|
|
59
59
|
const onDropDragOver = this._onDropDragOver.bind(this, group);
|
|
60
|
+
const onDragExit = this._onDragExit.bind(this, group);
|
|
60
61
|
this._memoCallbacksForGroups[group] = {
|
|
61
|
-
onDragStart
|
|
62
|
-
onResizeStart: onStart,
|
|
62
|
+
onDragStart,
|
|
63
63
|
onDragStop: onStop,
|
|
64
64
|
onResizeStop: onStop,
|
|
65
|
-
onDrop
|
|
65
|
+
onDrop,
|
|
66
66
|
onDropDragOver,
|
|
67
|
+
onDragExit,
|
|
67
68
|
};
|
|
68
69
|
}
|
|
69
70
|
return this._memoCallbacksForGroups[group];
|
|
@@ -90,48 +91,128 @@ class GridLayout extends React.PureComponent {
|
|
|
90
91
|
}
|
|
91
92
|
return this._memoForwardedPluginRef[refIndex];
|
|
92
93
|
};
|
|
93
|
-
this.
|
|
94
|
+
this._onDragStart = (group, _newLayout, layoutItem) => {
|
|
94
95
|
if (this.temporaryLayout)
|
|
95
96
|
return;
|
|
96
|
-
this.
|
|
97
|
+
if (this.context.dragOverPlugin) {
|
|
98
|
+
this.setState({ isDragging: true });
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
let currentDraggingElement = this.state.currentDraggingElement;
|
|
102
|
+
if (!currentDraggingElement) {
|
|
103
|
+
const _id = layoutItem.i;
|
|
104
|
+
const item = this.context.config.items.find(({ id }) => id === _id);
|
|
105
|
+
currentDraggingElement = [group, layoutItem, item];
|
|
106
|
+
}
|
|
107
|
+
this.setState({
|
|
108
|
+
isDragging: true,
|
|
109
|
+
currentDraggingElement,
|
|
110
|
+
draggedOverGroup: group,
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
this._onResizeStart = () => {
|
|
115
|
+
this.setState({
|
|
116
|
+
isDragging: true,
|
|
117
|
+
});
|
|
118
|
+
};
|
|
119
|
+
this._onDragExit = () => {
|
|
120
|
+
this.setState({
|
|
121
|
+
draggedOverGroup: null,
|
|
122
|
+
});
|
|
97
123
|
};
|
|
98
124
|
this._onStop = (group, newLayout) => {
|
|
99
125
|
const { layoutChange, onDrop, temporaryLayout } = this.context;
|
|
126
|
+
const { draggedOverGroup, currentDraggingElement } = this.state;
|
|
127
|
+
if (currentDraggingElement &&
|
|
128
|
+
draggedOverGroup !== null &&
|
|
129
|
+
draggedOverGroup !== currentDraggingElement[0]) {
|
|
130
|
+
// Skipping layout update when change event called for source grid
|
|
131
|
+
// and waiting _onDrop
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
100
134
|
const groupedLayout = this.mergeGroupsLayout(group, newLayout);
|
|
135
|
+
this.setState({
|
|
136
|
+
isDragging: false,
|
|
137
|
+
currentDraggingElement: null,
|
|
138
|
+
draggedOverGroup: null,
|
|
139
|
+
});
|
|
101
140
|
if (temporaryLayout) {
|
|
102
141
|
onDrop === null || onDrop === void 0 ? void 0 : onDrop(groupedLayout, groupedLayout.find(({ i }) => i === TEMPORARY_ITEM_ID));
|
|
103
142
|
}
|
|
104
143
|
else {
|
|
105
144
|
layoutChange(groupedLayout);
|
|
106
145
|
}
|
|
107
|
-
this.setState({ isDragging: false });
|
|
108
146
|
};
|
|
109
|
-
this.
|
|
110
|
-
const {
|
|
111
|
-
|
|
112
|
-
|
|
147
|
+
this._onSharedDrop = (targetGroup, newLayout, tempItem) => {
|
|
148
|
+
const { currentDraggingElement } = this.state;
|
|
149
|
+
const { layoutChange } = this.context;
|
|
150
|
+
if (!currentDraggingElement) {
|
|
151
|
+
return;
|
|
113
152
|
}
|
|
114
|
-
const
|
|
115
|
-
|
|
153
|
+
const [, sourceItem] = currentDraggingElement;
|
|
154
|
+
const groupedLayout = this.mergeGroupsLayout(targetGroup, newLayout, tempItem).map((item) => {
|
|
155
|
+
if (item.i === sourceItem.i) {
|
|
156
|
+
const copy = Object.assign({}, tempItem);
|
|
157
|
+
delete copy.parent;
|
|
158
|
+
if (targetGroup !== DEFAULT_GROUP) {
|
|
159
|
+
copy.parent = targetGroup;
|
|
160
|
+
}
|
|
161
|
+
copy.i = sourceItem.i;
|
|
162
|
+
return copy;
|
|
163
|
+
}
|
|
164
|
+
return item;
|
|
165
|
+
});
|
|
166
|
+
this.setState({
|
|
167
|
+
isDragging: false,
|
|
168
|
+
currentDraggingElement: null,
|
|
169
|
+
draggedOverGroup: null,
|
|
170
|
+
});
|
|
171
|
+
layoutChange(groupedLayout);
|
|
172
|
+
};
|
|
173
|
+
this._onExternalDrop = (group, newLayout, item, e) => {
|
|
174
|
+
const { onDrop } = this.context;
|
|
175
|
+
if (group !== DEFAULT_GROUP) {
|
|
176
|
+
item.parent = group;
|
|
177
|
+
}
|
|
178
|
+
const groupedLayout = this.mergeGroupsLayout(group, newLayout, item);
|
|
179
|
+
this.setState({ isDragging: false });
|
|
180
|
+
onDrop === null || onDrop === void 0 ? void 0 : onDrop(groupedLayout, item, e);
|
|
116
181
|
};
|
|
117
182
|
this._onDrop = (group, newLayout, item, e) => {
|
|
118
|
-
if (!item) {
|
|
183
|
+
if (!item || !this.context.editMode) {
|
|
119
184
|
return false;
|
|
120
185
|
}
|
|
121
|
-
const {
|
|
122
|
-
if (
|
|
186
|
+
const { draggedOverGroup, currentDraggingElement } = this.state;
|
|
187
|
+
if (currentDraggingElement && draggedOverGroup === group) {
|
|
188
|
+
this._onSharedDrop(group, newLayout, item);
|
|
189
|
+
}
|
|
190
|
+
else {
|
|
191
|
+
this._onExternalDrop(group, newLayout, item, e);
|
|
192
|
+
}
|
|
193
|
+
};
|
|
194
|
+
this._onDropDragOver = (group, e) => {
|
|
195
|
+
const { editMode, dragOverPlugin, onDropDragOver } = this.context;
|
|
196
|
+
const { currentDraggingElement } = this.state;
|
|
197
|
+
if (!editMode || (!dragOverPlugin && !currentDraggingElement)) {
|
|
123
198
|
return false;
|
|
124
199
|
}
|
|
125
|
-
|
|
126
|
-
|
|
200
|
+
const { properties, layout } = this.getLayoutAndPropsByGroup(group);
|
|
201
|
+
if (currentDraggingElement) {
|
|
202
|
+
const [, { h, w, i }, { type }] = currentDraggingElement;
|
|
203
|
+
return onDropDragOver(e, properties, layout, { h, w, i, type });
|
|
127
204
|
}
|
|
128
|
-
|
|
129
|
-
|
|
205
|
+
if (dragOverPlugin) {
|
|
206
|
+
return onDropDragOver(e, properties, layout);
|
|
207
|
+
}
|
|
208
|
+
return false;
|
|
130
209
|
};
|
|
131
210
|
this.pluginsRefs = [];
|
|
132
211
|
this.state = {
|
|
133
212
|
isDragging: false,
|
|
134
213
|
isPageHidden: false,
|
|
214
|
+
currentDraggingElement: null,
|
|
215
|
+
draggedOverGroup: null,
|
|
135
216
|
};
|
|
136
217
|
}
|
|
137
218
|
componentDidMount() {
|
|
@@ -198,6 +279,7 @@ class GridLayout extends React.PureComponent {
|
|
|
198
279
|
}
|
|
199
280
|
renderGroup(group, renderLayout, renderItems, offset = 0, groupGridProperties) {
|
|
200
281
|
const { registerManager, editMode, noOverlay, focusable, draggableHandleClassName, outerDnDEnable, } = this.context;
|
|
282
|
+
const { currentDraggingElement } = this.state;
|
|
201
283
|
const properties = groupGridProperties
|
|
202
284
|
? groupGridProperties(Object.assign({}, registerManager.gridLayout))
|
|
203
285
|
: registerManager.gridLayout;
|
|
@@ -206,13 +288,12 @@ class GridLayout extends React.PureComponent {
|
|
|
206
288
|
compactType = 'horizontal';
|
|
207
289
|
}
|
|
208
290
|
const { callbacks, layout } = this.getMemoGroupProps(group, renderLayout, properties);
|
|
209
|
-
|
|
291
|
+
const hasSharedDragItem = Boolean(currentDraggingElement && currentDraggingElement[0] !== group);
|
|
292
|
+
return (React.createElement(Layout, Object.assign({}, properties, { compactType: compactType, layout: layout, key: `group_${group}`, isDraggable: editMode, isResizable: editMode, onResizeStart: this._onResizeStart, onDragStart: callbacks.onDragStart, onDragStop: callbacks.onDragStop, onResizeStop: callbacks.onResizeStop, onDragExit: callbacks.onDragExit, onDropDragOver: callbacks.onDropDragOver, onDrop: callbacks.onDrop, hasSharedDragItem: hasSharedDragItem }, (draggableHandleClassName
|
|
210
293
|
? { draggableHandle: `.${draggableHandleClassName}` }
|
|
211
294
|
: null), (outerDnDEnable
|
|
212
295
|
? {
|
|
213
296
|
isDroppable: true,
|
|
214
|
-
onDropDragOver: callbacks.onDropDragOver,
|
|
215
|
-
onDrop: callbacks.onDrop,
|
|
216
297
|
}
|
|
217
298
|
: null), { draggableCancel: `.${OVERLAY_CONTROLS_CLASS_NAME}` }),
|
|
218
299
|
renderItems.map((item, i) => {
|
|
@@ -1,62 +1,215 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import ReactGridLayout, { WidthProvider } from 'react-grid-layout';
|
|
2
|
+
import ReactGridLayout, { WidthProvider, utils } from 'react-grid-layout';
|
|
3
3
|
import { OVERLAY_CLASS_NAME } from '../../constants';
|
|
4
|
+
const { compact, compactType } = utils;
|
|
5
|
+
// pointer-events disabled to make mouse events be able to passthrought
|
|
6
|
+
// while dragging element out of the grid the mouse positioned over grid item
|
|
7
|
+
// so there is only two ways to get it, calculate rect or just give browser make his work
|
|
8
|
+
const DRAGGING_PLACEHOLDER_STYLE = { pointerEvents: 'none' };
|
|
9
|
+
// when shared element is dragged over another group we still creating placeholder for it
|
|
10
|
+
// cause react-grid-layout is havely dependent on this element
|
|
11
|
+
// while in future there will be some wey not to create dummy div and hide it with opacity
|
|
12
|
+
// this hack is all what i've got now
|
|
13
|
+
const DRAGGING_PLACEHOLDER_HIDDEN_STYLE = Object.assign(Object.assign({}, DRAGGING_PLACEHOLDER_STYLE), { opacity: 0 });
|
|
4
14
|
class DragOverLayout extends ReactGridLayout {
|
|
5
15
|
constructor(...args) {
|
|
6
16
|
super(...args);
|
|
7
|
-
this.
|
|
17
|
+
this._isMouseOver = true;
|
|
18
|
+
this._savedDragoutState = null;
|
|
19
|
+
// Reset placeholder when item dragged from outside
|
|
20
|
+
this.resetExternalPlaceholder = () => {
|
|
8
21
|
if (this.dragEnterCounter) {
|
|
9
22
|
this.dragEnterCounter = 0;
|
|
10
23
|
this.removeDroppingPlaceholder();
|
|
11
24
|
}
|
|
12
25
|
};
|
|
26
|
+
// Hide placeholder when element is dragged out
|
|
27
|
+
this.hideLocalPlaceholder = (i) => {
|
|
28
|
+
const { layout } = this.state;
|
|
29
|
+
const { cols } = this.props;
|
|
30
|
+
const savedLayout = layout.map((item) => (Object.assign({}, item)));
|
|
31
|
+
let hiddenElement;
|
|
32
|
+
const newLayout = compact(layout.filter((item) => {
|
|
33
|
+
if (item.i === i) {
|
|
34
|
+
hiddenElement = item;
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
return true;
|
|
38
|
+
}), compactType(this.props), cols);
|
|
39
|
+
if (hiddenElement) {
|
|
40
|
+
newLayout.push(hiddenElement);
|
|
41
|
+
}
|
|
42
|
+
this.setState({
|
|
43
|
+
activeDrag: null,
|
|
44
|
+
layout: newLayout,
|
|
45
|
+
});
|
|
46
|
+
this.resetExternalPlaceholder();
|
|
47
|
+
return { layout: savedLayout, id: hiddenElement.i };
|
|
48
|
+
};
|
|
49
|
+
this.extendedOnDrag = (i, x, y, sintEv) => {
|
|
50
|
+
if (!this._isMouseOver) {
|
|
51
|
+
if (!this._savedDragoutState) {
|
|
52
|
+
this._savedDragoutState = this.hideLocalPlaceholder(i);
|
|
53
|
+
}
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
// parent onDrag will show new placeholder again
|
|
57
|
+
this.parentOnDrag(i, x, y, sintEv);
|
|
58
|
+
};
|
|
59
|
+
this.extendedOnDragStop = (i, x, y, sintEv) => {
|
|
60
|
+
// Restoring layout if item was dropped outside of the grid and wasn't captured
|
|
61
|
+
if (this._savedDragoutState) {
|
|
62
|
+
const savedLayout = this._savedDragoutState.layout;
|
|
63
|
+
const l = utils.getLayoutItem(savedLayout, i);
|
|
64
|
+
// Create placeholder (display only)
|
|
65
|
+
const placeholder = {
|
|
66
|
+
w: l.w,
|
|
67
|
+
h: l.h,
|
|
68
|
+
x: l.x,
|
|
69
|
+
y: l.y,
|
|
70
|
+
placeholder: true,
|
|
71
|
+
i: i,
|
|
72
|
+
};
|
|
73
|
+
this.setState({
|
|
74
|
+
layout: savedLayout,
|
|
75
|
+
activeDrag: placeholder,
|
|
76
|
+
}, () => {
|
|
77
|
+
this.parentOnDragStop(i, x, y, sintEv);
|
|
78
|
+
});
|
|
79
|
+
this._savedDragoutState = null;
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
this.parentOnDragStop(i, x, y, sintEv);
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
this.extendedOnDragEnter = (...args) => {
|
|
86
|
+
this._isMouseOver = true;
|
|
87
|
+
this.parentOnDragEnter(...args);
|
|
88
|
+
};
|
|
89
|
+
this.extendedOnDragLeave = (...args) => {
|
|
90
|
+
var _a, _b;
|
|
91
|
+
this._isMouseOver = false;
|
|
92
|
+
this.parentOnDragLeave(...args);
|
|
93
|
+
(_b = (_a = this.props).onDragExit) === null || _b === void 0 ? void 0 : _b.call(_a);
|
|
94
|
+
};
|
|
95
|
+
// Proxy mouse events -> drag methods for dnd between groups
|
|
96
|
+
this.mouseEnterHandler = (e) => {
|
|
97
|
+
this._isMouseOver = true;
|
|
98
|
+
if (this.props.hasSharedDragItem) {
|
|
99
|
+
this.parentOnDragEnter(e);
|
|
100
|
+
}
|
|
101
|
+
};
|
|
13
102
|
this.mouseLeaveHandler = (e) => {
|
|
14
|
-
var _a;
|
|
15
|
-
|
|
16
|
-
if (
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
rect.right <= e.clientX) {
|
|
20
|
-
this.dragReset();
|
|
103
|
+
var _a, _b;
|
|
104
|
+
this._isMouseOver = false;
|
|
105
|
+
if (this.props.hasSharedDragItem) {
|
|
106
|
+
this.parentOnDragLeave(e);
|
|
107
|
+
(_b = (_a = this.props).onDragExit) === null || _b === void 0 ? void 0 : _b.call(_a);
|
|
21
108
|
}
|
|
22
109
|
};
|
|
23
|
-
this.
|
|
24
|
-
|
|
25
|
-
this.
|
|
26
|
-
|
|
110
|
+
this.mouseMoveHandler = (e) => {
|
|
111
|
+
this._isMouseOver = true;
|
|
112
|
+
if (this.props.hasSharedDragItem) {
|
|
113
|
+
this.onDragOver(e);
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
this.mouseUpHandler = (e) => {
|
|
117
|
+
var _a, _b;
|
|
118
|
+
this._isMouseOver = true;
|
|
119
|
+
if (this.props.hasSharedDragItem) {
|
|
120
|
+
e.preventDefault();
|
|
121
|
+
const { droppingItem } = this.props;
|
|
122
|
+
const { layout } = this.state;
|
|
123
|
+
const item = layout.find((l) => l.i === droppingItem.i);
|
|
124
|
+
// reset dragEnter counter on drop
|
|
125
|
+
this.resetExternalPlaceholder();
|
|
126
|
+
(_b = (_a = this.props).onDrop) === null || _b === void 0 ? void 0 : _b.call(_a, layout, item, e);
|
|
127
|
+
}
|
|
27
128
|
};
|
|
129
|
+
this.parentOnDrag = this.onDrag;
|
|
130
|
+
this.onDrag = this.extendedOnDrag;
|
|
131
|
+
this.parentOnDragStop = this.onDragStop;
|
|
132
|
+
this.onDragStop = this.extendedOnDragStop;
|
|
133
|
+
this.parentOnDragEnter = this.onDragEnter;
|
|
134
|
+
this.onDragEnter = this.extendedOnDragEnter;
|
|
135
|
+
this.parentOnDragLeave = this.onDragLeave;
|
|
136
|
+
this.onDragLeave = this.extendedOnDragLeave;
|
|
28
137
|
}
|
|
29
138
|
componentDidMount() {
|
|
30
139
|
var _a;
|
|
31
140
|
(_a = super.componentDidMount) === null || _a === void 0 ? void 0 : _a.call(this);
|
|
32
|
-
window
|
|
141
|
+
// If cursor is moved out of the window there is a bug
|
|
142
|
+
// which leaves placeholder element in grid, this action needed to reset this state
|
|
143
|
+
window.addEventListener('dragend', this.resetExternalPlaceholder);
|
|
144
|
+
const innerElement = this.getInnerElement();
|
|
145
|
+
if (innerElement) {
|
|
146
|
+
innerElement.addEventListener('mouseup', this.mouseUpHandler);
|
|
147
|
+
innerElement.addEventListener('mouseenter', this.mouseEnterHandler);
|
|
148
|
+
innerElement.addEventListener('mouseleave', this.mouseLeaveHandler);
|
|
149
|
+
innerElement.addEventListener('mousemove', this.mouseMoveHandler);
|
|
150
|
+
}
|
|
33
151
|
}
|
|
34
152
|
componentWillUnmount() {
|
|
35
|
-
window.removeEventListener('dragend', this.
|
|
153
|
+
window.removeEventListener('dragend', this.resetExternalPlaceholder);
|
|
154
|
+
const innerElement = this.getInnerElement();
|
|
155
|
+
if (innerElement) {
|
|
156
|
+
innerElement.removeEventListener('mouseup', this.mouseUpHandler);
|
|
157
|
+
innerElement.removeEventListener('mouseenter', this.mouseEnterHandler);
|
|
158
|
+
innerElement.removeEventListener('mouseleave', this.mouseLeaveHandler);
|
|
159
|
+
innerElement.removeEventListener('mousemove', this.mouseMoveHandler);
|
|
160
|
+
}
|
|
161
|
+
// Resetting instance props
|
|
162
|
+
this._savedDragoutState = null;
|
|
36
163
|
}
|
|
164
|
+
// react-grid-layout doens't calculate it's height when last element is removed
|
|
165
|
+
// and just keeps the previous value
|
|
166
|
+
// so for autosize to work in that case we are resetting it's height value
|
|
37
167
|
containerHeight() {
|
|
38
168
|
if (this.props.autoSize && this.state.layout.length === 0) {
|
|
39
|
-
return
|
|
169
|
+
return;
|
|
40
170
|
}
|
|
171
|
+
// eslint-disable-next-line consistent-return
|
|
41
172
|
return super.containerHeight();
|
|
42
173
|
}
|
|
43
|
-
|
|
174
|
+
// innerRef is passed by WithProvider without this wrapper there are only
|
|
175
|
+
// * findDOMNode - deprecated
|
|
176
|
+
// * rewrite whole ReactGridLayout.render method
|
|
177
|
+
// so in that case don't try to use this class on it's own
|
|
178
|
+
// or pass innerRef: React.MutableRef as it's not optional prop
|
|
179
|
+
getInnerElement() {
|
|
44
180
|
var _a;
|
|
181
|
+
return ((_a = this.props.innerRef) === null || _a === void 0 ? void 0 : _a.current) || null;
|
|
182
|
+
}
|
|
183
|
+
// Drop item from outside gets 0,0 droppingPosition
|
|
184
|
+
// centering cursor on newly creted grid item
|
|
185
|
+
// And cause grid-layout using it's own GridItem to make it look
|
|
186
|
+
// like overlay adding className
|
|
187
|
+
processGridItem(child, isDroppingItem) {
|
|
188
|
+
var _a, _b, _c;
|
|
45
189
|
const gridItem = (_a = super.processGridItem) === null || _a === void 0 ? void 0 : _a.call(this, child, isDroppingItem);
|
|
190
|
+
if (!gridItem) {
|
|
191
|
+
return gridItem;
|
|
192
|
+
}
|
|
193
|
+
const { props: itemProps } = gridItem;
|
|
46
194
|
if (isDroppingItem) {
|
|
47
|
-
|
|
48
|
-
// centering cursor on newly creted grid item
|
|
49
|
-
// And cause grid-layout using it's own GridItem to make it look
|
|
50
|
-
// like overlay adding className
|
|
51
|
-
if (!gridItem)
|
|
52
|
-
return null;
|
|
53
|
-
const { props } = gridItem;
|
|
54
|
-
const { containerWidth, cols, w, h, rowHeight, margin, transformScale } = props;
|
|
195
|
+
const { containerWidth, cols, w, h, rowHeight, margin, transformScale, droppingPosition, } = itemProps;
|
|
55
196
|
const leftOffset = (((containerWidth / cols) * w) / 2 || 0) * transformScale;
|
|
56
197
|
const topOffset = ((h * rowHeight + (h - 1) * margin[1]) / 2 || 0) * transformScale;
|
|
198
|
+
const dragStyles = this.props.hasSharedDragItem
|
|
199
|
+
? DRAGGING_PLACEHOLDER_HIDDEN_STYLE
|
|
200
|
+
: DRAGGING_PLACEHOLDER_STYLE;
|
|
201
|
+
// React.cloneElement is just cleaner then copy-paste whole processGridItem method
|
|
57
202
|
return React.cloneElement(gridItem, {
|
|
203
|
+
style: itemProps.style ? Object.assign(Object.assign({}, itemProps.style), dragStyles) : dragStyles,
|
|
58
204
|
className: OVERLAY_CLASS_NAME,
|
|
59
|
-
droppingPosition: Object.assign(Object.assign({},
|
|
205
|
+
droppingPosition: Object.assign(Object.assign({}, droppingPosition), { left: droppingPosition.left - leftOffset, top: droppingPosition.top - topOffset }),
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
else if (itemProps.i === ((_b = this.state.activeDrag) === null || _b === void 0 ? void 0 : _b.i) ||
|
|
209
|
+
itemProps.i === ((_c = this._savedDragoutState) === null || _c === void 0 ? void 0 : _c.id)) {
|
|
210
|
+
const dragStyles = DRAGGING_PLACEHOLDER_STYLE;
|
|
211
|
+
return React.cloneElement(gridItem, {
|
|
212
|
+
style: itemProps.style ? Object.assign(Object.assign({}, itemProps.style), dragStyles) : dragStyles,
|
|
60
213
|
});
|
|
61
214
|
}
|
|
62
215
|
return gridItem;
|
|
@@ -29,7 +29,7 @@ function useMemoStateContext(props) {
|
|
|
29
29
|
isEqual(groups, props.groups))) {
|
|
30
30
|
props.onChange({ config, itemsStateAndParams, groups });
|
|
31
31
|
}
|
|
32
|
-
}, [props.config, props.itemsStateAndParams, props.onChange]);
|
|
32
|
+
}, [props.config, props.groups, props.itemsStateAndParams, props.onChange]);
|
|
33
33
|
// каллбэк вызывающийся при изменение лэйаута сетки, первым аргументом приходит актуальный конфиг лэйаута,
|
|
34
34
|
// т.е. если на текущей сетке есть виджеты, с активированной опцией автовысоты, их параметр "h" будет
|
|
35
35
|
// "подстроенный"; чтобы, для сохранения в сторе "ушли" значения без учёта подстройки (как если бы у этих
|
|
@@ -37,7 +37,17 @@ function useMemoStateContext(props) {
|
|
|
37
37
|
const onLayoutChange = React.useCallback((layout) => {
|
|
38
38
|
const currentInnerLayout = layout.map((item) => {
|
|
39
39
|
if (item.i in originalLayouts.current) {
|
|
40
|
-
|
|
40
|
+
// eslint-disable-next-line no-unused-vars
|
|
41
|
+
const _a = originalLayouts.current[item.i], { parent } = _a, originalCopy = __rest(_a, ["parent"]);
|
|
42
|
+
// Updating original if parent has changed and saving copy as original
|
|
43
|
+
// or leaving default
|
|
44
|
+
if (item.parent) {
|
|
45
|
+
originalCopy.parent = item.parent;
|
|
46
|
+
}
|
|
47
|
+
originalCopy.w = item.w;
|
|
48
|
+
originalCopy.x = item.x;
|
|
49
|
+
originalCopy.y = item.y;
|
|
50
|
+
return originalCopy;
|
|
41
51
|
}
|
|
42
52
|
else {
|
|
43
53
|
return Object.assign({}, item);
|
|
@@ -234,16 +244,24 @@ function useMemoStateContext(props) {
|
|
|
234
244
|
return null;
|
|
235
245
|
}
|
|
236
246
|
}, [dragProps, props.registerManager]);
|
|
237
|
-
const onDropDragOver = React.useCallback((_e, gridProps, groupLayout) => {
|
|
247
|
+
const onDropDragOver = React.useCallback((_e, gridProps, groupLayout, sharedItem) => {
|
|
238
248
|
if (temporaryLayout) {
|
|
239
249
|
resetTemporaryLayout();
|
|
240
250
|
return false;
|
|
241
251
|
}
|
|
242
|
-
|
|
252
|
+
let defaultLayout;
|
|
253
|
+
if (sharedItem) {
|
|
254
|
+
const { type, h, w } = sharedItem;
|
|
255
|
+
const _defaults = props.registerManager.getItem(type);
|
|
256
|
+
defaultLayout = _defaults ? Object.assign(Object.assign({}, _defaults.defaultLayout), { h, w }) : { h, w };
|
|
257
|
+
}
|
|
258
|
+
else if (dragOverPlugin) {
|
|
259
|
+
defaultLayout = dragOverPlugin.defaultLayout;
|
|
260
|
+
}
|
|
261
|
+
else {
|
|
243
262
|
return false;
|
|
244
263
|
}
|
|
245
264
|
let maxW = gridProps.cols;
|
|
246
|
-
const { defaultLayout } = dragOverPlugin;
|
|
247
265
|
const maxH = Math.min(gridProps.maxRows || Infinity, defaultLayout.maxH || Infinity);
|
|
248
266
|
if (gridProps.compactType === COMPACT_TYPE_HORIZONTAL_NOWRAP) {
|
|
249
267
|
maxW = groupLayout.reduce((memo, item) => memo - item.w, gridProps.cols);
|
|
@@ -254,7 +272,7 @@ function useMemoStateContext(props) {
|
|
|
254
272
|
maxH < defaultLayout.minH) {
|
|
255
273
|
return false;
|
|
256
274
|
}
|
|
257
|
-
const { h = (defaultLayout === null || defaultLayout === void 0 ? void 0 : defaultLayout.h) || DEFAULT_WIDGET_HEIGHT, w = (defaultLayout === null || defaultLayout === void 0 ? void 0 : defaultLayout.w) || DEFAULT_WIDGET_WIDTH, } = dragProps.layout || {};
|
|
275
|
+
const { h = (defaultLayout === null || defaultLayout === void 0 ? void 0 : defaultLayout.h) || DEFAULT_WIDGET_HEIGHT, w = (defaultLayout === null || defaultLayout === void 0 ? void 0 : defaultLayout.w) || DEFAULT_WIDGET_WIDTH, } = (dragProps === null || dragProps === void 0 ? void 0 : dragProps.layout) || {};
|
|
258
276
|
return {
|
|
259
277
|
h: maxH ? Math.min(h, maxH) : h,
|
|
260
278
|
w: maxW ? Math.min(w, maxW) : w,
|