@atlaskit/editor-plugin-table 7.2.3 → 7.3.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 (135) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/afm-cc/tsconfig.json +3 -0
  3. package/dist/cjs/commands/column-resize.js +115 -45
  4. package/dist/cjs/commands/go-to-next-cell.js +7 -11
  5. package/dist/cjs/commands/misc.js +7 -4
  6. package/dist/cjs/commands/selection.js +7 -5
  7. package/dist/cjs/event-handlers.js +38 -25
  8. package/dist/cjs/pm-plugins/drag-and-drop/commands.js +3 -1
  9. package/dist/cjs/pm-plugins/drag-and-drop/plugin.js +33 -1
  10. package/dist/cjs/pm-plugins/drag-and-drop/reducer.js +2 -1
  11. package/dist/cjs/pm-plugins/keymap.js +1 -0
  12. package/dist/cjs/pm-plugins/main.js +43 -9
  13. package/dist/cjs/pm-plugins/table-resizing/event-handlers.js +37 -7
  14. package/dist/cjs/pm-plugins/table-resizing/plugin.js +20 -6
  15. package/dist/cjs/pm-plugins/table-selection-keymap.js +2 -2
  16. package/dist/cjs/reducer.js +5 -2
  17. package/dist/cjs/ui/DragHandle/HandleIconComponent.js +1 -3
  18. package/dist/cjs/ui/DragHandle/index.js +22 -10
  19. package/dist/cjs/ui/FloatingDragMenu/DragMenu.js +75 -33
  20. package/dist/cjs/ui/FloatingDragMenu/DropdownMenu.js +123 -0
  21. package/dist/cjs/ui/FloatingDragMenu/index.js +2 -2
  22. package/dist/cjs/ui/TableFloatingColumnControls/ColumnControls/index.js +24 -35
  23. package/dist/cjs/ui/TableFloatingColumnControls/index.js +1 -2
  24. package/dist/cjs/ui/TableFloatingControls/CornerControls/DragCornerControls.js +4 -0
  25. package/dist/cjs/ui/TableFloatingControls/RowControls/DragControls.js +26 -33
  26. package/dist/cjs/ui/common-styles.js +1 -1
  27. package/dist/cjs/ui/consts.js +3 -2
  28. package/dist/es2019/commands/column-resize.js +100 -35
  29. package/dist/es2019/commands/go-to-next-cell.js +7 -9
  30. package/dist/es2019/commands/misc.js +7 -6
  31. package/dist/es2019/commands/selection.js +9 -9
  32. package/dist/es2019/event-handlers.js +17 -3
  33. package/dist/es2019/pm-plugins/drag-and-drop/commands.js +3 -3
  34. package/dist/es2019/pm-plugins/drag-and-drop/plugin.js +34 -1
  35. package/dist/es2019/pm-plugins/drag-and-drop/reducer.js +2 -1
  36. package/dist/es2019/pm-plugins/keymap.js +3 -2
  37. package/dist/es2019/pm-plugins/main.js +41 -5
  38. package/dist/es2019/pm-plugins/table-resizing/event-handlers.js +37 -4
  39. package/dist/es2019/pm-plugins/table-resizing/plugin.js +16 -1
  40. package/dist/es2019/pm-plugins/table-selection-keymap.js +2 -2
  41. package/dist/es2019/reducer.js +5 -2
  42. package/dist/es2019/ui/DragHandle/HandleIconComponent.js +1 -3
  43. package/dist/es2019/ui/DragHandle/index.js +25 -10
  44. package/dist/es2019/ui/FloatingDragMenu/DragMenu.js +72 -32
  45. package/dist/es2019/ui/FloatingDragMenu/DropdownMenu.js +109 -0
  46. package/dist/es2019/ui/FloatingDragMenu/index.js +2 -2
  47. package/dist/es2019/ui/TableFloatingColumnControls/ColumnControls/index.js +24 -35
  48. package/dist/es2019/ui/TableFloatingColumnControls/index.js +1 -2
  49. package/dist/es2019/ui/TableFloatingControls/CornerControls/DragCornerControls.js +4 -0
  50. package/dist/es2019/ui/TableFloatingControls/RowControls/DragControls.js +26 -33
  51. package/dist/es2019/ui/common-styles.js +11 -1
  52. package/dist/es2019/ui/consts.js +2 -1
  53. package/dist/esm/commands/column-resize.js +105 -35
  54. package/dist/esm/commands/go-to-next-cell.js +7 -11
  55. package/dist/esm/commands/misc.js +7 -4
  56. package/dist/esm/commands/selection.js +9 -7
  57. package/dist/esm/event-handlers.js +38 -25
  58. package/dist/esm/pm-plugins/drag-and-drop/commands.js +3 -2
  59. package/dist/esm/pm-plugins/drag-and-drop/plugin.js +33 -1
  60. package/dist/esm/pm-plugins/drag-and-drop/reducer.js +2 -1
  61. package/dist/esm/pm-plugins/keymap.js +3 -2
  62. package/dist/esm/pm-plugins/main.js +38 -4
  63. package/dist/esm/pm-plugins/table-resizing/event-handlers.js +34 -4
  64. package/dist/esm/pm-plugins/table-resizing/plugin.js +15 -1
  65. package/dist/esm/pm-plugins/table-selection-keymap.js +2 -2
  66. package/dist/esm/reducer.js +5 -2
  67. package/dist/esm/ui/DragHandle/HandleIconComponent.js +1 -3
  68. package/dist/esm/ui/DragHandle/index.js +21 -9
  69. package/dist/esm/ui/FloatingDragMenu/DragMenu.js +74 -35
  70. package/dist/esm/ui/FloatingDragMenu/DropdownMenu.js +116 -0
  71. package/dist/esm/ui/FloatingDragMenu/index.js +2 -2
  72. package/dist/esm/ui/TableFloatingColumnControls/ColumnControls/index.js +24 -35
  73. package/dist/esm/ui/TableFloatingColumnControls/index.js +1 -2
  74. package/dist/esm/ui/TableFloatingControls/CornerControls/DragCornerControls.js +4 -0
  75. package/dist/esm/ui/TableFloatingControls/RowControls/DragControls.js +26 -33
  76. package/dist/esm/ui/common-styles.js +1 -1
  77. package/dist/esm/ui/consts.js +2 -1
  78. package/dist/types/commands/column-resize.d.ts +2 -0
  79. package/dist/types/commands/misc.d.ts +3 -3
  80. package/dist/types/commands/selection.d.ts +2 -2
  81. package/dist/types/pm-plugins/drag-and-drop/actions.d.ts +1 -0
  82. package/dist/types/pm-plugins/drag-and-drop/commands.d.ts +2 -1
  83. package/dist/types/pm-plugins/drag-and-drop/types.d.ts +2 -0
  84. package/dist/types/types.d.ts +16 -0
  85. package/dist/types/ui/DragHandle/HandleIconComponent.d.ts +1 -2
  86. package/dist/types/ui/DragHandle/index.d.ts +3 -2
  87. package/dist/types/ui/FloatingDragMenu/DragMenu.d.ts +7 -8
  88. package/dist/types/ui/FloatingDragMenu/DropdownMenu.d.ts +30 -0
  89. package/dist/types/ui/TableFloatingColumnControls/ColumnControls/index.d.ts +1 -2
  90. package/dist/types/ui/TableFloatingControls/RowControls/DragControls.d.ts +1 -1
  91. package/dist/types/ui/consts.d.ts +1 -0
  92. package/dist/types-ts4.5/commands/column-resize.d.ts +2 -0
  93. package/dist/types-ts4.5/commands/misc.d.ts +3 -3
  94. package/dist/types-ts4.5/commands/selection.d.ts +2 -2
  95. package/dist/types-ts4.5/pm-plugins/drag-and-drop/actions.d.ts +1 -0
  96. package/dist/types-ts4.5/pm-plugins/drag-and-drop/commands.d.ts +2 -1
  97. package/dist/types-ts4.5/pm-plugins/drag-and-drop/types.d.ts +2 -0
  98. package/dist/types-ts4.5/types.d.ts +16 -0
  99. package/dist/types-ts4.5/ui/DragHandle/HandleIconComponent.d.ts +1 -2
  100. package/dist/types-ts4.5/ui/DragHandle/index.d.ts +3 -2
  101. package/dist/types-ts4.5/ui/FloatingDragMenu/DragMenu.d.ts +7 -8
  102. package/dist/types-ts4.5/ui/FloatingDragMenu/DropdownMenu.d.ts +30 -0
  103. package/dist/types-ts4.5/ui/TableFloatingColumnControls/ColumnControls/index.d.ts +1 -2
  104. package/dist/types-ts4.5/ui/TableFloatingControls/RowControls/DragControls.d.ts +1 -1
  105. package/dist/types-ts4.5/ui/consts.d.ts +1 -0
  106. package/package.json +4 -3
  107. package/src/commands/column-resize.ts +155 -40
  108. package/src/commands/go-to-next-cell.ts +6 -15
  109. package/src/commands/misc.ts +19 -4
  110. package/src/commands/selection.ts +17 -9
  111. package/src/event-handlers.ts +21 -4
  112. package/src/pm-plugins/drag-and-drop/actions.ts +1 -0
  113. package/src/pm-plugins/drag-and-drop/commands.ts +3 -0
  114. package/src/pm-plugins/drag-and-drop/plugin.ts +47 -0
  115. package/src/pm-plugins/drag-and-drop/reducer.ts +1 -0
  116. package/src/pm-plugins/drag-and-drop/types.ts +3 -0
  117. package/src/pm-plugins/keymap.ts +3 -0
  118. package/src/pm-plugins/main.ts +47 -2
  119. package/src/pm-plugins/table-resizing/event-handlers.ts +33 -5
  120. package/src/pm-plugins/table-resizing/plugin.ts +18 -1
  121. package/src/pm-plugins/table-selection-keymap.ts +2 -2
  122. package/src/reducer.ts +5 -2
  123. package/src/types.ts +16 -0
  124. package/src/ui/DragHandle/HandleIconComponent.tsx +2 -9
  125. package/src/ui/DragHandle/index.tsx +37 -16
  126. package/src/ui/FloatingDragMenu/DragMenu.tsx +362 -310
  127. package/src/ui/FloatingDragMenu/DropdownMenu.tsx +150 -0
  128. package/src/ui/FloatingDragMenu/index.tsx +3 -3
  129. package/src/ui/TableFloatingColumnControls/ColumnControls/index.tsx +72 -91
  130. package/src/ui/TableFloatingColumnControls/index.tsx +1 -2
  131. package/src/ui/TableFloatingControls/CornerControls/DragCornerControls.tsx +5 -0
  132. package/src/ui/TableFloatingControls/RowControls/DragControls.tsx +89 -104
  133. package/src/ui/common-styles.ts +11 -1
  134. package/src/ui/consts.ts +1 -0
  135. package/tsconfig.app.json +3 -0
@@ -1,13 +1,15 @@
1
1
  /* eslint-disable @atlaskit/design-system/prefer-primitives */
2
2
  /** @jsx jsx */
3
- import { useState } from 'react';
3
+ /** @jsxFrag */
4
+ import React, { useEffect, useState } from 'react';
4
5
  import { jsx } from '@emotion/react';
5
6
  import { injectIntl } from 'react-intl-next';
6
7
  import { INPUT_METHOD } from '@atlaskit/editor-common/analytics';
7
8
  import { tableMessages as messages } from '@atlaskit/editor-common/messages';
8
9
  import { DropdownMenuSharedCssClassName } from '@atlaskit/editor-common/styles';
9
- import { backgroundPaletteTooltipMessages, cellBackgroundColorPalette, ColorPalette } from '@atlaskit/editor-common/ui-color';
10
- import { ArrowKeyNavigationType, DropdownMenu } from '@atlaskit/editor-common/ui-menu';
10
+ import { withOuterListeners } from '@atlaskit/editor-common/ui';
11
+ import { backgroundPaletteTooltipMessages, cellBackgroundColorPalette, ColorPalette, getSelectedRowAndColumnFromPalette } from '@atlaskit/editor-common/ui-color';
12
+ import { ArrowKeyNavigationProvider, ArrowKeyNavigationType } from '@atlaskit/editor-common/ui-menu';
11
13
  import { closestElement } from '@atlaskit/editor-common/utils';
12
14
  import { hexToEditorBackgroundPaletteColor } from '@atlaskit/editor-palette';
13
15
  import { shortcutStyle } from '@atlaskit/editor-shared-styles/shortcut';
@@ -24,7 +26,8 @@ import { getPluginState as getTablePluginState } from '../../pm-plugins/plugin-f
24
26
  import { TableCssClassName as ClassName } from '../../types';
25
27
  import { checkIfHeaderColumnEnabled, checkIfHeaderRowEnabled, checkIfNumberColumnEnabled, getMergedCellsPositions, getSelectedColumnIndexes, getSelectedRowIndexes, hasMergedCellsInColumn, hasMergedCellsInRow } from '../../utils';
26
28
  import { getDragMenuConfig } from '../../utils/drag-menu';
27
- import { dragMenuDropdownWidth } from '../consts';
29
+ import { colorPalletteColumns } from '../consts';
30
+ import { DropdownMenu } from './DropdownMenu';
28
31
  import { cellColourPreviewStyles, dragMenuBackgroundColorStyles, elementBeforeIconStyles, toggleStyles } from './styles';
29
32
  const MapDragMenuOptionIdToMessage = {
30
33
  add_row_above: {
@@ -153,15 +156,14 @@ const convertToDropdownItems = (dragMenuConfig, formatMessage, selectionRect) =>
153
156
  menuCallback
154
157
  };
155
158
  };
156
- export const DragMenu = ({
159
+ const ColorPaletteWithListeners = withOuterListeners(ColorPalette);
160
+ export const DragMenu = /*#__PURE__*/React.memo(({
157
161
  direction = 'row',
158
162
  index,
163
+ target,
159
164
  isOpen,
160
165
  editorView,
161
166
  tableNode,
162
- mountPoint,
163
- boundariesElement,
164
- scrollableElement,
165
167
  targetCellPosition,
166
168
  getEditorContainerWidth,
167
169
  editorAnalyticsAPI,
@@ -180,6 +182,9 @@ export const DragMenu = ({
180
182
  } = state;
181
183
  const tableMap = tableNode ? TableMap.get(tableNode) : undefined;
182
184
  const [isSubmenuOpen, setIsSubmenuOpen] = useState(false);
185
+ const {
186
+ isKeyboardModeActive
187
+ } = getPluginState(state);
183
188
  const selectionRect = isSelectionType(selection, 'cell') ? getSelectionRect(selection) : findCellRectClosestToPos(selection.$from);
184
189
  const hasMergedCells = direction === 'row' ? hasMergedCellsInRow : hasMergedCellsInColumn;
185
190
  const shouldMoveDisabled = index !== undefined && hasMergedCells(index)(selection);
@@ -220,7 +225,12 @@ export const DragMenu = ({
220
225
  } = getTablePluginState(editorView.state);
221
226
  const node = targetCellPosition ? state.doc.nodeAt(targetCellPosition) : null;
222
227
  const background = hexToEditorBackgroundPaletteColor((node === null || node === void 0 ? void 0 : (_node$attrs = node.attrs) === null || _node$attrs === void 0 ? void 0 : _node$attrs.background) || '#ffffff');
228
+ const {
229
+ selectedRowIndex,
230
+ selectedColumnIndex
231
+ } = getSelectedRowAndColumnFromPalette(cellBackgroundColorPalette, background, colorPalletteColumns);
223
232
  return {
233
+ key: 'background',
224
234
  content: formatMessage(messages.backgroundColor),
225
235
  value: {
226
236
  name: 'background'
@@ -240,16 +250,33 @@ export const DragMenu = ({
240
250
  }), isSubmenuOpen && jsx("div", {
241
251
  className: ClassName.DRAG_SUBMENU,
242
252
  ref: handleSubMenuRef
243
- }, jsx(ColorPalette, {
244
- cols: 7,
245
- onClick: setColor,
253
+ }, jsx(ArrowKeyNavigationProvider, {
254
+ type: ArrowKeyNavigationType.COLOR,
255
+ selectedRowIndex: selectedRowIndex,
256
+ selectedColumnIndex: selectedColumnIndex,
257
+ handleClose: () => {
258
+ const keyboardEvent = new KeyboardEvent('keydown', {
259
+ key: 'ArrowDown',
260
+ bubbles: true
261
+ });
262
+ setIsSubmenuOpen(false);
263
+ target === null || target === void 0 ? void 0 : target.focus();
264
+ target === null || target === void 0 ? void 0 : target.dispatchEvent(keyboardEvent);
265
+ },
266
+ isPopupPositioned: true,
267
+ isOpenedByKeyboard: isKeyboardModeActive
268
+ }, jsx(ColorPaletteWithListeners, {
269
+ cols: colorPalletteColumns,
270
+ onClick: color => {
271
+ setColor(color);
272
+ },
246
273
  selectedColor: background,
247
274
  paletteOptions: {
248
275
  palette: cellBackgroundColorPalette,
249
276
  paletteColorTooltipMessages: backgroundPaletteTooltipMessages,
250
277
  hexToPaletteColor: hexToEditorBackgroundPaletteColor
251
278
  }
252
- })))
279
+ }))))
253
280
  };
254
281
  };
255
282
  const toggleHeaderColumn = () => {
@@ -261,8 +288,9 @@ export const DragMenu = ({
261
288
  const toggleRowNumbers = () => {
262
289
  toggleNumberColumnWithAnalytics(editorAnalyticsAPI)(state, dispatch);
263
290
  };
264
- const createhHeaderRowColumnMenuItem = direction => {
291
+ const createHeaderRowColumnMenuItem = direction => {
265
292
  return direction === 'column' ? {
293
+ key: 'header_column',
266
294
  content: formatMessage(messages.headerColumn),
267
295
  value: {
268
296
  name: 'header_column'
@@ -275,6 +303,7 @@ export const DragMenu = ({
275
303
  isChecked: checkIfHeaderColumnEnabled(selection)
276
304
  }))
277
305
  } : {
306
+ key: 'header_row',
278
307
  content: formatMessage(messages.headerRow),
279
308
  value: {
280
309
  name: 'header_row'
@@ -290,6 +319,7 @@ export const DragMenu = ({
290
319
  };
291
320
  const createRowNumbersMenuItem = () => {
292
321
  return {
322
+ key: 'row_numbers',
293
323
  content: formatMessage(messages.rowNumbers),
294
324
  value: {
295
325
  name: 'row_numbers'
@@ -326,12 +356,17 @@ export const DragMenu = ({
326
356
  return true;
327
357
  }
328
358
  };
329
- const closeMenu = () => {
359
+ const closeMenu = (focusTarget = 'handle') => {
330
360
  const {
331
361
  state,
332
362
  dispatch
333
363
  } = editorView;
334
364
  if (shouldCloseMenu(state)) {
365
+ if (target && focusTarget === 'handle') {
366
+ target === null || target === void 0 ? void 0 : target.focus();
367
+ } else {
368
+ editorView.dom.focus();
369
+ }
335
370
  toggleDragMenu(false, direction, index)(state, dispatch);
336
371
  }
337
372
  };
@@ -341,6 +376,9 @@ export const DragMenu = ({
341
376
  var _menuCallback$item$va;
342
377
  (_menuCallback$item$va = menuCallback[item.value.name]) === null || _menuCallback$item$va === void 0 ? void 0 : _menuCallback$item$va.call(menuCallback, state, dispatch);
343
378
  switch (item.value.name) {
379
+ case 'background':
380
+ setIsSubmenuOpen(!isSubmenuOpen);
381
+ break;
344
382
  case 'header_column':
345
383
  toggleHeaderColumn();
346
384
  break;
@@ -354,7 +392,7 @@ export const DragMenu = ({
354
392
  break;
355
393
  }
356
394
  if (['header_column', 'header_row', 'row_numbers', 'background'].indexOf(item.value.name) <= -1) {
357
- closeMenu();
395
+ closeMenu('editor');
358
396
  }
359
397
  };
360
398
  const handleItemMouseEnter = ({
@@ -382,6 +420,17 @@ export const DragMenu = ({
382
420
  clearHoverSelection()(state, dispatch);
383
421
  }
384
422
  };
423
+ useEffect(() => {
424
+ // focus on first menu item automatically when menu renders
425
+ // and user is using keyboard
426
+ if (isOpen && target && isKeyboardModeActive) {
427
+ const keyboardEvent = new KeyboardEvent('keydown', {
428
+ key: 'ArrowDown',
429
+ bubbles: true
430
+ });
431
+ target.dispatchEvent(keyboardEvent);
432
+ }
433
+ }, [isOpen, target, isKeyboardModeActive]);
385
434
  if (!menuItems) {
386
435
  return null;
387
436
  }
@@ -389,11 +438,11 @@ export const DragMenu = ({
389
438
  menuItems[0].items.unshift(createBackgroundColorMenuItem());
390
439
  }
391
440
 
392
- // If first row, add toggle for Hearder row, default is true
441
+ // If first row, add toggle for Header row, default is true
393
442
  // If first column, add toggle for Header column, default is false
394
443
  if (getBooleanFF('platform.editor.table.new-cell-context-menu-styling') && index === 0) {
395
444
  menuItems.push({
396
- items: [createhHeaderRowColumnMenuItem(direction)]
445
+ items: [createHeaderRowColumnMenuItem(direction)]
397
446
  });
398
447
  }
399
448
 
@@ -404,25 +453,16 @@ export const DragMenu = ({
404
453
  });
405
454
  }
406
455
  return jsx(DropdownMenu, {
407
- mountTo: mountPoint
408
- //This needs be removed when the a11y is completely handled
409
- //Disabling key navigation now as it works only partially
410
- ,
411
- arrowKeyNavigationProviderOptions: {
412
- type: ArrowKeyNavigationType.MENU,
413
- disableArrowKeyNavigation: true
456
+ disableKeyboardHandling: isSubmenuOpen,
457
+ section: {
458
+ hasSeparator: true
414
459
  },
460
+ target: target,
415
461
  items: menuItems,
416
- isOpen: isOpen,
417
- onOpenChange: closeMenu,
418
462
  onItemActivated: handleMenuItemActivated,
419
463
  onMouseEnter: handleItemMouseEnter,
420
464
  onMouseLeave: handleItemMouseLeave,
421
- fitWidth: dragMenuDropdownWidth,
422
- boundariesElement: boundariesElement,
423
- section: {
424
- hasSeparator: true
425
- }
465
+ handleClose: closeMenu
426
466
  });
427
- };
467
+ });
428
468
  export default injectIntl(DragMenu);
@@ -0,0 +1,109 @@
1
+ import React from 'react';
2
+ import { DropList } from '@atlaskit/editor-common/ui';
3
+ import { ArrowKeyNavigationProvider, ArrowKeyNavigationType, DropdownMenuItem } from '@atlaskit/editor-common/ui-menu';
4
+ import { withReactEditorViewOuterListeners } from '@atlaskit/editor-common/ui-react';
5
+ import { MenuGroup, Section } from '@atlaskit/menu';
6
+ import { getBooleanFF } from '@atlaskit/platform-feature-flags';
7
+ import { dragMenuDropdownWidth } from '../consts';
8
+ const DropListWithOutsideListeners = withReactEditorViewOuterListeners(DropList);
9
+ export const DropdownMenu = ({
10
+ target,
11
+ items,
12
+ section,
13
+ disableKeyboardHandling,
14
+ onItemActivated,
15
+ handleClose,
16
+ onMouseEnter,
17
+ onMouseLeave
18
+ }) => {
19
+ const innerMenu = () => {
20
+ return /*#__PURE__*/React.createElement(DropListWithOutsideListeners, {
21
+ isOpen: true,
22
+ shouldFitContainer: true,
23
+ position: ['bottom', 'left'].join(' '),
24
+ handleClickOutside: () => handleClose('editor'),
25
+ handleEscapeKeydown: () => {
26
+ if (!disableKeyboardHandling) {
27
+ handleClose('handle');
28
+ }
29
+ },
30
+ handleEnterKeydown: e => {
31
+ if (!disableKeyboardHandling) {
32
+ e.preventDefault();
33
+ e.stopPropagation();
34
+ }
35
+ },
36
+ targetRef: target
37
+ }, /*#__PURE__*/React.createElement("div", {
38
+ style: {
39
+ height: 0,
40
+ minWidth: dragMenuDropdownWidth
41
+ }
42
+ }), /*#__PURE__*/React.createElement(MenuGroup, {
43
+ role: "menu"
44
+ }, items.map((group, index) => /*#__PURE__*/React.createElement(Section, {
45
+ hasSeparator: (section === null || section === void 0 ? void 0 : section.hasSeparator) && index > 0,
46
+ title: section === null || section === void 0 ? void 0 : section.title,
47
+ key: index
48
+ }, group.items.map(item => {
49
+ var _item$key;
50
+ return /*#__PURE__*/React.createElement(DropdownMenuItem, {
51
+ shouldUseDefaultRole: false,
52
+ key: (_item$key = item.key) !== null && _item$key !== void 0 ? _item$key : String(item.content),
53
+ item: item,
54
+ onItemActivated: onItemActivated,
55
+ onMouseEnter: onMouseEnter,
56
+ onMouseLeave: onMouseLeave
57
+ });
58
+ })))));
59
+ };
60
+ if (disableKeyboardHandling) {
61
+ return innerMenu();
62
+ }
63
+ return /*#__PURE__*/React.createElement(ArrowKeyNavigationProvider, {
64
+ closeOnTab: true,
65
+ type: ArrowKeyNavigationType.MENU,
66
+ onSelection: index => {
67
+ const results = items.flatMap(item => 'items' in item ? item.items : item);
68
+
69
+ // onSelection is called when any focusable element is 'activated'
70
+ // this is an issue as some menu items have toggles, which cause the index value
71
+ // in the callback to be outside of array length.
72
+ // The logic below normalises the index value based on the number
73
+ // of menu items with 2 focusable elements, and adjusts the index to ensure
74
+ // the correct menu item is sent in onItemActivated callback
75
+ if (getBooleanFF('platform.editor.table.new-cell-context-menu-styling')) {
76
+ const keys = ['row_numbers', 'header_row', 'header_column'];
77
+ let doubleItemCount = 0;
78
+ const firstIndex = results.findIndex(value => keys.includes(value.key));
79
+ if (firstIndex === -1 || index <= firstIndex) {
80
+ onItemActivated && onItemActivated({
81
+ item: results[index]
82
+ });
83
+ return;
84
+ }
85
+ for (let i = firstIndex; i < results.length; i += 1) {
86
+ if (keys.includes(results[i].key)) {
87
+ doubleItemCount += 1;
88
+ }
89
+ if (firstIndex % 2 === 0 && index - doubleItemCount === i) {
90
+ onItemActivated && onItemActivated({
91
+ item: results[i]
92
+ });
93
+ return;
94
+ }
95
+ if (firstIndex % 2 === 1 && index - doubleItemCount === i) {
96
+ onItemActivated && onItemActivated({
97
+ item: results[i]
98
+ });
99
+ return;
100
+ }
101
+ }
102
+ } else {
103
+ onItemActivated && onItemActivated({
104
+ item: results[index]
105
+ });
106
+ }
107
+ }
108
+ }, innerMenu());
109
+ };
@@ -24,10 +24,10 @@ const FloatingDragMenu = ({
24
24
  }
25
25
  const inStickyMode = stickyHeaders === null || stickyHeaders === void 0 ? void 0 : stickyHeaders.sticky;
26
26
  const targetHandleRef = direction === 'row' ? document.querySelector('#drag-handle-button-row') : document.querySelector('#drag-handle-button-column');
27
+ const offset = direction === 'row' ? [-9, 6] : [0, -7];
27
28
  if (!targetHandleRef || !(editorView.state.selection instanceof CellSelection)) {
28
29
  return null;
29
30
  }
30
- const offset = direction === 'row' ? [-9, 6] : [0, -7];
31
31
 
32
32
  // TODO: we will need to adjust the alignment and offset values depending on whether this is a row or column menu.
33
33
  return /*#__PURE__*/React.createElement(Popup, {
@@ -49,10 +49,10 @@ const FloatingDragMenu = ({
49
49
  }, /*#__PURE__*/React.createElement(DragMenu, {
50
50
  editorView: editorView,
51
51
  isOpen: isOpen,
52
- boundariesElement: boundariesElement,
53
52
  tableNode: tableNode,
54
53
  direction: direction,
55
54
  index: index,
55
+ target: targetHandleRef || undefined,
56
56
  targetCellPosition: targetCellPosition,
57
57
  getEditorContainerWidth: getEditorContainerWidth,
58
58
  editorAnalyticsAPI: editorAnalyticsAPI,
@@ -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)"};