@gravity-ui/dashkit 8.0.2 → 8.1.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/README.md +1 -0
  2. package/build/cjs/components/ActionPanel/ActionPanel.d.ts +13 -1
  3. package/build/cjs/components/ActionPanel/ActionPanel.js +25 -6
  4. package/build/cjs/components/ActionPanel/types.d.ts +1 -0
  5. package/build/cjs/components/DashKit/DashKit.d.ts +10 -3
  6. package/build/cjs/components/DashKit/DashKit.js +2 -0
  7. package/build/cjs/components/DashKitDnDWrapper/DashKitDnDWrapper.d.ts +6 -0
  8. package/build/cjs/components/DashKitDnDWrapper/DashKitDnDWrapper.js +24 -0
  9. package/build/cjs/components/GridItem/GridItem.css +7 -0
  10. package/build/cjs/components/GridItem/GridItem.d.ts +2 -2
  11. package/build/cjs/components/GridItem/GridItem.js +63 -4
  12. package/build/cjs/components/GridLayout/GridLayout.d.ts +3 -0
  13. package/build/cjs/components/GridLayout/GridLayout.js +90 -10
  14. package/build/cjs/components/Item/Item.css +1 -1
  15. package/build/cjs/components/Item/Item.d.ts +1 -0
  16. package/build/cjs/components/Item/Item.js +7 -1
  17. package/build/cjs/components/index.d.ts +1 -0
  18. package/build/cjs/components/index.js +1 -0
  19. package/build/cjs/constants/common.d.ts +2 -0
  20. package/build/cjs/constants/common.js +3 -1
  21. package/build/cjs/context/DashKitContext.d.ts +1 -0
  22. package/build/cjs/context/DashKitContext.js +3 -1
  23. package/build/cjs/hocs/prepareItem.d.ts +1 -0
  24. package/build/cjs/hocs/prepareItem.js +4 -2
  25. package/build/cjs/hocs/withContext.js +87 -6
  26. package/build/cjs/shared/constants/common.d.ts +1 -0
  27. package/build/cjs/shared/constants/common.js +2 -1
  28. package/build/cjs/typings/config.d.ts +3 -0
  29. package/build/cjs/typings/plugin.d.ts +1 -0
  30. package/build/cjs/utils/update-manager.d.ts +2 -2
  31. package/build/cjs/utils/update-manager.js +25 -7
  32. package/build/esm/components/ActionPanel/ActionPanel.d.ts +13 -1
  33. package/build/esm/components/ActionPanel/ActionPanel.js +23 -5
  34. package/build/esm/components/ActionPanel/types.d.ts +1 -0
  35. package/build/esm/components/DashKit/DashKit.d.ts +10 -3
  36. package/build/esm/components/DashKit/DashKit.js +2 -0
  37. package/build/esm/components/DashKitDnDWrapper/DashKitDnDWrapper.d.ts +6 -0
  38. package/build/esm/components/DashKitDnDWrapper/DashKitDnDWrapper.js +19 -0
  39. package/build/esm/components/GridItem/GridItem.css +7 -0
  40. package/build/esm/components/GridItem/GridItem.d.ts +2 -2
  41. package/build/esm/components/GridItem/GridItem.js +63 -4
  42. package/build/esm/components/GridLayout/GridLayout.d.ts +3 -0
  43. package/build/esm/components/GridLayout/GridLayout.js +91 -11
  44. package/build/esm/components/Item/Item.css +1 -1
  45. package/build/esm/components/Item/Item.d.ts +1 -0
  46. package/build/esm/components/Item/Item.js +7 -1
  47. package/build/esm/components/index.d.ts +1 -0
  48. package/build/esm/components/index.js +1 -0
  49. package/build/esm/constants/common.d.ts +2 -0
  50. package/build/esm/constants/common.js +2 -0
  51. package/build/esm/context/DashKitContext.d.ts +1 -0
  52. package/build/esm/context/DashKitContext.js +2 -1
  53. package/build/esm/hocs/prepareItem.d.ts +1 -0
  54. package/build/esm/hocs/prepareItem.js +4 -2
  55. package/build/esm/hocs/withContext.js +88 -7
  56. package/build/esm/shared/constants/common.d.ts +1 -0
  57. package/build/esm/shared/constants/common.js +1 -0
  58. package/build/esm/typings/config.d.ts +3 -0
  59. package/build/esm/typings/plugin.d.ts +1 -0
  60. package/build/esm/utils/update-manager.d.ts +2 -2
  61. package/build/esm/utils/update-manager.js +25 -7
  62. package/package.json +1 -1
package/README.md CHANGED
@@ -49,6 +49,7 @@ interface DashKitProps {
49
49
  - **context**: Object that will be propped up on all widgets.
50
50
  - **overlayControls**: Object that overrides widget controls at the time of editing. If not transmitted, basic controls will be displayed.
51
51
  - **noOverlay**: If `true`, overlay and controls are not displayed while editing.
52
+ - **focusable**: If `true`, grid items will be focusable.
52
53
  - **draggableHandleClassName** : СSS class name of the element that makes the widget draggable.
53
54
 
54
55
  ## Usage
@@ -1,3 +1,15 @@
1
- /// <reference types="react" />
1
+ import React from 'react';
2
2
  import { ActionPanelProps } from './types';
3
+ export type ActionPanelItem = {
4
+ id: string;
5
+ icon: React.ReactNode;
6
+ title: string;
7
+ onClick?: () => void;
8
+ className?: string;
9
+ qa?: string;
10
+ pluginType?: string;
11
+ };
12
+ export declare const ActionPanelItemContainer: ({ item }: {
13
+ item: ActionPanelItem;
14
+ }) => JSX.Element;
3
15
  export declare const ActionPanel: (props: ActionPanelProps) => JSX.Element | null;
@@ -1,21 +1,40 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ActionPanel = void 0;
3
+ 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 DashKitContext_1 = require("../../context/DashKitContext");
7
8
  const cn_1 = require("../../utils/cn");
8
9
  const b = (0, cn_1.cn)('dashkit-action-panel');
10
+ const ActionPanelItemContainer = ({ item }) => {
11
+ const dragContext = react_1.default.useContext(DashKitContext_1.DashKitDnDContext);
12
+ const onDragStart = react_1.default.useCallback((e) => {
13
+ dragContext.onDragStart(e, item.pluginType);
14
+ }, [dragContext === null || dragContext === void 0 ? void 0 : dragContext.onDragStart, item.pluginType]);
15
+ const onDragEnd = react_1.default.useCallback((e) => {
16
+ dragContext.onDragEnd(e);
17
+ }, [dragContext === null || dragContext === void 0 ? void 0 : dragContext.onDragEnd]);
18
+ let dndProps = {};
19
+ if (item.pluginType) {
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),
28
+ react_1.default.createElement("div", { className: b('icon') }, item.icon),
29
+ react_1.default.createElement("div", { className: b('title'), title: item.title }, item.title)));
30
+ };
31
+ exports.ActionPanelItemContainer = ActionPanelItemContainer;
9
32
  const ActionPanel = (props) => {
10
33
  var _a, _b;
11
34
  const isDisabled = (_a = props.disable) !== null && _a !== void 0 ? _a : false;
12
35
  const isAnimated = (_b = props.toggleAnimation) !== null && _b !== void 0 ? _b : false;
13
36
  const nodeRef = react_1.default.useRef(null);
14
- const content = (react_1.default.createElement("div", { ref: nodeRef, className: b(null, props.className) }, props.items.map((item) => {
15
- return (react_1.default.createElement("div", { role: "button", className: b('item', item.className), key: `dk-action-panel-${item.id}`, onClick: item.onClick, "data-qa": item.qa },
16
- react_1.default.createElement("div", { className: b('icon') }, item.icon),
17
- react_1.default.createElement("div", { className: b('title'), title: item.title }, item.title)));
18
- })));
37
+ const content = (react_1.default.createElement("div", { ref: nodeRef, className: b(null, props.className) }, props.items.map((item, i) => (react_1.default.createElement(exports.ActionPanelItemContainer, { key: `item_${i}`, item: item })))));
19
38
  if (isAnimated) {
20
39
  return (react_1.default.createElement(react_transition_group_1.CSSTransition, { in: !isDisabled, nodeRef: nodeRef, classNames: b(null), timeout: 300, unmountOnExit: true }, content));
21
40
  }
@@ -6,6 +6,7 @@ export type ActionPanelItem = {
6
6
  onClick?: () => void;
7
7
  className?: string;
8
8
  qa?: string;
9
+ pluginType?: string;
9
10
  };
10
11
  export type ActionPanelProps = {
11
12
  items: ActionPanelItem[];
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
- import type { Config, ConfigItem, GlobalParams, ItemsStateAndParams } from '../../shared';
3
- import { ContextProps, Plugin, SetConfigItem, SetItemOptions, Settings, SettingsProps } from '../../typings';
2
+ import type { Config, ConfigItem, ConfigLayout, GlobalParams, ItemsStateAndParams } from '../../shared';
3
+ import { ContextProps, Plugin, SetConfigItem, SetNewItemOptions, Settings, SettingsProps } from '../../typings';
4
4
  import GridLayout from '../GridLayout/GridLayout';
5
5
  import { OverlayControlItem } from '../OverlayControls/OverlayControls';
6
6
  interface DashKitGeneralProps {
@@ -15,12 +15,19 @@ interface DashKitDefaultProps {
15
15
  config: Config;
16
16
  itemsStateAndParams: ItemsStateAndParams;
17
17
  }) => void;
18
+ onDrop: (dropProps: {
19
+ commit: () => void;
20
+ pluginType: string;
21
+ itemLayout: ConfigLayout;
22
+ newLayout: ConfigLayout[];
23
+ }) => void;
18
24
  defaultGlobalParams: GlobalParams;
19
25
  globalParams: GlobalParams;
20
26
  itemsStateAndParams: ItemsStateAndParams;
21
27
  settings: SettingsProps;
22
28
  context: ContextProps;
23
29
  noOverlay: boolean;
30
+ focusable?: boolean;
24
31
  }
25
32
  export interface DashKitProps extends DashKitGeneralProps, Partial<DashKitDefaultProps> {
26
33
  }
@@ -33,7 +40,7 @@ export declare class DashKit extends React.PureComponent<DashKitInnerProps> {
33
40
  item: SetConfigItem;
34
41
  namespace?: string;
35
42
  config: Config;
36
- options?: SetItemOptions;
43
+ options?: SetNewItemOptions;
37
44
  }): Config;
38
45
  static removeItem({ id, config, itemsStateAndParams, }: {
39
46
  id: string;
@@ -59,6 +59,7 @@ exports.DashKit = DashKit;
59
59
  DashKit.defaultProps = {
60
60
  onItemEdit: noop_1.default,
61
61
  onChange: noop_1.default,
62
+ onDrop: noop_1.default,
62
63
  defaultGlobalParams: {},
63
64
  globalParams: {},
64
65
  itemsStateAndParams: {},
@@ -68,4 +69,5 @@ DashKit.defaultProps = {
68
69
  },
69
70
  context: {},
70
71
  noOverlay: false,
72
+ focusable: false,
71
73
  };
@@ -0,0 +1,6 @@
1
+ import React from 'react';
2
+ type DashKitDnDWrapperProps = {
3
+ children: React.ReactElement;
4
+ };
5
+ export declare const DashKitDnDWrapper: React.FC<DashKitDnDWrapperProps>;
6
+ export {};
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DashKitDnDWrapper = 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 DashKitDnDWrapper = (props) => {
8
+ const [dragPluginType, setDragPluginType] = react_1.default.useState(null);
9
+ const onDragStart = react_1.default.useCallback((_, type) => {
10
+ setDragPluginType(type);
11
+ }, [setDragPluginType]);
12
+ const onDragEnd = react_1.default.useCallback((_) => {
13
+ setDragPluginType(null);
14
+ }, [setDragPluginType]);
15
+ const contextValue = react_1.default.useMemo(() => {
16
+ return {
17
+ dragPluginType,
18
+ onDragStart,
19
+ onDragEnd,
20
+ };
21
+ }, [dragPluginType, onDragStart, onDragEnd]);
22
+ return (react_1.default.createElement(DashKitContext_1.DashKitDnDContext.Provider, { value: contextValue }, props.children));
23
+ };
24
+ exports.DashKitDnDWrapper = DashKitDnDWrapper;
@@ -1,6 +1,9 @@
1
1
  .dashkit-grid-item {
2
2
  position: relative;
3
3
  }
4
+ .dashkit-grid-item:focus {
5
+ outline: none;
6
+ }
4
7
  .dashkit-grid-item__overlay {
5
8
  --_-dashkit-overlay-color: var(--dashkit-overlay-color, var(--g-color-base-generic));
6
9
  --_-dashkit-overlay-border-color: var(--dashkit-overlay-border-color, rgba(0, 0, 0, 0.1));
@@ -56,6 +59,10 @@
56
59
  will-change: transform;
57
60
  }
58
61
 
62
+ .react-grid-item.dashkit-grid-item_is-focused {
63
+ z-index: 2;
64
+ }
65
+
59
66
  .react-grid-item.react-grid-placeholder {
60
67
  --_-dashkit-placeholder-color: var(--dashkit-placeholder-color, #fc0);
61
68
  --_-dashkit-placeholder-opacity: var(--dashkit-placeholder-opacity, 0.2);
@@ -1,3 +1,3 @@
1
- declare const _default: React.ForwardRefExoticComponent<React.RefAttributes<any>>;
2
- export default _default;
1
+ export default GridItemForwarderRef;
2
+ declare const GridItemForwarderRef: React.ForwardRefExoticComponent<React.RefAttributes<any>>;
3
3
  import React from 'react';
@@ -8,7 +8,55 @@ const cn_1 = require("../../utils/cn");
8
8
  const Item_1 = tslib_1.__importDefault(require("../Item/Item"));
9
9
  const OverlayControls_1 = tslib_1.__importDefault(require("../OverlayControls/OverlayControls"));
10
10
  const b = (0, cn_1.cn)('dashkit-grid-item');
11
+ class WindowFocusObserver {
12
+ constructor() {
13
+ this.blurHandler = (e) => {
14
+ if (e.target === window) {
15
+ this.isFocused = false;
16
+ }
17
+ };
18
+ this.focusHandler = (e) => {
19
+ if (e.target === window) {
20
+ this.isFocused = true;
21
+ }
22
+ };
23
+ this.subscribers = 0;
24
+ this.isFocused = !document.hidden;
25
+ window.addEventListener('blur', this.blurHandler, true);
26
+ window.addEventListener('focus', this.focusHandler, true);
27
+ }
28
+ // Method to get state after all blur\focus events in document are triggered
29
+ async getFocuseState() {
30
+ return new Promise((resolve) => {
31
+ requestAnimationFrame(() => {
32
+ resolve(this.isFocused);
33
+ });
34
+ });
35
+ }
36
+ }
37
+ const windowFocusObserver = new WindowFocusObserver();
11
38
  class GridItem extends react_1.default.PureComponent {
39
+ constructor() {
40
+ super(...arguments);
41
+ this.state = {
42
+ isFocused: false,
43
+ };
44
+ this.onFocusHandler = () => {
45
+ this.setState({ isFocused: true });
46
+ if (this.controller) {
47
+ this.controller.abort();
48
+ }
49
+ };
50
+ this.onBlurHandler = () => {
51
+ this.controller = new AbortController();
52
+ windowFocusObserver.getFocuseState().then((isWindowFocused) => {
53
+ if (!this.controller.signal.aborted && isWindowFocused) {
54
+ this.setState({ isFocused: false });
55
+ }
56
+ this.controller = null;
57
+ });
58
+ };
59
+ }
12
60
  renderOverlay() {
13
61
  const { overlayControls } = this.props;
14
62
  const { editMode } = this.context;
@@ -24,7 +72,7 @@ class GridItem extends react_1.default.PureComponent {
24
72
  render() {
25
73
  // из-за бага, что Grid Items unmounts при изменении static, isDraggable, isResaizable
26
74
  // https://github.com/STRML/react-grid-layout/issues/721
27
- const { style, onMouseDown, onMouseUp, onTouchEnd, onTouchStart, children, className, isDragging, noOverlay, withCustomHandle, } = this.props;
75
+ const { style, onMouseDown, onMouseUp, onTouchEnd, onTouchStart, children, className, isDragging, noOverlay, focusable, withCustomHandle, isPlaceholder, } = this.props;
28
76
  const { editMode } = this.context;
29
77
  const width = Number.parseInt(style.width, 10);
30
78
  const height = Number.parseInt(style.height, 10);
@@ -39,10 +87,17 @@ class GridItem extends react_1.default.PureComponent {
39
87
  const { _editActive } = this.props.item.data;
40
88
  return (react_1.default.createElement("div", Object.assign({ className: b({
41
89
  'is-dragging': isDragging,
90
+ 'is-focused': this.state.isFocused,
42
91
  'with-custom-handle': withCustomHandle,
43
- }, preparedClassName), "data-qa": "dashkit-grid-item", style: style, ref: this.props.forwardedRef }, reactGridLayoutProps),
92
+ }, preparedClassName), "data-qa": "dashkit-grid-item", style: style, ref: this.props.forwardedRef }, reactGridLayoutProps, (focusable
93
+ ? {
94
+ onFocus: this.onFocusHandler,
95
+ onBlur: this.onBlurHandler,
96
+ tabIndex: -1,
97
+ }
98
+ : {})),
44
99
  react_1.default.createElement("div", { className: b('item', { editMode: editMode && !_editActive && !noOverlay }) },
45
- react_1.default.createElement(Item_1.default, { id: this.props.id, item: this.props.item, shouldItemUpdate: !isDragging, width: width, height: height, transform: transform, adjustWidgetLayout: this.props.adjustWidgetLayout, layout: this.props.layout, forwardedPluginRef: this.props.forwardedPluginRef })),
100
+ react_1.default.createElement(Item_1.default, { 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 })),
46
101
  !noOverlay && this.renderOverlay(),
47
102
  preparedChildren));
48
103
  }
@@ -56,11 +111,13 @@ GridItem.propTypes = {
56
111
  overlayControls: prop_types_1.default.object,
57
112
  forwardedRef: prop_types_1.default.any,
58
113
  forwardedPluginRef: prop_types_1.default.any,
114
+ isPlaceholder: prop_types_1.default.bool,
59
115
  // from react-grid-layout:
60
116
  children: prop_types_1.default.node,
61
117
  className: prop_types_1.default.string,
62
118
  style: prop_types_1.default.object,
63
119
  noOverlay: prop_types_1.default.bool,
120
+ focusable: prop_types_1.default.bool,
64
121
  withCustomHandle: prop_types_1.default.bool,
65
122
  onMouseDown: prop_types_1.default.func,
66
123
  onMouseUp: prop_types_1.default.func,
@@ -68,6 +125,8 @@ GridItem.propTypes = {
68
125
  onTouchStart: prop_types_1.default.func,
69
126
  };
70
127
  GridItem.contextType = DashKitContext_1.DashKitContext;
71
- exports.default = react_1.default.forwardRef((props, ref) => {
128
+ const GridItemForwarderRef = react_1.default.forwardRef((props, ref) => {
72
129
  return react_1.default.createElement(GridItem, Object.assign({}, props, { forwardedRef: ref }));
73
130
  });
131
+ GridItemForwarderRef.displayName = 'forwardRef(GridItem)';
132
+ exports.default = GridItemForwarderRef;
@@ -21,6 +21,9 @@ export default class GridLayout extends React.PureComponent<any, any, any> {
21
21
  reloadItems(): void;
22
22
  _onStart: () => void;
23
23
  _onStop: (newLayout: any) => void;
24
+ _onDropDragOver: (e: any) => any;
25
+ _onDrop: (layout: any, item: any, e: any) => false | undefined;
26
+ renderTemporaryPlaceholder(): JSX.Element | null;
24
27
  render(): JSX.Element;
25
28
  }
26
29
  import React from 'react';
@@ -6,7 +6,45 @@ const react_grid_layout_1 = tslib_1.__importStar(require("react-grid-layout"));
6
6
  const constants_1 = require("../../constants");
7
7
  const DashKitContext_1 = require("../../context/DashKitContext");
8
8
  const GridItem_1 = tslib_1.__importDefault(require("../GridItem/GridItem"));
9
- const Layout = (0, react_grid_layout_1.WidthProvider)(react_grid_layout_1.default); // eslint-disable-line new-cap
9
+ class DragOverLayout extends react_grid_layout_1.default {
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
+ if (isDroppingItem) {
28
+ // Drop item from outside gets 0,0 droppingPosition
29
+ // centering cursor on newly creted grid item
30
+ // And cause grid-layout using it's own GridItem to make it look
31
+ // like overlay adding className
32
+ const gridItem = super.processGridItem(child, isDroppingItem);
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 super.processGridItem(child, isDroppingItem);
45
+ }
46
+ }
47
+ const Layout = (0, react_grid_layout_1.WidthProvider)(DragOverLayout); // eslint-disable-line new-cap
10
48
  class GridLayout extends react_1.default.PureComponent {
11
49
  constructor(props, context) {
12
50
  super(props, context);
@@ -32,13 +70,38 @@ class GridLayout extends react_1.default.PureComponent {
32
70
  return getItemsMeta(this.pluginsRefs);
33
71
  };
34
72
  this._onStart = () => {
73
+ if (this.temporaryLayout)
74
+ return;
35
75
  this.setState({ isDragging: true });
36
76
  };
37
77
  this._onStop = (newLayout) => {
38
- const { layoutChange } = this.context;
39
- layoutChange(newLayout);
78
+ const { layoutChange, onDrop, temporaryLayout } = this.context;
79
+ if (temporaryLayout) {
80
+ onDrop === null || onDrop === void 0 ? void 0 : onDrop(newLayout, newLayout.find(({ i }) => i === constants_1.TEMPORARY_ITEM_ID));
81
+ }
82
+ else {
83
+ layoutChange(newLayout);
84
+ }
40
85
  this.setState({ isDragging: false });
41
86
  };
87
+ this._onDropDragOver = (e) => {
88
+ const { editMode, onDropDragOver, temporaryLayout } = this.context;
89
+ if (!editMode) {
90
+ return false;
91
+ }
92
+ const result = onDropDragOver(e);
93
+ if (temporaryLayout) {
94
+ return false;
95
+ }
96
+ return result;
97
+ };
98
+ this._onDrop = (layout, item, e) => {
99
+ const { editMode, temporaryLayout, onDrop } = this.context;
100
+ if (!editMode && temporaryLayout) {
101
+ return false;
102
+ }
103
+ onDrop === null || onDrop === void 0 ? void 0 : onDrop(layout, item, e);
104
+ };
42
105
  this.pluginsRefs = [];
43
106
  this.state = {
44
107
  isDragging: false,
@@ -71,16 +134,33 @@ class GridLayout extends react_1.default.PureComponent {
71
134
  this._timeout = setTimeout(() => this.reloadItems(), reloadIntervalRemains <= 0 ? autoupdateIntervalMs : reloadIntervalRemains);
72
135
  }
73
136
  }
137
+ renderTemporaryPlaceholder() {
138
+ const { temporaryLayout, dragOverPlugin, noOverlay, draggableHandleClassName } = this.context;
139
+ if (!temporaryLayout) {
140
+ return null;
141
+ }
142
+ const id = constants_1.TEMPORARY_ITEM_ID;
143
+ const type = dragOverPlugin.type;
144
+ return (react_1.default.createElement(GridItem_1.default, { key: id, id: id, item: { id, type, data: {} }, layout: temporaryLayout, adjustWidgetLayout: this.adjustWidgetLayout, isDragging: this.state.isDragging, isPlaceholder: true, noOverlay: noOverlay, withCustomHandle: Boolean(draggableHandleClassName), overlayControls: this.props.overlayControls }));
145
+ }
74
146
  render() {
75
- const { layout, config, registerManager, editMode, noOverlay, draggableHandleClassName } = this.context;
147
+ const { layout, temporaryLayout, config, registerManager, editMode, noOverlay, focusable, draggableHandleClassName, outerDnDEnable, } = this.context;
76
148
  this.pluginsRefs.length = config.items.length;
77
- return (react_1.default.createElement(Layout, Object.assign({}, registerManager.gridLayout, { layout: layout, isDraggable: editMode, isResizable: editMode, onDragStart: this._onStart, onDragStop: this._onStop, onResizeStart: this._onStart, onResizeStop: this._onStop }, (draggableHandleClassName
149
+ 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
78
150
  ? { draggableHandle: `.${draggableHandleClassName}` }
79
- : null), { draggableCancel: `.${constants_1.OVERLAY_CONTROLS_CLASS_NAME}` }), config.items.map((item, i) => {
80
- return (react_1.default.createElement(GridItem_1.default, { forwardedPluginRef: (pluginRef) => {
81
- this.pluginsRefs[i] = pluginRef;
82
- }, key: item.id, id: item.id, item: item, layout: layout, adjustWidgetLayout: this.adjustWidgetLayout, isDragging: this.state.isDragging, noOverlay: noOverlay, withCustomHandle: Boolean(draggableHandleClassName), overlayControls: this.props.overlayControls }));
83
- })));
151
+ : null), (outerDnDEnable
152
+ ? {
153
+ isDroppable: true,
154
+ onDropDragOver: this._onDropDragOver,
155
+ onDrop: this._onDrop,
156
+ }
157
+ : null), { draggableCancel: `.${constants_1.OVERLAY_CONTROLS_CLASS_NAME}` }),
158
+ config.items.map((item, i) => {
159
+ return (react_1.default.createElement(GridItem_1.default, { forwardedPluginRef: (pluginRef) => {
160
+ this.pluginsRefs[i] = pluginRef;
161
+ }, key: item.id, id: item.id, item: item, layout: temporaryLayout || layout, adjustWidgetLayout: this.adjustWidgetLayout, isDragging: this.state.isDragging, noOverlay: noOverlay, focusable: focusable, withCustomHandle: Boolean(draggableHandleClassName), overlayControls: this.props.overlayControls }));
162
+ }),
163
+ this.renderTemporaryPlaceholder()));
84
164
  }
85
165
  }
86
166
  GridLayout.contextType = DashKitContext_1.DashKitContext;
@@ -1,4 +1,4 @@
1
- .dashkit-item__renderer {
1
+ .dashkit-item__placeholder, .dashkit-item__renderer {
2
2
  position: absolute;
3
3
  inset: 0;
4
4
  }
@@ -56,6 +56,7 @@ declare const _default: {
56
56
  width: PropTypes.Requireable<number>;
57
57
  height: PropTypes.Requireable<number>;
58
58
  transform: PropTypes.Requireable<string>;
59
+ isPlaceholder: PropTypes.Requireable<boolean>;
59
60
  forwardedPluginRef: PropTypes.Requireable<any>;
60
61
  };
61
62
  contextType: React.Context<any>;
@@ -7,11 +7,16 @@ const prepareItem_1 = require("../../hocs/prepareItem");
7
7
  const cn_1 = require("../../utils/cn");
8
8
  const b = (0, cn_1.cn)('dashkit-item');
9
9
  // TODO: getDerivedStateFromError и заглушка с ошибкой
10
- const Item = ({ registerManager, rendererProps, type, forwardedPluginRef }) => {
10
+ const Item = ({ registerManager, rendererProps, type, isPlaceholder, forwardedPluginRef }) => {
11
+ var _a, _b;
11
12
  if (!registerManager.check(type)) {
12
13
  console.warn(`type [${type}] не зарегистрирован`);
13
14
  return null;
14
15
  }
16
+ if (isPlaceholder) {
17
+ return (react_1.default.createElement("div", { className: b('placeholder') }, ((_b = (_a = registerManager
18
+ .getItem(type)).placeholderRenderer) === null || _b === void 0 ? void 0 : _b.call(_a, rendererProps, forwardedPluginRef)) || null));
19
+ }
15
20
  return (react_1.default.createElement("div", { className: b('renderer') }, registerManager.getItem(type).renderer(rendererProps, forwardedPluginRef)));
16
21
  };
17
22
  Item.propTypes = {
@@ -19,5 +24,6 @@ Item.propTypes = {
19
24
  rendererProps: prop_types_1.default.object,
20
25
  registerManager: prop_types_1.default.object,
21
26
  type: prop_types_1.default.string,
27
+ isPlaceholder: prop_types_1.default.bool,
22
28
  };
23
29
  exports.default = (0, prepareItem_1.prepareItem)(Item);
@@ -2,3 +2,4 @@ export * from './DashKit';
2
2
  export type { OverlayControlItem, PreparedCopyItemOptions } from './OverlayControls/OverlayControls';
3
3
  export * from './ActionPanel/ActionPanel';
4
4
  export type { ActionPanelItem, ActionPanelProps } from './ActionPanel/types';
5
+ export * from './DashKitDnDWrapper/DashKitDnDWrapper';
@@ -3,3 +3,4 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const tslib_1 = require("tslib");
4
4
  tslib_1.__exportStar(require("./DashKit"), exports);
5
5
  tslib_1.__exportStar(require("./ActionPanel/ActionPanel"), exports);
6
+ tslib_1.__exportStar(require("./DashKitDnDWrapper/DashKitDnDWrapper"), exports);
@@ -1,6 +1,8 @@
1
1
  export declare const COPIED_WIDGET_STORE_KEY = "dashCopiedItem";
2
2
  export declare const DEFAULT_NAMESPACE = "default";
3
3
  export declare const OVERLAY_CONTROLS_CLASS_NAME = "dashkit-overlay-controls";
4
+ export declare const OVERLAY_CLASS_NAME = "dashkit-grid-item__overlay";
5
+ export declare const TEMPORARY_ITEM_ID = "__dropping-elem__";
4
6
  export declare const MenuItems: {
5
7
  readonly Copy: "copy";
6
8
  readonly Delete: "delete";
@@ -1,9 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.MenuItems = exports.OVERLAY_CONTROLS_CLASS_NAME = exports.DEFAULT_NAMESPACE = exports.COPIED_WIDGET_STORE_KEY = void 0;
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;
4
4
  exports.COPIED_WIDGET_STORE_KEY = 'dashCopiedItem';
5
5
  exports.DEFAULT_NAMESPACE = 'default';
6
6
  exports.OVERLAY_CONTROLS_CLASS_NAME = 'dashkit-overlay-controls';
7
+ exports.OVERLAY_CLASS_NAME = 'dashkit-grid-item__overlay';
8
+ exports.TEMPORARY_ITEM_ID = '__dropping-elem__';
7
9
  exports.MenuItems = {
8
10
  Copy: 'copy',
9
11
  Delete: 'delete',
@@ -1,2 +1,3 @@
1
1
  export const DashKitContext: React.Context<any>;
2
+ export const DashKitDnDContext: React.Context<any>;
2
3
  import React from 'react';
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.DashKitContext = void 0;
3
+ exports.DashKitDnDContext = exports.DashKitContext = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const react_1 = tslib_1.__importDefault(require("react"));
6
6
  const DashKitContext = react_1.default.createContext();
7
7
  exports.DashKitContext = DashKitContext;
8
+ const DashKitDnDContext = react_1.default.createContext();
9
+ exports.DashKitDnDContext = DashKitDnDContext;
@@ -56,6 +56,7 @@ export function prepareItem(Component: any): {
56
56
  width: PropTypes.Requireable<number>;
57
57
  height: PropTypes.Requireable<number>;
58
58
  transform: PropTypes.Requireable<string>;
59
+ isPlaceholder: PropTypes.Requireable<boolean>;
59
60
  forwardedPluginRef: PropTypes.Requireable<any>;
60
61
  };
61
62
  contextType: React.Context<any>;
@@ -26,7 +26,7 @@ function prepareItem(Component) {
26
26
  return true;
27
27
  }
28
28
  render() {
29
- const { id, width, height, item, adjustWidgetLayout, layout } = this.props;
29
+ const { id, width, height, item, adjustWidgetLayout, layout, isPlaceholder } = this.props;
30
30
  const { itemsState, itemsParams, registerManager, settings, context, editMode } = this.context;
31
31
  const { type, data, defaults, namespace } = item;
32
32
  const rendererProps = {
@@ -45,8 +45,9 @@ function prepareItem(Component) {
45
45
  layout,
46
46
  gridLayout: registerManager.gridLayout,
47
47
  adjustWidgetLayout,
48
+ isPlaceholder,
48
49
  };
49
- return (react_1.default.createElement(Component, { forwardedPluginRef: this.props.forwardedPluginRef, rendererProps: rendererProps, registerManager: registerManager, type: type }));
50
+ return (react_1.default.createElement(Component, { forwardedPluginRef: this.props.forwardedPluginRef, rendererProps: rendererProps, registerManager: registerManager, type: type, isPlaceholder: isPlaceholder }));
50
51
  }
51
52
  },
52
53
  _a.propTypes = {
@@ -58,6 +59,7 @@ function prepareItem(Component) {
58
59
  width: prop_types_1.default.number,
59
60
  height: prop_types_1.default.number,
60
61
  transform: prop_types_1.default.string,
62
+ isPlaceholder: prop_types_1.default.bool,
61
63
  forwardedPluginRef: prop_types_1.default.any,
62
64
  },
63
65
  _a.contextType = DashKitContext_1.DashKitContext,