@atlaskit/editor-plugin-table 7.3.0 → 7.3.2

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 (98) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/afm-cc/tsconfig.json +3 -0
  3. package/dist/cjs/commands/misc.js +4 -2
  4. package/dist/cjs/commands/selection.js +4 -2
  5. package/dist/cjs/pm-plugins/drag-and-drop/commands.js +3 -1
  6. package/dist/cjs/pm-plugins/drag-and-drop/plugin.js +33 -1
  7. package/dist/cjs/pm-plugins/drag-and-drop/reducer.js +2 -1
  8. package/dist/cjs/pm-plugins/table-selection-keymap.js +2 -2
  9. package/dist/cjs/ui/DragHandle/HandleIconComponent.js +1 -3
  10. package/dist/cjs/ui/DragHandle/index.js +24 -10
  11. package/dist/cjs/ui/FloatingDragMenu/DragMenu.js +75 -33
  12. package/dist/cjs/ui/FloatingDragMenu/DropdownMenu.js +123 -0
  13. package/dist/cjs/ui/FloatingDragMenu/index.js +2 -2
  14. package/dist/cjs/ui/TableFloatingColumnControls/ColumnControls/index.js +24 -35
  15. package/dist/cjs/ui/TableFloatingColumnControls/index.js +1 -2
  16. package/dist/cjs/ui/TableFloatingControls/CornerControls/DragCornerControls.js +4 -0
  17. package/dist/cjs/ui/TableFloatingControls/RowControls/DragControls.js +26 -33
  18. package/dist/cjs/ui/common-styles.js +1 -1
  19. package/dist/cjs/ui/consts.js +3 -2
  20. package/dist/es2019/commands/misc.js +4 -4
  21. package/dist/es2019/commands/selection.js +4 -4
  22. package/dist/es2019/pm-plugins/drag-and-drop/commands.js +3 -3
  23. package/dist/es2019/pm-plugins/drag-and-drop/plugin.js +34 -1
  24. package/dist/es2019/pm-plugins/drag-and-drop/reducer.js +2 -1
  25. package/dist/es2019/pm-plugins/table-selection-keymap.js +2 -2
  26. package/dist/es2019/ui/DragHandle/HandleIconComponent.js +1 -3
  27. package/dist/es2019/ui/DragHandle/index.js +27 -10
  28. package/dist/es2019/ui/FloatingDragMenu/DragMenu.js +72 -32
  29. package/dist/es2019/ui/FloatingDragMenu/DropdownMenu.js +109 -0
  30. package/dist/es2019/ui/FloatingDragMenu/index.js +2 -2
  31. package/dist/es2019/ui/TableFloatingColumnControls/ColumnControls/index.js +24 -35
  32. package/dist/es2019/ui/TableFloatingColumnControls/index.js +1 -2
  33. package/dist/es2019/ui/TableFloatingControls/CornerControls/DragCornerControls.js +4 -0
  34. package/dist/es2019/ui/TableFloatingControls/RowControls/DragControls.js +26 -33
  35. package/dist/es2019/ui/common-styles.js +11 -1
  36. package/dist/es2019/ui/consts.js +2 -1
  37. package/dist/esm/commands/misc.js +4 -2
  38. package/dist/esm/commands/selection.js +4 -2
  39. package/dist/esm/pm-plugins/drag-and-drop/commands.js +3 -2
  40. package/dist/esm/pm-plugins/drag-and-drop/plugin.js +33 -1
  41. package/dist/esm/pm-plugins/drag-and-drop/reducer.js +2 -1
  42. package/dist/esm/pm-plugins/table-selection-keymap.js +2 -2
  43. package/dist/esm/ui/DragHandle/HandleIconComponent.js +1 -3
  44. package/dist/esm/ui/DragHandle/index.js +23 -9
  45. package/dist/esm/ui/FloatingDragMenu/DragMenu.js +74 -35
  46. package/dist/esm/ui/FloatingDragMenu/DropdownMenu.js +116 -0
  47. package/dist/esm/ui/FloatingDragMenu/index.js +2 -2
  48. package/dist/esm/ui/TableFloatingColumnControls/ColumnControls/index.js +24 -35
  49. package/dist/esm/ui/TableFloatingColumnControls/index.js +1 -2
  50. package/dist/esm/ui/TableFloatingControls/CornerControls/DragCornerControls.js +4 -0
  51. package/dist/esm/ui/TableFloatingControls/RowControls/DragControls.js +26 -33
  52. package/dist/esm/ui/common-styles.js +1 -1
  53. package/dist/esm/ui/consts.js +2 -1
  54. package/dist/types/commands/misc.d.ts +2 -2
  55. package/dist/types/commands/selection.d.ts +2 -2
  56. package/dist/types/pm-plugins/drag-and-drop/actions.d.ts +1 -0
  57. package/dist/types/pm-plugins/drag-and-drop/commands.d.ts +2 -1
  58. package/dist/types/pm-plugins/drag-and-drop/types.d.ts +2 -0
  59. package/dist/types/ui/DragHandle/HandleIconComponent.d.ts +1 -2
  60. package/dist/types/ui/DragHandle/index.d.ts +3 -2
  61. package/dist/types/ui/FloatingDragMenu/DragMenu.d.ts +7 -8
  62. package/dist/types/ui/FloatingDragMenu/DropdownMenu.d.ts +30 -0
  63. package/dist/types/ui/TableFloatingColumnControls/ColumnControls/index.d.ts +1 -2
  64. package/dist/types/ui/TableFloatingControls/RowControls/DragControls.d.ts +1 -1
  65. package/dist/types/ui/consts.d.ts +1 -0
  66. package/dist/types-ts4.5/commands/misc.d.ts +2 -2
  67. package/dist/types-ts4.5/commands/selection.d.ts +2 -2
  68. package/dist/types-ts4.5/pm-plugins/drag-and-drop/actions.d.ts +1 -0
  69. package/dist/types-ts4.5/pm-plugins/drag-and-drop/commands.d.ts +2 -1
  70. package/dist/types-ts4.5/pm-plugins/drag-and-drop/types.d.ts +2 -0
  71. package/dist/types-ts4.5/ui/DragHandle/HandleIconComponent.d.ts +1 -2
  72. package/dist/types-ts4.5/ui/DragHandle/index.d.ts +3 -2
  73. package/dist/types-ts4.5/ui/FloatingDragMenu/DragMenu.d.ts +7 -8
  74. package/dist/types-ts4.5/ui/FloatingDragMenu/DropdownMenu.d.ts +30 -0
  75. package/dist/types-ts4.5/ui/TableFloatingColumnControls/ColumnControls/index.d.ts +1 -2
  76. package/dist/types-ts4.5/ui/TableFloatingControls/RowControls/DragControls.d.ts +1 -1
  77. package/dist/types-ts4.5/ui/consts.d.ts +1 -0
  78. package/package.json +3 -2
  79. package/src/commands/misc.ts +17 -4
  80. package/src/commands/selection.ts +12 -4
  81. package/src/pm-plugins/drag-and-drop/actions.ts +1 -0
  82. package/src/pm-plugins/drag-and-drop/commands.ts +3 -0
  83. package/src/pm-plugins/drag-and-drop/plugin.ts +47 -0
  84. package/src/pm-plugins/drag-and-drop/reducer.ts +1 -0
  85. package/src/pm-plugins/drag-and-drop/types.ts +3 -0
  86. package/src/pm-plugins/table-selection-keymap.ts +2 -2
  87. package/src/ui/DragHandle/HandleIconComponent.tsx +2 -9
  88. package/src/ui/DragHandle/index.tsx +39 -16
  89. package/src/ui/FloatingDragMenu/DragMenu.tsx +362 -310
  90. package/src/ui/FloatingDragMenu/DropdownMenu.tsx +150 -0
  91. package/src/ui/FloatingDragMenu/index.tsx +3 -3
  92. package/src/ui/TableFloatingColumnControls/ColumnControls/index.tsx +72 -91
  93. package/src/ui/TableFloatingColumnControls/index.tsx +1 -2
  94. package/src/ui/TableFloatingControls/CornerControls/DragCornerControls.tsx +5 -0
  95. package/src/ui/TableFloatingControls/RowControls/DragControls.tsx +89 -104
  96. package/src/ui/common-styles.ts +11 -1
  97. package/src/ui/consts.ts +1 -0
  98. package/tsconfig.app.json +3 -0
@@ -25,7 +25,6 @@ export const ColumnControls = ({
25
25
  tableActive,
26
26
  tableRef,
27
27
  hoveredCell,
28
- isResizing,
29
28
  stickyTop,
30
29
  localId,
31
30
  isInDanger,
@@ -102,15 +101,15 @@ export const ColumnControls = ({
102
101
  clearHoverSelection()(state, dispatch);
103
102
  }
104
103
  }, [editorView, tableActive]);
105
- const handleMouseUp = useCallback(event => {
104
+ const toggleDragMenuHandler = useCallback((trigger, event) => {
106
105
  const {
107
106
  state,
108
107
  dispatch
109
108
  } = editorView;
110
- if (event.shiftKey) {
109
+ if (event !== null && event !== void 0 && event.shiftKey) {
111
110
  return;
112
111
  }
113
- toggleDragMenu(undefined, 'column', colIndex)(state, dispatch);
112
+ toggleDragMenu(undefined, 'column', colIndex, trigger)(state, dispatch);
114
113
  }, [editorView, colIndex]);
115
114
  const colIndexes = useMemo(() => {
116
115
  return [colIndex];
@@ -119,31 +118,16 @@ export const ColumnControls = ({
119
118
  var _getScrollOffset;
120
119
  columnControlsRef.current.scrollLeft = (_getScrollOffset = getScrollOffset === null || getScrollOffset === void 0 ? void 0 : getScrollOffset()) !== null && _getScrollOffset !== void 0 ? _getScrollOffset : 0;
121
120
  }
122
- const generateHandleByType = type => {
121
+ const generateHandleByType = (type, appearance, gridColumn, indexes) => {
123
122
  var _rowHeights$reduce, _colWidths$reduce;
124
- if (!hoveredCell || !(colWidths !== null && colWidths !== void 0 && colWidths.length)) {
125
- return null;
126
- }
127
123
  const isHover = type === 'hover';
128
- const isColumnsSelected = selectedColIndexes.length > 0;
129
124
  const previewHeight = (_rowHeights$reduce = rowHeights === null || rowHeights === void 0 ? void 0 : rowHeights.reduce((sum, cur) => sum + cur, 0)) !== null && _rowHeights$reduce !== void 0 ? _rowHeights$reduce : 0;
130
- const showCondition = isHover ? isColumnsSelected && !selectedColIndexes.includes(colIndex) && Number.isFinite(hoveredCell === null || hoveredCell === void 0 ? void 0 : hoveredCell.colIndex) : selectedColIndexes.length < (colWidths === null || colWidths === void 0 ? void 0 : colWidths.length) && Number.isFinite(hoveredCell === null || hoveredCell === void 0 ? void 0 : hoveredCell.colIndex);
131
- if (!showCondition) {
132
- return null;
133
- }
134
- const gridColumnPosition = `${colIndex + 1} / span 1`;
135
- const selectedColumnPosition = `${selectedColIndexes[0] + 1} / span ${selectedColIndexes.length}`;
136
- const hoveredAppearance = selectedColIndexes.includes(colIndex) ? isInDanger ? 'danger' : 'selected' : 'default';
137
- const currentSelectionAppearance = isColumnsSelected ? isInDanger ? 'danger' : 'selected' : hoveredAppearance;
138
- const isSelecting = isColumnsSelected && !isHover;
139
-
140
- // this indexes are used to calculate the drag and drop source
141
- const indexes = isColumnsSelected ? isHover ? colIndexes : selectedColIndexes : colIndexes;
142
125
  const previewWidth = (_colWidths$reduce = colWidths === null || colWidths === void 0 ? void 0 : colWidths.reduce((sum, v, i) => sum + (v !== null && v !== void 0 ? v : tableCellMinWidth) * (indexes.includes(i) ? 1 : 0), 0)) !== null && _colWidths$reduce !== void 0 ? _colWidths$reduce : tableCellMinWidth;
143
126
  return /*#__PURE__*/React.createElement("div", {
144
127
  key: type,
145
128
  style: {
146
- gridColumn: isSelecting ? selectedColumnPosition : gridColumnPosition,
129
+ gridColumn,
130
+ gridRow: '1',
147
131
  display: 'flex',
148
132
  justifyContent: 'center',
149
133
  alignItems: 'center',
@@ -153,33 +137,38 @@ export const ColumnControls = ({
153
137
  width: '100%',
154
138
  position: 'relative'
155
139
  },
156
- "data-column-control-index": hoveredCell.colIndex,
157
- "data-testid": `table-floating-column-${isSelecting ? selectedColIndexes[0] : colIndex}-drag-handle`
140
+ "data-testid": `table-floating-column-${isHover ? colIndex : selectedColIndexes[0]}-drag-handle`
158
141
  }, /*#__PURE__*/React.createElement(DragHandle, {
159
142
  isDragMenuTarget: !isHover,
160
143
  direction: "column",
161
144
  tableLocalId: localId || '',
162
145
  indexes: indexes,
163
- forceDefaultHandle: isHover ? false : isColumnsSelected,
164
146
  previewWidth: previewWidth,
147
+ forceDefaultHandle: !isHover,
165
148
  previewHeight: previewHeight,
166
- appearance: isSelecting ? currentSelectionAppearance : hoveredAppearance,
149
+ appearance: appearance,
167
150
  onClick: handleClick,
168
151
  onMouseOver: handleMouseOver,
169
152
  onMouseOut: handleMouseOut,
170
- onMouseUp: handleMouseUp,
153
+ toggleDragMenu: toggleDragMenuHandler,
171
154
  editorView: editorView
172
155
  }));
173
156
  };
174
- const columnHandles = hoveredCell => {
175
- if (!hoveredCell) {
157
+ const columnHandles = () => {
158
+ const handles = [];
159
+ const isColumnSelected = selectedColIndexes.length > 0;
160
+ const isEntireTableSelected = (colWidths || []).length > selectedColIndexes.length;
161
+ if (!tableActive) {
176
162
  return null;
177
163
  }
178
- if (hoveredCell.colIndex === undefined) {
179
- return generateHandleByType('selected');
164
+
165
+ // placeholder / selected need to always render at least one handle
166
+ // so it can be focused via keyboard shortcuts
167
+ handles.push(generateHandleByType('selected', isColumnSelected && isEntireTableSelected ? isInDanger ? 'danger' : 'selected' : 'placeholder', `${selectedColIndexes[0] + 1} / span ${selectedColIndexes.length}`, selectedColIndexes));
168
+ if (hoveredCell && isTableHovered && colIndex !== undefined && !selectedColIndexes.includes(colIndex)) {
169
+ handles.push(generateHandleByType('hover', 'default', `${colIndex + 1} / span 1`, colIndexes));
180
170
  }
181
- const sortedHandles = [generateHandleByType('hover'), generateHandleByType('selected')];
182
- return hoveredCell.colIndex < selectedColIndexes[0] ? sortedHandles : sortedHandles.reverse();
171
+ return handles;
183
172
  };
184
173
  const containerWidth = isNumberColumnEnabled && tableContainerWidth ? tableContainerWidth - akEditorTableNumberColumnWidth : tableContainerWidth;
185
174
  return /*#__PURE__*/React.createElement("div", {
@@ -196,7 +185,7 @@ export const ColumnControls = ({
196
185
  overflowX: stickyTop ? 'hidden' : 'visible',
197
186
  pointerEvents: isDragging ? 'none' : undefined
198
187
  }
199
- }, !isResizing && columnParams.map(({
188
+ }, columnParams.map(({
200
189
  startIndex,
201
190
  endIndex
202
191
  }, index) => /*#__PURE__*/React.createElement("div", {
@@ -213,6 +202,6 @@ export const ColumnControls = ({
213
202
  style: columnParams.length - 1 === index ? {
214
203
  right: '0'
215
204
  } : {}
216
- }))), tableActive && isTableHovered && !isResizing && columnHandles(hoveredCell)));
205
+ }))), columnHandles()));
217
206
  };
218
207
  export default ColumnControls;
@@ -76,7 +76,7 @@ export const TableFloatingColumnControls = ({
76
76
  }
77
77
  return [0];
78
78
  }, [tableRef, tableRect.height]);
79
- if (!tableRef || !tableActive) {
79
+ if (!tableRef || !tableActive || isResizing) {
80
80
  return null;
81
81
  }
82
82
  const colWidths = getColumnsWidths(editorView);
@@ -97,7 +97,6 @@ export const TableFloatingColumnControls = ({
97
97
  editorView: editorView,
98
98
  hoveredCell: hoveredCell,
99
99
  tableRef: tableRef,
100
- isResizing: isResizing,
101
100
  tableActive: tableActive,
102
101
  isTableHovered: isTableHovered,
103
102
  stickyTop: tableActive ? stickyTop : undefined,
@@ -8,6 +8,7 @@ import { TableCssClassName as ClassName } from '../../../types';
8
8
  const DragCornerControlsComponent = ({
9
9
  editorView,
10
10
  isInDanger,
11
+ isResizing,
11
12
  intl: {
12
13
  formatMessage
13
14
  }
@@ -36,6 +37,9 @@ const DragCornerControlsComponent = ({
36
37
  }
37
38
  return isTableSelected(selection);
38
39
  }, [editorView.state]);
40
+ if (isResizing) {
41
+ return null;
42
+ }
39
43
  return /*#__PURE__*/React.createElement("button", {
40
44
  className: classnames(ClassName.DRAG_CORNER_BUTTON, {
41
45
  active: isActive,
@@ -73,11 +73,11 @@ const DragControlsComponent = ({
73
73
  }
74
74
  });
75
75
  }, [editorView]);
76
- const onMouseUp = useCallback(event => {
77
- if (event.shiftKey) {
76
+ const toggleDragMenuHandler = useCallback((trigger, event) => {
77
+ if (event !== null && event !== void 0 && event.shiftKey) {
78
78
  return;
79
79
  }
80
- toggleDragMenu(undefined, 'row', hoveredCell === null || hoveredCell === void 0 ? void 0 : hoveredCell.rowIndex)(editorView.state, editorView.dispatch);
80
+ toggleDragMenu(undefined, 'row', hoveredCell === null || hoveredCell === void 0 ? void 0 : hoveredCell.rowIndex, trigger)(editorView.state, editorView.dispatch);
81
81
  }, [editorView, hoveredCell === null || hoveredCell === void 0 ? void 0 : hoveredCell.rowIndex]);
82
82
  const rowIndex = hoveredCell === null || hoveredCell === void 0 ? void 0 : hoveredCell.rowIndex;
83
83
  const handleMouseOut = useCallback(() => {
@@ -114,29 +114,13 @@ const DragControlsComponent = ({
114
114
  selectRows(selectedRowIndexes);
115
115
  }
116
116
  }, [rowIndex, selectRow, selectRows, selectedRowIndexes]);
117
- const generateHandleByType = type => {
118
- if (!hoveredCell) {
119
- return null;
120
- }
117
+ const generateHandleByType = (type, appearance, gridRow, indexes) => {
121
118
  const isHover = type === 'hover';
122
- const isRowsSelected = selectedRowIndexes.length > 0;
123
- const showCondition = isHover ? isRowsSelected && !selectedRowIndexes.includes(rowIndex) && Number.isFinite(hoveredCell === null || hoveredCell === void 0 ? void 0 : hoveredCell.colIndex) : selectedRowIndexes.length < rowHeights.length && rowIndex < rowHeights.length && Number.isFinite(hoveredCell === null || hoveredCell === void 0 ? void 0 : hoveredCell.colIndex);
124
- if (!showCondition) {
125
- return null;
126
- }
127
- const gridRowPosition = `${rowIndex + 1} / span 1`;
128
-
129
- // if more than one row is selected, ensure the handle spans over the selected range
130
- const selectedRowPosition = `${selectedRowIndexes[0] + 1} / span ${selectedRowIndexes.length}`;
131
- const hoveredAppearance = selectedRowIndexes.includes(rowIndex) ? isInDanger ? 'danger' : 'selected' : 'default';
132
- const currentSelectionAppearance = isRowsSelected ? isInDanger ? 'danger' : 'selected' : hoveredAppearance;
133
- const isSelecting = isRowsSelected && !isHover;
134
- const indexes = isRowsSelected ? isHover ? rowIndexes : selectedRowIndexes : rowIndexes;
135
119
  const previewHeight = rowHeights.reduce((sum, v, i) => sum + v * (indexes.includes(i) ? 1 : 0), 0);
136
120
  return /*#__PURE__*/React.createElement("div", {
137
121
  key: type,
138
122
  style: {
139
- gridRow: isSelecting ? selectedRowPosition : gridRowPosition,
123
+ gridRow,
140
124
  gridColumn: '2',
141
125
  // DragHandle uses `transform: rotate(90)`, which doesn't affect its parent (this div) causing the width of this element to be the true height of the drag handle
142
126
  display: 'flex',
@@ -145,33 +129,42 @@ const DragControlsComponent = ({
145
129
  position: 'relative',
146
130
  right: '-0.5px'
147
131
  },
148
- "data-testid": `table-floating-row-${isSelecting ? selectedRowIndexes[0] : rowIndex}-drag-handle`
132
+ "data-testid": `table-floating-row-${isHover ? rowIndex : selectedRowIndexes[0]}-drag-handle`
149
133
  }, /*#__PURE__*/React.createElement(DragHandle, {
150
134
  isDragMenuTarget: !isHover,
151
135
  direction: "row",
152
136
  tableLocalId: currentNodeLocalId,
153
137
  indexes: indexes,
154
- forceDefaultHandle: isHover ? false : isRowsSelected,
138
+ forceDefaultHandle: !isHover,
155
139
  previewWidth: tableWidth,
156
140
  previewHeight: previewHeight,
157
- appearance: isSelecting ? currentSelectionAppearance : hoveredAppearance,
141
+ appearance: appearance,
158
142
  onClick: handleClick,
159
143
  onMouseOver: handleMouseOver,
160
144
  onMouseOut: handleMouseOut,
161
- onMouseUp: onMouseUp,
145
+ toggleDragMenu: toggleDragMenuHandler,
162
146
  editorView: editorView
163
147
  }));
164
148
  };
165
- const rowHandles = hoveredCell => {
166
- if (!hoveredCell) {
149
+ const rowHandles = () => {
150
+ const handles = [];
151
+ const isRowSelected = selectedRowIndexes.length > 0;
152
+ const isEntireTableSelected = rowHeights.length > selectedRowIndexes.length;
153
+ if (!tableActive) {
167
154
  return null;
168
155
  }
169
- if (hoveredCell.rowIndex === undefined) {
170
- return generateHandleByType('selected');
156
+
157
+ // placeholder / selected need to always render at least one handle
158
+ // so it can be focused via keyboard shortcuts
159
+ handles.push(generateHandleByType('selected', isRowSelected && isEntireTableSelected ? isInDanger ? 'danger' : 'selected' : 'placeholder', `${selectedRowIndexes[0] + 1} / span ${selectedRowIndexes.length}`, selectedRowIndexes));
160
+ if (hoveredCell && isTableHovered && rowIndex !== undefined && !selectedRowIndexes.includes(rowIndex) && rowIndex < rowHeights.length) {
161
+ handles.push(generateHandleByType('hover', 'default', `${rowIndex + 1} / span 1`, rowIndexes));
171
162
  }
172
- const sortedHandles = [generateHandleByType('hover'), generateHandleByType('selected')];
173
- return hoveredCell.rowIndex < selectedRowIndexes[0] ? sortedHandles : sortedHandles.reverse();
163
+ return handles;
174
164
  };
165
+ if (isResizing) {
166
+ return null;
167
+ }
175
168
  return /*#__PURE__*/React.createElement("div", {
176
169
  className: ClassName.DRAG_ROW_CONTROLS,
177
170
  style: {
@@ -181,7 +174,7 @@ const DragControlsComponent = ({
181
174
  },
182
175
  onMouseMove: handleMouseMove,
183
176
  contentEditable: false
184
- }, !isResizing && rowsParams.map(({
177
+ }, rowsParams.map(({
185
178
  startIndex,
186
179
  endIndex
187
180
  }, index) => /*#__PURE__*/React.createElement(Fragment, {
@@ -210,6 +203,6 @@ const DragControlsComponent = ({
210
203
  position: 'relative',
211
204
  left: "var(--ds-space-negative-100, -8px)"
212
205
  }
213
- }))), tableActive && isTableHovered && !isResizing && Number.isFinite(rowIndex) && rowHandles(hoveredCell));
206
+ }))), rowHandles());
214
207
  };
215
208
  export const DragControls = injectIntl(DragControlsComponent);
@@ -684,8 +684,13 @@ export const tableStyles = props => {
684
684
  display: flex;
685
685
  justify-content: center;
686
686
  align-items: center;
687
- outline: none !important;
688
687
  background: transparent;
688
+ outline: none;
689
+
690
+ &.placeholder {
691
+ background-color: transparent;
692
+ border: 2px solid transparent;
693
+ }
689
694
 
690
695
  &.${ClassName.DRAG_HANDLE_DISABLED} {
691
696
  & svg {
@@ -723,6 +728,11 @@ export const tableStyles = props => {
723
728
  }
724
729
 
725
730
  &.selected {
731
+ :focus {
732
+ outline: 2px solid ${"var(--ds-border-focused, #2684FF)"};
733
+ outline-offset: 1px;
734
+ }
735
+
726
736
  svg {
727
737
  rect {
728
738
  fill: ${"var(--ds-background-accent-blue-subtle, #579dff)"};
@@ -68,4 +68,5 @@ export const STICKY_HEADER_TOGGLE_TOLERANCE_MS = 5;
68
68
  export const TABLE_GUIDELINE_VISIBLE_ADJUSTMENT = -68;
69
69
  export const dragMenuDropdownWidth = 250;
70
70
  export const dragTableInsertColumnButtonSize = 16;
71
- export const dropTargetExtendedWidth = 150;
71
+ export const dropTargetExtendedWidth = 150;
72
+ export const colorPalletteColumns = 7;
@@ -321,6 +321,7 @@ export var setMultipleCellAttrs = function setMultipleCellAttrs(attrs, targetCel
321
321
  };
322
322
  };
323
323
  export var selectColumn = function selectColumn(column, expand) {
324
+ var triggeredByKeyboard = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
324
325
  return createCommand(function (state) {
325
326
  var cells = getCellsInColumn(column)(state.tr.selection);
326
327
  if (!cells || !cells.length || typeof cells[0].pos !== 'number') {
@@ -337,7 +338,7 @@ export var selectColumn = function selectColumn(column, expand) {
337
338
  }
338
339
  };
339
340
  }, function (tr) {
340
- return selectColumnTransform(column, expand)(tr).setMeta('addToHistory', false);
341
+ return selectColumnTransform(column, expand)(tr).setMeta('addToHistory', false).setMeta('selectedColumnViaKeyboard', triggeredByKeyboard);
341
342
  });
342
343
  };
343
344
  export var selectColumns = function selectColumns(columnIndexes) {
@@ -372,6 +373,7 @@ export var selectColumns = function selectColumns(columnIndexes) {
372
373
  });
373
374
  };
374
375
  export var selectRow = function selectRow(row, expand) {
376
+ var triggeredByKeyboard = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
375
377
  return createCommand(function (state) {
376
378
  var targetCellPosition;
377
379
  var cells = getCellsInRow(row)(state.tr.selection);
@@ -385,7 +387,7 @@ export var selectRow = function selectRow(row, expand) {
385
387
  }
386
388
  };
387
389
  }, function (tr) {
388
- return selectRowTransform(row, expand)(tr).setMeta('addToHistory', false);
390
+ return selectRowTransform(row, expand)(tr).setMeta('addToHistory', false).setMeta('selectedRowViaKeyboard', triggeredByKeyboard);
389
391
  });
390
392
  };
391
393
  export var selectRows = function selectRows(rowIndexes) {
@@ -82,6 +82,7 @@ var arrowRightFromCellSelection = function arrowRightFromCellSelection(editorSel
82
82
  };
83
83
  export var selectColumns = function selectColumns(editorSelectionAPI) {
84
84
  return function () {
85
+ var triggeredByKeyboard = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
85
86
  return function (state, dispatch) {
86
87
  var selection = state.selection;
87
88
  var table = findTable(selection);
@@ -94,7 +95,7 @@ export var selectColumns = function selectColumns(editorSelectionAPI) {
94
95
  })(state, dispatch);
95
96
  }
96
97
  if (table && rect) {
97
- return selectColumn(rect.left)(state, dispatch);
98
+ return selectColumn(rect.left, undefined, triggeredByKeyboard)(state, dispatch);
98
99
  }
99
100
  return false;
100
101
  };
@@ -102,6 +103,7 @@ export var selectColumns = function selectColumns(editorSelectionAPI) {
102
103
  };
103
104
  export var selectRows = function selectRows(editorSelectionAPI) {
104
105
  return function () {
106
+ var triggeredByKeyboard = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
105
107
  return function (state, dispatch) {
106
108
  var selection = state.selection;
107
109
  var table = findTable(selection);
@@ -114,7 +116,7 @@ export var selectRows = function selectRows(editorSelectionAPI) {
114
116
  })(state, dispatch);
115
117
  }
116
118
  if (table && rect) {
117
- return selectRow(rect.top)(state, dispatch);
119
+ return selectRow(rect.top, undefined, triggeredByKeyboard)(state, dispatch);
118
120
  }
119
121
  return false;
120
122
  };
@@ -6,7 +6,6 @@ import { DragAndDropActionType } from './actions';
6
6
  import { DropTargetType } from './consts';
7
7
  import { createCommand, getPluginState } from './plugin-factory';
8
8
  import { pluginKey } from './plugin-key';
9
-
10
9
  // TODO: This command is a placeholder example. Please replace this if required.
11
10
  export var getDecorations = function getDecorations(state) {
12
11
  var _pluginKey$getState;
@@ -79,6 +78,7 @@ export var moveSource = function moveSource(sourceType, sourceIndexes, targetInd
79
78
  });
80
79
  };
81
80
  export var toggleDragMenu = function toggleDragMenu(isDragMenuOpen, direction, index) {
81
+ var trigger = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 'mouse';
82
82
  return createCommand(function (state) {
83
83
  var _getPluginState3 = getPluginState(state),
84
84
  previousOpenState = _getPluginState3.isDragMenuOpen,
@@ -105,7 +105,8 @@ export var toggleDragMenu = function toggleDragMenu(isDragMenuOpen, direction, i
105
105
  data: {
106
106
  isDragMenuOpen: updatedMenuOpenState,
107
107
  direction: direction !== null && direction !== void 0 ? direction : previousDragMenuDirection,
108
- index: index !== null && index !== void 0 ? index : previousDragMenuIndex
108
+ index: index !== null && index !== void 0 ? index : previousDragMenuIndex,
109
+ isKeyboardModeActive: updatedMenuOpenState && trigger === 'keyboard'
109
110
  }
110
111
  };
111
112
  }, function (tr) {
@@ -164,7 +164,8 @@ export var createPlugin = function createPlugin(dispatch, eventDispatcher, edito
164
164
  dropTargetIndex: 0,
165
165
  isDragMenuOpen: false,
166
166
  dragMenuIndex: 0,
167
- isDragging: false
167
+ isDragging: false,
168
+ isKeyboardModeActive: false
168
169
  };
169
170
  }),
170
171
  key: pluginKey,
@@ -176,6 +177,20 @@ export var createPlugin = function createPlugin(dispatch, eventDispatcher, edito
176
177
  var _getPluginState = getPluginState(newState),
177
178
  isDragMenuOpen = _getPluginState.isDragMenuOpen,
178
179
  dragMenuIndex = _getPluginState.dragMenuIndex;
180
+ transactions.forEach(function (transaction) {
181
+ if (transaction.getMeta('selectedRowViaKeyboard')) {
182
+ var button = document.querySelector('#drag-handle-button-row');
183
+ if (button) {
184
+ button.focus();
185
+ }
186
+ }
187
+ if (transaction.getMeta('selectedColumnViaKeyboard')) {
188
+ var _button = document.querySelector('#drag-handle-button-column');
189
+ if (_button) {
190
+ _button.focus();
191
+ }
192
+ }
193
+ });
179
194
 
180
195
  // What's happening here? you asked... In a nutshell;
181
196
  // If the target cell position changes while the drag menu is open then we want to close the drag menu if it has been opened.
@@ -216,6 +231,23 @@ export var createPlugin = function createPlugin(dispatch, eventDispatcher, edito
216
231
  var _getPluginState2 = getPluginState(state),
217
232
  decorationSet = _getPluginState2.decorationSet;
218
233
  return decorationSet;
234
+ },
235
+ handleKeyDown: function handleKeyDown(view, event) {
236
+ var _ref8;
237
+ var isDragHandleFocused = ['drag-handle-button-row', 'drag-handle-button-column'].includes((_ref8 = event.target || null) === null || _ref8 === void 0 ? void 0 : _ref8.id);
238
+ var keysToTrap = ['Enter', ' '];
239
+ var keysToTrapWhen = ['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight'];
240
+ var _getPluginState3 = getPluginState(view.state),
241
+ isDragMenuOpen = _getPluginState3.isDragMenuOpen;
242
+
243
+ // drag handle is focused, and user presses any key return them back to editing
244
+ if (isDragHandleFocused && !isDragMenuOpen && !keysToTrap.includes(event.key)) {
245
+ view.dom.focus();
246
+ return true;
247
+ }
248
+ if (isDragHandleFocused && keysToTrap.includes(event.key) || isDragMenuOpen && keysToTrapWhen.includes(event.key)) {
249
+ return true;
250
+ }
219
251
  }
220
252
  }
221
253
  });
@@ -23,7 +23,8 @@ export default (function (pluginState, action) {
23
23
  return _objectSpread(_objectSpread({}, pluginState), {}, {
24
24
  isDragMenuOpen: action.data.isDragMenuOpen,
25
25
  dragMenuDirection: action.data.direction,
26
- dragMenuIndex: action.data.index
26
+ dragMenuIndex: action.data.index,
27
+ isKeyboardModeActive: action.data.isKeyboardModeActive
27
28
  });
28
29
  default:
29
30
  return pluginState;
@@ -7,8 +7,8 @@ export function tableSelectionKeymapPlugin(editorSelectionAPI) {
7
7
  bindKeymapWithCommand(moveRight.common, arrowRightFromTable(editorSelectionAPI)(), list);
8
8
  bindKeymapWithCommand(moveLeft.common, arrowLeftFromTable(editorSelectionAPI)(), list);
9
9
  if (getBooleanFF('platform.editor.a11y.table-selection_9uv33')) {
10
- bindKeymapArrayWithCommand(selectColumn, selectColumns(editorSelectionAPI)(), list);
11
- bindKeymapArrayWithCommand(selectRow, selectRows(editorSelectionAPI)(), list);
10
+ bindKeymapArrayWithCommand(selectColumn, selectColumns(editorSelectionAPI)(true), list);
11
+ bindKeymapArrayWithCommand(selectRow, selectRows(editorSelectionAPI)(true), list);
12
12
  }
13
13
  if (getBooleanFF('platform.editor.table.shift-arrowup-fix')) {
14
14
  bindKeymapWithCommand(shiftArrowUp.common, shiftArrowUpFromTable(editorSelectionAPI)(), list);
@@ -2,10 +2,8 @@ import React from 'react';
2
2
  import { DragHandleDisabledIcon, DragHandleIcon, MinimisedHandleIcon } from '../icons';
3
3
  export var HandleIconComponent = function HandleIconComponent(props) {
4
4
  var forceDefaultHandle = props.forceDefaultHandle,
5
- isRowHandleHovered = props.isRowHandleHovered,
6
- isColumnHandleHovered = props.isColumnHandleHovered,
5
+ isHandleHovered = props.isHandleHovered,
7
6
  hasMergedCells = props.hasMergedCells;
8
- var isHandleHovered = isRowHandleHovered || isColumnHandleHovered;
9
7
  if (isHandleHovered || forceDefaultHandle) {
10
8
  return hasMergedCells ? /*#__PURE__*/React.createElement(DragHandleDisabledIcon, null) : /*#__PURE__*/React.createElement(DragHandleIcon, null);
11
9
  }
@@ -8,6 +8,7 @@ import { tableMessages as messages } from '@atlaskit/editor-common/messages';
8
8
  import { browser } from '@atlaskit/editor-common/utils';
9
9
  import { draggable } from '@atlaskit/pragmatic-drag-and-drop/adapter/element';
10
10
  import { setCustomNativeDragPreview } from '@atlaskit/pragmatic-drag-and-drop/util/set-custom-native-drag-preview';
11
+ import { getPluginState as getDnDPluginState } from '../../pm-plugins/drag-and-drop/plugin-factory';
11
12
  import { getPluginState } from '../../pm-plugins/plugin-factory';
12
13
  import { TableCssClassName as ClassName } from '../../types';
13
14
  import { hasMergedCellsInColumn, hasMergedCellsInRow } from '../../utils';
@@ -28,7 +29,7 @@ var DragHandleComponent = function DragHandleComponent(_ref) {
28
29
  previewHeight = _ref.previewHeight,
29
30
  onMouseOver = _ref.onMouseOver,
30
31
  onMouseOut = _ref.onMouseOut,
31
- _onMouseUp = _ref.onMouseUp,
32
+ toggleDragMenu = _ref.toggleDragMenu,
32
33
  onClick = _ref.onClick,
33
34
  editorView = _ref.editorView,
34
35
  formatMessage = _ref.intl.formatMessage;
@@ -37,10 +38,13 @@ var DragHandleComponent = function DragHandleComponent(_ref) {
37
38
  _useState2 = _slicedToArray(_useState, 2),
38
39
  previewContainer = _useState2[0],
39
40
  setPreviewContainer = _useState2[1];
40
- var _getPluginState = getPluginState(editorView.state),
41
+ var state = editorView.state,
42
+ selection = editorView.state.selection;
43
+ var _getPluginState = getPluginState(state),
41
44
  hoveredColumns = _getPluginState.hoveredColumns,
42
45
  hoveredRows = _getPluginState.hoveredRows;
43
- var selection = editorView.state.selection;
46
+ var _getDnDPluginState = getDnDPluginState(state),
47
+ isDragMenuOpen = _getDnDPluginState.isDragMenuOpen;
44
48
  var isRow = direction === 'row';
45
49
  var isColumn = direction === 'column';
46
50
  var isRowHandleHovered = isRow && hoveredRows.length > 0;
@@ -50,8 +54,7 @@ var DragHandleComponent = function DragHandleComponent(_ref) {
50
54
  }, [indexes, isRow, selection]);
51
55
  var handleIconProps = {
52
56
  forceDefaultHandle: forceDefaultHandle,
53
- isColumnHandleHovered: isColumnHandleHovered,
54
- isRowHandleHovered: isRowHandleHovered,
57
+ isHandleHovered: isColumnHandleHovered || isRowHandleHovered,
55
58
  hasMergedCells: hasMergedCells
56
59
  };
57
60
  useEffect(function () {
@@ -111,6 +114,7 @@ var DragHandleComponent = function DragHandleComponent(_ref) {
111
114
  }, [tableLocalId, direction, indexes, isRow, editorView.state.selection, hasMergedCells]);
112
115
  var showDragMenuAnchorId = isRow ? 'drag-handle-button-row' : 'drag-handle-button-column';
113
116
  return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("button", {
117
+ type: "button",
114
118
  className: ClassName.DRAG_HANDLE_BUTTON_CLICKABLE_ZONE,
115
119
  "data-testid": "table-drag-handle-clickable-zone-button",
116
120
  style: {
@@ -125,6 +129,7 @@ var DragHandleComponent = function DragHandleComponent(_ref) {
125
129
  },
126
130
  onClick: onClick
127
131
  }), /*#__PURE__*/React.createElement("button", {
132
+ type: "button",
128
133
  id: isDragMenuTarget ? showDragMenuAnchorId : undefined,
129
134
  className: classnames(ClassName.DRAG_HANDLE_BUTTON_CONTAINER, appearance, _defineProperty({}, ClassName.DRAG_HANDLE_DISABLED, hasMergedCells)),
130
135
  ref: dragHandleDivRef,
@@ -134,20 +139,29 @@ var DragHandleComponent = function DragHandleComponent(_ref) {
134
139
  },
135
140
  "data-testid": "table-drag-handle-button",
136
141
  "aria-label": formatMessage(isRow ? messages.rowDragHandle : messages.columnDragHandle),
142
+ "aria-expanded": isDragMenuOpen && isDragMenuTarget ? 'true' : 'false',
143
+ "aria-haspopup": "menu",
137
144
  onMouseOver: onMouseOver,
138
145
  onMouseOut: onMouseOut,
139
146
  onMouseUp: function onMouseUp(e) {
140
147
  // return focus to editor so copying table selections whilst still works, i cannot call e.preventDefault in a mousemove event as this stops dragstart events from firing
141
148
  // -> this is bad for a11y but is the current standard new copy/paste keyboard shortcuts should be introduced instead
142
149
  editorView.focus();
143
- _onMouseUp && _onMouseUp(e);
150
+ toggleDragMenu && toggleDragMenu('mouse', e);
144
151
  },
145
- onClick: onClick
146
- }, browser.gecko ? /*#__PURE__*/React.createElement(HandleIconComponent, handleIconProps) : /*#__PURE__*/React.createElement("span", {
152
+ onClick: onClick,
153
+ onKeyDown: function onKeyDown(e) {
154
+ if (e.key === 'Enter' || e.key === ' ') {
155
+ toggleDragMenu && toggleDragMenu('keyboard');
156
+ }
157
+ }
158
+ }, appearance !== 'placeholder' ?
159
+ // cannot block pointer events in Firefox as it breaks Dragging functionality
160
+ browser.gecko ? /*#__PURE__*/React.createElement(HandleIconComponent, handleIconProps) : /*#__PURE__*/React.createElement("span", {
147
161
  style: {
148
162
  pointerEvents: 'none'
149
163
  }
150
- }, /*#__PURE__*/React.createElement(HandleIconComponent, handleIconProps))), previewContainer && previewWidth !== undefined && previewHeight !== undefined && /*#__PURE__*/ReactDOM.createPortal( /*#__PURE__*/React.createElement(DragPreview, {
164
+ }, /*#__PURE__*/React.createElement(HandleIconComponent, handleIconProps)) : null), previewContainer && previewWidth !== undefined && previewHeight !== undefined && /*#__PURE__*/ReactDOM.createPortal( /*#__PURE__*/React.createElement(DragPreview, {
151
165
  direction: direction,
152
166
  width: previewWidth,
153
167
  height: previewHeight