@gravity-ui/dashkit 8.8.1 → 8.9.1-beta.0
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/DashKit/DashKit.d.ts +5 -0
- package/build/cjs/components/GridItem/GridItem.css +1 -0
- package/build/cjs/components/GridItem/GridItem.js +30 -2
- package/build/cjs/components/GridLayout/GridLayout.d.ts +8 -2
- package/build/cjs/components/GridLayout/GridLayout.js +113 -25
- package/build/cjs/components/GridLayout/ReactGridLayout.js +142 -24
- package/build/cjs/components/Item/Item.d.ts +2 -0
- package/build/cjs/components/Item/Item.js +13 -2
- package/build/cjs/hocs/prepareItem.d.ts +2 -0
- package/build/cjs/hocs/prepareItem.js +6 -3
- package/build/cjs/hocs/withContext.js +28 -6
- package/build/cjs/plugins/Text/Text.d.ts +1 -0
- package/build/cjs/plugins/Text/Text.js +2 -0
- package/build/cjs/typings/plugin.d.ts +1 -0
- package/build/esm/components/DashKit/DashKit.d.ts +5 -0
- package/build/esm/components/GridItem/GridItem.css +1 -0
- package/build/esm/components/GridItem/GridItem.js +30 -2
- package/build/esm/components/GridLayout/GridLayout.d.ts +8 -2
- package/build/esm/components/GridLayout/GridLayout.js +113 -25
- package/build/esm/components/GridLayout/ReactGridLayout.js +143 -25
- package/build/esm/components/Item/Item.d.ts +2 -0
- package/build/esm/components/Item/Item.js +13 -2
- package/build/esm/hocs/prepareItem.d.ts +2 -0
- package/build/esm/hocs/prepareItem.js +6 -3
- package/build/esm/hocs/withContext.js +28 -6
- package/build/esm/plugins/Text/Text.d.ts +1 -0
- package/build/esm/plugins/Text/Text.js +2 -0
- package/build/esm/typings/plugin.d.ts +1 -0
- package/package.json +1 -1
|
@@ -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,
|
|
@@ -302,6 +320,8 @@ function useMemoStateContext(props) {
|
|
|
302
320
|
onItemStateAndParamsChange,
|
|
303
321
|
onDrop,
|
|
304
322
|
onDropDragOver,
|
|
323
|
+
onItemMountChange: props.onItemMountChange,
|
|
324
|
+
onItemRender: props.onItemRender,
|
|
305
325
|
layoutChange: onLayoutChange,
|
|
306
326
|
getItemsMeta,
|
|
307
327
|
reloadItems,
|
|
@@ -329,6 +349,8 @@ function useMemoStateContext(props) {
|
|
|
329
349
|
onDrop,
|
|
330
350
|
onDropDragOver,
|
|
331
351
|
onLayoutChange,
|
|
352
|
+
props.onItemMountChange,
|
|
353
|
+
props.onItemRender,
|
|
332
354
|
getItemsMeta,
|
|
333
355
|
reloadItems,
|
|
334
356
|
memorizeOriginalLayout,
|
|
@@ -80,6 +80,7 @@ class PluginText extends react_1.default.PureComponent {
|
|
|
80
80
|
return;
|
|
81
81
|
}
|
|
82
82
|
this.setState({ status: LoadStatus.Pending });
|
|
83
|
+
const onLoadComplete = this.props.onBeforeLoad();
|
|
83
84
|
try {
|
|
84
85
|
let htmlText = '';
|
|
85
86
|
if (this.state.text && this.state.text.trim()) {
|
|
@@ -100,6 +101,7 @@ class PluginText extends react_1.default.PureComponent {
|
|
|
100
101
|
}
|
|
101
102
|
this.setState({ status: LoadStatus.Fail });
|
|
102
103
|
}
|
|
104
|
+
onLoadComplete();
|
|
103
105
|
}
|
|
104
106
|
get withMarkdown() {
|
|
105
107
|
return typeof this.props.apiHandler === 'function';
|
|
@@ -8,6 +8,7 @@ export interface PluginWidgetProps<T = StringParams> {
|
|
|
8
8
|
params: T;
|
|
9
9
|
state: ItemState;
|
|
10
10
|
onStateAndParamsChange: (stateAndParams: ItemStateAndParams, options?: ItemStateAndParamsChangeOptions) => void;
|
|
11
|
+
onBeforeLoad: () => () => void;
|
|
11
12
|
width: number;
|
|
12
13
|
height: number;
|
|
13
14
|
data: ConfigItem['data'];
|
|
@@ -18,6 +18,11 @@ interface DashKitDefaultProps {
|
|
|
18
18
|
groups?: DashKitGroup[];
|
|
19
19
|
}) => void;
|
|
20
20
|
onDrop: (dropProps: ItemDropProps) => void;
|
|
21
|
+
onItemMountChange?: (item: ConfigItem, state: {
|
|
22
|
+
isAsync: boolean;
|
|
23
|
+
isMounted: boolean;
|
|
24
|
+
}) => void;
|
|
25
|
+
onItemRender?: (item: ConfigItem) => void;
|
|
21
26
|
defaultGlobalParams: GlobalParams;
|
|
22
27
|
globalParams: GlobalParams;
|
|
23
28
|
itemsStateAndParams: ItemsStateAndParams;
|
|
@@ -36,6 +36,7 @@ const windowFocusObserver = new WindowFocusObserver();
|
|
|
36
36
|
class GridItem extends React.PureComponent {
|
|
37
37
|
constructor() {
|
|
38
38
|
super(...arguments);
|
|
39
|
+
this._isAsyncItem = false;
|
|
39
40
|
this.state = {
|
|
40
41
|
isFocused: false,
|
|
41
42
|
};
|
|
@@ -54,6 +55,33 @@ class GridItem extends React.PureComponent {
|
|
|
54
55
|
this.controller = null;
|
|
55
56
|
});
|
|
56
57
|
};
|
|
58
|
+
this.onMountChange = (isMounted) => {
|
|
59
|
+
var _a, _b, _c, _d, _e, _f;
|
|
60
|
+
if (isMounted) {
|
|
61
|
+
this._inited = true;
|
|
62
|
+
(_b = (_a = this.props).onItemMountChange) === null || _b === void 0 ? void 0 : _b.call(_a, this.props.item, {
|
|
63
|
+
isAsync: this._isAsyncItem,
|
|
64
|
+
isMounted: isMounted,
|
|
65
|
+
});
|
|
66
|
+
if (!this._isAsyncItem) {
|
|
67
|
+
(_d = (_c = this.props).onItemRender) === null || _d === void 0 ? void 0 : _d.call(_c, this.props.item);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
(_f = (_e = this.props).onItemMountChange) === null || _f === void 0 ? void 0 : _f.call(_e, this.props.item, {
|
|
72
|
+
isAsync: this._isAsyncItem,
|
|
73
|
+
isMounted: isMounted,
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
this.onBeforeLoad = () => {
|
|
78
|
+
this._isAsyncItem = true;
|
|
79
|
+
return this.onLoad;
|
|
80
|
+
};
|
|
81
|
+
this.onLoad = () => {
|
|
82
|
+
var _a, _b;
|
|
83
|
+
(_b = (_a = this.props).onItemRender) === null || _b === void 0 ? void 0 : _b.call(_a, this.props.item);
|
|
84
|
+
};
|
|
57
85
|
}
|
|
58
86
|
renderOverlay() {
|
|
59
87
|
const { isPlaceholder } = this.props;
|
|
@@ -69,7 +97,7 @@ class GridItem extends React.PureComponent {
|
|
|
69
97
|
render() {
|
|
70
98
|
// из-за бага, что Grid Items unmounts при изменении static, isDraggable, isResaizable
|
|
71
99
|
// https://github.com/STRML/react-grid-layout/issues/721
|
|
72
|
-
const { style, onMouseDown, onMouseUp, onTouchEnd, onTouchStart, children, className, isDragging, noOverlay, focusable, withCustomHandle, isPlaceholder, } = this.props;
|
|
100
|
+
const { style, onMouseDown, onMouseUp, onTouchEnd, onTouchStart, children, className, isDragging, noOverlay, focusable, withCustomHandle, isPlaceholder = false, } = this.props;
|
|
73
101
|
const { editMode } = this.context;
|
|
74
102
|
const width = Number.parseInt(style.width, 10);
|
|
75
103
|
const height = Number.parseInt(style.height, 10);
|
|
@@ -94,7 +122,7 @@ class GridItem extends React.PureComponent {
|
|
|
94
122
|
}
|
|
95
123
|
: {})),
|
|
96
124
|
React.createElement("div", { className: b('item', { editMode: editMode && !_editActive && !noOverlay }) },
|
|
97
|
-
React.createElement(Item, { id: this.props.id, item: this.props.item, shouldItemUpdate: !isDragging, width: width, height: height, transform: transform, isPlaceholder: isPlaceholder, adjustWidgetLayout: this.props.adjustWidgetLayout, layout: this.props.layout, forwardedPluginRef: this.props.forwardedPluginRef })),
|
|
125
|
+
React.createElement(Item, { id: this.props.id, item: this.props.item, shouldItemUpdate: !isDragging, width: width, height: height, transform: transform, isPlaceholder: isPlaceholder, adjustWidgetLayout: this.props.adjustWidgetLayout, layout: this.props.layout, forwardedPluginRef: this.props.forwardedPluginRef, onMountChange: this.onMountChange, onBeforeLoad: this.onBeforeLoad })),
|
|
98
126
|
!noOverlay && this.renderOverlay(),
|
|
99
127
|
preparedChildren));
|
|
100
128
|
}
|
|
@@ -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
|
+
_onTargetRestore: () => 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 onDragTargetRestore = this._onTargetRestore.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
|
+
onDragTargetRestore,
|
|
67
68
|
};
|
|
68
69
|
}
|
|
69
70
|
return this._memoCallbacksForGroups[group];
|
|
@@ -90,48 +91,131 @@ 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._onTargetRestore = () => {
|
|
120
|
+
const { currentDraggingElement } = this.state;
|
|
121
|
+
if (currentDraggingElement) {
|
|
122
|
+
this.setState({
|
|
123
|
+
draggedOverGroup: currentDraggingElement[0],
|
|
124
|
+
});
|
|
125
|
+
}
|
|
97
126
|
};
|
|
98
127
|
this._onStop = (group, newLayout) => {
|
|
99
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
|
+
}
|
|
100
137
|
const groupedLayout = this.mergeGroupsLayout(group, newLayout);
|
|
138
|
+
this.setState({
|
|
139
|
+
isDragging: false,
|
|
140
|
+
currentDraggingElement: null,
|
|
141
|
+
draggedOverGroup: null,
|
|
142
|
+
});
|
|
101
143
|
if (temporaryLayout) {
|
|
102
144
|
onDrop === null || onDrop === void 0 ? void 0 : onDrop(groupedLayout, groupedLayout.find(({ i }) => i === TEMPORARY_ITEM_ID));
|
|
103
145
|
}
|
|
104
146
|
else {
|
|
105
147
|
layoutChange(groupedLayout);
|
|
106
148
|
}
|
|
107
|
-
this.setState({ isDragging: false });
|
|
108
149
|
};
|
|
109
|
-
this.
|
|
110
|
-
const {
|
|
111
|
-
|
|
112
|
-
|
|
150
|
+
this._onSharedDrop = (targetGroup, newLayout, tempItem) => {
|
|
151
|
+
const { currentDraggingElement } = this.state;
|
|
152
|
+
const { layoutChange } = this.context;
|
|
153
|
+
if (!currentDraggingElement) {
|
|
154
|
+
return;
|
|
113
155
|
}
|
|
114
|
-
const
|
|
115
|
-
|
|
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 !== 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 !== 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);
|
|
116
184
|
};
|
|
117
185
|
this._onDrop = (group, newLayout, item, e) => {
|
|
118
|
-
if (!item) {
|
|
186
|
+
if (!item || !this.context.editMode) {
|
|
119
187
|
return false;
|
|
120
188
|
}
|
|
121
|
-
const {
|
|
122
|
-
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)) {
|
|
123
201
|
return false;
|
|
124
202
|
}
|
|
125
|
-
|
|
126
|
-
|
|
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 });
|
|
127
207
|
}
|
|
128
|
-
|
|
129
|
-
|
|
208
|
+
if (dragOverPlugin) {
|
|
209
|
+
return onDropDragOver(e, properties, layout);
|
|
210
|
+
}
|
|
211
|
+
return false;
|
|
130
212
|
};
|
|
131
213
|
this.pluginsRefs = [];
|
|
132
214
|
this.state = {
|
|
133
215
|
isDragging: false,
|
|
134
216
|
isPageHidden: false,
|
|
217
|
+
currentDraggingElement: null,
|
|
218
|
+
draggedOverGroup: null,
|
|
135
219
|
};
|
|
136
220
|
}
|
|
137
221
|
componentDidMount() {
|
|
@@ -200,7 +284,8 @@ class GridLayout extends React.PureComponent {
|
|
|
200
284
|
return (React.createElement(GridItem, { key: id, id: id, item: { id, type, data: {} }, layout: temporaryLayout.data, adjustWidgetLayout: this.adjustWidgetLayout, isDragging: this.state.isDragging, isPlaceholder: true, noOverlay: noOverlay, withCustomHandle: Boolean(draggableHandleClassName) }));
|
|
201
285
|
}
|
|
202
286
|
renderGroup(group, renderLayout, renderItems, offset = 0, groupGridProperties) {
|
|
203
|
-
const { registerManager, editMode, noOverlay, focusable, draggableHandleClassName, outerDnDEnable, } = this.context;
|
|
287
|
+
const { registerManager, editMode, noOverlay, focusable, draggableHandleClassName, outerDnDEnable, onItemMountChange, onItemRender, } = this.context;
|
|
288
|
+
const { currentDraggingElement, draggedOverGroup } = this.state;
|
|
204
289
|
const properties = groupGridProperties
|
|
205
290
|
? groupGridProperties(Object.assign({}, registerManager.gridLayout))
|
|
206
291
|
: registerManager.gridLayout;
|
|
@@ -209,17 +294,20 @@ class GridLayout extends React.PureComponent {
|
|
|
209
294
|
compactType = 'horizontal';
|
|
210
295
|
}
|
|
211
296
|
const { callbacks, layout } = this.getMemoGroupProps(group, renderLayout, properties);
|
|
212
|
-
|
|
297
|
+
const hasSharedDragItem = Boolean(currentDraggingElement && currentDraggingElement[0] !== group);
|
|
298
|
+
const isDragCaptured = currentDraggingElement &&
|
|
299
|
+
group === currentDraggingElement[0] &&
|
|
300
|
+
draggedOverGroup !== null &&
|
|
301
|
+
draggedOverGroup !== group;
|
|
302
|
+
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, onDragTargetRestore: callbacks.onDragTargetRestore, onDropDragOver: callbacks.onDropDragOver, onDrop: callbacks.onDrop, hasSharedDragItem: hasSharedDragItem, isDragCaptured: isDragCaptured }, (draggableHandleClassName
|
|
213
303
|
? { draggableHandle: `.${draggableHandleClassName}` }
|
|
214
304
|
: null), (outerDnDEnable
|
|
215
305
|
? {
|
|
216
306
|
isDroppable: true,
|
|
217
|
-
onDropDragOver: callbacks.onDropDragOver,
|
|
218
|
-
onDrop: callbacks.onDrop,
|
|
219
307
|
}
|
|
220
308
|
: null), { draggableCancel: `.${OVERLAY_CONTROLS_CLASS_NAME}` }),
|
|
221
309
|
renderItems.map((item, i) => {
|
|
222
|
-
return (React.createElement(GridItem, { forwardedPluginRef: this.getMemoForwardRefCallback(offset + i), key: item.id, id: item.id, item: item, layout: layout, adjustWidgetLayout: this.adjustWidgetLayout, isDragging: this.state.isDragging, noOverlay: noOverlay, focusable: focusable, withCustomHandle: Boolean(draggableHandleClassName) }));
|
|
310
|
+
return (React.createElement(GridItem, { forwardedPluginRef: this.getMemoForwardRefCallback(offset + i), key: item.id, id: item.id, item: item, layout: layout, adjustWidgetLayout: this.adjustWidgetLayout, isDragging: this.state.isDragging, noOverlay: noOverlay, focusable: focusable, withCustomHandle: Boolean(draggableHandleClassName), onItemMountChange: onItemMountChange, onItemRender: onItemRender }));
|
|
223
311
|
}),
|
|
224
312
|
this.renderTemporaryPlaceholder()));
|
|
225
313
|
}
|
|
@@ -1,62 +1,180 @@
|
|
|
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
4
|
class DragOverLayout extends ReactGridLayout {
|
|
5
5
|
constructor(...args) {
|
|
6
6
|
super(...args);
|
|
7
|
-
this.
|
|
7
|
+
this._savedDraggedOutLayout = null;
|
|
8
|
+
// Reset placeholder when item dragged from outside
|
|
9
|
+
this.resetExternalPlaceholder = () => {
|
|
8
10
|
if (this.dragEnterCounter) {
|
|
9
11
|
this.dragEnterCounter = 0;
|
|
10
12
|
this.removeDroppingPlaceholder();
|
|
11
13
|
}
|
|
12
14
|
};
|
|
15
|
+
// Hide placeholder when element is dragged out
|
|
16
|
+
this.hideLocalPlaceholder = (i) => {
|
|
17
|
+
const { layout } = this.state;
|
|
18
|
+
const { cols } = this.props;
|
|
19
|
+
const savedLayout = layout.map((item) => (Object.assign({}, item)));
|
|
20
|
+
let hiddenElement;
|
|
21
|
+
const newLayout = utils.compact(layout.filter((item) => {
|
|
22
|
+
if (item.i === i) {
|
|
23
|
+
hiddenElement = item;
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
return true;
|
|
27
|
+
}), utils.compactType(this.props), cols);
|
|
28
|
+
if (hiddenElement) {
|
|
29
|
+
newLayout.push(hiddenElement);
|
|
30
|
+
}
|
|
31
|
+
this.setState({
|
|
32
|
+
activeDrag: null,
|
|
33
|
+
layout: newLayout,
|
|
34
|
+
});
|
|
35
|
+
return savedLayout;
|
|
36
|
+
};
|
|
37
|
+
this.extendedOnDrag = (i, x, y, sintEv) => {
|
|
38
|
+
if (this.props.isDragCaptured) {
|
|
39
|
+
if (!this._savedDraggedOutLayout) {
|
|
40
|
+
this._savedDraggedOutLayout = this.hideLocalPlaceholder(i);
|
|
41
|
+
}
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
this._savedDraggedOutLayout = null;
|
|
45
|
+
// parent onDrag will show new placeholder again
|
|
46
|
+
this.parentOnDrag(i, x, y, sintEv);
|
|
47
|
+
};
|
|
48
|
+
this.extendedOnDragStop = (i, x, y, sintEv) => {
|
|
49
|
+
// Restoring layout if item was dropped outside of the grid
|
|
50
|
+
if (this._savedDraggedOutLayout) {
|
|
51
|
+
const savedLayout = this._savedDraggedOutLayout;
|
|
52
|
+
const l = utils.getLayoutItem(savedLayout, i);
|
|
53
|
+
// Create placeholder (display only)
|
|
54
|
+
const placeholder = {
|
|
55
|
+
w: l.w,
|
|
56
|
+
h: l.h,
|
|
57
|
+
x: l.x,
|
|
58
|
+
y: l.y,
|
|
59
|
+
placeholder: true,
|
|
60
|
+
i: i,
|
|
61
|
+
};
|
|
62
|
+
this.setState({
|
|
63
|
+
layout: savedLayout,
|
|
64
|
+
activeDrag: placeholder,
|
|
65
|
+
}, () => {
|
|
66
|
+
this.parentOnDragStop(i, x, y, sintEv);
|
|
67
|
+
});
|
|
68
|
+
this._savedDraggedOutLayout = null;
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
this.parentOnDragStop(i, x, y, sintEv);
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
// Proxy mouse events -> drag methods for dnd between groups
|
|
75
|
+
this.mouseEnterHandler = (e) => {
|
|
76
|
+
var _a, _b;
|
|
77
|
+
if (this.props.hasSharedDragItem) {
|
|
78
|
+
this.onDragEnter(e);
|
|
79
|
+
}
|
|
80
|
+
else if (this.props.isDragCaptured) {
|
|
81
|
+
(_b = (_a = this.props).onDragTargetRestore) === null || _b === void 0 ? void 0 : _b.call(_a);
|
|
82
|
+
}
|
|
83
|
+
};
|
|
13
84
|
this.mouseLeaveHandler = (e) => {
|
|
14
|
-
var _a;
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
rect.left >= e.clientX ||
|
|
19
|
-
rect.right <= e.clientX) {
|
|
20
|
-
this.dragReset();
|
|
85
|
+
var _a, _b;
|
|
86
|
+
if (this.props.hasSharedDragItem) {
|
|
87
|
+
this.onDragLeave(e);
|
|
88
|
+
(_b = (_a = this.props).onDragTargetRestore) === null || _b === void 0 ? void 0 : _b.call(_a);
|
|
21
89
|
}
|
|
22
90
|
};
|
|
23
|
-
this.
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
91
|
+
this.mouseMoveHandler = (e) => {
|
|
92
|
+
if (this.props.hasSharedDragItem) {
|
|
93
|
+
this.onDragOver(e);
|
|
94
|
+
}
|
|
27
95
|
};
|
|
96
|
+
this.mouseUpHandler = (e) => {
|
|
97
|
+
var _a, _b;
|
|
98
|
+
if (this.props.hasSharedDragItem) {
|
|
99
|
+
e.preventDefault();
|
|
100
|
+
const { droppingItem } = this.props;
|
|
101
|
+
const { layout } = this.state;
|
|
102
|
+
const item = layout.find((l) => l.i === droppingItem.i);
|
|
103
|
+
// reset dragEnter counter on drop
|
|
104
|
+
this.resetExternalPlaceholder();
|
|
105
|
+
(_b = (_a = this.props).onDrop) === null || _b === void 0 ? void 0 : _b.call(_a, layout, item, e);
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
this.parentOnDrag = this.onDrag;
|
|
109
|
+
this.onDrag = this.extendedOnDrag;
|
|
110
|
+
this.parentOnDragStop = this.onDragStop;
|
|
111
|
+
this.onDragStop = this.extendedOnDragStop;
|
|
28
112
|
}
|
|
29
113
|
componentDidMount() {
|
|
30
114
|
var _a;
|
|
31
115
|
(_a = super.componentDidMount) === null || _a === void 0 ? void 0 : _a.call(this);
|
|
32
|
-
window
|
|
116
|
+
// If cursor is moved out of the window there is a bug
|
|
117
|
+
// which leaves placeholder element in grid, this action needed to reset this state
|
|
118
|
+
window.addEventListener('dragend', this.resetExternalPlaceholder);
|
|
119
|
+
const innerElement = this.getInnerElement();
|
|
120
|
+
if (innerElement) {
|
|
121
|
+
innerElement.addEventListener('mouseup', this.mouseUpHandler);
|
|
122
|
+
innerElement.addEventListener('mouseenter', this.mouseEnterHandler);
|
|
123
|
+
innerElement.addEventListener('mouseleave', this.mouseLeaveHandler);
|
|
124
|
+
innerElement.addEventListener('mousemove', this.mouseMoveHandler);
|
|
125
|
+
}
|
|
33
126
|
}
|
|
34
127
|
componentWillUnmount() {
|
|
35
|
-
window.removeEventListener('dragend', this.
|
|
128
|
+
window.removeEventListener('dragend', this.resetExternalPlaceholder);
|
|
129
|
+
const innerElement = this.getInnerElement();
|
|
130
|
+
if (innerElement) {
|
|
131
|
+
innerElement.removeEventListener('mouseup', this.mouseUpHandler);
|
|
132
|
+
innerElement.removeEventListener('mouseenter', this.mouseEnterHandler);
|
|
133
|
+
innerElement.removeEventListener('mouseleave', this.mouseLeaveHandler);
|
|
134
|
+
innerElement.removeEventListener('mousemove', this.mouseMoveHandler);
|
|
135
|
+
}
|
|
36
136
|
}
|
|
137
|
+
// react-grid-layout doens't calculate it's height when last element is removed
|
|
138
|
+
// and just keeps the previous value
|
|
139
|
+
// so for autosize to work in that case we are resetting it's height value
|
|
37
140
|
containerHeight() {
|
|
38
141
|
if (this.props.autoSize && this.state.layout.length === 0) {
|
|
39
|
-
return
|
|
142
|
+
return;
|
|
40
143
|
}
|
|
144
|
+
// eslint-disable-next-line consistent-return
|
|
41
145
|
return super.containerHeight();
|
|
42
146
|
}
|
|
147
|
+
// innerRef is passed by WithProvider without this wrapper there are only
|
|
148
|
+
// * findDOMNode - deprecated
|
|
149
|
+
// * rewrite whole ReactGridLayout.render method
|
|
150
|
+
// so in that case don't try to use this class on it's own
|
|
151
|
+
// or pass innerRef: React.MutableRef as it's not optional prop
|
|
152
|
+
getInnerElement() {
|
|
153
|
+
var _a;
|
|
154
|
+
return ((_a = this.props.innerRef) === null || _a === void 0 ? void 0 : _a.current) || null;
|
|
155
|
+
}
|
|
156
|
+
// Drop item from outside gets 0,0 droppingPosition
|
|
157
|
+
// centering cursor on newly creted grid item
|
|
158
|
+
// And cause grid-layout using it's own GridItem to make it look
|
|
159
|
+
// like overlay adding className
|
|
43
160
|
processGridItem(child, isDroppingItem) {
|
|
44
161
|
var _a;
|
|
45
162
|
const gridItem = (_a = super.processGridItem) === null || _a === void 0 ? void 0 : _a.call(this, child, isDroppingItem);
|
|
163
|
+
if (!gridItem) {
|
|
164
|
+
return gridItem;
|
|
165
|
+
}
|
|
166
|
+
const { props: itemProps } = gridItem;
|
|
46
167
|
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;
|
|
168
|
+
const { containerWidth, cols, w, h, rowHeight, margin, transformScale, droppingPosition, } = itemProps;
|
|
55
169
|
const leftOffset = (((containerWidth / cols) * w) / 2 || 0) * transformScale;
|
|
56
170
|
const topOffset = ((h * rowHeight + (h - 1) * margin[1]) / 2 || 0) * transformScale;
|
|
171
|
+
const style = gridItem.props.style || null;
|
|
172
|
+
// React.cloneElement is just cleaner then copy-paste whole processGridItem method
|
|
57
173
|
return React.cloneElement(gridItem, {
|
|
174
|
+
// hiding previre if dragging shared item
|
|
175
|
+
style: this.props.hasSharedDragItem ? Object.assign(Object.assign({}, style), { opacity: 0 }) : style,
|
|
58
176
|
className: OVERLAY_CLASS_NAME,
|
|
59
|
-
droppingPosition: Object.assign(Object.assign({},
|
|
177
|
+
droppingPosition: Object.assign(Object.assign({}, droppingPosition), { left: droppingPosition.left - leftOffset, top: droppingPosition.top - topOffset }),
|
|
60
178
|
});
|
|
61
179
|
}
|
|
62
180
|
return gridItem;
|
|
@@ -61,7 +61,9 @@ declare const _default: {
|
|
|
61
61
|
height: PropTypes.Requireable<number>;
|
|
62
62
|
transform: PropTypes.Requireable<string>;
|
|
63
63
|
isPlaceholder: PropTypes.Requireable<boolean>;
|
|
64
|
+
onBeforeLoad: PropTypes.Requireable<(...args: any[]) => any>;
|
|
64
65
|
forwardedPluginRef: PropTypes.Requireable<any>;
|
|
66
|
+
onMountChange: PropTypes.Requireable<(...args: any[]) => any>;
|
|
65
67
|
};
|
|
66
68
|
contextType: React.Context<any>;
|
|
67
69
|
};
|