@atlaskit/editor-plugin-table 5.3.12 → 5.3.14

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 (155) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/dist/cjs/plugins/table/event-handlers.js +6 -3
  3. package/dist/cjs/plugins/table/index.js +16 -2
  4. package/dist/cjs/plugins/table/nodeviews/TableComponent.js +2 -1
  5. package/dist/cjs/plugins/table/pm-plugins/decorations/plugin.js +3 -7
  6. package/dist/cjs/plugins/table/pm-plugins/decorations/utils/column-controls.js +1 -3
  7. package/dist/cjs/plugins/table/pm-plugins/drag-and-drop/actions.js +2 -1
  8. package/dist/cjs/plugins/table/pm-plugins/drag-and-drop/commands.js +22 -1
  9. package/dist/cjs/plugins/table/pm-plugins/drag-and-drop/plugin.js +54 -7
  10. package/dist/cjs/plugins/table/pm-plugins/drag-and-drop/reducer.js +6 -0
  11. package/dist/cjs/plugins/table/types.js +9 -2
  12. package/dist/cjs/plugins/table/ui/DragHandle/index.js +2 -0
  13. package/dist/cjs/plugins/table/ui/FloatingDragMenu/DragMenu.js +80 -0
  14. package/dist/cjs/plugins/table/ui/FloatingDragMenu/index.js +62 -0
  15. package/dist/cjs/plugins/table/ui/FloatingInsertButton/InsertButton.js +52 -4
  16. package/dist/cjs/plugins/table/ui/FloatingInsertButton/getPopupOptions.js +10 -8
  17. package/dist/cjs/plugins/table/ui/FloatingInsertButton/index.js +12 -3
  18. package/dist/cjs/plugins/table/ui/TableFloatingColumnControls/ColumnControls/index.js +44 -5
  19. package/dist/cjs/plugins/table/ui/TableFloatingColumnControls/index.js +6 -4
  20. package/dist/cjs/plugins/table/ui/TableFloatingControls/RowControls/DragControls.js +44 -20
  21. package/dist/cjs/plugins/table/ui/TableFloatingControls/index.js +4 -0
  22. package/dist/cjs/plugins/table/ui/common-styles.js +1 -1
  23. package/dist/cjs/plugins/table/ui/consts.js +3 -2
  24. package/dist/cjs/plugins/table/ui/ui-styles.js +27 -24
  25. package/dist/cjs/plugins/table/utils/dom.js +12 -4
  26. package/dist/cjs/plugins/table/utils/drag-menu.js +59 -0
  27. package/dist/cjs/plugins/table/utils/index.js +12 -0
  28. package/dist/es2019/plugins/table/event-handlers.js +5 -4
  29. package/dist/es2019/plugins/table/index.js +16 -2
  30. package/dist/es2019/plugins/table/nodeviews/TableComponent.js +2 -1
  31. package/dist/es2019/plugins/table/pm-plugins/decorations/plugin.js +3 -7
  32. package/dist/es2019/plugins/table/pm-plugins/decorations/utils/column-controls.js +1 -3
  33. package/dist/es2019/plugins/table/pm-plugins/drag-and-drop/actions.js +2 -1
  34. package/dist/es2019/plugins/table/pm-plugins/drag-and-drop/commands.js +20 -0
  35. package/dist/es2019/plugins/table/pm-plugins/drag-and-drop/plugin.js +54 -3
  36. package/dist/es2019/plugins/table/pm-plugins/drag-and-drop/reducer.js +7 -0
  37. package/dist/es2019/plugins/table/types.js +9 -2
  38. package/dist/es2019/plugins/table/ui/DragHandle/index.js +2 -0
  39. package/dist/es2019/plugins/table/ui/FloatingDragMenu/DragMenu.js +77 -0
  40. package/dist/es2019/plugins/table/ui/FloatingDragMenu/index.js +56 -0
  41. package/dist/es2019/plugins/table/ui/FloatingInsertButton/InsertButton.js +53 -2
  42. package/dist/es2019/plugins/table/ui/FloatingInsertButton/getPopupOptions.js +10 -8
  43. package/dist/es2019/plugins/table/ui/FloatingInsertButton/index.js +9 -3
  44. package/dist/es2019/plugins/table/ui/TableFloatingColumnControls/ColumnControls/index.js +46 -6
  45. package/dist/es2019/plugins/table/ui/TableFloatingColumnControls/index.js +7 -5
  46. package/dist/es2019/plugins/table/ui/TableFloatingControls/RowControls/DragControls.js +45 -22
  47. package/dist/es2019/plugins/table/ui/TableFloatingControls/index.js +4 -0
  48. package/dist/es2019/plugins/table/ui/common-styles.js +51 -3
  49. package/dist/es2019/plugins/table/ui/consts.js +2 -1
  50. package/dist/es2019/plugins/table/ui/ui-styles.js +23 -1
  51. package/dist/es2019/plugins/table/utils/dom.js +5 -1
  52. package/dist/es2019/plugins/table/utils/drag-menu.js +44 -0
  53. package/dist/es2019/plugins/table/utils/index.js +1 -1
  54. package/dist/esm/plugins/table/event-handlers.js +7 -4
  55. package/dist/esm/plugins/table/index.js +16 -2
  56. package/dist/esm/plugins/table/nodeviews/TableComponent.js +2 -1
  57. package/dist/esm/plugins/table/pm-plugins/decorations/plugin.js +3 -7
  58. package/dist/esm/plugins/table/pm-plugins/decorations/utils/column-controls.js +1 -3
  59. package/dist/esm/plugins/table/pm-plugins/drag-and-drop/actions.js +2 -1
  60. package/dist/esm/plugins/table/pm-plugins/drag-and-drop/commands.js +21 -0
  61. package/dist/esm/plugins/table/pm-plugins/drag-and-drop/plugin.js +54 -7
  62. package/dist/esm/plugins/table/pm-plugins/drag-and-drop/reducer.js +6 -0
  63. package/dist/esm/plugins/table/types.js +9 -2
  64. package/dist/esm/plugins/table/ui/DragHandle/index.js +2 -0
  65. package/dist/esm/plugins/table/ui/FloatingDragMenu/DragMenu.js +73 -0
  66. package/dist/esm/plugins/table/ui/FloatingDragMenu/index.js +55 -0
  67. package/dist/esm/plugins/table/ui/FloatingInsertButton/InsertButton.js +51 -3
  68. package/dist/esm/plugins/table/ui/FloatingInsertButton/getPopupOptions.js +10 -8
  69. package/dist/esm/plugins/table/ui/FloatingInsertButton/index.js +9 -3
  70. package/dist/esm/plugins/table/ui/TableFloatingColumnControls/ColumnControls/index.js +45 -6
  71. package/dist/esm/plugins/table/ui/TableFloatingColumnControls/index.js +7 -5
  72. package/dist/esm/plugins/table/ui/TableFloatingControls/RowControls/DragControls.js +46 -22
  73. package/dist/esm/plugins/table/ui/TableFloatingControls/index.js +4 -0
  74. package/dist/esm/plugins/table/ui/common-styles.js +2 -2
  75. package/dist/esm/plugins/table/ui/consts.js +2 -1
  76. package/dist/esm/plugins/table/ui/ui-styles.js +26 -23
  77. package/dist/esm/plugins/table/utils/dom.js +11 -3
  78. package/dist/esm/plugins/table/utils/drag-menu.js +52 -0
  79. package/dist/esm/plugins/table/utils/index.js +1 -1
  80. package/dist/types/plugins/table/pm-plugins/drag-and-drop/actions.d.ts +8 -1
  81. package/dist/types/plugins/table/pm-plugins/drag-and-drop/commands.d.ts +2 -1
  82. package/dist/types/plugins/table/pm-plugins/drag-and-drop/types.d.ts +4 -0
  83. package/dist/types/plugins/table/types.d.ts +10 -2
  84. package/dist/types/plugins/table/ui/DragHandle/index.d.ts +4 -2
  85. package/dist/types/plugins/table/ui/DragPreview/index.d.ts +2 -1
  86. package/dist/types/plugins/table/ui/FloatingDeleteButton/index.d.ts +2 -1
  87. package/dist/types/plugins/table/ui/FloatingDeleteButton/types.d.ts +2 -1
  88. package/dist/types/plugins/table/ui/FloatingDragMenu/DragMenu.d.ts +19 -0
  89. package/dist/types/plugins/table/ui/FloatingDragMenu/index.d.ts +21 -0
  90. package/dist/types/plugins/table/ui/FloatingInsertButton/InsertButton.d.ts +6 -1
  91. package/dist/types/plugins/table/ui/FloatingInsertButton/getPopupOptions.d.ts +2 -1
  92. package/dist/types/plugins/table/ui/FloatingInsertButton/index.d.ts +5 -5
  93. package/dist/types/plugins/table/ui/TableFloatingColumnControls/ColumnControls/index.d.ts +2 -1
  94. package/dist/types/plugins/table/ui/TableFloatingControls/RowControls/DragControls.d.ts +4 -0
  95. package/dist/types/plugins/table/ui/TableFloatingControls/index.d.ts +3 -0
  96. package/dist/types/plugins/table/ui/consts.d.ts +1 -0
  97. package/dist/types/plugins/table/ui/ui-styles.d.ts +1 -0
  98. package/dist/types/plugins/table/utils/dom.d.ts +4 -1
  99. package/dist/types/plugins/table/utils/drag-menu.d.ts +7 -0
  100. package/dist/types/plugins/table/utils/index.d.ts +1 -1
  101. package/dist/types-ts4.5/plugins/table/pm-plugins/drag-and-drop/actions.d.ts +8 -1
  102. package/dist/types-ts4.5/plugins/table/pm-plugins/drag-and-drop/commands.d.ts +2 -1
  103. package/dist/types-ts4.5/plugins/table/pm-plugins/drag-and-drop/types.d.ts +4 -0
  104. package/dist/types-ts4.5/plugins/table/types.d.ts +10 -2
  105. package/dist/types-ts4.5/plugins/table/ui/DragHandle/index.d.ts +4 -2
  106. package/dist/types-ts4.5/plugins/table/ui/DragPreview/index.d.ts +2 -1
  107. package/dist/types-ts4.5/plugins/table/ui/FloatingDeleteButton/index.d.ts +2 -1
  108. package/dist/types-ts4.5/plugins/table/ui/FloatingDeleteButton/types.d.ts +2 -1
  109. package/dist/types-ts4.5/plugins/table/ui/FloatingDragMenu/DragMenu.d.ts +19 -0
  110. package/dist/types-ts4.5/plugins/table/ui/FloatingDragMenu/index.d.ts +21 -0
  111. package/dist/types-ts4.5/plugins/table/ui/FloatingInsertButton/InsertButton.d.ts +6 -1
  112. package/dist/types-ts4.5/plugins/table/ui/FloatingInsertButton/getPopupOptions.d.ts +2 -1
  113. package/dist/types-ts4.5/plugins/table/ui/FloatingInsertButton/index.d.ts +5 -5
  114. package/dist/types-ts4.5/plugins/table/ui/TableFloatingColumnControls/ColumnControls/index.d.ts +2 -1
  115. package/dist/types-ts4.5/plugins/table/ui/TableFloatingControls/RowControls/DragControls.d.ts +4 -0
  116. package/dist/types-ts4.5/plugins/table/ui/TableFloatingControls/index.d.ts +3 -0
  117. package/dist/types-ts4.5/plugins/table/ui/consts.d.ts +1 -0
  118. package/dist/types-ts4.5/plugins/table/ui/ui-styles.d.ts +1 -0
  119. package/dist/types-ts4.5/plugins/table/utils/dom.d.ts +4 -1
  120. package/dist/types-ts4.5/plugins/table/utils/drag-menu.d.ts +7 -0
  121. package/dist/types-ts4.5/plugins/table/utils/index.d.ts +1 -1
  122. package/package.json +3 -2
  123. package/src/__tests__/unit/pm-plugins/decorations/plugin.ts +40 -194
  124. package/src/__tests__/unit/ui/RowDragControls.tsx +9 -11
  125. package/src/plugins/table/event-handlers.ts +15 -3
  126. package/src/plugins/table/index.tsx +18 -1
  127. package/src/plugins/table/nodeviews/TableComponent.tsx +2 -1
  128. package/src/plugins/table/pm-plugins/decorations/plugin.ts +2 -9
  129. package/src/plugins/table/pm-plugins/decorations/utils/column-controls.ts +1 -3
  130. package/src/plugins/table/pm-plugins/drag-and-drop/actions.ts +14 -1
  131. package/src/plugins/table/pm-plugins/drag-and-drop/commands.ts +32 -1
  132. package/src/plugins/table/pm-plugins/drag-and-drop/plugin.ts +50 -2
  133. package/src/plugins/table/pm-plugins/drag-and-drop/reducer.ts +7 -0
  134. package/src/plugins/table/pm-plugins/drag-and-drop/types.ts +5 -0
  135. package/src/plugins/table/types.ts +14 -2
  136. package/src/plugins/table/ui/DragHandle/index.tsx +5 -1
  137. package/src/plugins/table/ui/DragPreview/index.tsx +2 -1
  138. package/src/plugins/table/ui/FloatingDeleteButton/index.tsx +2 -1
  139. package/src/plugins/table/ui/FloatingDeleteButton/types.ts +3 -1
  140. package/src/plugins/table/ui/FloatingDragMenu/DragMenu.tsx +99 -0
  141. package/src/plugins/table/ui/FloatingDragMenu/index.tsx +91 -0
  142. package/src/plugins/table/ui/FloatingInsertButton/InsertButton.tsx +79 -4
  143. package/src/plugins/table/ui/FloatingInsertButton/getPopupOptions.ts +31 -7
  144. package/src/plugins/table/ui/FloatingInsertButton/index.tsx +28 -13
  145. package/src/plugins/table/ui/TableFloatingColumnControls/ColumnControls/index.tsx +47 -3
  146. package/src/plugins/table/ui/TableFloatingColumnControls/index.tsx +11 -4
  147. package/src/plugins/table/ui/TableFloatingControls/RowControls/DragControls.tsx +65 -25
  148. package/src/plugins/table/ui/TableFloatingControls/index.tsx +7 -0
  149. package/src/plugins/table/ui/common-styles.ts +57 -2
  150. package/src/plugins/table/ui/consts.ts +2 -0
  151. package/src/plugins/table/ui/ui-styles.ts +27 -1
  152. package/src/plugins/table/utils/dom.ts +11 -4
  153. package/src/plugins/table/utils/drag-menu.ts +65 -0
  154. package/src/plugins/table/utils/index.ts +2 -0
  155. package/tsconfig.app.json +3 -0
@@ -11,7 +11,7 @@ import {
11
11
  selectRow,
12
12
  } from '@atlaskit/editor-tables/utils';
13
13
 
14
- import type { DraggableType } from '../../types';
14
+ import type { DraggableType, TableDirection } from '../../types';
15
15
  import { TableDecorations } from '../../types';
16
16
  import {
17
17
  createColumnInsertLine,
@@ -121,3 +121,34 @@ export const moveSource = (
121
121
  return select(targetIndex)(newTr);
122
122
  },
123
123
  );
124
+
125
+ export const toggleDragMenu = (
126
+ isDragMenuOpen: boolean | undefined,
127
+ direction?: TableDirection,
128
+ index?: number,
129
+ ) =>
130
+ createCommand(
131
+ (state) => {
132
+ let {
133
+ isDragMenuOpen: previousOpenState,
134
+ dragMenuDirection,
135
+ dragMenuIndex,
136
+ } = getPluginState(state);
137
+ if (previousOpenState === isDragMenuOpen) {
138
+ return false;
139
+ }
140
+
141
+ return {
142
+ type: DragAndDropActionType.TOGGLE_DRAG_MENU,
143
+ data: {
144
+ isDragMenuOpen:
145
+ isDragMenuOpen === undefined ? !previousOpenState : isDragMenuOpen,
146
+ direction: direction ?? dragMenuDirection,
147
+ index: index ?? dragMenuIndex,
148
+ },
149
+ };
150
+ },
151
+ (tr: Transaction) => {
152
+ return tr.setMeta('addToHistory', false);
153
+ },
154
+ );
@@ -5,6 +5,8 @@ import type {
5
5
  import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
6
6
  import type { EditorView } from '@atlaskit/editor-prosemirror/view';
7
7
  import { DecorationSet } from '@atlaskit/editor-prosemirror/view';
8
+ import { getCellsInRow } from '@atlaskit/editor-tables/utils';
9
+ import { autoScroller } from '@atlaskit/pragmatic-drag-and-drop-react-beautiful-dnd-autoscroll';
8
10
  import { monitorForElements } from '@atlaskit/pragmatic-drag-and-drop/adapter/element';
9
11
 
10
12
  import type { DraggableSourceData } from '../../types';
@@ -14,6 +16,7 @@ import {
14
16
  } from '../../utils/merged-cells';
15
17
  import { getPluginState as getTablePluginState } from '../plugin-factory';
16
18
 
19
+ import { DragAndDropActionType } from './actions';
17
20
  import { clearDropTarget, moveSource, setDropTarget } from './commands';
18
21
  import { DropTargetType } from './consts';
19
22
  import { createPluginState, getPluginState } from './plugin-factory';
@@ -27,12 +30,49 @@ export const createPlugin = (
27
30
  return new SafePlugin({
28
31
  state: createPluginState(dispatch, (state) => ({
29
32
  decorationSet: DecorationSet.empty,
30
- // TODO: This is example placeholder state. We could use this to track which row/col is currently set as the drop target
31
- // This would result in a blue highlight being displayed on the corrisponding row/column to single the drop target location.
32
33
  dropTargetType: DropTargetType.NONE,
33
34
  dropTargetIndex: 0,
35
+ isDragMenuOpen: false,
36
+ dragMenuIndex: 0,
34
37
  })),
35
38
  key: pluginKey,
39
+ appendTransaction: (transactions, oldState, newState) => {
40
+ const { targetCellPosition: oldTargetCellPosition } =
41
+ getTablePluginState(oldState);
42
+ const { targetCellPosition: newTargetCellPosition } =
43
+ getTablePluginState(newState);
44
+ const { isDragMenuOpen, dragMenuIndex } = getPluginState(newState);
45
+
46
+ // What's happening here? you asked... In a nutshell;
47
+ // 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.
48
+ // This will stop the drag menu from moving around the screen to different row/cols. Too achieve this we need
49
+ // to check if the new target cell position is pointed at a different cell than what the drag menu was opened on.
50
+ if (oldTargetCellPosition !== newTargetCellPosition) {
51
+ if (isDragMenuOpen) {
52
+ const tr = newState.tr;
53
+ const action = {
54
+ type: DragAndDropActionType.TOGGLE_DRAG_MENU,
55
+ data: {
56
+ isDragMenuOpen: false,
57
+ direction: undefined,
58
+ },
59
+ };
60
+
61
+ if (newTargetCellPosition !== undefined) {
62
+ const cells = getCellsInRow(dragMenuIndex)(tr.selection);
63
+ if (
64
+ cells &&
65
+ cells.length &&
66
+ cells[0].node !== tr.doc.nodeAt(newTargetCellPosition)
67
+ ) {
68
+ return tr.setMeta(pluginKey, action);
69
+ } // else NOP
70
+ } else {
71
+ return tr.setMeta(pluginKey, action);
72
+ }
73
+ }
74
+ }
75
+ },
36
76
  view: (editorView: EditorView) => {
37
77
  return {
38
78
  destroy: monitorForElements({
@@ -57,7 +97,14 @@ export const createPlugin = (
57
97
  // watch for changes
58
98
  return localId === tableNode?.attrs.localId;
59
99
  },
100
+ onDragStart: ({ location }) => {
101
+ autoScroller.start({ input: location.current.input });
102
+ },
60
103
  onDrag(event) {
104
+ autoScroller.updateInput({
105
+ input: event.location.current.input,
106
+ });
107
+
61
108
  const data = getDraggableDataFromEvent(event);
62
109
  // If no data can be found then it's most like we do not want to perform any drag actions
63
110
  if (!data) {
@@ -79,6 +126,7 @@ export const createPlugin = (
79
126
  );
80
127
  },
81
128
  onDrop(event) {
129
+ autoScroller.stop();
82
130
  const data = getDraggableDataFromEvent(event);
83
131
 
84
132
  // If no data can be found then it's most like we do not want to perform any drop action
@@ -22,6 +22,13 @@ export default (
22
22
  dropTargetType: DropTargetType.NONE,
23
23
  dropTargetIndex: 0,
24
24
  };
25
+ case DragAndDropActionType.TOGGLE_DRAG_MENU:
26
+ return {
27
+ ...pluginState,
28
+ isDragMenuOpen: action.data.isDragMenuOpen,
29
+ dragMenuDirection: action.data.direction,
30
+ dragMenuIndex: action.data.index,
31
+ };
25
32
  default:
26
33
  return pluginState;
27
34
  }
@@ -1,9 +1,14 @@
1
1
  import type { DecorationSet } from '@atlaskit/editor-prosemirror/view';
2
2
 
3
+ import type { TableDirection } from '../../types';
4
+
3
5
  import type { DropTargetType } from './consts';
4
6
 
5
7
  export interface DragAndDropPluginState {
6
8
  decorationSet: DecorationSet;
7
9
  dropTargetType: DropTargetType;
8
10
  dropTargetIndex: number;
11
+ isDragMenuOpen: boolean;
12
+ dragMenuDirection?: TableDirection;
13
+ dragMenuIndex: number;
9
14
  }
@@ -293,6 +293,10 @@ export const TableCssClassName = {
293
293
  CONTROLS_BUTTON_OVERLAY: `${tablePrefixSelector}-controls__button-overlay`,
294
294
  LAYOUT_BUTTON: `${tablePrefixSelector}-layout-button`,
295
295
 
296
+ DRAG_CONTROLS_INSERT_BUTTON: `${tablePrefixSelector}-controls__drag-insert-button`,
297
+ DRAG_CONTROLS_INSERT_BUTTON_INNER: `${tablePrefixSelector}-controls__drag-insert-button-inner`,
298
+ DRAG_CONTROLS_INSERT_BUTTON_WRAP: `${tablePrefixSelector}-controls__drag-insert-button-wrap`,
299
+
296
300
  CONTROLS_INSERT_MARKER: `${tablePrefixSelector}-controls__insert-marker`,
297
301
  CONTROLS_INSERT_COLUMN: `${tablePrefixSelector}-controls__insert-column`,
298
302
  CONTROLS_INSERT_ROW: `${tablePrefixSelector}-controls__insert-row`,
@@ -308,8 +312,14 @@ export const TableCssClassName = {
308
312
  CONTROLS_CORNER_BUTTON: `${tablePrefixSelector}-corner-button`,
309
313
 
310
314
  /** Controls with drag handle */
311
- COLUMN_CONTROLS_WITH_DRAG: `${tablePrefixSelector}-column-controls-with-drag`,
312
- ROW_CONTROLS_WITH_DRAG: `${tablePrefixSelector}-row-controls-with-drag`,
315
+ DRAG_ROW_CONTROLS: `${tablePrefixSelector}-drag-row-controls`,
316
+ DRAG_ROW_FLOATING_INSERT_DOT_WRAPPER: `${tablePrefixSelector}-drag-row-floating-insert-dot-wrapper`,
317
+ DRAG_ROW_FLOATING_INSERT_DOT: `${tablePrefixSelector}-drag-row-floating-insert-dot`,
318
+
319
+ DRAG_COLUMN_CONTROLS: `${tablePrefixSelector}-drag-column-controls`,
320
+ DRAG_COLUMN_FLOATING_INSERT_DOT_WRAPPER: `${tablePrefixSelector}-drag-columns-floating-insert-dot-wrapper`,
321
+ DRAG_COLUMN_FLOATING_INSERT_DOT: `${tablePrefixSelector}-drag-columns-floating-insert-dot`,
322
+
313
323
  DRAG_HANDLE_BUTTON_CONTAINER: `${tablePrefixSelector}-drag-handle-button-container`,
314
324
 
315
325
  /** Other classes */
@@ -405,6 +415,8 @@ export type InvalidNodeAttr = {
405
415
  tableLocalId: string;
406
416
  };
407
417
 
418
+ export type TableDirection = 'row' | 'column';
419
+
408
420
  /**
409
421
  * Drag and Drop interfaces
410
422
  */
@@ -7,6 +7,7 @@ import ReactDOM from 'react-dom';
7
7
  import { draggable } from '@atlaskit/pragmatic-drag-and-drop/adapter/element';
8
8
  import { setCustomNativeDragPreview } from '@atlaskit/pragmatic-drag-and-drop/util/set-custom-native-drag-preview';
9
9
 
10
+ import type { TableDirection } from '../../types';
10
11
  import { TableCssClassName as ClassName } from '../../types';
11
12
  import { DragPreview } from '../DragPreview';
12
13
  import { DragHandleIcon } from '../icons';
@@ -18,11 +19,12 @@ type DragHandleProps = {
18
19
  indexes: number[];
19
20
  previewWidth?: number;
20
21
  previewHeight?: number;
21
- direction?: 'column' | 'row';
22
+ direction?: TableDirection;
22
23
  appearance?: DragHandleAppearance;
23
24
  onClick?: MouseEventHandler;
24
25
  onMouseOver?: MouseEventHandler;
25
26
  onMouseOut?: MouseEventHandler;
27
+ onMouseUp?: MouseEventHandler;
26
28
  };
27
29
 
28
30
  export const DragHandle = ({
@@ -34,6 +36,7 @@ export const DragHandle = ({
34
36
  previewHeight,
35
37
  onMouseOver,
36
38
  onMouseOut,
39
+ onMouseUp,
37
40
  onClick,
38
41
  }: DragHandleProps) => {
39
42
  const dragHandleDivRef = useRef<HTMLButtonElement>(null);
@@ -85,6 +88,7 @@ export const DragHandle = ({
85
88
  data-testid="table-floating-column-controls-drag-handle"
86
89
  onMouseOver={onMouseOver}
87
90
  onMouseOut={onMouseOut}
91
+ onMouseUp={onMouseUp}
88
92
  onClick={onClick}
89
93
  >
90
94
  <DragHandleIcon />
@@ -2,6 +2,7 @@ import React from 'react';
2
2
 
3
3
  import { Box, xcss } from '@atlaskit/primitives';
4
4
 
5
+ import type { TableDirection } from '../../types';
5
6
  import { DragInMotionIcon } from '../icons/DragInMotionIcon';
6
7
 
7
8
  const boxStyles = xcss({
@@ -17,7 +18,7 @@ export const DragPreview = ({
17
18
  width,
18
19
  height,
19
20
  }: {
20
- direction: 'column' | 'row';
21
+ direction: TableDirection;
21
22
  width: number;
22
23
  height: number;
23
24
  }) => {
@@ -23,6 +23,7 @@ import {
23
23
  } from '../../commands-with-analytics';
24
24
  import { getPluginState as getTablePluginState } from '../../pm-plugins/plugin-factory';
25
25
  import type { RowStickyState } from '../../pm-plugins/sticky-headers';
26
+ import type { TableDirection } from '../../types';
26
27
  import { TableCssClassName as ClassName } from '../../types';
27
28
  import {
28
29
  getColumnDeleteButtonParams,
@@ -60,7 +61,7 @@ export interface State {
60
61
 
61
62
  export function getSelectionType(
62
63
  selection: Selection,
63
- ): 'column' | 'row' | undefined {
64
+ ): TableDirection | undefined {
64
65
  if (!isTableSelected(selection) && selection instanceof CellSelection) {
65
66
  if (selection.isRowSelection()) {
66
67
  return 'row';
@@ -1 +1,3 @@
1
- export type CellSelectionType = 'column' | 'row' | undefined;
1
+ import type { TableDirection } from '../../types';
2
+
3
+ export type CellSelectionType = TableDirection | undefined;
@@ -0,0 +1,99 @@
1
+ import React from 'react';
2
+
3
+ import type { Command } from '@atlaskit/editor-common/types';
4
+ import {
5
+ ArrowKeyNavigationType,
6
+ DropdownMenu,
7
+ } from '@atlaskit/editor-common/ui-menu';
8
+ import type { MenuItem } from '@atlaskit/editor-common/ui-menu';
9
+ import type { Node as PmNode } from '@atlaskit/editor-prosemirror/model';
10
+ import type { EditorView } from '@atlaskit/editor-prosemirror/view';
11
+ import { TableMap } from '@atlaskit/editor-tables/table-map';
12
+
13
+ import { toggleDragMenu } from '../../pm-plugins/drag-and-drop/commands';
14
+ import type { PluginConfig, TableDirection } from '../../types';
15
+ import type { DragMenuConfig } from '../../utils/drag-menu';
16
+ import { getDragMenuConfig } from '../../utils/drag-menu';
17
+ import { dragMenuDropdownWidth } from '../consts';
18
+
19
+ type DragMenuProps = {
20
+ direction?: TableDirection;
21
+ index?: number;
22
+ tableRef?: HTMLTableElement;
23
+ tableNode?: PmNode;
24
+ editorView: EditorView;
25
+ isOpen?: boolean;
26
+ targetCellPosition?: number;
27
+ mountPoint?: HTMLElement;
28
+ boundariesElement?: HTMLElement;
29
+ scrollableElement?: HTMLElement;
30
+ pluginConfig?: PluginConfig;
31
+ };
32
+
33
+ const convertToDropdownItems = (dragMenuConfig: DragMenuConfig[]) => {
34
+ let menuItems: MenuItem[] = [];
35
+ let menuCallback: { [key: string]: Command } = {};
36
+ dragMenuConfig.forEach((item) => {
37
+ menuItems.push({
38
+ key: item.id,
39
+ content: item.title,
40
+ value: { name: item.id },
41
+ isDisabled: item.disabled,
42
+ });
43
+ item.onClick && (menuCallback[item.id] = item.onClick);
44
+ });
45
+ return { menuItems, menuCallback };
46
+ };
47
+
48
+ export const DragMenu = ({
49
+ direction = 'row',
50
+ index,
51
+ isOpen,
52
+ editorView,
53
+ tableNode,
54
+ mountPoint,
55
+ boundariesElement,
56
+ scrollableElement,
57
+ }: DragMenuProps) => {
58
+ const tableMap = tableNode ? TableMap.get(tableNode) : undefined;
59
+
60
+ const dragMenuConfig = getDragMenuConfig(direction, tableMap, index);
61
+
62
+ const { menuItems, menuCallback } = convertToDropdownItems(dragMenuConfig);
63
+
64
+ const closeMenu = () => {
65
+ const { state, dispatch } = editorView;
66
+ toggleDragMenu(false)(state, dispatch);
67
+ };
68
+
69
+ const onMenuItemActivated = ({ item }: { item: MenuItem }) => {
70
+ menuCallback[item.value.name]?.(editorView.state, editorView.dispatch);
71
+ closeMenu();
72
+ };
73
+
74
+ if (!menuItems) {
75
+ return null;
76
+ }
77
+
78
+ return (
79
+ <DropdownMenu
80
+ mountTo={mountPoint}
81
+ //This needs be removed when the a11y is completely handled
82
+ //Disabling key navigation now as it works only partially
83
+ arrowKeyNavigationProviderOptions={{
84
+ type: ArrowKeyNavigationType.MENU,
85
+ disableArrowKeyNavigation: true,
86
+ }}
87
+ items={[
88
+ {
89
+ items: menuItems,
90
+ },
91
+ ]}
92
+ isOpen={isOpen}
93
+ onOpenChange={closeMenu}
94
+ onItemActivated={onMenuItemActivated}
95
+ fitWidth={dragMenuDropdownWidth}
96
+ boundariesElement={boundariesElement}
97
+ />
98
+ );
99
+ };
@@ -0,0 +1,91 @@
1
+ import React from 'react';
2
+
3
+ import { Popup } from '@atlaskit/editor-common/ui';
4
+ import type { Node as PmNode } from '@atlaskit/editor-prosemirror/model';
5
+ import { findDomRefAtPos } from '@atlaskit/editor-prosemirror/utils';
6
+ import type { EditorView } from '@atlaskit/editor-prosemirror/view';
7
+ import { akEditorFloatingOverlapPanelZIndex } from '@atlaskit/editor-shared-styles';
8
+ import { TableMap } from '@atlaskit/editor-tables/table-map';
9
+
10
+ import type { TableDirection } from '../../types';
11
+ import { dragMenuDropdownWidth } from '../consts';
12
+
13
+ import { DragMenu } from './DragMenu';
14
+
15
+ export interface Props {
16
+ editorView: EditorView;
17
+ isOpen: boolean;
18
+ tableRef?: HTMLTableElement;
19
+ tableNode?: PmNode;
20
+ mountPoint?: HTMLElement;
21
+ boundariesElement?: HTMLElement;
22
+ scrollableElement?: HTMLElement;
23
+ direction?: TableDirection;
24
+ index?: number;
25
+ targetCellPosition?: number;
26
+ }
27
+
28
+ const FloatingDragMenu = ({
29
+ mountPoint,
30
+ boundariesElement,
31
+ scrollableElement,
32
+ editorView,
33
+ isOpen,
34
+ tableRef,
35
+ tableNode,
36
+ direction,
37
+ index,
38
+ targetCellPosition,
39
+ }: Props) => {
40
+ if (
41
+ !isOpen ||
42
+ !targetCellPosition ||
43
+ editorView.state.doc.nodeSize <= targetCellPosition
44
+ ) {
45
+ return null;
46
+ }
47
+
48
+ const domAtPos = editorView.domAtPos.bind(editorView);
49
+ const targetCellRef = findDomRefAtPos(targetCellPosition, domAtPos);
50
+ if (!targetCellRef) {
51
+ return null;
52
+ }
53
+ const tableMap = tableNode ? TableMap.get(tableNode) : undefined;
54
+ const offset =
55
+ direction === 'row'
56
+ ? [7, 0]
57
+ : index === (tableMap?.width || 1) - 1
58
+ ? [14, 0]
59
+ : [-14, 0];
60
+ // TODO: we will need to adjust the alignment and offset values depending on whether this is a row or column menu.
61
+ return (
62
+ <Popup
63
+ alignX={direction === 'row' ? 'left' : 'center'}
64
+ alignY="top"
65
+ target={targetCellRef as HTMLElement}
66
+ mountTo={mountPoint}
67
+ boundariesElement={boundariesElement}
68
+ scrollableElement={scrollableElement}
69
+ fitWidth={dragMenuDropdownWidth}
70
+ // z-index value below is to ensure that this menu is above other floating menu
71
+ // in table, but below floating dialogs like typeaheads, pickers, etc.
72
+ zIndex={akEditorFloatingOverlapPanelZIndex}
73
+ forcePlacement={true}
74
+ offset={offset}
75
+ stick={true}
76
+ >
77
+ <DragMenu
78
+ editorView={editorView}
79
+ isOpen={isOpen}
80
+ boundariesElement={boundariesElement}
81
+ tableNode={tableNode}
82
+ direction={direction}
83
+ index={index}
84
+ />
85
+ </Popup>
86
+ );
87
+ };
88
+
89
+ FloatingDragMenu.displayName = 'FloatingDragMenu';
90
+
91
+ export default FloatingDragMenu;
@@ -1,3 +1,4 @@
1
+ /* eslint-disable @atlaskit/design-system/ensure-design-token-usage */
1
2
  import type { SyntheticEvent } from 'react';
2
3
  import React from 'react';
3
4
 
@@ -14,12 +15,13 @@ import { closestElement } from '@atlaskit/editor-common/utils';
14
15
  import { akEditorTableNumberColumnWidth } from '@atlaskit/editor-shared-styles';
15
16
  import Tooltip from '@atlaskit/tooltip';
16
17
 
18
+ import type { TableDirection } from '../../types';
17
19
  import { TableCssClassName as ClassName } from '../../types';
18
20
  import { tableToolbarSize } from '../consts';
19
21
  import tableMessages from '../messages';
20
22
 
21
23
  export interface ButtonProps {
22
- type: 'row' | 'column';
24
+ type: TableDirection;
23
25
  tableRef: HTMLElement;
24
26
  onMouseDown: (event: SyntheticEvent<HTMLButtonElement>) => void;
25
27
  hasStickyHeaders: boolean;
@@ -51,7 +53,10 @@ const getToolbarSize = (tableRef: HTMLElement): number => {
51
53
  return tableToolbarSize;
52
54
  };
53
55
 
54
- const getInsertLineWidth = (tableRef: HTMLElement) => {
56
+ const getInsertLineWidth = (
57
+ tableRef: HTMLElement,
58
+ isDragAndDropEnabled?: boolean,
59
+ ) => {
55
60
  // The line gets width 100% from the table,
56
61
  // but since we have an overflow on the left,
57
62
  // we should add an offset to make up for it.
@@ -60,7 +65,7 @@ const getInsertLineWidth = (tableRef: HTMLElement) => {
60
65
  const parentOffsetWidth = parentElement!.offsetWidth;
61
66
  const { scrollLeft } = parentElement!;
62
67
  const diff = offsetWidth - parentOffsetWidth;
63
- const toolbarSize = getToolbarSize(tableRef);
68
+ const toolbarSize = isDragAndDropEnabled ? 0 : getToolbarSize(tableRef);
64
69
  return (
65
70
  Math.min(
66
71
  offsetWidth + toolbarSize,
@@ -69,10 +74,80 @@ const getInsertLineWidth = (tableRef: HTMLElement) => {
69
74
  );
70
75
  };
71
76
 
72
- const tooltipMessageByType = (type: string) => {
77
+ const tooltipMessageByType = (type: TableDirection) => {
73
78
  return type === 'row' ? tableMessages.insertRow : tableMessages.insertColumn;
74
79
  };
75
80
 
81
+ export const InsertButtonForDragAndDrop = ({
82
+ onMouseDown,
83
+ tableRef,
84
+ type,
85
+ intl: { formatMessage },
86
+ hasStickyHeaders,
87
+ }: ButtonProps & WrappedComponentProps) => {
88
+ const content = (
89
+ <Tooltip
90
+ content={
91
+ <ToolTipContent
92
+ description={formatMessage(tooltipMessageByType(type))}
93
+ keymap={type === 'row' ? addRowAfter : addColumnAfter}
94
+ />
95
+ }
96
+ position="top"
97
+ >
98
+ <>
99
+ <div className={ClassName.DRAG_CONTROLS_INSERT_BUTTON_INNER}>
100
+ <button
101
+ type="button"
102
+ className={ClassName.DRAG_CONTROLS_INSERT_BUTTON}
103
+ onMouseDown={onMouseDown}
104
+ >
105
+ <svg
106
+ width="10"
107
+ height="10"
108
+ viewBox="0 0 10 10"
109
+ fill="none"
110
+ xmlns="http://www.w3.org/2000/svg"
111
+ >
112
+ <path
113
+ fillRule="evenodd"
114
+ clipRule="evenodd"
115
+ d="M5.41667 4.58333V2.91667C5.41667 2.80616 5.37277 2.70018 5.29463 2.62204C5.21649 2.5439 5.11051 2.5 5 2.5C4.88949 2.5 4.78351 2.5439 4.70537 2.62204C4.62723 2.70018 4.58333 2.80616 4.58333 2.91667V4.58333H2.91667C2.80616 4.58333 2.70018 4.62723 2.62204 4.70537C2.5439 4.78351 2.5 4.88949 2.5 5C2.5 5.11051 2.5439 5.21649 2.62204 5.29463C2.70018 5.37277 2.80616 5.41667 2.91667 5.41667H4.58333V7.08333C4.58333 7.19384 4.62723 7.29982 4.70537 7.37796C4.78351 7.4561 4.88949 7.5 5 7.5C5.11051 7.5 5.21649 7.4561 5.29463 7.37796C5.37277 7.29982 5.41667 7.19384 5.41667 7.08333V5.41667H7.08333C7.19384 5.41667 7.29982 5.37277 7.37796 5.29463C7.4561 5.21649 7.5 5.11051 7.5 5C7.5 4.88949 7.4561 4.78351 7.37796 4.70537C7.29982 4.62723 7.19384 4.58333 7.08333 4.58333H5.41667Z"
116
+ fill="currentColor"
117
+ />
118
+ </svg>
119
+ </button>
120
+ </div>
121
+ <div
122
+ className={ClassName.CONTROLS_INSERT_LINE}
123
+ style={
124
+ type === 'row'
125
+ ? { width: getInsertLineWidth(tableRef, true), left: '14px' }
126
+ : { height: getInsertLineHeight(tableRef, hasStickyHeaders) - 11 }
127
+ }
128
+ />
129
+ </>
130
+ </Tooltip>
131
+ );
132
+
133
+ const floatingButtonClassName =
134
+ type === 'column'
135
+ ? ClassName.CONTROLS_FLOATING_BUTTON_COLUMN
136
+ : ClassName.CONTROLS_FLOATING_BUTTON_ROW;
137
+
138
+ return (
139
+ <div className={floatingButtonClassName}>
140
+ <div
141
+ className={`${ClassName.CONTROLS_INSERT_BUTTON_WRAP} ${ClassName.CONTROLS_INSERT_ROW}`}
142
+ >
143
+ {content}
144
+ </div>
145
+ </div>
146
+ );
147
+ };
148
+
149
+ export const DragAndDropInsertButton = injectIntl(InsertButtonForDragAndDrop);
150
+
76
151
  const InsertButton = ({
77
152
  onMouseDown,
78
153
  tableRef,
@@ -1,6 +1,7 @@
1
1
  import type { PopupProps } from '@atlaskit/editor-common/ui';
2
2
  import { akEditorTableNumberColumnWidth } from '@atlaskit/editor-shared-styles';
3
3
 
4
+ import type { TableDirection } from '../../types';
4
5
  import {
5
6
  tableInsertColumnButtonOffset,
6
7
  tableInsertColumnButtonSize,
@@ -10,17 +11,26 @@ import {
10
11
  const HORIZONTAL_ALIGN_COLUMN_BUTTON = -(tableInsertColumnButtonSize / 2);
11
12
  const HORIZONTAL_ALIGN_NUMBERED_COLUMN_BUTTON =
12
13
  HORIZONTAL_ALIGN_COLUMN_BUTTON + akEditorTableNumberColumnWidth;
14
+
13
15
  const VERTICAL_ALIGN_COLUMN_BUTTON =
14
16
  tableToolbarSize + tableInsertColumnButtonOffset;
15
17
 
18
+ const VERTICAL_ALIGN_COLUMN_BUTTON_DRAG = tableInsertColumnButtonOffset;
19
+
16
20
  const HORIZONTAL_ALIGN_ROW_BUTTON = -(
17
21
  tableToolbarSize +
18
22
  tableInsertColumnButtonOffset +
19
23
  tableInsertColumnButtonSize
20
24
  );
25
+
26
+ const HORIZONTAL_ALIGN_ROW_BUTTON_DRAG = -18;
27
+
21
28
  const VERTICAL_ALIGN_ROW_BUTTON = tableInsertColumnButtonSize / 2;
22
29
 
23
- function getRowOptions(index: number): Partial<PopupProps> {
30
+ function getRowOptions(
31
+ index: number,
32
+ isDragAndDropEnabled: boolean,
33
+ ): Partial<PopupProps> {
24
34
  let defaultOptions = {
25
35
  alignX: 'left',
26
36
  alignY: 'bottom',
@@ -42,7 +52,9 @@ function getRowOptions(index: number): Partial<PopupProps> {
42
52
  return {
43
53
  ...position,
44
54
  // Left position should be always the offset (To place in the correct position even if the table has overflow).
45
- left: HORIZONTAL_ALIGN_ROW_BUTTON,
55
+ left: isDragAndDropEnabled
56
+ ? HORIZONTAL_ALIGN_ROW_BUTTON_DRAG
57
+ : HORIZONTAL_ALIGN_ROW_BUTTON,
46
58
  };
47
59
  },
48
60
  };
@@ -52,11 +64,17 @@ function getColumnOptions(
52
64
  index: number,
53
65
  tableContainer: HTMLElement | null,
54
66
  hasNumberedColumns: boolean,
67
+ isDragAndDropEnabled: boolean,
55
68
  ): Partial<PopupProps> {
56
69
  const options: Partial<PopupProps> = {
57
70
  alignX: 'end',
58
71
  alignY: 'top',
59
- offset: [HORIZONTAL_ALIGN_COLUMN_BUTTON, VERTICAL_ALIGN_COLUMN_BUTTON],
72
+ offset: [
73
+ HORIZONTAL_ALIGN_COLUMN_BUTTON,
74
+ isDragAndDropEnabled
75
+ ? VERTICAL_ALIGN_COLUMN_BUTTON_DRAG
76
+ : VERTICAL_ALIGN_COLUMN_BUTTON,
77
+ ],
60
78
  // :: (position: PopupPosition) -> PopupPosition
61
79
  // Limit the InsertButton position to the table container
62
80
  // if the left position starts before it
@@ -104,16 +122,22 @@ function getColumnOptions(
104
122
  }
105
123
 
106
124
  function getPopupOptions(
107
- type: 'column' | 'row',
125
+ direction: TableDirection,
108
126
  index: number,
109
127
  hasNumberedColumns: boolean,
128
+ isDragAndDropEnabled: boolean,
110
129
  tableContainer: HTMLElement | null,
111
130
  ): Partial<PopupProps> {
112
- switch (type) {
131
+ switch (direction) {
113
132
  case 'column':
114
- return getColumnOptions(index, tableContainer, hasNumberedColumns);
133
+ return getColumnOptions(
134
+ index,
135
+ tableContainer,
136
+ hasNumberedColumns,
137
+ isDragAndDropEnabled,
138
+ );
115
139
  case 'row':
116
- return getRowOptions(index);
140
+ return getRowOptions(index, isDragAndDropEnabled);
117
141
  default:
118
142
  return {};
119
143
  }