@gravity-ui/dashkit 8.17.4 → 8.18.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/README.md +9 -0
- package/build/cjs/components/DashKitDnDWrapper/DashKitDnDWrapper.d.ts +2 -1
- package/build/cjs/components/DashKitDnDWrapper/DashKitDnDWrapper.js +8 -7
- package/build/cjs/components/GridItem/GridItem.css +5 -0
- package/build/cjs/components/GridLayout/GridLayout.d.ts +1 -1
- package/build/cjs/components/GridLayout/GridLayout.js +38 -30
- package/build/cjs/components/GridLayout/ReactGridLayout.js +19 -17
- package/build/cjs/components/OverlayControls/OverlayControls.js +4 -5
- package/build/cjs/constants/common.d.ts +1 -0
- package/build/cjs/constants/common.js +2 -1
- package/build/cjs/hocs/withContext.js +23 -12
- package/build/cjs/shared/types/common.d.ts +4 -0
- package/build/cjs/typings/common.d.ts +4 -1
- package/build/cjs/typings/config.d.ts +2 -1
- package/build/esm/components/DashKitDnDWrapper/DashKitDnDWrapper.d.ts +2 -1
- package/build/esm/components/DashKitDnDWrapper/DashKitDnDWrapper.js +8 -7
- package/build/esm/components/GridItem/GridItem.css +5 -0
- package/build/esm/components/GridLayout/GridLayout.d.ts +1 -1
- package/build/esm/components/GridLayout/GridLayout.js +38 -30
- package/build/esm/components/GridLayout/ReactGridLayout.js +20 -18
- package/build/esm/components/OverlayControls/OverlayControls.js +4 -5
- package/build/esm/constants/common.d.ts +1 -0
- package/build/esm/constants/common.js +1 -0
- package/build/esm/hocs/withContext.js +23 -12
- package/build/esm/shared/types/common.d.ts +4 -0
- package/build/esm/typings/common.d.ts +4 -1
- package/build/esm/typings/config.d.ts +2 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -384,10 +384,19 @@ DashKit.setSettings({menu: [] as Array<MenuItem>});
|
|
|
384
384
|
#### DashKitDnDWrapper
|
|
385
385
|
|
|
386
386
|
```ts
|
|
387
|
+
type DraggedOverItem = {
|
|
388
|
+
h: number;
|
|
389
|
+
w: number;
|
|
390
|
+
type: string;
|
|
391
|
+
parent: string;
|
|
392
|
+
i?: number;
|
|
393
|
+
};
|
|
394
|
+
|
|
387
395
|
interface DashKitDnDWrapperProps {
|
|
388
396
|
dragImageSrc?: string;
|
|
389
397
|
onDragStart?: (dragProps: ItemDragProps) => void;
|
|
390
398
|
onDragEnd?: () => void;
|
|
399
|
+
onDropDragOver?: (draggedItem: DraggedOverItem, sharedItem: DraggedOverItem | null) => void | boolean;
|
|
391
400
|
}
|
|
392
401
|
```
|
|
393
402
|
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import type { ItemDragProps } from '../../shared';
|
|
2
|
+
import type { DraggedOverItem, ItemDragProps } from '../../shared';
|
|
3
3
|
type DashKitDnDWrapperProps = {
|
|
4
4
|
dragImageSrc?: string;
|
|
5
|
+
onDropDragOver?: (draggedItem: DraggedOverItem, sharedItem: DraggedOverItem | null) => void | boolean;
|
|
5
6
|
onDragStart?: (dragProps: ItemDragProps) => void;
|
|
6
7
|
onDragEnd?: () => void;
|
|
7
8
|
children: React.ReactElement;
|
|
@@ -12,24 +12,25 @@ const DashKitDnDWrapper = (props) => {
|
|
|
12
12
|
img.src = props.dragImageSrc || defaultImageSrc;
|
|
13
13
|
return img;
|
|
14
14
|
}, [props.dragImageSrc]);
|
|
15
|
+
const onDragStartProp = props.onDragStart;
|
|
15
16
|
const onDragStart = react_1.default.useCallback((_, itemDragProps) => {
|
|
16
|
-
var _a;
|
|
17
17
|
setDragProps(itemDragProps);
|
|
18
|
-
|
|
19
|
-
}, [setDragProps,
|
|
18
|
+
onDragStartProp === null || onDragStartProp === void 0 ? void 0 : onDragStartProp(itemDragProps);
|
|
19
|
+
}, [setDragProps, onDragStartProp]);
|
|
20
|
+
const onDragEndProp = props.onDragEnd;
|
|
20
21
|
const onDragEnd = react_1.default.useCallback((_) => {
|
|
21
|
-
var _a;
|
|
22
22
|
setDragProps(null);
|
|
23
|
-
|
|
24
|
-
}, [setDragProps,
|
|
23
|
+
onDragEndProp === null || onDragEndProp === void 0 ? void 0 : onDragEndProp();
|
|
24
|
+
}, [setDragProps, onDragEndProp]);
|
|
25
25
|
const contextValue = react_1.default.useMemo(() => {
|
|
26
26
|
return {
|
|
27
27
|
dragProps,
|
|
28
28
|
dragImagePreview,
|
|
29
29
|
onDragStart,
|
|
30
30
|
onDragEnd,
|
|
31
|
+
onDropDragOver: props.onDropDragOver,
|
|
31
32
|
};
|
|
32
|
-
}, [dragProps, dragImagePreview, onDragStart, onDragEnd]);
|
|
33
|
+
}, [dragProps, dragImagePreview, onDragStart, onDragEnd, props.onDropDragOver]);
|
|
33
34
|
return (react_1.default.createElement(DashKitContext_1.DashKitDnDContext.Provider, { value: contextValue }, props.children));
|
|
34
35
|
};
|
|
35
36
|
exports.DashKitDnDWrapper = DashKitDnDWrapper;
|
|
@@ -4,10 +4,10 @@ export default class GridLayout extends React.PureComponent<any, any, any> {
|
|
|
4
4
|
pluginsRefs: any[];
|
|
5
5
|
state: {
|
|
6
6
|
isDragging: boolean;
|
|
7
|
+
isDraggedOut: boolean;
|
|
7
8
|
isPageHidden: boolean;
|
|
8
9
|
currentDraggingElement: null;
|
|
9
10
|
draggedOverGroup: null;
|
|
10
|
-
draggedOut: boolean;
|
|
11
11
|
};
|
|
12
12
|
componentDidMount(): void;
|
|
13
13
|
componentDidUpdate(): void;
|
|
@@ -142,20 +142,27 @@ class GridLayout extends react_1.default.PureComponent {
|
|
|
142
142
|
if (currentDraggingElement) {
|
|
143
143
|
const { h, w, i } = currentDraggingElement.layoutItem;
|
|
144
144
|
const { type } = currentDraggingElement.item;
|
|
145
|
-
|
|
145
|
+
const sharedItem = {
|
|
146
|
+
h,
|
|
147
|
+
w,
|
|
148
|
+
i,
|
|
149
|
+
type,
|
|
150
|
+
parent: currentDraggingElement.group,
|
|
151
|
+
};
|
|
152
|
+
return onDropDragOver(e, group, properties, layout, sharedItem);
|
|
146
153
|
}
|
|
147
154
|
if (dragOverPlugin) {
|
|
148
|
-
return onDropDragOver(e, properties, layout);
|
|
155
|
+
return onDropDragOver(e, group, properties, layout);
|
|
149
156
|
}
|
|
150
157
|
return false;
|
|
151
158
|
};
|
|
152
159
|
this.pluginsRefs = [];
|
|
153
160
|
this.state = {
|
|
154
161
|
isDragging: false,
|
|
162
|
+
isDraggedOut: false,
|
|
155
163
|
isPageHidden: false,
|
|
156
164
|
currentDraggingElement: null,
|
|
157
165
|
draggedOverGroup: null,
|
|
158
|
-
draggedOut: false,
|
|
159
166
|
};
|
|
160
167
|
}
|
|
161
168
|
componentDidMount() {
|
|
@@ -291,7 +298,7 @@ class GridLayout extends react_1.default.PureComponent {
|
|
|
291
298
|
_initDragCoordinatesWatcher(element) {
|
|
292
299
|
if (!this._parendDragNode) {
|
|
293
300
|
this._parendDragNode = element.parentElement;
|
|
294
|
-
this.setState({
|
|
301
|
+
this.setState({ isDraggedOut: false });
|
|
295
302
|
}
|
|
296
303
|
}
|
|
297
304
|
// When element is going back and prointer-event: none is removed mouse enter event is not fired
|
|
@@ -317,19 +324,19 @@ class GridLayout extends react_1.default.PureComponent {
|
|
|
317
324
|
const parent = this._parendDragNode;
|
|
318
325
|
const parentRect = parent.getBoundingClientRect();
|
|
319
326
|
const { clientX, clientY } = e;
|
|
320
|
-
let
|
|
327
|
+
let isDraggedOut = this.state.isDraggedOut;
|
|
321
328
|
if (clientX < parentRect.left ||
|
|
322
329
|
clientX > parentRect.right ||
|
|
323
330
|
clientY < parentRect.top ||
|
|
324
331
|
clientY > parentRect.bottom) {
|
|
325
|
-
|
|
332
|
+
isDraggedOut = true;
|
|
326
333
|
}
|
|
327
334
|
else {
|
|
328
|
-
|
|
335
|
+
isDraggedOut = false;
|
|
329
336
|
}
|
|
330
|
-
if (
|
|
331
|
-
this.setState({
|
|
332
|
-
if (!
|
|
337
|
+
if (isDraggedOut !== this.state.isDraggedOut) {
|
|
338
|
+
this.setState({ isDraggedOut });
|
|
339
|
+
if (!isDraggedOut) {
|
|
333
340
|
this._forceCursorCapture(parent, {
|
|
334
341
|
top: clientY - parentRect.top,
|
|
335
342
|
left: clientX - parentRect.left,
|
|
@@ -339,23 +346,25 @@ class GridLayout extends react_1.default.PureComponent {
|
|
|
339
346
|
}
|
|
340
347
|
_resetDragWatcher() {
|
|
341
348
|
this._parendDragNode = null;
|
|
342
|
-
this.setState({
|
|
349
|
+
this.setState({ isDraggedOut: false });
|
|
343
350
|
}
|
|
344
351
|
_onDragStart(group, _newLayout, layoutItem, _newItem, _placeholder, e, element) {
|
|
345
352
|
var _a;
|
|
346
353
|
(_a = this.context.onDragStart) === null || _a === void 0 ? void 0 : _a.call(this, this.prepareDefaultArguments(group, _newLayout, layoutItem, _newItem, _placeholder, e, element));
|
|
347
|
-
this._initDragCoordinatesWatcher(element);
|
|
348
354
|
if (this.context.dragOverPlugin) {
|
|
349
355
|
this.setState({ isDragging: true });
|
|
350
356
|
}
|
|
351
357
|
else {
|
|
358
|
+
this._initDragCoordinatesWatcher(element);
|
|
352
359
|
this.updateDraggingElementState(group, layoutItem, e);
|
|
353
360
|
this.setState({ isDragging: true });
|
|
354
361
|
}
|
|
355
362
|
}
|
|
356
363
|
_onDrag(group, layout, oldItem, newItem, placeholder, e, element) {
|
|
357
364
|
var _a;
|
|
358
|
-
this.
|
|
365
|
+
if (!this.context.dragOverPlugin) {
|
|
366
|
+
this._updateDragCoordinates(e);
|
|
367
|
+
}
|
|
359
368
|
(_a = this.context.onDrag) === null || _a === void 0 ? void 0 : _a.call(this, this.prepareDefaultArguments(group, layout, oldItem, newItem, placeholder, e, element));
|
|
360
369
|
}
|
|
361
370
|
_onDragStop(group, layout, oldItem, newItem, placeholder, e, element) {
|
|
@@ -403,7 +412,8 @@ class GridLayout extends react_1.default.PureComponent {
|
|
|
403
412
|
renderGroup(group, renderLayout, renderItems, offset = 0, groupGridProperties) {
|
|
404
413
|
const { registerManager, editMode, noOverlay, focusable, draggableHandleClassName, outerDnDEnable, onItemMountChange, onItemRender, } = this.context;
|
|
405
414
|
const { currentDraggingElement, draggedOverGroup } = this.state;
|
|
406
|
-
const
|
|
415
|
+
const hasOwnGroupProperties = typeof groupGridProperties === 'function';
|
|
416
|
+
const properties = hasOwnGroupProperties
|
|
407
417
|
? groupGridProperties(Object.assign({}, registerManager.gridLayout))
|
|
408
418
|
: registerManager.gridLayout;
|
|
409
419
|
let { compactType } = properties;
|
|
@@ -416,25 +426,22 @@ class GridLayout extends react_1.default.PureComponent {
|
|
|
416
426
|
group === currentDraggingElement.group &&
|
|
417
427
|
draggedOverGroup !== null &&
|
|
418
428
|
draggedOverGroup !== group;
|
|
419
|
-
return (react_1.default.createElement(ReactGridLayout_1.Layout
|
|
420
|
-
// Group properties
|
|
421
|
-
, Object.assign({}, properties, {
|
|
429
|
+
return (react_1.default.createElement(ReactGridLayout_1.Layout, Object.assign({ isDraggable: editMode, isResizable: editMode }, properties, { key: `group_${group}`,
|
|
422
430
|
// Layout props
|
|
423
|
-
compactType: compactType, layout: layout,
|
|
424
|
-
? { draggableHandle: `.${draggableHandleClassName}` }
|
|
425
|
-
: null), {
|
|
431
|
+
compactType: compactType, layout: layout, draggableCancel: `.${constants_1.DRAGGABLE_CANCEL_CLASS_NAME}`, draggableHandle: draggableHandleClassName ? `.${draggableHandleClassName}` : null,
|
|
426
432
|
// Default callbacks
|
|
427
433
|
onDragStart: callbacks.onDragStart, onDrag: callbacks.onDrag, onDragStop: callbacks.onDragStop, onResizeStart: callbacks.onResizeStart, onResize: callbacks.onResize, onResizeStop: callbacks.onResizeStop,
|
|
428
434
|
// External Drag N Drop options
|
|
429
|
-
onDragTargetRestore: callbacks.onDragTargetRestore, onDropDragOver: callbacks.onDropDragOver, onDrop: callbacks.onDrop, hasSharedDragItem: hasSharedDragItem, sharedDragPosition: currentDraggingElement === null || currentDraggingElement === void 0 ? void 0 : currentDraggingElement.cursorPosition, isDragCaptured: isDragCaptured
|
|
430
|
-
? {
|
|
431
|
-
isDroppable: true,
|
|
432
|
-
}
|
|
433
|
-
: null)),
|
|
435
|
+
onDragTargetRestore: callbacks.onDragTargetRestore, onDropDragOver: callbacks.onDropDragOver, onDrop: callbacks.onDrop, hasSharedDragItem: hasSharedDragItem, sharedDragPosition: currentDraggingElement === null || currentDraggingElement === void 0 ? void 0 : currentDraggingElement.cursorPosition, isDragCaptured: isDragCaptured, isDroppable: Boolean(outerDnDEnable) && editMode }),
|
|
434
436
|
renderItems.map((item, i) => {
|
|
435
|
-
const
|
|
436
|
-
const
|
|
437
|
-
|
|
437
|
+
const keyId = item.id;
|
|
438
|
+
const isDragging = this.state.isDragging;
|
|
439
|
+
const isCurrentDraggedItem = (currentDraggingElement === null || currentDraggingElement === void 0 ? void 0 : currentDraggingElement.item.id) === keyId;
|
|
440
|
+
const isDraggedOut = isCurrentDraggedItem && this.state.isDraggedOut;
|
|
441
|
+
const itemNoOverlay = hasOwnGroupProperties && 'noOverlay' in properties
|
|
442
|
+
? properties.noOverlay
|
|
443
|
+
: noOverlay;
|
|
444
|
+
return (react_1.default.createElement(GridItem_1.default, { forwardedPluginRef: this.getMemoForwardRefCallback(offset + i), key: keyId, id: keyId, item: item, layout: layout, adjustWidgetLayout: this.adjustWidgetLayout, isDragging: isDragging, isDraggedOut: isDraggedOut, noOverlay: itemNoOverlay, focusable: focusable, withCustomHandle: Boolean(draggableHandleClassName), onItemMountChange: onItemMountChange, onItemRender: onItemRender }));
|
|
438
445
|
}),
|
|
439
446
|
this.renderTemporaryPlaceholder()));
|
|
440
447
|
}
|
|
@@ -486,13 +493,14 @@ class GridLayout extends react_1.default.PureComponent {
|
|
|
486
493
|
const element = this.renderGroup(id, layout, items, offset, group.gridProperties);
|
|
487
494
|
offset += items.length;
|
|
488
495
|
if (group.render) {
|
|
489
|
-
|
|
496
|
+
const groupContext = {
|
|
490
497
|
config,
|
|
491
498
|
editMode,
|
|
492
499
|
items,
|
|
493
500
|
layout,
|
|
494
501
|
context,
|
|
495
|
-
}
|
|
502
|
+
};
|
|
503
|
+
return group.render(id, element, groupContext);
|
|
496
504
|
}
|
|
497
505
|
return element;
|
|
498
506
|
});
|
|
@@ -157,6 +157,20 @@ class DragOverLayout extends react_grid_layout_1.default {
|
|
|
157
157
|
var _a;
|
|
158
158
|
return ((_a = this.props.innerRef) === null || _a === void 0 ? void 0 : _a.current) || null;
|
|
159
159
|
}
|
|
160
|
+
calculateDroppingPosition(itemProps) {
|
|
161
|
+
const { containerWidth, cols, w, h, rowHeight, margin, transformScale, droppingPosition } = itemProps;
|
|
162
|
+
const { sharedDragPosition } = this.props;
|
|
163
|
+
let offsetX, offsetY;
|
|
164
|
+
if (sharedDragPosition) {
|
|
165
|
+
offsetX = sharedDragPosition.offsetX;
|
|
166
|
+
offsetY = sharedDragPosition.offsetY;
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
offsetX = (((containerWidth / cols) * w) / 2 || 0) * transformScale;
|
|
170
|
+
offsetY = ((h * rowHeight + (h - 1) * margin[1]) / 2 || 0) * transformScale;
|
|
171
|
+
}
|
|
172
|
+
return Object.assign(Object.assign({}, droppingPosition), { left: droppingPosition.left - offsetX, top: droppingPosition.top - offsetY });
|
|
173
|
+
}
|
|
160
174
|
// Drop item from outside gets 0,0 droppingPosition
|
|
161
175
|
// centering cursor on newly creted grid item
|
|
162
176
|
// And cause grid-layout using it's own GridItem to make it look
|
|
@@ -167,26 +181,14 @@ class DragOverLayout extends react_grid_layout_1.default {
|
|
|
167
181
|
if (!gridItem) {
|
|
168
182
|
return gridItem;
|
|
169
183
|
}
|
|
170
|
-
const { props: itemProps } = gridItem;
|
|
171
184
|
if (isDroppingItem) {
|
|
172
|
-
const { containerWidth, cols, w, h, rowHeight, margin, transformScale, droppingPosition, } = itemProps;
|
|
173
|
-
const { sharedDragPosition, hasSharedDragItem } = this.props;
|
|
174
|
-
let offsetX, offsetY;
|
|
175
|
-
if (sharedDragPosition) {
|
|
176
|
-
offsetX = sharedDragPosition.offsetX;
|
|
177
|
-
offsetY = sharedDragPosition.offsetY;
|
|
178
|
-
}
|
|
179
|
-
else {
|
|
180
|
-
offsetX = (((containerWidth / cols) * w) / 2 || 0) * transformScale;
|
|
181
|
-
offsetY = ((h * rowHeight + (h - 1) * margin[1]) / 2 || 0) * transformScale;
|
|
182
|
-
}
|
|
183
|
-
const style = gridItem.props.style || null;
|
|
184
185
|
// React.cloneElement is just cleaner then copy-paste whole processGridItem method
|
|
185
186
|
return react_1.default.cloneElement(gridItem, {
|
|
186
|
-
// hiding
|
|
187
|
-
style:
|
|
188
|
-
|
|
189
|
-
|
|
187
|
+
// hiding preview if dragging shared item
|
|
188
|
+
style: this.props.hasSharedDragItem
|
|
189
|
+
? Object.assign(Object.assign({}, gridItem.props.style), { opacity: 0 }) : gridItem.props.style,
|
|
190
|
+
className: `${constants_1.OVERLAY_CLASS_NAME} ${constants_1.DROPPING_ELEMENT_CLASS_NAME}`,
|
|
191
|
+
droppingPosition: this.calculateDroppingPosition(gridItem.props),
|
|
190
192
|
});
|
|
191
193
|
}
|
|
192
194
|
return gridItem;
|
|
@@ -32,7 +32,7 @@ class OverlayControls extends react_1.default.Component {
|
|
|
32
32
|
const { view, size, onItemClick } = this.props;
|
|
33
33
|
const { title, handler, icon, iconSize, qa } = item;
|
|
34
34
|
const onItemClickHandler = typeof handler === 'function' ? handler : noop_1.default;
|
|
35
|
-
return (react_1.default.createElement(uikit_1.Button, { key: index
|
|
35
|
+
return (react_1.default.createElement(uikit_1.Button, { key: `control_${index}`, view: view, size: size, title: title, pin: this.getControlItemPinStyle(index, length), onClick: () => {
|
|
36
36
|
onItemClickHandler(this.props.configItem);
|
|
37
37
|
onItemClick === null || onItemClick === void 0 ? void 0 : onItemClick();
|
|
38
38
|
}, qa: qa },
|
|
@@ -43,7 +43,7 @@ class OverlayControls extends react_1.default.Component {
|
|
|
43
43
|
if (this.context.overlayControls === null) {
|
|
44
44
|
return null;
|
|
45
45
|
}
|
|
46
|
-
return (react_1.default.createElement(uikit_1.Button, { view: view, size: size, title: (0, i18n_1.i18n)('label_settings'), pin: "round-brick", onClick: this.onEditItem, qa: "dashkit-overlay-control-settings" },
|
|
46
|
+
return (react_1.default.createElement(uikit_1.Button, { key: 'control_default', view: view, size: size, title: (0, i18n_1.i18n)('label_settings'), pin: "round-brick", onClick: this.onEditItem, qa: "dashkit-overlay-control-settings" },
|
|
47
47
|
react_1.default.createElement(uikit_1.Icon, { data: icons_1.Gear, size: constants_1.OVERLAY_ICON_SIZE })));
|
|
48
48
|
};
|
|
49
49
|
this.getCustomLeftOverlayControls = () => {
|
|
@@ -161,10 +161,9 @@ class OverlayControls extends react_1.default.Component {
|
|
|
161
161
|
renderControls() {
|
|
162
162
|
const customLeftControls = this.getCustomLeftOverlayControls();
|
|
163
163
|
const hasCustomOverlayLeftControls = Boolean(customLeftControls.length);
|
|
164
|
-
const defaultControl = this.getDefaultControls();
|
|
165
164
|
const controls = hasCustomOverlayLeftControls
|
|
166
165
|
? customLeftControls.map((item, index, items) => this.renderControlsItem(item, index, items.length + 1))
|
|
167
|
-
:
|
|
166
|
+
: this.getDefaultControls();
|
|
168
167
|
const menu = this.renderMenu(controls === null);
|
|
169
168
|
return (react_1.default.createElement("div", { className: b('default-controls', {
|
|
170
169
|
'with-custom-left': hasCustomOverlayLeftControls,
|
|
@@ -231,7 +230,7 @@ class OverlayControls extends react_1.default.Component {
|
|
|
231
230
|
if (items.length === 0) {
|
|
232
231
|
return null;
|
|
233
232
|
}
|
|
234
|
-
return (react_1.default.createElement(uikit_1.DropdownMenu, { items: items, renderSwitcher: (props) => (react_1.default.createElement(uikit_1.Button, Object.assign({}, props, { view: view, size: size, pin: isOnlyOneItem ? 'round-round' : 'brick-round', qa: "dashkit-overlay-control-menu" }),
|
|
233
|
+
return (react_1.default.createElement(uikit_1.DropdownMenu, { key: 'controls_dropdown', items: items, renderSwitcher: (props) => (react_1.default.createElement(uikit_1.Button, Object.assign({}, props, { view: view, size: size, pin: isOnlyOneItem ? 'round-round' : 'brick-round', qa: "dashkit-overlay-control-menu" }),
|
|
235
234
|
react_1.default.createElement(uikit_1.Icon, { data: icons_1.Ellipsis, size: constants_1.OVERLAY_ICON_SIZE }))), popupProps: {
|
|
236
235
|
contentClassName: constants_1.DRAGGABLE_CANCEL_CLASS_NAME,
|
|
237
236
|
} }));
|
|
@@ -15,3 +15,4 @@ export declare const DEFAULT_GROUP = "__default";
|
|
|
15
15
|
export declare const COMPACT_TYPE_HORIZONTAL_NOWRAP = "horizontal-nowrap";
|
|
16
16
|
export declare const DRAGGABLE_CANCEL_CLASS_NAME = "dashkit_draggable_cancel";
|
|
17
17
|
export declare const FOCUSED_CLASS_NAME = "dashkit_focused";
|
|
18
|
+
export declare const DROPPING_ELEMENT_CLASS_NAME = "dropping";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.FOCUSED_CLASS_NAME = exports.DRAGGABLE_CANCEL_CLASS_NAME = exports.COMPACT_TYPE_HORIZONTAL_NOWRAP = exports.DEFAULT_GROUP = exports.DEFAULT_WIDGET_WIDTH = exports.DEFAULT_WIDGET_HEIGHT = exports.MenuItems = exports.TEMPORARY_ITEM_ID = exports.OVERLAY_ICON_SIZE = exports.OVERLAY_CLASS_NAME = exports.OVERLAY_CONTROLS_CLASS_NAME = exports.DEFAULT_NAMESPACE = exports.COPIED_WIDGET_STORE_KEY = void 0;
|
|
3
|
+
exports.DROPPING_ELEMENT_CLASS_NAME = exports.FOCUSED_CLASS_NAME = exports.DRAGGABLE_CANCEL_CLASS_NAME = exports.COMPACT_TYPE_HORIZONTAL_NOWRAP = exports.DEFAULT_GROUP = exports.DEFAULT_WIDGET_WIDTH = exports.DEFAULT_WIDGET_HEIGHT = exports.MenuItems = exports.TEMPORARY_ITEM_ID = exports.OVERLAY_ICON_SIZE = exports.OVERLAY_CLASS_NAME = exports.OVERLAY_CONTROLS_CLASS_NAME = exports.DEFAULT_NAMESPACE = exports.COPIED_WIDGET_STORE_KEY = void 0;
|
|
4
4
|
exports.COPIED_WIDGET_STORE_KEY = 'dashCopiedItem';
|
|
5
5
|
exports.DEFAULT_NAMESPACE = 'default';
|
|
6
6
|
exports.OVERLAY_CONTROLS_CLASS_NAME = 'dashkit-overlay-controls';
|
|
@@ -18,3 +18,4 @@ exports.DEFAULT_GROUP = '__default';
|
|
|
18
18
|
exports.COMPACT_TYPE_HORIZONTAL_NOWRAP = 'horizontal-nowrap';
|
|
19
19
|
exports.DRAGGABLE_CANCEL_CLASS_NAME = 'dashkit_draggable_cancel';
|
|
20
20
|
exports.FOCUSED_CLASS_NAME = 'dashkit_focused';
|
|
21
|
+
exports.DROPPING_ELEMENT_CLASS_NAME = 'dropping';
|
|
@@ -232,12 +232,13 @@ function useMemoStateContext(props) {
|
|
|
232
232
|
const reloadItems = react_1.default.useCallback((pluginsRefs, data) => {
|
|
233
233
|
pluginsRefs.forEach((ref) => ref && ref.reload && ref.reload(data));
|
|
234
234
|
}, []);
|
|
235
|
-
const
|
|
235
|
+
const dragPropsContext = dndContext === null || dndContext === void 0 ? void 0 : dndContext.dragProps;
|
|
236
|
+
const onDropDragOverContext = dndContext === null || dndContext === void 0 ? void 0 : dndContext.onDropDragOver;
|
|
236
237
|
const dragOverPlugin = react_1.default.useMemo(() => {
|
|
237
|
-
if (!
|
|
238
|
+
if (!dragPropsContext) {
|
|
238
239
|
return null;
|
|
239
240
|
}
|
|
240
|
-
const pluginType =
|
|
241
|
+
const pluginType = dragPropsContext.type;
|
|
241
242
|
if (props.registerManager.check(pluginType)) {
|
|
242
243
|
return props.registerManager.getItem(pluginType);
|
|
243
244
|
}
|
|
@@ -246,8 +247,8 @@ function useMemoStateContext(props) {
|
|
|
246
247
|
console.error(`Uknown pluginType: ${pluginType}`);
|
|
247
248
|
return null;
|
|
248
249
|
}
|
|
249
|
-
}, [
|
|
250
|
-
const onDropDragOver = react_1.default.useCallback((_e, gridProps, groupLayout, sharedItem) => {
|
|
250
|
+
}, [dragPropsContext, props.registerManager]);
|
|
251
|
+
const onDropDragOver = react_1.default.useCallback((_e, group, gridProps, groupLayout, sharedItem) => {
|
|
251
252
|
if (temporaryLayout) {
|
|
252
253
|
resetTemporaryLayout();
|
|
253
254
|
return false;
|
|
@@ -275,20 +276,30 @@ function useMemoStateContext(props) {
|
|
|
275
276
|
maxH < defaultLayout.minH) {
|
|
276
277
|
return false;
|
|
277
278
|
}
|
|
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, } = (
|
|
279
|
-
|
|
279
|
+
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, } = (dragPropsContext === null || dragPropsContext === void 0 ? void 0 : dragPropsContext.layout) || {};
|
|
280
|
+
const itemLayout = {
|
|
280
281
|
h: maxH ? Math.min(h, maxH) : h,
|
|
281
282
|
w: maxW ? Math.min(w, maxW) : w,
|
|
282
283
|
};
|
|
283
|
-
|
|
284
|
+
if ((onDropDragOverContext === null || onDropDragOverContext === void 0 ? void 0 : onDropDragOverContext(Object.assign(Object.assign(Object.assign({}, sharedItem), itemLayout), { parent: group }), sharedItem !== null && sharedItem !== void 0 ? sharedItem : null)) === false) {
|
|
285
|
+
return false;
|
|
286
|
+
}
|
|
287
|
+
return itemLayout;
|
|
288
|
+
}, [
|
|
289
|
+
resetTemporaryLayout,
|
|
290
|
+
temporaryLayout,
|
|
291
|
+
dragOverPlugin,
|
|
292
|
+
dragPropsContext,
|
|
293
|
+
onDropDragOverContext,
|
|
294
|
+
]);
|
|
284
295
|
const onDropProp = props.onDrop;
|
|
285
296
|
const onDrop = react_1.default.useCallback((newLayout, item) => {
|
|
286
|
-
if (!
|
|
297
|
+
if (!dragPropsContext) {
|
|
287
298
|
return;
|
|
288
299
|
}
|
|
289
300
|
setTemporaryLayout({
|
|
290
301
|
data: [...newLayout, item],
|
|
291
|
-
dragProps,
|
|
302
|
+
dragProps: dragPropsContext,
|
|
292
303
|
});
|
|
293
304
|
onDropProp({
|
|
294
305
|
newLayout: newLayout.reduce((memo, l) => {
|
|
@@ -299,9 +310,9 @@ function useMemoStateContext(props) {
|
|
|
299
310
|
}, []),
|
|
300
311
|
itemLayout: (0, pick_1.default)(item, ITEM_PROPS),
|
|
301
312
|
commit: resetTemporaryLayout,
|
|
302
|
-
dragProps,
|
|
313
|
+
dragProps: dragPropsContext,
|
|
303
314
|
});
|
|
304
|
-
}, [
|
|
315
|
+
}, [dragPropsContext, onDropProp, setTemporaryLayout, resetTemporaryLayout]);
|
|
305
316
|
const dashkitContextValue = react_1.default.useMemo(() => ({
|
|
306
317
|
layout: resultLayout,
|
|
307
318
|
temporaryLayout,
|
|
@@ -12,6 +12,10 @@ export type ItemDragProps = {
|
|
|
12
12
|
};
|
|
13
13
|
extra?: any;
|
|
14
14
|
};
|
|
15
|
+
export type DraggedOverItem = Omit<ConfigLayout, 'x' | 'y' | 'i'> & {
|
|
16
|
+
type: string;
|
|
17
|
+
i?: ConfigLayout['i'];
|
|
18
|
+
};
|
|
15
19
|
export type ItemDropProps = {
|
|
16
20
|
commit: () => void;
|
|
17
21
|
dragProps: ItemDragProps;
|
|
@@ -2,8 +2,11 @@ import type ReactGridLayout from 'react-grid-layout';
|
|
|
2
2
|
import type { OverlayCustomControlItem } from '../components/OverlayControls/OverlayControls';
|
|
3
3
|
import { MenuItems } from '../constants';
|
|
4
4
|
import { AdditionalWidgetLayout } from '../shared';
|
|
5
|
+
export type GridLayoutSettings = ReactGridLayout.ReactGridLayoutProps & {
|
|
6
|
+
noOverlay?: boolean;
|
|
7
|
+
};
|
|
5
8
|
export interface Settings {
|
|
6
|
-
gridLayout?:
|
|
9
|
+
gridLayout?: GridLayoutSettings;
|
|
7
10
|
theme?: string;
|
|
8
11
|
isMobile?: boolean;
|
|
9
12
|
menu?: Array<MenuItem>;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
2
|
import type { Layout, Layouts } from 'react-grid-layout';
|
|
3
3
|
import type { Config, ConfigItem, ConfigLayout } from '../shared';
|
|
4
|
+
import { GridLayoutSettings } from './common';
|
|
4
5
|
export interface AddConfigItem extends Omit<ConfigItem, 'id' | 'namespace'> {
|
|
5
6
|
id?: null;
|
|
6
7
|
namespace?: string;
|
|
@@ -31,7 +32,7 @@ export interface DashkitGroupRenderProps {
|
|
|
31
32
|
layout: ConfigLayout[];
|
|
32
33
|
context: any;
|
|
33
34
|
}
|
|
34
|
-
export type ReactGridLayoutProps = Omit<
|
|
35
|
+
export type ReactGridLayoutProps = Omit<GridLayoutSettings, 'children' | 'compactType' | 'innerRef' | 'key' | 'layout' | 'onDragStart' | 'onDragStop' | 'onResizeStart' | 'onResizeStop' | 'draggableHandle' | 'isDroppable' | 'onDropDragOver' | 'onDrop' | 'draggableCancel'> & {
|
|
35
36
|
compactType?: CompactType;
|
|
36
37
|
};
|
|
37
38
|
export interface DashKitGroup {
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import type { ItemDragProps } from '../../shared';
|
|
2
|
+
import type { DraggedOverItem, ItemDragProps } from '../../shared';
|
|
3
3
|
type DashKitDnDWrapperProps = {
|
|
4
4
|
dragImageSrc?: string;
|
|
5
|
+
onDropDragOver?: (draggedItem: DraggedOverItem, sharedItem: DraggedOverItem | null) => void | boolean;
|
|
5
6
|
onDragStart?: (dragProps: ItemDragProps) => void;
|
|
6
7
|
onDragEnd?: () => void;
|
|
7
8
|
children: React.ReactElement;
|
|
@@ -8,23 +8,24 @@ export const DashKitDnDWrapper = (props) => {
|
|
|
8
8
|
img.src = props.dragImageSrc || defaultImageSrc;
|
|
9
9
|
return img;
|
|
10
10
|
}, [props.dragImageSrc]);
|
|
11
|
+
const onDragStartProp = props.onDragStart;
|
|
11
12
|
const onDragStart = React.useCallback((_, itemDragProps) => {
|
|
12
|
-
var _a;
|
|
13
13
|
setDragProps(itemDragProps);
|
|
14
|
-
|
|
15
|
-
}, [setDragProps,
|
|
14
|
+
onDragStartProp === null || onDragStartProp === void 0 ? void 0 : onDragStartProp(itemDragProps);
|
|
15
|
+
}, [setDragProps, onDragStartProp]);
|
|
16
|
+
const onDragEndProp = props.onDragEnd;
|
|
16
17
|
const onDragEnd = React.useCallback((_) => {
|
|
17
|
-
var _a;
|
|
18
18
|
setDragProps(null);
|
|
19
|
-
|
|
20
|
-
}, [setDragProps,
|
|
19
|
+
onDragEndProp === null || onDragEndProp === void 0 ? void 0 : onDragEndProp();
|
|
20
|
+
}, [setDragProps, onDragEndProp]);
|
|
21
21
|
const contextValue = React.useMemo(() => {
|
|
22
22
|
return {
|
|
23
23
|
dragProps,
|
|
24
24
|
dragImagePreview,
|
|
25
25
|
onDragStart,
|
|
26
26
|
onDragEnd,
|
|
27
|
+
onDropDragOver: props.onDropDragOver,
|
|
27
28
|
};
|
|
28
|
-
}, [dragProps, dragImagePreview, onDragStart, onDragEnd]);
|
|
29
|
+
}, [dragProps, dragImagePreview, onDragStart, onDragEnd, props.onDropDragOver]);
|
|
29
30
|
return (React.createElement(DashKitDnDContext.Provider, { value: contextValue }, props.children));
|
|
30
31
|
};
|
|
@@ -4,10 +4,10 @@ export default class GridLayout extends React.PureComponent<any, any, any> {
|
|
|
4
4
|
pluginsRefs: any[];
|
|
5
5
|
state: {
|
|
6
6
|
isDragging: boolean;
|
|
7
|
+
isDraggedOut: boolean;
|
|
7
8
|
isPageHidden: boolean;
|
|
8
9
|
currentDraggingElement: null;
|
|
9
10
|
draggedOverGroup: null;
|
|
10
|
-
draggedOut: boolean;
|
|
11
11
|
};
|
|
12
12
|
componentDidMount(): void;
|
|
13
13
|
componentDidUpdate(): void;
|
|
@@ -139,20 +139,27 @@ class GridLayout extends React.PureComponent {
|
|
|
139
139
|
if (currentDraggingElement) {
|
|
140
140
|
const { h, w, i } = currentDraggingElement.layoutItem;
|
|
141
141
|
const { type } = currentDraggingElement.item;
|
|
142
|
-
|
|
142
|
+
const sharedItem = {
|
|
143
|
+
h,
|
|
144
|
+
w,
|
|
145
|
+
i,
|
|
146
|
+
type,
|
|
147
|
+
parent: currentDraggingElement.group,
|
|
148
|
+
};
|
|
149
|
+
return onDropDragOver(e, group, properties, layout, sharedItem);
|
|
143
150
|
}
|
|
144
151
|
if (dragOverPlugin) {
|
|
145
|
-
return onDropDragOver(e, properties, layout);
|
|
152
|
+
return onDropDragOver(e, group, properties, layout);
|
|
146
153
|
}
|
|
147
154
|
return false;
|
|
148
155
|
};
|
|
149
156
|
this.pluginsRefs = [];
|
|
150
157
|
this.state = {
|
|
151
158
|
isDragging: false,
|
|
159
|
+
isDraggedOut: false,
|
|
152
160
|
isPageHidden: false,
|
|
153
161
|
currentDraggingElement: null,
|
|
154
162
|
draggedOverGroup: null,
|
|
155
|
-
draggedOut: false,
|
|
156
163
|
};
|
|
157
164
|
}
|
|
158
165
|
componentDidMount() {
|
|
@@ -288,7 +295,7 @@ class GridLayout extends React.PureComponent {
|
|
|
288
295
|
_initDragCoordinatesWatcher(element) {
|
|
289
296
|
if (!this._parendDragNode) {
|
|
290
297
|
this._parendDragNode = element.parentElement;
|
|
291
|
-
this.setState({
|
|
298
|
+
this.setState({ isDraggedOut: false });
|
|
292
299
|
}
|
|
293
300
|
}
|
|
294
301
|
// When element is going back and prointer-event: none is removed mouse enter event is not fired
|
|
@@ -314,19 +321,19 @@ class GridLayout extends React.PureComponent {
|
|
|
314
321
|
const parent = this._parendDragNode;
|
|
315
322
|
const parentRect = parent.getBoundingClientRect();
|
|
316
323
|
const { clientX, clientY } = e;
|
|
317
|
-
let
|
|
324
|
+
let isDraggedOut = this.state.isDraggedOut;
|
|
318
325
|
if (clientX < parentRect.left ||
|
|
319
326
|
clientX > parentRect.right ||
|
|
320
327
|
clientY < parentRect.top ||
|
|
321
328
|
clientY > parentRect.bottom) {
|
|
322
|
-
|
|
329
|
+
isDraggedOut = true;
|
|
323
330
|
}
|
|
324
331
|
else {
|
|
325
|
-
|
|
332
|
+
isDraggedOut = false;
|
|
326
333
|
}
|
|
327
|
-
if (
|
|
328
|
-
this.setState({
|
|
329
|
-
if (!
|
|
334
|
+
if (isDraggedOut !== this.state.isDraggedOut) {
|
|
335
|
+
this.setState({ isDraggedOut });
|
|
336
|
+
if (!isDraggedOut) {
|
|
330
337
|
this._forceCursorCapture(parent, {
|
|
331
338
|
top: clientY - parentRect.top,
|
|
332
339
|
left: clientX - parentRect.left,
|
|
@@ -336,23 +343,25 @@ class GridLayout extends React.PureComponent {
|
|
|
336
343
|
}
|
|
337
344
|
_resetDragWatcher() {
|
|
338
345
|
this._parendDragNode = null;
|
|
339
|
-
this.setState({
|
|
346
|
+
this.setState({ isDraggedOut: false });
|
|
340
347
|
}
|
|
341
348
|
_onDragStart(group, _newLayout, layoutItem, _newItem, _placeholder, e, element) {
|
|
342
349
|
var _a;
|
|
343
350
|
(_a = this.context.onDragStart) === null || _a === void 0 ? void 0 : _a.call(this, this.prepareDefaultArguments(group, _newLayout, layoutItem, _newItem, _placeholder, e, element));
|
|
344
|
-
this._initDragCoordinatesWatcher(element);
|
|
345
351
|
if (this.context.dragOverPlugin) {
|
|
346
352
|
this.setState({ isDragging: true });
|
|
347
353
|
}
|
|
348
354
|
else {
|
|
355
|
+
this._initDragCoordinatesWatcher(element);
|
|
349
356
|
this.updateDraggingElementState(group, layoutItem, e);
|
|
350
357
|
this.setState({ isDragging: true });
|
|
351
358
|
}
|
|
352
359
|
}
|
|
353
360
|
_onDrag(group, layout, oldItem, newItem, placeholder, e, element) {
|
|
354
361
|
var _a;
|
|
355
|
-
this.
|
|
362
|
+
if (!this.context.dragOverPlugin) {
|
|
363
|
+
this._updateDragCoordinates(e);
|
|
364
|
+
}
|
|
356
365
|
(_a = this.context.onDrag) === null || _a === void 0 ? void 0 : _a.call(this, this.prepareDefaultArguments(group, layout, oldItem, newItem, placeholder, e, element));
|
|
357
366
|
}
|
|
358
367
|
_onDragStop(group, layout, oldItem, newItem, placeholder, e, element) {
|
|
@@ -400,7 +409,8 @@ class GridLayout extends React.PureComponent {
|
|
|
400
409
|
renderGroup(group, renderLayout, renderItems, offset = 0, groupGridProperties) {
|
|
401
410
|
const { registerManager, editMode, noOverlay, focusable, draggableHandleClassName, outerDnDEnable, onItemMountChange, onItemRender, } = this.context;
|
|
402
411
|
const { currentDraggingElement, draggedOverGroup } = this.state;
|
|
403
|
-
const
|
|
412
|
+
const hasOwnGroupProperties = typeof groupGridProperties === 'function';
|
|
413
|
+
const properties = hasOwnGroupProperties
|
|
404
414
|
? groupGridProperties(Object.assign({}, registerManager.gridLayout))
|
|
405
415
|
: registerManager.gridLayout;
|
|
406
416
|
let { compactType } = properties;
|
|
@@ -413,25 +423,22 @@ class GridLayout extends React.PureComponent {
|
|
|
413
423
|
group === currentDraggingElement.group &&
|
|
414
424
|
draggedOverGroup !== null &&
|
|
415
425
|
draggedOverGroup !== group;
|
|
416
|
-
return (React.createElement(Layout
|
|
417
|
-
// Group properties
|
|
418
|
-
, Object.assign({}, properties, {
|
|
426
|
+
return (React.createElement(Layout, Object.assign({ isDraggable: editMode, isResizable: editMode }, properties, { key: `group_${group}`,
|
|
419
427
|
// Layout props
|
|
420
|
-
compactType: compactType, layout: layout,
|
|
421
|
-
? { draggableHandle: `.${draggableHandleClassName}` }
|
|
422
|
-
: null), {
|
|
428
|
+
compactType: compactType, layout: layout, draggableCancel: `.${DRAGGABLE_CANCEL_CLASS_NAME}`, draggableHandle: draggableHandleClassName ? `.${draggableHandleClassName}` : null,
|
|
423
429
|
// Default callbacks
|
|
424
430
|
onDragStart: callbacks.onDragStart, onDrag: callbacks.onDrag, onDragStop: callbacks.onDragStop, onResizeStart: callbacks.onResizeStart, onResize: callbacks.onResize, onResizeStop: callbacks.onResizeStop,
|
|
425
431
|
// External Drag N Drop options
|
|
426
|
-
onDragTargetRestore: callbacks.onDragTargetRestore, onDropDragOver: callbacks.onDropDragOver, onDrop: callbacks.onDrop, hasSharedDragItem: hasSharedDragItem, sharedDragPosition: currentDraggingElement === null || currentDraggingElement === void 0 ? void 0 : currentDraggingElement.cursorPosition, isDragCaptured: isDragCaptured
|
|
427
|
-
? {
|
|
428
|
-
isDroppable: true,
|
|
429
|
-
}
|
|
430
|
-
: null)),
|
|
432
|
+
onDragTargetRestore: callbacks.onDragTargetRestore, onDropDragOver: callbacks.onDropDragOver, onDrop: callbacks.onDrop, hasSharedDragItem: hasSharedDragItem, sharedDragPosition: currentDraggingElement === null || currentDraggingElement === void 0 ? void 0 : currentDraggingElement.cursorPosition, isDragCaptured: isDragCaptured, isDroppable: Boolean(outerDnDEnable) && editMode }),
|
|
431
433
|
renderItems.map((item, i) => {
|
|
432
|
-
const
|
|
433
|
-
const
|
|
434
|
-
|
|
434
|
+
const keyId = item.id;
|
|
435
|
+
const isDragging = this.state.isDragging;
|
|
436
|
+
const isCurrentDraggedItem = (currentDraggingElement === null || currentDraggingElement === void 0 ? void 0 : currentDraggingElement.item.id) === keyId;
|
|
437
|
+
const isDraggedOut = isCurrentDraggedItem && this.state.isDraggedOut;
|
|
438
|
+
const itemNoOverlay = hasOwnGroupProperties && 'noOverlay' in properties
|
|
439
|
+
? properties.noOverlay
|
|
440
|
+
: noOverlay;
|
|
441
|
+
return (React.createElement(GridItem, { forwardedPluginRef: this.getMemoForwardRefCallback(offset + i), key: keyId, id: keyId, item: item, layout: layout, adjustWidgetLayout: this.adjustWidgetLayout, isDragging: isDragging, isDraggedOut: isDraggedOut, noOverlay: itemNoOverlay, focusable: focusable, withCustomHandle: Boolean(draggableHandleClassName), onItemMountChange: onItemMountChange, onItemRender: onItemRender }));
|
|
435
442
|
}),
|
|
436
443
|
this.renderTemporaryPlaceholder()));
|
|
437
444
|
}
|
|
@@ -483,13 +490,14 @@ class GridLayout extends React.PureComponent {
|
|
|
483
490
|
const element = this.renderGroup(id, layout, items, offset, group.gridProperties);
|
|
484
491
|
offset += items.length;
|
|
485
492
|
if (group.render) {
|
|
486
|
-
|
|
493
|
+
const groupContext = {
|
|
487
494
|
config,
|
|
488
495
|
editMode,
|
|
489
496
|
items,
|
|
490
497
|
layout,
|
|
491
498
|
context,
|
|
492
|
-
}
|
|
499
|
+
};
|
|
500
|
+
return group.render(id, element, groupContext);
|
|
493
501
|
}
|
|
494
502
|
return element;
|
|
495
503
|
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import ReactGridLayout, { WidthProvider, utils } from 'react-grid-layout';
|
|
3
|
-
import { OVERLAY_CLASS_NAME } from '../../constants';
|
|
3
|
+
import { DROPPING_ELEMENT_CLASS_NAME, OVERLAY_CLASS_NAME } from '../../constants';
|
|
4
4
|
class DragOverLayout extends ReactGridLayout {
|
|
5
5
|
constructor(...args) {
|
|
6
6
|
super(...args);
|
|
@@ -153,6 +153,20 @@ class DragOverLayout extends ReactGridLayout {
|
|
|
153
153
|
var _a;
|
|
154
154
|
return ((_a = this.props.innerRef) === null || _a === void 0 ? void 0 : _a.current) || null;
|
|
155
155
|
}
|
|
156
|
+
calculateDroppingPosition(itemProps) {
|
|
157
|
+
const { containerWidth, cols, w, h, rowHeight, margin, transformScale, droppingPosition } = itemProps;
|
|
158
|
+
const { sharedDragPosition } = this.props;
|
|
159
|
+
let offsetX, offsetY;
|
|
160
|
+
if (sharedDragPosition) {
|
|
161
|
+
offsetX = sharedDragPosition.offsetX;
|
|
162
|
+
offsetY = sharedDragPosition.offsetY;
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
offsetX = (((containerWidth / cols) * w) / 2 || 0) * transformScale;
|
|
166
|
+
offsetY = ((h * rowHeight + (h - 1) * margin[1]) / 2 || 0) * transformScale;
|
|
167
|
+
}
|
|
168
|
+
return Object.assign(Object.assign({}, droppingPosition), { left: droppingPosition.left - offsetX, top: droppingPosition.top - offsetY });
|
|
169
|
+
}
|
|
156
170
|
// Drop item from outside gets 0,0 droppingPosition
|
|
157
171
|
// centering cursor on newly creted grid item
|
|
158
172
|
// And cause grid-layout using it's own GridItem to make it look
|
|
@@ -163,26 +177,14 @@ class DragOverLayout extends ReactGridLayout {
|
|
|
163
177
|
if (!gridItem) {
|
|
164
178
|
return gridItem;
|
|
165
179
|
}
|
|
166
|
-
const { props: itemProps } = gridItem;
|
|
167
180
|
if (isDroppingItem) {
|
|
168
|
-
const { containerWidth, cols, w, h, rowHeight, margin, transformScale, droppingPosition, } = itemProps;
|
|
169
|
-
const { sharedDragPosition, hasSharedDragItem } = this.props;
|
|
170
|
-
let offsetX, offsetY;
|
|
171
|
-
if (sharedDragPosition) {
|
|
172
|
-
offsetX = sharedDragPosition.offsetX;
|
|
173
|
-
offsetY = sharedDragPosition.offsetY;
|
|
174
|
-
}
|
|
175
|
-
else {
|
|
176
|
-
offsetX = (((containerWidth / cols) * w) / 2 || 0) * transformScale;
|
|
177
|
-
offsetY = ((h * rowHeight + (h - 1) * margin[1]) / 2 || 0) * transformScale;
|
|
178
|
-
}
|
|
179
|
-
const style = gridItem.props.style || null;
|
|
180
181
|
// React.cloneElement is just cleaner then copy-paste whole processGridItem method
|
|
181
182
|
return React.cloneElement(gridItem, {
|
|
182
|
-
// hiding
|
|
183
|
-
style:
|
|
184
|
-
|
|
185
|
-
|
|
183
|
+
// hiding preview if dragging shared item
|
|
184
|
+
style: this.props.hasSharedDragItem
|
|
185
|
+
? Object.assign(Object.assign({}, gridItem.props.style), { opacity: 0 }) : gridItem.props.style,
|
|
186
|
+
className: `${OVERLAY_CLASS_NAME} ${DROPPING_ELEMENT_CLASS_NAME}`,
|
|
187
|
+
droppingPosition: this.calculateDroppingPosition(gridItem.props),
|
|
186
188
|
});
|
|
187
189
|
}
|
|
188
190
|
return gridItem;
|
|
@@ -29,7 +29,7 @@ class OverlayControls extends React.Component {
|
|
|
29
29
|
const { view, size, onItemClick } = this.props;
|
|
30
30
|
const { title, handler, icon, iconSize, qa } = item;
|
|
31
31
|
const onItemClickHandler = typeof handler === 'function' ? handler : noop;
|
|
32
|
-
return (React.createElement(Button, { key: index
|
|
32
|
+
return (React.createElement(Button, { key: `control_${index}`, view: view, size: size, title: title, pin: this.getControlItemPinStyle(index, length), onClick: () => {
|
|
33
33
|
onItemClickHandler(this.props.configItem);
|
|
34
34
|
onItemClick === null || onItemClick === void 0 ? void 0 : onItemClick();
|
|
35
35
|
}, qa: qa },
|
|
@@ -40,7 +40,7 @@ class OverlayControls extends React.Component {
|
|
|
40
40
|
if (this.context.overlayControls === null) {
|
|
41
41
|
return null;
|
|
42
42
|
}
|
|
43
|
-
return (React.createElement(Button, { view: view, size: size, title: i18n('label_settings'), pin: "round-brick", onClick: this.onEditItem, qa: "dashkit-overlay-control-settings" },
|
|
43
|
+
return (React.createElement(Button, { key: 'control_default', view: view, size: size, title: i18n('label_settings'), pin: "round-brick", onClick: this.onEditItem, qa: "dashkit-overlay-control-settings" },
|
|
44
44
|
React.createElement(Icon, { data: Gear, size: OVERLAY_ICON_SIZE })));
|
|
45
45
|
};
|
|
46
46
|
this.getCustomLeftOverlayControls = () => {
|
|
@@ -158,10 +158,9 @@ class OverlayControls extends React.Component {
|
|
|
158
158
|
renderControls() {
|
|
159
159
|
const customLeftControls = this.getCustomLeftOverlayControls();
|
|
160
160
|
const hasCustomOverlayLeftControls = Boolean(customLeftControls.length);
|
|
161
|
-
const defaultControl = this.getDefaultControls();
|
|
162
161
|
const controls = hasCustomOverlayLeftControls
|
|
163
162
|
? customLeftControls.map((item, index, items) => this.renderControlsItem(item, index, items.length + 1))
|
|
164
|
-
:
|
|
163
|
+
: this.getDefaultControls();
|
|
165
164
|
const menu = this.renderMenu(controls === null);
|
|
166
165
|
return (React.createElement("div", { className: b('default-controls', {
|
|
167
166
|
'with-custom-left': hasCustomOverlayLeftControls,
|
|
@@ -228,7 +227,7 @@ class OverlayControls extends React.Component {
|
|
|
228
227
|
if (items.length === 0) {
|
|
229
228
|
return null;
|
|
230
229
|
}
|
|
231
|
-
return (React.createElement(DropdownMenu, { items: items, renderSwitcher: (props) => (React.createElement(Button, Object.assign({}, props, { view: view, size: size, pin: isOnlyOneItem ? 'round-round' : 'brick-round', qa: "dashkit-overlay-control-menu" }),
|
|
230
|
+
return (React.createElement(DropdownMenu, { key: 'controls_dropdown', items: items, renderSwitcher: (props) => (React.createElement(Button, Object.assign({}, props, { view: view, size: size, pin: isOnlyOneItem ? 'round-round' : 'brick-round', qa: "dashkit-overlay-control-menu" }),
|
|
232
231
|
React.createElement(Icon, { data: Ellipsis, size: OVERLAY_ICON_SIZE }))), popupProps: {
|
|
233
232
|
contentClassName: DRAGGABLE_CANCEL_CLASS_NAME,
|
|
234
233
|
} }));
|
|
@@ -15,3 +15,4 @@ export declare const DEFAULT_GROUP = "__default";
|
|
|
15
15
|
export declare const COMPACT_TYPE_HORIZONTAL_NOWRAP = "horizontal-nowrap";
|
|
16
16
|
export declare const DRAGGABLE_CANCEL_CLASS_NAME = "dashkit_draggable_cancel";
|
|
17
17
|
export declare const FOCUSED_CLASS_NAME = "dashkit_focused";
|
|
18
|
+
export declare const DROPPING_ELEMENT_CLASS_NAME = "dropping";
|
|
@@ -15,3 +15,4 @@ export const DEFAULT_GROUP = '__default';
|
|
|
15
15
|
export const COMPACT_TYPE_HORIZONTAL_NOWRAP = 'horizontal-nowrap';
|
|
16
16
|
export const DRAGGABLE_CANCEL_CLASS_NAME = 'dashkit_draggable_cancel';
|
|
17
17
|
export const FOCUSED_CLASS_NAME = 'dashkit_focused';
|
|
18
|
+
export const DROPPING_ELEMENT_CLASS_NAME = 'dropping';
|
|
@@ -229,12 +229,13 @@ function useMemoStateContext(props) {
|
|
|
229
229
|
const reloadItems = React.useCallback((pluginsRefs, data) => {
|
|
230
230
|
pluginsRefs.forEach((ref) => ref && ref.reload && ref.reload(data));
|
|
231
231
|
}, []);
|
|
232
|
-
const
|
|
232
|
+
const dragPropsContext = dndContext === null || dndContext === void 0 ? void 0 : dndContext.dragProps;
|
|
233
|
+
const onDropDragOverContext = dndContext === null || dndContext === void 0 ? void 0 : dndContext.onDropDragOver;
|
|
233
234
|
const dragOverPlugin = React.useMemo(() => {
|
|
234
|
-
if (!
|
|
235
|
+
if (!dragPropsContext) {
|
|
235
236
|
return null;
|
|
236
237
|
}
|
|
237
|
-
const pluginType =
|
|
238
|
+
const pluginType = dragPropsContext.type;
|
|
238
239
|
if (props.registerManager.check(pluginType)) {
|
|
239
240
|
return props.registerManager.getItem(pluginType);
|
|
240
241
|
}
|
|
@@ -243,8 +244,8 @@ function useMemoStateContext(props) {
|
|
|
243
244
|
console.error(`Uknown pluginType: ${pluginType}`);
|
|
244
245
|
return null;
|
|
245
246
|
}
|
|
246
|
-
}, [
|
|
247
|
-
const onDropDragOver = React.useCallback((_e, gridProps, groupLayout, sharedItem) => {
|
|
247
|
+
}, [dragPropsContext, props.registerManager]);
|
|
248
|
+
const onDropDragOver = React.useCallback((_e, group, gridProps, groupLayout, sharedItem) => {
|
|
248
249
|
if (temporaryLayout) {
|
|
249
250
|
resetTemporaryLayout();
|
|
250
251
|
return false;
|
|
@@ -272,20 +273,30 @@ function useMemoStateContext(props) {
|
|
|
272
273
|
maxH < defaultLayout.minH) {
|
|
273
274
|
return false;
|
|
274
275
|
}
|
|
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, } = (
|
|
276
|
-
|
|
276
|
+
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, } = (dragPropsContext === null || dragPropsContext === void 0 ? void 0 : dragPropsContext.layout) || {};
|
|
277
|
+
const itemLayout = {
|
|
277
278
|
h: maxH ? Math.min(h, maxH) : h,
|
|
278
279
|
w: maxW ? Math.min(w, maxW) : w,
|
|
279
280
|
};
|
|
280
|
-
|
|
281
|
+
if ((onDropDragOverContext === null || onDropDragOverContext === void 0 ? void 0 : onDropDragOverContext(Object.assign(Object.assign(Object.assign({}, sharedItem), itemLayout), { parent: group }), sharedItem !== null && sharedItem !== void 0 ? sharedItem : null)) === false) {
|
|
282
|
+
return false;
|
|
283
|
+
}
|
|
284
|
+
return itemLayout;
|
|
285
|
+
}, [
|
|
286
|
+
resetTemporaryLayout,
|
|
287
|
+
temporaryLayout,
|
|
288
|
+
dragOverPlugin,
|
|
289
|
+
dragPropsContext,
|
|
290
|
+
onDropDragOverContext,
|
|
291
|
+
]);
|
|
281
292
|
const onDropProp = props.onDrop;
|
|
282
293
|
const onDrop = React.useCallback((newLayout, item) => {
|
|
283
|
-
if (!
|
|
294
|
+
if (!dragPropsContext) {
|
|
284
295
|
return;
|
|
285
296
|
}
|
|
286
297
|
setTemporaryLayout({
|
|
287
298
|
data: [...newLayout, item],
|
|
288
|
-
dragProps,
|
|
299
|
+
dragProps: dragPropsContext,
|
|
289
300
|
});
|
|
290
301
|
onDropProp({
|
|
291
302
|
newLayout: newLayout.reduce((memo, l) => {
|
|
@@ -296,9 +307,9 @@ function useMemoStateContext(props) {
|
|
|
296
307
|
}, []),
|
|
297
308
|
itemLayout: pick(item, ITEM_PROPS),
|
|
298
309
|
commit: resetTemporaryLayout,
|
|
299
|
-
dragProps,
|
|
310
|
+
dragProps: dragPropsContext,
|
|
300
311
|
});
|
|
301
|
-
}, [
|
|
312
|
+
}, [dragPropsContext, onDropProp, setTemporaryLayout, resetTemporaryLayout]);
|
|
302
313
|
const dashkitContextValue = React.useMemo(() => ({
|
|
303
314
|
layout: resultLayout,
|
|
304
315
|
temporaryLayout,
|
|
@@ -12,6 +12,10 @@ export type ItemDragProps = {
|
|
|
12
12
|
};
|
|
13
13
|
extra?: any;
|
|
14
14
|
};
|
|
15
|
+
export type DraggedOverItem = Omit<ConfigLayout, 'x' | 'y' | 'i'> & {
|
|
16
|
+
type: string;
|
|
17
|
+
i?: ConfigLayout['i'];
|
|
18
|
+
};
|
|
15
19
|
export type ItemDropProps = {
|
|
16
20
|
commit: () => void;
|
|
17
21
|
dragProps: ItemDragProps;
|
|
@@ -2,8 +2,11 @@ import type ReactGridLayout from 'react-grid-layout';
|
|
|
2
2
|
import type { OverlayCustomControlItem } from '../components/OverlayControls/OverlayControls';
|
|
3
3
|
import { MenuItems } from '../constants';
|
|
4
4
|
import { AdditionalWidgetLayout } from '../shared';
|
|
5
|
+
export type GridLayoutSettings = ReactGridLayout.ReactGridLayoutProps & {
|
|
6
|
+
noOverlay?: boolean;
|
|
7
|
+
};
|
|
5
8
|
export interface Settings {
|
|
6
|
-
gridLayout?:
|
|
9
|
+
gridLayout?: GridLayoutSettings;
|
|
7
10
|
theme?: string;
|
|
8
11
|
isMobile?: boolean;
|
|
9
12
|
menu?: Array<MenuItem>;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
2
|
import type { Layout, Layouts } from 'react-grid-layout';
|
|
3
3
|
import type { Config, ConfigItem, ConfigLayout } from '../shared';
|
|
4
|
+
import { GridLayoutSettings } from './common';
|
|
4
5
|
export interface AddConfigItem extends Omit<ConfigItem, 'id' | 'namespace'> {
|
|
5
6
|
id?: null;
|
|
6
7
|
namespace?: string;
|
|
@@ -31,7 +32,7 @@ export interface DashkitGroupRenderProps {
|
|
|
31
32
|
layout: ConfigLayout[];
|
|
32
33
|
context: any;
|
|
33
34
|
}
|
|
34
|
-
export type ReactGridLayoutProps = Omit<
|
|
35
|
+
export type ReactGridLayoutProps = Omit<GridLayoutSettings, 'children' | 'compactType' | 'innerRef' | 'key' | 'layout' | 'onDragStart' | 'onDragStop' | 'onResizeStart' | 'onResizeStop' | 'draggableHandle' | 'isDroppable' | 'onDropDragOver' | 'onDrop' | 'draggableCancel'> & {
|
|
35
36
|
compactType?: CompactType;
|
|
36
37
|
};
|
|
37
38
|
export interface DashKitGroup {
|