@atlaskit/editor-plugin-layout 11.1.10 → 12.0.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.
Files changed (35) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/dist/cjs/layoutPlugin.js +7 -10
  3. package/dist/cjs/pm-plugins/actions.js +82 -49
  4. package/dist/cjs/pm-plugins/consts.js +2 -1
  5. package/dist/cjs/pm-plugins/keymap.js +19 -5
  6. package/dist/cjs/pm-plugins/main.js +28 -0
  7. package/dist/cjs/pm-plugins/utils/layout-column-selection.js +2 -1
  8. package/dist/cjs/ui/LayoutColumnMenu/DeleteColumnDropdownItem.js +4 -1
  9. package/dist/cjs/ui/LayoutColumnMenu/InsertColumnDropdownItem.js +5 -1
  10. package/dist/cjs/ui/LayoutColumnMenu/VerticalAlignDropdownItem.js +3 -1
  11. package/dist/es2019/layoutPlugin.js +8 -11
  12. package/dist/es2019/pm-plugins/actions.js +42 -14
  13. package/dist/es2019/pm-plugins/consts.js +1 -0
  14. package/dist/es2019/pm-plugins/keymap.js +19 -5
  15. package/dist/es2019/pm-plugins/main.js +30 -0
  16. package/dist/es2019/pm-plugins/utils/layout-column-selection.js +2 -1
  17. package/dist/es2019/ui/LayoutColumnMenu/DeleteColumnDropdownItem.js +4 -1
  18. package/dist/es2019/ui/LayoutColumnMenu/InsertColumnDropdownItem.js +5 -1
  19. package/dist/es2019/ui/LayoutColumnMenu/VerticalAlignDropdownItem.js +3 -1
  20. package/dist/esm/layoutPlugin.js +8 -11
  21. package/dist/esm/pm-plugins/actions.js +84 -51
  22. package/dist/esm/pm-plugins/consts.js +1 -0
  23. package/dist/esm/pm-plugins/keymap.js +19 -5
  24. package/dist/esm/pm-plugins/main.js +28 -0
  25. package/dist/esm/pm-plugins/utils/layout-column-selection.js +2 -1
  26. package/dist/esm/ui/LayoutColumnMenu/DeleteColumnDropdownItem.js +4 -1
  27. package/dist/esm/ui/LayoutColumnMenu/InsertColumnDropdownItem.js +5 -1
  28. package/dist/esm/ui/LayoutColumnMenu/VerticalAlignDropdownItem.js +3 -1
  29. package/dist/types/layoutPluginType.d.ts +4 -5
  30. package/dist/types/pm-plugins/actions.d.ts +15 -4
  31. package/dist/types/pm-plugins/consts.d.ts +2 -0
  32. package/dist/types-ts4.5/layoutPluginType.d.ts +4 -5
  33. package/dist/types-ts4.5/pm-plugins/actions.d.ts +15 -4
  34. package/dist/types-ts4.5/pm-plugins/consts.d.ts +2 -0
  35. package/package.json +5 -5
@@ -8,10 +8,10 @@ import { safeInsert } from '@atlaskit/editor-prosemirror/utils';
8
8
  import { fg } from '@atlaskit/platform-feature-flags';
9
9
  import { expValEqualsNoExposure } from '@atlaskit/tmp-editor-statsig/exp-val-equals-no-exposure';
10
10
  import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
11
- import { EVEN_DISTRIBUTED_COL_WIDTHS, MAX_LAYOUT_COLUMNS, MAX_STANDARD_LAYOUT_COLUMNS, MIN_LAYOUT_COLUMN_WIDTH_PERCENT } from './consts';
11
+ import { DEFAULT_LAYOUT_COLUMN_VALIGN, EVEN_DISTRIBUTED_COL_WIDTHS, MAX_LAYOUT_COLUMNS, MAX_STANDARD_LAYOUT_COLUMNS, MIN_LAYOUT_COLUMN_WIDTH_PERCENT } from './consts';
12
12
  import { pluginKey } from './plugin-key';
13
13
  import { calculateDistribution, isDistributedUniformly, redistributeAfterDeletion, redistributeProportionally } from './utils/layout-column-distribution';
14
- import { getAllLayoutColumnsFromSelection, getLayoutColumnsFromContentSelection, getSelectedLayoutColumnsFromSelection } from './utils/layout-column-selection';
14
+ import { getAllLayoutColumnsFromSelection, getLayoutColumnsFromContentSelection, getLayoutColumnValign, getSelectedLayoutColumnsFromSelection } from './utils/layout-column-selection';
15
15
  export const ONE_COL_LAYOUTS = ['single'];
16
16
  export const TWO_COL_LAYOUTS = ['two_equal', 'two_left_sidebar', 'two_right_sidebar'];
17
17
  export const THREE_COL_LAYOUTS = ['three_equal', 'three_with_sidebars'];
@@ -530,6 +530,15 @@ const formatLayoutName = layout => {
530
530
  }
531
531
  };
532
532
  export const LAYOUT_COLUMN_INSERT_META = 'layoutColumnInsert';
533
+ const getPreviousLayoutColumnValign = selectedLayoutColumns => {
534
+ var _selectedLayoutColumn;
535
+ const firstValign = getLayoutColumnValign((_selectedLayoutColumn = selectedLayoutColumns[0]) === null || _selectedLayoutColumn === void 0 ? void 0 : _selectedLayoutColumn.node);
536
+ const hasMixedValign = selectedLayoutColumns.some(({
537
+ node
538
+ }) => getLayoutColumnValign(node) !== firstValign);
539
+ return hasMixedValign ? 'mixed' : firstValign !== null && firstValign !== void 0 ? firstValign : DEFAULT_LAYOUT_COLUMN_VALIGN;
540
+ };
541
+ const hasLayoutColumnContent = node => !isEmptyDocument(node);
533
542
  const mapLayoutColumnPreservedSelection = (tr, api) => {
534
543
  const insertMeta = tr.getMeta(LAYOUT_COLUMN_INSERT_META);
535
544
  if (insertMeta) {
@@ -622,9 +631,10 @@ const insertLayoutColumnAt = (side, editorAnalyticsAPI, inputMethod = INPUT_METH
622
631
  actionSubject: ACTION_SUBJECT.DOCUMENT,
623
632
  actionSubjectId: ACTION_SUBJECT_ID.LAYOUT_COLUMN,
624
633
  attributes: {
625
- columnCount: redistributedWidths.length,
626
634
  endIndex,
627
635
  inputMethod,
636
+ newColumnCount: redistributedWidths.length,
637
+ previousColumnCount: layoutSectionNode.childCount,
628
638
  selectedCount: selectedColumnCount,
629
639
  side,
630
640
  startIndex
@@ -634,7 +644,10 @@ const insertLayoutColumnAt = (side, editorAnalyticsAPI, inputMethod = INPUT_METH
634
644
  tr.setMeta('scrollIntoView', false);
635
645
  return tr;
636
646
  };
637
- export const insertLayoutColumn = (side, editorAnalyticsAPI, api, inputMethod = INPUT_METHOD.LAYOUT_COLUMN_MENU) => ({
647
+ export const insertLayoutColumn = ({
648
+ side,
649
+ inputMethod = INPUT_METHOD.LAYOUT_COLUMN_MENU
650
+ }, editorAnalyticsAPI, api) => ({
638
651
  tr
639
652
  }) => {
640
653
  const result = insertLayoutColumnAt(side, editorAnalyticsAPI, inputMethod)({
@@ -645,7 +658,10 @@ export const insertLayoutColumn = (side, editorAnalyticsAPI, api, inputMethod =
645
658
  }
646
659
  return result;
647
660
  };
648
- export const setLayoutColumnValign = (valign, editorAnalyticsAPI, api) => ({
661
+ export const setLayoutColumnValign = ({
662
+ valign,
663
+ inputMethod = INPUT_METHOD.LAYOUT_COLUMN_MENU
664
+ }, editorAnalyticsAPI, api) => ({
649
665
  tr
650
666
  }) => {
651
667
  if (!expValEqualsNoExposure('platform_editor_layout_column_menu', 'isEnabled', true)) {
@@ -656,13 +672,15 @@ export const setLayoutColumnValign = (valign, editorAnalyticsAPI, api) => ({
656
672
  return null;
657
673
  }
658
674
  const {
675
+ layoutSectionNode,
659
676
  startIndex,
660
677
  endIndex,
661
678
  selectedLayoutColumns
662
679
  } = selectedLayoutColumnsResult;
680
+ const previousValign = getPreviousLayoutColumnValign(selectedLayoutColumns);
663
681
  const columnsToUpdate = selectedLayoutColumns.filter(({
664
682
  node
665
- }) => node.attrs.valign !== valign);
683
+ }) => getLayoutColumnValign(node) !== valign);
666
684
  if (columnsToUpdate.length === 0) {
667
685
  return null;
668
686
  }
@@ -681,8 +699,10 @@ export const setLayoutColumnValign = (valign, editorAnalyticsAPI, api) => ({
681
699
  actionSubject: ACTION_SUBJECT.DOCUMENT,
682
700
  actionSubjectId: ACTION_SUBJECT_ID.LAYOUT_COLUMN,
683
701
  attributes: {
702
+ columnCount: layoutSectionNode.childCount,
684
703
  endIndex,
685
- inputMethod: INPUT_METHOD.LAYOUT_COLUMN_MENU,
704
+ inputMethod,
705
+ previousValign,
686
706
  selectedCount: selectedLayoutColumns.length,
687
707
  startIndex,
688
708
  updatedCount: updatedColumnCount,
@@ -767,7 +787,8 @@ export const distributeLayoutColumns = (editorAnalyticsAPI, api) => ({
767
787
  endIndex,
768
788
  inputMethod,
769
789
  selectedCount: selectedLayoutColumns.length,
770
- startIndex
790
+ startIndex,
791
+ target
771
792
  },
772
793
  eventType: EVENT_TYPE.TRACK
773
794
  })(tr);
@@ -793,17 +814,19 @@ export const toggleLayoutColumnMenu = ({
793
814
  export const setLayoutColumnDangerPreview = show => ({
794
815
  tr
795
816
  }) => {
796
- var _selectedLayoutColumn;
817
+ var _selectedLayoutColumn2;
797
818
  const selectedLayoutColumnsResult = getSelectedLayoutColumnsFromSelection(tr.selection);
798
- const positions = show ? (_selectedLayoutColumn = selectedLayoutColumnsResult === null || selectedLayoutColumnsResult === void 0 ? void 0 : selectedLayoutColumnsResult.selectedLayoutColumns.map(({
819
+ const positions = show ? (_selectedLayoutColumn2 = selectedLayoutColumnsResult === null || selectedLayoutColumnsResult === void 0 ? void 0 : selectedLayoutColumnsResult.selectedLayoutColumns.map(({
799
820
  pos
800
- }) => pos)) !== null && _selectedLayoutColumn !== void 0 ? _selectedLayoutColumn : [] : null;
821
+ }) => pos)) !== null && _selectedLayoutColumn2 !== void 0 ? _selectedLayoutColumn2 : [] : null;
801
822
  tr.setMeta('layoutColumnDangerPreview', positions);
802
823
  tr.setMeta('addToHistory', false);
803
824
  tr.setMeta('scrollIntoView', false);
804
825
  return tr;
805
826
  };
806
- export const deleteLayoutColumn = (editorAnalyticsAPI, api, inputMethod = INPUT_METHOD.LAYOUT_COLUMN_MENU) => ({
827
+ export const deleteLayoutColumn = ({
828
+ inputMethod = INPUT_METHOD.LAYOUT_COLUMN_MENU
829
+ } = {}, editorAnalyticsAPI, api) => ({
807
830
  tr
808
831
  }) => {
809
832
  var _api$blockControls4;
@@ -821,15 +844,20 @@ export const deleteLayoutColumn = (editorAnalyticsAPI, api, inputMethod = INPUT_
821
844
  startIndex,
822
845
  endIndex
823
846
  } = selectedLayoutColumnsResult;
824
- const emitDeleteColumnAnalytics = columnCount => {
847
+ const hadContent = selectedLayoutColumns.some(({
848
+ node
849
+ }) => hasLayoutColumnContent(node));
850
+ const emitDeleteColumnAnalytics = newColumnCount => {
825
851
  editorAnalyticsAPI === null || editorAnalyticsAPI === void 0 ? void 0 : editorAnalyticsAPI.attachAnalyticsEvent({
826
852
  action: ACTION.DELETED,
827
853
  actionSubject: ACTION_SUBJECT.DOCUMENT,
828
854
  actionSubjectId: ACTION_SUBJECT_ID.LAYOUT_COLUMN,
829
855
  attributes: {
830
- columnCount,
831
856
  endIndex,
857
+ hadContent,
832
858
  inputMethod,
859
+ newColumnCount,
860
+ previousColumnCount: layoutSectionNode.childCount,
833
861
  selectedCount: selectedLayoutColumns.length,
834
862
  startIndex
835
863
  },
@@ -1,6 +1,7 @@
1
1
  export const MAX_STANDARD_LAYOUT_COLUMNS = 3;
2
2
  export const MAX_LAYOUT_COLUMNS = 5;
3
3
  export const MIN_LAYOUT_COLUMN_WIDTH_PERCENT = 5;
4
+ export const DEFAULT_LAYOUT_COLUMN_VALIGN = 'top';
4
5
  export const EVEN_DISTRIBUTED_COL_WIDTHS = {
5
6
  1: 100,
6
7
  2: 50,
@@ -16,11 +16,25 @@ function keymapPlugin({
16
16
  }) {
17
17
  var _api$analytics, _api$analytics2, _api$analytics3, _api$analytics4, _api$analytics5;
18
18
  const list = {};
19
- bindLayoutColumnShortcut(addColumnBefore.common, insertLayoutColumn('left', api === null || api === void 0 ? void 0 : (_api$analytics = api.analytics) === null || _api$analytics === void 0 ? void 0 : _api$analytics.actions, api, INPUT_METHOD.KEYBOARD), list);
20
- bindLayoutColumnShortcut(addColumnBeforeVO.common, insertLayoutColumn('left', api === null || api === void 0 ? void 0 : (_api$analytics2 = api.analytics) === null || _api$analytics2 === void 0 ? void 0 : _api$analytics2.actions, api, INPUT_METHOD.KEYBOARD), list);
21
- bindLayoutColumnShortcut(addColumnAfter.common, insertLayoutColumn('right', api === null || api === void 0 ? void 0 : (_api$analytics3 = api.analytics) === null || _api$analytics3 === void 0 ? void 0 : _api$analytics3.actions, api, INPUT_METHOD.KEYBOARD), list);
22
- bindLayoutColumnShortcut(addColumnAfterVO.common, insertLayoutColumn('right', api === null || api === void 0 ? void 0 : (_api$analytics4 = api.analytics) === null || _api$analytics4 === void 0 ? void 0 : _api$analytics4.actions, api, INPUT_METHOD.KEYBOARD), list);
23
- bindLayoutColumnShortcut(deleteColumn.common, deleteLayoutColumn(api === null || api === void 0 ? void 0 : (_api$analytics5 = api.analytics) === null || _api$analytics5 === void 0 ? void 0 : _api$analytics5.actions, api, INPUT_METHOD.KEYBOARD), list);
19
+ bindLayoutColumnShortcut(addColumnBefore.common, insertLayoutColumn({
20
+ side: 'left',
21
+ inputMethod: INPUT_METHOD.SHORTCUT
22
+ }, api === null || api === void 0 ? void 0 : (_api$analytics = api.analytics) === null || _api$analytics === void 0 ? void 0 : _api$analytics.actions, api), list);
23
+ bindLayoutColumnShortcut(addColumnBeforeVO.common, insertLayoutColumn({
24
+ side: 'left',
25
+ inputMethod: INPUT_METHOD.SHORTCUT
26
+ }, api === null || api === void 0 ? void 0 : (_api$analytics2 = api.analytics) === null || _api$analytics2 === void 0 ? void 0 : _api$analytics2.actions, api), list);
27
+ bindLayoutColumnShortcut(addColumnAfter.common, insertLayoutColumn({
28
+ side: 'right',
29
+ inputMethod: INPUT_METHOD.SHORTCUT
30
+ }, api === null || api === void 0 ? void 0 : (_api$analytics3 = api.analytics) === null || _api$analytics3 === void 0 ? void 0 : _api$analytics3.actions, api), list);
31
+ bindLayoutColumnShortcut(addColumnAfterVO.common, insertLayoutColumn({
32
+ side: 'right',
33
+ inputMethod: INPUT_METHOD.SHORTCUT
34
+ }, api === null || api === void 0 ? void 0 : (_api$analytics4 = api.analytics) === null || _api$analytics4 === void 0 ? void 0 : _api$analytics4.actions, api), list);
35
+ bindLayoutColumnShortcut(deleteColumn.common, deleteLayoutColumn({
36
+ inputMethod: INPUT_METHOD.SHORTCUT
37
+ }, api === null || api === void 0 ? void 0 : (_api$analytics5 = api.analytics) === null || _api$analytics5 === void 0 ? void 0 : _api$analytics5.actions, api), list);
24
38
  return keymap(list);
25
39
  }
26
40
  export default keymapPlugin;
@@ -1,3 +1,4 @@
1
+ import { ACTION, ACTION_SUBJECT, EVENT_TYPE, INPUT_METHOD } from '@atlaskit/editor-common/analytics';
1
2
  import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
2
3
  import { createSelectionClickHandler } from '@atlaskit/editor-common/selection';
3
4
  import { filterCommand as filter } from '@atlaskit/editor-common/utils';
@@ -13,6 +14,7 @@ import { EVEN_DISTRIBUTED_COL_WIDTHS } from './consts';
13
14
  import { pluginKey } from './plugin-key';
14
15
  import { pluginKey as layoutResizingPluginKey } from './resizing';
15
16
  import { getMaybeLayoutSection } from './utils';
17
+ import { getSelectedLayoutColumnsFromSelection } from './utils/layout-column-selection';
16
18
  export const DEFAULT_LAYOUT = 'two_equal';
17
19
  const isWholeSelectionInsideLayoutColumn = state => {
18
20
  // Since findParentNodeOfType doesn't check if selection.to shares the parent, we do this check ourselves
@@ -85,6 +87,30 @@ const getInitialPluginState = (options, state) => {
85
87
  dangerPreviewLayoutColumnPositions: undefined
86
88
  };
87
89
  };
90
+ const fireLayoutColumnMenuOpenedAnalytics = (editorAnalyticsAPI, state, openedViaKeyboard) => {
91
+ const selectedLayoutColumnsResult = getSelectedLayoutColumnsFromSelection(state.selection);
92
+ if (!selectedLayoutColumnsResult) {
93
+ return;
94
+ }
95
+ const {
96
+ layoutSectionNode,
97
+ selectedLayoutColumns,
98
+ startIndex,
99
+ endIndex
100
+ } = selectedLayoutColumnsResult;
101
+ editorAnalyticsAPI === null || editorAnalyticsAPI === void 0 ? void 0 : editorAnalyticsAPI.fireAnalyticsEvent({
102
+ action: ACTION.OPENED,
103
+ actionSubject: ACTION_SUBJECT.LAYOUT_COLUMN_MENU,
104
+ attributes: {
105
+ columnCount: layoutSectionNode.childCount,
106
+ endIndex,
107
+ inputMethod: openedViaKeyboard ? INPUT_METHOD.KEYBOARD : INPUT_METHOD.MOUSE,
108
+ selectedCount: selectedLayoutColumns.length,
109
+ startIndex
110
+ },
111
+ eventType: EVENT_TYPE.UI
112
+ });
113
+ };
88
114
  const reduceLayoutColumnMenuState = (pluginState, action) => {
89
115
  switch (action.type) {
90
116
  case 'toggleLayoutColumnMenu':
@@ -181,10 +207,14 @@ export default ((options, editorAnalyticsAPI) => {
181
207
  const columnMenuMeta = tr.getMeta('toggleLayoutColumnMenu');
182
208
  const dangerPreviewMeta = tr.getMeta('layoutColumnDangerPreview');
183
209
  if (columnMenuMeta) {
210
+ const wasLayoutColumnMenuOpen = nextPluginState.isLayoutColumnMenuOpen;
184
211
  nextPluginState = reduceLayoutColumnMenuState(nextPluginState, {
185
212
  meta: columnMenuMeta,
186
213
  type: 'toggleLayoutColumnMenu'
187
214
  });
215
+ if (!wasLayoutColumnMenuOpen && nextPluginState.isLayoutColumnMenuOpen) {
216
+ fireLayoutColumnMenuOpenedAnalytics(editorAnalyticsAPI, newState, columnMenuMeta.openedViaKeyboard);
217
+ }
188
218
  }
189
219
  if (tr.getMeta('layoutColumnDangerPreview') !== undefined) {
190
220
  nextPluginState = reduceLayoutColumnMenuState(nextPluginState, {
@@ -1,5 +1,6 @@
1
1
  import { NodeSelection } from '@atlaskit/editor-prosemirror/state';
2
2
  import { findChildrenByType, findParentNodeOfType } from '@atlaskit/editor-prosemirror/utils';
3
+ import { DEFAULT_LAYOUT_COLUMN_VALIGN } from '../consts';
3
4
  const findLayoutSectionFromSelection = selection => {
4
5
  const {
5
6
  layoutSection
@@ -102,7 +103,7 @@ export const getAllLayoutColumnsFromSelection = selection => {
102
103
  };
103
104
  export const getLayoutColumnValign = layoutColumn => {
104
105
  var _ref;
105
- return layoutColumn ? (_ref = layoutColumn.attrs.valign) !== null && _ref !== void 0 ? _ref : 'top' : undefined;
106
+ return layoutColumn ? (_ref = layoutColumn.attrs.valign) !== null && _ref !== void 0 ? _ref : DEFAULT_LAYOUT_COLUMN_VALIGN : undefined;
106
107
  };
107
108
  export const getLayoutColumnMenuAnchorPos = (selection, anchorPosFromHandle) => {
108
109
  var _clickedSelectedColum, _selectedLayoutColumn;
@@ -1,5 +1,6 @@
1
1
  import React, { useCallback } from 'react';
2
2
  import { useIntl } from 'react-intl';
3
+ import { INPUT_METHOD } from '@atlaskit/editor-common/analytics';
3
4
  import { deleteColumn, getAriaKeyshortcuts, tooltip } from '@atlaskit/editor-common/keymaps';
4
5
  import { layoutMessages } from '@atlaskit/editor-common/messages';
5
6
  import { DeleteIcon, ToolbarDropdownItem, ToolbarKeyboardShortcutHint } from '@atlaskit/editor-toolbar';
@@ -24,7 +25,9 @@ const DeleteColumnDropdownItem = ({
24
25
  }, [setDangerPreview]);
25
26
  const onClick = useCallback(() => {
26
27
  var _api$layout2, _api$core2;
27
- const deleteCommand = api === null || api === void 0 ? void 0 : (_api$layout2 = api.layout) === null || _api$layout2 === void 0 ? void 0 : _api$layout2.commands.deleteLayoutColumn();
28
+ const deleteCommand = api === null || api === void 0 ? void 0 : (_api$layout2 = api.layout) === null || _api$layout2 === void 0 ? void 0 : _api$layout2.commands.deleteLayoutColumn({
29
+ inputMethod: INPUT_METHOD.LAYOUT_COLUMN_MENU
30
+ });
28
31
  api === null || api === void 0 ? void 0 : (_api$core2 = api.core) === null || _api$core2 === void 0 ? void 0 : _api$core2.actions.execute(props => {
29
32
  var _api$layout3;
30
33
  const tr = deleteCommand === null || deleteCommand === void 0 ? void 0 : deleteCommand(props);
@@ -1,5 +1,6 @@
1
1
  import React, { useCallback } from 'react';
2
2
  import { useIntl } from 'react-intl';
3
+ import { INPUT_METHOD } from '@atlaskit/editor-common/analytics';
3
4
  import { addColumnAfter, addColumnBefore, getAriaKeyshortcuts, tooltip } from '@atlaskit/editor-common/keymaps';
4
5
  import { layoutMessages } from '@atlaskit/editor-common/messages';
5
6
  import { TableColumnAddLeftIcon, TableColumnAddRightIcon, ToolbarDropdownItem, ToolbarKeyboardShortcutHint } from '@atlaskit/editor-toolbar';
@@ -36,7 +37,10 @@ export const InsertColumnDropdownItem = ({
36
37
  const canInsertColumn = selectedLayoutColumns !== undefined && columnCount < maxColumnCount;
37
38
  const onClick = useCallback(() => {
38
39
  var _api$layout, _api$core;
39
- const insertCommand = api === null || api === void 0 ? void 0 : (_api$layout = api.layout) === null || _api$layout === void 0 ? void 0 : _api$layout.commands.insertLayoutColumn(side);
40
+ const insertCommand = api === null || api === void 0 ? void 0 : (_api$layout = api.layout) === null || _api$layout === void 0 ? void 0 : _api$layout.commands.insertLayoutColumn({
41
+ side,
42
+ inputMethod: INPUT_METHOD.LAYOUT_COLUMN_MENU
43
+ });
40
44
  api === null || api === void 0 ? void 0 : (_api$core = api.core) === null || _api$core === void 0 ? void 0 : _api$core.actions.execute(props => {
41
45
  var _api$layout2;
42
46
  const tr = insertCommand === null || insertCommand === void 0 ? void 0 : insertCommand(props);
@@ -20,7 +20,9 @@ export const VerticalAlignDropdownItem = ({
20
20
  const Icon = VERTICAL_ALIGN_ICONS[value];
21
21
  const onClick = useCallback(() => {
22
22
  var _api$core, _api$layout;
23
- api === null || api === void 0 ? void 0 : (_api$core = api.core) === null || _api$core === void 0 ? void 0 : _api$core.actions.execute(api === null || api === void 0 ? void 0 : (_api$layout = api.layout) === null || _api$layout === void 0 ? void 0 : _api$layout.commands.setLayoutColumnValign(value));
23
+ api === null || api === void 0 ? void 0 : (_api$core = api.core) === null || _api$core === void 0 ? void 0 : _api$core.actions.execute(api === null || api === void 0 ? void 0 : (_api$layout = api.layout) === null || _api$layout === void 0 ? void 0 : _api$layout.commands.setLayoutColumnValign({
24
+ valign: value
25
+ }));
24
26
  }, [api, value]);
25
27
  return /*#__PURE__*/React.createElement(ToolbarDropdownItem, {
26
28
  elemBefore: /*#__PURE__*/React.createElement(Icon, {
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { layoutColumn, layoutColumnStage0, layoutColumnWithLocalId, layoutSection, layoutSectionWithLocalId } from '@atlaskit/adf-schema';
2
+ import { layoutColumn, layoutColumnWithLocalId, layoutSection, layoutSectionWithLocalId } from '@atlaskit/adf-schema';
3
3
  import { layoutSectionWithSingleColumn, layoutSectionWithSingleColumnLocalId } from '@atlaskit/adf-schema/schema';
4
4
  import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE, INPUT_METHOD } from '@atlaskit/editor-common/analytics';
5
5
  import { TRANSFORM_STRUCTURE_LAYOUT_MENU_ITEM, TRANSFORM_STRUCTURE_MENU_SECTION, TRANSFORM_STRUCTURE_MENU_SECTION_RANK } from '@atlaskit/editor-common/block-menu';
@@ -89,10 +89,7 @@ export var layoutPlugin = function layoutPlugin(_ref) {
89
89
  node: editorExperiment('advanced_layouts', true) ? fg('platform_editor_adf_with_localid') ? layoutSectionWithSingleColumnLocalId : layoutSectionWithSingleColumn : fg('platform_editor_adf_with_localid') ? layoutSectionWithLocalId : layoutSection
90
90
  }, {
91
91
  name: 'layoutColumn',
92
- node: expValEqualsNoExposure('platform_editor_layout_column_menu', 'isEnabled', true) ?
93
- // `layoutColumnStage0` includes both `valign` and `localId` attrs, so it remains
94
- // compatible with `platform_editor_adf_with_localid` when both flags are enabled.
95
- layoutColumnStage0 : fg('platform_editor_adf_with_localid') ? layoutColumnWithLocalId : layoutColumn
92
+ node: fg('platform_editor_adf_with_localid') ? layoutColumnWithLocalId : layoutColumn
96
93
  }];
97
94
  },
98
95
  pmPlugins: function pmPlugins() {
@@ -383,22 +380,22 @@ export var layoutPlugin = function layoutPlugin(_ref) {
383
380
  return pluginKey.getState(editorState);
384
381
  },
385
382
  commands: {
386
- deleteLayoutColumn: function deleteLayoutColumn(inputMethod) {
383
+ deleteLayoutColumn: function deleteLayoutColumn(options) {
387
384
  var _api$analytics5;
388
- return _deleteLayoutColumn(api === null || api === void 0 || (_api$analytics5 = api.analytics) === null || _api$analytics5 === void 0 ? void 0 : _api$analytics5.actions, api, inputMethod);
385
+ return _deleteLayoutColumn(options, api === null || api === void 0 || (_api$analytics5 = api.analytics) === null || _api$analytics5 === void 0 ? void 0 : _api$analytics5.actions, api);
389
386
  },
390
387
  distributeLayoutColumns: function distributeLayoutColumns(options) {
391
388
  var _api$analytics6;
392
389
  return _distributeLayoutColumns(api === null || api === void 0 || (_api$analytics6 = api.analytics) === null || _api$analytics6 === void 0 ? void 0 : _api$analytics6.actions, api)(options);
393
390
  },
394
- insertLayoutColumn: function insertLayoutColumn(side, inputMethod) {
391
+ insertLayoutColumn: function insertLayoutColumn(options) {
395
392
  var _api$analytics7;
396
- return _insertLayoutColumn(side, api === null || api === void 0 || (_api$analytics7 = api.analytics) === null || _api$analytics7 === void 0 ? void 0 : _api$analytics7.actions, api, inputMethod);
393
+ return _insertLayoutColumn(options, api === null || api === void 0 || (_api$analytics7 = api.analytics) === null || _api$analytics7 === void 0 ? void 0 : _api$analytics7.actions, api);
397
394
  },
398
395
  setLayoutColumnDangerPreview: setLayoutColumnDangerPreview,
399
- setLayoutColumnValign: function setLayoutColumnValign(valign) {
396
+ setLayoutColumnValign: function setLayoutColumnValign(options) {
400
397
  var _api$analytics8;
401
- return _setLayoutColumnValign(valign, api === null || api === void 0 || (_api$analytics8 = api.analytics) === null || _api$analytics8 === void 0 ? void 0 : _api$analytics8.actions, api);
398
+ return _setLayoutColumnValign(options, api === null || api === void 0 || (_api$analytics8 = api.analytics) === null || _api$analytics8 === void 0 ? void 0 : _api$analytics8.actions, api);
402
399
  },
403
400
  toggleLayoutColumnMenu: toggleLayoutColumnMenu
404
401
  }
@@ -11,10 +11,10 @@ import { safeInsert } from '@atlaskit/editor-prosemirror/utils';
11
11
  import { fg } from '@atlaskit/platform-feature-flags';
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 { EVEN_DISTRIBUTED_COL_WIDTHS, MAX_LAYOUT_COLUMNS, MAX_STANDARD_LAYOUT_COLUMNS, MIN_LAYOUT_COLUMN_WIDTH_PERCENT } from './consts';
14
+ import { DEFAULT_LAYOUT_COLUMN_VALIGN, EVEN_DISTRIBUTED_COL_WIDTHS, MAX_LAYOUT_COLUMNS, MAX_STANDARD_LAYOUT_COLUMNS, MIN_LAYOUT_COLUMN_WIDTH_PERCENT } from './consts';
15
15
  import { pluginKey } from './plugin-key';
16
16
  import { calculateDistribution, isDistributedUniformly, redistributeAfterDeletion, redistributeProportionally } from './utils/layout-column-distribution';
17
- import { getAllLayoutColumnsFromSelection, getLayoutColumnsFromContentSelection, getSelectedLayoutColumnsFromSelection } from './utils/layout-column-selection';
17
+ import { getAllLayoutColumnsFromSelection, getLayoutColumnsFromContentSelection, getLayoutColumnValign, getSelectedLayoutColumnsFromSelection } from './utils/layout-column-selection';
18
18
  export var ONE_COL_LAYOUTS = ['single'];
19
19
  export var TWO_COL_LAYOUTS = ['two_equal', 'two_left_sidebar', 'two_right_sidebar'];
20
20
  export var THREE_COL_LAYOUTS = ['three_equal', 'three_with_sidebars'];
@@ -544,6 +544,18 @@ var formatLayoutName = function formatLayoutName(layout) {
544
544
  }
545
545
  };
546
546
  export var LAYOUT_COLUMN_INSERT_META = 'layoutColumnInsert';
547
+ var getPreviousLayoutColumnValign = function getPreviousLayoutColumnValign(selectedLayoutColumns) {
548
+ var _selectedLayoutColumn;
549
+ var firstValign = getLayoutColumnValign((_selectedLayoutColumn = selectedLayoutColumns[0]) === null || _selectedLayoutColumn === void 0 ? void 0 : _selectedLayoutColumn.node);
550
+ var hasMixedValign = selectedLayoutColumns.some(function (_ref4) {
551
+ var node = _ref4.node;
552
+ return getLayoutColumnValign(node) !== firstValign;
553
+ });
554
+ return hasMixedValign ? 'mixed' : firstValign !== null && firstValign !== void 0 ? firstValign : DEFAULT_LAYOUT_COLUMN_VALIGN;
555
+ };
556
+ var hasLayoutColumnContent = function hasLayoutColumnContent(node) {
557
+ return !isEmptyDocument(node);
558
+ };
547
559
  var mapLayoutColumnPreservedSelection = function mapLayoutColumnPreservedSelection(tr, api) {
548
560
  var insertMeta = tr.getMeta(LAYOUT_COLUMN_INSERT_META);
549
561
  if (insertMeta) {
@@ -572,8 +584,8 @@ export function getEffectiveMaxLayoutColumns() {
572
584
  }
573
585
  var insertLayoutColumnAt = function insertLayoutColumnAt(side, editorAnalyticsAPI) {
574
586
  var inputMethod = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : INPUT_METHOD.LAYOUT_COLUMN_MENU;
575
- return function (_ref4) {
576
- var tr = _ref4.tr;
587
+ return function (_ref5) {
588
+ var tr = _ref5.tr;
577
589
  if (!expValEqualsNoExposure('platform_editor_layout_column_menu', 'isEnabled', true)) {
578
590
  return null;
579
591
  }
@@ -635,9 +647,10 @@ var insertLayoutColumnAt = function insertLayoutColumnAt(side, editorAnalyticsAP
635
647
  actionSubject: ACTION_SUBJECT.DOCUMENT,
636
648
  actionSubjectId: ACTION_SUBJECT_ID.LAYOUT_COLUMN,
637
649
  attributes: {
638
- columnCount: redistributedWidths.length,
639
650
  endIndex: endIndex,
640
651
  inputMethod: inputMethod,
652
+ newColumnCount: redistributedWidths.length,
653
+ previousColumnCount: layoutSectionNode.childCount,
641
654
  selectedCount: selectedColumnCount,
642
655
  side: side,
643
656
  startIndex: startIndex
@@ -648,10 +661,12 @@ var insertLayoutColumnAt = function insertLayoutColumnAt(side, editorAnalyticsAP
648
661
  return tr;
649
662
  };
650
663
  };
651
- export var insertLayoutColumn = function insertLayoutColumn(side, editorAnalyticsAPI, api) {
652
- var inputMethod = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : INPUT_METHOD.LAYOUT_COLUMN_MENU;
653
- return function (_ref5) {
654
- var tr = _ref5.tr;
664
+ export var insertLayoutColumn = function insertLayoutColumn(_ref6, editorAnalyticsAPI, api) {
665
+ var side = _ref6.side,
666
+ _ref6$inputMethod = _ref6.inputMethod,
667
+ inputMethod = _ref6$inputMethod === void 0 ? INPUT_METHOD.LAYOUT_COLUMN_MENU : _ref6$inputMethod;
668
+ return function (_ref7) {
669
+ var tr = _ref7.tr;
655
670
  var result = insertLayoutColumnAt(side, editorAnalyticsAPI, inputMethod)({
656
671
  tr: tr
657
672
  });
@@ -661,9 +676,12 @@ export var insertLayoutColumn = function insertLayoutColumn(side, editorAnalytic
661
676
  return result;
662
677
  };
663
678
  };
664
- export var setLayoutColumnValign = function setLayoutColumnValign(valign, editorAnalyticsAPI, api) {
665
- return function (_ref6) {
666
- var tr = _ref6.tr;
679
+ export var setLayoutColumnValign = function setLayoutColumnValign(_ref8, editorAnalyticsAPI, api) {
680
+ var valign = _ref8.valign,
681
+ _ref8$inputMethod = _ref8.inputMethod,
682
+ inputMethod = _ref8$inputMethod === void 0 ? INPUT_METHOD.LAYOUT_COLUMN_MENU : _ref8$inputMethod;
683
+ return function (_ref9) {
684
+ var tr = _ref9.tr;
667
685
  if (!expValEqualsNoExposure('platform_editor_layout_column_menu', 'isEnabled', true)) {
668
686
  return null;
669
687
  }
@@ -671,20 +689,22 @@ export var setLayoutColumnValign = function setLayoutColumnValign(valign, editor
671
689
  if (!selectedLayoutColumnsResult) {
672
690
  return null;
673
691
  }
674
- var startIndex = selectedLayoutColumnsResult.startIndex,
692
+ var layoutSectionNode = selectedLayoutColumnsResult.layoutSectionNode,
693
+ startIndex = selectedLayoutColumnsResult.startIndex,
675
694
  endIndex = selectedLayoutColumnsResult.endIndex,
676
695
  selectedLayoutColumns = selectedLayoutColumnsResult.selectedLayoutColumns;
677
- var columnsToUpdate = selectedLayoutColumns.filter(function (_ref7) {
678
- var node = _ref7.node;
679
- return node.attrs.valign !== valign;
696
+ var previousValign = getPreviousLayoutColumnValign(selectedLayoutColumns);
697
+ var columnsToUpdate = selectedLayoutColumns.filter(function (_ref0) {
698
+ var node = _ref0.node;
699
+ return getLayoutColumnValign(node) !== valign;
680
700
  });
681
701
  if (columnsToUpdate.length === 0) {
682
702
  return null;
683
703
  }
684
704
  var updatedColumnCount = columnsToUpdate.length;
685
- columnsToUpdate.forEach(function (_ref8) {
686
- var node = _ref8.node,
687
- pos = _ref8.pos;
705
+ columnsToUpdate.forEach(function (_ref1) {
706
+ var node = _ref1.node,
707
+ pos = _ref1.pos;
688
708
  tr.setNodeMarkup(pos, node.type, _objectSpread(_objectSpread({}, node.attrs), {}, {
689
709
  valign: valign
690
710
  }));
@@ -694,8 +714,10 @@ export var setLayoutColumnValign = function setLayoutColumnValign(valign, editor
694
714
  actionSubject: ACTION_SUBJECT.DOCUMENT,
695
715
  actionSubjectId: ACTION_SUBJECT_ID.LAYOUT_COLUMN,
696
716
  attributes: {
717
+ columnCount: layoutSectionNode.childCount,
697
718
  endIndex: endIndex,
698
- inputMethod: INPUT_METHOD.LAYOUT_COLUMN_MENU,
719
+ inputMethod: inputMethod,
720
+ previousValign: previousValign,
699
721
  selectedCount: selectedLayoutColumns.length,
700
722
  startIndex: startIndex,
701
723
  updatedCount: updatedColumnCount,
@@ -710,13 +732,13 @@ export var setLayoutColumnValign = function setLayoutColumnValign(valign, editor
710
732
  };
711
733
  export var distributeLayoutColumns = function distributeLayoutColumns(editorAnalyticsAPI, api) {
712
734
  return function () {
713
- var _ref9 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
714
- _ref9$inputMethod = _ref9.inputMethod,
715
- inputMethod = _ref9$inputMethod === void 0 ? INPUT_METHOD.LAYOUT_COLUMN_MENU : _ref9$inputMethod,
716
- _ref9$target = _ref9.target,
717
- target = _ref9$target === void 0 ? 'selectedColumns' : _ref9$target;
718
- return function (_ref0) {
719
- var tr = _ref0.tr;
735
+ var _ref10 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
736
+ _ref10$inputMethod = _ref10.inputMethod,
737
+ inputMethod = _ref10$inputMethod === void 0 ? INPUT_METHOD.LAYOUT_COLUMN_MENU : _ref10$inputMethod,
738
+ _ref10$target = _ref10.target,
739
+ target = _ref10$target === void 0 ? 'selectedColumns' : _ref10$target;
740
+ return function (_ref11) {
741
+ var tr = _ref11.tr;
720
742
  if (!expValEqualsNoExposure('platform_editor_layout_column_menu', 'isEnabled', true)) {
721
743
  return null;
722
744
  }
@@ -731,8 +753,8 @@ export var distributeLayoutColumns = function distributeLayoutColumns(editorAnal
731
753
  var existingWidths = mapChildren(layoutSectionNode, function (column) {
732
754
  return column.attrs.width;
733
755
  });
734
- var selectedWidths = selectedLayoutColumns.map(function (_ref1) {
735
- var node = _ref1.node;
756
+ var selectedWidths = selectedLayoutColumns.map(function (_ref12) {
757
+ var node = _ref12.node;
736
758
  return node.attrs.width;
737
759
  });
738
760
  var distribution = calculateDistribution(selectedWidths);
@@ -764,9 +786,9 @@ export var distributeLayoutColumns = function distributeLayoutColumns(editorAnal
764
786
  });
765
787
 
766
788
  // Apply widths via setNodeMarkup per selected column — keeps nodes in place (preserves identity, marks, decorations)
767
- selectedLayoutColumns.forEach(function (_ref10, i) {
768
- var node = _ref10.node,
769
- pos = _ref10.pos;
789
+ selectedLayoutColumns.forEach(function (_ref13, i) {
790
+ var node = _ref13.node,
791
+ pos = _ref13.pos;
770
792
  var colIdx = startIndex + i;
771
793
  tr.setNodeMarkup(pos, node.type, _objectSpread(_objectSpread({}, node.attrs), {}, {
772
794
  width: newWidths[colIdx]
@@ -781,7 +803,8 @@ export var distributeLayoutColumns = function distributeLayoutColumns(editorAnal
781
803
  endIndex: endIndex,
782
804
  inputMethod: inputMethod,
783
805
  selectedCount: selectedLayoutColumns.length,
784
- startIndex: startIndex
806
+ startIndex: startIndex,
807
+ target: target
785
808
  },
786
809
  eventType: EVENT_TYPE.TRACK
787
810
  })(tr);
@@ -791,12 +814,12 @@ export var distributeLayoutColumns = function distributeLayoutColumns(editorAnal
791
814
  };
792
815
  };
793
816
  };
794
- export var toggleLayoutColumnMenu = function toggleLayoutColumnMenu(_ref11) {
795
- var anchorPos = _ref11.anchorPos,
796
- isOpen = _ref11.isOpen,
797
- openedViaKeyboard = _ref11.openedViaKeyboard;
798
- return function (_ref12) {
799
- var tr = _ref12.tr;
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;
800
823
  tr.setMeta('toggleLayoutColumnMenu', {
801
824
  anchorPos: anchorPos,
802
825
  isOpen: isOpen,
@@ -807,25 +830,29 @@ export var toggleLayoutColumnMenu = function toggleLayoutColumnMenu(_ref11) {
807
830
  };
808
831
  };
809
832
  export var setLayoutColumnDangerPreview = function setLayoutColumnDangerPreview(show) {
810
- return function (_ref13) {
811
- var _selectedLayoutColumn;
812
- var tr = _ref13.tr;
833
+ return function (_ref16) {
834
+ var _selectedLayoutColumn2;
835
+ var tr = _ref16.tr;
813
836
  var selectedLayoutColumnsResult = getSelectedLayoutColumnsFromSelection(tr.selection);
814
- var positions = show ? (_selectedLayoutColumn = selectedLayoutColumnsResult === null || selectedLayoutColumnsResult === void 0 ? void 0 : selectedLayoutColumnsResult.selectedLayoutColumns.map(function (_ref14) {
815
- var pos = _ref14.pos;
837
+ var positions = show ? (_selectedLayoutColumn2 = selectedLayoutColumnsResult === null || selectedLayoutColumnsResult === void 0 ? void 0 : selectedLayoutColumnsResult.selectedLayoutColumns.map(function (_ref17) {
838
+ var pos = _ref17.pos;
816
839
  return pos;
817
- })) !== null && _selectedLayoutColumn !== void 0 ? _selectedLayoutColumn : [] : null;
840
+ })) !== null && _selectedLayoutColumn2 !== void 0 ? _selectedLayoutColumn2 : [] : null;
818
841
  tr.setMeta('layoutColumnDangerPreview', positions);
819
842
  tr.setMeta('addToHistory', false);
820
843
  tr.setMeta('scrollIntoView', false);
821
844
  return tr;
822
845
  };
823
846
  };
824
- export var deleteLayoutColumn = function deleteLayoutColumn(editorAnalyticsAPI, api) {
825
- var inputMethod = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : INPUT_METHOD.LAYOUT_COLUMN_MENU;
826
- return function (_ref15) {
847
+ 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;
851
+ var editorAnalyticsAPI = arguments.length > 1 ? arguments[1] : undefined;
852
+ var api = arguments.length > 2 ? arguments[2] : undefined;
853
+ return function (_ref19) {
827
854
  var _api$blockControls4;
828
- var tr = _ref15.tr;
855
+ var tr = _ref19.tr;
829
856
  if (!expValEqualsNoExposure('platform_editor_layout_column_menu', 'isEnabled', true)) {
830
857
  return null;
831
858
  }
@@ -838,15 +865,21 @@ export var deleteLayoutColumn = function deleteLayoutColumn(editorAnalyticsAPI,
838
865
  selectedLayoutColumns = selectedLayoutColumnsResult.selectedLayoutColumns,
839
866
  startIndex = selectedLayoutColumnsResult.startIndex,
840
867
  endIndex = selectedLayoutColumnsResult.endIndex;
841
- var emitDeleteColumnAnalytics = function emitDeleteColumnAnalytics(columnCount) {
868
+ var hadContent = selectedLayoutColumns.some(function (_ref20) {
869
+ var node = _ref20.node;
870
+ return hasLayoutColumnContent(node);
871
+ });
872
+ var emitDeleteColumnAnalytics = function emitDeleteColumnAnalytics(newColumnCount) {
842
873
  editorAnalyticsAPI === null || editorAnalyticsAPI === void 0 || editorAnalyticsAPI.attachAnalyticsEvent({
843
874
  action: ACTION.DELETED,
844
875
  actionSubject: ACTION_SUBJECT.DOCUMENT,
845
876
  actionSubjectId: ACTION_SUBJECT_ID.LAYOUT_COLUMN,
846
877
  attributes: {
847
- columnCount: columnCount,
848
878
  endIndex: endIndex,
879
+ hadContent: hadContent,
849
880
  inputMethod: inputMethod,
881
+ newColumnCount: newColumnCount,
882
+ previousColumnCount: layoutSectionNode.childCount,
850
883
  selectedCount: selectedLayoutColumns.length,
851
884
  startIndex: startIndex
852
885
  },
@@ -1,6 +1,7 @@
1
1
  export var MAX_STANDARD_LAYOUT_COLUMNS = 3;
2
2
  export var MAX_LAYOUT_COLUMNS = 5;
3
3
  export var MIN_LAYOUT_COLUMN_WIDTH_PERCENT = 5;
4
+ export var DEFAULT_LAYOUT_COLUMN_VALIGN = 'top';
4
5
  export var EVEN_DISTRIBUTED_COL_WIDTHS = {
5
6
  1: 100,
6
7
  2: 50,