@atlaskit/editor-plugin-block-controls 1.4.11 → 1.4.13

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.13
4
+
5
+ ### Patch Changes
6
+
7
+ - [#108531](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/108531)
8
+ [`bc1dab1f64bd8`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/bc1dab1f64bd8) -
9
+ [ux] Don't render decorations when Editor is disabled or in 'view' mode
10
+ - [#110258](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/110258)
11
+ [`e12a40c7d31ee`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/e12a40c7d31ee) -
12
+ set selection on drag handle mouse down to ensure drag and drop does not use native behaviour
13
+ - Updated dependencies
14
+
15
+ ## 1.4.12
16
+
17
+ ### Patch Changes
18
+
19
+ - [#108853](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/108853)
20
+ [`390f442689fd6`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/390f442689fd6) -
21
+ Fix position of drag handle for extension/ bodiedExtension nodes in wide or fullWidth layout
22
+
3
23
  ## 1.4.11
4
24
 
5
25
  ### Patch Changes
@@ -30,7 +30,6 @@ var createPlugin = exports.createPlugin = function createPlugin(api) {
30
30
  },
31
31
  apply: function apply(tr, currentState, oldState, newState) {
32
32
  var _decorationState, _meta$activeNode, _meta$isDragging, _meta$editorHeight;
33
- // return currentState;
34
33
  var activeNode = currentState.activeNode,
35
34
  decorations = currentState.decorations,
36
35
  isMenuOpen = currentState.isMenuOpen,
@@ -115,7 +114,11 @@ var createPlugin = exports.createPlugin = function createPlugin(api) {
115
114
  },
116
115
  props: {
117
116
  decorations: function decorations(state) {
118
- var _key$getState;
117
+ var _api$editorDisabled, _key$getState;
118
+ var isDisabled = api === null || api === void 0 || (_api$editorDisabled = api.editorDisabled) === null || _api$editorDisabled === void 0 || (_api$editorDisabled = _api$editorDisabled.sharedState.currentState()) === null || _api$editorDisabled === void 0 ? void 0 : _api$editorDisabled.editorDisabled;
119
+ if (isDisabled) {
120
+ return;
121
+ }
119
122
  return (_key$getState = key.getState(state)) === null || _key$getState === void 0 ? void 0 : _key$getState.decorations;
120
123
  }
121
124
  },
@@ -8,6 +8,7 @@ exports.DragHandle = void 0;
8
8
  var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
9
9
  var _react = require("react");
10
10
  var _react2 = require("@emotion/react");
11
+ var _hooks = require("@atlaskit/editor-common/hooks");
11
12
  var _dragHandler = _interopRequireDefault(require("@atlaskit/icon/glyph/drag-handler"));
12
13
  var _adapter = require("@atlaskit/pragmatic-drag-and-drop/element/adapter");
13
14
  var _setCustomNativeDragPreview = require("@atlaskit/pragmatic-drag-and-drop/element/set-custom-native-drag-preview");
@@ -57,7 +58,9 @@ var DragHandle = exports.DragHandle = function DragHandle(_ref) {
57
58
  _useState2 = (0, _slicedToArray2.default)(_useState, 2),
58
59
  dragHandleSelected = _useState2[0],
59
60
  setDragHandleSelected = _useState2[1];
60
- var handleClick = (0, _react.useCallback)(function () {
61
+ var _useSharedPluginState = (0, _hooks.useSharedPluginState)(api, ['featureFlags']),
62
+ featureFlagsState = _useSharedPluginState.featureFlagsState;
63
+ var handleOnClick = (0, _react.useCallback)(function () {
61
64
  var _api$core, _api$core2;
62
65
  setDragHandleSelected(!dragHandleSelected);
63
66
  api === null || api === void 0 || (_api$core = api.core) === null || _api$core === void 0 || _api$core.actions.execute(function (_ref2) {
@@ -73,6 +76,25 @@ var DragHandle = exports.DragHandle = function DragHandle(_ref) {
73
76
  });
74
77
  api === null || api === void 0 || (_api$core2 = api.core) === null || _api$core2 === void 0 || _api$core2.actions.focus();
75
78
  }, [start, api, dragHandleSelected, setDragHandleSelected, nodeType]);
79
+
80
+ // handleMouseDown required along with onClick to ensure the correct selection
81
+ // is set immediately when the drag handle is clicked. Otherwise browser native
82
+ // drag and drop can take over and cause unpredictable behaviour.
83
+ var handleMouseDown = (0, _react.useCallback)(function () {
84
+ var _api$core3, _api$core4;
85
+ api === null || api === void 0 || (_api$core3 = api.core) === null || _api$core3 === void 0 || _api$core3.actions.execute(function (_ref3) {
86
+ var tr = _ref3.tr;
87
+ if (start === undefined) {
88
+ return tr;
89
+ }
90
+ tr = (0, _utils.selectNode)(tr, start, nodeType);
91
+ tr.setMeta(_main.key, {
92
+ pos: start
93
+ });
94
+ return tr;
95
+ });
96
+ api === null || api === void 0 || (_api$core4 = api.core) === null || _api$core4 === void 0 || _api$core4.actions.focus();
97
+ }, [start, api, nodeType]);
76
98
  (0, _react.useEffect)(function () {
77
99
  var element = buttonRef.current;
78
100
  if (!element) {
@@ -80,11 +102,11 @@ var DragHandle = exports.DragHandle = function DragHandle(_ref) {
80
102
  }
81
103
  return (0, _adapter.draggable)({
82
104
  element: element,
83
- onGenerateDragPreview: function onGenerateDragPreview(_ref3) {
84
- var nativeSetDragImage = _ref3.nativeSetDragImage;
105
+ onGenerateDragPreview: function onGenerateDragPreview(_ref4) {
106
+ var nativeSetDragImage = _ref4.nativeSetDragImage;
85
107
  (0, _setCustomNativeDragPreview.setCustomNativeDragPreview)({
86
- render: function render(_ref4) {
87
- var container = _ref4.container;
108
+ render: function render(_ref5) {
109
+ var container = _ref5.container;
88
110
  var dom = view.dom.querySelector("[data-drag-handler-anchor-name=\"".concat(anchorName, "\"]"));
89
111
  if (!dom) {
90
112
  return;
@@ -95,17 +117,17 @@ var DragHandle = exports.DragHandle = function DragHandle(_ref) {
95
117
  });
96
118
  },
97
119
  onDragStart: function onDragStart() {
98
- var _api$core3, _api$blockControls, _api$core4;
120
+ var _api$core5, _api$blockControls, _api$core6;
99
121
  if (start === undefined) {
100
122
  return;
101
123
  }
102
- api === null || api === void 0 || (_api$core3 = api.core) === null || _api$core3 === void 0 || _api$core3.actions.execute(api === null || api === void 0 || (_api$blockControls = api.blockControls) === null || _api$blockControls === void 0 ? void 0 : _api$blockControls.commands.setNodeDragged(start, anchorName, nodeType));
103
- api === null || api === void 0 || (_api$core4 = api.core) === null || _api$core4 === void 0 || _api$core4.actions.focus();
124
+ api === null || api === void 0 || (_api$core5 = api.core) === null || _api$core5 === void 0 || _api$core5.actions.execute(api === null || api === void 0 || (_api$blockControls = api.blockControls) === null || _api$blockControls === void 0 ? void 0 : _api$blockControls.commands.setNodeDragged(start, anchorName, nodeType));
125
+ api === null || api === void 0 || (_api$core6 = api.core) === null || _api$core6 === void 0 || _api$core6.actions.focus();
104
126
  },
105
127
  onDrop: function onDrop() {
106
- var _api$core5;
107
- api === null || api === void 0 || (_api$core5 = api.core) === null || _api$core5 === void 0 || _api$core5.actions.execute(function (_ref5) {
108
- var tr = _ref5.tr;
128
+ var _api$core7;
129
+ api === null || api === void 0 || (_api$core7 = api.core) === null || _api$core7 === void 0 || _api$core7.actions.execute(function (_ref6) {
130
+ var tr = _ref6.tr;
109
131
  return tr.setMeta(_main.key, {
110
132
  isDragging: false
111
133
  });
@@ -113,30 +135,34 @@ var DragHandle = exports.DragHandle = function DragHandle(_ref) {
113
135
  }
114
136
  });
115
137
  }, [api, start, view, anchorName, nodeType]);
138
+ var macroInteractionUpdates = featureFlagsState === null || featureFlagsState === void 0 ? void 0 : featureFlagsState.macroInteractionUpdates;
116
139
  var positionStyles = (0, _react.useMemo)(function () {
117
140
  var supportsAnchor = CSS.supports('top', "anchor(".concat(anchorName, " start)")) && CSS.supports('left', "anchor(".concat(anchorName, " start)"));
118
141
  var dom = view.dom.querySelector("[data-drag-handler-anchor-name=\"".concat(anchorName, "\"]"));
142
+ if (!dom) {
143
+ return;
144
+ }
145
+ var hasResizer = anchorName.includes('table') || anchorName.includes('mediaSingle');
146
+ var isExtension = anchorName.includes('extension') || anchorName.includes('bodiedExtension');
147
+ var innerContainer = hasResizer ? dom.querySelector('.resizer-item') : isExtension ? dom.querySelector('.extension-container[data-layout]') : null;
119
148
  if (supportsAnchor) {
120
- var hasResizer = (anchorName.includes('table') || anchorName.includes('mediaSingle')) && dom;
121
149
  return {
122
- left: hasResizer ? (0, _dragHandlePositions.getLeftPosition)(dom, nodeType) : "calc(anchor(".concat(anchorName, " start) - ").concat(_consts.DRAG_HANDLE_WIDTH, "px - ").concat((0, _consts.dragHandleGap)(nodeType), "px)"),
150
+ left: hasResizer || isExtension ? (0, _dragHandlePositions.getLeftPosition)(dom, nodeType, innerContainer, macroInteractionUpdates) : "calc(anchor(".concat(anchorName, " start) - ").concat(_consts.DRAG_HANDLE_WIDTH, "px - ").concat((0, _consts.dragHandleGap)(nodeType), "px)"),
123
151
  top: anchorName.includes('table') ? "calc(anchor(".concat(anchorName, " start) + ").concat(_consts.DRAG_HANDLE_HEIGHT, "px)") : "anchor(".concat(anchorName, " start)")
124
152
  };
125
153
  }
126
- if (!dom) {
127
- return;
128
- }
129
154
  return {
130
- left: (0, _dragHandlePositions.getLeftPosition)(dom, nodeType),
155
+ left: (0, _dragHandlePositions.getLeftPosition)(dom, nodeType, innerContainer, macroInteractionUpdates),
131
156
  top: (0, _dragHandlePositions.getTopPosition)(dom)
132
157
  };
133
- }, [anchorName, view, nodeType]);
158
+ }, [anchorName, view, nodeType, macroInteractionUpdates]);
134
159
  return (0, _react2.jsx)("button", {
135
160
  type: "button",
136
161
  css: [dragHandleButtonStyles, dragHandleSelected && selectedStyles],
137
162
  ref: buttonRef,
138
163
  style: positionStyles,
139
- onClick: handleClick,
164
+ onClick: handleOnClick,
165
+ onMouseDown: handleMouseDown,
140
166
  "data-testid": "block-ctrl-drag-handle"
141
167
  }, (0, _react2.jsx)(_dragHandler.default, {
142
168
  label: "",
@@ -13,11 +13,14 @@ var getTopPosition = exports.getTopPosition = function getTopPosition(dom) {
13
13
  return "".concat(dom.offsetTop, "px");
14
14
  }
15
15
  };
16
- var getLeftPosition = exports.getLeftPosition = function getLeftPosition(dom, type) {
17
- var resizer = ['table', 'mediaSingle'].includes(type) ? dom.querySelector('.resizer-item') : null;
18
- var left = "".concat(dom.offsetLeft - (0, _consts.dragHandleGap)(type) - _consts.DRAG_HANDLE_WIDTH, "px");
19
- if (resizer) {
20
- left = getComputedStyle(resizer).transform === 'none' ? "".concat(resizer.offsetLeft - (0, _consts.dragHandleGap)(type) - _consts.DRAG_HANDLE_WIDTH, "px") : "".concat(resizer.offsetLeft - resizer.offsetWidth / 2 - (0, _consts.dragHandleGap)(type) - _consts.DRAG_HANDLE_WIDTH, "px");
16
+ var getLeftPosition = exports.getLeftPosition = function getLeftPosition(dom, type, innerContainer, macroInteractionUpdates) {
17
+ if (!innerContainer) {
18
+ return "".concat(dom.offsetLeft - (0, _consts.dragHandleGap)(type) - _consts.DRAG_HANDLE_WIDTH, "px");
21
19
  }
22
- return left;
20
+
21
+ // There is a showMacroInteractionDesignUpdates prop in extension node wrapper that can add a relative span under the top level div
22
+ // We need to adjust the left offset position of the drag handle to account for the relative span
23
+ var relativeSpan = macroInteractionUpdates ? dom.querySelector('span.relative') : null;
24
+ var leftAdjustment = relativeSpan ? relativeSpan.offsetLeft : 0;
25
+ return getComputedStyle(innerContainer).transform === 'none' ? "".concat(innerContainer.offsetLeft + leftAdjustment - (0, _consts.dragHandleGap)(type) - _consts.DRAG_HANDLE_WIDTH, "px") : "".concat(innerContainer.offsetLeft + leftAdjustment - innerContainer.offsetWidth / 2 - (0, _consts.dragHandleGap)(type) - _consts.DRAG_HANDLE_WIDTH, "px");
23
26
  };
@@ -22,7 +22,6 @@ export const createPlugin = api => {
22
22
  },
23
23
  apply(tr, currentState, oldState, newState) {
24
24
  var _decorationState, _meta$activeNode, _meta$isDragging, _meta$editorHeight;
25
- // return currentState;
26
25
  let {
27
26
  activeNode,
28
27
  decorations,
@@ -109,7 +108,11 @@ export const createPlugin = api => {
109
108
  },
110
109
  props: {
111
110
  decorations: state => {
112
- var _key$getState;
111
+ var _api$editorDisabled, _api$editorDisabled$s, _key$getState;
112
+ const isDisabled = api === null || api === void 0 ? void 0 : (_api$editorDisabled = api.editorDisabled) === null || _api$editorDisabled === void 0 ? void 0 : (_api$editorDisabled$s = _api$editorDisabled.sharedState.currentState()) === null || _api$editorDisabled$s === void 0 ? void 0 : _api$editorDisabled$s.editorDisabled;
113
+ if (isDisabled) {
114
+ return;
115
+ }
113
116
  return (_key$getState = key.getState(state)) === null || _key$getState === void 0 ? void 0 : _key$getState.decorations;
114
117
  }
115
118
  },
@@ -1,6 +1,7 @@
1
1
  /** @jsx jsx */
2
2
  import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
3
3
  import { css, jsx } from '@emotion/react';
4
+ import { useSharedPluginState } from '@atlaskit/editor-common/hooks';
4
5
  import DragHandlerIcon from '@atlaskit/icon/glyph/drag-handler';
5
6
  import { draggable } from '@atlaskit/pragmatic-drag-and-drop/element/adapter';
6
7
  import { setCustomNativeDragPreview } from '@atlaskit/pragmatic-drag-and-drop/element/set-custom-native-drag-preview';
@@ -46,7 +47,10 @@ export const DragHandle = ({
46
47
  const start = getPos();
47
48
  const buttonRef = useRef(null);
48
49
  const [dragHandleSelected, setDragHandleSelected] = useState(false);
49
- const handleClick = useCallback(() => {
50
+ const {
51
+ featureFlagsState
52
+ } = useSharedPluginState(api, ['featureFlags']);
53
+ const handleOnClick = useCallback(() => {
50
54
  var _api$core, _api$core2;
51
55
  setDragHandleSelected(!dragHandleSelected);
52
56
  api === null || api === void 0 ? void 0 : (_api$core = api.core) === null || _api$core === void 0 ? void 0 : _api$core.actions.execute(({
@@ -63,6 +67,26 @@ export const DragHandle = ({
63
67
  });
64
68
  api === null || api === void 0 ? void 0 : (_api$core2 = api.core) === null || _api$core2 === void 0 ? void 0 : _api$core2.actions.focus();
65
69
  }, [start, api, dragHandleSelected, setDragHandleSelected, nodeType]);
70
+
71
+ // handleMouseDown required along with onClick to ensure the correct selection
72
+ // is set immediately when the drag handle is clicked. Otherwise browser native
73
+ // drag and drop can take over and cause unpredictable behaviour.
74
+ const handleMouseDown = useCallback(() => {
75
+ var _api$core3, _api$core4;
76
+ api === null || api === void 0 ? void 0 : (_api$core3 = api.core) === null || _api$core3 === void 0 ? void 0 : _api$core3.actions.execute(({
77
+ tr
78
+ }) => {
79
+ if (start === undefined) {
80
+ return tr;
81
+ }
82
+ tr = selectNode(tr, start, nodeType);
83
+ tr.setMeta(key, {
84
+ pos: start
85
+ });
86
+ return tr;
87
+ });
88
+ api === null || api === void 0 ? void 0 : (_api$core4 = api.core) === null || _api$core4 === void 0 ? void 0 : _api$core4.actions.focus();
89
+ }, [start, api, nodeType]);
66
90
  useEffect(() => {
67
91
  const element = buttonRef.current;
68
92
  if (!element) {
@@ -87,16 +111,16 @@ export const DragHandle = ({
87
111
  });
88
112
  },
89
113
  onDragStart() {
90
- var _api$core3, _api$blockControls, _api$core4;
114
+ var _api$core5, _api$blockControls, _api$core6;
91
115
  if (start === undefined) {
92
116
  return;
93
117
  }
94
- api === null || api === void 0 ? void 0 : (_api$core3 = api.core) === null || _api$core3 === void 0 ? void 0 : _api$core3.actions.execute(api === null || api === void 0 ? void 0 : (_api$blockControls = api.blockControls) === null || _api$blockControls === void 0 ? void 0 : _api$blockControls.commands.setNodeDragged(start, anchorName, nodeType));
95
- api === null || api === void 0 ? void 0 : (_api$core4 = api.core) === null || _api$core4 === void 0 ? void 0 : _api$core4.actions.focus();
118
+ api === null || api === void 0 ? void 0 : (_api$core5 = api.core) === null || _api$core5 === void 0 ? void 0 : _api$core5.actions.execute(api === null || api === void 0 ? void 0 : (_api$blockControls = api.blockControls) === null || _api$blockControls === void 0 ? void 0 : _api$blockControls.commands.setNodeDragged(start, anchorName, nodeType));
119
+ api === null || api === void 0 ? void 0 : (_api$core6 = api.core) === null || _api$core6 === void 0 ? void 0 : _api$core6.actions.focus();
96
120
  },
97
121
  onDrop() {
98
- var _api$core5;
99
- api === null || api === void 0 ? void 0 : (_api$core5 = api.core) === null || _api$core5 === void 0 ? void 0 : _api$core5.actions.execute(({
122
+ var _api$core7;
123
+ api === null || api === void 0 ? void 0 : (_api$core7 = api.core) === null || _api$core7 === void 0 ? void 0 : _api$core7.actions.execute(({
100
124
  tr
101
125
  }) => {
102
126
  return tr.setMeta(key, {
@@ -106,30 +130,34 @@ export const DragHandle = ({
106
130
  }
107
131
  });
108
132
  }, [api, start, view, anchorName, nodeType]);
133
+ const macroInteractionUpdates = featureFlagsState === null || featureFlagsState === void 0 ? void 0 : featureFlagsState.macroInteractionUpdates;
109
134
  const positionStyles = useMemo(() => {
110
135
  const supportsAnchor = CSS.supports('top', `anchor(${anchorName} start)`) && CSS.supports('left', `anchor(${anchorName} start)`);
111
136
  const dom = view.dom.querySelector(`[data-drag-handler-anchor-name="${anchorName}"]`);
137
+ if (!dom) {
138
+ return;
139
+ }
140
+ const hasResizer = anchorName.includes('table') || anchorName.includes('mediaSingle');
141
+ const isExtension = anchorName.includes('extension') || anchorName.includes('bodiedExtension');
142
+ const innerContainer = hasResizer ? dom.querySelector('.resizer-item') : isExtension ? dom.querySelector('.extension-container[data-layout]') : null;
112
143
  if (supportsAnchor) {
113
- const hasResizer = (anchorName.includes('table') || anchorName.includes('mediaSingle')) && dom;
114
144
  return {
115
- left: hasResizer ? getLeftPosition(dom, nodeType) : `calc(anchor(${anchorName} start) - ${DRAG_HANDLE_WIDTH}px - ${dragHandleGap(nodeType)}px)`,
145
+ left: hasResizer || isExtension ? getLeftPosition(dom, nodeType, innerContainer, macroInteractionUpdates) : `calc(anchor(${anchorName} start) - ${DRAG_HANDLE_WIDTH}px - ${dragHandleGap(nodeType)}px)`,
116
146
  top: anchorName.includes('table') ? `calc(anchor(${anchorName} start) + ${DRAG_HANDLE_HEIGHT}px)` : `anchor(${anchorName} start)`
117
147
  };
118
148
  }
119
- if (!dom) {
120
- return;
121
- }
122
149
  return {
123
- left: getLeftPosition(dom, nodeType),
150
+ left: getLeftPosition(dom, nodeType, innerContainer, macroInteractionUpdates),
124
151
  top: getTopPosition(dom)
125
152
  };
126
- }, [anchorName, view, nodeType]);
153
+ }, [anchorName, view, nodeType, macroInteractionUpdates]);
127
154
  return jsx("button", {
128
155
  type: "button",
129
156
  css: [dragHandleButtonStyles, dragHandleSelected && selectedStyles],
130
157
  ref: buttonRef,
131
158
  style: positionStyles,
132
- onClick: handleClick,
159
+ onClick: handleOnClick,
160
+ onMouseDown: handleMouseDown,
133
161
  "data-testid": "block-ctrl-drag-handle"
134
162
  }, jsx(DragHandlerIcon, {
135
163
  label: "",
@@ -7,11 +7,14 @@ export const getTopPosition = dom => {
7
7
  return `${dom.offsetTop}px`;
8
8
  }
9
9
  };
10
- export const getLeftPosition = (dom, type) => {
11
- const resizer = ['table', 'mediaSingle'].includes(type) ? dom.querySelector('.resizer-item') : null;
12
- let left = `${dom.offsetLeft - dragHandleGap(type) - DRAG_HANDLE_WIDTH}px`;
13
- if (resizer) {
14
- left = getComputedStyle(resizer).transform === 'none' ? `${resizer.offsetLeft - dragHandleGap(type) - DRAG_HANDLE_WIDTH}px` : `${resizer.offsetLeft - resizer.offsetWidth / 2 - dragHandleGap(type) - DRAG_HANDLE_WIDTH}px`;
10
+ export const getLeftPosition = (dom, type, innerContainer, macroInteractionUpdates) => {
11
+ if (!innerContainer) {
12
+ return `${dom.offsetLeft - dragHandleGap(type) - DRAG_HANDLE_WIDTH}px`;
15
13
  }
16
- return left;
14
+
15
+ // There is a showMacroInteractionDesignUpdates prop in extension node wrapper that can add a relative span under the top level div
16
+ // We need to adjust the left offset position of the drag handle to account for the relative span
17
+ const relativeSpan = macroInteractionUpdates ? dom.querySelector('span.relative') : null;
18
+ const leftAdjustment = relativeSpan ? relativeSpan.offsetLeft : 0;
19
+ return getComputedStyle(innerContainer).transform === 'none' ? `${innerContainer.offsetLeft + leftAdjustment - dragHandleGap(type) - DRAG_HANDLE_WIDTH}px` : `${innerContainer.offsetLeft + leftAdjustment - innerContainer.offsetWidth / 2 - dragHandleGap(type) - DRAG_HANDLE_WIDTH}px`;
17
20
  };
@@ -23,7 +23,6 @@ export var createPlugin = function createPlugin(api) {
23
23
  },
24
24
  apply: function apply(tr, currentState, oldState, newState) {
25
25
  var _decorationState, _meta$activeNode, _meta$isDragging, _meta$editorHeight;
26
- // return currentState;
27
26
  var activeNode = currentState.activeNode,
28
27
  decorations = currentState.decorations,
29
28
  isMenuOpen = currentState.isMenuOpen,
@@ -108,7 +107,11 @@ export var createPlugin = function createPlugin(api) {
108
107
  },
109
108
  props: {
110
109
  decorations: function decorations(state) {
111
- var _key$getState;
110
+ var _api$editorDisabled, _key$getState;
111
+ var isDisabled = api === null || api === void 0 || (_api$editorDisabled = api.editorDisabled) === null || _api$editorDisabled === void 0 || (_api$editorDisabled = _api$editorDisabled.sharedState.currentState()) === null || _api$editorDisabled === void 0 ? void 0 : _api$editorDisabled.editorDisabled;
112
+ if (isDisabled) {
113
+ return;
114
+ }
112
115
  return (_key$getState = key.getState(state)) === null || _key$getState === void 0 ? void 0 : _key$getState.decorations;
113
116
  }
114
117
  },
@@ -2,6 +2,7 @@ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
2
2
  /** @jsx jsx */
3
3
  import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
4
4
  import { css, jsx } from '@emotion/react';
5
+ import { useSharedPluginState } from '@atlaskit/editor-common/hooks';
5
6
  import DragHandlerIcon from '@atlaskit/icon/glyph/drag-handler';
6
7
  import { draggable } from '@atlaskit/pragmatic-drag-and-drop/element/adapter';
7
8
  import { setCustomNativeDragPreview } from '@atlaskit/pragmatic-drag-and-drop/element/set-custom-native-drag-preview';
@@ -49,7 +50,9 @@ export var DragHandle = function DragHandle(_ref) {
49
50
  _useState2 = _slicedToArray(_useState, 2),
50
51
  dragHandleSelected = _useState2[0],
51
52
  setDragHandleSelected = _useState2[1];
52
- var handleClick = useCallback(function () {
53
+ var _useSharedPluginState = useSharedPluginState(api, ['featureFlags']),
54
+ featureFlagsState = _useSharedPluginState.featureFlagsState;
55
+ var handleOnClick = useCallback(function () {
53
56
  var _api$core, _api$core2;
54
57
  setDragHandleSelected(!dragHandleSelected);
55
58
  api === null || api === void 0 || (_api$core = api.core) === null || _api$core === void 0 || _api$core.actions.execute(function (_ref2) {
@@ -65,6 +68,25 @@ export var DragHandle = function DragHandle(_ref) {
65
68
  });
66
69
  api === null || api === void 0 || (_api$core2 = api.core) === null || _api$core2 === void 0 || _api$core2.actions.focus();
67
70
  }, [start, api, dragHandleSelected, setDragHandleSelected, nodeType]);
71
+
72
+ // handleMouseDown required along with onClick to ensure the correct selection
73
+ // is set immediately when the drag handle is clicked. Otherwise browser native
74
+ // drag and drop can take over and cause unpredictable behaviour.
75
+ var handleMouseDown = useCallback(function () {
76
+ var _api$core3, _api$core4;
77
+ api === null || api === void 0 || (_api$core3 = api.core) === null || _api$core3 === void 0 || _api$core3.actions.execute(function (_ref3) {
78
+ var tr = _ref3.tr;
79
+ if (start === undefined) {
80
+ return tr;
81
+ }
82
+ tr = selectNode(tr, start, nodeType);
83
+ tr.setMeta(key, {
84
+ pos: start
85
+ });
86
+ return tr;
87
+ });
88
+ api === null || api === void 0 || (_api$core4 = api.core) === null || _api$core4 === void 0 || _api$core4.actions.focus();
89
+ }, [start, api, nodeType]);
68
90
  useEffect(function () {
69
91
  var element = buttonRef.current;
70
92
  if (!element) {
@@ -72,11 +94,11 @@ export var DragHandle = function DragHandle(_ref) {
72
94
  }
73
95
  return draggable({
74
96
  element: element,
75
- onGenerateDragPreview: function onGenerateDragPreview(_ref3) {
76
- var nativeSetDragImage = _ref3.nativeSetDragImage;
97
+ onGenerateDragPreview: function onGenerateDragPreview(_ref4) {
98
+ var nativeSetDragImage = _ref4.nativeSetDragImage;
77
99
  setCustomNativeDragPreview({
78
- render: function render(_ref4) {
79
- var container = _ref4.container;
100
+ render: function render(_ref5) {
101
+ var container = _ref5.container;
80
102
  var dom = view.dom.querySelector("[data-drag-handler-anchor-name=\"".concat(anchorName, "\"]"));
81
103
  if (!dom) {
82
104
  return;
@@ -87,17 +109,17 @@ export var DragHandle = function DragHandle(_ref) {
87
109
  });
88
110
  },
89
111
  onDragStart: function onDragStart() {
90
- var _api$core3, _api$blockControls, _api$core4;
112
+ var _api$core5, _api$blockControls, _api$core6;
91
113
  if (start === undefined) {
92
114
  return;
93
115
  }
94
- api === null || api === void 0 || (_api$core3 = api.core) === null || _api$core3 === void 0 || _api$core3.actions.execute(api === null || api === void 0 || (_api$blockControls = api.blockControls) === null || _api$blockControls === void 0 ? void 0 : _api$blockControls.commands.setNodeDragged(start, anchorName, nodeType));
95
- api === null || api === void 0 || (_api$core4 = api.core) === null || _api$core4 === void 0 || _api$core4.actions.focus();
116
+ api === null || api === void 0 || (_api$core5 = api.core) === null || _api$core5 === void 0 || _api$core5.actions.execute(api === null || api === void 0 || (_api$blockControls = api.blockControls) === null || _api$blockControls === void 0 ? void 0 : _api$blockControls.commands.setNodeDragged(start, anchorName, nodeType));
117
+ api === null || api === void 0 || (_api$core6 = api.core) === null || _api$core6 === void 0 || _api$core6.actions.focus();
96
118
  },
97
119
  onDrop: function onDrop() {
98
- var _api$core5;
99
- api === null || api === void 0 || (_api$core5 = api.core) === null || _api$core5 === void 0 || _api$core5.actions.execute(function (_ref5) {
100
- var tr = _ref5.tr;
120
+ var _api$core7;
121
+ api === null || api === void 0 || (_api$core7 = api.core) === null || _api$core7 === void 0 || _api$core7.actions.execute(function (_ref6) {
122
+ var tr = _ref6.tr;
101
123
  return tr.setMeta(key, {
102
124
  isDragging: false
103
125
  });
@@ -105,30 +127,34 @@ export var DragHandle = function DragHandle(_ref) {
105
127
  }
106
128
  });
107
129
  }, [api, start, view, anchorName, nodeType]);
130
+ var macroInteractionUpdates = featureFlagsState === null || featureFlagsState === void 0 ? void 0 : featureFlagsState.macroInteractionUpdates;
108
131
  var positionStyles = useMemo(function () {
109
132
  var supportsAnchor = CSS.supports('top', "anchor(".concat(anchorName, " start)")) && CSS.supports('left', "anchor(".concat(anchorName, " start)"));
110
133
  var dom = view.dom.querySelector("[data-drag-handler-anchor-name=\"".concat(anchorName, "\"]"));
134
+ if (!dom) {
135
+ return;
136
+ }
137
+ var hasResizer = anchorName.includes('table') || anchorName.includes('mediaSingle');
138
+ var isExtension = anchorName.includes('extension') || anchorName.includes('bodiedExtension');
139
+ var innerContainer = hasResizer ? dom.querySelector('.resizer-item') : isExtension ? dom.querySelector('.extension-container[data-layout]') : null;
111
140
  if (supportsAnchor) {
112
- var hasResizer = (anchorName.includes('table') || anchorName.includes('mediaSingle')) && dom;
113
141
  return {
114
- left: hasResizer ? getLeftPosition(dom, nodeType) : "calc(anchor(".concat(anchorName, " start) - ").concat(DRAG_HANDLE_WIDTH, "px - ").concat(dragHandleGap(nodeType), "px)"),
142
+ left: hasResizer || isExtension ? getLeftPosition(dom, nodeType, innerContainer, macroInteractionUpdates) : "calc(anchor(".concat(anchorName, " start) - ").concat(DRAG_HANDLE_WIDTH, "px - ").concat(dragHandleGap(nodeType), "px)"),
115
143
  top: anchorName.includes('table') ? "calc(anchor(".concat(anchorName, " start) + ").concat(DRAG_HANDLE_HEIGHT, "px)") : "anchor(".concat(anchorName, " start)")
116
144
  };
117
145
  }
118
- if (!dom) {
119
- return;
120
- }
121
146
  return {
122
- left: getLeftPosition(dom, nodeType),
147
+ left: getLeftPosition(dom, nodeType, innerContainer, macroInteractionUpdates),
123
148
  top: getTopPosition(dom)
124
149
  };
125
- }, [anchorName, view, nodeType]);
150
+ }, [anchorName, view, nodeType, macroInteractionUpdates]);
126
151
  return jsx("button", {
127
152
  type: "button",
128
153
  css: [dragHandleButtonStyles, dragHandleSelected && selectedStyles],
129
154
  ref: buttonRef,
130
155
  style: positionStyles,
131
- onClick: handleClick,
156
+ onClick: handleOnClick,
157
+ onMouseDown: handleMouseDown,
132
158
  "data-testid": "block-ctrl-drag-handle"
133
159
  }, jsx(DragHandlerIcon, {
134
160
  label: "",
@@ -7,11 +7,14 @@ export var getTopPosition = function getTopPosition(dom) {
7
7
  return "".concat(dom.offsetTop, "px");
8
8
  }
9
9
  };
10
- export var getLeftPosition = function getLeftPosition(dom, type) {
11
- var resizer = ['table', 'mediaSingle'].includes(type) ? dom.querySelector('.resizer-item') : null;
12
- var left = "".concat(dom.offsetLeft - dragHandleGap(type) - DRAG_HANDLE_WIDTH, "px");
13
- if (resizer) {
14
- left = getComputedStyle(resizer).transform === 'none' ? "".concat(resizer.offsetLeft - dragHandleGap(type) - DRAG_HANDLE_WIDTH, "px") : "".concat(resizer.offsetLeft - resizer.offsetWidth / 2 - dragHandleGap(type) - DRAG_HANDLE_WIDTH, "px");
10
+ export var getLeftPosition = function getLeftPosition(dom, type, innerContainer, macroInteractionUpdates) {
11
+ if (!innerContainer) {
12
+ return "".concat(dom.offsetLeft - dragHandleGap(type) - DRAG_HANDLE_WIDTH, "px");
15
13
  }
16
- return left;
14
+
15
+ // There is a showMacroInteractionDesignUpdates prop in extension node wrapper that can add a relative span under the top level div
16
+ // We need to adjust the left offset position of the drag handle to account for the relative span
17
+ var relativeSpan = macroInteractionUpdates ? dom.querySelector('span.relative') : null;
18
+ var leftAdjustment = relativeSpan ? relativeSpan.offsetLeft : 0;
19
+ return getComputedStyle(innerContainer).transform === 'none' ? "".concat(innerContainer.offsetLeft + leftAdjustment - dragHandleGap(type) - DRAG_HANDLE_WIDTH, "px") : "".concat(innerContainer.offsetLeft + leftAdjustment - innerContainer.offsetWidth / 2 - dragHandleGap(type) - DRAG_HANDLE_WIDTH, "px");
17
20
  };
@@ -1,4 +1,6 @@
1
1
  import type { EditorCommand, NextEditorPlugin, OptionalPlugin } from '@atlaskit/editor-common/types';
2
+ import type { EditorDisabledPlugin } from '@atlaskit/editor-plugin-editor-disabled';
3
+ import type { FeatureFlagsPlugin } from '@atlaskit/editor-plugin-feature-flags';
2
4
  import type { WidthPlugin } from '@atlaskit/editor-plugin-width';
3
5
  import { type DecorationSet } from '@atlaskit/editor-prosemirror/view';
4
6
  export interface PluginState {
@@ -15,7 +17,11 @@ export interface PluginState {
15
17
  }
16
18
  export type ReleaseHiddenDecoration = () => boolean | undefined;
17
19
  export type BlockControlsPlugin = NextEditorPlugin<'blockControls', {
18
- dependencies: [OptionalPlugin<WidthPlugin>];
20
+ dependencies: [
21
+ OptionalPlugin<EditorDisabledPlugin>,
22
+ OptionalPlugin<WidthPlugin>,
23
+ OptionalPlugin<FeatureFlagsPlugin>
24
+ ];
19
25
  sharedState: {
20
26
  isMenuOpen: boolean;
21
27
  activeNode: {
@@ -1,2 +1,2 @@
1
1
  export declare const getTopPosition: (dom: HTMLElement) => string;
2
- export declare const getLeftPosition: (dom: HTMLElement, type: string) => string;
2
+ export declare const getLeftPosition: (dom: HTMLElement, type: string, innerContainer?: HTMLElement | null, macroInteractionUpdates?: boolean) => string;
@@ -1,4 +1,6 @@
1
1
  import type { EditorCommand, NextEditorPlugin, OptionalPlugin } from '@atlaskit/editor-common/types';
2
+ import type { EditorDisabledPlugin } from '@atlaskit/editor-plugin-editor-disabled';
3
+ import type { FeatureFlagsPlugin } from '@atlaskit/editor-plugin-feature-flags';
2
4
  import type { WidthPlugin } from '@atlaskit/editor-plugin-width';
3
5
  import { type DecorationSet } from '@atlaskit/editor-prosemirror/view';
4
6
  export interface PluginState {
@@ -16,7 +18,9 @@ export interface PluginState {
16
18
  export type ReleaseHiddenDecoration = () => boolean | undefined;
17
19
  export type BlockControlsPlugin = NextEditorPlugin<'blockControls', {
18
20
  dependencies: [
19
- OptionalPlugin<WidthPlugin>
21
+ OptionalPlugin<EditorDisabledPlugin>,
22
+ OptionalPlugin<WidthPlugin>,
23
+ OptionalPlugin<FeatureFlagsPlugin>
20
24
  ];
21
25
  sharedState: {
22
26
  isMenuOpen: boolean;
@@ -1,2 +1,2 @@
1
1
  export declare const getTopPosition: (dom: HTMLElement) => string;
2
- export declare const getLeftPosition: (dom: HTMLElement, type: string) => string;
2
+ export declare const getLeftPosition: (dom: HTMLElement, type: string, innerContainer?: HTMLElement | null, macroInteractionUpdates?: boolean) => string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-block-controls",
3
- "version": "1.4.11",
3
+ "version": "1.4.13",
4
4
  "description": "Block controls plugin for @atlaskit/editor-core",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -31,7 +31,9 @@
31
31
  ".": "./src/index.ts"
32
32
  },
33
33
  "dependencies": {
34
- "@atlaskit/editor-common": "^82.1.0",
34
+ "@atlaskit/editor-common": "^82.3.0",
35
+ "@atlaskit/editor-plugin-editor-disabled": "^1.1.5",
36
+ "@atlaskit/editor-plugin-feature-flags": "^1.1.0",
35
37
  "@atlaskit/editor-plugin-width": "^1.1.0",
36
38
  "@atlaskit/editor-prosemirror": "4.0.1",
37
39
  "@atlaskit/editor-tables": "^2.7.0",
@@ -39,7 +41,7 @@
39
41
  "@atlaskit/pragmatic-drag-and-drop": "^1.1.0",
40
42
  "@atlaskit/pragmatic-drag-and-drop-auto-scroll": "^1.3.0",
41
43
  "@atlaskit/pragmatic-drag-and-drop-react-drop-indicator": "^1.1.0",
42
- "@atlaskit/tokens": "^1.49.0",
44
+ "@atlaskit/tokens": "^1.50.0",
43
45
  "@babel/runtime": "^7.0.0",
44
46
  "@emotion/react": "^11.7.1",
45
47
  "raf-schd": "^4.0.3"