@atlaskit/editor-plugin-block-controls 2.2.2 → 2.3.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.
@@ -1,6 +1,8 @@
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
+ 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; }
5
+ 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
6
  import { createElement } from 'react';
5
7
  import { bind } from 'bind-event-listener';
6
8
  import ReactDOM from 'react-dom';
@@ -10,8 +12,10 @@ import { isEmptyParagraph } from '@atlaskit/editor-common/utils';
10
12
  import { Decoration } from '@atlaskit/editor-prosemirror/view';
11
13
  import { fg } from '@atlaskit/platform-feature-flags';
12
14
  import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
15
+ import { nodeMargins } from '../ui/consts';
13
16
  import { DragHandle } from '../ui/drag-handle';
14
17
  import { DropTarget } from '../ui/drop-target';
18
+ import { DropTargetV2, EDITOR_BLOCK_CONTROLS_DROP_INDICATOR_GAP, EDITOR_BLOCK_CONTROLS_DROP_INDICATOR_OFFSET } from '../ui/drop-target-v2';
15
19
  import { isBlocksDragTargetDebug } from '../utils/drag-target-debug';
16
20
  import { canMoveNodeToIndex } from '../utils/validation';
17
21
  var IGNORE_NODES = ['tableCell', 'tableHeader', 'tableRow', 'layoutColumn', 'listItem', 'caption'];
@@ -21,24 +25,101 @@ var DISABLE_CHILD_DROP_TARGET = ['orderedList', 'bulletList'];
21
25
  var getNestedDepth = function getNestedDepth() {
22
26
  return editorExperiment('nested-dnd', true) ? 100 : 0;
23
27
  };
24
- var createDropTargetDecoration = function createDropTargetDecoration(pos, dropTargetDec) {
28
+ export var getNodeAnchor = function getNodeAnchor(node) {
29
+ var handleId = ObjHash.getForNode(node);
30
+ return "--node-anchor-".concat(node.type.name, "-").concat(handleId);
31
+ };
32
+ var getNodeMargins = function getNodeMargins(node) {
33
+ if (!node) {
34
+ return nodeMargins['default'];
35
+ }
36
+ var nodeTypeName = node.type.name;
37
+ if (nodeTypeName === 'heading') {
38
+ return nodeMargins["heading".concat(node.attrs.level)] || nodeMargins['default'];
39
+ }
40
+ return nodeMargins[nodeTypeName] || nodeMargins['default'];
41
+ };
42
+ var getGapAndOffset = function getGapAndOffset(prevNode, nextNode, parentNode) {
43
+ if (!prevNode && nextNode) {
44
+ // first node
45
+ return {
46
+ gap: 0,
47
+ offset: 0
48
+ };
49
+ } else if (prevNode && !nextNode) {
50
+ return {
51
+ gap: 0,
52
+ offset: 0
53
+ };
54
+ }
55
+ var top = getNodeMargins(nextNode).top || 4;
56
+ var bottom = getNodeMargins(prevNode).bottom || 4;
57
+ var gap = Math.max(top, bottom);
58
+ var offset = top - gap / 2;
59
+ if ((prevNode === null || prevNode === void 0 ? void 0 : prevNode.type.name) === 'mediaSingle' && (nextNode === null || nextNode === void 0 ? void 0 : nextNode.type.name) === 'mediaSingle') {
60
+ offset = -offset;
61
+ } else if (prevNode !== null && prevNode !== void 0 && prevNode.type.name && ['tableCell', 'tableHeader'].includes(prevNode === null || prevNode === void 0 ? void 0 : prevNode.type.name)) {
62
+ offset = 0;
63
+ }
64
+ return {
65
+ gap: gap,
66
+ offset: offset
67
+ };
68
+ };
69
+ var shouldDescend = function shouldDescend(node) {
70
+ if (fg('platform_editor_drag_and_drop_target_v2')) {
71
+ return !['mediaSingle', 'paragraph', 'heading'].includes(node.type.name);
72
+ }
73
+ return true;
74
+ };
75
+ export var createDropTargetDecoration = function createDropTargetDecoration(pos, props, side, anchorHeightsCache) {
25
76
  return Decoration.widget(pos, function (_, getPos) {
26
77
  var element = document.createElement('div');
27
78
  element.setAttribute('data-blocks-drop-target-container', 'true');
28
79
  element.style.clear = 'unset';
29
- ReactDOM.render(dropTargetDec(getPos), element);
80
+ if (fg('platform_editor_drag_and_drop_target_v2')) {
81
+ var _getGapAndOffset = getGapAndOffset(props.prevNode, props.nextNode, props.parentNode),
82
+ gap = _getGapAndOffset.gap,
83
+ offset = _getGapAndOffset.offset;
84
+ element.style.setProperty(EDITOR_BLOCK_CONTROLS_DROP_INDICATOR_OFFSET, "".concat(offset, "px"));
85
+ element.style.setProperty(EDITOR_BLOCK_CONTROLS_DROP_INDICATOR_GAP, "".concat(gap, "px"));
86
+ }
87
+ if (fg('platform_editor_drag_and_drop_target_v2')) {
88
+ ReactDOM.render( /*#__PURE__*/createElement(DropTargetV2, _objectSpread(_objectSpread({}, props), {}, {
89
+ getPos: getPos,
90
+ anchorHeightsCache: anchorHeightsCache
91
+ })), element);
92
+ } else {
93
+ ReactDOM.render( /*#__PURE__*/createElement(DropTarget, _objectSpread(_objectSpread({}, props), {}, {
94
+ getPos: getPos
95
+ })), element);
96
+ }
30
97
  return element;
31
98
  }, {
32
99
  type: 'drop-target-decoration',
33
- side: -1
100
+ side: side
34
101
  });
35
102
  };
36
- export var dropTargetDecorations = function dropTargetDecorations(newState, api, formatMessage, activeNode) {
103
+ export var dropTargetDecorations = function dropTargetDecorations(newState, api, formatMessage, activeNode, anchorHeightsCache) {
37
104
  var decs = [];
38
105
  unmountDecorations('data-blocks-drop-target-container');
39
106
  var prevNode;
40
107
  var activeNodePos = activeNode === null || activeNode === void 0 ? void 0 : activeNode.pos;
41
108
  var activePMNode = typeof activeNodePos === 'number' && newState.doc.resolve(activeNodePos).nodeAfter;
109
+ anchorHeightsCache === null || anchorHeightsCache === void 0 || anchorHeightsCache.clear();
110
+ var prevNodeStack = [];
111
+ var popNodeStack = function popNodeStack(depth) {
112
+ var result;
113
+ var toDepth = Math.max(depth, 0);
114
+ while (prevNodeStack.length > toDepth) {
115
+ result = prevNodeStack.pop();
116
+ }
117
+ return result;
118
+ };
119
+ var pushNodeStack = function pushNodeStack(node, depth) {
120
+ popNodeStack(depth);
121
+ prevNodeStack.push(node);
122
+ };
42
123
  newState.doc.descendants(function (node, pos, parent, index) {
43
124
  var depth = 0;
44
125
  // drop target deco at the end position
@@ -46,62 +127,65 @@ export var dropTargetDecorations = function dropTargetDecorations(newState, api,
46
127
  if (editorExperiment('nested-dnd', true)) {
47
128
  depth = newState.doc.resolve(pos).depth;
48
129
  if (node.isInline || !parent || DISABLE_CHILD_DROP_TARGET.includes(parent.type.name)) {
49
- prevNode = node;
130
+ if (fg('platform_editor_drag_and_drop_target_v2')) {
131
+ pushNodeStack(node, depth);
132
+ } else {
133
+ prevNode = node;
134
+ }
50
135
  return false;
51
136
  }
52
137
  if (IGNORE_NODES.includes(node.type.name)) {
53
- prevNode = node;
54
- return true; //skip over, don't consider it a valid depth
138
+ if (fg('platform_editor_drag_and_drop_target_v2')) {
139
+ pushNodeStack(node, depth);
140
+ } else {
141
+ prevNode = node;
142
+ }
143
+ return shouldDescend(node); //skip over, don't consider it a valid depth
55
144
  }
56
145
  var canDrop = activePMNode && canMoveNodeToIndex(parent, index, activePMNode);
57
146
 
58
147
  //NOTE: This will block drop targets showing for nodes that are valid after transformation (i.e. expand -> nestedExpand)
59
148
  if (!canDrop && !isBlocksDragTargetDebug()) {
60
- prevNode = node;
149
+ if (fg('platform_editor_drag_and_drop_target_v2')) {
150
+ pushNodeStack(node, depth);
151
+ } else {
152
+ prevNode = node;
153
+ }
61
154
  return false; //not valid pos, so nested not valid either
62
155
  }
63
156
  if (parent.lastChild === node && !isEmptyParagraph(node) && PARENT_WITH_END_DROP_TARGET.includes(parent.type.name)) {
64
157
  endPos = pos + node.nodeSize;
65
158
  }
66
159
  }
67
- var previousNode = prevNode; // created scoped variable
68
- decs.push(createDropTargetDecoration(pos, function (getPos) {
69
- return /*#__PURE__*/createElement(DropTarget, {
160
+ var previousNode = fg('platform_editor_drag_and_drop_target_v2') ? popNodeStack(depth) : prevNode; // created scoped variable
161
+ decs.push(createDropTargetDecoration(pos, {
162
+ api: api,
163
+ prevNode: previousNode,
164
+ nextNode: node,
165
+ parentNode: parent || undefined,
166
+ formatMessage: formatMessage
167
+ }, -1, anchorHeightsCache));
168
+ if (endPos !== undefined) {
169
+ decs.push(createDropTargetDecoration(endPos, {
70
170
  api: api,
71
- getPos: getPos,
72
- prevNode: previousNode,
73
- nextNode: node,
74
- parentNode: parent,
171
+ prevNode: fg('platform_editor_drag_and_drop_target_v2') ? node : undefined,
172
+ parentNode: parent || undefined,
75
173
  formatMessage: formatMessage
76
- });
77
- }));
78
- if (endPos !== undefined) {
79
- decs.push(createDropTargetDecoration(endPos, function (getPos) {
80
- return /*#__PURE__*/createElement(DropTarget, {
81
- api: api,
82
- getPos: getPos,
83
- parentNode: parent,
84
- formatMessage: formatMessage
85
- });
86
- }));
174
+ }, -1, anchorHeightsCache));
175
+ }
176
+ if (fg('platform_editor_drag_and_drop_target_v2')) {
177
+ pushNodeStack(node, depth);
178
+ } else {
179
+ prevNode = node;
87
180
  }
88
- prevNode = node;
89
- return depth < getNestedDepth();
181
+ return depth < getNestedDepth() && shouldDescend(node);
90
182
  });
91
-
92
- //TODO: Should this use createDropTargetDecoration?
93
- decs.push(Decoration.widget(newState.doc.nodeSize - 2, function (_, getPos) {
94
- var element = document.createElement('div');
95
- element.setAttribute('data-blocks-drop-target-container', 'true');
96
- ReactDOM.render( /*#__PURE__*/createElement(DropTarget, {
97
- api: api,
98
- getPos: getPos,
99
- formatMessage: formatMessage
100
- }), element);
101
- return element;
102
- }, {
103
- type: 'drop-target-decoration'
104
- }));
183
+ decs.push(createDropTargetDecoration(newState.doc.nodeSize - 2, {
184
+ api: api,
185
+ formatMessage: formatMessage,
186
+ prevNode: newState.doc.lastChild || undefined,
187
+ parentNode: newState.doc
188
+ }, undefined, anchorHeightsCache));
105
189
  return decs;
106
190
  };
107
191
  export var emptyParagraphNodeDecorations = function emptyParagraphNodeDecorations() {
@@ -12,6 +12,7 @@ import { autoScrollForElements } from '@atlaskit/pragmatic-drag-and-drop-auto-sc
12
12
  import { combine } from '@atlaskit/pragmatic-drag-and-drop/combine';
13
13
  import { monitorForElements } from '@atlaskit/pragmatic-drag-and-drop/element/adapter';
14
14
  import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
15
+ import { AnchorHeightsCache, isAnchorSupported } from '../utils/anchor-utils';
15
16
  import { isBlocksDragTargetDebug } from '../utils/drag-target-debug';
16
17
  import { dragHandleDecoration, dropTargetDecorations, emptyParagraphNodeDecorations, nodeDecorations } from './decorations';
17
18
  import { handleMouseOver } from './handle-mouse-over';
@@ -95,6 +96,10 @@ export var createPlugin = function createPlugin(api, getIntl) {
95
96
  if (fg('platform_editor_element_dnd_nested_fix_patch_2')) {
96
97
  // TODO: Remove this once FG is used in code
97
98
  }
99
+ var anchorHeightsCache;
100
+ if (!isAnchorSupported() && fg('platform_editor_drag_and_drop_target_v2')) {
101
+ anchorHeightsCache = new AnchorHeightsCache();
102
+ }
98
103
  return new SafePlugin({
99
104
  key: key,
100
105
  state: {
@@ -263,7 +268,7 @@ export var createPlugin = function createPlugin(api, getIntl) {
263
268
  // if the transaction is only for analytics and user is dragging, continue to draw drop targets
264
269
  if (shouldCreateDropTargets || isBlocksDragTargetDebug()) {
265
270
  var _meta$activeNode6;
266
- var _decs2 = dropTargetDecorations(newState, api, formatMessage, isNestedEnabled ? (_meta$activeNode6 = meta === null || meta === void 0 ? void 0 : meta.activeNode) !== null && _meta$activeNode6 !== void 0 ? _meta$activeNode6 : mappedActiveNodePos : meta === null || meta === void 0 ? void 0 : meta.activeNode);
271
+ var _decs2 = dropTargetDecorations(newState, api, formatMessage, isNestedEnabled ? (_meta$activeNode6 = meta === null || meta === void 0 ? void 0 : meta.activeNode) !== null && _meta$activeNode6 !== void 0 ? _meta$activeNode6 : mappedActiveNodePos : meta === null || meta === void 0 ? void 0 : meta.activeNode, anchorHeightsCache);
267
272
  decorations = decorations.add(newState.doc, _decs2);
268
273
  }
269
274
  }
@@ -340,6 +345,8 @@ export var createPlugin = function createPlugin(api, getIntl) {
340
345
  return false;
341
346
  },
342
347
  dragstart: function dragstart(view) {
348
+ var _anchorHeightsCache;
349
+ (_anchorHeightsCache = anchorHeightsCache) === null || _anchorHeightsCache === void 0 || _anchorHeightsCache.setEditorView(view);
343
350
  view.dispatch(view.state.tr.setMeta(key, {
344
351
  isPMDragging: true
345
352
  }));
@@ -100,7 +100,7 @@ export var nodeMargins = {
100
100
  bottom: 0
101
101
  },
102
102
  codeBlock: {
103
- top: 0,
103
+ top: 12,
104
104
  bottom: 0
105
105
  },
106
106
  panel: {
@@ -108,8 +108,8 @@ export var nodeMargins = {
108
108
  bottom: 0
109
109
  },
110
110
  rule: {
111
- top: 20,
112
- bottom: 20
111
+ top: 24,
112
+ bottom: 24
113
113
  },
114
114
  mediaSingle: {
115
115
  top: 24,
@@ -0,0 +1,176 @@
1
+ import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
+ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
3
+ /**
4
+ * @jsxRuntime classic
5
+ * @jsx jsx
6
+ */
7
+ import { Fragment, useEffect, useMemo, useRef, useState } from 'react';
8
+
9
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766
10
+ import { css, jsx } from '@emotion/react';
11
+ import { useSharedPluginState } from '@atlaskit/editor-common/hooks';
12
+ import { DropIndicator } from '@atlaskit/pragmatic-drag-and-drop-react-drop-indicator/box';
13
+ import { dropTargetForElements } from '@atlaskit/pragmatic-drag-and-drop/element/adapter';
14
+ import { layers } from '@atlaskit/theme/constants';
15
+ import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
16
+ import { getNodeAnchor } from '../pm-plugins/decorations';
17
+ import { isAnchorSupported } from '../utils/anchor-utils';
18
+ import { isBlocksDragTargetDebug } from '../utils/drag-target-debug';
19
+ import { getNestedNodeLeftPaddingMargin } from './consts';
20
+ var DEFAULT_DROP_INDICATOR_WIDTH = 760;
21
+ var EDITOR_BLOCK_CONTROLS_DROP_INDICATOR_WIDTH = '--editor-block-controls-drop-indicator-width';
22
+ var EDITOR_BLOCK_CONTROLS_DROP_TARGET_LEFT_MARGIN = '--editor-block-controls-drop-target-leftMargin';
23
+ var EDITOR_BLOCK_CONTROLS_DROP_TARGET_ZINDEX = '--editor-block-controls-drop-target-zindex';
24
+ export var EDITOR_BLOCK_CONTROLS_DROP_INDICATOR_OFFSET = '--editor-block-controls-drop-indicator-offset';
25
+ export var EDITOR_BLOCK_CONTROLS_DROP_INDICATOR_GAP = '--editor-block-controls-drop-indicator-gap';
26
+ var styleDropTarget = css({
27
+ marginLeft: "calc(-1 * var(".concat(EDITOR_BLOCK_CONTROLS_DROP_TARGET_LEFT_MARGIN, ", 0))"),
28
+ paddingLeft: "var(".concat(EDITOR_BLOCK_CONTROLS_DROP_TARGET_LEFT_MARGIN, ", 0)"),
29
+ position: 'absolute',
30
+ left: '0',
31
+ display: 'block',
32
+ zIndex: "var(".concat(EDITOR_BLOCK_CONTROLS_DROP_TARGET_ZINDEX, ", 110)"),
33
+ transform: "translateY(var(".concat(EDITOR_BLOCK_CONTROLS_DROP_INDICATOR_OFFSET, ", 0))")
34
+ });
35
+ var styleDropIndicator = css({
36
+ height: '100%',
37
+ margin: '0 auto',
38
+ position: 'relative',
39
+ width: "var(".concat(EDITOR_BLOCK_CONTROLS_DROP_INDICATOR_WIDTH, ", 100%)")
40
+ });
41
+ var nestedDropIndicatorStyle = css({
42
+ position: 'relative'
43
+ });
44
+ var dropZoneStyles = css({
45
+ margin: 0,
46
+ position: 'absolute',
47
+ width: '100%',
48
+ zIndex: 110,
49
+ minHeight: '4px'
50
+ });
51
+ var nestedDropZoneStyle = css({
52
+ left: '4px',
53
+ right: '4px',
54
+ width: 'unset'
55
+ });
56
+ var enableDropZone = ['paragraph', 'mediaSingle', 'heading', 'codeBlock', 'decisionList', 'bulletList', 'orderedList', 'taskList', 'extension', 'blockCard'];
57
+ var HoverZone = function HoverZone(_ref) {
58
+ var onDragEnter = _ref.onDragEnter,
59
+ onDragLeave = _ref.onDragLeave,
60
+ onDrop = _ref.onDrop,
61
+ node = _ref.node,
62
+ editorWidth = _ref.editorWidth,
63
+ anchorHeightsCache = _ref.anchorHeightsCache,
64
+ position = _ref.position,
65
+ isNestedDropTarget = _ref.isNestedDropTarget;
66
+ var ref = useRef(null);
67
+ useEffect(function () {
68
+ if (ref.current) {
69
+ return dropTargetForElements({
70
+ element: ref.current,
71
+ onDragEnter: onDragEnter,
72
+ onDragLeave: onDragLeave,
73
+ onDrop: onDrop
74
+ });
75
+ }
76
+ }, [onDragEnter, onDragLeave, onDrop]);
77
+ var hoverZoneUpperStyle = useMemo(function () {
78
+ var anchorName = node ? getNodeAnchor(node) : '';
79
+ var heightStyleOffset = "var(--editor-block-controls-drop-indicator-gap, 0)/2";
80
+ var transformOffset = "var(".concat(EDITOR_BLOCK_CONTROLS_DROP_INDICATOR_OFFSET, ", 0)");
81
+ var heightStyle = anchorName && enableDropZone.includes((node === null || node === void 0 ? void 0 : node.type.name) || '') ? isAnchorSupported() ? "calc(anchor-size(".concat(anchorName, " height)/2 + ").concat(heightStyleOffset, ")") : "calc(".concat(((anchorHeightsCache === null || anchorHeightsCache === void 0 ? void 0 : anchorHeightsCache.getHeight(anchorName)) || 0) / 2, "px + ").concat(heightStyleOffset, ")") : '4px';
82
+ var transform = position === 'upper' ? "translateY(calc(-100% + ".concat(transformOffset, "))") : "translateY(".concat(transformOffset, ")");
83
+ return css({
84
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-values
85
+ height: heightStyle,
86
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-values
87
+ transform: transform,
88
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-values
89
+ maxWidth: "".concat(editorWidth || 0, "px")
90
+ });
91
+ }, [anchorHeightsCache, editorWidth, node, position]);
92
+ return jsx("div", {
93
+ ref: ref
94
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop
95
+ ,
96
+ className: "drop-target-hover-zone-".concat(position)
97
+ // eslint-disable-next-line @atlaskit/design-system/consistent-css-prop-usage
98
+ ,
99
+ css: [dropZoneStyles, isNestedDropTarget && nestedDropZoneStyle, hoverZoneUpperStyle]
100
+ });
101
+ };
102
+ export var DropTargetV2 = function DropTargetV2(_ref2) {
103
+ var _dynamicStyle;
104
+ var api = _ref2.api,
105
+ getPos = _ref2.getPos,
106
+ prevNode = _ref2.prevNode,
107
+ nextNode = _ref2.nextNode,
108
+ parentNode = _ref2.parentNode,
109
+ formatMessage = _ref2.formatMessage,
110
+ anchorHeightsCache = _ref2.anchorHeightsCache;
111
+ var _useState = useState(false),
112
+ _useState2 = _slicedToArray(_useState, 2),
113
+ isDraggedOver = _useState2[0],
114
+ setIsDraggedOver = _useState2[1];
115
+ var _useSharedPluginState = useSharedPluginState(api, ['width']),
116
+ widthState = _useSharedPluginState.widthState;
117
+ var isNestedDropTarget = (parentNode === null || parentNode === void 0 ? void 0 : parentNode.type.name) !== 'doc';
118
+ var onDrop = function onDrop() {
119
+ var _api$blockControls;
120
+ var _ref3 = (api === null || api === void 0 || (_api$blockControls = api.blockControls) === null || _api$blockControls === void 0 ? void 0 : _api$blockControls.sharedState.currentState()) || {},
121
+ activeNode = _ref3.activeNode;
122
+ if (!activeNode) {
123
+ return;
124
+ }
125
+ var pos = getPos();
126
+ if (activeNode && pos !== undefined) {
127
+ var _api$core, _api$blockControls2;
128
+ var start = activeNode.pos;
129
+ api === null || api === void 0 || (_api$core = api.core) === null || _api$core === void 0 || _api$core.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.moveNode(start, pos, undefined, formatMessage));
130
+ }
131
+ };
132
+ var dynamicStyle = (_dynamicStyle = {
133
+ width: isNestedDropTarget ? 'unset' : '100%'
134
+ }, _defineProperty(_dynamicStyle, EDITOR_BLOCK_CONTROLS_DROP_INDICATOR_WIDTH, isNestedDropTarget ? '100%' : "".concat((widthState === null || widthState === void 0 ? void 0 : widthState.lineLength) || DEFAULT_DROP_INDICATOR_WIDTH, "px")), _defineProperty(_dynamicStyle, EDITOR_BLOCK_CONTROLS_DROP_TARGET_LEFT_MARGIN, isNestedDropTarget ? getNestedNodeLeftPaddingMargin(parentNode === null || parentNode === void 0 ? void 0 : parentNode.type.name) : '0'), _defineProperty(_dynamicStyle, EDITOR_BLOCK_CONTROLS_DROP_TARGET_ZINDEX, editorExperiment('nested-dnd', true) ? layers.navigation() : layers.card()), _dynamicStyle);
135
+ return jsx(Fragment, null, jsx(HoverZone, {
136
+ onDragEnter: function onDragEnter() {
137
+ return setIsDraggedOver(true);
138
+ },
139
+ onDragLeave: function onDragLeave() {
140
+ return setIsDraggedOver(false);
141
+ },
142
+ onDrop: onDrop,
143
+ node: prevNode,
144
+ editorWidth: widthState === null || widthState === void 0 ? void 0 : widthState.lineLength,
145
+ anchorHeightsCache: anchorHeightsCache,
146
+ position: "upper",
147
+ isNestedDropTarget: isNestedDropTarget
148
+ }), jsx("div", {
149
+ // eslint-disable-next-line @atlaskit/design-system/consistent-css-prop-usage
150
+ css: [styleDropTarget, isNestedDropTarget && nestedDropIndicatorStyle]
151
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop
152
+ ,
153
+ style: dynamicStyle,
154
+ "data-testid": "block-ctrl-drop-target"
155
+ },
156
+ // 4px gap to clear expand node border
157
+ (isDraggedOver || isBlocksDragTargetDebug()) && jsx("div", {
158
+ css: styleDropIndicator,
159
+ "data-testid": "block-ctrl-drop-indicator"
160
+ }, jsx(DropIndicator, {
161
+ edge: "bottom"
162
+ }))), jsx(HoverZone, {
163
+ onDragEnter: function onDragEnter() {
164
+ return setIsDraggedOver(true);
165
+ },
166
+ onDragLeave: function onDragLeave() {
167
+ return setIsDraggedOver(false);
168
+ },
169
+ onDrop: onDrop,
170
+ node: nextNode,
171
+ editorWidth: widthState === null || widthState === void 0 ? void 0 : widthState.lineLength,
172
+ anchorHeightsCache: anchorHeightsCache,
173
+ position: "lower",
174
+ isNestedDropTarget: isNestedDropTarget
175
+ }));
176
+ };
@@ -0,0 +1,63 @@
1
+ import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
2
+ import _createClass from "@babel/runtime/helpers/createClass";
3
+ import _defineProperty from "@babel/runtime/helpers/defineProperty";
4
+ 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; }
5
+ 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; }
6
+ import memoizeOne from 'memoize-one';
7
+ export var isAnchorSupported = memoizeOne(function () {
8
+ // directly use CSS would cause failed SSR tests.
9
+ if (window.CSS && window.CSS.supports) {
10
+ return window.CSS.supports('anchor-name: --a');
11
+ }
12
+ return false;
13
+ });
14
+ export var AnchorHeightsCache = /*#__PURE__*/function () {
15
+ function AnchorHeightsCache() {
16
+ _classCallCheck(this, AnchorHeightsCache);
17
+ _defineProperty(this, "anchorHeightsMap", {});
18
+ _defineProperty(this, "isAnchorSupported", isAnchorSupported());
19
+ _defineProperty(this, "isDirty", true);
20
+ _defineProperty(this, "view", null);
21
+ }
22
+ _createClass(AnchorHeightsCache, [{
23
+ key: "clear",
24
+ value: function clear() {
25
+ this.isDirty = true;
26
+ this.anchorHeightsMap = {};
27
+ }
28
+ }, {
29
+ key: "getHeights",
30
+ value: function getHeights() {
31
+ if (this.isDirty) {
32
+ var _this$view;
33
+ var anchorElements = ((_this$view = this.view) === null || _this$view === void 0 ? void 0 : _this$view.dom.querySelectorAll('[data-drag-handler-anchor-name]')) || [];
34
+ this.anchorHeightsMap = Array.from(anchorElements).reduce(function (prev, curr) {
35
+ var anchorName = curr.getAttribute('data-drag-handler-anchor-name');
36
+ if (anchorName) {
37
+ return _objectSpread(_objectSpread({}, prev), {}, _defineProperty({}, anchorName, curr.clientHeight));
38
+ }
39
+ return prev;
40
+ }, {});
41
+ this.isDirty = false;
42
+ }
43
+ return this.anchorHeightsMap;
44
+ }
45
+ }, {
46
+ key: "setEditorView",
47
+ value: function setEditorView(view) {
48
+ if (this.view !== view) {
49
+ this.view = view;
50
+ }
51
+ }
52
+ }, {
53
+ key: "getHeight",
54
+ value: function getHeight(anchorName) {
55
+ if (this.isAnchorSupported) {
56
+ return null;
57
+ }
58
+ var heights = this.getHeights();
59
+ return heights[anchorName];
60
+ }
61
+ }]);
62
+ return AnchorHeightsCache;
63
+ }();
@@ -9,10 +9,10 @@ export var getNestedNodePosition = function getNestedNodePosition(state) {
9
9
  if ($pos.depth < 1) {
10
10
  return nestedNodePos;
11
11
  }
12
- var parentNodeOfSpecificTypes = findParentNodeOfType([state.schema.nodes.bulletList, state.schema.nodes.orderedList, state.schema.nodes.blockquote, state.schema.nodes.taskList])(state.selection);
12
+ var parentNodeOfSpecificTypes = findParentNodeOfType([state.schema.nodes.bulletList, state.schema.nodes.orderedList, state.schema.nodes.blockquote, state.schema.nodes.taskList, state.schema.nodes.decisionList])(state.selection);
13
13
  if (parentNodeOfSpecificTypes) {
14
14
  var parentNodeType = parentNodeOfSpecificTypes.node.type.name;
15
- nestedNodePos = ['bulletList', 'orderedList'].includes(parentNodeType) ? $pos.before($pos.depth - 1) : ['blockquote', 'taskList'].includes(parentNodeType) ? $pos.before() : nestedNodePos;
15
+ nestedNodePos = ['bulletList', 'orderedList'].includes(parentNodeType) ? $pos.before($pos.depth - 1) : ['blockquote', 'taskList', 'decisionList'].includes(parentNodeType) ? $pos.before() : nestedNodePos;
16
16
  }
17
17
  } else {
18
18
  nestedNodePos = selection.$from.pos;
@@ -1,9 +1,14 @@
1
1
  import { type IntlShape } from 'react-intl-next';
2
2
  import type { ExtractInjectionAPI } from '@atlaskit/editor-common/types';
3
+ import type { Node as PMNode } from '@atlaskit/editor-prosemirror/model';
3
4
  import type { EditorState } from '@atlaskit/editor-prosemirror/state';
4
5
  import { Decoration } from '@atlaskit/editor-prosemirror/view';
5
6
  import type { ActiveNode, BlockControlsPlugin, HandleOptions } from '../types';
6
- export declare const dropTargetDecorations: (newState: EditorState, api: ExtractInjectionAPI<BlockControlsPlugin>, formatMessage: IntlShape['formatMessage'], activeNode?: ActiveNode) => Decoration[];
7
+ import { type DropTargetProps } from '../ui/drop-target';
8
+ import { type AnchorHeightsCache } from '../utils/anchor-utils';
9
+ export declare const getNodeAnchor: (node: PMNode) => string;
10
+ export declare const createDropTargetDecoration: (pos: number, props: Omit<DropTargetProps, 'getPos'>, side?: number, anchorHeightsCache?: AnchorHeightsCache) => Decoration;
11
+ export declare const dropTargetDecorations: (newState: EditorState, api: ExtractInjectionAPI<BlockControlsPlugin>, formatMessage: IntlShape['formatMessage'], activeNode?: ActiveNode, anchorHeightsCache?: AnchorHeightsCache) => Decoration[];
7
12
  export declare const emptyParagraphNodeDecorations: () => Decoration;
8
13
  export declare const nodeDecorations: (newState: EditorState) => Decoration[];
9
14
  export declare const dragHandleDecoration: (api: ExtractInjectionAPI<BlockControlsPlugin>, getIntl: () => IntlShape, pos: number, anchorName: string, nodeType: string, handleOptions?: HandleOptions) => Decoration;
@@ -0,0 +1,8 @@
1
+ import { jsx } from '@emotion/react';
2
+ import { type AnchorHeightsCache } from '../utils/anchor-utils';
3
+ import { type DropTargetProps } from './drop-target';
4
+ export declare const EDITOR_BLOCK_CONTROLS_DROP_INDICATOR_OFFSET = "--editor-block-controls-drop-indicator-offset";
5
+ export declare const EDITOR_BLOCK_CONTROLS_DROP_INDICATOR_GAP = "--editor-block-controls-drop-indicator-gap";
6
+ export declare const DropTargetV2: ({ api, getPos, prevNode, nextNode, parentNode, formatMessage, anchorHeightsCache, }: DropTargetProps & {
7
+ anchorHeightsCache?: AnchorHeightsCache | undefined;
8
+ }) => jsx.JSX.Element;
@@ -0,0 +1,12 @@
1
+ import type { EditorView } from '@atlaskit/editor-prosemirror/view';
2
+ export declare const isAnchorSupported: import("memoize-one").MemoizedFn<() => boolean>;
3
+ export declare class AnchorHeightsCache {
4
+ private anchorHeightsMap;
5
+ private isAnchorSupported;
6
+ private isDirty;
7
+ private view;
8
+ clear(): void;
9
+ private getHeights;
10
+ setEditorView(view: EditorView): void;
11
+ getHeight(anchorName: string): number | null;
12
+ }
@@ -1,9 +1,14 @@
1
1
  import { type IntlShape } from 'react-intl-next';
2
2
  import type { ExtractInjectionAPI } from '@atlaskit/editor-common/types';
3
+ import type { Node as PMNode } from '@atlaskit/editor-prosemirror/model';
3
4
  import type { EditorState } from '@atlaskit/editor-prosemirror/state';
4
5
  import { Decoration } from '@atlaskit/editor-prosemirror/view';
5
6
  import type { ActiveNode, BlockControlsPlugin, HandleOptions } from '../types';
6
- export declare const dropTargetDecorations: (newState: EditorState, api: ExtractInjectionAPI<BlockControlsPlugin>, formatMessage: IntlShape['formatMessage'], activeNode?: ActiveNode) => Decoration[];
7
+ import { type DropTargetProps } from '../ui/drop-target';
8
+ import { type AnchorHeightsCache } from '../utils/anchor-utils';
9
+ export declare const getNodeAnchor: (node: PMNode) => string;
10
+ export declare const createDropTargetDecoration: (pos: number, props: Omit<DropTargetProps, 'getPos'>, side?: number, anchorHeightsCache?: AnchorHeightsCache) => Decoration;
11
+ export declare const dropTargetDecorations: (newState: EditorState, api: ExtractInjectionAPI<BlockControlsPlugin>, formatMessage: IntlShape['formatMessage'], activeNode?: ActiveNode, anchorHeightsCache?: AnchorHeightsCache) => Decoration[];
7
12
  export declare const emptyParagraphNodeDecorations: () => Decoration;
8
13
  export declare const nodeDecorations: (newState: EditorState) => Decoration[];
9
14
  export declare const dragHandleDecoration: (api: ExtractInjectionAPI<BlockControlsPlugin>, getIntl: () => IntlShape, pos: number, anchorName: string, nodeType: string, handleOptions?: HandleOptions) => Decoration;
@@ -0,0 +1,8 @@
1
+ import { jsx } from '@emotion/react';
2
+ import { type AnchorHeightsCache } from '../utils/anchor-utils';
3
+ import { type DropTargetProps } from './drop-target';
4
+ export declare const EDITOR_BLOCK_CONTROLS_DROP_INDICATOR_OFFSET = "--editor-block-controls-drop-indicator-offset";
5
+ export declare const EDITOR_BLOCK_CONTROLS_DROP_INDICATOR_GAP = "--editor-block-controls-drop-indicator-gap";
6
+ export declare const DropTargetV2: ({ api, getPos, prevNode, nextNode, parentNode, formatMessage, anchorHeightsCache, }: DropTargetProps & {
7
+ anchorHeightsCache?: AnchorHeightsCache | undefined;
8
+ }) => jsx.JSX.Element;
@@ -0,0 +1,12 @@
1
+ import type { EditorView } from '@atlaskit/editor-prosemirror/view';
2
+ export declare const isAnchorSupported: import("memoize-one").MemoizedFn<() => boolean>;
3
+ export declare class AnchorHeightsCache {
4
+ private anchorHeightsMap;
5
+ private isAnchorSupported;
6
+ private isDirty;
7
+ private view;
8
+ clear(): void;
9
+ private getHeights;
10
+ setEditorView(view: EditorView): void;
11
+ getHeight(anchorName: string): number | null;
12
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-block-controls",
3
- "version": "2.2.2",
3
+ "version": "2.3.1",
4
4
  "description": "Block controls plugin for @atlaskit/editor-core",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -150,6 +150,9 @@
150
150
  },
151
151
  "platform_editor_element_dnd_nested_a11y": {
152
152
  "type": "boolean"
153
+ },
154
+ "platform_editor_drag_and_drop_target_v2": {
155
+ "type": "boolean"
153
156
  }
154
157
  }
155
158
  }