@atlaskit/editor-plugin-table 5.3.29 → 5.3.31

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 (75) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/cjs/plugins/table/event-handlers.js +10 -2
  3. package/dist/cjs/plugins/table/nodeviews/ExternalDropTargets.js +75 -0
  4. package/dist/cjs/plugins/table/nodeviews/TableComponent.js +75 -4
  5. package/dist/cjs/plugins/table/nodeviews/TableRow.js +36 -112
  6. package/dist/cjs/plugins/table/nodeviews/TableStickyScrollbar.js +9 -9
  7. package/dist/cjs/plugins/table/pm-plugins/drag-and-drop/plugin.js +0 -8
  8. package/dist/cjs/plugins/table/ui/TableFloatingColumnControls/ColumnDropTargets/ColumnDropTarget.js +2 -1
  9. package/dist/cjs/plugins/table/ui/TableFloatingColumnControls/index.js +2 -4
  10. package/dist/cjs/plugins/table/ui/TableFloatingControls/RowControls/DragControls.js +62 -10
  11. package/dist/cjs/plugins/table/ui/TableFloatingControls/RowDropTarget/index.js +61 -0
  12. package/dist/cjs/plugins/table/ui/TableFloatingControls/index.js +21 -15
  13. package/dist/cjs/plugins/table/ui/common-styles.js +1 -1
  14. package/dist/cjs/plugins/table/ui/consts.js +4 -2
  15. package/dist/es2019/plugins/table/event-handlers.js +11 -3
  16. package/dist/es2019/plugins/table/nodeviews/ExternalDropTargets.js +64 -0
  17. package/dist/es2019/plugins/table/nodeviews/TableComponent.js +80 -5
  18. package/dist/es2019/plugins/table/nodeviews/TableRow.js +4 -78
  19. package/dist/es2019/plugins/table/nodeviews/TableStickyScrollbar.js +6 -6
  20. package/dist/es2019/plugins/table/pm-plugins/drag-and-drop/plugin.js +0 -8
  21. package/dist/es2019/plugins/table/ui/TableFloatingColumnControls/ColumnDropTargets/ColumnDropTarget.js +2 -1
  22. package/dist/es2019/plugins/table/ui/TableFloatingColumnControls/index.js +2 -4
  23. package/dist/es2019/plugins/table/ui/TableFloatingControls/RowControls/DragControls.js +58 -8
  24. package/dist/es2019/plugins/table/ui/TableFloatingControls/RowDropTarget/index.js +55 -0
  25. package/dist/es2019/plugins/table/ui/TableFloatingControls/index.js +17 -11
  26. package/dist/es2019/plugins/table/ui/common-styles.js +2 -2
  27. package/dist/es2019/plugins/table/ui/consts.js +3 -1
  28. package/dist/esm/plugins/table/event-handlers.js +10 -2
  29. package/dist/esm/plugins/table/nodeviews/ExternalDropTargets.js +65 -0
  30. package/dist/esm/plugins/table/nodeviews/TableComponent.js +76 -5
  31. package/dist/esm/plugins/table/nodeviews/TableRow.js +36 -112
  32. package/dist/esm/plugins/table/nodeviews/TableStickyScrollbar.js +9 -9
  33. package/dist/esm/plugins/table/pm-plugins/drag-and-drop/plugin.js +0 -8
  34. package/dist/esm/plugins/table/ui/TableFloatingColumnControls/ColumnDropTargets/ColumnDropTarget.js +2 -1
  35. package/dist/esm/plugins/table/ui/TableFloatingColumnControls/index.js +2 -4
  36. package/dist/esm/plugins/table/ui/TableFloatingControls/RowControls/DragControls.js +62 -11
  37. package/dist/esm/plugins/table/ui/TableFloatingControls/RowDropTarget/index.js +52 -0
  38. package/dist/esm/plugins/table/ui/TableFloatingControls/index.js +21 -15
  39. package/dist/esm/plugins/table/ui/common-styles.js +2 -2
  40. package/dist/esm/plugins/table/ui/consts.js +3 -1
  41. package/dist/types/plugins/table/nodeviews/ExternalDropTargets.d.ts +9 -0
  42. package/dist/types/plugins/table/nodeviews/TableComponent.d.ts +1 -0
  43. package/dist/types/plugins/table/nodeviews/TableRow.d.ts +0 -4
  44. package/dist/types/plugins/table/nodeviews/TableStickyScrollbar.d.ts +3 -3
  45. package/dist/types/plugins/table/ui/TableFloatingControls/RowControls/DragControls.d.ts +1 -1
  46. package/dist/types/plugins/table/ui/TableFloatingControls/RowDropTarget/index.d.ts +8 -0
  47. package/dist/types/plugins/table/ui/TableFloatingControls/index.d.ts +3 -1
  48. package/dist/types/plugins/table/ui/consts.d.ts +2 -0
  49. package/dist/types/plugins/table/utils/column-controls.d.ts +2 -2
  50. package/dist/types-ts4.5/plugins/table/nodeviews/ExternalDropTargets.d.ts +9 -0
  51. package/dist/types-ts4.5/plugins/table/nodeviews/TableComponent.d.ts +1 -0
  52. package/dist/types-ts4.5/plugins/table/nodeviews/TableRow.d.ts +0 -4
  53. package/dist/types-ts4.5/plugins/table/nodeviews/TableStickyScrollbar.d.ts +3 -3
  54. package/dist/types-ts4.5/plugins/table/ui/TableFloatingControls/RowControls/DragControls.d.ts +1 -1
  55. package/dist/types-ts4.5/plugins/table/ui/TableFloatingControls/RowDropTarget/index.d.ts +8 -0
  56. package/dist/types-ts4.5/plugins/table/ui/TableFloatingControls/index.d.ts +3 -1
  57. package/dist/types-ts4.5/plugins/table/ui/consts.d.ts +2 -0
  58. package/dist/types-ts4.5/plugins/table/utils/column-controls.d.ts +2 -2
  59. package/package.json +3 -3
  60. package/src/__tests__/unit/ui/RowDragControls.tsx +2 -0
  61. package/src/plugins/table/event-handlers.ts +14 -1
  62. package/src/plugins/table/nodeviews/ExternalDropTargets.tsx +86 -0
  63. package/src/plugins/table/nodeviews/TableComponent.tsx +92 -7
  64. package/src/plugins/table/nodeviews/TableRow.ts +2 -65
  65. package/src/plugins/table/nodeviews/TableStickyScrollbar.ts +6 -6
  66. package/src/plugins/table/pm-plugins/drag-and-drop/plugin.ts +0 -7
  67. package/src/plugins/table/ui/TableFloatingColumnControls/ColumnDropTargets/ColumnDropTarget.tsx +1 -0
  68. package/src/plugins/table/ui/TableFloatingColumnControls/index.tsx +2 -7
  69. package/src/plugins/table/ui/TableFloatingControls/RowControls/DragControls.tsx +80 -21
  70. package/src/plugins/table/ui/TableFloatingControls/RowDropTarget/index.tsx +62 -0
  71. package/src/plugins/table/ui/TableFloatingControls/index.tsx +29 -8
  72. package/src/plugins/table/ui/common-styles.ts +2 -1
  73. package/src/plugins/table/ui/consts.ts +3 -0
  74. package/src/plugins/table/utils/column-controls.ts +2 -2
  75. package/tsconfig.app.json +2 -2
@@ -11,6 +11,9 @@ import { analyticsEventKey, browser, isValidPosition } from '@atlaskit/editor-co
11
11
  import { MAX_BROWSER_SCROLLBAR_HEIGHT, akEditorTableToolbarSize as tableToolbarSize } from '@atlaskit/editor-shared-styles';
12
12
  import { findTable, isTableSelected } from '@atlaskit/editor-tables/utils';
13
13
  import { getBooleanFF } from '@atlaskit/platform-feature-flags';
14
+ import { combine } from '@atlaskit/pragmatic-drag-and-drop/util/combine';
15
+ import { autoScrollForElements, autoScrollWindowForElements } from '@atlaskit/pragmatic-drag-and-drop-auto-scroll/element';
16
+ import { unsafeOverflowAutoScrollForElements } from '@atlaskit/pragmatic-drag-and-drop-auto-scroll/unsafe-overflow/element';
14
17
  import { autoSizeTable, clearHoverSelection } from '../commands';
15
18
  import { getPluginState } from '../pm-plugins/plugin-factory';
16
19
  import { findStickyHeaderForTable, pluginKey as stickyHeadersPluginKey } from '../pm-plugins/sticky-headers';
@@ -19,10 +22,11 @@ import { getLayoutSize, insertColgroupFromNode as recreateResizeColsByNode, scal
19
22
  import { hasTableBeenResized } from '../pm-plugins/table-resizing/utils/colgroup';
20
23
  import { updateControls } from '../pm-plugins/table-resizing/utils/dom';
21
24
  import { TableCssClassName as ClassName, ShadowEvent } from '../types';
22
- import { tableOverflowShadowWidth, tableOverflowShadowWidthWide } from '../ui/consts';
25
+ import { dropTargetExtendedWidth, tableOverflowShadowWidth, tableOverflowShadowWidthWide } from '../ui/consts';
23
26
  import TableFloatingColumnControls from '../ui/TableFloatingColumnControls';
24
27
  import TableFloatingControls from '../ui/TableFloatingControls';
25
28
  import { containsHeaderRow, isTableNested, tablesHaveDifferentColumnWidths, tablesHaveDifferentNoOfColumns } from '../utils';
29
+ import { ExternalDropTargets } from './ExternalDropTargets';
26
30
  import { OverflowShadowsObserver } from './OverflowShadowsObserver';
27
31
  import { TableContainer } from './TableContainer';
28
32
  import { TableStickyScrollbar } from './TableStickyScrollbar';
@@ -304,7 +308,9 @@ class TableComponent extends React.Component {
304
308
  const {
305
309
  allowColumnResizing,
306
310
  eventDispatcher,
307
- options
311
+ options,
312
+ isDragAndDropEnabled,
313
+ getNode
308
314
  } = this.props;
309
315
  if (allowColumnResizing && this.wrapper && !isIE11) {
310
316
  this.wrapper.addEventListener('scroll', this.handleScrollDebounced, {
@@ -315,6 +321,60 @@ class TableComponent extends React.Component {
315
321
  this.stickyScrollbar = new TableStickyScrollbar(this.wrapper, this.props.view);
316
322
  }
317
323
  }
324
+ if (isDragAndDropEnabled) {
325
+ this.dragAndDropCleanupFn = combine(autoScrollForElements({
326
+ element: this.wrapper,
327
+ canScroll: ({
328
+ source
329
+ }) => {
330
+ const {
331
+ localId,
332
+ type
333
+ } = source.data;
334
+ const node = getNode();
335
+ return localId === (node === null || node === void 0 ? void 0 : node.attrs.localId) && type === 'table-column';
336
+ }
337
+ }), autoScrollWindowForElements({
338
+ canScroll: ({
339
+ source
340
+ }) => {
341
+ const {
342
+ localId,
343
+ type
344
+ } = source.data;
345
+ const node = getNode();
346
+ return localId === (node === null || node === void 0 ? void 0 : node.attrs.localId) && type === 'table-row';
347
+ }
348
+ }), unsafeOverflowAutoScrollForElements({
349
+ element: this.wrapper,
350
+ canScroll: ({
351
+ source
352
+ }) => {
353
+ const {
354
+ localId
355
+ } = source.data;
356
+ const node = getNode();
357
+ return localId === (node === null || node === void 0 ? void 0 : node.attrs.localId);
358
+ },
359
+ getOverflow: () => ({
360
+ fromTopEdge: {
361
+ top: dropTargetExtendedWidth,
362
+ right: dropTargetExtendedWidth,
363
+ left: dropTargetExtendedWidth
364
+ },
365
+ fromRightEdge: {
366
+ right: dropTargetExtendedWidth,
367
+ top: dropTargetExtendedWidth,
368
+ bottom: dropTargetExtendedWidth
369
+ },
370
+ fromLeftEdge: {
371
+ top: dropTargetExtendedWidth,
372
+ left: dropTargetExtendedWidth,
373
+ bottom: dropTargetExtendedWidth
374
+ }
375
+ })
376
+ }));
377
+ }
318
378
  }
319
379
  if (allowColumnResizing) {
320
380
  /**
@@ -340,11 +400,15 @@ class TableComponent extends React.Component {
340
400
  const {
341
401
  allowColumnResizing,
342
402
  eventDispatcher,
343
- options
403
+ options,
404
+ isDragAndDropEnabled
344
405
  } = this.props;
345
406
  if (this.wrapper && !isIE11) {
346
407
  this.wrapper.removeEventListener('scroll', this.handleScrollDebounced);
347
408
  }
409
+ if (isDragAndDropEnabled && this.dragAndDropCleanupFn) {
410
+ this.dragAndDropCleanupFn();
411
+ }
348
412
  if (getBooleanFF('platform.editor.table-sticky-scrollbar')) {
349
413
  if (this.stickyScrollbar) {
350
414
  this.stickyScrollbar.dispose();
@@ -553,7 +617,18 @@ class TableComponent extends React.Component {
553
617
  }), getBooleanFF('platform.editor.table-sticky-scrollbar') && /*#__PURE__*/React.createElement("div", {
554
618
  className: ClassName.TABLE_STICKY_SCROLLBAR_SENTINEL_TOP,
555
619
  "data-testid": "sticky-scrollbar-sentinel-top"
556
- }), allowControls && rowControls, isDragAndDropEnabled && allowControls && colControls, /*#__PURE__*/React.createElement("div", {
620
+ }), allowControls && rowControls, isDragAndDropEnabled && /*#__PURE__*/React.createElement(ExternalDropTargets, {
621
+ editorView: view,
622
+ node: node,
623
+ getScrollOffset: () => {
624
+ var _this$wrapper2;
625
+ return ((_this$wrapper2 = this.wrapper) === null || _this$wrapper2 === void 0 ? void 0 : _this$wrapper2.scrollLeft) || 0;
626
+ },
627
+ getTableWrapperWidth: () => {
628
+ var _this$wrapper3;
629
+ return ((_this$wrapper3 = this.wrapper) === null || _this$wrapper3 === void 0 ? void 0 : _this$wrapper3.clientWidth) || 760;
630
+ }
631
+ }), /*#__PURE__*/React.createElement("div", {
557
632
  style: shadowStyle(showBeforeShadow),
558
633
  className: ClassName.TABLE_LEFT_SHADOW
559
634
  }), this.state.stickyHeader && /*#__PURE__*/React.createElement("div", {
@@ -575,7 +650,7 @@ class TableComponent extends React.Component {
575
650
  }
576
651
  }
577
652
  }
578
- }), getBooleanFF('platform.editor.table-sticky-scrollbar') && /*#__PURE__*/React.createElement("div", {
653
+ }, allowControls && colControls), getBooleanFF('platform.editor.table-sticky-scrollbar') && /*#__PURE__*/React.createElement("div", {
579
654
  className: ClassName.TABLE_STICKY_SCROLLBAR_CONTAINER,
580
655
  style: {
581
656
  height: MAX_BROWSER_SCROLLBAR_HEIGHT,
@@ -3,8 +3,6 @@ import debounce from 'lodash/debounce';
3
3
  import throttle from 'lodash/throttle';
4
4
  import { findOverflowScrollParent } from '@atlaskit/editor-common/ui';
5
5
  import { browser } from '@atlaskit/editor-common/utils';
6
- import { dropTargetForElements } from '@atlaskit/pragmatic-drag-and-drop/adapter/element';
7
- import { attachClosestEdge } from '@atlaskit/pragmatic-drag-and-drop-hitbox/addon/closest-edge';
8
6
  import { getPluginState } from '../pm-plugins/plugin-factory';
9
7
  import { pluginKey as tablePluginKey } from '../pm-plugins/plugin-key';
10
8
  import { updateStickyState } from '../pm-plugins/sticky-headers/commands';
@@ -31,6 +29,9 @@ export default class TableRow extends TableNodeView {
31
29
  _defineProperty(this, "listening", false);
32
30
  _defineProperty(this, "padding", 0);
33
31
  _defineProperty(this, "top", 0);
32
+ /**
33
+ * Methods
34
+ */
34
35
  _defineProperty(this, "headerRowMouseScrollEnd", debounce(() => {
35
36
  this.dom.classList.remove('no-pointer-events');
36
37
  }, HEADER_ROW_SCROLL_RESET_DEBOUNCE_TIMEOUT));
@@ -46,28 +47,21 @@ export default class TableRow extends TableNodeView {
46
47
  this.isHeaderRow = supportedHeaderRow(node);
47
48
  this.isSticky = false;
48
49
  const {
49
- pluginConfig,
50
- isDragAndDropEnabled
50
+ pluginConfig
51
51
  } = getPluginState(view.state);
52
52
  this.isStickyHeaderEnabled = !!pluginConfig.stickyHeaders;
53
- this.isDragAndDropEnabled = !!isDragAndDropEnabled;
54
53
  if (this.isHeaderRow) {
55
54
  this.dom.setAttribute('data-header-row', 'true');
56
55
  if (this.isStickyHeaderEnabled) {
57
56
  this.subscribe();
58
57
  }
59
58
  }
60
- if (this.isDragAndDropEnabled) {
61
- this.addDropTarget(this.contentDOM);
62
- }
63
59
  }
64
60
 
65
61
  /**
66
62
  * Variables
67
63
  */
68
64
 
69
- // @ts-ignore
70
-
71
65
  /**
72
66
  * Methods: Nodeview Lifecycle
73
67
  */
@@ -101,7 +95,6 @@ export default class TableRow extends TableNodeView {
101
95
  return true;
102
96
  }
103
97
  destroy() {
104
- var _this$dropTargetClean;
105
98
  if (this.isStickyHeaderEnabled) {
106
99
  this.unsubscribe();
107
100
  const tree = getTree(this.dom);
@@ -110,9 +103,6 @@ export default class TableRow extends TableNodeView {
110
103
  }
111
104
  this.emitOff(true);
112
105
  }
113
-
114
- // If a drop target cleanup method has been set then we should call it.
115
- (_this$dropTargetClean = this.dropTargetCleanup) === null || _this$dropTargetClean === void 0 ? void 0 : _this$dropTargetClean.call(this);
116
106
  }
117
107
  ignoreMutation(mutationRecord) {
118
108
  /* tableRows are not directly editable by the user
@@ -137,70 +127,6 @@ export default class TableRow extends TableNodeView {
137
127
  }
138
128
  return true;
139
129
  }
140
-
141
- /**
142
- * Methods
143
- */
144
-
145
- addDropTarget(element) {
146
- const pos = this.getPos();
147
- if (!Number.isFinite(pos)) {
148
- return;
149
- }
150
- if (this.dropTargetCleanup) {
151
- this.dropTargetCleanup();
152
- }
153
- this.dropTargetCleanup = dropTargetForElements({
154
- element: element,
155
- canDrop: ({
156
- source
157
- }) => {
158
- var _data$indexes, _data$indexes2;
159
- const data = source.data;
160
- const {
161
- localId,
162
- targetIndex
163
- } = this.getCurrentData();
164
- return (
165
- // Only draggables of row type can be dropped on this target
166
- data.type === 'table-row' &&
167
- // Only draggables which came from the same table can be dropped on this target
168
- data.localId === localId &&
169
- // Only draggables which DO NOT include this drop targets index can be dropped
170
- !!((_data$indexes = data.indexes) !== null && _data$indexes !== void 0 && _data$indexes.length) && ((_data$indexes2 = data.indexes) === null || _data$indexes2 === void 0 ? void 0 : _data$indexes2.indexOf(targetIndex)) === -1
171
- );
172
- },
173
- getIsSticky: () => true,
174
- getData: ({
175
- input,
176
- element
177
- }) => {
178
- const {
179
- localId,
180
- targetIndex
181
- } = this.getCurrentData();
182
- const data = {
183
- localId,
184
- type: 'table-row',
185
- targetIndex
186
- };
187
- return attachClosestEdge(data, {
188
- input,
189
- element,
190
- allowedEdges: ['top', 'bottom']
191
- });
192
- }
193
- });
194
- }
195
- getCurrentData() {
196
- const resolvedPos = this.view.state.doc.resolve(this.getPos());
197
- const targetIndex = resolvedPos.index();
198
- const localId = resolvedPos.parent.attrs.localId;
199
- return {
200
- targetIndex,
201
- localId
202
- };
203
- }
204
130
  subscribe() {
205
131
  this.editorScrollableElement = findOverflowScrollParent(this.view.dom) || window;
206
132
  if (this.editorScrollableElement) {
@@ -21,7 +21,7 @@ export class TableStickyScrollbar {
21
21
  this.stickyScrollbarContainerElement.removeEventListener('scroll', this.handleScrollDebounced);
22
22
  this.handleScrollDebounced.cancel();
23
23
  }
24
- this.deleteIntesactionObserver();
24
+ this.deleteIntersectionObserver();
25
25
  }
26
26
  scrollLeft(left) {
27
27
  if (this.stickyScrollbarContainerElement) {
@@ -59,10 +59,10 @@ export class TableStickyScrollbar {
59
59
  return;
60
60
  }
61
61
  if (target.classList.contains(ClassName.TABLE_STICKY_SCROLLBAR_SENTINEL_BOTTOM)) {
62
- this.sentenialBottomCallback(entry);
62
+ this.sentinelBottomCallback(entry);
63
63
  }
64
64
  if (target.classList.contains(ClassName.TABLE_STICKY_SCROLLBAR_SENTINEL_TOP)) {
65
- this.sentenialTopCallback(entry);
65
+ this.sentinelTopCallback(entry);
66
66
  }
67
67
  });
68
68
  }, {
@@ -72,7 +72,7 @@ export class TableStickyScrollbar {
72
72
  this.sentinels.top = (_this$wrapper2 = this.wrapper) === null || _this$wrapper2 === void 0 ? void 0 : (_this$wrapper2$parent = _this$wrapper2.parentElement) === null || _this$wrapper2$parent === void 0 ? void 0 : (_this$wrapper2$parent2 = _this$wrapper2$parent.getElementsByClassName(ClassName.TABLE_STICKY_SCROLLBAR_SENTINEL_TOP)) === null || _this$wrapper2$parent2 === void 0 ? void 0 : _this$wrapper2$parent2.item(0);
73
73
  [this.sentinels.bottom, this.sentinels.top].forEach(el => this.intersectionObserver.observe(el));
74
74
  }
75
- deleteIntesactionObserver() {
75
+ deleteIntersectionObserver() {
76
76
  if (this.intersectionObserver) {
77
77
  if (this.sentinels.bottom) {
78
78
  this.intersectionObserver.unobserve(this.sentinels.bottom);
@@ -80,13 +80,13 @@ export class TableStickyScrollbar {
80
80
  this.intersectionObserver.disconnect();
81
81
  }
82
82
  }
83
- sentenialBottomCallback(entry) {
83
+ sentinelBottomCallback(entry) {
84
84
  var _entry$rootBounds2;
85
85
  const sentinelIsAboveScrollArea = entry.boundingClientRect.top < (((_entry$rootBounds2 = entry.rootBounds) === null || _entry$rootBounds2 === void 0 ? void 0 : _entry$rootBounds2.top) || 0);
86
86
  this.bottomSentinelState = sentinelIsAboveScrollArea ? 'above' : entry.isIntersecting ? 'visible' : 'below';
87
87
  this.toggle();
88
88
  }
89
- sentenialTopCallback(entry) {
89
+ sentinelTopCallback(entry) {
90
90
  var _entry$rootBounds3;
91
91
  const sentinelIsBelowScrollArea = (((_entry$rootBounds3 = entry.rootBounds) === null || _entry$rootBounds3 === void 0 ? void 0 : _entry$rootBounds3.bottom) || 0) < entry.boundingClientRect.top;
92
92
  this.topSentinelState = sentinelIsBelowScrollArea ? 'below' : entry.isIntersecting ? 'visible' : 'above';
@@ -3,7 +3,6 @@ import { DecorationSet } from '@atlaskit/editor-prosemirror/view';
3
3
  import { CellSelection } from '@atlaskit/editor-tables/cell-selection';
4
4
  import { getCellsInRow } from '@atlaskit/editor-tables/utils';
5
5
  import { monitorForElements } from '@atlaskit/pragmatic-drag-and-drop/adapter/element';
6
- import { autoScroller } from '@atlaskit/pragmatic-drag-and-drop-react-beautiful-dnd-autoscroll';
7
6
  import { hasMergedCellsInColumn, hasMergedCellsInRow } from '../../utils/merged-cells';
8
7
  import { getPluginState as getTablePluginState } from '../plugin-factory';
9
8
  import { DragAndDropActionType } from './actions';
@@ -92,15 +91,9 @@ export const createPlugin = (dispatch, eventDispatcher) => {
92
91
  onDragStart: ({
93
92
  location
94
93
  }) => {
95
- autoScroller.start({
96
- input: location.current.input
97
- });
98
94
  toggleDragMenu(false)(editorView.state, editorView.dispatch);
99
95
  },
100
96
  onDrag(event) {
101
- autoScroller.updateInput({
102
- input: event.location.current.input
103
- });
104
97
  const data = getDraggableDataFromEvent(event);
105
98
  // If no data can be found then it's most like we do not want to perform any drag actions
106
99
  if (!data) {
@@ -118,7 +111,6 @@ export const createPlugin = (dispatch, eventDispatcher) => {
118
111
  setDropTarget(dropTargetType, targetAdjustedIndex)(editorView.state, editorView.dispatch);
119
112
  },
120
113
  onDrop(event) {
121
- autoScroller.stop();
122
114
  const data = getDraggableDataFromEvent(event);
123
115
 
124
116
  // If no data can be found then it's most like we do not want to perform any drop action
@@ -53,7 +53,8 @@ export const ColumnDropTarget = ({
53
53
  width: width && `${width - 1}px`,
54
54
  height: height && `${height}px`,
55
55
  marginTop: marginTop && `${marginTop}px`,
56
- pointerEvents: 'auto'
56
+ pointerEvents: 'auto',
57
+ flexShrink: 0
57
58
  },
58
59
  "data-drop-target-index": index,
59
60
  "data-drop-target-localid": localId,
@@ -1,5 +1,4 @@
1
1
  import React, { useEffect, useMemo, useState } from 'react';
2
- import ReactDOM from 'react-dom';
3
2
  import { monitorForElements } from '@atlaskit/pragmatic-drag-and-drop/adapter/element';
4
3
  import { TableCssClassName as ClassName } from '../../types';
5
4
  import { containsHeaderColumn, getColumnsWidths, getRowHeights } from '../../utils';
@@ -76,11 +75,10 @@ export const TableFloatingColumnControls = ({
76
75
  }
77
76
  const colWidths = getColumnsWidths(editorView);
78
77
  const stickyTop = stickyHeader && stickyHeader.sticky && hasHeaderRow ? stickyHeader.top : undefined;
79
- const mountTo = tableRef && (tableRef === null || tableRef === void 0 ? void 0 : tableRef.parentElement) || document.body;
80
78
  if (!tableActive) {
81
79
  return null;
82
80
  }
83
- return /*#__PURE__*/ReactDOM.createPortal( /*#__PURE__*/React.createElement("div", {
81
+ return /*#__PURE__*/React.createElement("div", {
84
82
  className: ClassName.DRAG_COLUMN_CONTROLS_WRAPPER,
85
83
  "data-testid": "table-floating-column-controls-wrapper"
86
84
  }, /*#__PURE__*/React.createElement(ColumnControls, {
@@ -102,6 +100,6 @@ export const TableFloatingColumnControls = ({
102
100
  localId: currentNodeLocalId,
103
101
  rowHeights: rowHeights,
104
102
  colWidths: colWidths
105
- })), mountTo);
103
+ }));
106
104
  };
107
105
  export default TableFloatingColumnControls;
@@ -1,12 +1,16 @@
1
- import React, { useCallback, useMemo } from 'react';
1
+ import React, { Fragment, useCallback, useEffect, useMemo, useState } from 'react';
2
2
  import { injectIntl } from 'react-intl-next';
3
3
  import { CellSelection } from '@atlaskit/editor-tables';
4
4
  import { getSelectionRect } from '@atlaskit/editor-tables/utils';
5
+ import { monitorForElements } from '@atlaskit/pragmatic-drag-and-drop/adapter/element';
5
6
  import { clearHoverSelection } from '../../../commands';
6
7
  import { toggleDragMenu } from '../../../pm-plugins/drag-and-drop/commands';
8
+ import { getPluginState as getTablePluginState } from '../../../pm-plugins/plugin-factory';
7
9
  import { TableCssClassName as ClassName } from '../../../types';
8
10
  import { getRowHeights, getRowsParams, getSelectedRowIndexes } from '../../../utils';
11
+ import { dropTargetExtendedWidth } from '../../consts';
9
12
  import { DragHandle } from '../../DragHandle';
13
+ import RowDropTarget from '../RowDropTarget';
10
14
  const getSelectedRows = selection => {
11
15
  if (selection instanceof CellSelection && selection.isRowSelection()) {
12
16
  const rect = getSelectionRect(selection);
@@ -20,22 +24,51 @@ const getSelectedRows = selection => {
20
24
  const DragControlsComponent = ({
21
25
  tableRef,
22
26
  tableNode,
27
+ tableWidth,
23
28
  hoveredCell,
24
29
  tableActive,
25
30
  editorView,
26
31
  isInDanger,
27
32
  isResizing,
28
- hasHeaderRow,
29
33
  hoverRows,
30
34
  selectRow,
31
35
  updateCellHoverLocation
32
36
  }) => {
33
37
  var _tableNode$attrs$loca, _tableNode$attrs;
38
+ const [isDragging, setIsDragging] = useState(false);
34
39
  const rowHeights = getRowHeights(tableRef);
35
40
  const rowsParams = getRowsParams(rowHeights);
36
41
  const heights = rowHeights.map(height => `${height - 1}px`).join(' ');
37
42
  const selectedRowIndexes = getSelectedRows(editorView.state.selection);
38
- const rowWidth = tableRef.offsetWidth;
43
+ const currentNodeLocalId = (_tableNode$attrs$loca = tableNode === null || tableNode === void 0 ? void 0 : (_tableNode$attrs = tableNode.attrs) === null || _tableNode$attrs === void 0 ? void 0 : _tableNode$attrs.localId) !== null && _tableNode$attrs$loca !== void 0 ? _tableNode$attrs$loca : '';
44
+ useEffect(() => {
45
+ return monitorForElements({
46
+ canMonitor({
47
+ source
48
+ }) {
49
+ const {
50
+ type,
51
+ localId,
52
+ indexes
53
+ } = source.data;
54
+ if (!indexes || !localId || type !== 'table-row') {
55
+ return false;
56
+ }
57
+ const {
58
+ tableNode
59
+ } = getTablePluginState(editorView.state);
60
+ // If the draggable localId is the same as the current selected table localId then we will allow the monitor
61
+ // watch for changes
62
+ return localId === (tableNode === null || tableNode === void 0 ? void 0 : tableNode.attrs.localId);
63
+ },
64
+ onDragStart() {
65
+ setIsDragging(true);
66
+ },
67
+ onDrop() {
68
+ setIsDragging(false);
69
+ }
70
+ });
71
+ }, [editorView]);
39
72
  const onMouseUp = useCallback(() => {
40
73
  toggleDragMenu(undefined, 'row', hoveredCell === null || hoveredCell === void 0 ? void 0 : hoveredCell.rowIndex)(editorView.state, editorView.dispatch);
41
74
  }, [editorView, hoveredCell === null || hoveredCell === void 0 ? void 0 : hoveredCell.rowIndex]);
@@ -75,15 +108,19 @@ const DragControlsComponent = ({
75
108
  return /*#__PURE__*/React.createElement("div", {
76
109
  className: ClassName.DRAG_ROW_CONTROLS,
77
110
  style: {
78
- gridTemplateRows: heights
111
+ gridTemplateRows: heights,
112
+ gridTemplateColumns: isDragging ? `${dropTargetExtendedWidth}px 24px ${tableWidth}px` : `${dropTargetExtendedWidth}px 24px`
79
113
  },
80
114
  onMouseMove: handleMouseMove
81
115
  }, !isResizing && rowsParams.map(({
82
116
  startIndex,
83
117
  endIndex
84
- }, index) => /*#__PURE__*/React.createElement("div", {
118
+ }, index) => /*#__PURE__*/React.createElement(Fragment, {
119
+ key: index
120
+ }, /*#__PURE__*/React.createElement("div", {
85
121
  style: {
86
- gridRow: `${index + 1} / span 1`
122
+ gridRow: `${index + 1} / span 1`,
123
+ gridColumn: '2'
87
124
  },
88
125
  "data-start-index": startIndex,
89
126
  "data-end-index": endIndex,
@@ -92,9 +129,22 @@ const DragControlsComponent = ({
92
129
  key: index
93
130
  }, /*#__PURE__*/React.createElement("div", {
94
131
  className: ClassName.DRAG_ROW_FLOATING_INSERT_DOT
132
+ })), isDragging && /*#__PURE__*/React.createElement(RowDropTarget, {
133
+ key: index,
134
+ index: index,
135
+ localId: currentNodeLocalId,
136
+ style: {
137
+ gridColumn: '1 / span 3',
138
+ gridRow: `${index + 1} / span 1`,
139
+ height: '100%',
140
+ pointerEvents: 'auto',
141
+ position: 'relative',
142
+ left: "var(--ds-space-negative-100, -8px)"
143
+ }
95
144
  }))), !isResizing && Number.isFinite(rowIndex) && /*#__PURE__*/React.createElement("div", {
96
145
  style: {
97
146
  gridRow: gridRowPosition,
147
+ gridColumn: '2',
98
148
  display: 'flex',
99
149
  height: '100%',
100
150
  alignItems: 'center',
@@ -102,9 +152,9 @@ const DragControlsComponent = ({
102
152
  },
103
153
  "data-testid": "table-floating-row-drag-handle"
104
154
  }, /*#__PURE__*/React.createElement(DragHandle, {
105
- tableLocalId: (_tableNode$attrs$loca = tableNode === null || tableNode === void 0 ? void 0 : (_tableNode$attrs = tableNode.attrs) === null || _tableNode$attrs === void 0 ? void 0 : _tableNode$attrs.localId) !== null && _tableNode$attrs$loca !== void 0 ? _tableNode$attrs$loca : '',
155
+ tableLocalId: currentNodeLocalId,
106
156
  indexes: [rowIndex],
107
- previewWidth: rowWidth,
157
+ previewWidth: tableWidth,
108
158
  previewHeight: rowHeights[rowIndex],
109
159
  appearance: selectedRowIndexes.includes(rowIndex) ? isInDanger ? 'danger' : 'selected' : 'default',
110
160
  onClick: handleClick,
@@ -0,0 +1,55 @@
1
+ import React, { useEffect, useRef } from 'react';
2
+ import { dropTargetForElements } from '@atlaskit/pragmatic-drag-and-drop/adapter/element';
3
+ import { attachClosestEdge } from '@atlaskit/pragmatic-drag-and-drop-hitbox/addon/closest-edge';
4
+ const RowDropTarget = ({
5
+ index,
6
+ localId,
7
+ style
8
+ }) => {
9
+ const dropTargetRef = useRef(null);
10
+ useEffect(() => {
11
+ if (!dropTargetRef.current) {
12
+ return;
13
+ }
14
+ return dropTargetForElements({
15
+ element: dropTargetRef.current,
16
+ canDrop({
17
+ source
18
+ }) {
19
+ var _data$indexes, _data$indexes2;
20
+ const data = source.data;
21
+ return (
22
+ // Only draggables of row type can be dropped on this target
23
+ data.type === 'table-row' &&
24
+ // Only draggables which came from the same table can be dropped on this target
25
+ data.localId === localId &&
26
+ // Only draggables which DO NOT include this drop targets index can be dropped
27
+ !!((_data$indexes = data.indexes) !== null && _data$indexes !== void 0 && _data$indexes.length) && ((_data$indexes2 = data.indexes) === null || _data$indexes2 === void 0 ? void 0 : _data$indexes2.indexOf(index)) === -1
28
+ );
29
+ },
30
+ getData({
31
+ input,
32
+ element
33
+ }) {
34
+ const data = {
35
+ localId,
36
+ type: 'table-row',
37
+ targetIndex: index
38
+ };
39
+ return attachClosestEdge(data, {
40
+ input,
41
+ element,
42
+ allowedEdges: ['top', 'bottom']
43
+ });
44
+ }
45
+ });
46
+ }, [index, localId]);
47
+ return /*#__PURE__*/React.createElement("div", {
48
+ ref: dropTargetRef,
49
+ style: style,
50
+ "data-drop-target-index": index,
51
+ "data-drop-target-localid": localId,
52
+ "data-testid": "table-floating-row-controls-drop-target"
53
+ });
54
+ };
55
+ export default RowDropTarget;
@@ -3,13 +3,14 @@ import React, { Component } from 'react';
3
3
  import { browser } from '@atlaskit/editor-common/utils';
4
4
  import { hoverCell, hoverRows, selectRow } from '../../commands';
5
5
  import { getPluginState } from '../../pm-plugins/plugin-factory';
6
+ import { TableCssClassName as ClassName } from '../../types';
6
7
  import { isSelectionUpdated } from '../../utils';
7
8
  import { CornerControls, DragCornerControls } from './CornerControls';
8
9
  import NumberColumn from './NumberColumn';
9
10
  import { DragControls, RowControls } from './RowControls';
10
11
  export default class TableFloatingControls extends Component {
11
- constructor(...args) {
12
- super(...args);
12
+ constructor(props) {
13
+ super(props);
13
14
  _defineProperty(this, "selectRow", (row, expand) => {
14
15
  const {
15
16
  editorView
@@ -48,6 +49,11 @@ export default class TableFloatingControls extends Component {
48
49
  hoverCell(rowIndex, hoveredCell.colIndex)(state, dispatch);
49
50
  }
50
51
  });
52
+ this.state = {
53
+ tableWrapperWidth: 0,
54
+ /** Height needs to be tracked to re-render decorations correctly, do not remove */
55
+ tableWrapperHeight: 0
56
+ };
51
57
  }
52
58
  componentDidMount() {
53
59
  this.tryInitResizeObserver();
@@ -64,19 +70,21 @@ export default class TableFloatingControls extends Component {
64
70
  tableRef
65
71
  } = this.props;
66
72
  if (tableRef && !this.resizeObserver && (_window = window) !== null && _window !== void 0 && _window.ResizeObserver) {
73
+ const tableWrapper = tableRef.closest(`.${ClassName.TABLE_NODE_WRAPPER}`);
67
74
  this.resizeObserver = new ResizeObserver(entries => {
68
75
  for (let entry of entries) {
69
- const tableHeight = entry.contentRect.height;
70
- this.setState({
71
- tableHeight
76
+ this.setState(prev => {
77
+ return (prev === null || prev === void 0 ? void 0 : prev.tableWrapperWidth) === entry.contentRect.width && prev.tableWrapperHeight === entry.contentRect.height ? prev : {
78
+ tableWrapperWidth: entry.contentRect.width,
79
+ tableWrapperHeight: entry.contentRect.height
80
+ };
72
81
  });
73
82
  }
74
83
  });
75
- this.resizeObserver.observe(tableRef);
84
+ this.resizeObserver.observe(tableWrapper);
76
85
  }
77
86
  }
78
87
  shouldComponentUpdate(nextProps, nextState) {
79
- var _this$state;
80
88
  const {
81
89
  tableRef,
82
90
  isInDanger,
@@ -92,9 +100,7 @@ export default class TableFloatingControls extends Component {
92
100
  stickyHeader,
93
101
  hoveredCell
94
102
  } = this.props;
95
- const tableHeight = (_this$state = this.state) === null || _this$state === void 0 ? void 0 : _this$state.tableHeight;
96
- const nextTableHeight = nextState === null || nextState === void 0 ? void 0 : nextState.tableHeight;
97
- return ordering !== nextProps.ordering || tableRef !== nextProps.tableRef || tableHeight !== nextTableHeight || tableActive !== nextProps.tableActive || isInDanger !== nextProps.isInDanger || isResizing !== nextProps.isResizing || hoveredRows !== nextProps.hoveredRows || isHeaderRowEnabled !== nextProps.isHeaderRowEnabled || isHeaderColumnEnabled !== nextProps.isHeaderColumnEnabled || isNumberColumnEnabled !== nextProps.isNumberColumnEnabled || isSelectionUpdated(selection, nextProps.selection) || headerRowHeight !== nextProps.headerRowHeight || stickyHeader !== nextProps.stickyHeader || hoveredCell !== nextProps.hoveredCell;
103
+ return this.state.tableWrapperWidth !== nextState.tableWrapperWidth || this.state.tableWrapperHeight !== nextState.tableWrapperHeight || ordering !== nextProps.ordering || tableRef !== nextProps.tableRef || tableActive !== nextProps.tableActive || isInDanger !== nextProps.isInDanger || isResizing !== nextProps.isResizing || hoveredRows !== nextProps.hoveredRows || isHeaderRowEnabled !== nextProps.isHeaderRowEnabled || isHeaderColumnEnabled !== nextProps.isHeaderColumnEnabled || isNumberColumnEnabled !== nextProps.isNumberColumnEnabled || isSelectionUpdated(selection, nextProps.selection) || headerRowHeight !== nextProps.headerRowHeight || stickyHeader !== nextProps.stickyHeader || hoveredCell !== nextProps.hoveredCell;
98
104
  }
99
105
  componentWillUnmount() {
100
106
  if (this.resizeObserver) {
@@ -150,7 +156,7 @@ export default class TableFloatingControls extends Component {
150
156
  tableActive: tableActive,
151
157
  isInDanger: isInDanger,
152
158
  isResizing: isResizing,
153
- hasHeaderRow: hasHeaderRow,
159
+ tableWidth: this.state.tableWrapperWidth,
154
160
  hoverRows: this.hoverRows,
155
161
  selectRow: this.selectRow,
156
162
  updateCellHoverLocation: this.updateCellHoverLocation