@gravity-ui/dashkit 8.1.0-beta.4 → 8.1.0-beta.5
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/ActionPanel/ActionPanel.js +3 -18
- package/build/cjs/components/ActionPanel/types.d.ts +3 -3
- package/build/cjs/components/DashKit/DashKit.d.ts +2 -2
- package/build/cjs/components/DashKitDnDWrapper/DashKitDnDWrapper.d.ts +1 -0
- package/build/cjs/components/DashKitDnDWrapper/DashKitDnDWrapper.js +8 -1
- package/build/cjs/components/GridLayout/GridLayout.js +2 -41
- package/build/cjs/components/GridLayout/ReactGridLayout.d.ts +3 -0
- package/build/cjs/components/GridLayout/ReactGridLayout.js +49 -0
- package/build/cjs/components/OverlayControls/OverlayControls.js +2 -2
- package/build/cjs/constants/common.d.ts +2 -0
- package/build/cjs/constants/common.js +3 -1
- package/build/cjs/hocs/withContext.js +2 -4
- package/build/cjs/hooks/useDnDItemProps.d.ts +10 -0
- package/build/cjs/hooks/useDnDItemProps.js +30 -0
- package/build/cjs/shared/types/common.d.ts +7 -0
- package/build/cjs/shared/types/config.d.ts +0 -5
- package/build/esm/components/ActionPanel/ActionPanel.js +3 -18
- package/build/esm/components/ActionPanel/types.d.ts +3 -3
- package/build/esm/components/DashKit/DashKit.d.ts +2 -2
- package/build/esm/components/DashKitDnDWrapper/DashKitDnDWrapper.d.ts +1 -0
- package/build/esm/components/DashKitDnDWrapper/DashKitDnDWrapper.js +8 -1
- package/build/esm/components/GridLayout/GridLayout.js +2 -41
- package/build/esm/components/GridLayout/ReactGridLayout.d.ts +3 -0
- package/build/esm/components/GridLayout/ReactGridLayout.js +45 -0
- package/build/esm/components/OverlayControls/OverlayControls.js +2 -2
- package/build/esm/constants/common.d.ts +2 -0
- package/build/esm/constants/common.js +2 -0
- package/build/esm/hocs/withContext.js +3 -5
- package/build/esm/hooks/useDnDItemProps.d.ts +10 -0
- package/build/esm/hooks/useDnDItemProps.js +25 -0
- package/build/esm/shared/types/common.d.ts +7 -0
- package/build/esm/shared/types/config.d.ts +0 -5
- package/package.json +1 -1
|
@@ -4,27 +4,12 @@ exports.ActionPanel = exports.ActionPanelItemContainer = void 0;
|
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const react_1 = tslib_1.__importDefault(require("react"));
|
|
6
6
|
const react_transition_group_1 = require("react-transition-group");
|
|
7
|
-
const
|
|
7
|
+
const useDnDItemProps_1 = require("../../hooks/useDnDItemProps");
|
|
8
8
|
const cn_1 = require("../../utils/cn");
|
|
9
9
|
const b = (0, cn_1.cn)('dashkit-action-panel');
|
|
10
10
|
const ActionPanelItemContainer = ({ item }) => {
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
dragContext === null || dragContext === void 0 ? void 0 : dragContext.onDragStart(e, item.dragProps);
|
|
14
|
-
}, [dragContext === null || dragContext === void 0 ? void 0 : dragContext.onDragStart, item.dragProps]);
|
|
15
|
-
const onDragEnd = react_1.default.useCallback((e) => {
|
|
16
|
-
dragContext === null || dragContext === void 0 ? void 0 : dragContext.onDragEnd(e);
|
|
17
|
-
}, [dragContext === null || dragContext === void 0 ? void 0 : dragContext.onDragEnd]);
|
|
18
|
-
let dndProps = {};
|
|
19
|
-
if (item.dragProps) {
|
|
20
|
-
dndProps = {
|
|
21
|
-
draggable: true,
|
|
22
|
-
unselectable: 'on',
|
|
23
|
-
onDragStart,
|
|
24
|
-
onDragEnd,
|
|
25
|
-
};
|
|
26
|
-
}
|
|
27
|
-
return (react_1.default.createElement("div", Object.assign({ role: "button", className: b('item', item.className), key: `dk-action-panel-${item.id}`, onClick: item.onClick, "data-qa": item.qa }, dndProps),
|
|
11
|
+
const dndProps = (0, useDnDItemProps_1.useDnDItemProps)(item);
|
|
12
|
+
return (react_1.default.createElement("div", Object.assign({ role: "button", className: b('item', { draggable: Boolean(dndProps) }, item.className), key: `dk-action-panel-${item.id}`, onClick: item.onClick, "data-qa": item.qa }, dndProps),
|
|
28
13
|
react_1.default.createElement("div", { className: b('icon') }, item.icon),
|
|
29
14
|
react_1.default.createElement("div", { className: b('title'), title: item.title }, item.title)));
|
|
30
15
|
};
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import type {
|
|
2
|
+
import type { ItemDragProps } from '../../shared';
|
|
3
3
|
export type ActionPanelItem = {
|
|
4
4
|
id: string;
|
|
5
5
|
icon: React.ReactNode;
|
|
6
6
|
title: string;
|
|
7
|
-
onClick?: () => void;
|
|
8
7
|
className?: string;
|
|
9
8
|
qa?: string;
|
|
10
|
-
|
|
9
|
+
onClick?: () => void;
|
|
10
|
+
dragProps?: ItemDragProps;
|
|
11
11
|
};
|
|
12
12
|
export type ActionPanelProps = {
|
|
13
13
|
items: ActionPanelItem[];
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import type { Config, ConfigItem, ConfigLayout,
|
|
2
|
+
import type { Config, ConfigItem, ConfigLayout, GlobalParams, ItemDragProps, ItemsStateAndParams } from '../../shared';
|
|
3
3
|
import { ContextProps, Plugin, SetConfigItem, SetNewItemOptions, Settings, SettingsProps } from '../../typings';
|
|
4
4
|
import GridLayout from '../GridLayout/GridLayout';
|
|
5
5
|
import { OverlayControlItem } from '../OverlayControls/OverlayControls';
|
|
@@ -17,7 +17,7 @@ interface DashKitDefaultProps {
|
|
|
17
17
|
}) => void;
|
|
18
18
|
onDrop: (dropProps: {
|
|
19
19
|
commit: () => void;
|
|
20
|
-
dragProps:
|
|
20
|
+
dragProps: ItemDragProps;
|
|
21
21
|
itemLayout: ConfigLayout;
|
|
22
22
|
newLayout: ConfigLayout[];
|
|
23
23
|
}) => void;
|
|
@@ -4,8 +4,14 @@ exports.DashKitDnDWrapper = void 0;
|
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const react_1 = tslib_1.__importDefault(require("react"));
|
|
6
6
|
const DashKitContext_1 = require("../../context/DashKitContext");
|
|
7
|
+
const defaultImageSrc = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=';
|
|
7
8
|
const DashKitDnDWrapper = (props) => {
|
|
8
9
|
const [dragProps, setDragProps] = react_1.default.useState(null);
|
|
10
|
+
const dragImagePreview = react_1.default.useMemo(() => {
|
|
11
|
+
const img = new Image(1, 1);
|
|
12
|
+
img.src = props.dragImageSrc || defaultImageSrc;
|
|
13
|
+
return img;
|
|
14
|
+
}, [props]);
|
|
9
15
|
const onDragStart = react_1.default.useCallback((_, currentProps) => {
|
|
10
16
|
setDragProps(currentProps);
|
|
11
17
|
}, [setDragProps]);
|
|
@@ -15,10 +21,11 @@ const DashKitDnDWrapper = (props) => {
|
|
|
15
21
|
const contextValue = react_1.default.useMemo(() => {
|
|
16
22
|
return {
|
|
17
23
|
dragProps,
|
|
24
|
+
dragImagePreview,
|
|
18
25
|
onDragStart,
|
|
19
26
|
onDragEnd,
|
|
20
27
|
};
|
|
21
|
-
}, [dragProps, onDragStart, onDragEnd]);
|
|
28
|
+
}, [dragProps, dragImagePreview, onDragStart, onDragEnd]);
|
|
22
29
|
return (react_1.default.createElement(DashKitContext_1.DashKitDnDContext.Provider, { value: contextValue }, props.children));
|
|
23
30
|
};
|
|
24
31
|
exports.DashKitDnDWrapper = DashKitDnDWrapper;
|
|
@@ -2,49 +2,10 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const tslib_1 = require("tslib");
|
|
4
4
|
const react_1 = tslib_1.__importDefault(require("react"));
|
|
5
|
-
const react_grid_layout_1 = tslib_1.__importStar(require("react-grid-layout"));
|
|
6
5
|
const constants_1 = require("../../constants");
|
|
7
6
|
const DashKitContext_1 = require("../../context/DashKitContext");
|
|
8
7
|
const GridItem_1 = tslib_1.__importDefault(require("../GridItem/GridItem"));
|
|
9
|
-
|
|
10
|
-
constructor() {
|
|
11
|
-
super(...arguments);
|
|
12
|
-
this.dragReset = () => {
|
|
13
|
-
if (this.dragEnterCounter) {
|
|
14
|
-
this.dragEnterCounter = 0;
|
|
15
|
-
this.removeDroppingPlaceholder();
|
|
16
|
-
}
|
|
17
|
-
};
|
|
18
|
-
}
|
|
19
|
-
componentDidMount() {
|
|
20
|
-
super.componentDidMount();
|
|
21
|
-
window.addEventListener('dragend', this.dragReset);
|
|
22
|
-
}
|
|
23
|
-
componentWillUnmount() {
|
|
24
|
-
window.removeEventListener('dragend', this.dragReset);
|
|
25
|
-
}
|
|
26
|
-
processGridItem(child, isDroppingItem) {
|
|
27
|
-
const gridItem = super.processGridItem(child, isDroppingItem);
|
|
28
|
-
if (isDroppingItem) {
|
|
29
|
-
// Drop item from outside gets 0,0 droppingPosition
|
|
30
|
-
// centering cursor on newly creted grid item
|
|
31
|
-
// And cause grid-layout using it's own GridItem to make it look
|
|
32
|
-
// like overlay adding className
|
|
33
|
-
if (!gridItem)
|
|
34
|
-
return null;
|
|
35
|
-
const { props } = gridItem;
|
|
36
|
-
const { containerWidth, cols, w, h, rowHeight, margin, transformScale } = props;
|
|
37
|
-
const leftOffset = (((containerWidth / cols) * w) / 2 || 0) * transformScale;
|
|
38
|
-
const topOffset = ((h * rowHeight + (h - 1) * margin[1]) / 2 || 0) * transformScale;
|
|
39
|
-
return react_1.default.cloneElement(gridItem, {
|
|
40
|
-
className: constants_1.OVERLAY_CLASS_NAME,
|
|
41
|
-
droppingPosition: Object.assign(Object.assign({}, props.droppingPosition), { left: props.droppingPosition.left - leftOffset, top: props.droppingPosition.top - topOffset }),
|
|
42
|
-
});
|
|
43
|
-
}
|
|
44
|
-
return gridItem;
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
const Layout = (0, react_grid_layout_1.WidthProvider)(DragOverLayout); // eslint-disable-line new-cap
|
|
8
|
+
const ReactGridLayout_1 = require("./ReactGridLayout");
|
|
48
9
|
class GridLayout extends react_1.default.PureComponent {
|
|
49
10
|
constructor(props, context) {
|
|
50
11
|
super(props, context);
|
|
@@ -145,7 +106,7 @@ class GridLayout extends react_1.default.PureComponent {
|
|
|
145
106
|
render() {
|
|
146
107
|
const { layout, temporaryLayout, config, registerManager, editMode, noOverlay, focusable, draggableHandleClassName, outerDnDEnable, } = this.context;
|
|
147
108
|
this.pluginsRefs.length = config.items.length;
|
|
148
|
-
return (react_1.default.createElement(Layout, Object.assign({}, registerManager.gridLayout, { layout: temporaryLayout || layout, isDraggable: editMode, isResizable: editMode, onDragStart: this._onStart, onDragStop: this._onStop, onResizeStart: this._onStart, onResizeStop: this._onStop }, (draggableHandleClassName
|
|
109
|
+
return (react_1.default.createElement(ReactGridLayout_1.Layout, Object.assign({}, registerManager.gridLayout, { layout: temporaryLayout || layout, isDraggable: editMode, isResizable: editMode, onDragStart: this._onStart, onDragStop: this._onStop, onResizeStart: this._onStart, onResizeStop: this._onStop }, (draggableHandleClassName
|
|
149
110
|
? { draggableHandle: `.${draggableHandleClassName}` }
|
|
150
111
|
: null), (outerDnDEnable
|
|
151
112
|
? {
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Layout = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const react_1 = tslib_1.__importDefault(require("react"));
|
|
6
|
+
const react_grid_layout_1 = tslib_1.__importStar(require("react-grid-layout"));
|
|
7
|
+
const constants_1 = require("../../constants");
|
|
8
|
+
class DragOverLayout extends react_grid_layout_1.default {
|
|
9
|
+
constructor() {
|
|
10
|
+
super(...arguments);
|
|
11
|
+
this.dragReset = () => {
|
|
12
|
+
if (this.dragEnterCounter) {
|
|
13
|
+
this.dragEnterCounter = 0;
|
|
14
|
+
this.removeDroppingPlaceholder();
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
componentDidMount() {
|
|
19
|
+
var _a;
|
|
20
|
+
(_a = super.componentDidMount) === null || _a === void 0 ? void 0 : _a.call(this);
|
|
21
|
+
window.addEventListener('dragend', this.dragReset);
|
|
22
|
+
}
|
|
23
|
+
componentWillUnmount() {
|
|
24
|
+
window.removeEventListener('dragend', this.dragReset);
|
|
25
|
+
}
|
|
26
|
+
processGridItem(child, isDroppingItem) {
|
|
27
|
+
var _a;
|
|
28
|
+
const gridItem = (_a = super.processGridItem) === null || _a === void 0 ? void 0 : _a.call(this, child, isDroppingItem);
|
|
29
|
+
if (isDroppingItem) {
|
|
30
|
+
// Drop item from outside gets 0,0 droppingPosition
|
|
31
|
+
// centering cursor on newly creted grid item
|
|
32
|
+
// And cause grid-layout using it's own GridItem to make it look
|
|
33
|
+
// like overlay adding className
|
|
34
|
+
if (!gridItem)
|
|
35
|
+
return null;
|
|
36
|
+
const { props } = gridItem;
|
|
37
|
+
const { containerWidth, cols, w, h, rowHeight, margin, transformScale } = props;
|
|
38
|
+
const leftOffset = (((containerWidth / cols) * w) / 2 || 0) * transformScale;
|
|
39
|
+
const topOffset = ((h * rowHeight + (h - 1) * margin[1]) / 2 || 0) * transformScale;
|
|
40
|
+
return react_1.default.cloneElement(gridItem, {
|
|
41
|
+
className: constants_1.OVERLAY_CLASS_NAME,
|
|
42
|
+
droppingPosition: Object.assign(Object.assign({}, props.droppingPosition), { left: props.droppingPosition.left - leftOffset, top: props.droppingPosition.top - topOffset }),
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
return gridItem;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
// eslint-disable-next-line new-cap
|
|
49
|
+
exports.Layout = (0, react_grid_layout_1.WidthProvider)(DragOverLayout);
|
|
@@ -183,8 +183,8 @@ class OverlayControls extends react_1.default.Component {
|
|
|
183
183
|
};
|
|
184
184
|
});
|
|
185
185
|
items = items.filter(Boolean);
|
|
186
|
-
return (react_1.default.createElement(uikit_1.DropdownMenu, { items: items,
|
|
187
|
-
react_1.default.createElement(uikit_1.Icon, { data: DotsIcon_1.DotsIcon, size: "16" })) }));
|
|
186
|
+
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: "brick-round", qa: "dashkit-overlay-control-menu" }),
|
|
187
|
+
react_1.default.createElement(uikit_1.Icon, { data: DotsIcon_1.DotsIcon, size: "16" }))) }));
|
|
188
188
|
}
|
|
189
189
|
getControlItemPinStyle(index, itemsLength) {
|
|
190
190
|
const isOnlyOneItem = itemsLength === 1;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.MenuItems = exports.TEMPORARY_ITEM_ID = exports.OVERLAY_CLASS_NAME = exports.OVERLAY_CONTROLS_CLASS_NAME = exports.DEFAULT_NAMESPACE = exports.COPIED_WIDGET_STORE_KEY = void 0;
|
|
3
|
+
exports.DEFAULT_WIDGET_WIDTH = exports.DEFAULT_WIDGET_HEIGHT = exports.MenuItems = exports.TEMPORARY_ITEM_ID = 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';
|
|
@@ -11,3 +11,5 @@ exports.MenuItems = {
|
|
|
11
11
|
Delete: 'delete',
|
|
12
12
|
Settings: 'settings',
|
|
13
13
|
};
|
|
14
|
+
exports.DEFAULT_WIDGET_HEIGHT = 3;
|
|
15
|
+
exports.DEFAULT_WIDGET_WIDTH = 3;
|
|
@@ -8,8 +8,6 @@ const common_1 = require("../constants/common");
|
|
|
8
8
|
const DashKitContext_1 = require("../context/DashKitContext");
|
|
9
9
|
const shared_1 = require("../shared");
|
|
10
10
|
const utils_1 = require("../utils");
|
|
11
|
-
const DEFAULT_HEIGHT = 3;
|
|
12
|
-
const DEFAULT_WIDTH = 3;
|
|
13
11
|
function useMemoStateContext(props) {
|
|
14
12
|
// так как мы не хотим хранить параметры виджета с активированной автовысотой в сторе и на сервере, актуальный
|
|
15
13
|
// (видимый юзером в конкретный момент времени) лэйаут (массив объектов с данными о ширине, высоте,
|
|
@@ -148,7 +146,7 @@ function useMemoStateContext(props) {
|
|
|
148
146
|
}, []);
|
|
149
147
|
const dragProps = dndContext === null || dndContext === void 0 ? void 0 : dndContext.dragProps;
|
|
150
148
|
const dragOverPlugin = react_1.default.useMemo(() => {
|
|
151
|
-
if (dragProps
|
|
149
|
+
if (!dragProps) {
|
|
152
150
|
return null;
|
|
153
151
|
}
|
|
154
152
|
const pluginType = dragProps.type;
|
|
@@ -168,7 +166,7 @@ function useMemoStateContext(props) {
|
|
|
168
166
|
}
|
|
169
167
|
if (dragOverPlugin) {
|
|
170
168
|
const { defaultLayout } = dragOverPlugin;
|
|
171
|
-
const { h = (defaultLayout === null || defaultLayout === void 0 ? void 0 : defaultLayout.h) ||
|
|
169
|
+
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 || {};
|
|
172
170
|
return { h, w };
|
|
173
171
|
}
|
|
174
172
|
return false;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { ActionPanelItem } from '../components';
|
|
3
|
+
type DndProps = null | {
|
|
4
|
+
draggable: true;
|
|
5
|
+
unselectable: 'on';
|
|
6
|
+
onDragStart: React.DragEventHandler<HTMLDivElement>;
|
|
7
|
+
onDragEnd: React.DragEventHandler<HTMLDivElement>;
|
|
8
|
+
};
|
|
9
|
+
export declare const useDnDItemProps: (item: ActionPanelItem) => DndProps;
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.useDnDItemProps = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const react_1 = tslib_1.__importDefault(require("react"));
|
|
6
|
+
const DashKitContext_1 = require("../context/DashKitContext");
|
|
7
|
+
const useDnDItemProps = (item) => {
|
|
8
|
+
const dragContext = react_1.default.useContext(DashKitContext_1.DashKitDnDContext);
|
|
9
|
+
const onDragStart = react_1.default.useCallback((e) => {
|
|
10
|
+
if (dragContext && item.dragProps) {
|
|
11
|
+
dragContext.onDragStart(e, item.dragProps);
|
|
12
|
+
e.dataTransfer.setDragImage(dragContext.dragImagePreview, 0, 0);
|
|
13
|
+
}
|
|
14
|
+
}, [dragContext, item.dragProps]);
|
|
15
|
+
const onDragEnd = react_1.default.useCallback((e) => {
|
|
16
|
+
if (dragContext) {
|
|
17
|
+
dragContext.onDragEnd(e);
|
|
18
|
+
}
|
|
19
|
+
}, [dragContext]);
|
|
20
|
+
if (dragContext && item.dragProps) {
|
|
21
|
+
return {
|
|
22
|
+
draggable: true,
|
|
23
|
+
unselectable: 'on',
|
|
24
|
+
onDragStart,
|
|
25
|
+
onDragEnd,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
return null;
|
|
29
|
+
};
|
|
30
|
+
exports.useDnDItemProps = useDnDItemProps;
|
|
@@ -1,27 +1,12 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { CSSTransition } from 'react-transition-group';
|
|
3
|
-
import {
|
|
3
|
+
import { useDnDItemProps } from '../../hooks/useDnDItemProps';
|
|
4
4
|
import { cn } from '../../utils/cn';
|
|
5
5
|
import './ActionPanel.css';
|
|
6
6
|
const b = cn('dashkit-action-panel');
|
|
7
7
|
export const ActionPanelItemContainer = ({ item }) => {
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
dragContext === null || dragContext === void 0 ? void 0 : dragContext.onDragStart(e, item.dragProps);
|
|
11
|
-
}, [dragContext === null || dragContext === void 0 ? void 0 : dragContext.onDragStart, item.dragProps]);
|
|
12
|
-
const onDragEnd = React.useCallback((e) => {
|
|
13
|
-
dragContext === null || dragContext === void 0 ? void 0 : dragContext.onDragEnd(e);
|
|
14
|
-
}, [dragContext === null || dragContext === void 0 ? void 0 : dragContext.onDragEnd]);
|
|
15
|
-
let dndProps = {};
|
|
16
|
-
if (item.dragProps) {
|
|
17
|
-
dndProps = {
|
|
18
|
-
draggable: true,
|
|
19
|
-
unselectable: 'on',
|
|
20
|
-
onDragStart,
|
|
21
|
-
onDragEnd,
|
|
22
|
-
};
|
|
23
|
-
}
|
|
24
|
-
return (React.createElement("div", Object.assign({ role: "button", className: b('item', item.className), key: `dk-action-panel-${item.id}`, onClick: item.onClick, "data-qa": item.qa }, dndProps),
|
|
8
|
+
const dndProps = useDnDItemProps(item);
|
|
9
|
+
return (React.createElement("div", Object.assign({ role: "button", className: b('item', { draggable: Boolean(dndProps) }, item.className), key: `dk-action-panel-${item.id}`, onClick: item.onClick, "data-qa": item.qa }, dndProps),
|
|
25
10
|
React.createElement("div", { className: b('icon') }, item.icon),
|
|
26
11
|
React.createElement("div", { className: b('title'), title: item.title }, item.title)));
|
|
27
12
|
};
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import type {
|
|
2
|
+
import type { ItemDragProps } from '../../shared';
|
|
3
3
|
export type ActionPanelItem = {
|
|
4
4
|
id: string;
|
|
5
5
|
icon: React.ReactNode;
|
|
6
6
|
title: string;
|
|
7
|
-
onClick?: () => void;
|
|
8
7
|
className?: string;
|
|
9
8
|
qa?: string;
|
|
10
|
-
|
|
9
|
+
onClick?: () => void;
|
|
10
|
+
dragProps?: ItemDragProps;
|
|
11
11
|
};
|
|
12
12
|
export type ActionPanelProps = {
|
|
13
13
|
items: ActionPanelItem[];
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import type { Config, ConfigItem, ConfigLayout,
|
|
2
|
+
import type { Config, ConfigItem, ConfigLayout, GlobalParams, ItemDragProps, ItemsStateAndParams } from '../../shared';
|
|
3
3
|
import { ContextProps, Plugin, SetConfigItem, SetNewItemOptions, Settings, SettingsProps } from '../../typings';
|
|
4
4
|
import GridLayout from '../GridLayout/GridLayout';
|
|
5
5
|
import { OverlayControlItem } from '../OverlayControls/OverlayControls';
|
|
@@ -17,7 +17,7 @@ interface DashKitDefaultProps {
|
|
|
17
17
|
}) => void;
|
|
18
18
|
onDrop: (dropProps: {
|
|
19
19
|
commit: () => void;
|
|
20
|
-
dragProps:
|
|
20
|
+
dragProps: ItemDragProps;
|
|
21
21
|
itemLayout: ConfigLayout;
|
|
22
22
|
newLayout: ConfigLayout[];
|
|
23
23
|
}) => void;
|
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { DashKitDnDContext } from '../../context/DashKitContext';
|
|
3
|
+
const defaultImageSrc = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=';
|
|
3
4
|
export const DashKitDnDWrapper = (props) => {
|
|
4
5
|
const [dragProps, setDragProps] = React.useState(null);
|
|
6
|
+
const dragImagePreview = React.useMemo(() => {
|
|
7
|
+
const img = new Image(1, 1);
|
|
8
|
+
img.src = props.dragImageSrc || defaultImageSrc;
|
|
9
|
+
return img;
|
|
10
|
+
}, [props]);
|
|
5
11
|
const onDragStart = React.useCallback((_, currentProps) => {
|
|
6
12
|
setDragProps(currentProps);
|
|
7
13
|
}, [setDragProps]);
|
|
@@ -11,9 +17,10 @@ export const DashKitDnDWrapper = (props) => {
|
|
|
11
17
|
const contextValue = React.useMemo(() => {
|
|
12
18
|
return {
|
|
13
19
|
dragProps,
|
|
20
|
+
dragImagePreview,
|
|
14
21
|
onDragStart,
|
|
15
22
|
onDragEnd,
|
|
16
23
|
};
|
|
17
|
-
}, [dragProps, onDragStart, onDragEnd]);
|
|
24
|
+
}, [dragProps, dragImagePreview, onDragStart, onDragEnd]);
|
|
18
25
|
return (React.createElement(DashKitDnDContext.Provider, { value: contextValue }, props.children));
|
|
19
26
|
};
|
|
@@ -1,47 +1,8 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import
|
|
3
|
-
import { OVERLAY_CLASS_NAME, OVERLAY_CONTROLS_CLASS_NAME, TEMPORARY_ITEM_ID } from '../../constants';
|
|
2
|
+
import { OVERLAY_CONTROLS_CLASS_NAME, TEMPORARY_ITEM_ID } from '../../constants';
|
|
4
3
|
import { DashKitContext } from '../../context/DashKitContext';
|
|
5
4
|
import GridItem from '../GridItem/GridItem';
|
|
6
|
-
|
|
7
|
-
constructor() {
|
|
8
|
-
super(...arguments);
|
|
9
|
-
this.dragReset = () => {
|
|
10
|
-
if (this.dragEnterCounter) {
|
|
11
|
-
this.dragEnterCounter = 0;
|
|
12
|
-
this.removeDroppingPlaceholder();
|
|
13
|
-
}
|
|
14
|
-
};
|
|
15
|
-
}
|
|
16
|
-
componentDidMount() {
|
|
17
|
-
super.componentDidMount();
|
|
18
|
-
window.addEventListener('dragend', this.dragReset);
|
|
19
|
-
}
|
|
20
|
-
componentWillUnmount() {
|
|
21
|
-
window.removeEventListener('dragend', this.dragReset);
|
|
22
|
-
}
|
|
23
|
-
processGridItem(child, isDroppingItem) {
|
|
24
|
-
const gridItem = super.processGridItem(child, isDroppingItem);
|
|
25
|
-
if (isDroppingItem) {
|
|
26
|
-
// Drop item from outside gets 0,0 droppingPosition
|
|
27
|
-
// centering cursor on newly creted grid item
|
|
28
|
-
// And cause grid-layout using it's own GridItem to make it look
|
|
29
|
-
// like overlay adding className
|
|
30
|
-
if (!gridItem)
|
|
31
|
-
return null;
|
|
32
|
-
const { props } = gridItem;
|
|
33
|
-
const { containerWidth, cols, w, h, rowHeight, margin, transformScale } = props;
|
|
34
|
-
const leftOffset = (((containerWidth / cols) * w) / 2 || 0) * transformScale;
|
|
35
|
-
const topOffset = ((h * rowHeight + (h - 1) * margin[1]) / 2 || 0) * transformScale;
|
|
36
|
-
return React.cloneElement(gridItem, {
|
|
37
|
-
className: OVERLAY_CLASS_NAME,
|
|
38
|
-
droppingPosition: Object.assign(Object.assign({}, props.droppingPosition), { left: props.droppingPosition.left - leftOffset, top: props.droppingPosition.top - topOffset }),
|
|
39
|
-
});
|
|
40
|
-
}
|
|
41
|
-
return gridItem;
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
const Layout = WidthProvider(DragOverLayout); // eslint-disable-line new-cap
|
|
5
|
+
import { Layout } from './ReactGridLayout';
|
|
45
6
|
class GridLayout extends React.PureComponent {
|
|
46
7
|
constructor(props, context) {
|
|
47
8
|
super(props, context);
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import ReactGridLayout, { WidthProvider } from 'react-grid-layout';
|
|
3
|
+
import { OVERLAY_CLASS_NAME } from '../../constants';
|
|
4
|
+
class DragOverLayout extends ReactGridLayout {
|
|
5
|
+
constructor() {
|
|
6
|
+
super(...arguments);
|
|
7
|
+
this.dragReset = () => {
|
|
8
|
+
if (this.dragEnterCounter) {
|
|
9
|
+
this.dragEnterCounter = 0;
|
|
10
|
+
this.removeDroppingPlaceholder();
|
|
11
|
+
}
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
componentDidMount() {
|
|
15
|
+
var _a;
|
|
16
|
+
(_a = super.componentDidMount) === null || _a === void 0 ? void 0 : _a.call(this);
|
|
17
|
+
window.addEventListener('dragend', this.dragReset);
|
|
18
|
+
}
|
|
19
|
+
componentWillUnmount() {
|
|
20
|
+
window.removeEventListener('dragend', this.dragReset);
|
|
21
|
+
}
|
|
22
|
+
processGridItem(child, isDroppingItem) {
|
|
23
|
+
var _a;
|
|
24
|
+
const gridItem = (_a = super.processGridItem) === null || _a === void 0 ? void 0 : _a.call(this, child, isDroppingItem);
|
|
25
|
+
if (isDroppingItem) {
|
|
26
|
+
// Drop item from outside gets 0,0 droppingPosition
|
|
27
|
+
// centering cursor on newly creted grid item
|
|
28
|
+
// And cause grid-layout using it's own GridItem to make it look
|
|
29
|
+
// like overlay adding className
|
|
30
|
+
if (!gridItem)
|
|
31
|
+
return null;
|
|
32
|
+
const { props } = gridItem;
|
|
33
|
+
const { containerWidth, cols, w, h, rowHeight, margin, transformScale } = props;
|
|
34
|
+
const leftOffset = (((containerWidth / cols) * w) / 2 || 0) * transformScale;
|
|
35
|
+
const topOffset = ((h * rowHeight + (h - 1) * margin[1]) / 2 || 0) * transformScale;
|
|
36
|
+
return React.cloneElement(gridItem, {
|
|
37
|
+
className: OVERLAY_CLASS_NAME,
|
|
38
|
+
droppingPosition: Object.assign(Object.assign({}, props.droppingPosition), { left: props.droppingPosition.left - leftOffset, top: props.droppingPosition.top - topOffset }),
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
return gridItem;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
// eslint-disable-next-line new-cap
|
|
45
|
+
export const Layout = WidthProvider(DragOverLayout);
|
|
@@ -180,8 +180,8 @@ class OverlayControls extends React.Component {
|
|
|
180
180
|
};
|
|
181
181
|
});
|
|
182
182
|
items = items.filter(Boolean);
|
|
183
|
-
return (React.createElement(DropdownMenu, { items: items,
|
|
184
|
-
React.createElement(Icon, { data: DotsIcon, size: "16" })) }));
|
|
183
|
+
return (React.createElement(DropdownMenu, { items: items, renderSwitcher: (props) => (React.createElement(Button, Object.assign({}, props, { view: view, size: size, pin: "brick-round", qa: "dashkit-overlay-control-menu" }),
|
|
184
|
+
React.createElement(Icon, { data: DotsIcon, size: "16" }))) }));
|
|
185
185
|
}
|
|
186
186
|
getControlItemPinStyle(index, itemsLength) {
|
|
187
187
|
const isOnlyOneItem = itemsLength === 1;
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import isEqual from 'lodash/isEqual';
|
|
3
|
-
import { TEMPORARY_ITEM_ID } from '../constants/common';
|
|
3
|
+
import { DEFAULT_WIDGET_HEIGHT, DEFAULT_WIDGET_WIDTH, TEMPORARY_ITEM_ID } from '../constants/common';
|
|
4
4
|
import { DashKitContext, DashKitDnDContext } from '../context/DashKitContext';
|
|
5
5
|
import { getItemsParams, getItemsState } from '../shared';
|
|
6
6
|
import { UpdateManager } from '../utils';
|
|
7
|
-
const DEFAULT_HEIGHT = 3;
|
|
8
|
-
const DEFAULT_WIDTH = 3;
|
|
9
7
|
function useMemoStateContext(props) {
|
|
10
8
|
// так как мы не хотим хранить параметры виджета с активированной автовысотой в сторе и на сервере, актуальный
|
|
11
9
|
// (видимый юзером в конкретный момент времени) лэйаут (массив объектов с данными о ширине, высоте,
|
|
@@ -144,7 +142,7 @@ function useMemoStateContext(props) {
|
|
|
144
142
|
}, []);
|
|
145
143
|
const dragProps = dndContext === null || dndContext === void 0 ? void 0 : dndContext.dragProps;
|
|
146
144
|
const dragOverPlugin = React.useMemo(() => {
|
|
147
|
-
if (dragProps
|
|
145
|
+
if (!dragProps) {
|
|
148
146
|
return null;
|
|
149
147
|
}
|
|
150
148
|
const pluginType = dragProps.type;
|
|
@@ -164,7 +162,7 @@ function useMemoStateContext(props) {
|
|
|
164
162
|
}
|
|
165
163
|
if (dragOverPlugin) {
|
|
166
164
|
const { defaultLayout } = dragOverPlugin;
|
|
167
|
-
const { h = (defaultLayout === null || defaultLayout === void 0 ? void 0 : defaultLayout.h) ||
|
|
165
|
+
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 || {};
|
|
168
166
|
return { h, w };
|
|
169
167
|
}
|
|
170
168
|
return false;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { ActionPanelItem } from '../components';
|
|
3
|
+
type DndProps = null | {
|
|
4
|
+
draggable: true;
|
|
5
|
+
unselectable: 'on';
|
|
6
|
+
onDragStart: React.DragEventHandler<HTMLDivElement>;
|
|
7
|
+
onDragEnd: React.DragEventHandler<HTMLDivElement>;
|
|
8
|
+
};
|
|
9
|
+
export declare const useDnDItemProps: (item: ActionPanelItem) => DndProps;
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { DashKitDnDContext } from '../context/DashKitContext';
|
|
3
|
+
export const useDnDItemProps = (item) => {
|
|
4
|
+
const dragContext = React.useContext(DashKitDnDContext);
|
|
5
|
+
const onDragStart = React.useCallback((e) => {
|
|
6
|
+
if (dragContext && item.dragProps) {
|
|
7
|
+
dragContext.onDragStart(e, item.dragProps);
|
|
8
|
+
e.dataTransfer.setDragImage(dragContext.dragImagePreview, 0, 0);
|
|
9
|
+
}
|
|
10
|
+
}, [dragContext, item.dragProps]);
|
|
11
|
+
const onDragEnd = React.useCallback((e) => {
|
|
12
|
+
if (dragContext) {
|
|
13
|
+
dragContext.onDragEnd(e);
|
|
14
|
+
}
|
|
15
|
+
}, [dragContext]);
|
|
16
|
+
if (dragContext && item.dragProps) {
|
|
17
|
+
return {
|
|
18
|
+
draggable: true,
|
|
19
|
+
unselectable: 'on',
|
|
20
|
+
onDragStart,
|
|
21
|
+
onDragEnd,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
return null;
|
|
25
|
+
};
|