@atlaskit/editor-plugin-block-controls 2.13.16 → 2.13.18

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.
Files changed (30) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/dist/cjs/pm-plugins/decorations-drop-target.js +5 -4
  3. package/dist/cjs/ui/consts.js +16 -0
  4. package/dist/cjs/ui/drop-target-layout.js +28 -5
  5. package/dist/cjs/ui/inline-drop-target.js +32 -6
  6. package/dist/cjs/utils/advanced-layouts-flags.js +4 -1
  7. package/dist/cjs/utils/anchor-utils.js +2 -1
  8. package/dist/es2019/pm-plugins/decorations-drop-target.js +5 -4
  9. package/dist/es2019/ui/consts.js +16 -0
  10. package/dist/es2019/ui/drop-target-layout.js +30 -5
  11. package/dist/es2019/ui/inline-drop-target.js +33 -7
  12. package/dist/es2019/utils/advanced-layouts-flags.js +3 -0
  13. package/dist/es2019/utils/anchor-utils.js +2 -1
  14. package/dist/esm/pm-plugins/decorations-drop-target.js +5 -4
  15. package/dist/esm/ui/consts.js +16 -0
  16. package/dist/esm/ui/drop-target-layout.js +28 -5
  17. package/dist/esm/ui/inline-drop-target.js +32 -6
  18. package/dist/esm/utils/advanced-layouts-flags.js +3 -0
  19. package/dist/esm/utils/anchor-utils.js +2 -1
  20. package/dist/types/pm-plugins/decorations-drop-target.d.ts +1 -1
  21. package/dist/types/ui/consts.d.ts +1 -1
  22. package/dist/types/ui/drop-target-layout.d.ts +4 -1
  23. package/dist/types/utils/advanced-layouts-flags.d.ts +1 -0
  24. package/dist/types/utils/anchor-utils.d.ts +1 -0
  25. package/dist/types-ts4.5/pm-plugins/decorations-drop-target.d.ts +1 -1
  26. package/dist/types-ts4.5/ui/consts.d.ts +1 -1
  27. package/dist/types-ts4.5/ui/drop-target-layout.d.ts +4 -1
  28. package/dist/types-ts4.5/utils/advanced-layouts-flags.d.ts +1 -0
  29. package/dist/types-ts4.5/utils/anchor-utils.d.ts +1 -0
  30. package/package.json +6 -3
package/CHANGELOG.md CHANGED
@@ -1,5 +1,25 @@
1
1
  # @atlaskit/editor-plugin-block-controls
2
2
 
3
+ ## 2.13.18
4
+
5
+ ### Patch Changes
6
+
7
+ - [#165840](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/165840)
8
+ [`02a637ba38316`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/02a637ba38316) -
9
+ [ux] Update layout drop target using anchor position to work in stack layout
10
+ - [#166685](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/166685)
11
+ [`52915bfd0d222`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/52915bfd0d222) -
12
+ Add overrides for layout, to account for new DOM structure with resizer
13
+
14
+ ## 2.13.17
15
+
16
+ ### Patch Changes
17
+
18
+ - [#166056](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/166056)
19
+ [`00e53bfc73e8f`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/00e53bfc73e8f) -
20
+ ED-25760 drop hints are not triggered for unchanged layout
21
+ - Updated dependencies
22
+
3
23
  ## 2.13.16
4
24
 
5
25
  ### Patch Changes
@@ -116,13 +116,14 @@ var createDropTargetDecoration = exports.createDropTargetDecoration = function c
116
116
  side: side
117
117
  });
118
118
  };
119
- var createLayoutDropTargetDecoration = exports.createLayoutDropTargetDecoration = function createLayoutDropTargetDecoration(pos, props) {
119
+ var createLayoutDropTargetDecoration = exports.createLayoutDropTargetDecoration = function createLayoutDropTargetDecoration(pos, props, anchorRectCache) {
120
120
  return _view.Decoration.widget(pos, function (_, getPos) {
121
121
  var element = document.createElement('div');
122
122
  element.setAttribute('data-blocks-drop-target-container', 'true');
123
123
  element.style.clear = 'unset';
124
124
  _reactDom.default.render( /*#__PURE__*/(0, _react.createElement)(_dropTargetLayout.DropTargetLayout, _objectSpread(_objectSpread({}, props), {}, {
125
- getPos: getPos
125
+ getPos: getPos,
126
+ anchorRectCache: anchorRectCache
126
127
  })), element);
127
128
  return element;
128
129
  }, {
@@ -166,7 +167,7 @@ var dropTargetDecorations = exports.dropTargetDecorations = function dropTargetD
166
167
  if ((activeNode === null || activeNode === void 0 ? void 0 : activeNode.pos) === pos && activeNode.nodeType !== 'layoutColumn') {
167
168
  return false;
168
169
  }
169
- if (node.type.name === 'layoutColumn' && (parent === null || parent === void 0 ? void 0 : parent.type.name) === 'layoutSection' && (parent === null || parent === void 0 ? void 0 : parent.firstChild) !== node && (
170
+ if (node.type.name === 'layoutColumn' && (parent === null || parent === void 0 ? void 0 : parent.type.name) === 'layoutSection' && index !== 0 && (
170
171
  // Not the first node
171
172
  (parent === null || parent === void 0 ? void 0 : parent.childCount) < (0, _consts.maxLayoutColumnSupported)() || isSameLayout)) {
172
173
  // Add drop target for layout columns
@@ -174,7 +175,7 @@ var dropTargetDecorations = exports.dropTargetDecorations = function dropTargetD
174
175
  api: api,
175
176
  parent: parent,
176
177
  formatMessage: formatMessage
177
- }));
178
+ }, anchorRectCache));
178
179
  }
179
180
  }
180
181
  if (node.isInline || !parent || DISABLE_CHILD_DROP_TARGET.includes(parent.type.name)) {
@@ -7,6 +7,7 @@ Object.defineProperty(exports, "__esModule", {
7
7
  exports.topPositionAdjustment = exports.spaceLookupMap = exports.nodeMargins = exports.getNestedNodeLeftPaddingMargin = exports.dropTargetMarginMap = exports.dragHandleGap = exports.DRAG_HANDLE_ZINDEX = exports.DRAG_HANDLE_WIDTH = exports.DRAG_HANDLE_NARROW_GAP = exports.DRAG_HANDLE_MAX_WIDTH_PLUS_GAP = exports.DRAG_HANDLE_MAX_GAP = exports.DRAG_HANDLE_HEIGHT = exports.DRAG_HANDLE_DIVIDER_TOP_ADJUSTMENT = exports.DRAG_HANDLE_DEFAULT_GAP = exports.DRAG_HANDLE_BORDER_RADIUS = exports.DEFAULT_COLUMN_DISTRIBUTIONS = void 0;
8
8
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
9
9
  var _editorSharedStyles = require("@atlaskit/editor-shared-styles");
10
+ var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
10
11
  var _dropTargetMarginMap;
11
12
  var DRAG_HANDLE_HEIGHT = exports.DRAG_HANDLE_HEIGHT = 24;
12
13
  var DRAG_HANDLE_WIDTH = exports.DRAG_HANDLE_WIDTH = 12;
@@ -23,6 +24,9 @@ var dragHandleGap = exports.dragHandleGap = function dragHandleGap(nodeType, par
23
24
  if (parentNodeType && parentNodeType !== 'doc') {
24
25
  return DRAG_HANDLE_NARROW_GAP;
25
26
  }
27
+ if (nodeType === 'layoutSection' && (0, _platformFeatureFlags.fg)('platform_editor_advanced_layouts_breakout_resizing')) {
28
+ return DRAG_HANDLE_MAX_GAP + 12;
29
+ }
26
30
  if (nodeTypeExcludeList.includes(nodeType)) {
27
31
  return DRAG_HANDLE_MAX_GAP;
28
32
  }
@@ -48,6 +52,18 @@ var getNestedNodeLeftPaddingMargin = exports.getNestedNodeLeftPaddingMargin = fu
48
52
  }
49
53
  };
50
54
  var topPositionAdjustment = exports.topPositionAdjustment = function topPositionAdjustment(nodeType) {
55
+ if ((0, _platformFeatureFlags.fg)('platform_editor_advanced_layouts_breakout_resizing')) {
56
+ switch (nodeType) {
57
+ case 'rule':
58
+ return -DRAG_HANDLE_DIVIDER_TOP_ADJUSTMENT;
59
+ case 'table':
60
+ return DRAG_HANDLE_HEIGHT;
61
+ case 'layoutSection':
62
+ return 8;
63
+ default:
64
+ return 0;
65
+ }
66
+ }
51
67
  switch (nodeType) {
52
68
  case 'rule':
53
69
  return -DRAG_HANDLE_DIVIDER_TOP_ADJUSTMENT;
@@ -5,14 +5,17 @@ Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
7
  exports.DropTargetLayout = void 0;
8
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
8
9
  var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
9
10
  var _react = require("react");
10
11
  var _react2 = require("@emotion/react");
12
+ var _editorSharedStyles = require("@atlaskit/editor-shared-styles");
11
13
  var _box = require("@atlaskit/pragmatic-drag-and-drop-react-drop-indicator/box");
12
14
  var _adapter = require("@atlaskit/pragmatic-drag-and-drop/element/adapter");
13
15
  var _colors = require("@atlaskit/theme/colors");
14
16
  var _decorationsCommon = require("../pm-plugins/decorations-common");
15
17
  var _activeAnchorTracker = require("../utils/active-anchor-tracker");
18
+ var _anchorUtils = require("../utils/anchor-utils");
16
19
  var _dragTargetDebug = require("../utils/drag-target-debug");
17
20
  /**
18
21
  * @jsxRuntime classic
@@ -39,16 +42,32 @@ var dropTargetLayoutHintStyle = (0, _react2.css)({
39
42
  width: 0
40
43
  });
41
44
  var DropTargetLayout = exports.DropTargetLayout = function DropTargetLayout(props) {
42
- var _api$blockControls;
45
+ var _ref$current, _api$blockControls;
43
46
  var api = props.api,
44
47
  getPos = props.getPos,
45
- parent = props.parent;
48
+ parent = props.parent,
49
+ anchorRectCache = props.anchorRectCache;
46
50
  var ref = (0, _react.useRef)(null);
47
51
  var _useState = (0, _react.useState)(false),
48
52
  _useState2 = (0, _slicedToArray2.default)(_useState, 2),
49
53
  isDraggedOver = _useState2[0],
50
54
  setIsDraggedOver = _useState2[1];
51
55
  var anchorName = (0, _decorationsCommon.getNodeAnchor)(parent);
56
+ var nextNodeAnchorName = (_ref$current = ref.current) === null || _ref$current === void 0 || (_ref$current = _ref$current.parentElement) === null || _ref$current === void 0 || (_ref$current = _ref$current.nextElementSibling) === null || _ref$current === void 0 ? void 0 : _ref$current.getAttribute('data-drag-handler-anchor-name');
57
+ var height = '100%';
58
+ if (nextNodeAnchorName) {
59
+ if ((0, _anchorUtils.isAnchorSupported)()) {
60
+ height = "anchor-size(".concat(nextNodeAnchorName, " height)");
61
+ } else if (anchorRectCache) {
62
+ var layoutColumnRect = anchorRectCache.getRect(nextNodeAnchorName);
63
+ height = "".concat((layoutColumnRect === null || layoutColumnRect === void 0 ? void 0 : layoutColumnRect.height) || 0, "px");
64
+ }
65
+ }
66
+ var dropTargetStackLayoutHintStyle = (0, _react2.css)((0, _defineProperty2.default)({}, "@container layout-area (max-width:".concat(_editorSharedStyles.layoutBreakpointWidth.MEDIUM - 1, "px)"), {
67
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-values
68
+ height: height,
69
+ marginTop: "var(--ds-space-050, 4px)"
70
+ }));
52
71
  var _useActiveAnchorTrack = (0, _activeAnchorTracker.useActiveAnchorTracker)(anchorName),
53
72
  _useActiveAnchorTrack2 = (0, _slicedToArray2.default)(_useActiveAnchorTrack, 1),
54
73
  isActiveAnchor = _useActiveAnchorTrack2[0];
@@ -83,14 +102,18 @@ var DropTargetLayout = exports.DropTargetLayout = function DropTargetLayout(prop
83
102
  return null;
84
103
  }
85
104
  return (0, _react2.jsx)("div", {
86
- ref: ref,
87
- css: dropTargetLayoutStyle,
105
+ ref: ref
106
+ // eslint-disable-next-line @atlaskit/design-system/consistent-css-prop-usage
107
+ ,
108
+ css: [dropTargetLayoutStyle, dropTargetStackLayoutHintStyle],
88
109
  "data-testid": "block-ctrl-drop-indicator"
89
110
  }, isDraggedOver || (0, _dragTargetDebug.isBlocksDragTargetDebug)() ? (0, _react2.jsx)(_box.DropIndicator, {
90
111
  edge: "right",
91
112
  gap: "-".concat(DROP_TARGET_LAYOUT_DROP_ZONE_WIDTH, "px")
92
113
  }) : isActiveAnchor && (0, _react2.jsx)("div", {
93
- "data-testid": "block-ctrl-drop-hint",
114
+ "data-testid": "block-ctrl-drop-hint"
115
+ // eslint-disable-next-line @atlaskit/design-system/consistent-css-prop-usage
116
+ ,
94
117
  css: dropTargetLayoutHintStyle
95
118
  }));
96
119
  };
@@ -13,6 +13,7 @@ var _adapter = require("@atlaskit/pragmatic-drag-and-drop/element/adapter");
13
13
  var _colors = require("@atlaskit/theme/colors");
14
14
  var _decorationsCommon = require("../pm-plugins/decorations-common");
15
15
  var _activeAnchorTracker = require("../utils/active-anchor-tracker");
16
+ var _advancedLayoutsFlags = require("../utils/advanced-layouts-flags");
16
17
  var _anchorUtils = require("../utils/anchor-utils");
17
18
  var _dragTargetDebug = require("../utils/drag-target-debug");
18
19
  /* eslint-disable @atlaskit/design-system/consistent-css-prop-usage */
@@ -46,7 +47,8 @@ var dropTargetLayoutHintLeftStyle = (0, _react2.css)({
46
47
  var defaultNodeDimension = {
47
48
  width: '0',
48
49
  height: '0',
49
- top: 'unset'
50
+ top: 'unset',
51
+ bottom: 'unset'
50
52
  };
51
53
  var getWidthOffset = function getWidthOffset(node, width, position) {
52
54
  if (node.type.name === 'mediaSingle' || node.type.name === 'table') {
@@ -80,6 +82,7 @@ var InlineDropTarget = exports.InlineDropTarget = function InlineDropTarget(_ref
80
82
  _useActiveAnchorTrack2 = (0, _slicedToArray2.default)(_useActiveAnchorTrack, 1),
81
83
  isActiveAnchor = _useActiveAnchorTrack2[0];
82
84
  var isLeftPosition = position === 'left';
85
+ var shouldShowResponsiveLayout = (0, _advancedLayoutsFlags.showResponsiveLayout)();
83
86
  var nodeDimension = (0, _react.useMemo)(function () {
84
87
  if (!nextNode) {
85
88
  return defaultNodeDimension;
@@ -108,13 +111,20 @@ var InlineDropTarget = exports.InlineDropTarget = function InlineDropTarget(_ref
108
111
  } else if (nextNode.type.name === 'mediaSingle' && nextNode.firstChild) {
109
112
  targetAnchorName = (0, _decorationsCommon.getNodeAnchor)(nextNode.firstChild);
110
113
  }
114
+
115
+ // Set the height target anchor name to the first or last column of the layout section so that it also works for stacked layout
116
+ var heightTargetAnchorName = targetAnchorName;
117
+ if (shouldShowResponsiveLayout && nextNode.type.name === 'layoutSection' && nextNode.firstChild && nextNode.lastChild) {
118
+ heightTargetAnchorName = isLeftPosition ? (0, _decorationsCommon.getNodeAnchor)(nextNode.firstChild) : (0, _decorationsCommon.getNodeAnchor)(nextNode.lastChild);
119
+ }
111
120
  if ((0, _anchorUtils.isAnchorSupported)()) {
112
121
  var width = innerContainerWidth || "anchor-size(".concat(targetAnchorName, " width)");
113
- var height = "anchor-size(".concat(targetAnchorName, " height)");
122
+ var height = "anchor-size(".concat(heightTargetAnchorName, " height)");
114
123
  return {
115
124
  width: width,
116
125
  height: height,
117
126
  top: 'anchor(top)',
127
+ bottom: 'anchor(bottom)',
118
128
  widthOffset: getWidthOffset(nextNode, width, position)
119
129
  };
120
130
  }
@@ -122,16 +132,22 @@ var InlineDropTarget = exports.InlineDropTarget = function InlineDropTarget(_ref
122
132
  var nodeRect = anchorRectCache.getRect(targetAnchorName);
123
133
  var _width = innerContainerWidth || "".concat((nodeRect === null || nodeRect === void 0 ? void 0 : nodeRect.width) || 0, "px");
124
134
  var top = nodeRect !== null && nodeRect !== void 0 && nodeRect.top ? "".concat(nodeRect === null || nodeRect === void 0 ? void 0 : nodeRect.top, "px") : 'unset';
135
+ var bottom = "100% - ".concat((nodeRect === null || nodeRect === void 0 ? void 0 : nodeRect.bottom) || 0, "px + ").concat(GAP, "px");
125
136
  var _height = "".concat((nodeRect === null || nodeRect === void 0 ? void 0 : nodeRect.height) || 0, "px");
137
+ if (heightTargetAnchorName !== targetAnchorName) {
138
+ var nodeHeightRect = anchorRectCache.getRect(heightTargetAnchorName);
139
+ _height = "".concat((nodeHeightRect === null || nodeHeightRect === void 0 ? void 0 : nodeHeightRect.height) || 0, "px + ").concat(GAP, "px");
140
+ }
126
141
  return {
127
142
  width: _width,
128
143
  height: _height,
129
144
  top: top,
145
+ bottom: bottom,
130
146
  widthOffset: getWidthOffset(nextNode, _width, position)
131
147
  };
132
148
  }
133
149
  return defaultNodeDimension;
134
- }, [anchorName, anchorRectCache, nextNode, position]);
150
+ }, [anchorName, anchorRectCache, nextNode, position, isLeftPosition, shouldShowResponsiveLayout]);
135
151
  var onDrop = (0, _react.useCallback)(function () {
136
152
  var _api$blockControls;
137
153
  var _ref2 = (api === null || api === void 0 || (_api$blockControls = api.blockControls) === null || _api$blockControls === void 0 ? void 0 : _api$blockControls.sharedState.currentState()) || {},
@@ -149,16 +165,26 @@ var InlineDropTarget = exports.InlineDropTarget = function InlineDropTarget(_ref
149
165
  }
150
166
  }, [api, getPos, position]);
151
167
  var inlineHoverZoneRectStyle = (0, _react.useMemo)(function () {
168
+ var isLayoutNode = (nextNode === null || nextNode === void 0 ? void 0 : nextNode.type.name) === 'layoutSection';
169
+ var layoutAdjustment = isLayoutNode && shouldShowResponsiveLayout ? {
170
+ width: 11,
171
+ height: 4,
172
+ top: 6,
173
+ bottom: 2
174
+ } : undefined;
152
175
  return (0, _react2.css)({
153
176
  positionAnchor: anchorName,
154
177
  minWidth: "var(--ds-space-100, 8px)",
155
178
  left: isLeftPosition ? 0 : 'unset',
156
179
  right: isLeftPosition ? 'unset' : 0,
157
180
  top: "calc(anchor(top))",
158
- width: nodeDimension.widthOffset ? "calc((100% - ".concat(nodeDimension.width, ")/2 - ").concat(GAP, "px + ").concat(nodeDimension.widthOffset, ")") : "calc((100% - ".concat(nodeDimension.width, ")/2 - ").concat(GAP, "px)"),
159
- height: "calc(".concat(nodeDimension.height, ")")
181
+ width: nodeDimension.widthOffset ? "calc((100% - ".concat(nodeDimension.width, ")/2 - ").concat(GAP, "px + ").concat(nodeDimension.widthOffset, " - ").concat((layoutAdjustment === null || layoutAdjustment === void 0 ? void 0 : layoutAdjustment.width) || 0, "px)") : "calc((100% - ".concat(nodeDimension.width, ")/2 - ").concat(GAP, "px - ").concat((layoutAdjustment === null || layoutAdjustment === void 0 ? void 0 : layoutAdjustment.width) || 0, "px)"),
182
+ height: "calc(".concat(nodeDimension.height, " + ").concat((layoutAdjustment === null || layoutAdjustment === void 0 ? void 0 : layoutAdjustment.height) || 0, "px)")
183
+ }, isLayoutNode && shouldShowResponsiveLayout && {
184
+ top: isLeftPosition ? "calc(".concat(nodeDimension.top, " + ").concat((layoutAdjustment === null || layoutAdjustment === void 0 ? void 0 : layoutAdjustment.top) || 0, "px)") : 'unset',
185
+ bottom: isLeftPosition ? 'unset' : "calc(".concat(nodeDimension.bottom, " - ").concat((layoutAdjustment === null || layoutAdjustment === void 0 ? void 0 : layoutAdjustment.bottom) || 0, "px)")
160
186
  });
161
- }, [anchorName, isLeftPosition, nodeDimension]);
187
+ }, [anchorName, isLeftPosition, nodeDimension, nextNode, shouldShowResponsiveLayout]);
162
188
  var dropIndicatorPos = (0, _react.useMemo)(function () {
163
189
  return isLeftPosition ? 'right' : 'left';
164
190
  }, [isLeftPosition]);
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.isPreRelease2 = exports.isPreRelease1 = void 0;
6
+ exports.showResponsiveLayout = exports.isPreRelease2 = exports.isPreRelease1 = void 0;
7
7
  var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
8
8
  var _experiments = require("@atlaskit/tmp-editor-statsig/experiments");
9
9
  // When we turn on re-release 2, will also turn on pre-release 1
@@ -13,4 +13,7 @@ var isPreRelease1 = exports.isPreRelease1 = function isPreRelease1() {
13
13
  };
14
14
  var isPreRelease2 = exports.isPreRelease2 = function isPreRelease2() {
15
15
  return (0, _experiments.editorExperiment)('advanced_layouts', true) || (0, _platformFeatureFlags.fg)('platform_editor_advanced_layouts_pre_release_2');
16
+ };
17
+ var showResponsiveLayout = exports.showResponsiveLayout = function showResponsiveLayout() {
18
+ return (0, _experiments.editorExperiment)('advanced_layouts', true) && (0, _platformFeatureFlags.fg)('platform_editor_advanced_layouts_breakout_resizing');
16
19
  };
@@ -46,7 +46,8 @@ var AnchorRectCache = exports.AnchorRectCache = /*#__PURE__*/function () {
46
46
  top: curr.offsetTop,
47
47
  left: curr.offsetLeft,
48
48
  right: curr.offsetLeft + curr.clientWidth,
49
- width: curr.clientWidth
49
+ width: curr.clientWidth,
50
+ bottom: curr.offsetTop + curr.clientHeight
50
51
  }));
51
52
  }
52
53
  return prev;
@@ -107,14 +107,15 @@ export const createDropTargetDecoration = (pos, props, side, anchorRectCache, is
107
107
  side
108
108
  });
109
109
  };
110
- export const createLayoutDropTargetDecoration = (pos, props) => {
110
+ export const createLayoutDropTargetDecoration = (pos, props, anchorRectCache) => {
111
111
  return Decoration.widget(pos, (_, getPos) => {
112
112
  const element = document.createElement('div');
113
113
  element.setAttribute('data-blocks-drop-target-container', 'true');
114
114
  element.style.clear = 'unset';
115
115
  ReactDOM.render( /*#__PURE__*/createElement(DropTargetLayout, {
116
116
  ...props,
117
- getPos
117
+ getPos,
118
+ anchorRectCache
118
119
  }), element);
119
120
  return element;
120
121
  }, {
@@ -158,7 +159,7 @@ export const dropTargetDecorations = (newState, api, formatMessage, activeNode,
158
159
  if ((activeNode === null || activeNode === void 0 ? void 0 : activeNode.pos) === pos && activeNode.nodeType !== 'layoutColumn') {
159
160
  return false;
160
161
  }
161
- if (node.type.name === 'layoutColumn' && (parent === null || parent === void 0 ? void 0 : parent.type.name) === 'layoutSection' && (parent === null || parent === void 0 ? void 0 : parent.firstChild) !== node && (
162
+ if (node.type.name === 'layoutColumn' && (parent === null || parent === void 0 ? void 0 : parent.type.name) === 'layoutSection' && index !== 0 && (
162
163
  // Not the first node
163
164
  (parent === null || parent === void 0 ? void 0 : parent.childCount) < maxLayoutColumnSupported() || isSameLayout)) {
164
165
  // Add drop target for layout columns
@@ -166,7 +167,7 @@ export const dropTargetDecorations = (newState, api, formatMessage, activeNode,
166
167
  api,
167
168
  parent,
168
169
  formatMessage
169
- }));
170
+ }, anchorRectCache));
170
171
  }
171
172
  }
172
173
  if (node.isInline || !parent || DISABLE_CHILD_DROP_TARGET.includes(parent.type.name)) {
@@ -1,4 +1,5 @@
1
1
  import { akEditorUnitZIndex, akRichMediaResizeZIndex } from '@atlaskit/editor-shared-styles';
2
+ import { fg } from '@atlaskit/platform-feature-flags';
2
3
  export const DRAG_HANDLE_HEIGHT = 24;
3
4
  export const DRAG_HANDLE_WIDTH = 12;
4
5
  export const DRAG_HANDLE_BORDER_RADIUS = 4;
@@ -14,6 +15,9 @@ export const dragHandleGap = (nodeType, parentNodeType) => {
14
15
  if (parentNodeType && parentNodeType !== 'doc') {
15
16
  return DRAG_HANDLE_NARROW_GAP;
16
17
  }
18
+ if (nodeType === 'layoutSection' && fg('platform_editor_advanced_layouts_breakout_resizing')) {
19
+ return DRAG_HANDLE_MAX_GAP + 12;
20
+ }
17
21
  if (nodeTypeExcludeList.includes(nodeType)) {
18
22
  return DRAG_HANDLE_MAX_GAP;
19
23
  }
@@ -39,6 +43,18 @@ export const getNestedNodeLeftPaddingMargin = nodeType => {
39
43
  }
40
44
  };
41
45
  export const topPositionAdjustment = nodeType => {
46
+ if (fg('platform_editor_advanced_layouts_breakout_resizing')) {
47
+ switch (nodeType) {
48
+ case 'rule':
49
+ return -DRAG_HANDLE_DIVIDER_TOP_ADJUSTMENT;
50
+ case 'table':
51
+ return DRAG_HANDLE_HEIGHT;
52
+ case 'layoutSection':
53
+ return 8;
54
+ default:
55
+ return 0;
56
+ }
57
+ }
42
58
  switch (nodeType) {
43
59
  case 'rule':
44
60
  return -DRAG_HANDLE_DIVIDER_TOP_ADJUSTMENT;
@@ -6,11 +6,13 @@ import { useCallback, useEffect, useRef, useState } from 'react';
6
6
 
7
7
  // eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled
8
8
  import { css, jsx } from '@emotion/react';
9
+ import { layoutBreakpointWidth } from '@atlaskit/editor-shared-styles';
9
10
  import { DropIndicator } from '@atlaskit/pragmatic-drag-and-drop-react-drop-indicator/box';
10
11
  import { dropTargetForElements } from '@atlaskit/pragmatic-drag-and-drop/element/adapter';
11
12
  import { B200 } from '@atlaskit/theme/colors';
12
13
  import { getNodeAnchor } from '../pm-plugins/decorations-common';
13
14
  import { useActiveAnchorTracker } from '../utils/active-anchor-tracker';
15
+ import { isAnchorSupported } from '../utils/anchor-utils';
14
16
  import { isBlocksDragTargetDebug } from '../utils/drag-target-debug';
15
17
 
16
18
  // 8px gap + 16px on left and right
@@ -31,15 +33,34 @@ const dropTargetLayoutHintStyle = css({
31
33
  width: 0
32
34
  });
33
35
  export const DropTargetLayout = props => {
34
- var _api$blockControls;
36
+ var _ref$current, _ref$current$parentEl, _ref$current$parentEl2, _api$blockControls;
35
37
  const {
36
38
  api,
37
39
  getPos,
38
- parent
40
+ parent,
41
+ anchorRectCache
39
42
  } = props;
40
43
  const ref = useRef(null);
41
44
  const [isDraggedOver, setIsDraggedOver] = useState(false);
42
45
  const anchorName = getNodeAnchor(parent);
46
+ const nextNodeAnchorName = (_ref$current = ref.current) === null || _ref$current === void 0 ? void 0 : (_ref$current$parentEl = _ref$current.parentElement) === null || _ref$current$parentEl === void 0 ? void 0 : (_ref$current$parentEl2 = _ref$current$parentEl.nextElementSibling) === null || _ref$current$parentEl2 === void 0 ? void 0 : _ref$current$parentEl2.getAttribute('data-drag-handler-anchor-name');
47
+ let height = '100%';
48
+ if (nextNodeAnchorName) {
49
+ if (isAnchorSupported()) {
50
+ height = `anchor-size(${nextNodeAnchorName} height)`;
51
+ } else if (anchorRectCache) {
52
+ const layoutColumnRect = anchorRectCache.getRect(nextNodeAnchorName);
53
+ height = `${(layoutColumnRect === null || layoutColumnRect === void 0 ? void 0 : layoutColumnRect.height) || 0}px`;
54
+ }
55
+ }
56
+ const dropTargetStackLayoutHintStyle = css({
57
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-container-queries, @atlaskit/ui-styling-standard/no-unsafe-values, @atlaskit/ui-styling-standard/no-imported-style-values
58
+ [`@container layout-area (max-width:${layoutBreakpointWidth.MEDIUM - 1}px)`]: {
59
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-values
60
+ height,
61
+ marginTop: `${"var(--ds-space-050, 4px)"}`
62
+ }
63
+ });
43
64
  const [isActiveAnchor] = useActiveAnchorTracker(anchorName);
44
65
  const {
45
66
  activeNode
@@ -75,14 +96,18 @@ export const DropTargetLayout = props => {
75
96
  return null;
76
97
  }
77
98
  return jsx("div", {
78
- ref: ref,
79
- css: dropTargetLayoutStyle,
99
+ ref: ref
100
+ // eslint-disable-next-line @atlaskit/design-system/consistent-css-prop-usage
101
+ ,
102
+ css: [dropTargetLayoutStyle, dropTargetStackLayoutHintStyle],
80
103
  "data-testid": "block-ctrl-drop-indicator"
81
104
  }, isDraggedOver || isBlocksDragTargetDebug() ? jsx(DropIndicator, {
82
105
  edge: "right",
83
106
  gap: `-${DROP_TARGET_LAYOUT_DROP_ZONE_WIDTH}px`
84
107
  }) : isActiveAnchor && jsx("div", {
85
- "data-testid": "block-ctrl-drop-hint",
108
+ "data-testid": "block-ctrl-drop-hint"
109
+ // eslint-disable-next-line @atlaskit/design-system/consistent-css-prop-usage
110
+ ,
86
111
  css: dropTargetLayoutHintStyle
87
112
  }));
88
113
  };
@@ -13,6 +13,7 @@ import { dropTargetForElements } from '@atlaskit/pragmatic-drag-and-drop/element
13
13
  import { B200 } from '@atlaskit/theme/colors';
14
14
  import { getNodeAnchor } from '../pm-plugins/decorations-common';
15
15
  import { useActiveAnchorTracker } from '../utils/active-anchor-tracker';
16
+ import { showResponsiveLayout } from '../utils/advanced-layouts-flags';
16
17
  import { isAnchorSupported } from '../utils/anchor-utils';
17
18
  import { isBlocksDragTargetDebug } from '../utils/drag-target-debug';
18
19
  const hoverZoneCommonStyle = css({
@@ -37,7 +38,8 @@ const dropTargetLayoutHintLeftStyle = css({
37
38
  const defaultNodeDimension = {
38
39
  width: '0',
39
40
  height: '0',
40
- top: 'unset'
41
+ top: 'unset',
42
+ bottom: 'unset'
41
43
  };
42
44
  const getWidthOffset = (node, width, position) => {
43
45
  if (node.type.name === 'mediaSingle' || node.type.name === 'table') {
@@ -67,6 +69,7 @@ export const InlineDropTarget = ({
67
69
  }, [nextNode]);
68
70
  const [isActiveAnchor] = useActiveAnchorTracker(anchorName);
69
71
  const isLeftPosition = position === 'left';
72
+ const shouldShowResponsiveLayout = showResponsiveLayout();
70
73
  const nodeDimension = useMemo(() => {
71
74
  if (!nextNode) {
72
75
  return defaultNodeDimension;
@@ -95,13 +98,20 @@ export const InlineDropTarget = ({
95
98
  } else if (nextNode.type.name === 'mediaSingle' && nextNode.firstChild) {
96
99
  targetAnchorName = getNodeAnchor(nextNode.firstChild);
97
100
  }
101
+
102
+ // Set the height target anchor name to the first or last column of the layout section so that it also works for stacked layout
103
+ let heightTargetAnchorName = targetAnchorName;
104
+ if (shouldShowResponsiveLayout && nextNode.type.name === 'layoutSection' && nextNode.firstChild && nextNode.lastChild) {
105
+ heightTargetAnchorName = isLeftPosition ? getNodeAnchor(nextNode.firstChild) : getNodeAnchor(nextNode.lastChild);
106
+ }
98
107
  if (isAnchorSupported()) {
99
108
  const width = innerContainerWidth || `anchor-size(${targetAnchorName} width)`;
100
- const height = `anchor-size(${targetAnchorName} height)`;
109
+ const height = `anchor-size(${heightTargetAnchorName} height)`;
101
110
  return {
102
111
  width,
103
112
  height,
104
113
  top: 'anchor(top)',
114
+ bottom: 'anchor(bottom)',
105
115
  widthOffset: getWidthOffset(nextNode, width, position)
106
116
  };
107
117
  }
@@ -109,16 +119,22 @@ export const InlineDropTarget = ({
109
119
  const nodeRect = anchorRectCache.getRect(targetAnchorName);
110
120
  const width = innerContainerWidth || `${(nodeRect === null || nodeRect === void 0 ? void 0 : nodeRect.width) || 0}px`;
111
121
  const top = nodeRect !== null && nodeRect !== void 0 && nodeRect.top ? `${nodeRect === null || nodeRect === void 0 ? void 0 : nodeRect.top}px` : 'unset';
112
- const height = `${(nodeRect === null || nodeRect === void 0 ? void 0 : nodeRect.height) || 0}px`;
122
+ const bottom = `100% - ${(nodeRect === null || nodeRect === void 0 ? void 0 : nodeRect.bottom) || 0}px + ${GAP}px`;
123
+ let height = `${(nodeRect === null || nodeRect === void 0 ? void 0 : nodeRect.height) || 0}px`;
124
+ if (heightTargetAnchorName !== targetAnchorName) {
125
+ const nodeHeightRect = anchorRectCache.getRect(heightTargetAnchorName);
126
+ height = `${(nodeHeightRect === null || nodeHeightRect === void 0 ? void 0 : nodeHeightRect.height) || 0}px + ${GAP}px`;
127
+ }
113
128
  return {
114
129
  width,
115
130
  height,
116
131
  top,
132
+ bottom,
117
133
  widthOffset: getWidthOffset(nextNode, width, position)
118
134
  };
119
135
  }
120
136
  return defaultNodeDimension;
121
- }, [anchorName, anchorRectCache, nextNode, position]);
137
+ }, [anchorName, anchorRectCache, nextNode, position, isLeftPosition, shouldShowResponsiveLayout]);
122
138
  const onDrop = useCallback(() => {
123
139
  var _api$blockControls;
124
140
  const {
@@ -139,16 +155,26 @@ export const InlineDropTarget = ({
139
155
  }
140
156
  }, [api, getPos, position]);
141
157
  const inlineHoverZoneRectStyle = useMemo(() => {
158
+ const isLayoutNode = (nextNode === null || nextNode === void 0 ? void 0 : nextNode.type.name) === 'layoutSection';
159
+ const layoutAdjustment = isLayoutNode && shouldShowResponsiveLayout ? {
160
+ width: 11,
161
+ height: 4,
162
+ top: 6,
163
+ bottom: 2
164
+ } : undefined;
142
165
  return css({
143
166
  positionAnchor: anchorName,
144
167
  minWidth: "var(--ds-space-100, 8px)",
145
168
  left: isLeftPosition ? 0 : 'unset',
146
169
  right: isLeftPosition ? 'unset' : 0,
147
170
  top: `calc(anchor(top))`,
148
- width: nodeDimension.widthOffset ? `calc((100% - ${nodeDimension.width})/2 - ${GAP}px + ${nodeDimension.widthOffset})` : `calc((100% - ${nodeDimension.width})/2 - ${GAP}px)`,
149
- height: `calc(${nodeDimension.height})`
171
+ width: nodeDimension.widthOffset ? `calc((100% - ${nodeDimension.width})/2 - ${GAP}px + ${nodeDimension.widthOffset} - ${(layoutAdjustment === null || layoutAdjustment === void 0 ? void 0 : layoutAdjustment.width) || 0}px)` : `calc((100% - ${nodeDimension.width})/2 - ${GAP}px - ${(layoutAdjustment === null || layoutAdjustment === void 0 ? void 0 : layoutAdjustment.width) || 0}px)`,
172
+ height: `calc(${nodeDimension.height} + ${(layoutAdjustment === null || layoutAdjustment === void 0 ? void 0 : layoutAdjustment.height) || 0}px)`
173
+ }, isLayoutNode && shouldShowResponsiveLayout && {
174
+ top: isLeftPosition ? `calc(${nodeDimension.top} + ${(layoutAdjustment === null || layoutAdjustment === void 0 ? void 0 : layoutAdjustment.top) || 0}px)` : 'unset',
175
+ bottom: isLeftPosition ? 'unset' : `calc(${nodeDimension.bottom} - ${(layoutAdjustment === null || layoutAdjustment === void 0 ? void 0 : layoutAdjustment.bottom) || 0}px)`
150
176
  });
151
- }, [anchorName, isLeftPosition, nodeDimension]);
177
+ }, [anchorName, isLeftPosition, nodeDimension, nextNode, shouldShowResponsiveLayout]);
152
178
  const dropIndicatorPos = useMemo(() => {
153
179
  return isLeftPosition ? 'right' : 'left';
154
180
  }, [isLeftPosition]);
@@ -8,4 +8,7 @@ export const isPreRelease1 = () => {
8
8
  };
9
9
  export const isPreRelease2 = () => {
10
10
  return editorExperiment('advanced_layouts', true) || fg('platform_editor_advanced_layouts_pre_release_2');
11
+ };
12
+ export const showResponsiveLayout = () => {
13
+ return editorExperiment('advanced_layouts', true) && fg('platform_editor_advanced_layouts_breakout_resizing');
11
14
  };
@@ -32,7 +32,8 @@ export class AnchorRectCache {
32
32
  top: curr.offsetTop,
33
33
  left: curr.offsetLeft,
34
34
  right: curr.offsetLeft + curr.clientWidth,
35
- width: curr.clientWidth
35
+ width: curr.clientWidth,
36
+ bottom: curr.offsetTop + curr.clientHeight
36
37
  }
37
38
  };
38
39
  }
@@ -109,13 +109,14 @@ export var createDropTargetDecoration = function createDropTargetDecoration(pos,
109
109
  side: side
110
110
  });
111
111
  };
112
- export var createLayoutDropTargetDecoration = function createLayoutDropTargetDecoration(pos, props) {
112
+ export var createLayoutDropTargetDecoration = function createLayoutDropTargetDecoration(pos, props, anchorRectCache) {
113
113
  return Decoration.widget(pos, function (_, getPos) {
114
114
  var element = document.createElement('div');
115
115
  element.setAttribute('data-blocks-drop-target-container', 'true');
116
116
  element.style.clear = 'unset';
117
117
  ReactDOM.render( /*#__PURE__*/createElement(DropTargetLayout, _objectSpread(_objectSpread({}, props), {}, {
118
- getPos: getPos
118
+ getPos: getPos,
119
+ anchorRectCache: anchorRectCache
119
120
  })), element);
120
121
  return element;
121
122
  }, {
@@ -159,7 +160,7 @@ export var dropTargetDecorations = function dropTargetDecorations(newState, api,
159
160
  if ((activeNode === null || activeNode === void 0 ? void 0 : activeNode.pos) === pos && activeNode.nodeType !== 'layoutColumn') {
160
161
  return false;
161
162
  }
162
- if (node.type.name === 'layoutColumn' && (parent === null || parent === void 0 ? void 0 : parent.type.name) === 'layoutSection' && (parent === null || parent === void 0 ? void 0 : parent.firstChild) !== node && (
163
+ if (node.type.name === 'layoutColumn' && (parent === null || parent === void 0 ? void 0 : parent.type.name) === 'layoutSection' && index !== 0 && (
163
164
  // Not the first node
164
165
  (parent === null || parent === void 0 ? void 0 : parent.childCount) < maxLayoutColumnSupported() || isSameLayout)) {
165
166
  // Add drop target for layout columns
@@ -167,7 +168,7 @@ export var dropTargetDecorations = function dropTargetDecorations(newState, api,
167
168
  api: api,
168
169
  parent: parent,
169
170
  formatMessage: formatMessage
170
- }));
171
+ }, anchorRectCache));
171
172
  }
172
173
  }
173
174
  if (node.isInline || !parent || DISABLE_CHILD_DROP_TARGET.includes(parent.type.name)) {
@@ -1,6 +1,7 @@
1
1
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
2
  var _dropTargetMarginMap;
3
3
  import { akEditorUnitZIndex, akRichMediaResizeZIndex } from '@atlaskit/editor-shared-styles';
4
+ import { fg } from '@atlaskit/platform-feature-flags';
4
5
  export var DRAG_HANDLE_HEIGHT = 24;
5
6
  export var DRAG_HANDLE_WIDTH = 12;
6
7
  export var DRAG_HANDLE_BORDER_RADIUS = 4;
@@ -16,6 +17,9 @@ export var dragHandleGap = function dragHandleGap(nodeType, parentNodeType) {
16
17
  if (parentNodeType && parentNodeType !== 'doc') {
17
18
  return DRAG_HANDLE_NARROW_GAP;
18
19
  }
20
+ if (nodeType === 'layoutSection' && fg('platform_editor_advanced_layouts_breakout_resizing')) {
21
+ return DRAG_HANDLE_MAX_GAP + 12;
22
+ }
19
23
  if (nodeTypeExcludeList.includes(nodeType)) {
20
24
  return DRAG_HANDLE_MAX_GAP;
21
25
  }
@@ -41,6 +45,18 @@ export var getNestedNodeLeftPaddingMargin = function getNestedNodeLeftPaddingMar
41
45
  }
42
46
  };
43
47
  export var topPositionAdjustment = function topPositionAdjustment(nodeType) {
48
+ if (fg('platform_editor_advanced_layouts_breakout_resizing')) {
49
+ switch (nodeType) {
50
+ case 'rule':
51
+ return -DRAG_HANDLE_DIVIDER_TOP_ADJUSTMENT;
52
+ case 'table':
53
+ return DRAG_HANDLE_HEIGHT;
54
+ case 'layoutSection':
55
+ return 8;
56
+ default:
57
+ return 0;
58
+ }
59
+ }
44
60
  switch (nodeType) {
45
61
  case 'rule':
46
62
  return -DRAG_HANDLE_DIVIDER_TOP_ADJUSTMENT;
@@ -1,3 +1,4 @@
1
+ import _defineProperty from "@babel/runtime/helpers/defineProperty";
1
2
  import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
2
3
  /**
3
4
  * @jsxRuntime classic
@@ -7,11 +8,13 @@ import { useCallback, useEffect, useRef, useState } from 'react';
7
8
 
8
9
  // eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled
9
10
  import { css, jsx } from '@emotion/react';
11
+ import { layoutBreakpointWidth } from '@atlaskit/editor-shared-styles';
10
12
  import { DropIndicator } from '@atlaskit/pragmatic-drag-and-drop-react-drop-indicator/box';
11
13
  import { dropTargetForElements } from '@atlaskit/pragmatic-drag-and-drop/element/adapter';
12
14
  import { B200 } from '@atlaskit/theme/colors';
13
15
  import { getNodeAnchor } from '../pm-plugins/decorations-common';
14
16
  import { useActiveAnchorTracker } from '../utils/active-anchor-tracker';
17
+ import { isAnchorSupported } from '../utils/anchor-utils';
15
18
  import { isBlocksDragTargetDebug } from '../utils/drag-target-debug';
16
19
 
17
20
  // 8px gap + 16px on left and right
@@ -32,16 +35,32 @@ var dropTargetLayoutHintStyle = css({
32
35
  width: 0
33
36
  });
34
37
  export var DropTargetLayout = function DropTargetLayout(props) {
35
- var _api$blockControls;
38
+ var _ref$current, _api$blockControls;
36
39
  var api = props.api,
37
40
  getPos = props.getPos,
38
- parent = props.parent;
41
+ parent = props.parent,
42
+ anchorRectCache = props.anchorRectCache;
39
43
  var ref = useRef(null);
40
44
  var _useState = useState(false),
41
45
  _useState2 = _slicedToArray(_useState, 2),
42
46
  isDraggedOver = _useState2[0],
43
47
  setIsDraggedOver = _useState2[1];
44
48
  var anchorName = getNodeAnchor(parent);
49
+ var nextNodeAnchorName = (_ref$current = ref.current) === null || _ref$current === void 0 || (_ref$current = _ref$current.parentElement) === null || _ref$current === void 0 || (_ref$current = _ref$current.nextElementSibling) === null || _ref$current === void 0 ? void 0 : _ref$current.getAttribute('data-drag-handler-anchor-name');
50
+ var height = '100%';
51
+ if (nextNodeAnchorName) {
52
+ if (isAnchorSupported()) {
53
+ height = "anchor-size(".concat(nextNodeAnchorName, " height)");
54
+ } else if (anchorRectCache) {
55
+ var layoutColumnRect = anchorRectCache.getRect(nextNodeAnchorName);
56
+ height = "".concat((layoutColumnRect === null || layoutColumnRect === void 0 ? void 0 : layoutColumnRect.height) || 0, "px");
57
+ }
58
+ }
59
+ var dropTargetStackLayoutHintStyle = css(_defineProperty({}, "@container layout-area (max-width:".concat(layoutBreakpointWidth.MEDIUM - 1, "px)"), {
60
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-values
61
+ height: height,
62
+ marginTop: "var(--ds-space-050, 4px)"
63
+ }));
45
64
  var _useActiveAnchorTrack = useActiveAnchorTracker(anchorName),
46
65
  _useActiveAnchorTrack2 = _slicedToArray(_useActiveAnchorTrack, 1),
47
66
  isActiveAnchor = _useActiveAnchorTrack2[0];
@@ -76,14 +95,18 @@ export var DropTargetLayout = function DropTargetLayout(props) {
76
95
  return null;
77
96
  }
78
97
  return jsx("div", {
79
- ref: ref,
80
- css: dropTargetLayoutStyle,
98
+ ref: ref
99
+ // eslint-disable-next-line @atlaskit/design-system/consistent-css-prop-usage
100
+ ,
101
+ css: [dropTargetLayoutStyle, dropTargetStackLayoutHintStyle],
81
102
  "data-testid": "block-ctrl-drop-indicator"
82
103
  }, isDraggedOver || isBlocksDragTargetDebug() ? jsx(DropIndicator, {
83
104
  edge: "right",
84
105
  gap: "-".concat(DROP_TARGET_LAYOUT_DROP_ZONE_WIDTH, "px")
85
106
  }) : isActiveAnchor && jsx("div", {
86
- "data-testid": "block-ctrl-drop-hint",
107
+ "data-testid": "block-ctrl-drop-hint"
108
+ // eslint-disable-next-line @atlaskit/design-system/consistent-css-prop-usage
109
+ ,
87
110
  css: dropTargetLayoutHintStyle
88
111
  }));
89
112
  };
@@ -14,6 +14,7 @@ import { dropTargetForElements } from '@atlaskit/pragmatic-drag-and-drop/element
14
14
  import { B200 } from '@atlaskit/theme/colors';
15
15
  import { getNodeAnchor } from '../pm-plugins/decorations-common';
16
16
  import { useActiveAnchorTracker } from '../utils/active-anchor-tracker';
17
+ import { showResponsiveLayout } from '../utils/advanced-layouts-flags';
17
18
  import { isAnchorSupported } from '../utils/anchor-utils';
18
19
  import { isBlocksDragTargetDebug } from '../utils/drag-target-debug';
19
20
  var hoverZoneCommonStyle = css({
@@ -38,7 +39,8 @@ var dropTargetLayoutHintLeftStyle = css({
38
39
  var defaultNodeDimension = {
39
40
  width: '0',
40
41
  height: '0',
41
- top: 'unset'
42
+ top: 'unset',
43
+ bottom: 'unset'
42
44
  };
43
45
  var getWidthOffset = function getWidthOffset(node, width, position) {
44
46
  if (node.type.name === 'mediaSingle' || node.type.name === 'table') {
@@ -72,6 +74,7 @@ export var InlineDropTarget = function InlineDropTarget(_ref) {
72
74
  _useActiveAnchorTrack2 = _slicedToArray(_useActiveAnchorTrack, 1),
73
75
  isActiveAnchor = _useActiveAnchorTrack2[0];
74
76
  var isLeftPosition = position === 'left';
77
+ var shouldShowResponsiveLayout = showResponsiveLayout();
75
78
  var nodeDimension = useMemo(function () {
76
79
  if (!nextNode) {
77
80
  return defaultNodeDimension;
@@ -100,13 +103,20 @@ export var InlineDropTarget = function InlineDropTarget(_ref) {
100
103
  } else if (nextNode.type.name === 'mediaSingle' && nextNode.firstChild) {
101
104
  targetAnchorName = getNodeAnchor(nextNode.firstChild);
102
105
  }
106
+
107
+ // Set the height target anchor name to the first or last column of the layout section so that it also works for stacked layout
108
+ var heightTargetAnchorName = targetAnchorName;
109
+ if (shouldShowResponsiveLayout && nextNode.type.name === 'layoutSection' && nextNode.firstChild && nextNode.lastChild) {
110
+ heightTargetAnchorName = isLeftPosition ? getNodeAnchor(nextNode.firstChild) : getNodeAnchor(nextNode.lastChild);
111
+ }
103
112
  if (isAnchorSupported()) {
104
113
  var width = innerContainerWidth || "anchor-size(".concat(targetAnchorName, " width)");
105
- var height = "anchor-size(".concat(targetAnchorName, " height)");
114
+ var height = "anchor-size(".concat(heightTargetAnchorName, " height)");
106
115
  return {
107
116
  width: width,
108
117
  height: height,
109
118
  top: 'anchor(top)',
119
+ bottom: 'anchor(bottom)',
110
120
  widthOffset: getWidthOffset(nextNode, width, position)
111
121
  };
112
122
  }
@@ -114,16 +124,22 @@ export var InlineDropTarget = function InlineDropTarget(_ref) {
114
124
  var nodeRect = anchorRectCache.getRect(targetAnchorName);
115
125
  var _width = innerContainerWidth || "".concat((nodeRect === null || nodeRect === void 0 ? void 0 : nodeRect.width) || 0, "px");
116
126
  var top = nodeRect !== null && nodeRect !== void 0 && nodeRect.top ? "".concat(nodeRect === null || nodeRect === void 0 ? void 0 : nodeRect.top, "px") : 'unset';
127
+ var bottom = "100% - ".concat((nodeRect === null || nodeRect === void 0 ? void 0 : nodeRect.bottom) || 0, "px + ").concat(GAP, "px");
117
128
  var _height = "".concat((nodeRect === null || nodeRect === void 0 ? void 0 : nodeRect.height) || 0, "px");
129
+ if (heightTargetAnchorName !== targetAnchorName) {
130
+ var nodeHeightRect = anchorRectCache.getRect(heightTargetAnchorName);
131
+ _height = "".concat((nodeHeightRect === null || nodeHeightRect === void 0 ? void 0 : nodeHeightRect.height) || 0, "px + ").concat(GAP, "px");
132
+ }
118
133
  return {
119
134
  width: _width,
120
135
  height: _height,
121
136
  top: top,
137
+ bottom: bottom,
122
138
  widthOffset: getWidthOffset(nextNode, _width, position)
123
139
  };
124
140
  }
125
141
  return defaultNodeDimension;
126
- }, [anchorName, anchorRectCache, nextNode, position]);
142
+ }, [anchorName, anchorRectCache, nextNode, position, isLeftPosition, shouldShowResponsiveLayout]);
127
143
  var onDrop = useCallback(function () {
128
144
  var _api$blockControls;
129
145
  var _ref2 = (api === null || api === void 0 || (_api$blockControls = api.blockControls) === null || _api$blockControls === void 0 ? void 0 : _api$blockControls.sharedState.currentState()) || {},
@@ -141,16 +157,26 @@ export var InlineDropTarget = function InlineDropTarget(_ref) {
141
157
  }
142
158
  }, [api, getPos, position]);
143
159
  var inlineHoverZoneRectStyle = useMemo(function () {
160
+ var isLayoutNode = (nextNode === null || nextNode === void 0 ? void 0 : nextNode.type.name) === 'layoutSection';
161
+ var layoutAdjustment = isLayoutNode && shouldShowResponsiveLayout ? {
162
+ width: 11,
163
+ height: 4,
164
+ top: 6,
165
+ bottom: 2
166
+ } : undefined;
144
167
  return css({
145
168
  positionAnchor: anchorName,
146
169
  minWidth: "var(--ds-space-100, 8px)",
147
170
  left: isLeftPosition ? 0 : 'unset',
148
171
  right: isLeftPosition ? 'unset' : 0,
149
172
  top: "calc(anchor(top))",
150
- width: nodeDimension.widthOffset ? "calc((100% - ".concat(nodeDimension.width, ")/2 - ").concat(GAP, "px + ").concat(nodeDimension.widthOffset, ")") : "calc((100% - ".concat(nodeDimension.width, ")/2 - ").concat(GAP, "px)"),
151
- height: "calc(".concat(nodeDimension.height, ")")
173
+ width: nodeDimension.widthOffset ? "calc((100% - ".concat(nodeDimension.width, ")/2 - ").concat(GAP, "px + ").concat(nodeDimension.widthOffset, " - ").concat((layoutAdjustment === null || layoutAdjustment === void 0 ? void 0 : layoutAdjustment.width) || 0, "px)") : "calc((100% - ".concat(nodeDimension.width, ")/2 - ").concat(GAP, "px - ").concat((layoutAdjustment === null || layoutAdjustment === void 0 ? void 0 : layoutAdjustment.width) || 0, "px)"),
174
+ height: "calc(".concat(nodeDimension.height, " + ").concat((layoutAdjustment === null || layoutAdjustment === void 0 ? void 0 : layoutAdjustment.height) || 0, "px)")
175
+ }, isLayoutNode && shouldShowResponsiveLayout && {
176
+ top: isLeftPosition ? "calc(".concat(nodeDimension.top, " + ").concat((layoutAdjustment === null || layoutAdjustment === void 0 ? void 0 : layoutAdjustment.top) || 0, "px)") : 'unset',
177
+ bottom: isLeftPosition ? 'unset' : "calc(".concat(nodeDimension.bottom, " - ").concat((layoutAdjustment === null || layoutAdjustment === void 0 ? void 0 : layoutAdjustment.bottom) || 0, "px)")
152
178
  });
153
- }, [anchorName, isLeftPosition, nodeDimension]);
179
+ }, [anchorName, isLeftPosition, nodeDimension, nextNode, shouldShowResponsiveLayout]);
154
180
  var dropIndicatorPos = useMemo(function () {
155
181
  return isLeftPosition ? 'right' : 'left';
156
182
  }, [isLeftPosition]);
@@ -8,4 +8,7 @@ export var isPreRelease1 = function isPreRelease1() {
8
8
  };
9
9
  export var isPreRelease2 = function isPreRelease2() {
10
10
  return editorExperiment('advanced_layouts', true) || fg('platform_editor_advanced_layouts_pre_release_2');
11
+ };
12
+ export var showResponsiveLayout = function showResponsiveLayout() {
13
+ return editorExperiment('advanced_layouts', true) && fg('platform_editor_advanced_layouts_breakout_resizing');
11
14
  };
@@ -39,7 +39,8 @@ export var AnchorRectCache = /*#__PURE__*/function () {
39
39
  top: curr.offsetTop,
40
40
  left: curr.offsetLeft,
41
41
  right: curr.offsetLeft + curr.clientWidth,
42
- width: curr.clientWidth
42
+ width: curr.clientWidth,
43
+ bottom: curr.offsetTop + curr.clientHeight
43
44
  }));
44
45
  }
45
46
  return prev;
@@ -15,5 +15,5 @@ import { type AnchorRectCache } from '../utils/anchor-utils';
15
15
  */
16
16
  export declare const findDropTargetDecs: (decorations: DecorationSet, from?: number, to?: number) => Decoration[];
17
17
  export declare const createDropTargetDecoration: (pos: number, props: Omit<DropTargetProps, 'getPos'>, side?: number, anchorRectCache?: AnchorRectCache, isSameLayout?: boolean) => Decoration;
18
- export declare const createLayoutDropTargetDecoration: (pos: number, props: Omit<DropTargetLayoutProps, 'getPos'>) => Decoration;
18
+ export declare const createLayoutDropTargetDecoration: (pos: number, props: Omit<DropTargetLayoutProps, 'getPos'>, anchorRectCache?: AnchorRectCache) => Decoration;
19
19
  export declare const dropTargetDecorations: (newState: EditorState, api: ExtractInjectionAPI<BlockControlsPlugin>, formatMessage: IntlShape['formatMessage'], activeNode?: ActiveNode, anchorRectCache?: AnchorRectCache, from?: number, to?: number) => Decoration[];
@@ -7,7 +7,7 @@ export declare const DRAG_HANDLE_NARROW_GAP = 4;
7
7
  export declare const DRAG_HANDLE_MAX_GAP = 12;
8
8
  export declare const DRAG_HANDLE_MAX_WIDTH_PLUS_GAP: number;
9
9
  export declare const DRAG_HANDLE_DIVIDER_TOP_ADJUSTMENT: number;
10
- export declare const dragHandleGap: (nodeType: string, parentNodeType?: string) => 4 | 8 | 12;
10
+ export declare const dragHandleGap: (nodeType: string, parentNodeType?: string) => number;
11
11
  export declare const getNestedNodeLeftPaddingMargin: (nodeType?: string) => "8px" | "16px" | "20px" | "24px" | "28px" | "40px";
12
12
  export declare const topPositionAdjustment: (nodeType: string) => number;
13
13
  export declare const dropTargetMarginMap: {
@@ -3,10 +3,13 @@ import { type IntlShape } from 'react-intl-next';
3
3
  import type { ExtractInjectionAPI } from '@atlaskit/editor-common/types';
4
4
  import type { Node as PMNode } from '@atlaskit/editor-prosemirror/model';
5
5
  import type { BlockControlsPlugin } from '../types';
6
+ import { type AnchorRectCache } from '../utils/anchor-utils';
6
7
  export type DropTargetLayoutProps = {
7
8
  api: ExtractInjectionAPI<BlockControlsPlugin> | undefined;
8
9
  getPos: () => number | undefined;
9
10
  parent: PMNode;
10
11
  formatMessage?: IntlShape['formatMessage'];
11
12
  };
12
- export declare const DropTargetLayout: (props: DropTargetLayoutProps) => jsx.JSX.Element | null;
13
+ export declare const DropTargetLayout: (props: DropTargetLayoutProps & {
14
+ anchorRectCache?: AnchorRectCache | undefined;
15
+ }) => jsx.JSX.Element | null;
@@ -1,2 +1,3 @@
1
1
  export declare const isPreRelease1: () => boolean;
2
2
  export declare const isPreRelease2: () => boolean;
3
+ export declare const showResponsiveLayout: () => boolean;
@@ -6,6 +6,7 @@ type RectInfo = {
6
6
  left: number;
7
7
  right: number;
8
8
  width: number;
9
+ bottom: number;
9
10
  };
10
11
  export declare class AnchorRectCache {
11
12
  private anchorRectMap;
@@ -15,5 +15,5 @@ import { type AnchorRectCache } from '../utils/anchor-utils';
15
15
  */
16
16
  export declare const findDropTargetDecs: (decorations: DecorationSet, from?: number, to?: number) => Decoration[];
17
17
  export declare const createDropTargetDecoration: (pos: number, props: Omit<DropTargetProps, 'getPos'>, side?: number, anchorRectCache?: AnchorRectCache, isSameLayout?: boolean) => Decoration;
18
- export declare const createLayoutDropTargetDecoration: (pos: number, props: Omit<DropTargetLayoutProps, 'getPos'>) => Decoration;
18
+ export declare const createLayoutDropTargetDecoration: (pos: number, props: Omit<DropTargetLayoutProps, 'getPos'>, anchorRectCache?: AnchorRectCache) => Decoration;
19
19
  export declare const dropTargetDecorations: (newState: EditorState, api: ExtractInjectionAPI<BlockControlsPlugin>, formatMessage: IntlShape['formatMessage'], activeNode?: ActiveNode, anchorRectCache?: AnchorRectCache, from?: number, to?: number) => Decoration[];
@@ -7,7 +7,7 @@ export declare const DRAG_HANDLE_NARROW_GAP = 4;
7
7
  export declare const DRAG_HANDLE_MAX_GAP = 12;
8
8
  export declare const DRAG_HANDLE_MAX_WIDTH_PLUS_GAP: number;
9
9
  export declare const DRAG_HANDLE_DIVIDER_TOP_ADJUSTMENT: number;
10
- export declare const dragHandleGap: (nodeType: string, parentNodeType?: string) => 4 | 8 | 12;
10
+ export declare const dragHandleGap: (nodeType: string, parentNodeType?: string) => number;
11
11
  export declare const getNestedNodeLeftPaddingMargin: (nodeType?: string) => "8px" | "16px" | "20px" | "24px" | "28px" | "40px";
12
12
  export declare const topPositionAdjustment: (nodeType: string) => number;
13
13
  export declare const dropTargetMarginMap: {
@@ -3,10 +3,13 @@ import { type IntlShape } from 'react-intl-next';
3
3
  import type { ExtractInjectionAPI } from '@atlaskit/editor-common/types';
4
4
  import type { Node as PMNode } from '@atlaskit/editor-prosemirror/model';
5
5
  import type { BlockControlsPlugin } from '../types';
6
+ import { type AnchorRectCache } from '../utils/anchor-utils';
6
7
  export type DropTargetLayoutProps = {
7
8
  api: ExtractInjectionAPI<BlockControlsPlugin> | undefined;
8
9
  getPos: () => number | undefined;
9
10
  parent: PMNode;
10
11
  formatMessage?: IntlShape['formatMessage'];
11
12
  };
12
- export declare const DropTargetLayout: (props: DropTargetLayoutProps) => jsx.JSX.Element | null;
13
+ export declare const DropTargetLayout: (props: DropTargetLayoutProps & {
14
+ anchorRectCache?: AnchorRectCache | undefined;
15
+ }) => jsx.JSX.Element | null;
@@ -1,2 +1,3 @@
1
1
  export declare const isPreRelease1: () => boolean;
2
2
  export declare const isPreRelease2: () => boolean;
3
+ export declare const showResponsiveLayout: () => boolean;
@@ -6,6 +6,7 @@ type RectInfo = {
6
6
  left: number;
7
7
  right: number;
8
8
  width: number;
9
+ bottom: number;
9
10
  };
10
11
  export declare class AnchorRectCache {
11
12
  private anchorRectMap;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-block-controls",
3
- "version": "2.13.16",
3
+ "version": "2.13.18",
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": "^44.2.0",
34
- "@atlaskit/editor-common": "^94.23.0",
34
+ "@atlaskit/editor-common": "^94.24.0",
35
35
  "@atlaskit/editor-plugin-accessibility-utils": "^1.2.0",
36
36
  "@atlaskit/editor-plugin-analytics": "^1.10.0",
37
37
  "@atlaskit/editor-plugin-editor-disabled": "^1.3.0",
@@ -48,7 +48,7 @@
48
48
  "@atlaskit/pragmatic-drag-and-drop-react-drop-indicator": "^1.1.0",
49
49
  "@atlaskit/primitives": "^13.2.0",
50
50
  "@atlaskit/theme": "^14.0.0",
51
- "@atlaskit/tmp-editor-statsig": "^2.18.0",
51
+ "@atlaskit/tmp-editor-statsig": "^2.19.0",
52
52
  "@atlaskit/tokens": "^2.2.0",
53
53
  "@atlaskit/tooltip": "^18.9.0",
54
54
  "@babel/runtime": "^7.0.0",
@@ -159,6 +159,9 @@
159
159
  },
160
160
  "platform_editor_advanced_layouts_redraw_on_drag": {
161
161
  "type": "boolean"
162
+ },
163
+ "platform_editor_advanced_layouts_breakout_resizing": {
164
+ "type": "boolean"
162
165
  }
163
166
  }
164
167
  }