@atlaskit/editor-plugin-block-controls 1.4.19 → 1.4.21

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/CHANGELOG.md CHANGED
@@ -1,5 +1,25 @@
1
1
  # @atlaskit/editor-plugin-block-controls
2
2
 
3
+ ## 1.4.21
4
+
5
+ ### Patch Changes
6
+
7
+ - [#111695](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/111695)
8
+ [`4dadac69832d7`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/4dadac69832d7) -
9
+ Refactor Pragmatic usage
10
+ - [#111695](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/111695)
11
+ [`c8e7bf89f5bd8`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/c8e7bf89f5bd8) -
12
+ reduce rerenders in mousemovewrapper
13
+
14
+ ## 1.4.20
15
+
16
+ ### Patch Changes
17
+
18
+ - [#111514](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/111514)
19
+ [`a1b90bef5f34b`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/a1b90bef5f34b) -
20
+ [ux] Revert: Fix cursor and handle position when changing node type
21
+ - Updated dependencies
22
+
3
23
  ## 1.4.19
4
24
 
5
25
  ### Patch Changes
@@ -12,18 +12,32 @@ var _safePlugin = require("@atlaskit/editor-common/safe-plugin");
12
12
  var _state = require("@atlaskit/editor-prosemirror/state");
13
13
  var _view = require("@atlaskit/editor-prosemirror/view");
14
14
  var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
15
+ var _element = require("@atlaskit/pragmatic-drag-and-drop-auto-scroll/element");
16
+ var _combine = require("@atlaskit/pragmatic-drag-and-drop/combine");
15
17
  var _adapter = require("@atlaskit/pragmatic-drag-and-drop/element/adapter");
16
18
  var _decorations = require("./decorations");
17
19
  var key = exports.key = new _state.PluginKey('blockControls');
18
20
  var destroyFn = function destroyFn(api) {
19
- return (0, _adapter.monitorForElements)({
21
+ var scrollable = document.querySelector('.fabric-editor-popup-scroll-parent');
22
+ var cleanupFn = [];
23
+ if (scrollable) {
24
+ cleanupFn.push((0, _element.autoScrollForElements)({
25
+ element: scrollable
26
+ }));
27
+ }
28
+ cleanupFn.push((0, _adapter.monitorForElements)({
20
29
  canMonitor: function canMonitor(_ref) {
21
30
  var source = _ref.source;
22
31
  return source.data.type === 'element';
23
32
  },
33
+ onDragStart: function onDragStart() {
34
+ scrollable.style.setProperty('scroll-behavior', 'unset');
35
+ },
24
36
  onDrop: function onDrop(_ref2) {
25
37
  var location = _ref2.location,
26
38
  source = _ref2.source;
39
+ scrollable.style.setProperty('scroll-behavior', null);
40
+
27
41
  // if no drop targets are rendered, assume that drop is invalid
28
42
  if (location.current.dropTargets.length === 0) {
29
43
  var _api$core;
@@ -48,7 +62,8 @@ var destroyFn = function destroyFn(api) {
48
62
  });
49
63
  }
50
64
  }
51
- });
65
+ }));
66
+ return _combine.combine.apply(void 0, cleanupFn);
52
67
  };
53
68
  var initialState = {
54
69
  decorations: _view.DecorationSet.empty,
@@ -56,8 +71,6 @@ var initialState = {
56
71
  activeNode: null,
57
72
  isDragging: false,
58
73
  isMenuOpen: false,
59
- start: null,
60
- end: null,
61
74
  editorHeight: 0,
62
75
  isResizerResizing: false,
63
76
  isDocSizeLimitEnabled: false
@@ -74,7 +87,7 @@ var createPlugin = exports.createPlugin = function createPlugin(api) {
74
87
  return initialState;
75
88
  },
76
89
  apply: function apply(tr, currentState, oldState, newState) {
77
- var _decorationState, _meta$activeNode, _meta$isDragging, _meta$editorHeight, _isResizerResizing;
90
+ var _decorationState, _meta$activeNode, _meta$isDragging, _meta$editorHeight;
78
91
  if (initialState.isDocSizeLimitEnabled && newState.doc.nodeSize > DRAG_AND_DROP_DOC_SIZE_LIMIT) {
79
92
  return initialState;
80
93
  }
@@ -89,14 +102,10 @@ var createPlugin = exports.createPlugin = function createPlugin(api) {
89
102
  // If tables or media are being resized, we want to hide the drag handle
90
103
  var resizerMeta = tr.getMeta('is-resizer-resizing');
91
104
  isResizerResizing = resizerMeta !== null && resizerMeta !== void 0 ? resizerMeta : isResizerResizing;
92
- var isEmptyDoc = newState.doc.childCount === 1 && newState.doc.nodeSize <= 4;
93
-
94
- // This is not targeted enough - it's trying to catch events like expand being set to breakout
95
- var maybeWidthUpdated = tr.docChanged && oldState.doc.nodeSize === newState.doc.nodeSize && oldState.doc.childCount === newState.doc.childCount;
96
105
  var nodeCountChanged = oldState.doc.childCount !== newState.doc.childCount;
97
106
 
98
107
  // During resize, remove the drag handle widget
99
- if (isResizerResizing || nodeCountChanged) {
108
+ if (isResizerResizing || nodeCountChanged || meta !== null && meta !== void 0 && meta.nodeMoved) {
100
109
  var oldHandle = decorations.find().filter(function (_ref5) {
101
110
  var spec = _ref5.spec;
102
111
  return spec.id === 'drag-handle';
@@ -104,22 +113,21 @@ var createPlugin = exports.createPlugin = function createPlugin(api) {
104
113
  decorations = decorations.remove(oldHandle);
105
114
  }
106
115
 
116
+ // This is not targeted enough - it's trying to catch events like expand being set to breakout
117
+ var maybeWidthUpdated = tr.docChanged && oldState.doc.nodeSize === newState.doc.nodeSize && !nodeCountChanged;
118
+ var redrawDecorations = decorations === _view.DecorationSet.empty || (meta === null || meta === void 0 ? void 0 : meta.editorHeight) !== undefined && (meta === null || meta === void 0 ? void 0 : meta.editorHeight) !== editorHeight || maybeWidthUpdated || nodeCountChanged || resizerMeta === false || !!(meta !== null && meta !== void 0 && meta.nodeMoved) && tr.docChanged;
119
+
107
120
  // Draw node and mouseWrapper decorations at top level node if decorations is empty, editor height changes or node is moved
108
- var redrawDecorations = decorations === _view.DecorationSet.empty || (meta === null || meta === void 0 ? void 0 : meta.editorHeight) !== undefined && (meta === null || meta === void 0 ? void 0 : meta.editorHeight) !== editorHeight || maybeWidthUpdated || nodeCountChanged || resizerMeta === false || (meta === null || meta === void 0 ? void 0 : meta.nodeMoved) && tr.docChanged;
109
- if (redrawDecorations && isResizerResizing === false && api) {
121
+ if (redrawDecorations && !isResizerResizing && api) {
110
122
  decorations = _view.DecorationSet.create(newState.doc, []);
111
123
  var nodeDecs = (0, _decorations.nodeDecorations)(newState);
112
124
  var mouseWrapperDecs = (0, _decorations.mouseMoveWrapperDecorations)(newState, api);
113
125
  decorations = decorations.add(newState.doc, [].concat((0, _toConsumableArray2.default)(nodeDecs), (0, _toConsumableArray2.default)(mouseWrapperDecs)));
114
- if (activeNode) {
115
- var newActiveNode = activeNode && tr.doc.nodeAt(activeNode.pos);
116
- var nodeType = activeNode.nodeType;
117
- var anchorName = activeNode.anchorName;
118
- if (newActiveNode && (newActiveNode === null || newActiveNode === void 0 ? void 0 : newActiveNode.type.name) !== activeNode.nodeType && !(meta !== null && meta !== void 0 && meta.nodeMoved)) {
119
- nodeType = newActiveNode.type.name;
120
- anchorName = activeNode.anchorName.replace(activeNode.nodeType, nodeType);
121
- }
122
- var draghandleDec = (0, _decorations.dragHandleDecoration)(activeNode.pos, anchorName, nodeType, api);
126
+
127
+ // Note: Quite often the handle is not in the right position after a node is moved
128
+ // it is safer for now to not show it when a node is moved
129
+ if (activeNode && !(meta !== null && meta !== void 0 && meta.nodeMoved)) {
130
+ var draghandleDec = (0, _decorations.dragHandleDecoration)(activeNode.pos, activeNode.anchorName, activeNode.nodeType, api);
123
131
  decorations = decorations.add(newState.doc, [draghandleDec]);
124
132
  }
125
133
  }
@@ -176,6 +184,7 @@ var createPlugin = exports.createPlugin = function createPlugin(api) {
176
184
  anchorName: activeNode.anchorName,
177
185
  nodeType: activeNode.nodeType
178
186
  } : activeNode;
187
+ var isEmptyDoc = newState.doc.childCount === 1 && newState.doc.nodeSize <= 4;
179
188
  return {
180
189
  decorations: decorations,
181
190
  decorationState: (_decorationState = decorationState) !== null && _decorationState !== void 0 ? _decorationState : currentState.decorationState,
@@ -183,7 +192,7 @@ var createPlugin = exports.createPlugin = function createPlugin(api) {
183
192
  isDragging: (_meta$isDragging = meta === null || meta === void 0 ? void 0 : meta.isDragging) !== null && _meta$isDragging !== void 0 ? _meta$isDragging : currentState.isDragging,
184
193
  isMenuOpen: meta !== null && meta !== void 0 && meta.toggleMenu ? !isMenuOpen : isMenuOpen,
185
194
  editorHeight: (_meta$editorHeight = meta === null || meta === void 0 ? void 0 : meta.editorHeight) !== null && _meta$editorHeight !== void 0 ? _meta$editorHeight : currentState.editorHeight,
186
- isResizerResizing: (_isResizerResizing = isResizerResizing) !== null && _isResizerResizing !== void 0 ? _isResizerResizing : isResizerResizing,
195
+ isResizerResizing: isResizerResizing,
187
196
  isDocSizeLimitEnabled: initialState.isDocSizeLimitEnabled
188
197
  };
189
198
  }
@@ -216,10 +225,13 @@ var createPlugin = exports.createPlugin = function createPlugin(api) {
216
225
 
217
226
  // Start observing the editor DOM element
218
227
  resizeObserver.observe(dom);
228
+
229
+ // Start pragmatic monitors
230
+ var pragmaticCleanup = destroyFn(api);
219
231
  return {
220
232
  destroy: function destroy() {
221
233
  resizeObserver.unobserve(dom);
222
- return destroyFn(api);
234
+ return pragmaticCleanup;
223
235
  }
224
236
  };
225
237
  }
@@ -10,9 +10,7 @@ var _react = require("react");
10
10
  var _react2 = require("@emotion/react");
11
11
  var _analytics = require("@atlaskit/editor-common/analytics");
12
12
  var _hooks = require("@atlaskit/editor-common/hooks");
13
- var _element = require("@atlaskit/pragmatic-drag-and-drop-auto-scroll/element");
14
13
  var _box = require("@atlaskit/pragmatic-drag-and-drop-react-drop-indicator/box");
15
- var _combine = require("@atlaskit/pragmatic-drag-and-drop/combine");
16
14
  var _adapter = require("@atlaskit/pragmatic-drag-and-drop/element/adapter");
17
15
  /** @jsx jsx */
18
16
 
@@ -47,21 +45,11 @@ var DropTarget = exports.DropTarget = function DropTarget(_ref) {
47
45
  if (!element) {
48
46
  return;
49
47
  }
50
- var combined = [];
51
- var scrollable = document.querySelector('.fabric-editor-popup-scroll-parent');
52
- if (scrollable) {
53
- combined.push((0, _element.autoScrollForElements)({
54
- element: scrollable
55
- }));
56
- }
57
- combined.push((0, _adapter.dropTargetForElements)({
48
+ return (0, _adapter.dropTargetForElements)({
58
49
  element: element,
59
50
  getIsSticky: function getIsSticky() {
60
51
  return true;
61
52
  },
62
- onDrag: function onDrag() {
63
- scrollable.style.setProperty('scroll-behavior', 'unset');
64
- },
65
53
  onDragEnter: function onDragEnter() {
66
54
  setIsDraggedOver(true);
67
55
  },
@@ -70,7 +58,6 @@ var DropTarget = exports.DropTarget = function DropTarget(_ref) {
70
58
  },
71
59
  onDrop: function onDrop() {
72
60
  var _api$blockControls;
73
- scrollable.style.setProperty('scroll-behavior', null);
74
61
  var _ref2 = (api === null || api === void 0 || (_api$blockControls = api.blockControls) === null || _api$blockControls === void 0 ? void 0 : _api$blockControls.sharedState.currentState()) || {},
75
62
  activeNode = _ref2.activeNode,
76
63
  decorationState = _ref2.decorationState;
@@ -103,8 +90,7 @@ var DropTarget = exports.DropTarget = function DropTarget(_ref) {
103
90
  });
104
91
  }
105
92
  }
106
- }));
107
- return _combine.combine.apply(void 0, combined);
93
+ });
108
94
  }, [index, api]);
109
95
  return (
110
96
  // Note: Firefox has trouble with using a button element as the handle for drag and drop
@@ -9,7 +9,6 @@ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/sli
9
9
  var _react = require("react");
10
10
  var _react2 = require("@emotion/react");
11
11
  var _bindEventListener = require("bind-event-listener");
12
- var _hooks = require("@atlaskit/editor-common/hooks");
13
12
  var _dragHandlePositions = require("../utils/drag-handle-positions");
14
13
  /** @jsx jsx */
15
14
 
@@ -29,21 +28,17 @@ var MouseMoveWrapper = exports.MouseMoveWrapper = function MouseMoveWrapper(_ref
29
28
  anchorName = _ref.anchorName,
30
29
  nodeType = _ref.nodeType,
31
30
  getPos = _ref.getPos;
32
- var _useSharedPluginState = (0, _hooks.useSharedPluginState)(api, ['blockControls']),
33
- blockControlsState = _useSharedPluginState.blockControlsState;
31
+ // Using a ref for isDragging reduce re-renders
32
+ var isDragging = (0, _react.useRef)(false);
34
33
  var _useState = (0, _react.useState)(false),
35
34
  _useState2 = (0, _slicedToArray2.default)(_useState, 2),
36
- isDragging = _useState2[0],
37
- setIsDragging = _useState2[1];
38
- var _useState3 = (0, _react.useState)(false),
39
- _useState4 = (0, _slicedToArray2.default)(_useState3, 2),
40
- hideWrapper = _useState4[0],
41
- setHideWrapper = _useState4[1];
35
+ hideWrapper = _useState2[0],
36
+ setHideWrapper = _useState2[1];
42
37
  var ref = (0, _react.useRef)(null);
43
- var _useState5 = (0, _react.useState)(),
44
- _useState6 = (0, _slicedToArray2.default)(_useState5, 2),
45
- pos = _useState6[0],
46
- setPos = _useState6[1];
38
+ var _useState3 = (0, _react.useState)(),
39
+ _useState4 = (0, _slicedToArray2.default)(_useState3, 2),
40
+ pos = _useState4[0],
41
+ setPos = _useState4[1];
47
42
  (0, _react.useEffect)(function () {
48
43
  // Adding this event listener to fix issue where wrapper isn't hidden if user navigates to node before page finishes loading
49
44
  // This will be removed when we refactor to remove this component
@@ -63,34 +58,42 @@ var MouseMoveWrapper = exports.MouseMoveWrapper = function MouseMoveWrapper(_ref
63
58
  };
64
59
  }, []);
65
60
  var onMouseEnter = (0, _react.useCallback)(function () {
66
- if (!isDragging) {
61
+ if (!isDragging.current) {
67
62
  setHideWrapper(true);
68
63
  }
69
64
  var pos = getPos();
70
65
  if (pos === undefined) {
71
66
  return;
72
67
  }
73
- if (api && api.blockControls && !isDragging) {
68
+ if (api && api.blockControls && !isDragging.current) {
74
69
  var _api$core;
75
70
  api === null || api === void 0 || (_api$core = api.core) === null || _api$core === void 0 || _api$core.actions.execute(api.blockControls.commands.showDragHandleAt(pos, anchorName, nodeType));
76
71
  }
77
- }, [setHideWrapper, getPos, isDragging, api, anchorName, nodeType]);
78
- (0, _react.useEffect)(function () {
79
- var _blockControlsState$a;
80
- setIsDragging(Boolean(blockControlsState === null || blockControlsState === void 0 ? void 0 : blockControlsState.isDragging));
81
- var pos = getPos();
82
- if (!(blockControlsState !== null && blockControlsState !== void 0 && blockControlsState.activeNode)) {
83
- return;
84
- }
85
- if ((blockControlsState === null || blockControlsState === void 0 || (_blockControlsState$a = blockControlsState.activeNode) === null || _blockControlsState$a === void 0 ? void 0 : _blockControlsState$a.pos) !== pos && !(blockControlsState !== null && blockControlsState !== void 0 && blockControlsState.isDragging)) {
72
+ }, [getPos, isDragging, api, anchorName, nodeType]);
73
+
74
+ //THIS IS TRIGGERED A LOT!
75
+ var onSharedStateChange = (0, _react.useCallback)(function (_ref2) {
76
+ var _nextSharedState$acti;
77
+ var nextSharedState = _ref2.nextSharedState;
78
+ if ((nextSharedState === null || nextSharedState === void 0 || (_nextSharedState$acti = nextSharedState.activeNode) === null || _nextSharedState$acti === void 0 ? void 0 : _nextSharedState$acti.anchorName) !== anchorName && !isDragging.current) {
86
79
  setHideWrapper(false);
87
- return;
88
80
  }
89
- if (blockControlsState !== null && blockControlsState !== void 0 && blockControlsState.isDragging) {
81
+ if (nextSharedState !== null && nextSharedState !== void 0 && nextSharedState.isDragging && !isDragging.current) {
82
+ isDragging.current = true;
90
83
  setHideWrapper(true);
91
- return;
92
84
  }
93
- }, [getPos, blockControlsState]);
85
+ if ((nextSharedState === null || nextSharedState === void 0 ? void 0 : nextSharedState.isDragging) === false && isDragging.current) {
86
+ isDragging.current = false;
87
+ setHideWrapper(false);
88
+ }
89
+ }, [anchorName]);
90
+ (0, _react.useEffect)(function () {
91
+ var _api$blockControls;
92
+ var unbind = api === null || api === void 0 || (_api$blockControls = api.blockControls) === null || _api$blockControls === void 0 ? void 0 : _api$blockControls.sharedState.onChange(onSharedStateChange);
93
+ return function () {
94
+ unbind === null || unbind === void 0 || unbind();
95
+ };
96
+ }, [onSharedStateChange, api]);
94
97
  (0, _react.useLayoutEffect)(function () {
95
98
  var supportsAnchor = CSS.supports('height', "anchor-size(".concat(anchorName, " height)")) && CSS.supports('top', "anchor(".concat(anchorName, " start)"));
96
99
  if (supportsAnchor) {
@@ -4,18 +4,32 @@ import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
4
4
  import { PluginKey } from '@atlaskit/editor-prosemirror/state';
5
5
  import { DecorationSet } from '@atlaskit/editor-prosemirror/view';
6
6
  import { getBooleanFF } from '@atlaskit/platform-feature-flags';
7
+ import { autoScrollForElements } from '@atlaskit/pragmatic-drag-and-drop-auto-scroll/element';
8
+ import { combine } from '@atlaskit/pragmatic-drag-and-drop/combine';
7
9
  import { monitorForElements } from '@atlaskit/pragmatic-drag-and-drop/element/adapter';
8
10
  import { dragHandleDecoration, dropTargetDecorations, mouseMoveWrapperDecorations, nodeDecorations } from './decorations';
9
11
  export const key = new PluginKey('blockControls');
10
12
  const destroyFn = api => {
11
- return monitorForElements({
13
+ const scrollable = document.querySelector('.fabric-editor-popup-scroll-parent');
14
+ const cleanupFn = [];
15
+ if (scrollable) {
16
+ cleanupFn.push(autoScrollForElements({
17
+ element: scrollable
18
+ }));
19
+ }
20
+ cleanupFn.push(monitorForElements({
12
21
  canMonitor: ({
13
22
  source
14
23
  }) => source.data.type === 'element',
24
+ onDragStart: () => {
25
+ scrollable.style.setProperty('scroll-behavior', 'unset');
26
+ },
15
27
  onDrop: ({
16
28
  location,
17
29
  source
18
30
  }) => {
31
+ scrollable.style.setProperty('scroll-behavior', null);
32
+
19
33
  // if no drop targets are rendered, assume that drop is invalid
20
34
  if (location.current.dropTargets.length === 0) {
21
35
  var _api$core;
@@ -42,7 +56,8 @@ const destroyFn = api => {
42
56
  });
43
57
  }
44
58
  }
45
- });
59
+ }));
60
+ return combine(...cleanupFn);
46
61
  };
47
62
  const initialState = {
48
63
  decorations: DecorationSet.empty,
@@ -50,8 +65,6 @@ const initialState = {
50
65
  activeNode: null,
51
66
  isDragging: false,
52
67
  isMenuOpen: false,
53
- start: null,
54
- end: null,
55
68
  editorHeight: 0,
56
69
  isResizerResizing: false,
57
70
  isDocSizeLimitEnabled: false
@@ -68,7 +81,7 @@ export const createPlugin = api => {
68
81
  return initialState;
69
82
  },
70
83
  apply(tr, currentState, oldState, newState) {
71
- var _decorationState, _meta$activeNode, _meta$isDragging, _meta$editorHeight, _isResizerResizing;
84
+ var _decorationState, _meta$activeNode, _meta$isDragging, _meta$editorHeight;
72
85
  if (initialState.isDocSizeLimitEnabled && newState.doc.nodeSize > DRAG_AND_DROP_DOC_SIZE_LIMIT) {
73
86
  return initialState;
74
87
  }
@@ -85,36 +98,31 @@ export const createPlugin = api => {
85
98
  // If tables or media are being resized, we want to hide the drag handle
86
99
  const resizerMeta = tr.getMeta('is-resizer-resizing');
87
100
  isResizerResizing = resizerMeta !== null && resizerMeta !== void 0 ? resizerMeta : isResizerResizing;
88
- const isEmptyDoc = newState.doc.childCount === 1 && newState.doc.nodeSize <= 4;
89
-
90
- // This is not targeted enough - it's trying to catch events like expand being set to breakout
91
- const maybeWidthUpdated = tr.docChanged && oldState.doc.nodeSize === newState.doc.nodeSize && oldState.doc.childCount === newState.doc.childCount;
92
101
  const nodeCountChanged = oldState.doc.childCount !== newState.doc.childCount;
93
102
 
94
103
  // During resize, remove the drag handle widget
95
- if (isResizerResizing || nodeCountChanged) {
104
+ if (isResizerResizing || nodeCountChanged || meta !== null && meta !== void 0 && meta.nodeMoved) {
96
105
  const oldHandle = decorations.find().filter(({
97
106
  spec
98
107
  }) => spec.id === 'drag-handle');
99
108
  decorations = decorations.remove(oldHandle);
100
109
  }
101
110
 
111
+ // This is not targeted enough - it's trying to catch events like expand being set to breakout
112
+ const maybeWidthUpdated = tr.docChanged && oldState.doc.nodeSize === newState.doc.nodeSize && !nodeCountChanged;
113
+ const redrawDecorations = decorations === DecorationSet.empty || (meta === null || meta === void 0 ? void 0 : meta.editorHeight) !== undefined && (meta === null || meta === void 0 ? void 0 : meta.editorHeight) !== editorHeight || maybeWidthUpdated || nodeCountChanged || resizerMeta === false || !!(meta !== null && meta !== void 0 && meta.nodeMoved) && tr.docChanged;
114
+
102
115
  // Draw node and mouseWrapper decorations at top level node if decorations is empty, editor height changes or node is moved
103
- const redrawDecorations = decorations === DecorationSet.empty || (meta === null || meta === void 0 ? void 0 : meta.editorHeight) !== undefined && (meta === null || meta === void 0 ? void 0 : meta.editorHeight) !== editorHeight || maybeWidthUpdated || nodeCountChanged || resizerMeta === false || (meta === null || meta === void 0 ? void 0 : meta.nodeMoved) && tr.docChanged;
104
- if (redrawDecorations && isResizerResizing === false && api) {
116
+ if (redrawDecorations && !isResizerResizing && api) {
105
117
  decorations = DecorationSet.create(newState.doc, []);
106
118
  const nodeDecs = nodeDecorations(newState);
107
119
  const mouseWrapperDecs = mouseMoveWrapperDecorations(newState, api);
108
120
  decorations = decorations.add(newState.doc, [...nodeDecs, ...mouseWrapperDecs]);
109
- if (activeNode) {
110
- const newActiveNode = activeNode && tr.doc.nodeAt(activeNode.pos);
111
- let nodeType = activeNode.nodeType;
112
- let anchorName = activeNode.anchorName;
113
- if (newActiveNode && (newActiveNode === null || newActiveNode === void 0 ? void 0 : newActiveNode.type.name) !== activeNode.nodeType && !(meta !== null && meta !== void 0 && meta.nodeMoved)) {
114
- nodeType = newActiveNode.type.name;
115
- anchorName = activeNode.anchorName.replace(activeNode.nodeType, nodeType);
116
- }
117
- const draghandleDec = dragHandleDecoration(activeNode.pos, anchorName, nodeType, api);
121
+
122
+ // Note: Quite often the handle is not in the right position after a node is moved
123
+ // it is safer for now to not show it when a node is moved
124
+ if (activeNode && !(meta !== null && meta !== void 0 && meta.nodeMoved)) {
125
+ const draghandleDec = dragHandleDecoration(activeNode.pos, activeNode.anchorName, activeNode.nodeType, api);
118
126
  decorations = decorations.add(newState.doc, [draghandleDec]);
119
127
  }
120
128
  }
@@ -171,6 +179,7 @@ export const createPlugin = api => {
171
179
  anchorName: activeNode.anchorName,
172
180
  nodeType: activeNode.nodeType
173
181
  } : activeNode;
182
+ const isEmptyDoc = newState.doc.childCount === 1 && newState.doc.nodeSize <= 4;
174
183
  return {
175
184
  decorations,
176
185
  decorationState: (_decorationState = decorationState) !== null && _decorationState !== void 0 ? _decorationState : currentState.decorationState,
@@ -178,7 +187,7 @@ export const createPlugin = api => {
178
187
  isDragging: (_meta$isDragging = meta === null || meta === void 0 ? void 0 : meta.isDragging) !== null && _meta$isDragging !== void 0 ? _meta$isDragging : currentState.isDragging,
179
188
  isMenuOpen: meta !== null && meta !== void 0 && meta.toggleMenu ? !isMenuOpen : isMenuOpen,
180
189
  editorHeight: (_meta$editorHeight = meta === null || meta === void 0 ? void 0 : meta.editorHeight) !== null && _meta$editorHeight !== void 0 ? _meta$editorHeight : currentState.editorHeight,
181
- isResizerResizing: (_isResizerResizing = isResizerResizing) !== null && _isResizerResizing !== void 0 ? _isResizerResizing : isResizerResizing,
190
+ isResizerResizing: isResizerResizing,
182
191
  isDocSizeLimitEnabled: initialState.isDocSizeLimitEnabled
183
192
  };
184
193
  }
@@ -211,10 +220,13 @@ export const createPlugin = api => {
211
220
 
212
221
  // Start observing the editor DOM element
213
222
  resizeObserver.observe(dom);
223
+
224
+ // Start pragmatic monitors
225
+ const pragmaticCleanup = destroyFn(api);
214
226
  return {
215
227
  destroy() {
216
228
  resizeObserver.unobserve(dom);
217
- return destroyFn(api);
229
+ return pragmaticCleanup;
218
230
  }
219
231
  };
220
232
  }
@@ -3,9 +3,7 @@ import { useEffect, useRef, useState } from 'react';
3
3
  import { css, jsx } from '@emotion/react';
4
4
  import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE } from '@atlaskit/editor-common/analytics';
5
5
  import { useSharedPluginState } from '@atlaskit/editor-common/hooks';
6
- import { autoScrollForElements } from '@atlaskit/pragmatic-drag-and-drop-auto-scroll/element';
7
6
  import { DropIndicator } from '@atlaskit/pragmatic-drag-and-drop-react-drop-indicator/box';
8
- import { combine } from '@atlaskit/pragmatic-drag-and-drop/combine';
9
7
  import { dropTargetForElements } from '@atlaskit/pragmatic-drag-and-drop/element/adapter';
10
8
  const DEFAULT_DROP_INDICATOR_WIDTH = 760;
11
9
  const styleDropTarget = css({
@@ -37,26 +35,15 @@ export const DropTarget = ({
37
35
  if (!element) {
38
36
  return;
39
37
  }
40
- const combined = [];
41
- const scrollable = document.querySelector('.fabric-editor-popup-scroll-parent');
42
- if (scrollable) {
43
- combined.push(autoScrollForElements({
44
- element: scrollable
45
- }));
46
- }
47
- combined.push(dropTargetForElements({
38
+ return dropTargetForElements({
48
39
  element,
49
40
  getIsSticky: () => true,
50
- onDrag: () => {
51
- scrollable.style.setProperty('scroll-behavior', 'unset');
52
- },
53
41
  onDragEnter: () => {
54
42
  setIsDraggedOver(true);
55
43
  },
56
44
  onDragLeave: () => setIsDraggedOver(false),
57
45
  onDrop: () => {
58
46
  var _api$blockControls;
59
- scrollable.style.setProperty('scroll-behavior', null);
60
47
  const {
61
48
  activeNode,
62
49
  decorationState
@@ -91,8 +78,7 @@ export const DropTarget = ({
91
78
  });
92
79
  }
93
80
  }
94
- }));
95
- return combine(...combined);
81
+ });
96
82
  }, [index, api]);
97
83
  return (
98
84
  // Note: Firefox has trouble with using a button element as the handle for drag and drop
@@ -2,7 +2,6 @@
2
2
  import { useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react';
3
3
  import { css, jsx } from '@emotion/react';
4
4
  import { bind } from 'bind-event-listener';
5
- import { useSharedPluginState } from '@atlaskit/editor-common/hooks';
6
5
  import { getTopPosition } from '../utils/drag-handle-positions';
7
6
  const basicStyles = css({
8
7
  position: 'absolute',
@@ -21,10 +20,8 @@ export const MouseMoveWrapper = ({
21
20
  nodeType,
22
21
  getPos
23
22
  }) => {
24
- const {
25
- blockControlsState
26
- } = useSharedPluginState(api, ['blockControls']);
27
- const [isDragging, setIsDragging] = useState(false);
23
+ // Using a ref for isDragging reduce re-renders
24
+ const isDragging = useRef(false);
28
25
  const [hideWrapper, setHideWrapper] = useState(false);
29
26
  const ref = useRef(null);
30
27
  const [pos, setPos] = useState();
@@ -47,34 +44,43 @@ export const MouseMoveWrapper = ({
47
44
  };
48
45
  }, []);
49
46
  const onMouseEnter = useCallback(() => {
50
- if (!isDragging) {
47
+ if (!isDragging.current) {
51
48
  setHideWrapper(true);
52
49
  }
53
50
  const pos = getPos();
54
51
  if (pos === undefined) {
55
52
  return;
56
53
  }
57
- if (api && api.blockControls && !isDragging) {
54
+ if (api && api.blockControls && !isDragging.current) {
58
55
  var _api$core;
59
56
  api === null || api === void 0 ? void 0 : (_api$core = api.core) === null || _api$core === void 0 ? void 0 : _api$core.actions.execute(api.blockControls.commands.showDragHandleAt(pos, anchorName, nodeType));
60
57
  }
61
- }, [setHideWrapper, getPos, isDragging, api, anchorName, nodeType]);
62
- useEffect(() => {
63
- var _blockControlsState$a;
64
- setIsDragging(Boolean(blockControlsState === null || blockControlsState === void 0 ? void 0 : blockControlsState.isDragging));
65
- const pos = getPos();
66
- if (!(blockControlsState !== null && blockControlsState !== void 0 && blockControlsState.activeNode)) {
67
- return;
68
- }
69
- if ((blockControlsState === null || blockControlsState === void 0 ? void 0 : (_blockControlsState$a = blockControlsState.activeNode) === null || _blockControlsState$a === void 0 ? void 0 : _blockControlsState$a.pos) !== pos && !(blockControlsState !== null && blockControlsState !== void 0 && blockControlsState.isDragging)) {
58
+ }, [getPos, isDragging, api, anchorName, nodeType]);
59
+
60
+ //THIS IS TRIGGERED A LOT!
61
+ const onSharedStateChange = useCallback(({
62
+ nextSharedState
63
+ }) => {
64
+ var _nextSharedState$acti;
65
+ if ((nextSharedState === null || nextSharedState === void 0 ? void 0 : (_nextSharedState$acti = nextSharedState.activeNode) === null || _nextSharedState$acti === void 0 ? void 0 : _nextSharedState$acti.anchorName) !== anchorName && !isDragging.current) {
70
66
  setHideWrapper(false);
71
- return;
72
67
  }
73
- if (blockControlsState !== null && blockControlsState !== void 0 && blockControlsState.isDragging) {
68
+ if (nextSharedState !== null && nextSharedState !== void 0 && nextSharedState.isDragging && !isDragging.current) {
69
+ isDragging.current = true;
74
70
  setHideWrapper(true);
75
- return;
76
71
  }
77
- }, [getPos, blockControlsState]);
72
+ if ((nextSharedState === null || nextSharedState === void 0 ? void 0 : nextSharedState.isDragging) === false && isDragging.current) {
73
+ isDragging.current = false;
74
+ setHideWrapper(false);
75
+ }
76
+ }, [anchorName]);
77
+ useEffect(() => {
78
+ var _api$blockControls;
79
+ const unbind = api === null || api === void 0 ? void 0 : (_api$blockControls = api.blockControls) === null || _api$blockControls === void 0 ? void 0 : _api$blockControls.sharedState.onChange(onSharedStateChange);
80
+ return () => {
81
+ unbind === null || unbind === void 0 ? void 0 : unbind();
82
+ };
83
+ }, [onSharedStateChange, api]);
78
84
  useLayoutEffect(() => {
79
85
  const supportsAnchor = CSS.supports('height', `anchor-size(${anchorName} height)`) && CSS.supports('top', `anchor(${anchorName} start)`);
80
86
  if (supportsAnchor) {
@@ -5,18 +5,32 @@ import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
5
5
  import { PluginKey } from '@atlaskit/editor-prosemirror/state';
6
6
  import { DecorationSet } from '@atlaskit/editor-prosemirror/view';
7
7
  import { getBooleanFF } from '@atlaskit/platform-feature-flags';
8
+ import { autoScrollForElements } from '@atlaskit/pragmatic-drag-and-drop-auto-scroll/element';
9
+ import { combine } from '@atlaskit/pragmatic-drag-and-drop/combine';
8
10
  import { monitorForElements } from '@atlaskit/pragmatic-drag-and-drop/element/adapter';
9
11
  import { dragHandleDecoration, dropTargetDecorations, mouseMoveWrapperDecorations, nodeDecorations } from './decorations';
10
12
  export var key = new PluginKey('blockControls');
11
13
  var destroyFn = function destroyFn(api) {
12
- return monitorForElements({
14
+ var scrollable = document.querySelector('.fabric-editor-popup-scroll-parent');
15
+ var cleanupFn = [];
16
+ if (scrollable) {
17
+ cleanupFn.push(autoScrollForElements({
18
+ element: scrollable
19
+ }));
20
+ }
21
+ cleanupFn.push(monitorForElements({
13
22
  canMonitor: function canMonitor(_ref) {
14
23
  var source = _ref.source;
15
24
  return source.data.type === 'element';
16
25
  },
26
+ onDragStart: function onDragStart() {
27
+ scrollable.style.setProperty('scroll-behavior', 'unset');
28
+ },
17
29
  onDrop: function onDrop(_ref2) {
18
30
  var location = _ref2.location,
19
31
  source = _ref2.source;
32
+ scrollable.style.setProperty('scroll-behavior', null);
33
+
20
34
  // if no drop targets are rendered, assume that drop is invalid
21
35
  if (location.current.dropTargets.length === 0) {
22
36
  var _api$core;
@@ -41,7 +55,8 @@ var destroyFn = function destroyFn(api) {
41
55
  });
42
56
  }
43
57
  }
44
- });
58
+ }));
59
+ return combine.apply(void 0, cleanupFn);
45
60
  };
46
61
  var initialState = {
47
62
  decorations: DecorationSet.empty,
@@ -49,8 +64,6 @@ var initialState = {
49
64
  activeNode: null,
50
65
  isDragging: false,
51
66
  isMenuOpen: false,
52
- start: null,
53
- end: null,
54
67
  editorHeight: 0,
55
68
  isResizerResizing: false,
56
69
  isDocSizeLimitEnabled: false
@@ -67,7 +80,7 @@ export var createPlugin = function createPlugin(api) {
67
80
  return initialState;
68
81
  },
69
82
  apply: function apply(tr, currentState, oldState, newState) {
70
- var _decorationState, _meta$activeNode, _meta$isDragging, _meta$editorHeight, _isResizerResizing;
83
+ var _decorationState, _meta$activeNode, _meta$isDragging, _meta$editorHeight;
71
84
  if (initialState.isDocSizeLimitEnabled && newState.doc.nodeSize > DRAG_AND_DROP_DOC_SIZE_LIMIT) {
72
85
  return initialState;
73
86
  }
@@ -82,14 +95,10 @@ export var createPlugin = function createPlugin(api) {
82
95
  // If tables or media are being resized, we want to hide the drag handle
83
96
  var resizerMeta = tr.getMeta('is-resizer-resizing');
84
97
  isResizerResizing = resizerMeta !== null && resizerMeta !== void 0 ? resizerMeta : isResizerResizing;
85
- var isEmptyDoc = newState.doc.childCount === 1 && newState.doc.nodeSize <= 4;
86
-
87
- // This is not targeted enough - it's trying to catch events like expand being set to breakout
88
- var maybeWidthUpdated = tr.docChanged && oldState.doc.nodeSize === newState.doc.nodeSize && oldState.doc.childCount === newState.doc.childCount;
89
98
  var nodeCountChanged = oldState.doc.childCount !== newState.doc.childCount;
90
99
 
91
100
  // During resize, remove the drag handle widget
92
- if (isResizerResizing || nodeCountChanged) {
101
+ if (isResizerResizing || nodeCountChanged || meta !== null && meta !== void 0 && meta.nodeMoved) {
93
102
  var oldHandle = decorations.find().filter(function (_ref5) {
94
103
  var spec = _ref5.spec;
95
104
  return spec.id === 'drag-handle';
@@ -97,22 +106,21 @@ export var createPlugin = function createPlugin(api) {
97
106
  decorations = decorations.remove(oldHandle);
98
107
  }
99
108
 
109
+ // This is not targeted enough - it's trying to catch events like expand being set to breakout
110
+ var maybeWidthUpdated = tr.docChanged && oldState.doc.nodeSize === newState.doc.nodeSize && !nodeCountChanged;
111
+ var redrawDecorations = decorations === DecorationSet.empty || (meta === null || meta === void 0 ? void 0 : meta.editorHeight) !== undefined && (meta === null || meta === void 0 ? void 0 : meta.editorHeight) !== editorHeight || maybeWidthUpdated || nodeCountChanged || resizerMeta === false || !!(meta !== null && meta !== void 0 && meta.nodeMoved) && tr.docChanged;
112
+
100
113
  // Draw node and mouseWrapper decorations at top level node if decorations is empty, editor height changes or node is moved
101
- var redrawDecorations = decorations === DecorationSet.empty || (meta === null || meta === void 0 ? void 0 : meta.editorHeight) !== undefined && (meta === null || meta === void 0 ? void 0 : meta.editorHeight) !== editorHeight || maybeWidthUpdated || nodeCountChanged || resizerMeta === false || (meta === null || meta === void 0 ? void 0 : meta.nodeMoved) && tr.docChanged;
102
- if (redrawDecorations && isResizerResizing === false && api) {
114
+ if (redrawDecorations && !isResizerResizing && api) {
103
115
  decorations = DecorationSet.create(newState.doc, []);
104
116
  var nodeDecs = nodeDecorations(newState);
105
117
  var mouseWrapperDecs = mouseMoveWrapperDecorations(newState, api);
106
118
  decorations = decorations.add(newState.doc, [].concat(_toConsumableArray(nodeDecs), _toConsumableArray(mouseWrapperDecs)));
107
- if (activeNode) {
108
- var newActiveNode = activeNode && tr.doc.nodeAt(activeNode.pos);
109
- var nodeType = activeNode.nodeType;
110
- var anchorName = activeNode.anchorName;
111
- if (newActiveNode && (newActiveNode === null || newActiveNode === void 0 ? void 0 : newActiveNode.type.name) !== activeNode.nodeType && !(meta !== null && meta !== void 0 && meta.nodeMoved)) {
112
- nodeType = newActiveNode.type.name;
113
- anchorName = activeNode.anchorName.replace(activeNode.nodeType, nodeType);
114
- }
115
- var draghandleDec = dragHandleDecoration(activeNode.pos, anchorName, nodeType, api);
119
+
120
+ // Note: Quite often the handle is not in the right position after a node is moved
121
+ // it is safer for now to not show it when a node is moved
122
+ if (activeNode && !(meta !== null && meta !== void 0 && meta.nodeMoved)) {
123
+ var draghandleDec = dragHandleDecoration(activeNode.pos, activeNode.anchorName, activeNode.nodeType, api);
116
124
  decorations = decorations.add(newState.doc, [draghandleDec]);
117
125
  }
118
126
  }
@@ -169,6 +177,7 @@ export var createPlugin = function createPlugin(api) {
169
177
  anchorName: activeNode.anchorName,
170
178
  nodeType: activeNode.nodeType
171
179
  } : activeNode;
180
+ var isEmptyDoc = newState.doc.childCount === 1 && newState.doc.nodeSize <= 4;
172
181
  return {
173
182
  decorations: decorations,
174
183
  decorationState: (_decorationState = decorationState) !== null && _decorationState !== void 0 ? _decorationState : currentState.decorationState,
@@ -176,7 +185,7 @@ export var createPlugin = function createPlugin(api) {
176
185
  isDragging: (_meta$isDragging = meta === null || meta === void 0 ? void 0 : meta.isDragging) !== null && _meta$isDragging !== void 0 ? _meta$isDragging : currentState.isDragging,
177
186
  isMenuOpen: meta !== null && meta !== void 0 && meta.toggleMenu ? !isMenuOpen : isMenuOpen,
178
187
  editorHeight: (_meta$editorHeight = meta === null || meta === void 0 ? void 0 : meta.editorHeight) !== null && _meta$editorHeight !== void 0 ? _meta$editorHeight : currentState.editorHeight,
179
- isResizerResizing: (_isResizerResizing = isResizerResizing) !== null && _isResizerResizing !== void 0 ? _isResizerResizing : isResizerResizing,
188
+ isResizerResizing: isResizerResizing,
180
189
  isDocSizeLimitEnabled: initialState.isDocSizeLimitEnabled
181
190
  };
182
191
  }
@@ -209,10 +218,13 @@ export var createPlugin = function createPlugin(api) {
209
218
 
210
219
  // Start observing the editor DOM element
211
220
  resizeObserver.observe(dom);
221
+
222
+ // Start pragmatic monitors
223
+ var pragmaticCleanup = destroyFn(api);
212
224
  return {
213
225
  destroy: function destroy() {
214
226
  resizeObserver.unobserve(dom);
215
- return destroyFn(api);
227
+ return pragmaticCleanup;
216
228
  }
217
229
  };
218
230
  }
@@ -4,9 +4,7 @@ import { useEffect, useRef, useState } from 'react';
4
4
  import { css, jsx } from '@emotion/react';
5
5
  import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE } from '@atlaskit/editor-common/analytics';
6
6
  import { useSharedPluginState } from '@atlaskit/editor-common/hooks';
7
- import { autoScrollForElements } from '@atlaskit/pragmatic-drag-and-drop-auto-scroll/element';
8
7
  import { DropIndicator } from '@atlaskit/pragmatic-drag-and-drop-react-drop-indicator/box';
9
- import { combine } from '@atlaskit/pragmatic-drag-and-drop/combine';
10
8
  import { dropTargetForElements } from '@atlaskit/pragmatic-drag-and-drop/element/adapter';
11
9
  var DEFAULT_DROP_INDICATOR_WIDTH = 760;
12
10
  var styleDropTarget = css({
@@ -39,21 +37,11 @@ export var DropTarget = function DropTarget(_ref) {
39
37
  if (!element) {
40
38
  return;
41
39
  }
42
- var combined = [];
43
- var scrollable = document.querySelector('.fabric-editor-popup-scroll-parent');
44
- if (scrollable) {
45
- combined.push(autoScrollForElements({
46
- element: scrollable
47
- }));
48
- }
49
- combined.push(dropTargetForElements({
40
+ return dropTargetForElements({
50
41
  element: element,
51
42
  getIsSticky: function getIsSticky() {
52
43
  return true;
53
44
  },
54
- onDrag: function onDrag() {
55
- scrollable.style.setProperty('scroll-behavior', 'unset');
56
- },
57
45
  onDragEnter: function onDragEnter() {
58
46
  setIsDraggedOver(true);
59
47
  },
@@ -62,7 +50,6 @@ export var DropTarget = function DropTarget(_ref) {
62
50
  },
63
51
  onDrop: function onDrop() {
64
52
  var _api$blockControls;
65
- scrollable.style.setProperty('scroll-behavior', null);
66
53
  var _ref2 = (api === null || api === void 0 || (_api$blockControls = api.blockControls) === null || _api$blockControls === void 0 ? void 0 : _api$blockControls.sharedState.currentState()) || {},
67
54
  activeNode = _ref2.activeNode,
68
55
  decorationState = _ref2.decorationState;
@@ -95,8 +82,7 @@ export var DropTarget = function DropTarget(_ref) {
95
82
  });
96
83
  }
97
84
  }
98
- }));
99
- return combine.apply(void 0, combined);
85
+ });
100
86
  }, [index, api]);
101
87
  return (
102
88
  // Note: Firefox has trouble with using a button element as the handle for drag and drop
@@ -3,7 +3,6 @@ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
3
3
  import { useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react';
4
4
  import { css, jsx } from '@emotion/react';
5
5
  import { bind } from 'bind-event-listener';
6
- import { useSharedPluginState } from '@atlaskit/editor-common/hooks';
7
6
  import { getTopPosition } from '../utils/drag-handle-positions';
8
7
  var basicStyles = css({
9
8
  position: 'absolute',
@@ -21,21 +20,17 @@ export var MouseMoveWrapper = function MouseMoveWrapper(_ref) {
21
20
  anchorName = _ref.anchorName,
22
21
  nodeType = _ref.nodeType,
23
22
  getPos = _ref.getPos;
24
- var _useSharedPluginState = useSharedPluginState(api, ['blockControls']),
25
- blockControlsState = _useSharedPluginState.blockControlsState;
23
+ // Using a ref for isDragging reduce re-renders
24
+ var isDragging = useRef(false);
26
25
  var _useState = useState(false),
27
26
  _useState2 = _slicedToArray(_useState, 2),
28
- isDragging = _useState2[0],
29
- setIsDragging = _useState2[1];
30
- var _useState3 = useState(false),
31
- _useState4 = _slicedToArray(_useState3, 2),
32
- hideWrapper = _useState4[0],
33
- setHideWrapper = _useState4[1];
27
+ hideWrapper = _useState2[0],
28
+ setHideWrapper = _useState2[1];
34
29
  var ref = useRef(null);
35
- var _useState5 = useState(),
36
- _useState6 = _slicedToArray(_useState5, 2),
37
- pos = _useState6[0],
38
- setPos = _useState6[1];
30
+ var _useState3 = useState(),
31
+ _useState4 = _slicedToArray(_useState3, 2),
32
+ pos = _useState4[0],
33
+ setPos = _useState4[1];
39
34
  useEffect(function () {
40
35
  // Adding this event listener to fix issue where wrapper isn't hidden if user navigates to node before page finishes loading
41
36
  // This will be removed when we refactor to remove this component
@@ -55,34 +50,42 @@ export var MouseMoveWrapper = function MouseMoveWrapper(_ref) {
55
50
  };
56
51
  }, []);
57
52
  var onMouseEnter = useCallback(function () {
58
- if (!isDragging) {
53
+ if (!isDragging.current) {
59
54
  setHideWrapper(true);
60
55
  }
61
56
  var pos = getPos();
62
57
  if (pos === undefined) {
63
58
  return;
64
59
  }
65
- if (api && api.blockControls && !isDragging) {
60
+ if (api && api.blockControls && !isDragging.current) {
66
61
  var _api$core;
67
62
  api === null || api === void 0 || (_api$core = api.core) === null || _api$core === void 0 || _api$core.actions.execute(api.blockControls.commands.showDragHandleAt(pos, anchorName, nodeType));
68
63
  }
69
- }, [setHideWrapper, getPos, isDragging, api, anchorName, nodeType]);
70
- useEffect(function () {
71
- var _blockControlsState$a;
72
- setIsDragging(Boolean(blockControlsState === null || blockControlsState === void 0 ? void 0 : blockControlsState.isDragging));
73
- var pos = getPos();
74
- if (!(blockControlsState !== null && blockControlsState !== void 0 && blockControlsState.activeNode)) {
75
- return;
76
- }
77
- if ((blockControlsState === null || blockControlsState === void 0 || (_blockControlsState$a = blockControlsState.activeNode) === null || _blockControlsState$a === void 0 ? void 0 : _blockControlsState$a.pos) !== pos && !(blockControlsState !== null && blockControlsState !== void 0 && blockControlsState.isDragging)) {
64
+ }, [getPos, isDragging, api, anchorName, nodeType]);
65
+
66
+ //THIS IS TRIGGERED A LOT!
67
+ var onSharedStateChange = useCallback(function (_ref2) {
68
+ var _nextSharedState$acti;
69
+ var nextSharedState = _ref2.nextSharedState;
70
+ if ((nextSharedState === null || nextSharedState === void 0 || (_nextSharedState$acti = nextSharedState.activeNode) === null || _nextSharedState$acti === void 0 ? void 0 : _nextSharedState$acti.anchorName) !== anchorName && !isDragging.current) {
78
71
  setHideWrapper(false);
79
- return;
80
72
  }
81
- if (blockControlsState !== null && blockControlsState !== void 0 && blockControlsState.isDragging) {
73
+ if (nextSharedState !== null && nextSharedState !== void 0 && nextSharedState.isDragging && !isDragging.current) {
74
+ isDragging.current = true;
82
75
  setHideWrapper(true);
83
- return;
84
76
  }
85
- }, [getPos, blockControlsState]);
77
+ if ((nextSharedState === null || nextSharedState === void 0 ? void 0 : nextSharedState.isDragging) === false && isDragging.current) {
78
+ isDragging.current = false;
79
+ setHideWrapper(false);
80
+ }
81
+ }, [anchorName]);
82
+ useEffect(function () {
83
+ var _api$blockControls;
84
+ var unbind = api === null || api === void 0 || (_api$blockControls = api.blockControls) === null || _api$blockControls === void 0 ? void 0 : _api$blockControls.sharedState.onChange(onSharedStateChange);
85
+ return function () {
86
+ unbind === null || unbind === void 0 || unbind();
87
+ };
88
+ }, [onSharedStateChange, api]);
86
89
  useLayoutEffect(function () {
87
90
  var supportsAnchor = CSS.supports('height', "anchor-size(".concat(anchorName, " height)")) && CSS.supports('top', "anchor(".concat(anchorName, " start)"));
88
91
  if (supportsAnchor) {
@@ -1,6 +1,16 @@
1
1
  import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
2
2
  import type { ExtractInjectionAPI } from '@atlaskit/editor-common/types';
3
3
  import { PluginKey } from '@atlaskit/editor-prosemirror/state';
4
+ import { DecorationSet } from '@atlaskit/editor-prosemirror/view';
4
5
  import type { BlockControlsPlugin, PluginState } from '../types';
5
6
  export declare const key: PluginKey<PluginState>;
6
- export declare const createPlugin: (api: ExtractInjectionAPI<BlockControlsPlugin> | undefined) => SafePlugin<PluginState>;
7
+ export declare const createPlugin: (api: ExtractInjectionAPI<BlockControlsPlugin> | undefined) => SafePlugin<PluginState | {
8
+ decorations: DecorationSet;
9
+ decorationState: import("../types").DecorationState;
10
+ activeNode: any;
11
+ isDragging: any;
12
+ isMenuOpen: boolean | undefined;
13
+ editorHeight: any;
14
+ isResizerResizing: boolean;
15
+ isDocSizeLimitEnabled: boolean;
16
+ }>;
@@ -1,6 +1,16 @@
1
1
  import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
2
2
  import type { ExtractInjectionAPI } from '@atlaskit/editor-common/types';
3
3
  import { PluginKey } from '@atlaskit/editor-prosemirror/state';
4
+ import { DecorationSet } from '@atlaskit/editor-prosemirror/view';
4
5
  import type { BlockControlsPlugin, PluginState } from '../types';
5
6
  export declare const key: PluginKey<PluginState>;
6
- export declare const createPlugin: (api: ExtractInjectionAPI<BlockControlsPlugin> | undefined) => SafePlugin<PluginState>;
7
+ export declare const createPlugin: (api: ExtractInjectionAPI<BlockControlsPlugin> | undefined) => SafePlugin<PluginState | {
8
+ decorations: DecorationSet;
9
+ decorationState: import("../types").DecorationState;
10
+ activeNode: any;
11
+ isDragging: any;
12
+ isMenuOpen: boolean | undefined;
13
+ editorHeight: any;
14
+ isResizerResizing: boolean;
15
+ isDocSizeLimitEnabled: boolean;
16
+ }>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-block-controls",
3
- "version": "1.4.19",
3
+ "version": "1.4.21",
4
4
  "description": "Block controls plugin for @atlaskit/editor-core",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -19,7 +19,10 @@
19
19
  "types": "dist/types/index.d.ts",
20
20
  "typesVersions": {
21
21
  ">=4.5 <4.9": {
22
- "*": ["dist/types-ts4.5/*", "dist/types-ts4.5/index.d.ts"]
22
+ "*": [
23
+ "dist/types-ts4.5/*",
24
+ "dist/types-ts4.5/index.d.ts"
25
+ ]
23
26
  }
24
27
  },
25
28
  "sideEffects": false,
@@ -28,7 +31,7 @@
28
31
  ".": "./src/index.ts"
29
32
  },
30
33
  "dependencies": {
31
- "@atlaskit/editor-common": "^82.6.0",
34
+ "@atlaskit/editor-common": "^82.7.0",
32
35
  "@atlaskit/editor-plugin-analytics": "^1.2.3",
33
36
  "@atlaskit/editor-plugin-editor-disabled": "^1.1.5",
34
37
  "@atlaskit/editor-plugin-feature-flags": "^1.1.0",
@@ -52,18 +55,37 @@
52
55
  },
53
56
  "techstack": {
54
57
  "@atlassian/frontend": {
55
- "import-structure": ["atlassian-conventions"],
56
- "circular-dependencies": ["file-and-folder-level"]
58
+ "import-structure": [
59
+ "atlassian-conventions"
60
+ ],
61
+ "circular-dependencies": [
62
+ "file-and-folder-level"
63
+ ]
57
64
  },
58
65
  "@repo/internal": {
59
66
  "dom-events": "use-bind-event-listener",
60
- "analytics": ["analytics-next"],
61
- "design-tokens": ["color"],
62
- "theming": ["react-context"],
63
- "ui-components": ["lite-mode"],
64
- "deprecation": ["no-deprecated-imports"],
65
- "styling": ["emotion", "compiled"],
66
- "imports": ["import-no-extraneous-disable-for-examples-and-docs"]
67
+ "analytics": [
68
+ "analytics-next"
69
+ ],
70
+ "design-tokens": [
71
+ "color"
72
+ ],
73
+ "theming": [
74
+ "react-context"
75
+ ],
76
+ "ui-components": [
77
+ "lite-mode"
78
+ ],
79
+ "deprecation": [
80
+ "no-deprecated-imports"
81
+ ],
82
+ "styling": [
83
+ "emotion",
84
+ "compiled"
85
+ ],
86
+ "imports": [
87
+ "import-no-extraneous-disable-for-examples-and-docs"
88
+ ]
67
89
  }
68
90
  },
69
91
  "platform-feature-flags": {