@atlaskit/editor-plugin-layout 13.1.0 → 13.2.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,32 @@
1
1
  # @atlaskit/editor-plugin-layout
2
2
 
3
+ ## 13.2.1
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies
8
+
9
+ ## 13.2.0
10
+
11
+ ### Minor Changes
12
+
13
+ - [`bb48c26acb8ba`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/bb48c26acb8ba) -
14
+ Add platform_editor_layout_column_menu_kill_switch_1 kill switch and render the full block drag
15
+ handle icon for layout columns when the new behaviour is enabled (gate OFF). When the new
16
+ behaviour is enabled, re-clicking the layout column whose menu is already open now closes the
17
+ menu, while clicking a different column switches the menu to that column. The layout column menu
18
+ now opens below the drag handle with left-aligned edges (relying on the popup's built-in placement
19
+ to invert horizontally or nudge up when space is tight) instead of the previous centred
20
+ prefer-above behaviour. The layout column Delete hover/focus danger preview now matches the table
21
+ delete affordance exactly, using the translucent color.blanket.danger fill and a 1px
22
+ color.border.danger border instead of the previous low-alpha fill with a 2px border, and clears
23
+ the concurrent blue selected blanket while the danger preview is active so the preview reads as
24
+ pure red with no blue cast.
25
+
26
+ ### Patch Changes
27
+
28
+ - Updated dependencies
29
+
3
30
  ## 13.1.0
4
31
 
5
32
  ### Minor Changes
@@ -824,28 +824,25 @@ var distributeLayoutColumns = exports.distributeLayoutColumns = function distrib
824
824
  };
825
825
  };
826
826
  };
827
- var toggleLayoutColumnMenu = exports.toggleLayoutColumnMenu = function toggleLayoutColumnMenu(_ref14) {
828
- var anchorPos = _ref14.anchorPos,
829
- isOpen = _ref14.isOpen,
830
- openedViaKeyboard = _ref14.openedViaKeyboard;
831
- return function (_ref15) {
832
- var tr = _ref15.tr;
833
- tr.setMeta('toggleLayoutColumnMenu', {
834
- anchorPos: anchorPos,
835
- isOpen: isOpen,
836
- openedViaKeyboard: openedViaKeyboard
837
- });
827
+
828
+ // Omitting `isOpen` (toggle) requires `anchorPos`, so a toggle can never open the menu
829
+ // without a valid anchor. Explicit open/close keeps `anchorPos` optional (close needs none).
830
+
831
+ var toggleLayoutColumnMenu = exports.toggleLayoutColumnMenu = function toggleLayoutColumnMenu(options) {
832
+ return function (_ref14) {
833
+ var tr = _ref14.tr;
834
+ tr.setMeta('toggleLayoutColumnMenu', options);
838
835
  tr.setMeta('scrollIntoView', false);
839
836
  return tr;
840
837
  };
841
838
  };
842
839
  var setLayoutColumnDangerPreview = exports.setLayoutColumnDangerPreview = function setLayoutColumnDangerPreview(show) {
843
- return function (_ref16) {
840
+ return function (_ref15) {
844
841
  var _selectedLayoutColumn2;
845
- var tr = _ref16.tr;
842
+ var tr = _ref15.tr;
846
843
  var selectedLayoutColumnsResult = (0, _layoutColumnSelection.getSelectedLayoutColumnsFromSelection)(tr.selection);
847
- var positions = show ? (_selectedLayoutColumn2 = selectedLayoutColumnsResult === null || selectedLayoutColumnsResult === void 0 ? void 0 : selectedLayoutColumnsResult.selectedLayoutColumns.map(function (_ref17) {
848
- var pos = _ref17.pos;
844
+ var positions = show ? (_selectedLayoutColumn2 = selectedLayoutColumnsResult === null || selectedLayoutColumnsResult === void 0 ? void 0 : selectedLayoutColumnsResult.selectedLayoutColumns.map(function (_ref16) {
845
+ var pos = _ref16.pos;
849
846
  return pos;
850
847
  })) !== null && _selectedLayoutColumn2 !== void 0 ? _selectedLayoutColumn2 : [] : null;
851
848
  tr.setMeta('layoutColumnDangerPreview', positions);
@@ -855,14 +852,14 @@ var setLayoutColumnDangerPreview = exports.setLayoutColumnDangerPreview = functi
855
852
  };
856
853
  };
857
854
  var deleteLayoutColumn = exports.deleteLayoutColumn = function deleteLayoutColumn() {
858
- var _ref18 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
859
- _ref18$inputMethod = _ref18.inputMethod,
860
- inputMethod = _ref18$inputMethod === void 0 ? _analytics.INPUT_METHOD.LAYOUT_COLUMN_MENU : _ref18$inputMethod;
855
+ var _ref17 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
856
+ _ref17$inputMethod = _ref17.inputMethod,
857
+ inputMethod = _ref17$inputMethod === void 0 ? _analytics.INPUT_METHOD.LAYOUT_COLUMN_MENU : _ref17$inputMethod;
861
858
  var editorAnalyticsAPI = arguments.length > 1 ? arguments[1] : undefined;
862
859
  var api = arguments.length > 2 ? arguments[2] : undefined;
863
- return function (_ref19) {
860
+ return function (_ref18) {
864
861
  var _api$blockControls4;
865
- var tr = _ref19.tr;
862
+ var tr = _ref18.tr;
866
863
  if (!(0, _expValEqualsNoExposure.expValEqualsNoExposure)('platform_editor_layout_column_menu', 'isEnabled', true)) {
867
864
  return null;
868
865
  }
@@ -875,8 +872,8 @@ var deleteLayoutColumn = exports.deleteLayoutColumn = function deleteLayoutColum
875
872
  selectedLayoutColumns = selectedLayoutColumnsResult.selectedLayoutColumns,
876
873
  startIndex = selectedLayoutColumnsResult.startIndex,
877
874
  endIndex = selectedLayoutColumnsResult.endIndex;
878
- var hadContent = selectedLayoutColumns.some(function (_ref20) {
879
- var node = _ref20.node;
875
+ var hadContent = selectedLayoutColumns.some(function (_ref19) {
876
+ var node = _ref19.node;
880
877
  return hasLayoutColumnContent(node);
881
878
  });
882
879
  var emitDeleteColumnAnalytics = function emitDeleteColumnAnalytics(newColumnCount) {
@@ -123,7 +123,10 @@ var reduceLayoutColumnMenuState = function reduceLayoutColumnMenuState(pluginSta
123
123
  anchorPos = _action$meta.anchorPos,
124
124
  isOpen = _action$meta.isOpen,
125
125
  openedViaKeyboard = _action$meta.openedViaKeyboard;
126
- var nextIsOpen = isOpen !== null && isOpen !== void 0 ? isOpen : !pluginState.isLayoutColumnMenuOpen;
126
+ // `isOpen` provided: use directly (legacy). Omitted: toggle off only when re-clicking
127
+ // the already-open column; otherwise open for the clicked column.
128
+ var isSameColumnAsOpenMenu = pluginState.isLayoutColumnMenuOpen && anchorPos !== undefined && anchorPos === pluginState.layoutColumnMenuAnchorPos;
129
+ var nextIsOpen = isOpen !== null && isOpen !== void 0 ? isOpen : !isSameColumnAsOpenMenu;
127
130
  return _objectSpread(_objectSpread({}, pluginState), {}, {
128
131
  isLayoutColumnMenuOpen: nextIsOpen,
129
132
  layoutColumnMenuOpenedViaKeyboard: nextIsOpen ? openedViaKeyboard !== null && openedViaKeyboard !== void 0 ? openedViaKeyboard : false : false,
@@ -146,6 +146,13 @@ var LayoutColumnMenu = exports.LayoutColumnMenu = /*#__PURE__*/_react.default.me
146
146
  closeLayoutColumnMenu();
147
147
  }
148
148
  }, [closeLayoutColumnMenu, components.length, hasValidTarget, isLayoutColumnMenuOpen]);
149
+ var _useMemo = (0, _react.useMemo)(function () {
150
+ return (0, _utils.getLayoutColumnMenuPositioningProps)();
151
+ }, []),
152
+ alignX = _useMemo.alignX,
153
+ alignY = _useMemo.alignY,
154
+ offset = _useMemo.offset,
155
+ useManualBelowFlip = _useMemo.useManualBelowFlip;
149
156
  if (!isLayoutColumnMenuOpen || components.length === 0 || !hasValidTarget) {
150
157
  return null;
151
158
  }
@@ -155,13 +162,13 @@ var LayoutColumnMenu = exports.LayoutColumnMenu = /*#__PURE__*/_react.default.me
155
162
  boundariesElement: boundariesElement,
156
163
  scrollableElement: scrollableElement,
157
164
  zIndex: _editorSharedStyles.akEditorFloatingOverlapPanelZIndex,
158
- alignX: "center",
159
- alignY: "top",
165
+ alignX: alignX,
166
+ alignY: alignY,
160
167
  forcePlacement: true,
161
168
  preventOverflow: true,
162
169
  stick: true,
163
- offset: _utils.LAYOUT_COLUMN_MENU_POPUP_OFFSET,
164
- onPositionCalculated: positionLayoutColumnMenu,
170
+ offset: offset,
171
+ onPositionCalculated: useManualBelowFlip ? positionLayoutColumnMenu : undefined,
165
172
  handleClickOutside: handleClickOutside,
166
173
  handleEscapeKeydown: closeLayoutColumnMenu,
167
174
  focusTrap: openedViaKeyboard ? focusTrap : undefined
@@ -4,12 +4,33 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
4
4
  Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
- exports.shouldOpenLayoutColumnMenuBelow = exports.calculateFallbackBottomPosition = exports.LAYOUT_COLUMN_MENU_POPUP_OFFSET = void 0;
7
+ exports.shouldOpenLayoutColumnMenuBelow = exports.getLayoutColumnMenuPositioningProps = exports.calculateFallbackBottomPosition = exports.LAYOUT_COLUMN_MENU_POPUP_OFFSET_BELOW = exports.LAYOUT_COLUMN_MENU_POPUP_OFFSET = void 0;
8
8
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
9
9
  var _ui = require("@atlaskit/editor-common/ui");
10
+ var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
10
11
  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; }
11
12
  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; }
12
13
  var LAYOUT_COLUMN_MENU_POPUP_OFFSET = exports.LAYOUT_COLUMN_MENU_POPUP_OFFSET = [0, 4];
14
+
15
+ // Gate OFF: small gap below the handle; Popup handles invert/nudge fallbacks.
16
+ var LAYOUT_COLUMN_MENU_POPUP_OFFSET_BELOW = exports.LAYOUT_COLUMN_MENU_POPUP_OFFSET_BELOW = [0, 2];
17
+ // Gate OFF: left-aligned, below the handle. Gate ON (legacy): centred, prefer above with manual flip.
18
+ var getLayoutColumnMenuPositioningProps = exports.getLayoutColumnMenuPositioningProps = function getLayoutColumnMenuPositioningProps() {
19
+ if (!(0, _platformFeatureFlags.fg)('platform_editor_layout_column_menu_kill_switch_1')) {
20
+ return {
21
+ alignX: undefined,
22
+ alignY: undefined,
23
+ offset: LAYOUT_COLUMN_MENU_POPUP_OFFSET_BELOW,
24
+ useManualBelowFlip: false
25
+ };
26
+ }
27
+ return {
28
+ alignX: 'center',
29
+ alignY: 'top',
30
+ offset: LAYOUT_COLUMN_MENU_POPUP_OFFSET,
31
+ useManualBelowFlip: true
32
+ };
33
+ };
13
34
  var getVisibleEditorAreaTop = function getVisibleEditorAreaTop(editorView, scrollableElement) {
14
35
  var visibleEditorArea = scrollableElement || (0, _ui.findOverflowScrollParent)(editorView.dom);
15
36
  return Math.max(visibleEditorArea ? visibleEditorArea.getBoundingClientRect().top : 0, 0);
@@ -22,8 +22,12 @@ var PLACEHOLDER_SELECTOR = '.ProseMirror-focused .layoutSectionView-content-wrap
22
22
  var layoutColumnDangerPreviewStyle = (0, _react2.css)({
23
23
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors -- Ignored via go/DSP-18766
24
24
  '.ProseMirror [data-layout-column].layout-column-danger-preview': {
25
- backgroundColor: "var(--ds-background-danger, #FFECEB)",
26
- boxShadow: "inset 0 0 0 2px ".concat("var(--ds-border-danger, #E2483D)")
25
+ backgroundColor: "var(--ds-blanket-danger, #EF5C4814)",
26
+ boxShadow: "inset 0 0 0 1px ".concat("var(--ds-border-danger, #E2483D)"),
27
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors -- Ignored via go/DSP-18766
28
+ '&::before': {
29
+ visibility: 'hidden'
30
+ }
27
31
  }
28
32
  });
29
33
  var getPlaceholderStyle = function getPlaceholderStyle(message) {
@@ -796,18 +796,14 @@ export const distributeLayoutColumns = (editorAnalyticsAPI, api) => ({
796
796
  mapLayoutColumnPreservedSelection(tr, api);
797
797
  return tr;
798
798
  };
799
- export const toggleLayoutColumnMenu = ({
800
- anchorPos,
801
- isOpen,
802
- openedViaKeyboard
803
- }) => ({
799
+
800
+ // Omitting `isOpen` (toggle) requires `anchorPos`, so a toggle can never open the menu
801
+ // without a valid anchor. Explicit open/close keeps `anchorPos` optional (close needs none).
802
+
803
+ export const toggleLayoutColumnMenu = options => ({
804
804
  tr
805
805
  }) => {
806
- tr.setMeta('toggleLayoutColumnMenu', {
807
- anchorPos,
808
- isOpen,
809
- openedViaKeyboard
810
- });
806
+ tr.setMeta('toggleLayoutColumnMenu', options);
811
807
  tr.setMeta('scrollIntoView', false);
812
808
  return tr;
813
809
  };
@@ -120,7 +120,10 @@ const reduceLayoutColumnMenuState = (pluginState, action) => {
120
120
  isOpen,
121
121
  openedViaKeyboard
122
122
  } = action.meta;
123
- const nextIsOpen = isOpen !== null && isOpen !== void 0 ? isOpen : !pluginState.isLayoutColumnMenuOpen;
123
+ // `isOpen` provided: use directly (legacy). Omitted: toggle off only when re-clicking
124
+ // the already-open column; otherwise open for the clicked column.
125
+ const isSameColumnAsOpenMenu = pluginState.isLayoutColumnMenuOpen && anchorPos !== undefined && anchorPos === pluginState.layoutColumnMenuAnchorPos;
126
+ const nextIsOpen = isOpen !== null && isOpen !== void 0 ? isOpen : !isSameColumnAsOpenMenu;
124
127
  return {
125
128
  ...pluginState,
126
129
  isLayoutColumnMenuOpen: nextIsOpen,
@@ -12,7 +12,7 @@ import { SurfaceRenderer } from '@atlaskit/editor-ui-control-model';
12
12
  import { getLayoutColumnMenuAnchorPos } from '../../pm-plugins/utils/layout-column-selection';
13
13
  import { LAYOUT_COLUMN_MENU_FALLBACKS } from './components';
14
14
  import { LAYOUT_COLUMN_MENU } from './keys';
15
- import { calculateFallbackBottomPosition, LAYOUT_COLUMN_MENU_POPUP_OFFSET, shouldOpenLayoutColumnMenuBelow } from './utils';
15
+ import { calculateFallbackBottomPosition, getLayoutColumnMenuPositioningProps, shouldOpenLayoutColumnMenuBelow } from './utils';
16
16
  const PopupWithListeners = withReactEditorViewOuterListeners(Popup);
17
17
  const TOOLBAR_MENU_SELECTOR = '[data-toolbar-component="menu"]';
18
18
  const NESTED_DROPDOWN_MENU_SELECTOR = '[data-toolbar-nested-dropdown-menu]';
@@ -138,6 +138,12 @@ export const LayoutColumnMenu = /*#__PURE__*/React.memo(function LayoutColumnMen
138
138
  closeLayoutColumnMenu();
139
139
  }
140
140
  }, [closeLayoutColumnMenu, components.length, hasValidTarget, isLayoutColumnMenuOpen]);
141
+ const {
142
+ alignX,
143
+ alignY,
144
+ offset,
145
+ useManualBelowFlip
146
+ } = useMemo(() => getLayoutColumnMenuPositioningProps(), []);
141
147
  if (!isLayoutColumnMenuOpen || components.length === 0 || !hasValidTarget) {
142
148
  return null;
143
149
  }
@@ -147,13 +153,13 @@ export const LayoutColumnMenu = /*#__PURE__*/React.memo(function LayoutColumnMen
147
153
  boundariesElement: boundariesElement,
148
154
  scrollableElement: scrollableElement,
149
155
  zIndex: akEditorFloatingOverlapPanelZIndex,
150
- alignX: "center",
151
- alignY: "top",
156
+ alignX: alignX,
157
+ alignY: alignY,
152
158
  forcePlacement: true,
153
159
  preventOverflow: true,
154
160
  stick: true,
155
- offset: LAYOUT_COLUMN_MENU_POPUP_OFFSET,
156
- onPositionCalculated: positionLayoutColumnMenu,
161
+ offset: offset,
162
+ onPositionCalculated: useManualBelowFlip ? positionLayoutColumnMenu : undefined,
157
163
  handleClickOutside: handleClickOutside,
158
164
  handleEscapeKeydown: closeLayoutColumnMenu,
159
165
  focusTrap: openedViaKeyboard ? focusTrap : undefined
@@ -1,5 +1,26 @@
1
1
  import { findOverflowScrollParent } from '@atlaskit/editor-common/ui';
2
+ import { fg } from '@atlaskit/platform-feature-flags';
2
3
  export const LAYOUT_COLUMN_MENU_POPUP_OFFSET = [0, 4];
4
+
5
+ // Gate OFF: small gap below the handle; Popup handles invert/nudge fallbacks.
6
+ export const LAYOUT_COLUMN_MENU_POPUP_OFFSET_BELOW = [0, 2];
7
+ // Gate OFF: left-aligned, below the handle. Gate ON (legacy): centred, prefer above with manual flip.
8
+ export const getLayoutColumnMenuPositioningProps = () => {
9
+ if (!fg('platform_editor_layout_column_menu_kill_switch_1')) {
10
+ return {
11
+ alignX: undefined,
12
+ alignY: undefined,
13
+ offset: LAYOUT_COLUMN_MENU_POPUP_OFFSET_BELOW,
14
+ useManualBelowFlip: false
15
+ };
16
+ }
17
+ return {
18
+ alignX: 'center',
19
+ alignY: 'top',
20
+ offset: LAYOUT_COLUMN_MENU_POPUP_OFFSET,
21
+ useManualBelowFlip: true
22
+ };
23
+ };
3
24
  const getVisibleEditorAreaTop = (editorView, scrollableElement) => {
4
25
  const visibleEditorArea = scrollableElement || findOverflowScrollParent(editorView.dom);
5
26
  return Math.max(visibleEditorArea ? visibleEditorArea.getBoundingClientRect().top : 0, 0);
@@ -5,7 +5,7 @@
5
5
  import { useMemo } from 'react';
6
6
 
7
7
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-global-styles, @atlaskit/ui-styling-standard/use-compiled, @typescript-eslint/consistent-type-imports
8
- import { css, Global, jsx } from '@emotion/react';
8
+ import { Global, css, jsx } from '@emotion/react';
9
9
  import { useIntl } from 'react-intl';
10
10
  import { layoutMessages as messages } from '@atlaskit/editor-common/messages';
11
11
  import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
@@ -13,8 +13,12 @@ const PLACEHOLDER_SELECTOR = '.ProseMirror-focused .layoutSectionView-content-wr
13
13
  const layoutColumnDangerPreviewStyle = css({
14
14
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors -- Ignored via go/DSP-18766
15
15
  '.ProseMirror [data-layout-column].layout-column-danger-preview': {
16
- backgroundColor: "var(--ds-background-danger, #FFECEB)",
17
- boxShadow: `inset 0 0 0 2px ${"var(--ds-border-danger, #E2483D)"}`
16
+ backgroundColor: "var(--ds-blanket-danger, #EF5C4814)",
17
+ boxShadow: `inset 0 0 0 1px ${"var(--ds-border-danger, #E2483D)"}`,
18
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors -- Ignored via go/DSP-18766
19
+ '&::before': {
20
+ visibility: 'hidden'
21
+ }
18
22
  }
19
23
  });
20
24
  const getPlaceholderStyle = message => {
@@ -814,28 +814,25 @@ export var distributeLayoutColumns = function distributeLayoutColumns(editorAnal
814
814
  };
815
815
  };
816
816
  };
817
- export var toggleLayoutColumnMenu = function toggleLayoutColumnMenu(_ref14) {
818
- var anchorPos = _ref14.anchorPos,
819
- isOpen = _ref14.isOpen,
820
- openedViaKeyboard = _ref14.openedViaKeyboard;
821
- return function (_ref15) {
822
- var tr = _ref15.tr;
823
- tr.setMeta('toggleLayoutColumnMenu', {
824
- anchorPos: anchorPos,
825
- isOpen: isOpen,
826
- openedViaKeyboard: openedViaKeyboard
827
- });
817
+
818
+ // Omitting `isOpen` (toggle) requires `anchorPos`, so a toggle can never open the menu
819
+ // without a valid anchor. Explicit open/close keeps `anchorPos` optional (close needs none).
820
+
821
+ export var toggleLayoutColumnMenu = function toggleLayoutColumnMenu(options) {
822
+ return function (_ref14) {
823
+ var tr = _ref14.tr;
824
+ tr.setMeta('toggleLayoutColumnMenu', options);
828
825
  tr.setMeta('scrollIntoView', false);
829
826
  return tr;
830
827
  };
831
828
  };
832
829
  export var setLayoutColumnDangerPreview = function setLayoutColumnDangerPreview(show) {
833
- return function (_ref16) {
830
+ return function (_ref15) {
834
831
  var _selectedLayoutColumn2;
835
- var tr = _ref16.tr;
832
+ var tr = _ref15.tr;
836
833
  var selectedLayoutColumnsResult = getSelectedLayoutColumnsFromSelection(tr.selection);
837
- var positions = show ? (_selectedLayoutColumn2 = selectedLayoutColumnsResult === null || selectedLayoutColumnsResult === void 0 ? void 0 : selectedLayoutColumnsResult.selectedLayoutColumns.map(function (_ref17) {
838
- var pos = _ref17.pos;
834
+ var positions = show ? (_selectedLayoutColumn2 = selectedLayoutColumnsResult === null || selectedLayoutColumnsResult === void 0 ? void 0 : selectedLayoutColumnsResult.selectedLayoutColumns.map(function (_ref16) {
835
+ var pos = _ref16.pos;
839
836
  return pos;
840
837
  })) !== null && _selectedLayoutColumn2 !== void 0 ? _selectedLayoutColumn2 : [] : null;
841
838
  tr.setMeta('layoutColumnDangerPreview', positions);
@@ -845,14 +842,14 @@ export var setLayoutColumnDangerPreview = function setLayoutColumnDangerPreview(
845
842
  };
846
843
  };
847
844
  export var deleteLayoutColumn = function deleteLayoutColumn() {
848
- var _ref18 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
849
- _ref18$inputMethod = _ref18.inputMethod,
850
- inputMethod = _ref18$inputMethod === void 0 ? INPUT_METHOD.LAYOUT_COLUMN_MENU : _ref18$inputMethod;
845
+ var _ref17 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
846
+ _ref17$inputMethod = _ref17.inputMethod,
847
+ inputMethod = _ref17$inputMethod === void 0 ? INPUT_METHOD.LAYOUT_COLUMN_MENU : _ref17$inputMethod;
851
848
  var editorAnalyticsAPI = arguments.length > 1 ? arguments[1] : undefined;
852
849
  var api = arguments.length > 2 ? arguments[2] : undefined;
853
- return function (_ref19) {
850
+ return function (_ref18) {
854
851
  var _api$blockControls4;
855
- var tr = _ref19.tr;
852
+ var tr = _ref18.tr;
856
853
  if (!expValEqualsNoExposure('platform_editor_layout_column_menu', 'isEnabled', true)) {
857
854
  return null;
858
855
  }
@@ -865,8 +862,8 @@ export var deleteLayoutColumn = function deleteLayoutColumn() {
865
862
  selectedLayoutColumns = selectedLayoutColumnsResult.selectedLayoutColumns,
866
863
  startIndex = selectedLayoutColumnsResult.startIndex,
867
864
  endIndex = selectedLayoutColumnsResult.endIndex;
868
- var hadContent = selectedLayoutColumns.some(function (_ref20) {
869
- var node = _ref20.node;
865
+ var hadContent = selectedLayoutColumns.some(function (_ref19) {
866
+ var node = _ref19.node;
870
867
  return hasLayoutColumnContent(node);
871
868
  });
872
869
  var emitDeleteColumnAnalytics = function emitDeleteColumnAnalytics(newColumnCount) {
@@ -116,7 +116,10 @@ var reduceLayoutColumnMenuState = function reduceLayoutColumnMenuState(pluginSta
116
116
  anchorPos = _action$meta.anchorPos,
117
117
  isOpen = _action$meta.isOpen,
118
118
  openedViaKeyboard = _action$meta.openedViaKeyboard;
119
- var nextIsOpen = isOpen !== null && isOpen !== void 0 ? isOpen : !pluginState.isLayoutColumnMenuOpen;
119
+ // `isOpen` provided: use directly (legacy). Omitted: toggle off only when re-clicking
120
+ // the already-open column; otherwise open for the clicked column.
121
+ var isSameColumnAsOpenMenu = pluginState.isLayoutColumnMenuOpen && anchorPos !== undefined && anchorPos === pluginState.layoutColumnMenuAnchorPos;
122
+ var nextIsOpen = isOpen !== null && isOpen !== void 0 ? isOpen : !isSameColumnAsOpenMenu;
120
123
  return _objectSpread(_objectSpread({}, pluginState), {}, {
121
124
  isLayoutColumnMenuOpen: nextIsOpen,
122
125
  layoutColumnMenuOpenedViaKeyboard: nextIsOpen ? openedViaKeyboard !== null && openedViaKeyboard !== void 0 ? openedViaKeyboard : false : false,
@@ -12,7 +12,7 @@ import { SurfaceRenderer } from '@atlaskit/editor-ui-control-model';
12
12
  import { getLayoutColumnMenuAnchorPos } from '../../pm-plugins/utils/layout-column-selection';
13
13
  import { LAYOUT_COLUMN_MENU_FALLBACKS } from './components';
14
14
  import { LAYOUT_COLUMN_MENU } from './keys';
15
- import { calculateFallbackBottomPosition, LAYOUT_COLUMN_MENU_POPUP_OFFSET, shouldOpenLayoutColumnMenuBelow } from './utils';
15
+ import { calculateFallbackBottomPosition, getLayoutColumnMenuPositioningProps, shouldOpenLayoutColumnMenuBelow } from './utils';
16
16
  var PopupWithListeners = withReactEditorViewOuterListeners(Popup);
17
17
  var TOOLBAR_MENU_SELECTOR = '[data-toolbar-component="menu"]';
18
18
  var NESTED_DROPDOWN_MENU_SELECTOR = '[data-toolbar-nested-dropdown-menu]';
@@ -138,6 +138,13 @@ export var LayoutColumnMenu = /*#__PURE__*/React.memo(function LayoutColumnMenu(
138
138
  closeLayoutColumnMenu();
139
139
  }
140
140
  }, [closeLayoutColumnMenu, components.length, hasValidTarget, isLayoutColumnMenuOpen]);
141
+ var _useMemo = useMemo(function () {
142
+ return getLayoutColumnMenuPositioningProps();
143
+ }, []),
144
+ alignX = _useMemo.alignX,
145
+ alignY = _useMemo.alignY,
146
+ offset = _useMemo.offset,
147
+ useManualBelowFlip = _useMemo.useManualBelowFlip;
141
148
  if (!isLayoutColumnMenuOpen || components.length === 0 || !hasValidTarget) {
142
149
  return null;
143
150
  }
@@ -147,13 +154,13 @@ export var LayoutColumnMenu = /*#__PURE__*/React.memo(function LayoutColumnMenu(
147
154
  boundariesElement: boundariesElement,
148
155
  scrollableElement: scrollableElement,
149
156
  zIndex: akEditorFloatingOverlapPanelZIndex,
150
- alignX: "center",
151
- alignY: "top",
157
+ alignX: alignX,
158
+ alignY: alignY,
152
159
  forcePlacement: true,
153
160
  preventOverflow: true,
154
161
  stick: true,
155
- offset: LAYOUT_COLUMN_MENU_POPUP_OFFSET,
156
- onPositionCalculated: positionLayoutColumnMenu,
162
+ offset: offset,
163
+ onPositionCalculated: useManualBelowFlip ? positionLayoutColumnMenu : undefined,
157
164
  handleClickOutside: handleClickOutside,
158
165
  handleEscapeKeydown: closeLayoutColumnMenu,
159
166
  focusTrap: openedViaKeyboard ? focusTrap : undefined
@@ -2,7 +2,28 @@ 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 { findOverflowScrollParent } from '@atlaskit/editor-common/ui';
5
+ import { fg } from '@atlaskit/platform-feature-flags';
5
6
  export var LAYOUT_COLUMN_MENU_POPUP_OFFSET = [0, 4];
7
+
8
+ // Gate OFF: small gap below the handle; Popup handles invert/nudge fallbacks.
9
+ export var LAYOUT_COLUMN_MENU_POPUP_OFFSET_BELOW = [0, 2];
10
+ // Gate OFF: left-aligned, below the handle. Gate ON (legacy): centred, prefer above with manual flip.
11
+ export var getLayoutColumnMenuPositioningProps = function getLayoutColumnMenuPositioningProps() {
12
+ if (!fg('platform_editor_layout_column_menu_kill_switch_1')) {
13
+ return {
14
+ alignX: undefined,
15
+ alignY: undefined,
16
+ offset: LAYOUT_COLUMN_MENU_POPUP_OFFSET_BELOW,
17
+ useManualBelowFlip: false
18
+ };
19
+ }
20
+ return {
21
+ alignX: 'center',
22
+ alignY: 'top',
23
+ offset: LAYOUT_COLUMN_MENU_POPUP_OFFSET,
24
+ useManualBelowFlip: true
25
+ };
26
+ };
6
27
  var getVisibleEditorAreaTop = function getVisibleEditorAreaTop(editorView, scrollableElement) {
7
28
  var visibleEditorArea = scrollableElement || findOverflowScrollParent(editorView.dom);
8
29
  return Math.max(visibleEditorArea ? visibleEditorArea.getBoundingClientRect().top : 0, 0);
@@ -6,7 +6,7 @@ import _defineProperty from "@babel/runtime/helpers/defineProperty";
6
6
  import { useMemo } from 'react';
7
7
 
8
8
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-global-styles, @atlaskit/ui-styling-standard/use-compiled, @typescript-eslint/consistent-type-imports
9
- import { css, Global, jsx } from '@emotion/react';
9
+ import { Global, css, jsx } from '@emotion/react';
10
10
  import { useIntl } from 'react-intl';
11
11
  import { layoutMessages as messages } from '@atlaskit/editor-common/messages';
12
12
  import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
@@ -14,8 +14,12 @@ var PLACEHOLDER_SELECTOR = '.ProseMirror-focused .layoutSectionView-content-wrap
14
14
  var layoutColumnDangerPreviewStyle = css({
15
15
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors -- Ignored via go/DSP-18766
16
16
  '.ProseMirror [data-layout-column].layout-column-danger-preview': {
17
- backgroundColor: "var(--ds-background-danger, #FFECEB)",
18
- boxShadow: "inset 0 0 0 2px ".concat("var(--ds-border-danger, #E2483D)")
17
+ backgroundColor: "var(--ds-blanket-danger, #EF5C4814)",
18
+ boxShadow: "inset 0 0 0 1px ".concat("var(--ds-border-danger, #E2483D)"),
19
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors -- Ignored via go/DSP-18766
20
+ '&::before': {
21
+ visibility: 'hidden'
22
+ }
19
23
  }
20
24
  });
21
25
  var getPlaceholderStyle = function getPlaceholderStyle(message) {
@@ -58,11 +58,15 @@ export type DistributeLayoutColumnsOptions = {
58
58
  };
59
59
  export declare const distributeLayoutColumns: (editorAnalyticsAPI?: EditorAnalyticsAPI, api?: LayoutPluginAPI) => ({ inputMethod, target, }?: DistributeLayoutColumnsOptions) => EditorCommand;
60
60
  export type ToggleLayoutColumnMenuOptions = {
61
+ anchorPos: number;
62
+ isOpen?: undefined;
63
+ openedViaKeyboard?: boolean;
64
+ } | {
61
65
  anchorPos?: number;
62
- isOpen?: boolean;
66
+ isOpen: boolean;
63
67
  openedViaKeyboard?: boolean;
64
68
  };
65
- export declare const toggleLayoutColumnMenu: ({ anchorPos, isOpen, openedViaKeyboard }: ToggleLayoutColumnMenuOptions) => EditorCommand;
69
+ export declare const toggleLayoutColumnMenu: (options: ToggleLayoutColumnMenuOptions) => EditorCommand;
66
70
  export declare const setLayoutColumnDangerPreview: (show: boolean) => EditorCommand;
67
71
  export type DeleteLayoutColumnOptions = {
68
72
  inputMethod?: LayoutColumnActionInputMethod;
@@ -1,6 +1,14 @@
1
1
  import { type PopupPosition } from '@atlaskit/editor-common/ui';
2
2
  import type { EditorView } from '@atlaskit/editor-prosemirror/view';
3
3
  export declare const LAYOUT_COLUMN_MENU_POPUP_OFFSET: [number, number];
4
+ export declare const LAYOUT_COLUMN_MENU_POPUP_OFFSET_BELOW: [number, number];
5
+ type LayoutColumnMenuPositioningProps = {
6
+ alignX: 'center' | undefined;
7
+ alignY: 'top' | undefined;
8
+ offset: [number, number];
9
+ useManualBelowFlip: boolean;
10
+ };
11
+ export declare const getLayoutColumnMenuPositioningProps: () => LayoutColumnMenuPositioningProps;
4
12
  export declare const shouldOpenLayoutColumnMenuBelow: ({ editorView, popup, scrollableElement, target, }: {
5
13
  editorView: EditorView;
6
14
  popup: HTMLElement;
@@ -8,3 +16,4 @@ export declare const shouldOpenLayoutColumnMenuBelow: ({ editorView, popup, scro
8
16
  target: HTMLElement;
9
17
  }) => boolean;
10
18
  export declare const calculateFallbackBottomPosition: (position: PopupPosition, target: HTMLElement, popup: HTMLElement) => PopupPosition;
19
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-layout",
3
- "version": "13.1.0",
3
+ "version": "13.2.1",
4
4
  "description": "Layout plugin for @atlaskit/editor-core",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -24,7 +24,7 @@
24
24
  "@atlaskit/adf-schema": "^56.0.0",
25
25
  "@atlaskit/css": "^1.0.0",
26
26
  "@atlaskit/editor-plugin-analytics": "^12.0.0",
27
- "@atlaskit/editor-plugin-block-controls": "^13.0.0",
27
+ "@atlaskit/editor-plugin-block-controls": "^13.1.0",
28
28
  "@atlaskit/editor-plugin-block-menu": "^11.1.0",
29
29
  "@atlaskit/editor-plugin-decorations": "^12.0.0",
30
30
  "@atlaskit/editor-plugin-editor-disabled": "^12.0.0",
@@ -42,14 +42,14 @@
42
42
  "@atlaskit/icon": "^36.0.0",
43
43
  "@atlaskit/icon-lab": "^7.1.0",
44
44
  "@atlaskit/platform-feature-flags": "^2.0.0",
45
- "@atlaskit/tmp-editor-statsig": "^110.0.0",
45
+ "@atlaskit/tmp-editor-statsig": "^112.0.0",
46
46
  "@atlaskit/tokens": "^15.0.0",
47
47
  "@babel/runtime": "^7.0.0",
48
48
  "@emotion/react": "^11.7.1",
49
49
  "bind-event-listener": "^3.0.0"
50
50
  },
51
51
  "peerDependencies": {
52
- "@atlaskit/editor-common": "^116.11.0",
52
+ "@atlaskit/editor-common": "^116.12.0",
53
53
  "react": "^18.2.0",
54
54
  "react-intl": "^5.25.1 || ^6.0.0 || ^7.0.0"
55
55
  },
@@ -109,6 +109,9 @@
109
109
  },
110
110
  "platform_editor_layout_resize_analytics": {
111
111
  "type": "boolean"
112
+ },
113
+ "platform_editor_layout_column_menu_kill_switch_1": {
114
+ "type": "boolean"
112
115
  }
113
116
  },
114
117
  "devDependencies": {