@atlaskit/editor-plugin-block-controls 1.4.10 → 1.4.12

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,22 @@
1
1
  # @atlaskit/editor-plugin-block-controls
2
2
 
3
+ ## 1.4.12
4
+
5
+ ### Patch Changes
6
+
7
+ - [#108853](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/108853)
8
+ [`390f442689fd6`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/390f442689fd6) -
9
+ Fix position of drag handle for extension/ bodiedExtension nodes in wide or fullWidth layout
10
+
11
+ ## 1.4.11
12
+
13
+ ### Patch Changes
14
+
15
+ - [#108763](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/108763)
16
+ [`f97149e66b556`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/f97149e66b556) -
17
+ Fix table scroll when table selected by drag handle
18
+ - Updated dependencies
19
+
3
20
  ## 1.4.10
4
21
 
5
22
  ### Patch Changes
@@ -9,7 +9,7 @@ var _react = _interopRequireDefault(require("react"));
9
9
  var _main = require("./pm-plugins/main");
10
10
  var _dragHandleMenu = require("./ui/drag-handle-menu");
11
11
  var _globalStyles = require("./ui/global-styles");
12
- var _getSelection = require("./utils/getSelection");
12
+ var _utils = require("./utils");
13
13
  var blockControlsPlugin = exports.blockControlsPlugin = function blockControlsPlugin(_ref) {
14
14
  var api = _ref.api;
15
15
  return {
@@ -28,13 +28,16 @@ var blockControlsPlugin = exports.blockControlsPlugin = function blockControlsPl
28
28
  var _node$nodeSize;
29
29
  var tr = _ref2.tr;
30
30
  var node = tr.doc.nodeAt(start);
31
+ if (!node) {
32
+ return tr;
33
+ }
31
34
  var size = (_node$nodeSize = node === null || node === void 0 ? void 0 : node.nodeSize) !== null && _node$nodeSize !== void 0 ? _node$nodeSize : 1;
32
35
  var end = start + size;
33
36
  var nodeCopy = tr.doc.content.cut(start, end); // cut the content
34
37
  tr.delete(start, end); // delete the content from the original position
35
38
  var mappedTo = tr.mapping.map(to);
36
39
  tr.insert(mappedTo, nodeCopy); // insert the content at the new position
37
- tr.setSelection((0, _getSelection.getSelection)(tr, mappedTo));
40
+ tr = (0, _utils.selectNode)(tr, mappedTo, node.type.name);
38
41
  tr.setMeta(_main.key, {
39
42
  nodeMoved: true
40
43
  });
@@ -55,19 +58,20 @@ var blockControlsPlugin = exports.blockControlsPlugin = function blockControlsPl
55
58
  return tr;
56
59
  };
57
60
  },
58
- setNodeDragged: function setNodeDragged(pos, anchorName) {
61
+ setNodeDragged: function setNodeDragged(pos, anchorName, nodeType) {
59
62
  return function (_ref4) {
60
63
  var tr = _ref4.tr;
61
- var newTr = tr;
62
64
  if (pos === undefined) {
63
65
  return tr;
64
66
  }
65
- newTr.setSelection((0, _getSelection.getSelection)(newTr, pos));
67
+ var newTr = tr;
68
+ newTr = (0, _utils.selectNode)(newTr, pos, nodeType);
66
69
  newTr.setMeta(_main.key, {
67
70
  isDragging: true,
68
71
  activeNode: {
69
72
  pos: pos,
70
- anchorName: anchorName
73
+ anchorName: anchorName,
74
+ nodeType: nodeType
71
75
  }
72
76
  });
73
77
  return newTr;
@@ -100,7 +100,8 @@ var createPlugin = exports.createPlugin = function createPlugin(api) {
100
100
  // Map active node position when the document changes
101
101
  var mappedActiveNodePos = tr.docChanged && activeNode ? {
102
102
  pos: tr.mapping.map(activeNode.pos),
103
- anchorName: activeNode.anchorName
103
+ anchorName: activeNode.anchorName,
104
+ nodeType: activeNode.nodeType
104
105
  } : activeNode;
105
106
  return {
106
107
  decorations: decorations,
@@ -8,12 +8,13 @@ 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");
14
15
  var _main = require("../pm-plugins/main");
16
+ var _utils = require("../utils");
15
17
  var _dragHandlePositions = require("../utils/drag-handle-positions");
16
- var _getSelection = require("../utils/getSelection");
17
18
  var _consts = require("./consts");
18
19
  var _dragPreview = require("./drag-preview");
19
20
  /** @jsx jsx */
@@ -57,6 +58,8 @@ 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];
61
+ var _useSharedPluginState = (0, _hooks.useSharedPluginState)(api, ['featureFlags']),
62
+ featureFlagsState = _useSharedPluginState.featureFlagsState;
60
63
  var handleClick = (0, _react.useCallback)(function () {
61
64
  var _api$core, _api$core2;
62
65
  setDragHandleSelected(!dragHandleSelected);
@@ -65,14 +68,14 @@ var DragHandle = exports.DragHandle = function DragHandle(_ref) {
65
68
  if (start === undefined) {
66
69
  return tr;
67
70
  }
68
- tr.setSelection((0, _getSelection.getSelection)(tr, start));
71
+ tr = (0, _utils.selectNode)(tr, start, nodeType);
69
72
  tr.setMeta(_main.key, {
70
73
  pos: start
71
74
  });
72
75
  return tr;
73
76
  });
74
77
  api === null || api === void 0 || (_api$core2 = api.core) === null || _api$core2 === void 0 || _api$core2.actions.focus();
75
- }, [start, api, dragHandleSelected, setDragHandleSelected]);
78
+ }, [start, api, dragHandleSelected, setDragHandleSelected, nodeType]);
76
79
  (0, _react.useEffect)(function () {
77
80
  var element = buttonRef.current;
78
81
  if (!element) {
@@ -99,7 +102,7 @@ var DragHandle = exports.DragHandle = function DragHandle(_ref) {
99
102
  if (start === undefined) {
100
103
  return;
101
104
  }
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));
105
+ 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
106
  api === null || api === void 0 || (_api$core4 = api.core) === null || _api$core4 === void 0 || _api$core4.actions.focus();
104
107
  },
105
108
  onDrop: function onDrop() {
@@ -112,25 +115,28 @@ var DragHandle = exports.DragHandle = function DragHandle(_ref) {
112
115
  });
113
116
  }
114
117
  });
115
- }, [api, start, view, anchorName]);
118
+ }, [api, start, view, anchorName, nodeType]);
119
+ var macroInteractionUpdates = featureFlagsState === null || featureFlagsState === void 0 ? void 0 : featureFlagsState.macroInteractionUpdates;
116
120
  var positionStyles = (0, _react.useMemo)(function () {
117
121
  var supportsAnchor = CSS.supports('top', "anchor(".concat(anchorName, " start)")) && CSS.supports('left', "anchor(".concat(anchorName, " start)"));
118
122
  var dom = view.dom.querySelector("[data-drag-handler-anchor-name=\"".concat(anchorName, "\"]"));
123
+ if (!dom) {
124
+ return;
125
+ }
126
+ var hasResizer = anchorName.includes('table') || anchorName.includes('mediaSingle');
127
+ var isExtension = anchorName.includes('extension') || anchorName.includes('bodiedExtension');
128
+ var innerContainer = hasResizer ? dom.querySelector('.resizer-item') : isExtension ? dom.querySelector('.extension-container[data-layout]') : null;
119
129
  if (supportsAnchor) {
120
- var hasResizer = (anchorName.includes('table') || anchorName.includes('mediaSingle')) && dom;
121
130
  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)"),
131
+ 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
132
  top: anchorName.includes('table') ? "calc(anchor(".concat(anchorName, " start) + ").concat(_consts.DRAG_HANDLE_HEIGHT, "px)") : "anchor(".concat(anchorName, " start)")
124
133
  };
125
134
  }
126
- if (!dom) {
127
- return;
128
- }
129
135
  return {
130
- left: (0, _dragHandlePositions.getLeftPosition)(dom, nodeType),
136
+ left: (0, _dragHandlePositions.getLeftPosition)(dom, nodeType, innerContainer, macroInteractionUpdates),
131
137
  top: (0, _dragHandlePositions.getTopPosition)(dom)
132
138
  };
133
- }, [anchorName, view, nodeType]);
139
+ }, [anchorName, view, nodeType, macroInteractionUpdates]);
134
140
  return (0, _react2.jsx)("button", {
135
141
  type: "button",
136
142
  css: [dragHandleButtonStyles, dragHandleSelected && selectedStyles],
@@ -100,7 +100,7 @@ var DropTarget = exports.DropTarget = function DropTarget(_ref) {
100
100
  isDraggedOver && (0, _react2.jsx)("div", {
101
101
  css: styleDropIndicator,
102
102
  style: {
103
- 'width': "".concat(lineLength, "px")
103
+ width: "".concat(lineLength, "px")
104
104
  },
105
105
  "data-testid": "block-ctrl-drop-indicator"
106
106
  }, (0, _react2.jsx)(_box.DropIndicator, {
@@ -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
  };
@@ -3,8 +3,9 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.getSelection = void 0;
6
+ exports.selectNode = exports.getSelection = void 0;
7
7
  var _state = require("@atlaskit/editor-prosemirror/state");
8
+ var _utils = require("@atlaskit/editor-tables/utils");
8
9
  var getSelection = exports.getSelection = function getSelection(tr, start) {
9
10
  var node = tr.doc.nodeAt(start);
10
11
  var isNodeSelection = node && _state.NodeSelection.isSelectable(node);
@@ -31,4 +32,13 @@ var getSelection = exports.getSelection = function getSelection(tr, start) {
31
32
  var textNodeDepth = textNodesPos - start;
32
33
  return new _state.TextSelection(tr.doc.resolve(textNodesPos), tr.doc.resolve(start + nodeSize - textNodeDepth));
33
34
  }
35
+ };
36
+ var selectNode = exports.selectNode = function selectNode(tr, start, nodeType) {
37
+ // For table, we need to do cell selection instead of node selection
38
+ if (nodeType === 'table') {
39
+ tr = (0, _utils.selectTableClosestToPos)(tr, tr.doc.resolve(start + 1));
40
+ } else {
41
+ tr.setSelection(getSelection(tr, start));
42
+ }
43
+ return tr;
34
44
  };
@@ -9,4 +9,10 @@ Object.defineProperty(exports, "getSelection", {
9
9
  return _getSelection.getSelection;
10
10
  }
11
11
  });
12
+ Object.defineProperty(exports, "selectNode", {
13
+ enumerable: true,
14
+ get: function get() {
15
+ return _getSelection.selectNode;
16
+ }
17
+ });
12
18
  var _getSelection = require("./getSelection");
@@ -2,7 +2,7 @@ import React from 'react';
2
2
  import { createPlugin, key } from './pm-plugins/main';
3
3
  import { DragHandleMenu } from './ui/drag-handle-menu';
4
4
  import { GlobalStylesWrapper } from './ui/global-styles';
5
- import { getSelection } from './utils/getSelection';
5
+ import { selectNode } from './utils';
6
6
  export const blockControlsPlugin = ({
7
7
  api
8
8
  }) => ({
@@ -19,13 +19,16 @@ export const blockControlsPlugin = ({
19
19
  }) => {
20
20
  var _node$nodeSize;
21
21
  const node = tr.doc.nodeAt(start);
22
+ if (!node) {
23
+ return tr;
24
+ }
22
25
  const size = (_node$nodeSize = node === null || node === void 0 ? void 0 : node.nodeSize) !== null && _node$nodeSize !== void 0 ? _node$nodeSize : 1;
23
26
  const end = start + size;
24
27
  let nodeCopy = tr.doc.content.cut(start, end); // cut the content
25
28
  tr.delete(start, end); // delete the content from the original position
26
29
  const mappedTo = tr.mapping.map(to);
27
30
  tr.insert(mappedTo, nodeCopy); // insert the content at the new position
28
- tr.setSelection(getSelection(tr, mappedTo));
31
+ tr = selectNode(tr, mappedTo, node.type.name);
29
32
  tr.setMeta(key, {
30
33
  nodeMoved: true
31
34
  });
@@ -44,19 +47,20 @@ export const blockControlsPlugin = ({
44
47
  });
45
48
  return tr;
46
49
  },
47
- setNodeDragged: (pos, anchorName) => ({
50
+ setNodeDragged: (pos, anchorName, nodeType) => ({
48
51
  tr
49
52
  }) => {
50
- const newTr = tr;
51
53
  if (pos === undefined) {
52
54
  return tr;
53
55
  }
54
- newTr.setSelection(getSelection(newTr, pos));
56
+ let newTr = tr;
57
+ newTr = selectNode(newTr, pos, nodeType);
55
58
  newTr.setMeta(key, {
56
59
  isDragging: true,
57
60
  activeNode: {
58
61
  pos,
59
- anchorName
62
+ anchorName,
63
+ nodeType
60
64
  }
61
65
  });
62
66
  return newTr;
@@ -94,7 +94,8 @@ export const createPlugin = api => {
94
94
  // Map active node position when the document changes
95
95
  const mappedActiveNodePos = tr.docChanged && activeNode ? {
96
96
  pos: tr.mapping.map(activeNode.pos),
97
- anchorName: activeNode.anchorName
97
+ anchorName: activeNode.anchorName,
98
+ nodeType: activeNode.nodeType
98
99
  } : activeNode;
99
100
  return {
100
101
  decorations,
@@ -1,12 +1,13 @@
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';
7
8
  import { key } from '../pm-plugins/main';
9
+ import { selectNode } from '../utils';
8
10
  import { getLeftPosition, getTopPosition } from '../utils/drag-handle-positions';
9
- import { getSelection } from '../utils/getSelection';
10
11
  import { DRAG_HANDLE_BORDER_RADIUS, DRAG_HANDLE_HEIGHT, DRAG_HANDLE_WIDTH, dragHandleGap } from './consts';
11
12
  import { dragPreview } from './drag-preview';
12
13
  const dragHandleButtonStyles = css({
@@ -46,6 +47,9 @@ export const DragHandle = ({
46
47
  const start = getPos();
47
48
  const buttonRef = useRef(null);
48
49
  const [dragHandleSelected, setDragHandleSelected] = useState(false);
50
+ const {
51
+ featureFlagsState
52
+ } = useSharedPluginState(api, ['featureFlags']);
49
53
  const handleClick = useCallback(() => {
50
54
  var _api$core, _api$core2;
51
55
  setDragHandleSelected(!dragHandleSelected);
@@ -55,14 +59,14 @@ export const DragHandle = ({
55
59
  if (start === undefined) {
56
60
  return tr;
57
61
  }
58
- tr.setSelection(getSelection(tr, start));
62
+ tr = selectNode(tr, start, nodeType);
59
63
  tr.setMeta(key, {
60
64
  pos: start
61
65
  });
62
66
  return tr;
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
- }, [start, api, dragHandleSelected, setDragHandleSelected]);
69
+ }, [start, api, dragHandleSelected, setDragHandleSelected, nodeType]);
66
70
  useEffect(() => {
67
71
  const element = buttonRef.current;
68
72
  if (!element) {
@@ -91,7 +95,7 @@ export const DragHandle = ({
91
95
  if (start === undefined) {
92
96
  return;
93
97
  }
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));
98
+ 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
99
  api === null || api === void 0 ? void 0 : (_api$core4 = api.core) === null || _api$core4 === void 0 ? void 0 : _api$core4.actions.focus();
96
100
  },
97
101
  onDrop() {
@@ -105,25 +109,28 @@ export const DragHandle = ({
105
109
  });
106
110
  }
107
111
  });
108
- }, [api, start, view, anchorName]);
112
+ }, [api, start, view, anchorName, nodeType]);
113
+ const macroInteractionUpdates = featureFlagsState === null || featureFlagsState === void 0 ? void 0 : featureFlagsState.macroInteractionUpdates;
109
114
  const positionStyles = useMemo(() => {
110
115
  const supportsAnchor = CSS.supports('top', `anchor(${anchorName} start)`) && CSS.supports('left', `anchor(${anchorName} start)`);
111
116
  const dom = view.dom.querySelector(`[data-drag-handler-anchor-name="${anchorName}"]`);
117
+ if (!dom) {
118
+ return;
119
+ }
120
+ const hasResizer = anchorName.includes('table') || anchorName.includes('mediaSingle');
121
+ const isExtension = anchorName.includes('extension') || anchorName.includes('bodiedExtension');
122
+ const innerContainer = hasResizer ? dom.querySelector('.resizer-item') : isExtension ? dom.querySelector('.extension-container[data-layout]') : null;
112
123
  if (supportsAnchor) {
113
- const hasResizer = (anchorName.includes('table') || anchorName.includes('mediaSingle')) && dom;
114
124
  return {
115
- left: hasResizer ? getLeftPosition(dom, nodeType) : `calc(anchor(${anchorName} start) - ${DRAG_HANDLE_WIDTH}px - ${dragHandleGap(nodeType)}px)`,
125
+ left: hasResizer || isExtension ? getLeftPosition(dom, nodeType, innerContainer, macroInteractionUpdates) : `calc(anchor(${anchorName} start) - ${DRAG_HANDLE_WIDTH}px - ${dragHandleGap(nodeType)}px)`,
116
126
  top: anchorName.includes('table') ? `calc(anchor(${anchorName} start) + ${DRAG_HANDLE_HEIGHT}px)` : `anchor(${anchorName} start)`
117
127
  };
118
128
  }
119
- if (!dom) {
120
- return;
121
- }
122
129
  return {
123
- left: getLeftPosition(dom, nodeType),
130
+ left: getLeftPosition(dom, nodeType, innerContainer, macroInteractionUpdates),
124
131
  top: getTopPosition(dom)
125
132
  };
126
- }, [anchorName, view, nodeType]);
133
+ }, [anchorName, view, nodeType, macroInteractionUpdates]);
127
134
  return jsx("button", {
128
135
  type: "button",
129
136
  css: [dragHandleButtonStyles, dragHandleSelected && selectedStyles],
@@ -86,7 +86,7 @@ export const DropTarget = ({
86
86
  isDraggedOver && jsx("div", {
87
87
  css: styleDropIndicator,
88
88
  style: {
89
- 'width': `${lineLength}px`
89
+ width: `${lineLength}px`
90
90
  },
91
91
  "data-testid": "block-ctrl-drop-indicator"
92
92
  }, jsx(DropIndicator, {
@@ -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
  };
@@ -1,4 +1,5 @@
1
1
  import { NodeSelection, TextSelection } from '@atlaskit/editor-prosemirror/state';
2
+ import { selectTableClosestToPos } from '@atlaskit/editor-tables/utils';
2
3
  export const getSelection = (tr, start) => {
3
4
  const node = tr.doc.nodeAt(start);
4
5
  const isNodeSelection = node && NodeSelection.isSelectable(node);
@@ -25,4 +26,13 @@ export const getSelection = (tr, start) => {
25
26
  const textNodeDepth = textNodesPos - start;
26
27
  return new TextSelection(tr.doc.resolve(textNodesPos), tr.doc.resolve(start + nodeSize - textNodeDepth));
27
28
  }
29
+ };
30
+ export const selectNode = (tr, start, nodeType) => {
31
+ // For table, we need to do cell selection instead of node selection
32
+ if (nodeType === 'table') {
33
+ tr = selectTableClosestToPos(tr, tr.doc.resolve(start + 1));
34
+ } else {
35
+ tr.setSelection(getSelection(tr, start));
36
+ }
37
+ return tr;
28
38
  };
@@ -1 +1 @@
1
- export { getSelection } from './getSelection';
1
+ export { getSelection, selectNode } from './getSelection';
@@ -2,7 +2,7 @@ import React from 'react';
2
2
  import { createPlugin, key } from './pm-plugins/main';
3
3
  import { DragHandleMenu } from './ui/drag-handle-menu';
4
4
  import { GlobalStylesWrapper } from './ui/global-styles';
5
- import { getSelection } from './utils/getSelection';
5
+ import { selectNode } from './utils';
6
6
  export var blockControlsPlugin = function blockControlsPlugin(_ref) {
7
7
  var api = _ref.api;
8
8
  return {
@@ -21,13 +21,16 @@ export var blockControlsPlugin = function blockControlsPlugin(_ref) {
21
21
  var _node$nodeSize;
22
22
  var tr = _ref2.tr;
23
23
  var node = tr.doc.nodeAt(start);
24
+ if (!node) {
25
+ return tr;
26
+ }
24
27
  var size = (_node$nodeSize = node === null || node === void 0 ? void 0 : node.nodeSize) !== null && _node$nodeSize !== void 0 ? _node$nodeSize : 1;
25
28
  var end = start + size;
26
29
  var nodeCopy = tr.doc.content.cut(start, end); // cut the content
27
30
  tr.delete(start, end); // delete the content from the original position
28
31
  var mappedTo = tr.mapping.map(to);
29
32
  tr.insert(mappedTo, nodeCopy); // insert the content at the new position
30
- tr.setSelection(getSelection(tr, mappedTo));
33
+ tr = selectNode(tr, mappedTo, node.type.name);
31
34
  tr.setMeta(key, {
32
35
  nodeMoved: true
33
36
  });
@@ -48,19 +51,20 @@ export var blockControlsPlugin = function blockControlsPlugin(_ref) {
48
51
  return tr;
49
52
  };
50
53
  },
51
- setNodeDragged: function setNodeDragged(pos, anchorName) {
54
+ setNodeDragged: function setNodeDragged(pos, anchorName, nodeType) {
52
55
  return function (_ref4) {
53
56
  var tr = _ref4.tr;
54
- var newTr = tr;
55
57
  if (pos === undefined) {
56
58
  return tr;
57
59
  }
58
- newTr.setSelection(getSelection(newTr, pos));
60
+ var newTr = tr;
61
+ newTr = selectNode(newTr, pos, nodeType);
59
62
  newTr.setMeta(key, {
60
63
  isDragging: true,
61
64
  activeNode: {
62
65
  pos: pos,
63
- anchorName: anchorName
66
+ anchorName: anchorName,
67
+ nodeType: nodeType
64
68
  }
65
69
  });
66
70
  return newTr;
@@ -93,7 +93,8 @@ export var createPlugin = function createPlugin(api) {
93
93
  // Map active node position when the document changes
94
94
  var mappedActiveNodePos = tr.docChanged && activeNode ? {
95
95
  pos: tr.mapping.map(activeNode.pos),
96
- anchorName: activeNode.anchorName
96
+ anchorName: activeNode.anchorName,
97
+ nodeType: activeNode.nodeType
97
98
  } : activeNode;
98
99
  return {
99
100
  decorations: decorations,
@@ -2,12 +2,13 @@ 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';
8
9
  import { key } from '../pm-plugins/main';
10
+ import { selectNode } from '../utils';
9
11
  import { getLeftPosition, getTopPosition } from '../utils/drag-handle-positions';
10
- import { getSelection } from '../utils/getSelection';
11
12
  import { DRAG_HANDLE_BORDER_RADIUS, DRAG_HANDLE_HEIGHT, DRAG_HANDLE_WIDTH, dragHandleGap } from './consts';
12
13
  import { dragPreview } from './drag-preview';
13
14
  var dragHandleButtonStyles = css({
@@ -49,6 +50,8 @@ export var DragHandle = function DragHandle(_ref) {
49
50
  _useState2 = _slicedToArray(_useState, 2),
50
51
  dragHandleSelected = _useState2[0],
51
52
  setDragHandleSelected = _useState2[1];
53
+ var _useSharedPluginState = useSharedPluginState(api, ['featureFlags']),
54
+ featureFlagsState = _useSharedPluginState.featureFlagsState;
52
55
  var handleClick = useCallback(function () {
53
56
  var _api$core, _api$core2;
54
57
  setDragHandleSelected(!dragHandleSelected);
@@ -57,14 +60,14 @@ export var DragHandle = function DragHandle(_ref) {
57
60
  if (start === undefined) {
58
61
  return tr;
59
62
  }
60
- tr.setSelection(getSelection(tr, start));
63
+ tr = selectNode(tr, start, nodeType);
61
64
  tr.setMeta(key, {
62
65
  pos: start
63
66
  });
64
67
  return tr;
65
68
  });
66
69
  api === null || api === void 0 || (_api$core2 = api.core) === null || _api$core2 === void 0 || _api$core2.actions.focus();
67
- }, [start, api, dragHandleSelected, setDragHandleSelected]);
70
+ }, [start, api, dragHandleSelected, setDragHandleSelected, nodeType]);
68
71
  useEffect(function () {
69
72
  var element = buttonRef.current;
70
73
  if (!element) {
@@ -91,7 +94,7 @@ export var DragHandle = function DragHandle(_ref) {
91
94
  if (start === undefined) {
92
95
  return;
93
96
  }
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));
97
+ 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
98
  api === null || api === void 0 || (_api$core4 = api.core) === null || _api$core4 === void 0 || _api$core4.actions.focus();
96
99
  },
97
100
  onDrop: function onDrop() {
@@ -104,25 +107,28 @@ export var DragHandle = function DragHandle(_ref) {
104
107
  });
105
108
  }
106
109
  });
107
- }, [api, start, view, anchorName]);
110
+ }, [api, start, view, anchorName, nodeType]);
111
+ var macroInteractionUpdates = featureFlagsState === null || featureFlagsState === void 0 ? void 0 : featureFlagsState.macroInteractionUpdates;
108
112
  var positionStyles = useMemo(function () {
109
113
  var supportsAnchor = CSS.supports('top', "anchor(".concat(anchorName, " start)")) && CSS.supports('left', "anchor(".concat(anchorName, " start)"));
110
114
  var dom = view.dom.querySelector("[data-drag-handler-anchor-name=\"".concat(anchorName, "\"]"));
115
+ if (!dom) {
116
+ return;
117
+ }
118
+ var hasResizer = anchorName.includes('table') || anchorName.includes('mediaSingle');
119
+ var isExtension = anchorName.includes('extension') || anchorName.includes('bodiedExtension');
120
+ var innerContainer = hasResizer ? dom.querySelector('.resizer-item') : isExtension ? dom.querySelector('.extension-container[data-layout]') : null;
111
121
  if (supportsAnchor) {
112
- var hasResizer = (anchorName.includes('table') || anchorName.includes('mediaSingle')) && dom;
113
122
  return {
114
- left: hasResizer ? getLeftPosition(dom, nodeType) : "calc(anchor(".concat(anchorName, " start) - ").concat(DRAG_HANDLE_WIDTH, "px - ").concat(dragHandleGap(nodeType), "px)"),
123
+ left: hasResizer || isExtension ? getLeftPosition(dom, nodeType, innerContainer, macroInteractionUpdates) : "calc(anchor(".concat(anchorName, " start) - ").concat(DRAG_HANDLE_WIDTH, "px - ").concat(dragHandleGap(nodeType), "px)"),
115
124
  top: anchorName.includes('table') ? "calc(anchor(".concat(anchorName, " start) + ").concat(DRAG_HANDLE_HEIGHT, "px)") : "anchor(".concat(anchorName, " start)")
116
125
  };
117
126
  }
118
- if (!dom) {
119
- return;
120
- }
121
127
  return {
122
- left: getLeftPosition(dom, nodeType),
128
+ left: getLeftPosition(dom, nodeType, innerContainer, macroInteractionUpdates),
123
129
  top: getTopPosition(dom)
124
130
  };
125
- }, [anchorName, view, nodeType]);
131
+ }, [anchorName, view, nodeType, macroInteractionUpdates]);
126
132
  return jsx("button", {
127
133
  type: "button",
128
134
  css: [dragHandleButtonStyles, dragHandleSelected && selectedStyles],
@@ -92,7 +92,7 @@ export var DropTarget = function DropTarget(_ref) {
92
92
  isDraggedOver && jsx("div", {
93
93
  css: styleDropIndicator,
94
94
  style: {
95
- 'width': "".concat(lineLength, "px")
95
+ width: "".concat(lineLength, "px")
96
96
  },
97
97
  "data-testid": "block-ctrl-drop-indicator"
98
98
  }, jsx(DropIndicator, {
@@ -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,5 @@
1
1
  import { NodeSelection, TextSelection } from '@atlaskit/editor-prosemirror/state';
2
+ import { selectTableClosestToPos } from '@atlaskit/editor-tables/utils';
2
3
  export var getSelection = function getSelection(tr, start) {
3
4
  var node = tr.doc.nodeAt(start);
4
5
  var isNodeSelection = node && NodeSelection.isSelectable(node);
@@ -25,4 +26,13 @@ export var getSelection = function getSelection(tr, start) {
25
26
  var textNodeDepth = textNodesPos - start;
26
27
  return new TextSelection(tr.doc.resolve(textNodesPos), tr.doc.resolve(start + nodeSize - textNodeDepth));
27
28
  }
29
+ };
30
+ export var selectNode = function selectNode(tr, start, nodeType) {
31
+ // For table, we need to do cell selection instead of node selection
32
+ if (nodeType === 'table') {
33
+ tr = selectTableClosestToPos(tr, tr.doc.resolve(start + 1));
34
+ } else {
35
+ tr.setSelection(getSelection(tr, start));
36
+ }
37
+ return tr;
28
38
  };
@@ -1 +1 @@
1
- export { getSelection } from './getSelection';
1
+ export { getSelection, selectNode } from './getSelection';
@@ -1,4 +1,5 @@
1
1
  import type { EditorCommand, NextEditorPlugin, OptionalPlugin } from '@atlaskit/editor-common/types';
2
+ import type { FeatureFlagsPlugin } from '@atlaskit/editor-plugin-feature-flags';
2
3
  import type { WidthPlugin } from '@atlaskit/editor-plugin-width';
3
4
  import { type DecorationSet } from '@atlaskit/editor-prosemirror/view';
4
5
  export interface PluginState {
@@ -15,7 +16,7 @@ export interface PluginState {
15
16
  }
16
17
  export type ReleaseHiddenDecoration = () => boolean | undefined;
17
18
  export type BlockControlsPlugin = NextEditorPlugin<'blockControls', {
18
- dependencies: [OptionalPlugin<WidthPlugin>];
19
+ dependencies: [OptionalPlugin<WidthPlugin>, OptionalPlugin<FeatureFlagsPlugin>];
19
20
  sharedState: {
20
21
  isMenuOpen: boolean;
21
22
  activeNode: {
@@ -28,7 +29,7 @@ export type BlockControlsPlugin = NextEditorPlugin<'blockControls', {
28
29
  commands: {
29
30
  moveNode: (start: number, to: number) => EditorCommand;
30
31
  showDragHandleAt: (pos: number, anchorName: string, nodeType: string) => EditorCommand;
31
- setNodeDragged: (posNumber: number, anchorName: string) => EditorCommand;
32
+ setNodeDragged: (posNumber: number, anchorName: string, nodeType: string) => EditorCommand;
32
33
  };
33
34
  }>;
34
35
  export type DecorationState = {
@@ -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,2 +1,3 @@
1
1
  import { NodeSelection, TextSelection, type Transaction } from '@atlaskit/editor-prosemirror/state';
2
2
  export declare const getSelection: (tr: Transaction, start: number) => NodeSelection | TextSelection;
3
+ export declare const selectNode: (tr: Transaction, start: number, nodeType: string) => Transaction;
@@ -1 +1 @@
1
- export { getSelection } from './getSelection';
1
+ export { getSelection, selectNode } from './getSelection';
@@ -1,4 +1,5 @@
1
1
  import type { EditorCommand, NextEditorPlugin, OptionalPlugin } from '@atlaskit/editor-common/types';
2
+ import type { FeatureFlagsPlugin } from '@atlaskit/editor-plugin-feature-flags';
2
3
  import type { WidthPlugin } from '@atlaskit/editor-plugin-width';
3
4
  import { type DecorationSet } from '@atlaskit/editor-prosemirror/view';
4
5
  export interface PluginState {
@@ -16,7 +17,8 @@ export interface PluginState {
16
17
  export type ReleaseHiddenDecoration = () => boolean | undefined;
17
18
  export type BlockControlsPlugin = NextEditorPlugin<'blockControls', {
18
19
  dependencies: [
19
- OptionalPlugin<WidthPlugin>
20
+ OptionalPlugin<WidthPlugin>,
21
+ OptionalPlugin<FeatureFlagsPlugin>
20
22
  ];
21
23
  sharedState: {
22
24
  isMenuOpen: boolean;
@@ -30,7 +32,7 @@ export type BlockControlsPlugin = NextEditorPlugin<'blockControls', {
30
32
  commands: {
31
33
  moveNode: (start: number, to: number) => EditorCommand;
32
34
  showDragHandleAt: (pos: number, anchorName: string, nodeType: string) => EditorCommand;
33
- setNodeDragged: (posNumber: number, anchorName: string) => EditorCommand;
35
+ setNodeDragged: (posNumber: number, anchorName: string, nodeType: string) => EditorCommand;
34
36
  };
35
37
  }>;
36
38
  export type DecorationState = {
@@ -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,2 +1,3 @@
1
1
  import { NodeSelection, TextSelection, type Transaction } from '@atlaskit/editor-prosemirror/state';
2
2
  export declare const getSelection: (tr: Transaction, start: number) => NodeSelection | TextSelection;
3
+ export declare const selectNode: (tr: Transaction, start: number, nodeType: string) => Transaction;
@@ -1 +1 @@
1
- export { getSelection } from './getSelection';
1
+ export { getSelection, selectNode } from './getSelection';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-block-controls",
3
- "version": "1.4.10",
3
+ "version": "1.4.12",
4
4
  "description": "Block controls plugin for @atlaskit/editor-core",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -31,9 +31,11 @@
31
31
  ".": "./src/index.ts"
32
32
  },
33
33
  "dependencies": {
34
- "@atlaskit/editor-common": "^82.0.0",
34
+ "@atlaskit/editor-common": "^82.2.0",
35
+ "@atlaskit/editor-plugin-feature-flags": "^1.1.0",
35
36
  "@atlaskit/editor-plugin-width": "^1.1.0",
36
37
  "@atlaskit/editor-prosemirror": "4.0.1",
38
+ "@atlaskit/editor-tables": "^2.7.0",
37
39
  "@atlaskit/icon": "^22.3.0",
38
40
  "@atlaskit/pragmatic-drag-and-drop": "^1.1.0",
39
41
  "@atlaskit/pragmatic-drag-and-drop-auto-scroll": "^1.3.0",