@atlaskit/editor-plugin-layout 10.8.0 → 10.9.0

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 (48) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/dist/cjs/layoutPlugin.js +2 -5
  3. package/dist/cjs/pm-plugins/actions.js +91 -82
  4. package/dist/cjs/pm-plugins/utils/{redistribute-proportionally.js → layout-column-distribution.js} +39 -3
  5. package/dist/cjs/pm-plugins/utils/layout-column-selection.js +56 -98
  6. package/dist/cjs/ui/LayoutColumnMenu/DeleteColumnDropdownItem.js +1 -1
  7. package/dist/cjs/ui/LayoutColumnMenu/DistributeColumnsDropdownItem.js +14 -19
  8. package/dist/cjs/ui/LayoutColumnMenu/InsertColumnDropdownItem.js +2 -2
  9. package/dist/cjs/ui/LayoutColumnMenu/VerticalAlignDropdownItem.js +1 -1
  10. package/dist/cjs/ui/LayoutColumnMenu/VerticalAlignNestedMenu.js +1 -1
  11. package/dist/cjs/ui/LayoutColumnMenu/index.js +1 -1
  12. package/dist/cjs/ui/LayoutColumnMenu/useSelectedLayoutColumns.js +4 -3
  13. package/dist/cjs/ui/toolbar.js +70 -11
  14. package/dist/es2019/layoutPlugin.js +3 -6
  15. package/dist/es2019/pm-plugins/actions.js +74 -63
  16. package/dist/es2019/pm-plugins/utils/{redistribute-proportionally.js → layout-column-distribution.js} +34 -1
  17. package/dist/es2019/pm-plugins/utils/layout-column-selection.js +54 -94
  18. package/dist/es2019/ui/LayoutColumnMenu/DeleteColumnDropdownItem.js +1 -1
  19. package/dist/es2019/ui/LayoutColumnMenu/DistributeColumnsDropdownItem.js +15 -15
  20. package/dist/es2019/ui/LayoutColumnMenu/InsertColumnDropdownItem.js +2 -2
  21. package/dist/es2019/ui/LayoutColumnMenu/VerticalAlignDropdownItem.js +1 -1
  22. package/dist/es2019/ui/LayoutColumnMenu/VerticalAlignNestedMenu.js +1 -1
  23. package/dist/es2019/ui/LayoutColumnMenu/index.js +1 -1
  24. package/dist/es2019/ui/LayoutColumnMenu/useSelectedLayoutColumns.js +6 -4
  25. package/dist/es2019/ui/toolbar.js +68 -11
  26. package/dist/esm/layoutPlugin.js +3 -6
  27. package/dist/esm/pm-plugins/actions.js +89 -80
  28. package/dist/esm/pm-plugins/utils/{redistribute-proportionally.js → layout-column-distribution.js} +37 -3
  29. package/dist/esm/pm-plugins/utils/layout-column-selection.js +55 -97
  30. package/dist/esm/ui/LayoutColumnMenu/DeleteColumnDropdownItem.js +1 -1
  31. package/dist/esm/ui/LayoutColumnMenu/DistributeColumnsDropdownItem.js +14 -19
  32. package/dist/esm/ui/LayoutColumnMenu/InsertColumnDropdownItem.js +2 -2
  33. package/dist/esm/ui/LayoutColumnMenu/VerticalAlignDropdownItem.js +1 -1
  34. package/dist/esm/ui/LayoutColumnMenu/VerticalAlignNestedMenu.js +1 -1
  35. package/dist/esm/ui/LayoutColumnMenu/index.js +1 -1
  36. package/dist/esm/ui/LayoutColumnMenu/useSelectedLayoutColumns.js +5 -4
  37. package/dist/esm/ui/toolbar.js +71 -12
  38. package/dist/types/layoutPluginType.d.ts +2 -2
  39. package/dist/types/pm-plugins/actions.d.ts +12 -2
  40. package/dist/types/pm-plugins/utils/layout-column-distribution.d.ts +16 -0
  41. package/dist/types/pm-plugins/utils/layout-column-selection.d.ts +8 -7
  42. package/dist/types-ts4.5/layoutPluginType.d.ts +2 -2
  43. package/dist/types-ts4.5/pm-plugins/actions.d.ts +12 -2
  44. package/dist/types-ts4.5/pm-plugins/utils/layout-column-distribution.d.ts +16 -0
  45. package/dist/types-ts4.5/pm-plugins/utils/layout-column-selection.d.ts +8 -7
  46. package/package.json +5 -5
  47. package/dist/types/pm-plugins/utils/redistribute-proportionally.d.ts +0 -2
  48. package/dist/types-ts4.5/pm-plugins/utils/redistribute-proportionally.d.ts +0 -2
package/CHANGELOG.md CHANGED
@@ -1,5 +1,24 @@
1
1
  # @atlaskit/editor-plugin-layout
2
2
 
3
+ ## 10.9.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [`10c5beb57bb0d`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/10c5beb57bb0d) -
8
+ [ux] Add Distribute columns to the layout floating toolbar
9
+
10
+ ### Patch Changes
11
+
12
+ - Updated dependencies
13
+
14
+ ## 10.8.1
15
+
16
+ ### Patch Changes
17
+
18
+ - [`2ad681c18e86f`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/2ad681c18e86f) -
19
+ Add layout column menu actions for inserting, deleting, distributing, and aligning columns.
20
+ - Updated dependencies
21
+
3
22
  ## 10.8.0
4
23
 
5
24
  ### Minor Changes
@@ -57,7 +57,7 @@ var selectIntoLayoutSection = exports.selectIntoLayoutSection = function selectI
57
57
  return tr;
58
58
  };
59
59
  var layoutPlugin = exports.layoutPlugin = function layoutPlugin(_ref) {
60
- var _api$analytics;
60
+ var _api$analytics, _api$analytics5;
61
61
  var _ref$config = _ref.config,
62
62
  options = _ref$config === void 0 ? {} : _ref$config,
63
63
  api = _ref.api;
@@ -381,10 +381,7 @@ var layoutPlugin = exports.layoutPlugin = function layoutPlugin(_ref) {
381
381
  var _api$analytics4;
382
382
  return (0, _actions.deleteLayoutColumn)(api === null || api === void 0 || (_api$analytics4 = api.analytics) === null || _api$analytics4 === void 0 ? void 0 : _api$analytics4.actions)(props);
383
383
  },
384
- distributeLayoutColumns: function distributeLayoutColumns(props) {
385
- var _api$analytics5;
386
- return (0, _actions.distributeLayoutColumns)(api === null || api === void 0 || (_api$analytics5 = api.analytics) === null || _api$analytics5 === void 0 ? void 0 : _api$analytics5.actions)(props);
387
- },
384
+ distributeLayoutColumns: (0, _actions.createDistributeLayoutColumnsCommand)(api === null || api === void 0 || (_api$analytics5 = api.analytics) === null || _api$analytics5 === void 0 ? void 0 : _api$analytics5.actions),
388
385
  insertLayoutColumn: function insertLayoutColumn(side) {
389
386
  var _api$analytics6;
390
387
  return (0, _actions.insertLayoutColumn)(side, api === null || api === void 0 || (_api$analytics6 = api.analytics) === null || _api$analytics6 === void 0 ? void 0 : _api$analytics6.actions);
@@ -4,7 +4,7 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
4
4
  Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
- exports.fixColumnStructure = exports.fixColumnSizes = exports.distributeLayoutColumns = exports.deleteLayoutColumn = exports.deleteActiveLayoutNode = exports.createMultiColumnLayoutSection = exports.createDefaultLayoutSection = exports.TWO_COL_LAYOUTS = exports.THREE_COL_LAYOUTS = exports.ONE_COL_LAYOUTS = void 0;
7
+ exports.fixColumnStructure = exports.fixColumnSizes = exports.distributeLayoutColumns = exports.deleteLayoutColumn = exports.deleteActiveLayoutNode = exports.createMultiColumnLayoutSection = exports.createDistributeLayoutColumnsCommand = exports.createDefaultLayoutSection = exports.TWO_COL_LAYOUTS = exports.THREE_COL_LAYOUTS = exports.ONE_COL_LAYOUTS = void 0;
8
8
  exports.forceSectionToPresetLayout = forceSectionToPresetLayout;
9
9
  exports.getEffectiveMaxLayoutColumns = getEffectiveMaxLayoutColumns;
10
10
  exports.toggleLayoutColumnMenu = exports.setPresetLayout = exports.setLayoutColumnValign = exports.insertLayoutColumnsWithAnalytics = exports.insertLayoutColumns = exports.insertLayoutColumn = exports.getSelectedLayout = exports.getPresetLayout = void 0;
@@ -20,8 +20,8 @@ var _expValEqualsNoExposure = require("@atlaskit/tmp-editor-statsig/exp-val-equa
20
20
  var _experiments = require("@atlaskit/tmp-editor-statsig/experiments");
21
21
  var _consts = require("./consts");
22
22
  var _pluginKey = require("./plugin-key");
23
+ var _layoutColumnDistribution = require("./utils/layout-column-distribution");
23
24
  var _layoutColumnSelection = require("./utils/layout-column-selection");
24
- var _redistributeProportionally = require("./utils/redistribute-proportionally");
25
25
  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; }
26
26
  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; }
27
27
  var ONE_COL_LAYOUTS = exports.ONE_COL_LAYOUTS = ['single'];
@@ -564,18 +564,17 @@ var insertLayoutColumnAt = function insertLayoutColumnAt(side, editorAnalyticsAP
564
564
  if (!(0, _expValEqualsNoExposure.expValEqualsNoExposure)('platform_editor_layout_column_menu', 'isEnabled', true)) {
565
565
  return null;
566
566
  }
567
- var selectedLayoutColumns = (0, _layoutColumnSelection.getSelectedLayoutColumns)(tr.selection);
568
- if (!selectedLayoutColumns) {
567
+ var selectedLayoutColumnsResult = (0, _layoutColumnSelection.getSelectedLayoutColumnsFromSelection)(tr.selection);
568
+ if (!selectedLayoutColumnsResult || selectedLayoutColumnsResult.selectedLayoutColumns.length === 0) {
569
569
  return null;
570
570
  }
571
- var layoutSectionNode = selectedLayoutColumns.layoutSectionNode,
572
- layoutSectionPos = selectedLayoutColumns.layoutSectionPos,
573
- selectedColumnIndices = selectedLayoutColumns.selectedColumnIndices,
574
- selectedColumns = selectedLayoutColumns.selectedColumns;
575
- var startIndex = selectedColumnIndices[0];
576
- var endIndex = selectedColumnIndices[selectedColumnIndices.length - 1];
571
+ var layoutSectionNode = selectedLayoutColumnsResult.layoutSectionNode,
572
+ layoutSectionPos = selectedLayoutColumnsResult.layoutSectionPos,
573
+ startIndex = selectedLayoutColumnsResult.startIndex,
574
+ endIndex = selectedLayoutColumnsResult.endIndex,
575
+ selectedLayoutColumns = selectedLayoutColumnsResult.selectedLayoutColumns;
577
576
  var selectedColumnIndex = side === 'left' ? startIndex : endIndex;
578
- var selectedColumnCount = selectedColumns.length;
577
+ var selectedColumnCount = selectedLayoutColumns.length;
579
578
  if (layoutSectionNode.childCount >= getEffectiveMaxLayoutColumns()) {
580
579
  return null;
581
580
  }
@@ -583,7 +582,7 @@ var insertLayoutColumnAt = function insertLayoutColumnAt(side, editorAnalyticsAP
583
582
  var existingWidths = (0, _utils.mapChildren)(layoutSectionNode, function (column) {
584
583
  return column.attrs.width;
585
584
  });
586
- var redistributedWidths = (0, _redistributeProportionally.redistributeProportionally)(existingWidths, insertIndex, getEffectiveMaxLayoutColumns(), _consts.MIN_LAYOUT_COLUMN_WIDTH_PERCENT);
585
+ var redistributedWidths = (0, _layoutColumnDistribution.redistributeProportionally)(existingWidths, insertIndex, getEffectiveMaxLayoutColumns(), _consts.MIN_LAYOUT_COLUMN_WIDTH_PERCENT);
587
586
  if (redistributedWidths === existingWidths) {
588
587
  return null;
589
588
  }
@@ -633,22 +632,20 @@ var setLayoutColumnValign = exports.setLayoutColumnValign = function setLayoutCo
633
632
  if (!(0, _expValEqualsNoExposure.expValEqualsNoExposure)('platform_editor_layout_column_menu', 'isEnabled', true)) {
634
633
  return null;
635
634
  }
636
- var selectedLayoutColumns = (0, _layoutColumnSelection.getSelectedLayoutColumns)(tr.selection);
637
- if (!selectedLayoutColumns) {
635
+ var selectedLayoutColumnsResult = (0, _layoutColumnSelection.getSelectedLayoutColumnsFromSelection)(tr.selection);
636
+ if (!selectedLayoutColumnsResult) {
638
637
  return null;
639
638
  }
640
- var selectedColumnIndices = selectedLayoutColumns.selectedColumnIndices,
641
- selectedColumns = selectedLayoutColumns.selectedColumns;
642
- var columnsToUpdate = selectedColumns.filter(function (_ref6) {
639
+ var startIndex = selectedLayoutColumnsResult.startIndex,
640
+ endIndex = selectedLayoutColumnsResult.endIndex,
641
+ selectedLayoutColumns = selectedLayoutColumnsResult.selectedLayoutColumns;
642
+ var columnsToUpdate = selectedLayoutColumns.filter(function (_ref6) {
643
643
  var node = _ref6.node;
644
644
  return node.attrs.valign !== valign;
645
645
  });
646
646
  if (columnsToUpdate.length === 0) {
647
647
  return null;
648
648
  }
649
- var startIndex = selectedColumnIndices[0];
650
- var endIndex = selectedColumnIndices[selectedColumnIndices.length - 1];
651
- var selectedColumnCount = selectedColumns.length;
652
649
  var updatedColumnCount = columnsToUpdate.length;
653
650
  columnsToUpdate.forEach(function (_ref7) {
654
651
  var node = _ref7.node,
@@ -664,7 +661,7 @@ var setLayoutColumnValign = exports.setLayoutColumnValign = function setLayoutCo
664
661
  attributes: {
665
662
  endIndex: endIndex,
666
663
  inputMethod: _analytics.INPUT_METHOD.LAYOUT_COLUMN_MENU,
667
- selectedCount: selectedColumnCount,
664
+ selectedCount: selectedLayoutColumns.length,
668
665
  startIndex: startIndex,
669
666
  updatedCount: updatedColumnCount,
670
667
  valign: valign
@@ -675,73 +672,80 @@ var setLayoutColumnValign = exports.setLayoutColumnValign = function setLayoutCo
675
672
  return tr;
676
673
  };
677
674
  };
678
- var distributeLayoutColumns = exports.distributeLayoutColumns = function distributeLayoutColumns(editorAnalyticsAPI) {
679
- var inputMethod = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _analytics.INPUT_METHOD.LAYOUT_COLUMN_MENU;
680
- return function (_ref8) {
681
- var tr = _ref8.tr;
675
+ var distributeLayoutColumns = exports.distributeLayoutColumns = function distributeLayoutColumns() {
676
+ var _ref8 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
677
+ editorAnalyticsAPI = _ref8.editorAnalyticsAPI,
678
+ _ref8$inputMethod = _ref8.inputMethod,
679
+ inputMethod = _ref8$inputMethod === void 0 ? _analytics.INPUT_METHOD.LAYOUT_COLUMN_MENU : _ref8$inputMethod,
680
+ _ref8$target = _ref8.target,
681
+ target = _ref8$target === void 0 ? 'selectedColumns' : _ref8$target;
682
+ return function (_ref9) {
683
+ var tr = _ref9.tr;
682
684
  if (!(0, _expValEqualsNoExposure.expValEqualsNoExposure)('platform_editor_layout_column_menu', 'isEnabled', true)) {
683
685
  return null;
684
686
  }
685
- var selectedLayoutColumns = (0, _layoutColumnSelection.getSelectedLayoutColumns)(tr.selection);
686
- if (!selectedLayoutColumns || selectedLayoutColumns.selectedColumns.length < 2) {
687
+ var selectedLayoutColumnsResult = target === 'allColumns' ? (0, _layoutColumnSelection.getAllLayoutColumnsFromSelection)(tr.selection) : (0, _layoutColumnSelection.getSelectedLayoutColumnsFromSelection)(tr.selection);
688
+ if (!selectedLayoutColumnsResult || selectedLayoutColumnsResult.selectedLayoutColumns.length < 2) {
687
689
  return null;
688
690
  }
689
- var layoutSectionNode = selectedLayoutColumns.layoutSectionNode,
690
- layoutSectionPos = selectedLayoutColumns.layoutSectionPos,
691
- selectedColumnIndices = selectedLayoutColumns.selectedColumnIndices,
692
- selectedColumns = selectedLayoutColumns.selectedColumns;
693
- var endIndex = selectedColumnIndices[selectedColumnIndices.length - 1];
694
- var selectedColumnCount = selectedColumns.length;
695
- var totalColumnCount = layoutSectionNode.childCount;
696
-
697
- // Compute equal width for selected columns
691
+ var layoutSectionNode = selectedLayoutColumnsResult.layoutSectionNode,
692
+ startIndex = selectedLayoutColumnsResult.startIndex,
693
+ endIndex = selectedLayoutColumnsResult.endIndex,
694
+ selectedLayoutColumns = selectedLayoutColumnsResult.selectedLayoutColumns;
698
695
  var existingWidths = (0, _utils.mapChildren)(layoutSectionNode, function (column) {
699
696
  return column.attrs.width;
700
697
  });
701
- var selectedTotal = selectedColumnIndices.reduce(function (sum, idx) {
702
- return sum + existingWidths[idx];
703
- }, 0);
704
- var equalWidth = selectedTotal / selectedColumnCount;
705
-
706
- // Early return if selected columns are already uniformly distributed — avoids spurious undo entry.
707
- if (selectedColumnIndices.every(function (idx) {
708
- return existingWidths[idx] === Number(equalWidth.toFixed(2));
709
- })) {
698
+ var selectedWidths = selectedLayoutColumns.map(function (_ref0) {
699
+ var node = _ref0.node;
700
+ return node.attrs.width;
701
+ });
702
+ var distribution = (0, _layoutColumnDistribution.calculateDistribution)(selectedWidths);
703
+ if (!distribution) {
704
+ return null;
705
+ }
706
+ var selectedTotal = distribution.selectedTotal,
707
+ equalWidth = distribution.equalWidth;
708
+ if ((0, _layoutColumnDistribution.isDistributedUniformly)(selectedWidths, distribution)) {
710
709
  return null;
711
710
  }
712
711
 
713
712
  // Build new widths array: selected columns get equal share, unselected unchanged.
714
- // Assign truncated (2dp) equal widths to all selected cols except the last, which absorbs
713
+ // Assign rounded (2dp) equal widths to all selected cols except the last, which absorbs
715
714
  // the rounding remainder so the sum of selected widths equals selectedTotal exactly.
716
- var selectedIndexSet = new Set(selectedColumnIndices);
717
715
  var assignedToSelected = 0;
718
716
  var selectedAssignedCount = 0;
719
717
  var newWidths = existingWidths.map(function (w, idx) {
720
- if (!selectedIndexSet.has(idx)) {
718
+ if (idx < startIndex || idx > endIndex) {
721
719
  return w;
722
720
  }
723
721
  selectedAssignedCount += 1;
724
- if (selectedAssignedCount < selectedColumnCount) {
725
- var truncated = Number(equalWidth.toFixed(2));
726
- assignedToSelected += truncated;
727
- return truncated;
722
+ if (selectedAssignedCount < selectedLayoutColumns.length) {
723
+ assignedToSelected += equalWidth;
724
+ return equalWidth;
728
725
  }
729
726
  // Last selected column: absorb the remainder to avoid drift
730
727
  return Number((selectedTotal - assignedToSelected).toFixed(2));
731
728
  });
732
729
 
733
- // Apply widths via replaceWith (mirroring forceColumnWidths approach)
734
- tr.replaceWith(layoutSectionPos + 1, layoutSectionPos + layoutSectionNode.nodeSize - 1, columnWidth(layoutSectionNode, tr.doc.type.schema, newWidths));
730
+ // Apply widths via setNodeMarkup per selected column — keeps nodes in place (preserves identity, marks, decorations)
731
+ selectedLayoutColumns.forEach(function (_ref1, i) {
732
+ var node = _ref1.node,
733
+ pos = _ref1.pos;
734
+ var colIdx = startIndex + i;
735
+ tr.setNodeMarkup(pos, node.type, _objectSpread(_objectSpread({}, node.attrs), {}, {
736
+ width: newWidths[colIdx]
737
+ }));
738
+ });
735
739
  editorAnalyticsAPI === null || editorAnalyticsAPI === void 0 || editorAnalyticsAPI.attachAnalyticsEvent({
736
740
  action: _analytics.ACTION.UPDATED,
737
741
  actionSubject: _analytics.ACTION_SUBJECT.DOCUMENT,
738
742
  actionSubjectId: _analytics.ACTION_SUBJECT_ID.LAYOUT_COLUMN,
739
743
  attributes: {
740
- columnCount: totalColumnCount,
744
+ columnCount: layoutSectionNode.childCount,
741
745
  endIndex: endIndex,
742
746
  inputMethod: inputMethod,
743
- selectedCount: selectedColumnCount,
744
- startIndex: selectedColumnIndices[0]
747
+ selectedCount: selectedLayoutColumns.length,
748
+ startIndex: startIndex
745
749
  },
746
750
  eventType: _analytics.EVENT_TYPE.TRACK
747
751
  })(tr);
@@ -749,11 +753,19 @@ var distributeLayoutColumns = exports.distributeLayoutColumns = function distrib
749
753
  return tr;
750
754
  };
751
755
  };
752
- var toggleLayoutColumnMenu = exports.toggleLayoutColumnMenu = function toggleLayoutColumnMenu(_ref9) {
753
- var anchorPos = _ref9.anchorPos,
754
- isOpen = _ref9.isOpen;
755
- return function (_ref0) {
756
- var tr = _ref0.tr;
756
+ var createDistributeLayoutColumnsCommand = exports.createDistributeLayoutColumnsCommand = function createDistributeLayoutColumnsCommand(editorAnalyticsAPI) {
757
+ return function () {
758
+ var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
759
+ return distributeLayoutColumns(_objectSpread(_objectSpread({}, options), {}, {
760
+ editorAnalyticsAPI: editorAnalyticsAPI
761
+ }));
762
+ };
763
+ };
764
+ var toggleLayoutColumnMenu = exports.toggleLayoutColumnMenu = function toggleLayoutColumnMenu(_ref10) {
765
+ var anchorPos = _ref10.anchorPos,
766
+ isOpen = _ref10.isOpen;
767
+ return function (_ref11) {
768
+ var tr = _ref11.tr;
757
769
  tr.setMeta('toggleLayoutColumnMenu', {
758
770
  anchorPos: anchorPos,
759
771
  isOpen: isOpen
@@ -763,23 +775,20 @@ var toggleLayoutColumnMenu = exports.toggleLayoutColumnMenu = function toggleLay
763
775
  };
764
776
  };
765
777
  var deleteLayoutColumn = exports.deleteLayoutColumn = function deleteLayoutColumn(editorAnalyticsAPI) {
766
- return function (_ref1) {
767
- var tr = _ref1.tr;
778
+ return function (_ref12) {
779
+ var tr = _ref12.tr;
768
780
  if (!(0, _expValEqualsNoExposure.expValEqualsNoExposure)('platform_editor_layout_column_menu', 'isEnabled', true)) {
769
781
  return null;
770
782
  }
771
- var selectedLayoutColumns = (0, _layoutColumnSelection.getSelectedLayoutColumns)(tr.selection);
772
- if (!selectedLayoutColumns) {
783
+ var selectedLayoutColumnsResult = (0, _layoutColumnSelection.getSelectedLayoutColumnsFromSelection)(tr.selection);
784
+ if (!selectedLayoutColumnsResult || selectedLayoutColumnsResult.selectedLayoutColumns.length === 0) {
773
785
  return null;
774
786
  }
775
- var layoutSectionNode = selectedLayoutColumns.layoutSectionNode,
776
- layoutSectionPos = selectedLayoutColumns.layoutSectionPos,
777
- selectedColumnIndices = selectedLayoutColumns.selectedColumnIndices,
778
- selectedColumns = selectedLayoutColumns.selectedColumns;
779
- var startIndex = selectedColumnIndices[0];
780
- var endIndex = selectedColumnIndices[selectedColumnIndices.length - 1];
781
- var selectedColumnCount = selectedColumns.length;
782
- var selectedColumnIndexSet = new Set(selectedColumnIndices);
787
+ var layoutSectionNode = selectedLayoutColumnsResult.layoutSectionNode,
788
+ layoutSectionPos = selectedLayoutColumnsResult.layoutSectionPos,
789
+ selectedLayoutColumns = selectedLayoutColumnsResult.selectedLayoutColumns,
790
+ startIndex = selectedLayoutColumnsResult.startIndex,
791
+ endIndex = selectedLayoutColumnsResult.endIndex;
783
792
  var emitDeleteColumnAnalytics = function emitDeleteColumnAnalytics(columnCount) {
784
793
  editorAnalyticsAPI === null || editorAnalyticsAPI === void 0 || editorAnalyticsAPI.attachAnalyticsEvent({
785
794
  action: _analytics.ACTION.DELETED,
@@ -789,7 +798,7 @@ var deleteLayoutColumn = exports.deleteLayoutColumn = function deleteLayoutColum
789
798
  columnCount: columnCount,
790
799
  endIndex: endIndex,
791
800
  inputMethod: _analytics.INPUT_METHOD.LAYOUT_COLUMN_MENU,
792
- selectedCount: selectedColumnCount,
801
+ selectedCount: selectedLayoutColumns.length,
793
802
  startIndex: startIndex
794
803
  },
795
804
  eventType: _analytics.EVENT_TYPE.TRACK
@@ -797,7 +806,7 @@ var deleteLayoutColumn = exports.deleteLayoutColumn = function deleteLayoutColum
797
806
  };
798
807
 
799
808
  // If all columns are selected, remove the entire layoutSection
800
- if (selectedColumnCount === layoutSectionNode.childCount) {
809
+ if (selectedLayoutColumns.length === layoutSectionNode.childCount) {
801
810
  tr.delete(layoutSectionPos, layoutSectionPos + layoutSectionNode.nodeSize);
802
811
  emitDeleteColumnAnalytics(0);
803
812
  tr.setMeta('scrollIntoView', false);
@@ -807,7 +816,7 @@ var deleteLayoutColumn = exports.deleteLayoutColumn = function deleteLayoutColum
807
816
  // Build new column list without the selected columns
808
817
  var remainingColumns = [];
809
818
  layoutSectionNode.forEach(function (column, _offset, index) {
810
- if (!selectedColumnIndexSet.has(index)) {
819
+ if (index < startIndex || index > endIndex) {
811
820
  remainingColumns.push(column);
812
821
  }
813
822
  });
@@ -816,13 +825,13 @@ var deleteLayoutColumn = exports.deleteLayoutColumn = function deleteLayoutColum
816
825
  var existingWidths = (0, _utils.mapChildren)(layoutSectionNode, function (column) {
817
826
  return column.attrs.width;
818
827
  });
819
- var redistributed = selectedColumnIndices.slice()
828
+ var redistributed = selectedLayoutColumns.map(function (_, i) {
829
+ return startIndex + i;
830
+ })
820
831
  // Delete highest indices first so lower original indices still point at the same columns
821
832
  // as each redistribution step shrinks the widths array.
822
- .sort(function (a, b) {
823
- return b - a;
824
- }).reduce(function (widths, selectedIndex) {
825
- return (0, _redistributeProportionally.redistributeAfterDeletion)(widths, selectedIndex, _consts.MIN_LAYOUT_COLUMN_WIDTH_PERCENT);
833
+ .reverse().reduce(function (widths, selectedIndex) {
834
+ return (0, _layoutColumnDistribution.redistributeAfterDeletion)(widths, selectedIndex, _consts.MIN_LAYOUT_COLUMN_WIDTH_PERCENT);
826
835
  }, existingWidths);
827
836
  var updatedLayoutSectionNode = layoutSectionNode.copy(_model.Fragment.fromArray(remainingColumns));
828
837
  tr.replaceWith(layoutSectionPos + 1, layoutSectionPos + layoutSectionNode.nodeSize - 1, columnWidth(updatedLayoutSectionNode, tr.doc.type.schema, redistributed));
@@ -4,6 +4,8 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
4
4
  Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
+ exports.calculateDistribution = void 0;
8
+ exports.isDistributedUniformly = isDistributedUniformly;
7
9
  exports.redistributeProportionally = exports.redistributeAfterDeletion = void 0;
8
10
  var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
9
11
  var roundLayoutColumnWidth = function roundLayoutColumnWidth(width) {
@@ -14,9 +16,6 @@ var sumWidths = function sumWidths(widths) {
14
16
  return sum + width;
15
17
  }, 0);
16
18
  };
17
- var isValidWidth = function isValidWidth(width) {
18
- return Number.isFinite(width) && width > 0;
19
- };
20
19
  var normaliseWidthsTotal = function normaliseWidthsTotal(widths, totalWidth, minWidth) {
21
20
  var roundedWidths = widths.map(roundLayoutColumnWidth);
22
21
  var remainder = roundLayoutColumnWidth(totalWidth - sumWidths(roundedWidths));
@@ -37,6 +36,9 @@ var normaliseWidthsTotal = function normaliseWidthsTotal(widths, totalWidth, min
37
36
  return index === adjustmentIndex ? adjustedWidth : width;
38
37
  });
39
38
  };
39
+ var isValidWidth = function isValidWidth(width) {
40
+ return Number.isFinite(width) && width > 0;
41
+ };
40
42
  var redistributeWithMinimumWidth = function redistributeWithMinimumWidth(_ref) {
41
43
  var minWidth = _ref.minWidth,
42
44
  totalWidth = _ref.totalWidth,
@@ -81,6 +83,40 @@ var redistributeWithMinimumWidth = function redistributeWithMinimumWidth(_ref) {
81
83
  });
82
84
  return widths;
83
85
  };
86
+
87
+ /**
88
+ * Returns true when the given selected columns already reflect the distribution that
89
+ * `distributeLayoutColumns` would produce — i.e. the first N-1 cols each hold
90
+ * `equalWidth` (rounded to 2 dp) and the last col absorbs the rounding remainder.
91
+ *
92
+ * This mirrors the action's "last col absorbs remainder" logic so that the UI can
93
+ * disable the option when it would be a no-op, avoiding spurious undo entries.
94
+ */
95
+
96
+ var calculateDistribution = exports.calculateDistribution = function calculateDistribution(selectedWidths) {
97
+ var count = selectedWidths.length;
98
+ if (count < 2) {
99
+ return undefined;
100
+ }
101
+ var selectedTotal = sumWidths(selectedWidths);
102
+ var equalWidth = roundLayoutColumnWidth(selectedTotal / count);
103
+ return {
104
+ selectedTotal: selectedTotal,
105
+ equalWidth: equalWidth
106
+ };
107
+ };
108
+ function isDistributedUniformly(selectedWidths) {
109
+ var distribution = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : calculateDistribution(selectedWidths);
110
+ if (!distribution || selectedWidths.length < 2) {
111
+ return false;
112
+ }
113
+ var selectedTotal = distribution.selectedTotal,
114
+ equalWidth = distribution.equalWidth;
115
+ var lastColWidth = roundLayoutColumnWidth(selectedTotal - equalWidth * (selectedWidths.length - 1));
116
+ return selectedWidths.slice(0, -1).every(function (width) {
117
+ return width === equalWidth;
118
+ }) && selectedWidths[selectedWidths.length - 1] === lastColWidth;
119
+ }
84
120
  var redistributeAfterDeletion = exports.redistributeAfterDeletion = function redistributeAfterDeletion(currentWidths, removeIndex, minWidth) {
85
121
  if (currentWidths.length === 0 || removeIndex < 0 || removeIndex >= currentWidths.length || !isValidWidth(minWidth)) {
86
122
  return currentWidths;
@@ -3,127 +3,85 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.getSelectedLayoutColumns = exports.getLayoutSectionColumnCount = exports.getLayoutColumnValign = exports.getLayoutColumnMenuAnchorPos = void 0;
7
- var _state = require("@atlaskit/editor-prosemirror/state");
8
- var _experiments = require("@atlaskit/tmp-editor-statsig/experiments");
9
- var isLayoutColumn = function isLayoutColumn(node) {
10
- return (node === null || node === void 0 ? void 0 : node.type.name) === 'layoutColumn';
6
+ exports.getSelectedLayoutColumnsFromSelection = exports.getLayoutColumnValign = exports.getLayoutColumnMenuAnchorPos = exports.getAllLayoutColumnsFromSelection = void 0;
7
+ var _utils = require("@atlaskit/editor-prosemirror/utils");
8
+ var findLayoutSectionFromSelection = function findLayoutSectionFromSelection(selection) {
9
+ return (0, _utils.findParentNodeOfType)(selection.$from.doc.type.schema.nodes.layoutSection)(selection);
11
10
  };
12
- var isLayoutSection = function isLayoutSection(node) {
13
- return (node === null || node === void 0 ? void 0 : node.type.name) === 'layoutSection';
14
- };
15
- var getLayoutColumnIndexAtPos = function getLayoutColumnIndexAtPos($pos) {
16
- for (var depth = $pos.depth; depth > 0; depth--) {
17
- if (isLayoutColumn($pos.node(depth)) && isLayoutSection($pos.node(depth - 1))) {
18
- return $pos.index(depth - 1);
19
- }
20
- }
21
- return undefined;
22
- };
23
- var getLayoutSectionDepth = function getLayoutSectionDepth(selection) {
24
- var $from = selection.$from,
25
- $to = selection.$to;
26
- var sharedDepth = $from.sharedDepth($to.pos);
27
- for (var depth = sharedDepth; depth > 0; depth--) {
28
- if (isLayoutSection($from.node(depth))) {
29
- return depth;
30
- }
31
- }
32
- return undefined;
33
- };
34
- var getSelectedLayoutColumns = exports.getSelectedLayoutColumns = function getSelectedLayoutColumns(selection) {
35
- if (!selection) {
36
- return undefined;
37
- }
38
- if (selection instanceof _state.NodeSelection && isLayoutColumn(selection.node)) {
39
- var _$from = selection.$from;
40
- var _layoutSectionNode = _$from.parent;
41
- if (!isLayoutSection(_layoutSectionNode)) {
42
- return undefined;
43
- }
44
- var selectedColumnIndex = _$from.index(_$from.depth);
11
+ var findLayoutColumnsFromLayoutSection = function findLayoutColumnsFromLayoutSection(layoutSectionNode) {
12
+ var layoutSectionPos = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
13
+ return (0, _utils.findChildrenByType)(layoutSectionNode, layoutSectionNode.type.schema.nodes.layoutColumn).map(function (_ref) {
14
+ var node = _ref.node,
15
+ pos = _ref.pos;
45
16
  return {
46
- layoutSectionNode: _layoutSectionNode,
47
- layoutSectionPos: _$from.before(_$from.depth),
48
- selectedColumnIndices: [selectedColumnIndex],
49
- selectedColumns: [{
50
- index: selectedColumnIndex,
51
- node: selection.node,
52
- pos: selection.from
53
- }]
17
+ node: node,
18
+ pos: pos + layoutSectionPos + 1
54
19
  };
55
- }
56
- if (selection.empty) {
57
- return undefined;
58
- }
59
- if (!(0, _experiments.editorExperiment)('platform_editor_block_menu', true)) {
20
+ });
21
+ };
22
+ var getSelectedLayoutColumnsFromSelection = exports.getSelectedLayoutColumnsFromSelection = function getSelectedLayoutColumnsFromSelection(selection) {
23
+ var layoutSection = findLayoutSectionFromSelection(selection);
24
+ if (!layoutSection) {
60
25
  return undefined;
61
26
  }
62
- var layoutSectionDepth = getLayoutSectionDepth(selection);
63
- if (layoutSectionDepth === undefined) {
27
+ var layoutSectionNode = layoutSection.node,
28
+ layoutSectionPos = layoutSection.pos;
29
+ var allLayoutColumns = findLayoutColumnsFromLayoutSection(layoutSectionNode, layoutSectionPos);
30
+ if (!allLayoutColumns.length) {
64
31
  return undefined;
65
32
  }
66
- var $from = selection.$from,
67
- $to = selection.$to;
68
- var layoutSectionNode = $from.node(layoutSectionDepth);
69
- var layoutSectionPos = $from.before(layoutSectionDepth);
70
- var selectedColumns = [];
71
- var invalidSelection = false;
72
- layoutSectionNode.forEach(function (column, offset, index) {
73
- var columnStart = layoutSectionPos + 1 + offset;
74
- var columnEnd = columnStart + column.nodeSize;
75
- var intersectsColumn = selection.from < columnEnd && selection.to > columnStart;
76
- if (!intersectsColumn) {
77
- return;
78
- }
79
- if (!isLayoutColumn(column)) {
80
- invalidSelection = true;
81
- return;
33
+ var startIndex = -1;
34
+ var endIndex = -1;
35
+ var selectedLayoutColumns = allLayoutColumns.filter(function (_ref2, index) {
36
+ var node = _ref2.node,
37
+ pos = _ref2.pos;
38
+ var isSelected = selection.from <= pos && selection.to >= pos + node.nodeSize;
39
+ if (isSelected) {
40
+ if (startIndex === -1) {
41
+ startIndex = index;
42
+ }
43
+ endIndex = index;
82
44
  }
83
- selectedColumns.push({
84
- index: index,
85
- node: column,
86
- pos: columnStart
87
- });
45
+ return isSelected;
88
46
  });
89
-
90
- // TextSelection inside a single column is normal text editing, not a selected column set.
91
- if (invalidSelection || selectedColumns.length < 2) {
47
+ return {
48
+ layoutSectionNode: layoutSectionNode,
49
+ layoutSectionPos: layoutSectionPos,
50
+ selectedLayoutColumns: selectedLayoutColumns,
51
+ startIndex: startIndex,
52
+ endIndex: endIndex
53
+ };
54
+ };
55
+ var getAllLayoutColumnsFromSelection = exports.getAllLayoutColumnsFromSelection = function getAllLayoutColumnsFromSelection(selection) {
56
+ var layoutSection = findLayoutSectionFromSelection(selection);
57
+ if (!layoutSection) {
92
58
  return undefined;
93
59
  }
94
- var firstColumn = selectedColumns[0];
95
- var lastColumn = selectedColumns[selectedColumns.length - 1];
96
- var startColumnIndex = getLayoutColumnIndexAtPos($from);
97
- var endColumnIndex = getLayoutColumnIndexAtPos($to);
98
- if (startColumnIndex !== undefined && startColumnIndex !== firstColumn.index || endColumnIndex !== undefined && endColumnIndex !== lastColumn.index) {
60
+ var layoutColumns = findLayoutColumnsFromLayoutSection(layoutSection.node, layoutSection.pos);
61
+ if (!(layoutColumns !== null && layoutColumns !== void 0 && layoutColumns.length)) {
99
62
  return undefined;
100
63
  }
101
64
  return {
102
- layoutSectionNode: layoutSectionNode,
103
- layoutSectionPos: layoutSectionPos,
104
- selectedColumnIndices: selectedColumns.map(function (_ref) {
105
- var index = _ref.index;
106
- return index;
107
- }),
108
- selectedColumns: selectedColumns
65
+ layoutSectionNode: layoutSection.node,
66
+ layoutSectionPos: layoutSection.pos,
67
+ selectedLayoutColumns: layoutColumns,
68
+ startIndex: 0,
69
+ endIndex: layoutColumns.length - 1
109
70
  };
110
71
  };
111
- var getLayoutSectionColumnCount = exports.getLayoutSectionColumnCount = function getLayoutSectionColumnCount(layoutSection) {
112
- return (layoutSection === null || layoutSection === void 0 ? void 0 : layoutSection.type.name) === 'layoutSection' ? layoutSection.childCount : 0;
113
- };
114
72
  var getLayoutColumnValign = exports.getLayoutColumnValign = function getLayoutColumnValign(layoutColumn) {
115
- var _ref2;
116
- return layoutColumn ? (_ref2 = layoutColumn.attrs.valign) !== null && _ref2 !== void 0 ? _ref2 : 'top' : undefined;
73
+ var _ref3;
74
+ return layoutColumn ? (_ref3 = layoutColumn.attrs.valign) !== null && _ref3 !== void 0 ? _ref3 : 'top' : undefined;
117
75
  };
118
76
  var getLayoutColumnMenuAnchorPos = exports.getLayoutColumnMenuAnchorPos = function getLayoutColumnMenuAnchorPos(selection, anchorPosFromHandle) {
119
77
  var _clickedSelectedColum, _selectedLayoutColumn;
120
- var selectedLayoutColumns = getSelectedLayoutColumns(selection);
78
+ var selectedLayoutColumns = getSelectedLayoutColumnsFromSelection(selection);
121
79
  if (!selectedLayoutColumns) {
122
80
  return undefined;
123
81
  }
124
- var clickedSelectedColumn = selectedLayoutColumns.selectedColumns.find(function (_ref3) {
125
- var pos = _ref3.pos;
82
+ var clickedSelectedColumn = selectedLayoutColumns.selectedLayoutColumns.find(function (_ref4) {
83
+ var pos = _ref4.pos;
126
84
  return pos === anchorPosFromHandle;
127
85
  });
128
- return (_clickedSelectedColum = clickedSelectedColumn === null || clickedSelectedColumn === void 0 ? void 0 : clickedSelectedColumn.pos) !== null && _clickedSelectedColum !== void 0 ? _clickedSelectedColum : (_selectedLayoutColumn = selectedLayoutColumns.selectedColumns[0]) === null || _selectedLayoutColumn === void 0 ? void 0 : _selectedLayoutColumn.pos;
86
+ return (_clickedSelectedColum = clickedSelectedColumn === null || clickedSelectedColumn === void 0 ? void 0 : clickedSelectedColumn.pos) !== null && _clickedSelectedColum !== void 0 ? _clickedSelectedColum : (_selectedLayoutColumn = selectedLayoutColumns.selectedLayoutColumns[0]) === null || _selectedLayoutColumn === void 0 ? void 0 : _selectedLayoutColumn.pos;
129
87
  };
@@ -36,7 +36,7 @@ var DeleteColumnDropdownItem = exports.DeleteColumnDropdownItem = function Delet
36
36
  if (selectedLayoutColumns === undefined) {
37
37
  return null;
38
38
  }
39
- var selectedColumnCount = selectedLayoutColumns.selectedColumns.length;
39
+ var selectedColumnCount = selectedLayoutColumns.selectedLayoutColumns.length;
40
40
  return /*#__PURE__*/_react.default.createElement(_editorToolbar.ToolbarDropdownItem, {
41
41
  onClick: onClick
42
42
  }, formatMessage(_messages.layoutMessages.deleteColumn, {