@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
@@ -1,121 +1,81 @@
1
- import { NodeSelection } from '@atlaskit/editor-prosemirror/state';
2
- import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
3
- const isLayoutColumn = node => (node === null || node === void 0 ? void 0 : node.type.name) === 'layoutColumn';
4
- const isLayoutSection = node => (node === null || node === void 0 ? void 0 : node.type.name) === 'layoutSection';
5
- const getLayoutColumnIndexAtPos = $pos => {
6
- for (let depth = $pos.depth; depth > 0; depth--) {
7
- if (isLayoutColumn($pos.node(depth)) && isLayoutSection($pos.node(depth - 1))) {
8
- return $pos.index(depth - 1);
9
- }
10
- }
11
- return undefined;
1
+ import { findChildrenByType, findParentNodeOfType } from '@atlaskit/editor-prosemirror/utils';
2
+ const findLayoutSectionFromSelection = selection => {
3
+ return findParentNodeOfType(selection.$from.doc.type.schema.nodes.layoutSection)(selection);
12
4
  };
13
- const getLayoutSectionDepth = selection => {
14
- const {
15
- $from,
16
- $to
17
- } = selection;
18
- const sharedDepth = $from.sharedDepth($to.pos);
19
- for (let depth = sharedDepth; depth > 0; depth--) {
20
- if (isLayoutSection($from.node(depth))) {
21
- return depth;
22
- }
23
- }
24
- return undefined;
5
+ const findLayoutColumnsFromLayoutSection = (layoutSectionNode, layoutSectionPos = 0) => {
6
+ return findChildrenByType(layoutSectionNode, layoutSectionNode.type.schema.nodes.layoutColumn).map(({
7
+ node,
8
+ pos
9
+ }) => ({
10
+ node,
11
+ pos: pos + layoutSectionPos + 1
12
+ }));
25
13
  };
26
- export const getSelectedLayoutColumns = selection => {
27
- if (!selection) {
28
- return undefined;
29
- }
30
- if (selection instanceof NodeSelection && isLayoutColumn(selection.node)) {
31
- const {
32
- $from
33
- } = selection;
34
- const layoutSectionNode = $from.parent;
35
- if (!isLayoutSection(layoutSectionNode)) {
36
- return undefined;
37
- }
38
- const selectedColumnIndex = $from.index($from.depth);
39
- return {
40
- layoutSectionNode,
41
- layoutSectionPos: $from.before($from.depth),
42
- selectedColumnIndices: [selectedColumnIndex],
43
- selectedColumns: [{
44
- index: selectedColumnIndex,
45
- node: selection.node,
46
- pos: selection.from
47
- }]
48
- };
49
- }
50
- if (selection.empty) {
51
- return undefined;
52
- }
53
- if (!editorExperiment('platform_editor_block_menu', true)) {
14
+ export const getSelectedLayoutColumnsFromSelection = selection => {
15
+ const layoutSection = findLayoutSectionFromSelection(selection);
16
+ if (!layoutSection) {
54
17
  return undefined;
55
18
  }
56
- const layoutSectionDepth = getLayoutSectionDepth(selection);
57
- if (layoutSectionDepth === undefined) {
19
+ const {
20
+ node: layoutSectionNode,
21
+ pos: layoutSectionPos
22
+ } = layoutSection;
23
+ const allLayoutColumns = findLayoutColumnsFromLayoutSection(layoutSectionNode, layoutSectionPos);
24
+ if (!allLayoutColumns.length) {
58
25
  return undefined;
59
26
  }
60
- const {
61
- $from,
62
- $to
63
- } = selection;
64
- const layoutSectionNode = $from.node(layoutSectionDepth);
65
- const layoutSectionPos = $from.before(layoutSectionDepth);
66
- const selectedColumns = [];
67
- let invalidSelection = false;
68
- layoutSectionNode.forEach((column, offset, index) => {
69
- const columnStart = layoutSectionPos + 1 + offset;
70
- const columnEnd = columnStart + column.nodeSize;
71
- const intersectsColumn = selection.from < columnEnd && selection.to > columnStart;
72
- if (!intersectsColumn) {
73
- return;
74
- }
75
- if (!isLayoutColumn(column)) {
76
- invalidSelection = true;
77
- return;
27
+ let startIndex = -1;
28
+ let endIndex = -1;
29
+ const selectedLayoutColumns = allLayoutColumns.filter(({
30
+ node,
31
+ pos
32
+ }, index) => {
33
+ const isSelected = selection.from <= pos && selection.to >= pos + node.nodeSize;
34
+ if (isSelected) {
35
+ if (startIndex === -1) {
36
+ startIndex = index;
37
+ }
38
+ endIndex = index;
78
39
  }
79
- selectedColumns.push({
80
- index,
81
- node: column,
82
- pos: columnStart
83
- });
40
+ return isSelected;
84
41
  });
85
-
86
- // TextSelection inside a single column is normal text editing, not a selected column set.
87
- if (invalidSelection || selectedColumns.length < 2) {
42
+ return {
43
+ layoutSectionNode,
44
+ layoutSectionPos,
45
+ selectedLayoutColumns,
46
+ startIndex,
47
+ endIndex
48
+ };
49
+ };
50
+ export const getAllLayoutColumnsFromSelection = selection => {
51
+ const layoutSection = findLayoutSectionFromSelection(selection);
52
+ if (!layoutSection) {
88
53
  return undefined;
89
54
  }
90
- const firstColumn = selectedColumns[0];
91
- const lastColumn = selectedColumns[selectedColumns.length - 1];
92
- const startColumnIndex = getLayoutColumnIndexAtPos($from);
93
- const endColumnIndex = getLayoutColumnIndexAtPos($to);
94
- if (startColumnIndex !== undefined && startColumnIndex !== firstColumn.index || endColumnIndex !== undefined && endColumnIndex !== lastColumn.index) {
55
+ const layoutColumns = findLayoutColumnsFromLayoutSection(layoutSection.node, layoutSection.pos);
56
+ if (!(layoutColumns !== null && layoutColumns !== void 0 && layoutColumns.length)) {
95
57
  return undefined;
96
58
  }
97
59
  return {
98
- layoutSectionNode,
99
- layoutSectionPos,
100
- selectedColumnIndices: selectedColumns.map(({
101
- index
102
- }) => index),
103
- selectedColumns
60
+ layoutSectionNode: layoutSection.node,
61
+ layoutSectionPos: layoutSection.pos,
62
+ selectedLayoutColumns: layoutColumns,
63
+ startIndex: 0,
64
+ endIndex: layoutColumns.length - 1
104
65
  };
105
66
  };
106
- export const getLayoutSectionColumnCount = layoutSection => (layoutSection === null || layoutSection === void 0 ? void 0 : layoutSection.type.name) === 'layoutSection' ? layoutSection.childCount : 0;
107
67
  export const getLayoutColumnValign = layoutColumn => {
108
68
  var _ref;
109
69
  return layoutColumn ? (_ref = layoutColumn.attrs.valign) !== null && _ref !== void 0 ? _ref : 'top' : undefined;
110
70
  };
111
71
  export const getLayoutColumnMenuAnchorPos = (selection, anchorPosFromHandle) => {
112
72
  var _clickedSelectedColum, _selectedLayoutColumn;
113
- const selectedLayoutColumns = getSelectedLayoutColumns(selection);
73
+ const selectedLayoutColumns = getSelectedLayoutColumnsFromSelection(selection);
114
74
  if (!selectedLayoutColumns) {
115
75
  return undefined;
116
76
  }
117
- const clickedSelectedColumn = selectedLayoutColumns.selectedColumns.find(({
77
+ const clickedSelectedColumn = selectedLayoutColumns.selectedLayoutColumns.find(({
118
78
  pos
119
79
  }) => pos === anchorPosFromHandle);
120
- 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;
80
+ 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;
121
81
  };
@@ -30,7 +30,7 @@ const DeleteColumnDropdownItem = ({
30
30
  if (selectedLayoutColumns === undefined) {
31
31
  return null;
32
32
  }
33
- const selectedColumnCount = selectedLayoutColumns.selectedColumns.length;
33
+ const selectedColumnCount = selectedLayoutColumns.selectedLayoutColumns.length;
34
34
  return /*#__PURE__*/React.createElement(ToolbarDropdownItem, {
35
35
  onClick: onClick
36
36
  }, formatMessage(layoutMessages.deleteColumn, {
@@ -1,7 +1,9 @@
1
1
  import React, { useCallback, useMemo } from 'react';
2
2
  import { useIntl } from 'react-intl';
3
+ import { INPUT_METHOD } from '@atlaskit/editor-common/analytics';
3
4
  import { layoutMessages } from '@atlaskit/editor-common/messages';
4
5
  import { ToolbarDropdownItem } from '@atlaskit/editor-toolbar';
6
+ import { isDistributedUniformly } from '../../pm-plugins/utils/layout-column-distribution';
5
7
  import { useSelectedLayoutColumns } from './useSelectedLayoutColumns';
6
8
  export const DistributeColumnsDropdownItem = ({
7
9
  api
@@ -9,12 +11,17 @@ export const DistributeColumnsDropdownItem = ({
9
11
  const {
10
12
  formatMessage
11
13
  } = useIntl();
12
- const selectedLayoutColumns = useSelectedLayoutColumns(api);
14
+ const selectedLayoutColumnsResult = useSelectedLayoutColumns(api);
15
+ const {
16
+ selectedLayoutColumns
17
+ } = selectedLayoutColumnsResult !== null && selectedLayoutColumnsResult !== void 0 ? selectedLayoutColumnsResult : {};
13
18
  const handleClick = useCallback(() => {
14
19
  var _api$core;
15
20
  api === null || api === void 0 ? void 0 : (_api$core = api.core) === null || _api$core === void 0 ? void 0 : _api$core.actions.execute(props => {
16
21
  var _api$layout, _api$layout2;
17
- const tr = api === null || api === void 0 ? void 0 : (_api$layout = api.layout) === null || _api$layout === void 0 ? void 0 : _api$layout.commands.distributeLayoutColumns(props);
22
+ const tr = api === null || api === void 0 ? void 0 : (_api$layout = api.layout) === null || _api$layout === void 0 ? void 0 : _api$layout.commands.distributeLayoutColumns({
23
+ inputMethod: INPUT_METHOD.LAYOUT_COLUMN_MENU
24
+ })(props);
18
25
  if (!tr) {
19
26
  return null;
20
27
  }
@@ -26,25 +33,18 @@ export const DistributeColumnsDropdownItem = ({
26
33
  return closedTr !== null && closedTr !== void 0 ? closedTr : tr;
27
34
  });
28
35
  }, [api]);
29
-
30
- // Hide when selected columns are already evenly distributed — no-op action.
31
- // Must be before any early return to satisfy rules-of-hooks.
32
36
  const isAlreadyUniform = useMemo(() => {
33
- if (!selectedLayoutColumns || selectedLayoutColumns.selectedColumns.length < 2) {
37
+ if (!selectedLayoutColumns || selectedLayoutColumns.length < 2) {
34
38
  return false;
35
39
  }
36
- const selectedWidths = selectedLayoutColumns.selectedColumns.map(col => col.node.attrs.width);
37
- const selectedTotal = selectedWidths.reduce((sum, w) => sum + w, 0);
38
- const equalWidth = Number((selectedTotal / selectedWidths.length).toFixed(2));
39
- return selectedWidths.every(w => w === equalWidth);
40
+ const selectedWidths = selectedLayoutColumns.map(col => col.node.attrs.width);
41
+ return isDistributedUniformly(selectedWidths);
40
42
  }, [selectedLayoutColumns]);
41
- if (selectedLayoutColumns === undefined || selectedLayoutColumns.selectedColumns.length < 2) {
42
- return null;
43
- }
44
- if (isAlreadyUniform) {
43
+ if (selectedLayoutColumns === undefined || selectedLayoutColumns.length < 2) {
45
44
  return null;
46
45
  }
47
46
  return /*#__PURE__*/React.createElement(ToolbarDropdownItem, {
48
- onClick: handleClick
47
+ onClick: handleClick,
48
+ isDisabled: isAlreadyUniform
49
49
  }, formatMessage(layoutMessages.distributeColumns));
50
50
  };
@@ -3,7 +3,6 @@ import { useIntl } from 'react-intl';
3
3
  import { layoutMessages } from '@atlaskit/editor-common/messages';
4
4
  import { TableColumnAddLeftIcon, TableColumnAddRightIcon, ToolbarDropdownItem } from '@atlaskit/editor-toolbar';
5
5
  import { getEffectiveMaxLayoutColumns } from '../../pm-plugins/actions';
6
- import { getLayoutSectionColumnCount } from '../../pm-plugins/utils/layout-column-selection';
7
6
  import { useSelectedLayoutColumns } from './useSelectedLayoutColumns';
8
7
  const INSERT_COLUMN_OPTIONS = {
9
8
  left: {
@@ -21,6 +20,7 @@ export const InsertColumnDropdownItem = ({
21
20
  api,
22
21
  side
23
22
  }) => {
23
+ var _selectedLayoutColumn, _selectedLayoutColumn2;
24
24
  const {
25
25
  formatMessage
26
26
  } = useIntl();
@@ -29,7 +29,7 @@ export const InsertColumnDropdownItem = ({
29
29
  label
30
30
  } = INSERT_COLUMN_OPTIONS[side];
31
31
  const selectedLayoutColumns = useSelectedLayoutColumns(api);
32
- const columnCount = getLayoutSectionColumnCount(selectedLayoutColumns === null || selectedLayoutColumns === void 0 ? void 0 : selectedLayoutColumns.layoutSectionNode);
32
+ const columnCount = (_selectedLayoutColumn = selectedLayoutColumns === null || selectedLayoutColumns === void 0 ? void 0 : (_selectedLayoutColumn2 = selectedLayoutColumns.layoutSectionNode) === null || _selectedLayoutColumn2 === void 0 ? void 0 : _selectedLayoutColumn2.childCount) !== null && _selectedLayoutColumn !== void 0 ? _selectedLayoutColumn : 0;
33
33
  const maxColumnCount = getEffectiveMaxLayoutColumns();
34
34
  const canInsertColumn = selectedLayoutColumns !== undefined && columnCount < maxColumnCount;
35
35
  const onClick = useCallback(() => {
@@ -14,7 +14,7 @@ export const VerticalAlignDropdownItem = ({
14
14
  formatMessage
15
15
  } = useIntl();
16
16
  const selectedLayoutColumns = useSelectedLayoutColumns(api);
17
- const isSelected = (_selectedLayoutColumn = selectedLayoutColumns === null || selectedLayoutColumns === void 0 ? void 0 : selectedLayoutColumns.selectedColumns.every(({
17
+ const isSelected = (_selectedLayoutColumn = selectedLayoutColumns === null || selectedLayoutColumns === void 0 ? void 0 : selectedLayoutColumns.selectedLayoutColumns.every(({
18
18
  node
19
19
  }) => getLayoutColumnValign(node) === value)) !== null && _selectedLayoutColumn !== void 0 ? _selectedLayoutColumn : false;
20
20
  const Icon = VERTICAL_ALIGN_ICONS[value];
@@ -14,7 +14,7 @@ export const VerticalAlignNestedMenu = ({
14
14
  } = useIntl();
15
15
  const selectedLayoutColumns = useSelectedLayoutColumns(api);
16
16
  const currentValign = useMemo(() => {
17
- const selectedColumns = selectedLayoutColumns === null || selectedLayoutColumns === void 0 ? void 0 : selectedLayoutColumns.selectedColumns;
17
+ const selectedColumns = selectedLayoutColumns === null || selectedLayoutColumns === void 0 ? void 0 : selectedLayoutColumns.selectedLayoutColumns;
18
18
  const firstColumn = selectedColumns === null || selectedColumns === void 0 ? void 0 : selectedColumns[0];
19
19
  const firstValign = getLayoutColumnValign(firstColumn === null || firstColumn === void 0 ? void 0 : firstColumn.node);
20
20
  if (!firstValign || !(selectedColumns !== null && selectedColumns !== void 0 && selectedColumns.every(({
@@ -18,7 +18,7 @@ const TOOLBAR_MENU_SELECTOR = '[data-toolbar-component="menu"]';
18
18
  */
19
19
  const getLayoutColumnMenuTarget = (editorView, selection, anchorPosFromHandle) => {
20
20
  var _columnDomRef$parentE;
21
- const anchorPos = getLayoutColumnMenuAnchorPos(selection, anchorPosFromHandle);
21
+ const anchorPos = selection && getLayoutColumnMenuAnchorPos(selection, anchorPosFromHandle);
22
22
  if (anchorPos === undefined) {
23
23
  return null;
24
24
  }
@@ -1,6 +1,8 @@
1
1
  import { useSharedPluginStateWithSelector } from '@atlaskit/editor-common/hooks';
2
- import { getSelectedLayoutColumns } from '../../pm-plugins/utils/layout-column-selection';
3
- export const useSelectedLayoutColumns = api => useSharedPluginStateWithSelector(api, ['selection'], states => {
4
- var _states$selectionStat;
5
- return getSelectedLayoutColumns((_states$selectionStat = states.selectionState) === null || _states$selectionStat === void 0 ? void 0 : _states$selectionStat.selection);
2
+ import { getSelectedLayoutColumnsFromSelection } from '../../pm-plugins/utils/layout-column-selection';
3
+ export const useSelectedLayoutColumns = api => useSharedPluginStateWithSelector(api, ['selection'], ({
4
+ selectionState
5
+ }) => {
6
+ const selectedLayoutColumns = (selectionState === null || selectionState === void 0 ? void 0 : selectionState.selection) && getSelectedLayoutColumnsFromSelection(selectionState.selection);
7
+ return selectedLayoutColumns !== null && selectedLayoutColumns !== void 0 && selectedLayoutColumns.selectedLayoutColumns.length ? selectedLayoutColumns : undefined;
6
8
  });
@@ -12,8 +12,11 @@ import LayoutThreeColumnsSidebarsIcon from '@atlaskit/icon/core/layout-three-col
12
12
  import LayoutTwoColumnsIcon from '@atlaskit/icon/core/layout-two-columns';
13
13
  import LayoutTwoColumnsSidebarLeftIcon from '@atlaskit/icon/core/layout-two-columns-sidebar-left';
14
14
  import LayoutTwoColumnsSidebarRightIcon from '@atlaskit/icon/core/layout-two-columns-sidebar-right';
15
+ import TableColumnsDistributeIcon from '@atlaskit/icon/core/table-columns-distribute';
16
+ import { expValEqualsNoExposure } from '@atlaskit/tmp-editor-statsig/exp-val-equals-no-exposure';
15
17
  import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
16
- import { deleteActiveLayoutNode, getPresetLayout, setPresetLayout } from '../pm-plugins/actions';
18
+ import { deleteActiveLayoutNode, distributeLayoutColumns, getPresetLayout, setPresetLayout } from '../pm-plugins/actions';
19
+ import { isDistributedUniformly } from '../pm-plugins/utils/layout-column-distribution';
17
20
  import { EditorLayoutFiveColumnsIcon, EditorLayoutFourColumnsIcon } from './icons/LayoutColumnsIcon';
18
21
  import { LayoutThreeWithLeftSidebarsIcon } from './icons/LayoutThreeWithLeftSidebars';
19
22
  import { LayoutThreeWithRightSidebarsIcon } from './icons/LayoutThreeWithRightSidebars';
@@ -52,7 +55,7 @@ const SIDEBAR_LAYOUT_TYPES = [{
52
55
  }];
53
56
 
54
57
  // These are used for advanced layout options
55
- const LAYOUT_WITH_TWO_COL_DISTRIBUTION = [{
58
+ const LAYOUT_WITH_TWO_COL_DISTRIBUTION_OLD = [{
56
59
  id: 'editor.layout.twoEquals',
57
60
  type: 'two_equal',
58
61
  title: toolbarMessages.twoColumns,
@@ -68,7 +71,7 @@ const LAYOUT_WITH_TWO_COL_DISTRIBUTION = [{
68
71
  title: toolbarMessages.leftSidebar,
69
72
  icon: LayoutTwoColumnsSidebarLeftIcon
70
73
  }];
71
- const LAYOUT_WITH_THREE_COL_DISTRIBUTION = [{
74
+ const LAYOUT_WITH_THREE_COL_DISTRIBUTION_OLD = [{
72
75
  id: 'editor.layout.threeEquals',
73
76
  type: 'three_equal',
74
77
  title: toolbarMessages.threeColumns,
@@ -91,6 +94,35 @@ const LAYOUT_WITH_THREE_COL_DISTRIBUTION = [{
91
94
  icon: LayoutThreeWithLeftSidebarsIcon,
92
95
  iconFallback: LayoutThreeWithLeftSidebarsIcon
93
96
  }];
97
+ const LAYOUT_WITH_TWO_COL_DISTRIBUTION = [{
98
+ id: 'editor.layout.twoRightSidebar',
99
+ type: 'two_right_sidebar',
100
+ title: toolbarMessages.rightSidebar,
101
+ icon: LayoutTwoColumnsSidebarRightIcon
102
+ }, {
103
+ id: 'editor.layout.twoLeftSidebar',
104
+ type: 'two_left_sidebar',
105
+ title: toolbarMessages.leftSidebar,
106
+ icon: LayoutTwoColumnsSidebarLeftIcon
107
+ }];
108
+ const LAYOUT_WITH_THREE_COL_DISTRIBUTION = [{
109
+ id: 'editor.layout.threeWithSidebars',
110
+ type: 'three_with_sidebars',
111
+ title: toolbarMessages.threeColumnsWithSidebars,
112
+ icon: LayoutThreeColumnsSidebarsIcon
113
+ }, {
114
+ id: 'editor.layout.threeRightSidebars',
115
+ type: 'three_right_sidebars',
116
+ title: toolbarMessages.threeColumnsWithRightSidebars,
117
+ icon: LayoutThreeWithRightSidebarsIcon,
118
+ iconFallback: LayoutThreeWithRightSidebarsIcon
119
+ }, {
120
+ id: 'editor.layout.threeLeftSidebars',
121
+ type: 'three_left_sidebars',
122
+ title: toolbarMessages.threeColumnsWithLeftSidebars,
123
+ icon: LayoutThreeWithLeftSidebarsIcon,
124
+ iconFallback: LayoutThreeWithLeftSidebarsIcon
125
+ }];
94
126
  const buildLayoutButton = (intl, item, currentLayout, editorAnalyticsAPI) => ({
95
127
  id: item.id,
96
128
  type: 'button',
@@ -103,7 +135,9 @@ const buildLayoutButton = (intl, item, currentLayout, editorAnalyticsAPI) => ({
103
135
  tabIndex: null
104
136
  });
105
137
  export const layoutToolbarTitle = 'Layout floating controls';
106
- const iconPlaceholder = LayoutTwoColumnsIcon; // TODO: ED-25466 - Replace with proper icon
138
+ const iconPlaceholder = /*#__PURE__*/React.createElement(LayoutTwoColumnsIcon, {
139
+ label: ""
140
+ }); // TODO: ED-25466 - Replace with proper icon
107
141
 
108
142
  const getLayoutColumnsIcons = colCount => {
109
143
  if (!editorExperiment('single_column_layouts', true) && !editorExperiment('platform_editor_controls', 'variant1')) {
@@ -130,11 +164,13 @@ const getLayoutColumnsIcons = colCount => {
130
164
  return undefined;
131
165
  }
132
166
  };
167
+ const getLayoutColumnWidths = node => {
168
+ return node.children.map(child => child.attrs.width);
169
+ };
133
170
  const getAdvancedLayoutItems = ({
134
171
  addSidebarLayouts,
135
172
  intl,
136
173
  editorAnalyticsAPI,
137
- state,
138
174
  node,
139
175
  nodeType,
140
176
  separator,
@@ -143,7 +179,8 @@ const getAdvancedLayoutItems = ({
143
179
  allowAdvancedSingleColumnLayout
144
180
  }) => {
145
181
  const numberOfColumns = node.content.childCount || 2;
146
- const distributionOptions = numberOfColumns === 2 ? LAYOUT_WITH_TWO_COL_DISTRIBUTION : numberOfColumns === 3 ? LAYOUT_WITH_THREE_COL_DISTRIBUTION : [];
182
+ const isLayoutColumnMenuEnabled = expValEqualsNoExposure('platform_editor_layout_column_menu', 'isEnabled', true);
183
+ const distributionOptions = isLayoutColumnMenuEnabled ? numberOfColumns === 2 ? LAYOUT_WITH_TWO_COL_DISTRIBUTION : numberOfColumns === 3 ? LAYOUT_WITH_THREE_COL_DISTRIBUTION : [] : numberOfColumns === 2 ? LAYOUT_WITH_TWO_COL_DISTRIBUTION_OLD : numberOfColumns === 3 ? LAYOUT_WITH_THREE_COL_DISTRIBUTION_OLD : [];
147
184
  const columnOptions = [{
148
185
  title: intl.formatMessage(layoutMessages.columnOption, {
149
186
  count: 2
@@ -177,7 +214,7 @@ const getAdvancedLayoutItems = ({
177
214
  onClick: setPresetLayout(editorAnalyticsAPI)('five_equal'),
178
215
  selected: numberOfColumns === 5
179
216
  }];
180
- const singleColumnOption = allowAdvancedSingleColumnLayout ? {
217
+ const dropdownOptions = [...(allowAdvancedSingleColumnLayout ? [{
181
218
  title: intl.formatMessage(layoutMessages.columnOption, {
182
219
  count: 1
183
220
  }),
@@ -185,17 +222,38 @@ const getAdvancedLayoutItems = ({
185
222
  icon: getLayoutColumnsIcons(1) || iconPlaceholder,
186
223
  onClick: setPresetLayout(editorAnalyticsAPI)('single'),
187
224
  selected: numberOfColumns === 1
188
- } : [];
225
+ }] : []), ...columnOptions];
226
+ const distributeColumnsButton = isLayoutColumnMenuEnabled && numberOfColumns > 1 ? {
227
+ disabled: isDistributedUniformly(getLayoutColumnWidths(node)),
228
+ icon: TableColumnsDistributeIcon,
229
+ onClick: (editorState, dispatch) => {
230
+ const tr = distributeLayoutColumns({
231
+ editorAnalyticsAPI,
232
+ inputMethod: INPUT_METHOD.FLOATING_TB,
233
+ target: 'allColumns'
234
+ })({
235
+ tr: editorState.tr
236
+ });
237
+ if (!tr) {
238
+ return false;
239
+ }
240
+ dispatch === null || dispatch === void 0 ? void 0 : dispatch(tr);
241
+ return true;
242
+ },
243
+ testId: 'layout-distribute-columns',
244
+ title: intl.formatMessage(layoutMessages.distributeColumns),
245
+ type: 'button'
246
+ } : undefined;
189
247
  return [{
190
248
  type: 'dropdown',
191
249
  title: intl.formatMessage(layoutMessages.columnOption, {
192
250
  count: numberOfColumns
193
251
  }),
194
252
  //`${numberOfColumns}-columns`,
195
- options: [singleColumnOption, columnOptions].flat(),
253
+ options: dropdownOptions,
196
254
  showSelected: true,
197
255
  testId: 'column-options-button'
198
- }, ...(distributionOptions.length > 0 ? [separator] : []), ...(addSidebarLayouts ? distributionOptions.map(i => buildLayoutButton(intl, i, currentLayout, editorAnalyticsAPI)) : [])];
256
+ }, ...(distributionOptions.length > 0 || distributeColumnsButton ? [separator] : []), ...(addSidebarLayouts ? distributionOptions.map(i => buildLayoutButton(intl, i, currentLayout, editorAnalyticsAPI)) : []), ...(distributeColumnsButton ? [distributeColumnsButton] : [])];
199
257
  };
200
258
  const fullHeightSeparator = {
201
259
  type: 'separator',
@@ -283,7 +341,6 @@ export const buildToolbar = (state, intl, pos, _allowBreakout, addSidebarLayouts
283
341
  addSidebarLayouts,
284
342
  intl,
285
343
  editorAnalyticsAPI,
286
- state,
287
344
  nodeType,
288
345
  node,
289
346
  separator,
@@ -11,7 +11,7 @@ import { fg } from '@atlaskit/platform-feature-flags';
11
11
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
12
12
  import { expValEqualsNoExposure } from '@atlaskit/tmp-editor-statsig/exp-val-equals-no-exposure';
13
13
  import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
14
- import { createDefaultLayoutSection, createMultiColumnLayoutSection, deleteLayoutColumn as _deleteLayoutColumn, distributeLayoutColumns as _distributeLayoutColumns, insertLayoutColumn as _insertLayoutColumn, insertLayoutColumnsWithAnalytics, setLayoutColumnValign as _setLayoutColumnValign, toggleLayoutColumnMenu } from './pm-plugins/actions';
14
+ import { createDefaultLayoutSection, createDistributeLayoutColumnsCommand, createMultiColumnLayoutSection, deleteLayoutColumn as _deleteLayoutColumn, insertLayoutColumn as _insertLayoutColumn, insertLayoutColumnsWithAnalytics, setLayoutColumnValign as _setLayoutColumnValign, toggleLayoutColumnMenu } from './pm-plugins/actions';
15
15
  import { default as createLayoutPlugin } from './pm-plugins/main';
16
16
  import { pluginKey } from './pm-plugins/plugin-key';
17
17
  import { default as createLayoutResizingPlugin } from './pm-plugins/resizing';
@@ -50,7 +50,7 @@ export var selectIntoLayoutSection = function selectIntoLayoutSection(tr) {
50
50
  return tr;
51
51
  };
52
52
  export var layoutPlugin = function layoutPlugin(_ref) {
53
- var _api$analytics;
53
+ var _api$analytics, _api$analytics5;
54
54
  var _ref$config = _ref.config,
55
55
  options = _ref$config === void 0 ? {} : _ref$config,
56
56
  api = _ref.api;
@@ -374,10 +374,7 @@ export var layoutPlugin = function layoutPlugin(_ref) {
374
374
  var _api$analytics4;
375
375
  return _deleteLayoutColumn(api === null || api === void 0 || (_api$analytics4 = api.analytics) === null || _api$analytics4 === void 0 ? void 0 : _api$analytics4.actions)(props);
376
376
  },
377
- distributeLayoutColumns: function distributeLayoutColumns(props) {
378
- var _api$analytics5;
379
- return _distributeLayoutColumns(api === null || api === void 0 || (_api$analytics5 = api.analytics) === null || _api$analytics5 === void 0 ? void 0 : _api$analytics5.actions)(props);
380
- },
377
+ distributeLayoutColumns: createDistributeLayoutColumnsCommand(api === null || api === void 0 || (_api$analytics5 = api.analytics) === null || _api$analytics5 === void 0 ? void 0 : _api$analytics5.actions),
381
378
  insertLayoutColumn: function insertLayoutColumn(side) {
382
379
  var _api$analytics6;
383
380
  return _insertLayoutColumn(side, api === null || api === void 0 || (_api$analytics6 = api.analytics) === null || _api$analytics6 === void 0 ? void 0 : _api$analytics6.actions);