@atlaskit/editor-plugin-block-controls 2.26.0 → 2.26.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # @atlaskit/editor-plugin-block-controls
2
2
 
3
+ ## 2.26.1
4
+
5
+ ### Patch Changes
6
+
7
+ - [#111887](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/111887)
8
+ [`dc433156e592a`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/dc433156e592a) -
9
+ [ux] ED-26101 Create layout with nodes before/after using keyboard shortcuts
10
+
3
11
  ## 2.26.0
4
12
 
5
13
  ### Minor Changes
@@ -25,6 +25,7 @@ var _getNestedNodePosition = require("../pm-plugins/utils/getNestedNodePosition"
25
25
  var _getSelection = require("../pm-plugins/utils/getSelection");
26
26
  var _removeFromSource = require("../pm-plugins/utils/remove-from-source");
27
27
  var _selection2 = require("../pm-plugins/utils/selection");
28
+ var _updateSelection = require("../pm-plugins/utils/update-selection");
28
29
  var _validation = require("../pm-plugins/utils/validation");
29
30
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
30
31
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
@@ -58,7 +59,7 @@ var isDragLayoutColumnToTopLevel = function isDragLayoutColumnToTopLevel($from,
58
59
  *
59
60
  * @returns the start position of a node if the node can be moved, otherwise -1
60
61
  */
61
- var getCurrentNodePos = function getCurrentNodePos(state, isParentNodeOfTypeLayout) {
62
+ var getCurrentNodePos = function getCurrentNodePos(state) {
62
63
  var _activeNode$handleOpt;
63
64
  var selection = state.selection;
64
65
  var _ref = _main.key.getState(state) || {},
@@ -94,27 +95,46 @@ var moveNodeViaShortcut = exports.moveNodeViaShortcut = function moveNodeViaShor
94
95
  if (shouldEnableNestedDndA11y) {
95
96
  isParentNodeOfTypeLayout = !!(0, _utils2.findParentNodeOfType)([state.schema.nodes.layoutSection])(state.selection);
96
97
  }
97
- var currentNodePos = getCurrentNodePos(state, isParentNodeOfTypeLayout);
98
+ var currentNodePos = getCurrentNodePos(state);
98
99
  if (currentNodePos > -1) {
99
100
  var _state$doc$nodeAt;
100
101
  var $pos = state.doc.resolve(currentNodePos);
102
+ var isTopLevelNode = $pos.depth === 0;
101
103
  var moveToPos = -1;
102
104
  var nodeIndex = $pos.index();
103
105
  var isLayoutColumnSelected = selection instanceof _state.NodeSelection && selection.node.type.name === 'layoutColumn';
104
106
  if (direction === _consts.DIRECTION.LEFT && shouldEnableNestedDndA11y) {
105
- if (isLayoutColumnSelected && (0, _platformFeatureFlags.fg)('platform_editor_advanced_layouts_accessibility')) {
106
- var _$pos$nodeBefore, _api$core;
107
- moveToPos = selection.from - (((_$pos$nodeBefore = $pos.nodeBefore) === null || _$pos$nodeBefore === void 0 ? void 0 : _$pos$nodeBefore.nodeSize) || 1);
107
+ if (isTopLevelNode && (0, _experiments.editorExperiment)('advanced_layouts', true) && (0, _platformFeatureFlags.fg)('platform_editor_advanced_layouts_accessibility')) {
108
+ var _api$core, _api$core2;
109
+ var nodeBefore = $pos.nodeBefore;
110
+ if (nodeBefore) {
111
+ moveToPos = currentNodePos - nodeBefore.nodeSize;
112
+ }
113
+ if (moveToPos < 0) {
114
+ return false;
115
+ }
108
116
  api === null || api === void 0 || (_api$core = api.core) === null || _api$core === void 0 || _api$core.actions.execute(function (_ref2) {
109
117
  var _api$blockControls;
110
118
  var tr = _ref2.tr;
111
119
  api === null || api === void 0 || (_api$blockControls = api.blockControls) === null || _api$blockControls === void 0 || (_api$blockControls = _api$blockControls.commands) === null || _api$blockControls === void 0 || _api$blockControls.moveToLayout(currentNodePos, moveToPos, {
112
- selectMovedNode: true
120
+ moveToEnd: true,
121
+ moveNodeAtCursorPos: true
113
122
  })({
114
123
  tr: tr
115
124
  });
125
+ var insertColumnStep = (0, _updateSelection.getInsertLayoutStep)(tr);
126
+ var mappedTo = insertColumnStep === null || insertColumnStep === void 0 ? void 0 : insertColumnStep.from;
127
+ (0, _updateSelection.updateSelection)(tr, mappedTo, true);
116
128
  return tr;
117
129
  });
130
+ api === null || api === void 0 || (_api$core2 = api.core) === null || _api$core2 === void 0 || _api$core2.actions.focus();
131
+ return true;
132
+ } else if (isLayoutColumnSelected && (0, _platformFeatureFlags.fg)('platform_editor_advanced_layouts_accessibility')) {
133
+ var _$pos$nodeBefore, _api$core3, _api$blockControls2;
134
+ moveToPos = selection.from - (((_$pos$nodeBefore = $pos.nodeBefore) === null || _$pos$nodeBefore === void 0 ? void 0 : _$pos$nodeBefore.nodeSize) || 1);
135
+ api === null || api === void 0 || (_api$core3 = api.core) === null || _api$core3 === void 0 || _api$core3.actions.execute(api === null || api === void 0 || (_api$blockControls2 = api.blockControls) === null || _api$blockControls2 === void 0 || (_api$blockControls2 = _api$blockControls2.commands) === null || _api$blockControls2 === void 0 ? void 0 : _api$blockControls2.moveToLayout(currentNodePos, moveToPos, {
136
+ selectMovedNode: true
137
+ }));
118
138
  return true;
119
139
  } else {
120
140
  if ($pos.depth < 2 || !isParentNodeOfTypeLayout) {
@@ -128,8 +148,30 @@ var moveNodeViaShortcut = exports.moveNodeViaShortcut = function moveNodeViaShor
128
148
  moveToPos = $pos.start() - ((previousNode === null || previousNode === void 0 ? void 0 : previousNode.nodeSize) || 1);
129
149
  }
130
150
  } else if (direction === _consts.DIRECTION.RIGHT && shouldEnableNestedDndA11y) {
131
- if (isLayoutColumnSelected && (0, _platformFeatureFlags.fg)('platform_editor_advanced_layouts_accessibility')) {
132
- var _api$core2;
151
+ if (isTopLevelNode && (0, _experiments.editorExperiment)('advanced_layouts', true) && (0, _platformFeatureFlags.fg)('platform_editor_advanced_layouts_accessibility')) {
152
+ var _api$core4, _api$core5;
153
+ var endOfDoc = $pos.end();
154
+ moveToPos = $pos.posAtIndex($pos.index() + 1);
155
+ if (moveToPos >= endOfDoc) {
156
+ return false;
157
+ }
158
+ api === null || api === void 0 || (_api$core4 = api.core) === null || _api$core4 === void 0 || _api$core4.actions.execute(function (_ref3) {
159
+ var _api$blockControls3;
160
+ var tr = _ref3.tr;
161
+ api === null || api === void 0 || (_api$blockControls3 = api.blockControls) === null || _api$blockControls3 === void 0 || (_api$blockControls3 = _api$blockControls3.commands) === null || _api$blockControls3 === void 0 || _api$blockControls3.moveToLayout(currentNodePos, moveToPos, {
162
+ moveNodeAtCursorPos: true
163
+ })({
164
+ tr: tr
165
+ });
166
+ var insertColumnStep = (0, _updateSelection.getInsertLayoutStep)(tr);
167
+ var mappedTo = insertColumnStep === null || insertColumnStep === void 0 ? void 0 : insertColumnStep.from;
168
+ (0, _updateSelection.updateSelection)(tr, mappedTo);
169
+ return tr;
170
+ });
171
+ api === null || api === void 0 || (_api$core5 = api.core) === null || _api$core5 === void 0 || _api$core5.actions.focus();
172
+ return true;
173
+ } else if (isLayoutColumnSelected && (0, _platformFeatureFlags.fg)('platform_editor_advanced_layouts_accessibility')) {
174
+ var _api$core6, _api$blockControls4;
133
175
  var _index = $pos.index($pos.depth);
134
176
  var parent = $pos.node($pos.depth);
135
177
  // get the next layoutColumn node
@@ -142,17 +184,10 @@ var moveNodeViaShortcut = exports.moveNodeViaShortcut = function moveNodeViaShor
142
184
  }
143
185
  var moveToEnd = _index === parent.childCount - 2;
144
186
  moveToPos = moveToEnd ? $pos.before() : selection.to + ((nextNode === null || nextNode === void 0 ? void 0 : nextNode.nodeSize) || 1);
145
- api === null || api === void 0 || (_api$core2 = api.core) === null || _api$core2 === void 0 || _api$core2.actions.execute(function (_ref3) {
146
- var _api$blockControls2;
147
- var tr = _ref3.tr;
148
- api === null || api === void 0 || (_api$blockControls2 = api.blockControls) === null || _api$blockControls2 === void 0 || (_api$blockControls2 = _api$blockControls2.commands) === null || _api$blockControls2 === void 0 || _api$blockControls2.moveToLayout(currentNodePos, moveToPos, {
149
- moveToEnd: moveToEnd,
150
- selectMovedNode: true
151
- })({
152
- tr: tr
153
- });
154
- return tr;
155
- });
187
+ api === null || api === void 0 || (_api$core6 = api.core) === null || _api$core6 === void 0 || _api$core6.actions.execute(api === null || api === void 0 || (_api$blockControls4 = api.blockControls) === null || _api$blockControls4 === void 0 || (_api$blockControls4 = _api$blockControls4.commands) === null || _api$blockControls4 === void 0 ? void 0 : _api$blockControls4.moveToLayout(currentNodePos, moveToPos, {
188
+ moveToEnd: moveToEnd,
189
+ selectMovedNode: true
190
+ }));
156
191
  return true;
157
192
  } else {
158
193
  if ($pos.depth < 2 || !isParentNodeOfTypeLayout) {
@@ -164,15 +199,15 @@ var moveNodeViaShortcut = exports.moveNodeViaShortcut = function moveNodeViaShor
164
199
  if (isLayoutColumnSelected && (0, _platformFeatureFlags.fg)('platform_editor_advanced_layouts_accessibility')) {
165
200
  moveToPos = $pos.start() - 1;
166
201
  } else {
167
- var nodeBefore = $pos.depth > 1 && nodeIndex === 0 && shouldEnableNestedDndA11y ? $pos.node($pos.depth) : $pos.nodeBefore;
168
- if (nodeBefore) {
169
- moveToPos = currentNodePos - nodeBefore.nodeSize;
202
+ var _nodeBefore = $pos.depth > 1 && nodeIndex === 0 && shouldEnableNestedDndA11y ? $pos.node($pos.depth) : $pos.nodeBefore;
203
+ if (_nodeBefore) {
204
+ moveToPos = currentNodePos - _nodeBefore.nodeSize;
170
205
  }
171
206
  }
172
207
  } else {
173
- var endOfDoc = $pos.end();
208
+ var _endOfDoc = $pos.end();
174
209
  var nodeAfterPos = $pos.posAtIndex($pos.index() + 1);
175
- if (nodeAfterPos > endOfDoc) {
210
+ if (nodeAfterPos > _endOfDoc) {
176
211
  return false;
177
212
  }
178
213
  if (isLayoutColumnSelected && (0, _platformFeatureFlags.fg)('platform_editor_advanced_layouts_accessibility')) {
@@ -190,8 +225,8 @@ var moveNodeViaShortcut = exports.moveNodeViaShortcut = function moveNodeViaShor
190
225
  // only move the node if the destination is at the same depth, not support moving a nested node to a parent node
191
226
  var shouldMoveNode = (shouldEnableNestedDndA11y ? moveToPos > -1 && $pos.depth === state.doc.resolve(moveToPos).depth || nodeType === 'layoutColumn' : moveToPos > -1) || nodeType === 'layoutColumn' && (0, _platformFeatureFlags.fg)('platform_editor_advanced_layouts_accessibility');
192
227
  if (shouldMoveNode) {
193
- var _api$core3;
194
- api === null || api === void 0 || (_api$core3 = api.core) === null || _api$core3 === void 0 || _api$core3.actions.execute(function (_ref4) {
228
+ var _api$core7;
229
+ api === null || api === void 0 || (_api$core7 = api.core) === null || _api$core7 === void 0 || _api$core7.actions.execute(function (_ref4) {
195
230
  var tr = _ref4.tr;
196
231
  moveNode(api)(currentNodePos, moveToPos, _analytics.INPUT_METHOD.SHORTCUT, formatMessage)({
197
232
  tr: tr
@@ -201,9 +236,9 @@ var moveNodeViaShortcut = exports.moveNodeViaShortcut = function moveNodeViaShor
201
236
  });
202
237
  return true;
203
238
  } else if (nodeType) {
204
- var _api$core4;
239
+ var _api$core8;
205
240
  // If the node is first/last one, only select the node
206
- api === null || api === void 0 || (_api$core4 = api.core) === null || _api$core4 === void 0 || _api$core4.actions.execute(function (_ref5) {
241
+ api === null || api === void 0 || (_api$core8 = api.core) === null || _api$core8 === void 0 || _api$core8.actions.execute(function (_ref5) {
207
242
  var tr = _ref5.tr;
208
243
  (0, _getSelection.selectNode)(tr, currentNodePos, nodeType);
209
244
  tr.scrollIntoView();
@@ -162,7 +162,7 @@ var insertToDestination = function insertToDestination(tr, to, sourceContent, to
162
162
  * Check if the node at `from` can be moved to node at `to` to create/expand a layout.
163
163
  * Returns the source and destination nodes and positions if it's a valid move, otherwise, undefined
164
164
  */
165
- var canMoveToLayout = function canMoveToLayout(api, from, to, tr) {
165
+ var canMoveToLayout = function canMoveToLayout(api, from, to, tr, moveNodeAtCursorPos) {
166
166
  if (from === to) {
167
167
  return;
168
168
  }
@@ -193,7 +193,7 @@ var canMoveToLayout = function canMoveToLayout(api, from, to, tr) {
193
193
  var sourceContent = $from.nodeAfter;
194
194
  var sourceFrom = from;
195
195
  var sourceTo = from + sourceContent.nodeSize;
196
- if (isMultiSelect) {
196
+ if (isMultiSelect && !moveNodeAtCursorPos) {
197
197
  var _getMultiSelectionIfP = (0, _selection.getMultiSelectionIfPosInside)(api, from),
198
198
  anchor = _getMultiSelectionIfP.anchor,
199
199
  head = _getMultiSelectionIfP.head;
@@ -290,7 +290,7 @@ var moveToLayout = exports.moveToLayout = function moveToLayout(api) {
290
290
  if (!api) {
291
291
  return tr;
292
292
  }
293
- var canMove = canMoveToLayout(api, from, to, tr);
293
+ var canMove = canMoveToLayout(api, from, to, tr, options === null || options === void 0 ? void 0 : options.moveNodeAtCursorPos);
294
294
  if (!canMove) {
295
295
  return tr;
296
296
  }
@@ -8,9 +8,7 @@ exports.unmountDecorations = exports.getNodeAnchor = exports.getNestedDepth = ex
8
8
  var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
9
9
  var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
10
10
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
11
- var _reactDom = _interopRequireDefault(require("react-dom"));
12
11
  var _uuid = _interopRequireDefault(require("uuid"));
13
- var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
14
12
  var _experiments = require("@atlaskit/tmp-editor-statsig/experiments");
15
13
  var TYPE_DROP_TARGET_DEC = exports.TYPE_DROP_TARGET_DEC = 'drop-target-decoration';
16
14
  var TYPE_HANDLE_DEC = exports.TYPE_HANDLE_DEC = 'drag-handle';
@@ -44,13 +42,9 @@ var unmountDecorations = exports.unmountDecorations = function unmountDecoration
44
42
  // as it was more responsive and causes less re-rendering
45
43
  var decorationsToRemove = document.querySelectorAll("[".concat(selector, "=\"true\"]"));
46
44
  decorationsToRemove.forEach(function (el) {
47
- if ((0, _platformFeatureFlags.fg)('platform_editor_react18_plugin_portalprovider')) {
48
- var nodeKey = el.getAttribute(key);
49
- if (nodeKey) {
50
- nodeViewPortalProviderAPI.remove(nodeKey);
51
- }
52
- } else {
53
- _reactDom.default.unmountComponentAtNode(el);
45
+ var nodeKey = el.getAttribute(key);
46
+ if (nodeKey) {
47
+ nodeViewPortalProviderAPI.remove(nodeKey);
54
48
  }
55
49
  });
56
50
  };
@@ -8,10 +8,8 @@ exports.findHandleDec = exports.emptyParagraphNodeDecorations = exports.dragHand
8
8
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
9
9
  var _react = require("react");
10
10
  var _bindEventListener = require("bind-event-listener");
11
- var _reactDom = _interopRequireDefault(require("react-dom"));
12
11
  var _uuid = _interopRequireDefault(require("uuid"));
13
12
  var _view = require("@atlaskit/editor-prosemirror/view");
14
- var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
15
13
  var _experiments = require("@atlaskit/tmp-editor-statsig/experiments");
16
14
  var _dragHandle = require("../ui/drag-handle");
17
15
  var _decorationsCommon = require("./decorations-common");
@@ -72,21 +70,8 @@ var dragHandleDecoration = exports.dragHandleDecoration = function dragHandleDec
72
70
  // There are times when global clear: "both" styles are applied to this decoration causing jumpiness
73
71
  // due to margins applied to other nodes eg. Headings
74
72
  element.style.clear = 'unset';
75
- if ((0, _platformFeatureFlags.fg)('platform_editor_react18_plugin_portalprovider')) {
76
- nodeViewPortalProviderAPI.render(function () {
77
- return /*#__PURE__*/(0, _react.createElement)(_dragHandle.DragHandle, {
78
- view: view,
79
- api: api,
80
- formatMessage: formatMessage,
81
- getPos: getPos,
82
- anchorName: anchorName,
83
- nodeType: nodeType,
84
- handleOptions: handleOptions,
85
- isTopLevelNode: isTopLevelNode
86
- });
87
- }, element, key);
88
- } else {
89
- _reactDom.default.render( /*#__PURE__*/(0, _react.createElement)(_dragHandle.DragHandle, {
73
+ nodeViewPortalProviderAPI.render(function () {
74
+ return /*#__PURE__*/(0, _react.createElement)(_dragHandle.DragHandle, {
90
75
  view: view,
91
76
  api: api,
92
77
  formatMessage: formatMessage,
@@ -95,8 +80,8 @@ var dragHandleDecoration = exports.dragHandleDecoration = function dragHandleDec
95
80
  nodeType: nodeType,
96
81
  handleOptions: handleOptions,
97
82
  isTopLevelNode: isTopLevelNode
98
- }), element);
99
- }
83
+ });
84
+ }, element, key);
100
85
  return element;
101
86
  }, {
102
87
  side: -1,
@@ -7,11 +7,9 @@ Object.defineProperty(exports, "__esModule", {
7
7
  exports.findDropTargetDecs = exports.dropTargetDecorations = exports.createLayoutDropTargetDecoration = exports.createDropTargetDecoration = void 0;
8
8
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
9
9
  var _react = require("react");
10
- var _reactDom = _interopRequireDefault(require("react-dom"));
11
10
  var _uuid = _interopRequireDefault(require("uuid"));
12
11
  var _utils = require("@atlaskit/editor-common/utils");
13
12
  var _view = require("@atlaskit/editor-prosemirror/view");
14
- var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
15
13
  var _experiments = require("@atlaskit/tmp-editor-statsig/experiments");
16
14
  var _consts = require("../ui/consts");
17
15
  var _dropTarget = require("../ui/drop-target");
@@ -103,21 +101,13 @@ var createDropTargetDecoration = exports.createDropTargetDecoration = function c
103
101
  element.style.setProperty(_dropTarget.EDITOR_BLOCK_CONTROLS_DROP_INDICATOR_OFFSET, "".concat(offset, "px"));
104
102
  element.style.setProperty(_dropTarget.EDITOR_BLOCK_CONTROLS_DROP_INDICATOR_GAP, "".concat(gap, "px"));
105
103
  element.style.setProperty('display', 'block');
106
- if ((0, _platformFeatureFlags.fg)('platform_editor_react18_plugin_portalprovider')) {
107
- nodeViewPortalProviderAPI.render(function () {
108
- return /*#__PURE__*/(0, _react.createElement)(_dropTarget.DropTarget, _objectSpread(_objectSpread({}, props), {}, {
109
- getPos: getPos,
110
- anchorRectCache: anchorRectCache,
111
- isSameLayout: isSameLayout
112
- }));
113
- }, element, key);
114
- } else {
115
- _reactDom.default.render( /*#__PURE__*/(0, _react.createElement)(_dropTarget.DropTarget, _objectSpread(_objectSpread({}, props), {}, {
104
+ nodeViewPortalProviderAPI.render(function () {
105
+ return /*#__PURE__*/(0, _react.createElement)(_dropTarget.DropTarget, _objectSpread(_objectSpread({}, props), {}, {
116
106
  getPos: getPos,
117
107
  anchorRectCache: anchorRectCache,
118
108
  isSameLayout: isSameLayout
119
- })), element);
120
- }
109
+ }));
110
+ }, element, key);
121
111
  return element;
122
112
  }, {
123
113
  type: _decorationsCommon.TYPE_DROP_TARGET_DEC,
@@ -138,19 +128,12 @@ var createLayoutDropTargetDecoration = exports.createLayoutDropTargetDecoration
138
128
  element.setAttribute('data-blocks-drop-target-container', 'true');
139
129
  element.setAttribute('data-blocks-drop-target-key', key);
140
130
  element.style.clear = 'unset';
141
- if ((0, _platformFeatureFlags.fg)('platform_editor_react18_plugin_portalprovider')) {
142
- nodeViewPortalProviderAPI.render(function () {
143
- return /*#__PURE__*/(0, _react.createElement)(_dropTargetLayout.DropTargetLayout, _objectSpread(_objectSpread({}, props), {}, {
144
- getPos: getPos,
145
- anchorRectCache: anchorRectCache
146
- }));
147
- }, element, key);
148
- } else {
149
- _reactDom.default.render( /*#__PURE__*/(0, _react.createElement)(_dropTargetLayout.DropTargetLayout, _objectSpread(_objectSpread({}, props), {}, {
131
+ nodeViewPortalProviderAPI.render(function () {
132
+ return /*#__PURE__*/(0, _react.createElement)(_dropTargetLayout.DropTargetLayout, _objectSpread(_objectSpread({}, props), {}, {
150
133
  getPos: getPos,
151
134
  anchorRectCache: anchorRectCache
152
- })), element);
153
- }
135
+ }));
136
+ }, element, key);
154
137
  return element;
155
138
  }, {
156
139
  type: _decorationsCommon.TYPE_DROP_TARGET_DEC
@@ -389,7 +389,21 @@ var DragHandle = exports.DragHandle = function DragHandle(_ref) {
389
389
  }
390
390
  setDragHandleSelected((0, _getSelection.isHandleInSelection)(view.state, selection, start));
391
391
  }, [start, selection, view.state]);
392
- var helpDescriptors = [{
392
+ var helpDescriptors = isTopLevelNode && (0, _platformFeatureFlags.fg)('platform_editor_advanced_layouts_accessibility') ? [{
393
+ description: formatMessage(_messages.blockControlsMessages.dragToMove)
394
+ }, {
395
+ description: formatMessage(_messages.blockControlsMessages.moveUp),
396
+ keymap: _keymaps.dragToMoveUp
397
+ }, {
398
+ description: formatMessage(_messages.blockControlsMessages.moveDown),
399
+ keymap: _keymaps.dragToMoveDown
400
+ }, {
401
+ description: formatMessage(_messages.blockControlsMessages.moveLeft),
402
+ keymap: _keymaps.dragToMoveLeft
403
+ }, {
404
+ description: formatMessage(_messages.blockControlsMessages.moveRight),
405
+ keymap: _keymaps.dragToMoveRight
406
+ }] : [{
393
407
  description: formatMessage(_messages.blockControlsMessages.dragToMove)
394
408
  }, {
395
409
  description: formatMessage(_messages.blockControlsMessages.moveUp),
@@ -17,6 +17,7 @@ import { getNestedNodePosition } from '../pm-plugins/utils/getNestedNodePosition
17
17
  import { selectNode, setCursorPositionAtMovedNode } from '../pm-plugins/utils/getSelection';
18
18
  import { removeFromSource } from '../pm-plugins/utils/remove-from-source';
19
19
  import { getMultiSelectionIfPosInside } from '../pm-plugins/utils/selection';
20
+ import { getInsertLayoutStep, updateSelection } from '../pm-plugins/utils/update-selection';
20
21
  import { canMoveNodeToIndex, isInsideTable, transformSliceExpandToNestedExpand } from '../pm-plugins/utils/validation';
21
22
 
22
23
  /**
@@ -50,7 +51,7 @@ const isDragLayoutColumnToTopLevel = ($from, $to) => {
50
51
  *
51
52
  * @returns the start position of a node if the node can be moved, otherwise -1
52
53
  */
53
- const getCurrentNodePos = (state, isParentNodeOfTypeLayout) => {
54
+ const getCurrentNodePos = state => {
54
55
  var _activeNode$handleOpt;
55
56
  const {
56
57
  selection
@@ -91,28 +92,47 @@ export const moveNodeViaShortcut = (api, direction, formatMessage) => {
91
92
  if (shouldEnableNestedDndA11y) {
92
93
  isParentNodeOfTypeLayout = !!findParentNodeOfType([state.schema.nodes.layoutSection])(state.selection);
93
94
  }
94
- const currentNodePos = getCurrentNodePos(state, isParentNodeOfTypeLayout);
95
+ const currentNodePos = getCurrentNodePos(state);
95
96
  if (currentNodePos > -1) {
96
97
  var _state$doc$nodeAt;
97
98
  const $pos = state.doc.resolve(currentNodePos);
99
+ const isTopLevelNode = $pos.depth === 0;
98
100
  let moveToPos = -1;
99
101
  const nodeIndex = $pos.index();
100
102
  const isLayoutColumnSelected = selection instanceof NodeSelection && selection.node.type.name === 'layoutColumn';
101
103
  if (direction === DIRECTION.LEFT && shouldEnableNestedDndA11y) {
102
- if (isLayoutColumnSelected && fg('platform_editor_advanced_layouts_accessibility')) {
103
- var _$pos$nodeBefore, _api$core;
104
- moveToPos = selection.from - (((_$pos$nodeBefore = $pos.nodeBefore) === null || _$pos$nodeBefore === void 0 ? void 0 : _$pos$nodeBefore.nodeSize) || 1);
104
+ if (isTopLevelNode && editorExperiment('advanced_layouts', true) && fg('platform_editor_advanced_layouts_accessibility')) {
105
+ var _api$core, _api$core2;
106
+ const nodeBefore = $pos.nodeBefore;
107
+ if (nodeBefore) {
108
+ moveToPos = currentNodePos - nodeBefore.nodeSize;
109
+ }
110
+ if (moveToPos < 0) {
111
+ return false;
112
+ }
105
113
  api === null || api === void 0 ? void 0 : (_api$core = api.core) === null || _api$core === void 0 ? void 0 : _api$core.actions.execute(({
106
114
  tr
107
115
  }) => {
108
116
  var _api$blockControls, _api$blockControls$co;
109
117
  api === null || api === void 0 ? void 0 : (_api$blockControls = api.blockControls) === null || _api$blockControls === void 0 ? void 0 : (_api$blockControls$co = _api$blockControls.commands) === null || _api$blockControls$co === void 0 ? void 0 : _api$blockControls$co.moveToLayout(currentNodePos, moveToPos, {
110
- selectMovedNode: true
118
+ moveToEnd: true,
119
+ moveNodeAtCursorPos: true
111
120
  })({
112
121
  tr
113
122
  });
123
+ const insertColumnStep = getInsertLayoutStep(tr);
124
+ const mappedTo = insertColumnStep === null || insertColumnStep === void 0 ? void 0 : insertColumnStep.from;
125
+ updateSelection(tr, mappedTo, true);
114
126
  return tr;
115
127
  });
128
+ api === null || api === void 0 ? void 0 : (_api$core2 = api.core) === null || _api$core2 === void 0 ? void 0 : _api$core2.actions.focus();
129
+ return true;
130
+ } else if (isLayoutColumnSelected && fg('platform_editor_advanced_layouts_accessibility')) {
131
+ var _$pos$nodeBefore, _api$core3, _api$blockControls2, _api$blockControls2$c;
132
+ moveToPos = selection.from - (((_$pos$nodeBefore = $pos.nodeBefore) === null || _$pos$nodeBefore === void 0 ? void 0 : _$pos$nodeBefore.nodeSize) || 1);
133
+ 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$blockControls2 = api.blockControls) === null || _api$blockControls2 === void 0 ? void 0 : (_api$blockControls2$c = _api$blockControls2.commands) === null || _api$blockControls2$c === void 0 ? void 0 : _api$blockControls2$c.moveToLayout(currentNodePos, moveToPos, {
134
+ selectMovedNode: true
135
+ }));
116
136
  return true;
117
137
  } else {
118
138
  if ($pos.depth < 2 || !isParentNodeOfTypeLayout) {
@@ -126,8 +146,31 @@ export const moveNodeViaShortcut = (api, direction, formatMessage) => {
126
146
  moveToPos = $pos.start() - ((previousNode === null || previousNode === void 0 ? void 0 : previousNode.nodeSize) || 1);
127
147
  }
128
148
  } else if (direction === DIRECTION.RIGHT && shouldEnableNestedDndA11y) {
129
- if (isLayoutColumnSelected && fg('platform_editor_advanced_layouts_accessibility')) {
130
- var _api$core2;
149
+ if (isTopLevelNode && editorExperiment('advanced_layouts', true) && fg('platform_editor_advanced_layouts_accessibility')) {
150
+ var _api$core4, _api$core5;
151
+ const endOfDoc = $pos.end();
152
+ moveToPos = $pos.posAtIndex($pos.index() + 1);
153
+ if (moveToPos >= endOfDoc) {
154
+ return false;
155
+ }
156
+ api === null || api === void 0 ? void 0 : (_api$core4 = api.core) === null || _api$core4 === void 0 ? void 0 : _api$core4.actions.execute(({
157
+ tr
158
+ }) => {
159
+ var _api$blockControls3, _api$blockControls3$c;
160
+ api === null || api === void 0 ? void 0 : (_api$blockControls3 = api.blockControls) === null || _api$blockControls3 === void 0 ? void 0 : (_api$blockControls3$c = _api$blockControls3.commands) === null || _api$blockControls3$c === void 0 ? void 0 : _api$blockControls3$c.moveToLayout(currentNodePos, moveToPos, {
161
+ moveNodeAtCursorPos: true
162
+ })({
163
+ tr
164
+ });
165
+ const insertColumnStep = getInsertLayoutStep(tr);
166
+ const mappedTo = insertColumnStep === null || insertColumnStep === void 0 ? void 0 : insertColumnStep.from;
167
+ updateSelection(tr, mappedTo);
168
+ return tr;
169
+ });
170
+ api === null || api === void 0 ? void 0 : (_api$core5 = api.core) === null || _api$core5 === void 0 ? void 0 : _api$core5.actions.focus();
171
+ return true;
172
+ } else if (isLayoutColumnSelected && fg('platform_editor_advanced_layouts_accessibility')) {
173
+ var _api$core6, _api$blockControls4, _api$blockControls4$c;
131
174
  const index = $pos.index($pos.depth);
132
175
  const parent = $pos.node($pos.depth);
133
176
  // get the next layoutColumn node
@@ -140,18 +183,10 @@ export const moveNodeViaShortcut = (api, direction, formatMessage) => {
140
183
  }
141
184
  const moveToEnd = index === parent.childCount - 2;
142
185
  moveToPos = moveToEnd ? $pos.before() : selection.to + ((nextNode === null || nextNode === void 0 ? void 0 : nextNode.nodeSize) || 1);
143
- api === null || api === void 0 ? void 0 : (_api$core2 = api.core) === null || _api$core2 === void 0 ? void 0 : _api$core2.actions.execute(({
144
- tr
145
- }) => {
146
- var _api$blockControls2, _api$blockControls2$c;
147
- api === null || api === void 0 ? void 0 : (_api$blockControls2 = api.blockControls) === null || _api$blockControls2 === void 0 ? void 0 : (_api$blockControls2$c = _api$blockControls2.commands) === null || _api$blockControls2$c === void 0 ? void 0 : _api$blockControls2$c.moveToLayout(currentNodePos, moveToPos, {
148
- moveToEnd,
149
- selectMovedNode: true
150
- })({
151
- tr
152
- });
153
- return tr;
154
- });
186
+ api === null || api === void 0 ? void 0 : (_api$core6 = api.core) === null || _api$core6 === void 0 ? void 0 : _api$core6.actions.execute(api === null || api === void 0 ? void 0 : (_api$blockControls4 = api.blockControls) === null || _api$blockControls4 === void 0 ? void 0 : (_api$blockControls4$c = _api$blockControls4.commands) === null || _api$blockControls4$c === void 0 ? void 0 : _api$blockControls4$c.moveToLayout(currentNodePos, moveToPos, {
187
+ moveToEnd,
188
+ selectMovedNode: true
189
+ }));
155
190
  return true;
156
191
  } else {
157
192
  if ($pos.depth < 2 || !isParentNodeOfTypeLayout) {
@@ -189,8 +224,8 @@ export const moveNodeViaShortcut = (api, direction, formatMessage) => {
189
224
  // only move the node if the destination is at the same depth, not support moving a nested node to a parent node
190
225
  const shouldMoveNode = (shouldEnableNestedDndA11y ? moveToPos > -1 && $pos.depth === state.doc.resolve(moveToPos).depth || nodeType === 'layoutColumn' : moveToPos > -1) || nodeType === 'layoutColumn' && fg('platform_editor_advanced_layouts_accessibility');
191
226
  if (shouldMoveNode) {
192
- var _api$core3;
193
- api === null || api === void 0 ? void 0 : (_api$core3 = api.core) === null || _api$core3 === void 0 ? void 0 : _api$core3.actions.execute(({
227
+ var _api$core7;
228
+ api === null || api === void 0 ? void 0 : (_api$core7 = api.core) === null || _api$core7 === void 0 ? void 0 : _api$core7.actions.execute(({
194
229
  tr
195
230
  }) => {
196
231
  moveNode(api)(currentNodePos, moveToPos, INPUT_METHOD.SHORTCUT, formatMessage)({
@@ -201,9 +236,9 @@ export const moveNodeViaShortcut = (api, direction, formatMessage) => {
201
236
  });
202
237
  return true;
203
238
  } else if (nodeType) {
204
- var _api$core4;
239
+ var _api$core8;
205
240
  // If the node is first/last one, only select the node
206
- api === null || api === void 0 ? void 0 : (_api$core4 = api.core) === null || _api$core4 === void 0 ? void 0 : _api$core4.actions.execute(({
241
+ api === null || api === void 0 ? void 0 : (_api$core8 = api.core) === null || _api$core8 === void 0 ? void 0 : _api$core8.actions.execute(({
207
242
  tr
208
243
  }) => {
209
244
  selectNode(tr, currentNodePos, nodeType);
@@ -160,7 +160,7 @@ const insertToDestination = (tr, to, sourceContent, toLayout, toLayoutPos) => {
160
160
  * Check if the node at `from` can be moved to node at `to` to create/expand a layout.
161
161
  * Returns the source and destination nodes and positions if it's a valid move, otherwise, undefined
162
162
  */
163
- const canMoveToLayout = (api, from, to, tr) => {
163
+ const canMoveToLayout = (api, from, to, tr, moveNodeAtCursorPos) => {
164
164
  if (from === to) {
165
165
  return;
166
166
  }
@@ -192,7 +192,7 @@ const canMoveToLayout = (api, from, to, tr) => {
192
192
  let sourceContent = $from.nodeAfter;
193
193
  let sourceFrom = from;
194
194
  let sourceTo = from + sourceContent.nodeSize;
195
- if (isMultiSelect) {
195
+ if (isMultiSelect && !moveNodeAtCursorPos) {
196
196
  const {
197
197
  anchor,
198
198
  head
@@ -280,7 +280,7 @@ export const moveToLayout = api => (from, to, options) => ({
280
280
  if (!api) {
281
281
  return tr;
282
282
  }
283
- const canMove = canMoveToLayout(api, from, to, tr);
283
+ const canMove = canMoveToLayout(api, from, to, tr, options === null || options === void 0 ? void 0 : options.moveNodeAtCursorPos);
284
284
  if (!canMove) {
285
285
  return tr;
286
286
  }
@@ -1,7 +1,5 @@
1
1
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
- import ReactDOM from 'react-dom';
3
2
  import uuid from 'uuid';
4
- import { fg } from '@atlaskit/platform-feature-flags';
5
3
  import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
6
4
  export const TYPE_DROP_TARGET_DEC = 'drop-target-decoration';
7
5
  export const TYPE_HANDLE_DEC = 'drag-handle';
@@ -27,13 +25,9 @@ export const unmountDecorations = (nodeViewPortalProviderAPI, selector, key) =>
27
25
  // as it was more responsive and causes less re-rendering
28
26
  const decorationsToRemove = document.querySelectorAll(`[${selector}="true"]`);
29
27
  decorationsToRemove.forEach(el => {
30
- if (fg('platform_editor_react18_plugin_portalprovider')) {
31
- const nodeKey = el.getAttribute(key);
32
- if (nodeKey) {
33
- nodeViewPortalProviderAPI.remove(nodeKey);
34
- }
35
- } else {
36
- ReactDOM.unmountComponentAtNode(el);
28
+ const nodeKey = el.getAttribute(key);
29
+ if (nodeKey) {
30
+ nodeViewPortalProviderAPI.remove(nodeKey);
37
31
  }
38
32
  });
39
33
  };
@@ -1,9 +1,7 @@
1
1
  import { createElement } from 'react';
2
2
  import { bind } from 'bind-event-listener';
3
- import ReactDOM from 'react-dom';
4
3
  import uuid from 'uuid';
5
4
  import { Decoration } from '@atlaskit/editor-prosemirror/view';
6
- import { fg } from '@atlaskit/platform-feature-flags';
7
5
  import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
8
6
  import { DragHandle } from '../ui/drag-handle';
9
7
  import { TYPE_HANDLE_DEC, TYPE_NODE_DEC, unmountDecorations } from './decorations-common';
@@ -63,29 +61,16 @@ export const dragHandleDecoration = (api, formatMessage, pos, anchorName, nodeTy
63
61
  // There are times when global clear: "both" styles are applied to this decoration causing jumpiness
64
62
  // due to margins applied to other nodes eg. Headings
65
63
  element.style.clear = 'unset';
66
- if (fg('platform_editor_react18_plugin_portalprovider')) {
67
- nodeViewPortalProviderAPI.render(() => /*#__PURE__*/createElement(DragHandle, {
68
- view,
69
- api,
70
- formatMessage,
71
- getPos,
72
- anchorName,
73
- nodeType,
74
- handleOptions,
75
- isTopLevelNode
76
- }), element, key);
77
- } else {
78
- ReactDOM.render( /*#__PURE__*/createElement(DragHandle, {
79
- view,
80
- api,
81
- formatMessage,
82
- getPos,
83
- anchorName,
84
- nodeType,
85
- handleOptions,
86
- isTopLevelNode
87
- }), element);
88
- }
64
+ nodeViewPortalProviderAPI.render(() => /*#__PURE__*/createElement(DragHandle, {
65
+ view,
66
+ api,
67
+ formatMessage,
68
+ getPos,
69
+ anchorName,
70
+ nodeType,
71
+ handleOptions,
72
+ isTopLevelNode
73
+ }), element, key);
89
74
  return element;
90
75
  }, {
91
76
  side: -1,
@@ -1,9 +1,7 @@
1
1
  import { createElement } from 'react';
2
- import ReactDOM from 'react-dom';
3
2
  import uuid from 'uuid';
4
3
  import { isEmptyParagraph } from '@atlaskit/editor-common/utils';
5
4
  import { Decoration } from '@atlaskit/editor-prosemirror/view';
6
- import { fg } from '@atlaskit/platform-feature-flags';
7
5
  import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
8
6
  import { nodeMargins } from '../ui/consts';
9
7
  import { DropTarget, EDITOR_BLOCK_CONTROLS_DROP_INDICATOR_GAP, EDITOR_BLOCK_CONTROLS_DROP_INDICATOR_OFFSET } from '../ui/drop-target';
@@ -92,21 +90,12 @@ export const createDropTargetDecoration = (pos, props, nodeViewPortalProviderAPI
92
90
  element.style.setProperty(EDITOR_BLOCK_CONTROLS_DROP_INDICATOR_OFFSET, `${offset}px`);
93
91
  element.style.setProperty(EDITOR_BLOCK_CONTROLS_DROP_INDICATOR_GAP, `${gap}px`);
94
92
  element.style.setProperty('display', 'block');
95
- if (fg('platform_editor_react18_plugin_portalprovider')) {
96
- nodeViewPortalProviderAPI.render(() => /*#__PURE__*/createElement(DropTarget, {
97
- ...props,
98
- getPos,
99
- anchorRectCache,
100
- isSameLayout
101
- }), element, key);
102
- } else {
103
- ReactDOM.render( /*#__PURE__*/createElement(DropTarget, {
104
- ...props,
105
- getPos,
106
- anchorRectCache,
107
- isSameLayout
108
- }), element);
109
- }
93
+ nodeViewPortalProviderAPI.render(() => /*#__PURE__*/createElement(DropTarget, {
94
+ ...props,
95
+ getPos,
96
+ anchorRectCache,
97
+ isSameLayout
98
+ }), element, key);
110
99
  return element;
111
100
  }, {
112
101
  type: TYPE_DROP_TARGET_DEC,
@@ -127,19 +116,11 @@ export const createLayoutDropTargetDecoration = (pos, props, nodeViewPortalProvi
127
116
  element.setAttribute('data-blocks-drop-target-container', 'true');
128
117
  element.setAttribute('data-blocks-drop-target-key', key);
129
118
  element.style.clear = 'unset';
130
- if (fg('platform_editor_react18_plugin_portalprovider')) {
131
- nodeViewPortalProviderAPI.render(() => /*#__PURE__*/createElement(DropTargetLayout, {
132
- ...props,
133
- getPos,
134
- anchorRectCache
135
- }), element, key);
136
- } else {
137
- ReactDOM.render( /*#__PURE__*/createElement(DropTargetLayout, {
138
- ...props,
139
- getPos,
140
- anchorRectCache
141
- }), element);
142
- }
119
+ nodeViewPortalProviderAPI.render(() => /*#__PURE__*/createElement(DropTargetLayout, {
120
+ ...props,
121
+ getPos,
122
+ anchorRectCache
123
+ }), element, key);
143
124
  return element;
144
125
  }, {
145
126
  type: TYPE_DROP_TARGET_DEC
@@ -369,7 +369,21 @@ export const DragHandle = ({
369
369
  }
370
370
  setDragHandleSelected(isHandleInSelection(view.state, selection, start));
371
371
  }, [start, selection, view.state]);
372
- let helpDescriptors = [{
372
+ let helpDescriptors = isTopLevelNode && fg('platform_editor_advanced_layouts_accessibility') ? [{
373
+ description: formatMessage(blockControlsMessages.dragToMove)
374
+ }, {
375
+ description: formatMessage(blockControlsMessages.moveUp),
376
+ keymap: dragToMoveUp
377
+ }, {
378
+ description: formatMessage(blockControlsMessages.moveDown),
379
+ keymap: dragToMoveDown
380
+ }, {
381
+ description: formatMessage(blockControlsMessages.moveLeft),
382
+ keymap: dragToMoveLeft
383
+ }, {
384
+ description: formatMessage(blockControlsMessages.moveRight),
385
+ keymap: dragToMoveRight
386
+ }] : [{
373
387
  description: formatMessage(blockControlsMessages.dragToMove)
374
388
  }, {
375
389
  description: formatMessage(blockControlsMessages.moveUp),
@@ -20,6 +20,7 @@ import { getNestedNodePosition } from '../pm-plugins/utils/getNestedNodePosition
20
20
  import { selectNode, setCursorPositionAtMovedNode } from '../pm-plugins/utils/getSelection';
21
21
  import { removeFromSource } from '../pm-plugins/utils/remove-from-source';
22
22
  import { getMultiSelectionIfPosInside } from '../pm-plugins/utils/selection';
23
+ import { getInsertLayoutStep, updateSelection } from '../pm-plugins/utils/update-selection';
23
24
  import { canMoveNodeToIndex, isInsideTable, transformSliceExpandToNestedExpand } from '../pm-plugins/utils/validation';
24
25
 
25
26
  /**
@@ -52,7 +53,7 @@ var isDragLayoutColumnToTopLevel = function isDragLayoutColumnToTopLevel($from,
52
53
  *
53
54
  * @returns the start position of a node if the node can be moved, otherwise -1
54
55
  */
55
- var getCurrentNodePos = function getCurrentNodePos(state, isParentNodeOfTypeLayout) {
56
+ var getCurrentNodePos = function getCurrentNodePos(state) {
56
57
  var _activeNode$handleOpt;
57
58
  var selection = state.selection;
58
59
  var _ref = key.getState(state) || {},
@@ -88,27 +89,46 @@ export var moveNodeViaShortcut = function moveNodeViaShortcut(api, direction, fo
88
89
  if (shouldEnableNestedDndA11y) {
89
90
  isParentNodeOfTypeLayout = !!findParentNodeOfType([state.schema.nodes.layoutSection])(state.selection);
90
91
  }
91
- var currentNodePos = getCurrentNodePos(state, isParentNodeOfTypeLayout);
92
+ var currentNodePos = getCurrentNodePos(state);
92
93
  if (currentNodePos > -1) {
93
94
  var _state$doc$nodeAt;
94
95
  var $pos = state.doc.resolve(currentNodePos);
96
+ var isTopLevelNode = $pos.depth === 0;
95
97
  var moveToPos = -1;
96
98
  var nodeIndex = $pos.index();
97
99
  var isLayoutColumnSelected = selection instanceof NodeSelection && selection.node.type.name === 'layoutColumn';
98
100
  if (direction === DIRECTION.LEFT && shouldEnableNestedDndA11y) {
99
- if (isLayoutColumnSelected && fg('platform_editor_advanced_layouts_accessibility')) {
100
- var _$pos$nodeBefore, _api$core;
101
- moveToPos = selection.from - (((_$pos$nodeBefore = $pos.nodeBefore) === null || _$pos$nodeBefore === void 0 ? void 0 : _$pos$nodeBefore.nodeSize) || 1);
101
+ if (isTopLevelNode && editorExperiment('advanced_layouts', true) && fg('platform_editor_advanced_layouts_accessibility')) {
102
+ var _api$core, _api$core2;
103
+ var nodeBefore = $pos.nodeBefore;
104
+ if (nodeBefore) {
105
+ moveToPos = currentNodePos - nodeBefore.nodeSize;
106
+ }
107
+ if (moveToPos < 0) {
108
+ return false;
109
+ }
102
110
  api === null || api === void 0 || (_api$core = api.core) === null || _api$core === void 0 || _api$core.actions.execute(function (_ref2) {
103
111
  var _api$blockControls;
104
112
  var tr = _ref2.tr;
105
113
  api === null || api === void 0 || (_api$blockControls = api.blockControls) === null || _api$blockControls === void 0 || (_api$blockControls = _api$blockControls.commands) === null || _api$blockControls === void 0 || _api$blockControls.moveToLayout(currentNodePos, moveToPos, {
106
- selectMovedNode: true
114
+ moveToEnd: true,
115
+ moveNodeAtCursorPos: true
107
116
  })({
108
117
  tr: tr
109
118
  });
119
+ var insertColumnStep = getInsertLayoutStep(tr);
120
+ var mappedTo = insertColumnStep === null || insertColumnStep === void 0 ? void 0 : insertColumnStep.from;
121
+ updateSelection(tr, mappedTo, true);
110
122
  return tr;
111
123
  });
124
+ api === null || api === void 0 || (_api$core2 = api.core) === null || _api$core2 === void 0 || _api$core2.actions.focus();
125
+ return true;
126
+ } else if (isLayoutColumnSelected && fg('platform_editor_advanced_layouts_accessibility')) {
127
+ var _$pos$nodeBefore, _api$core3, _api$blockControls2;
128
+ moveToPos = selection.from - (((_$pos$nodeBefore = $pos.nodeBefore) === null || _$pos$nodeBefore === void 0 ? void 0 : _$pos$nodeBefore.nodeSize) || 1);
129
+ api === null || api === void 0 || (_api$core3 = api.core) === null || _api$core3 === void 0 || _api$core3.actions.execute(api === null || api === void 0 || (_api$blockControls2 = api.blockControls) === null || _api$blockControls2 === void 0 || (_api$blockControls2 = _api$blockControls2.commands) === null || _api$blockControls2 === void 0 ? void 0 : _api$blockControls2.moveToLayout(currentNodePos, moveToPos, {
130
+ selectMovedNode: true
131
+ }));
112
132
  return true;
113
133
  } else {
114
134
  if ($pos.depth < 2 || !isParentNodeOfTypeLayout) {
@@ -122,8 +142,30 @@ export var moveNodeViaShortcut = function moveNodeViaShortcut(api, direction, fo
122
142
  moveToPos = $pos.start() - ((previousNode === null || previousNode === void 0 ? void 0 : previousNode.nodeSize) || 1);
123
143
  }
124
144
  } else if (direction === DIRECTION.RIGHT && shouldEnableNestedDndA11y) {
125
- if (isLayoutColumnSelected && fg('platform_editor_advanced_layouts_accessibility')) {
126
- var _api$core2;
145
+ if (isTopLevelNode && editorExperiment('advanced_layouts', true) && fg('platform_editor_advanced_layouts_accessibility')) {
146
+ var _api$core4, _api$core5;
147
+ var endOfDoc = $pos.end();
148
+ moveToPos = $pos.posAtIndex($pos.index() + 1);
149
+ if (moveToPos >= endOfDoc) {
150
+ return false;
151
+ }
152
+ api === null || api === void 0 || (_api$core4 = api.core) === null || _api$core4 === void 0 || _api$core4.actions.execute(function (_ref3) {
153
+ var _api$blockControls3;
154
+ var tr = _ref3.tr;
155
+ api === null || api === void 0 || (_api$blockControls3 = api.blockControls) === null || _api$blockControls3 === void 0 || (_api$blockControls3 = _api$blockControls3.commands) === null || _api$blockControls3 === void 0 || _api$blockControls3.moveToLayout(currentNodePos, moveToPos, {
156
+ moveNodeAtCursorPos: true
157
+ })({
158
+ tr: tr
159
+ });
160
+ var insertColumnStep = getInsertLayoutStep(tr);
161
+ var mappedTo = insertColumnStep === null || insertColumnStep === void 0 ? void 0 : insertColumnStep.from;
162
+ updateSelection(tr, mappedTo);
163
+ return tr;
164
+ });
165
+ api === null || api === void 0 || (_api$core5 = api.core) === null || _api$core5 === void 0 || _api$core5.actions.focus();
166
+ return true;
167
+ } else if (isLayoutColumnSelected && fg('platform_editor_advanced_layouts_accessibility')) {
168
+ var _api$core6, _api$blockControls4;
127
169
  var _index = $pos.index($pos.depth);
128
170
  var parent = $pos.node($pos.depth);
129
171
  // get the next layoutColumn node
@@ -136,17 +178,10 @@ export var moveNodeViaShortcut = function moveNodeViaShortcut(api, direction, fo
136
178
  }
137
179
  var moveToEnd = _index === parent.childCount - 2;
138
180
  moveToPos = moveToEnd ? $pos.before() : selection.to + ((nextNode === null || nextNode === void 0 ? void 0 : nextNode.nodeSize) || 1);
139
- api === null || api === void 0 || (_api$core2 = api.core) === null || _api$core2 === void 0 || _api$core2.actions.execute(function (_ref3) {
140
- var _api$blockControls2;
141
- var tr = _ref3.tr;
142
- api === null || api === void 0 || (_api$blockControls2 = api.blockControls) === null || _api$blockControls2 === void 0 || (_api$blockControls2 = _api$blockControls2.commands) === null || _api$blockControls2 === void 0 || _api$blockControls2.moveToLayout(currentNodePos, moveToPos, {
143
- moveToEnd: moveToEnd,
144
- selectMovedNode: true
145
- })({
146
- tr: tr
147
- });
148
- return tr;
149
- });
181
+ api === null || api === void 0 || (_api$core6 = api.core) === null || _api$core6 === void 0 || _api$core6.actions.execute(api === null || api === void 0 || (_api$blockControls4 = api.blockControls) === null || _api$blockControls4 === void 0 || (_api$blockControls4 = _api$blockControls4.commands) === null || _api$blockControls4 === void 0 ? void 0 : _api$blockControls4.moveToLayout(currentNodePos, moveToPos, {
182
+ moveToEnd: moveToEnd,
183
+ selectMovedNode: true
184
+ }));
150
185
  return true;
151
186
  } else {
152
187
  if ($pos.depth < 2 || !isParentNodeOfTypeLayout) {
@@ -158,15 +193,15 @@ export var moveNodeViaShortcut = function moveNodeViaShortcut(api, direction, fo
158
193
  if (isLayoutColumnSelected && fg('platform_editor_advanced_layouts_accessibility')) {
159
194
  moveToPos = $pos.start() - 1;
160
195
  } else {
161
- var nodeBefore = $pos.depth > 1 && nodeIndex === 0 && shouldEnableNestedDndA11y ? $pos.node($pos.depth) : $pos.nodeBefore;
162
- if (nodeBefore) {
163
- moveToPos = currentNodePos - nodeBefore.nodeSize;
196
+ var _nodeBefore = $pos.depth > 1 && nodeIndex === 0 && shouldEnableNestedDndA11y ? $pos.node($pos.depth) : $pos.nodeBefore;
197
+ if (_nodeBefore) {
198
+ moveToPos = currentNodePos - _nodeBefore.nodeSize;
164
199
  }
165
200
  }
166
201
  } else {
167
- var endOfDoc = $pos.end();
202
+ var _endOfDoc = $pos.end();
168
203
  var nodeAfterPos = $pos.posAtIndex($pos.index() + 1);
169
- if (nodeAfterPos > endOfDoc) {
204
+ if (nodeAfterPos > _endOfDoc) {
170
205
  return false;
171
206
  }
172
207
  if (isLayoutColumnSelected && fg('platform_editor_advanced_layouts_accessibility')) {
@@ -184,8 +219,8 @@ export var moveNodeViaShortcut = function moveNodeViaShortcut(api, direction, fo
184
219
  // only move the node if the destination is at the same depth, not support moving a nested node to a parent node
185
220
  var shouldMoveNode = (shouldEnableNestedDndA11y ? moveToPos > -1 && $pos.depth === state.doc.resolve(moveToPos).depth || nodeType === 'layoutColumn' : moveToPos > -1) || nodeType === 'layoutColumn' && fg('platform_editor_advanced_layouts_accessibility');
186
221
  if (shouldMoveNode) {
187
- var _api$core3;
188
- api === null || api === void 0 || (_api$core3 = api.core) === null || _api$core3 === void 0 || _api$core3.actions.execute(function (_ref4) {
222
+ var _api$core7;
223
+ api === null || api === void 0 || (_api$core7 = api.core) === null || _api$core7 === void 0 || _api$core7.actions.execute(function (_ref4) {
189
224
  var tr = _ref4.tr;
190
225
  moveNode(api)(currentNodePos, moveToPos, INPUT_METHOD.SHORTCUT, formatMessage)({
191
226
  tr: tr
@@ -195,9 +230,9 @@ export var moveNodeViaShortcut = function moveNodeViaShortcut(api, direction, fo
195
230
  });
196
231
  return true;
197
232
  } else if (nodeType) {
198
- var _api$core4;
233
+ var _api$core8;
199
234
  // If the node is first/last one, only select the node
200
- api === null || api === void 0 || (_api$core4 = api.core) === null || _api$core4 === void 0 || _api$core4.actions.execute(function (_ref5) {
235
+ api === null || api === void 0 || (_api$core8 = api.core) === null || _api$core8 === void 0 || _api$core8.actions.execute(function (_ref5) {
201
236
  var tr = _ref5.tr;
202
237
  selectNode(tr, currentNodePos, nodeType);
203
238
  tr.scrollIntoView();
@@ -156,7 +156,7 @@ var insertToDestination = function insertToDestination(tr, to, sourceContent, to
156
156
  * Check if the node at `from` can be moved to node at `to` to create/expand a layout.
157
157
  * Returns the source and destination nodes and positions if it's a valid move, otherwise, undefined
158
158
  */
159
- var canMoveToLayout = function canMoveToLayout(api, from, to, tr) {
159
+ var canMoveToLayout = function canMoveToLayout(api, from, to, tr, moveNodeAtCursorPos) {
160
160
  if (from === to) {
161
161
  return;
162
162
  }
@@ -187,7 +187,7 @@ var canMoveToLayout = function canMoveToLayout(api, from, to, tr) {
187
187
  var sourceContent = $from.nodeAfter;
188
188
  var sourceFrom = from;
189
189
  var sourceTo = from + sourceContent.nodeSize;
190
- if (isMultiSelect) {
190
+ if (isMultiSelect && !moveNodeAtCursorPos) {
191
191
  var _getMultiSelectionIfP = getMultiSelectionIfPosInside(api, from),
192
192
  anchor = _getMultiSelectionIfP.anchor,
193
193
  head = _getMultiSelectionIfP.head;
@@ -284,7 +284,7 @@ export var moveToLayout = function moveToLayout(api) {
284
284
  if (!api) {
285
285
  return tr;
286
286
  }
287
- var canMove = canMoveToLayout(api, from, to, tr);
287
+ var canMove = canMoveToLayout(api, from, to, tr, options === null || options === void 0 ? void 0 : options.moveNodeAtCursorPos);
288
288
  if (!canMove) {
289
289
  return tr;
290
290
  }
@@ -1,9 +1,7 @@
1
1
  import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
2
2
  import _createClass from "@babel/runtime/helpers/createClass";
3
3
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
4
- import ReactDOM from 'react-dom';
5
4
  import uuid from 'uuid';
6
- import { fg } from '@atlaskit/platform-feature-flags';
7
5
  import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
8
6
  export var TYPE_DROP_TARGET_DEC = 'drop-target-decoration';
9
7
  export var TYPE_HANDLE_DEC = 'drag-handle';
@@ -37,13 +35,9 @@ export var unmountDecorations = function unmountDecorations(nodeViewPortalProvid
37
35
  // as it was more responsive and causes less re-rendering
38
36
  var decorationsToRemove = document.querySelectorAll("[".concat(selector, "=\"true\"]"));
39
37
  decorationsToRemove.forEach(function (el) {
40
- if (fg('platform_editor_react18_plugin_portalprovider')) {
41
- var nodeKey = el.getAttribute(key);
42
- if (nodeKey) {
43
- nodeViewPortalProviderAPI.remove(nodeKey);
44
- }
45
- } else {
46
- ReactDOM.unmountComponentAtNode(el);
38
+ var nodeKey = el.getAttribute(key);
39
+ if (nodeKey) {
40
+ nodeViewPortalProviderAPI.remove(nodeKey);
47
41
  }
48
42
  });
49
43
  };
@@ -1,10 +1,8 @@
1
1
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
2
  import { createElement } from 'react';
3
3
  import { bind } from 'bind-event-listener';
4
- import ReactDOM from 'react-dom';
5
4
  import uuid from 'uuid';
6
5
  import { Decoration } from '@atlaskit/editor-prosemirror/view';
7
- import { fg } from '@atlaskit/platform-feature-flags';
8
6
  import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
9
7
  import { DragHandle } from '../ui/drag-handle';
10
8
  import { TYPE_HANDLE_DEC, TYPE_NODE_DEC, unmountDecorations } from './decorations-common';
@@ -65,21 +63,8 @@ export var dragHandleDecoration = function dragHandleDecoration(api, formatMessa
65
63
  // There are times when global clear: "both" styles are applied to this decoration causing jumpiness
66
64
  // due to margins applied to other nodes eg. Headings
67
65
  element.style.clear = 'unset';
68
- if (fg('platform_editor_react18_plugin_portalprovider')) {
69
- nodeViewPortalProviderAPI.render(function () {
70
- return /*#__PURE__*/createElement(DragHandle, {
71
- view: view,
72
- api: api,
73
- formatMessage: formatMessage,
74
- getPos: getPos,
75
- anchorName: anchorName,
76
- nodeType: nodeType,
77
- handleOptions: handleOptions,
78
- isTopLevelNode: isTopLevelNode
79
- });
80
- }, element, key);
81
- } else {
82
- ReactDOM.render( /*#__PURE__*/createElement(DragHandle, {
66
+ nodeViewPortalProviderAPI.render(function () {
67
+ return /*#__PURE__*/createElement(DragHandle, {
83
68
  view: view,
84
69
  api: api,
85
70
  formatMessage: formatMessage,
@@ -88,8 +73,8 @@ export var dragHandleDecoration = function dragHandleDecoration(api, formatMessa
88
73
  nodeType: nodeType,
89
74
  handleOptions: handleOptions,
90
75
  isTopLevelNode: isTopLevelNode
91
- }), element);
92
- }
76
+ });
77
+ }, element, key);
93
78
  return element;
94
79
  }, {
95
80
  side: -1,
@@ -2,11 +2,9 @@ import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
2
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
3
3
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
4
4
  import { createElement } from 'react';
5
- import ReactDOM from 'react-dom';
6
5
  import uuid from 'uuid';
7
6
  import { isEmptyParagraph } from '@atlaskit/editor-common/utils';
8
7
  import { Decoration } from '@atlaskit/editor-prosemirror/view';
9
- import { fg } from '@atlaskit/platform-feature-flags';
10
8
  import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
11
9
  import { nodeMargins } from '../ui/consts';
12
10
  import { DropTarget, EDITOR_BLOCK_CONTROLS_DROP_INDICATOR_GAP, EDITOR_BLOCK_CONTROLS_DROP_INDICATOR_OFFSET } from '../ui/drop-target';
@@ -96,21 +94,13 @@ export var createDropTargetDecoration = function createDropTargetDecoration(pos,
96
94
  element.style.setProperty(EDITOR_BLOCK_CONTROLS_DROP_INDICATOR_OFFSET, "".concat(offset, "px"));
97
95
  element.style.setProperty(EDITOR_BLOCK_CONTROLS_DROP_INDICATOR_GAP, "".concat(gap, "px"));
98
96
  element.style.setProperty('display', 'block');
99
- if (fg('platform_editor_react18_plugin_portalprovider')) {
100
- nodeViewPortalProviderAPI.render(function () {
101
- return /*#__PURE__*/createElement(DropTarget, _objectSpread(_objectSpread({}, props), {}, {
102
- getPos: getPos,
103
- anchorRectCache: anchorRectCache,
104
- isSameLayout: isSameLayout
105
- }));
106
- }, element, key);
107
- } else {
108
- ReactDOM.render( /*#__PURE__*/createElement(DropTarget, _objectSpread(_objectSpread({}, props), {}, {
97
+ nodeViewPortalProviderAPI.render(function () {
98
+ return /*#__PURE__*/createElement(DropTarget, _objectSpread(_objectSpread({}, props), {}, {
109
99
  getPos: getPos,
110
100
  anchorRectCache: anchorRectCache,
111
101
  isSameLayout: isSameLayout
112
- })), element);
113
- }
102
+ }));
103
+ }, element, key);
114
104
  return element;
115
105
  }, {
116
106
  type: TYPE_DROP_TARGET_DEC,
@@ -131,19 +121,12 @@ export var createLayoutDropTargetDecoration = function createLayoutDropTargetDec
131
121
  element.setAttribute('data-blocks-drop-target-container', 'true');
132
122
  element.setAttribute('data-blocks-drop-target-key', key);
133
123
  element.style.clear = 'unset';
134
- if (fg('platform_editor_react18_plugin_portalprovider')) {
135
- nodeViewPortalProviderAPI.render(function () {
136
- return /*#__PURE__*/createElement(DropTargetLayout, _objectSpread(_objectSpread({}, props), {}, {
137
- getPos: getPos,
138
- anchorRectCache: anchorRectCache
139
- }));
140
- }, element, key);
141
- } else {
142
- ReactDOM.render( /*#__PURE__*/createElement(DropTargetLayout, _objectSpread(_objectSpread({}, props), {}, {
124
+ nodeViewPortalProviderAPI.render(function () {
125
+ return /*#__PURE__*/createElement(DropTargetLayout, _objectSpread(_objectSpread({}, props), {}, {
143
126
  getPos: getPos,
144
127
  anchorRectCache: anchorRectCache
145
- })), element);
146
- }
128
+ }));
129
+ }, element, key);
147
130
  return element;
148
131
  }, {
149
132
  type: TYPE_DROP_TARGET_DEC
@@ -380,7 +380,21 @@ export var DragHandle = function DragHandle(_ref) {
380
380
  }
381
381
  setDragHandleSelected(isHandleInSelection(view.state, selection, start));
382
382
  }, [start, selection, view.state]);
383
- var helpDescriptors = [{
383
+ var helpDescriptors = isTopLevelNode && fg('platform_editor_advanced_layouts_accessibility') ? [{
384
+ description: formatMessage(blockControlsMessages.dragToMove)
385
+ }, {
386
+ description: formatMessage(blockControlsMessages.moveUp),
387
+ keymap: dragToMoveUp
388
+ }, {
389
+ description: formatMessage(blockControlsMessages.moveDown),
390
+ keymap: dragToMoveDown
391
+ }, {
392
+ description: formatMessage(blockControlsMessages.moveLeft),
393
+ keymap: dragToMoveLeft
394
+ }, {
395
+ description: formatMessage(blockControlsMessages.moveRight),
396
+ keymap: dragToMoveRight
397
+ }] : [{
384
398
  description: formatMessage(blockControlsMessages.dragToMove)
385
399
  }, {
386
400
  description: formatMessage(blockControlsMessages.moveUp),
@@ -82,6 +82,7 @@ export type BlockControlsPlugin = NextEditorPlugin<'blockControls', {
82
82
  moveToLayout: (start: number, to: number, options?: {
83
83
  moveToEnd?: boolean;
84
84
  selectMovedNode?: boolean;
85
+ moveNodeAtCursorPos?: boolean;
85
86
  }) => EditorCommand;
86
87
  moveNode: MoveNode;
87
88
  showDragHandleAt: (pos: number, anchorName: string, nodeType: string, handleOptions?: HandleOptions) => EditorCommand;
@@ -3,4 +3,5 @@ import type { BlockControlsPlugin } from '../blockControlsPluginType';
3
3
  export declare const moveToLayout: (api?: ExtractInjectionAPI<BlockControlsPlugin>) => (from: number, to: number, options?: {
4
4
  moveToEnd?: boolean;
5
5
  selectMovedNode?: boolean;
6
+ moveNodeAtCursorPos?: boolean;
6
7
  }) => EditorCommand;
@@ -82,6 +82,7 @@ export type BlockControlsPlugin = NextEditorPlugin<'blockControls', {
82
82
  moveToLayout: (start: number, to: number, options?: {
83
83
  moveToEnd?: boolean;
84
84
  selectMovedNode?: boolean;
85
+ moveNodeAtCursorPos?: boolean;
85
86
  }) => EditorCommand;
86
87
  moveNode: MoveNode;
87
88
  showDragHandleAt: (pos: number, anchorName: string, nodeType: string, handleOptions?: HandleOptions) => EditorCommand;
@@ -3,4 +3,5 @@ import type { BlockControlsPlugin } from '../blockControlsPluginType';
3
3
  export declare const moveToLayout: (api?: ExtractInjectionAPI<BlockControlsPlugin>) => (from: number, to: number, options?: {
4
4
  moveToEnd?: boolean;
5
5
  selectMovedNode?: boolean;
6
+ moveNodeAtCursorPos?: boolean;
6
7
  }) => EditorCommand;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-block-controls",
3
- "version": "2.26.0",
3
+ "version": "2.26.1",
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,7 @@
31
31
  },
32
32
  "dependencies": {
33
33
  "@atlaskit/adf-schema": "^46.1.0",
34
- "@atlaskit/editor-common": "^99.12.0",
34
+ "@atlaskit/editor-common": "^99.13.0",
35
35
  "@atlaskit/editor-plugin-accessibility-utils": "^1.4.0",
36
36
  "@atlaskit/editor-plugin-analytics": "^1.12.0",
37
37
  "@atlaskit/editor-plugin-editor-disabled": "^1.5.0",
@@ -119,9 +119,6 @@
119
119
  "platform_editor_advanced_layouts_redraw_on_drag": {
120
120
  "type": "boolean"
121
121
  },
122
- "platform_editor_react18_plugin_portalprovider": {
123
- "type": "boolean"
124
- },
125
122
  "platform_editor_use_nested_table_pm_nodes": {
126
123
  "type": "boolean"
127
124
  },