@atlaskit/editor-plugin-table 5.3.7 → 5.3.9

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 (97) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/cjs/plugins/table/nodeviews/TableComponent.js +6 -5
  3. package/dist/cjs/plugins/table/pm-plugins/decorations/plugin.js +3 -2
  4. package/dist/cjs/plugins/table/pm-plugins/decorations/utils/column-controls.js +1 -2
  5. package/dist/cjs/plugins/table/pm-plugins/drag-and-drop/commands.js +1 -1
  6. package/dist/cjs/plugins/table/pm-plugins/drag-and-drop/plugin.js +3 -2
  7. package/dist/cjs/plugins/table/pm-plugins/drag-and-drop/utils/monitor.js +6 -1
  8. package/dist/cjs/plugins/table/types.js +1 -1
  9. package/dist/cjs/plugins/table/ui/DragHandle/index.js +6 -4
  10. package/dist/cjs/plugins/table/ui/TableFloatingColumnControls/ColumnControls/index.js +62 -0
  11. package/dist/cjs/plugins/table/ui/TableFloatingColumnControls/ColumnDropTargets/ColumnDropTarget.js +70 -0
  12. package/dist/cjs/plugins/table/ui/TableFloatingColumnControls/ColumnDropTargets/index.js +12 -77
  13. package/dist/cjs/plugins/table/ui/TableFloatingColumnControls/index.js +58 -16
  14. package/dist/cjs/plugins/table/ui/common-styles.js +1 -1
  15. package/dist/cjs/plugins/table/ui/icons/index.js +19 -0
  16. package/dist/cjs/plugins/table/ui/ui-styles.js +19 -15
  17. package/dist/cjs/plugins/table/utils/decoration.js +3 -24
  18. package/dist/cjs/plugins/table/utils/dom.js +1 -4
  19. package/dist/cjs/plugins/table/utils/index.js +0 -6
  20. package/dist/es2019/plugins/table/nodeviews/TableComponent.js +6 -5
  21. package/dist/es2019/plugins/table/pm-plugins/decorations/plugin.js +3 -2
  22. package/dist/es2019/plugins/table/pm-plugins/decorations/utils/column-controls.js +1 -2
  23. package/dist/es2019/plugins/table/pm-plugins/drag-and-drop/commands.js +1 -1
  24. package/dist/es2019/plugins/table/pm-plugins/drag-and-drop/plugin.js +3 -2
  25. package/dist/es2019/plugins/table/pm-plugins/drag-and-drop/utils/monitor.js +6 -1
  26. package/dist/es2019/plugins/table/types.js +1 -1
  27. package/dist/es2019/plugins/table/ui/DragHandle/index.js +5 -3
  28. package/dist/es2019/plugins/table/ui/TableFloatingColumnControls/ColumnControls/index.js +52 -0
  29. package/dist/es2019/plugins/table/ui/TableFloatingColumnControls/ColumnDropTargets/ColumnDropTarget.js +62 -0
  30. package/dist/es2019/plugins/table/ui/TableFloatingColumnControls/ColumnDropTargets/index.js +8 -74
  31. package/dist/es2019/plugins/table/ui/TableFloatingColumnControls/index.js +58 -15
  32. package/dist/es2019/plugins/table/ui/common-styles.js +2 -5
  33. package/dist/es2019/plugins/table/ui/icons/index.js +2 -0
  34. package/dist/es2019/plugins/table/ui/ui-styles.js +28 -30
  35. package/dist/es2019/plugins/table/utils/decoration.js +3 -24
  36. package/dist/es2019/plugins/table/utils/dom.js +0 -1
  37. package/dist/es2019/plugins/table/utils/index.js +1 -1
  38. package/dist/esm/plugins/table/nodeviews/TableComponent.js +6 -5
  39. package/dist/esm/plugins/table/pm-plugins/decorations/plugin.js +3 -2
  40. package/dist/esm/plugins/table/pm-plugins/decorations/utils/column-controls.js +1 -2
  41. package/dist/esm/plugins/table/pm-plugins/drag-and-drop/commands.js +1 -1
  42. package/dist/esm/plugins/table/pm-plugins/drag-and-drop/plugin.js +3 -2
  43. package/dist/esm/plugins/table/pm-plugins/drag-and-drop/utils/monitor.js +6 -1
  44. package/dist/esm/plugins/table/types.js +1 -1
  45. package/dist/esm/plugins/table/ui/DragHandle/index.js +5 -3
  46. package/dist/esm/plugins/table/ui/TableFloatingColumnControls/ColumnControls/index.js +55 -0
  47. package/dist/esm/plugins/table/ui/TableFloatingColumnControls/ColumnDropTargets/ColumnDropTarget.js +61 -0
  48. package/dist/esm/plugins/table/ui/TableFloatingColumnControls/ColumnDropTargets/index.js +9 -72
  49. package/dist/esm/plugins/table/ui/TableFloatingColumnControls/index.js +58 -16
  50. package/dist/esm/plugins/table/ui/common-styles.js +2 -2
  51. package/dist/esm/plugins/table/ui/icons/index.js +2 -0
  52. package/dist/esm/plugins/table/ui/ui-styles.js +18 -14
  53. package/dist/esm/plugins/table/utils/decoration.js +3 -24
  54. package/dist/esm/plugins/table/utils/dom.js +0 -3
  55. package/dist/esm/plugins/table/utils/index.js +1 -1
  56. package/dist/types/plugins/table/types.d.ts +2 -1
  57. package/dist/types/plugins/table/ui/TableFloatingColumnControls/ColumnControls/index.d.ts +16 -0
  58. package/dist/types/plugins/table/ui/TableFloatingColumnControls/ColumnDropTargets/ColumnDropTarget.d.ts +9 -0
  59. package/dist/types/plugins/table/ui/TableFloatingColumnControls/ColumnDropTargets/index.d.ts +2 -3
  60. package/dist/types/plugins/table/ui/TableFloatingColumnControls/index.d.ts +5 -0
  61. package/dist/types/plugins/table/ui/icons/index.d.ts +2 -0
  62. package/dist/types/plugins/table/ui/ui-styles.d.ts +1 -0
  63. package/dist/types/plugins/table/utils/decoration.d.ts +2 -2
  64. package/dist/types/plugins/table/utils/dom.d.ts +0 -1
  65. package/dist/types/plugins/table/utils/index.d.ts +1 -1
  66. package/dist/types-ts4.5/plugins/table/types.d.ts +2 -1
  67. package/dist/types-ts4.5/plugins/table/ui/TableFloatingColumnControls/ColumnControls/index.d.ts +16 -0
  68. package/dist/types-ts4.5/plugins/table/ui/TableFloatingColumnControls/ColumnDropTargets/ColumnDropTarget.d.ts +9 -0
  69. package/dist/types-ts4.5/plugins/table/ui/TableFloatingColumnControls/ColumnDropTargets/index.d.ts +2 -3
  70. package/dist/types-ts4.5/plugins/table/ui/TableFloatingColumnControls/index.d.ts +5 -0
  71. package/dist/types-ts4.5/plugins/table/ui/icons/index.d.ts +2 -0
  72. package/dist/types-ts4.5/plugins/table/ui/ui-styles.d.ts +1 -0
  73. package/dist/types-ts4.5/plugins/table/utils/decoration.d.ts +2 -2
  74. package/dist/types-ts4.5/plugins/table/utils/dom.d.ts +0 -1
  75. package/dist/types-ts4.5/plugins/table/utils/index.d.ts +1 -1
  76. package/package.json +2 -1
  77. package/src/__tests__/unit/pm-plugins/decorations/column-controls.ts +2 -2
  78. package/src/__tests__/unit/pm-plugins/decorations/plugin.ts +84 -34
  79. package/src/__tests__/unit/ui/TableFloatingColumnControls.tsx +61 -12
  80. package/src/plugins/table/nodeviews/TableComponent.tsx +16 -15
  81. package/src/plugins/table/pm-plugins/decorations/plugin.ts +3 -2
  82. package/src/plugins/table/pm-plugins/decorations/utils/column-controls.ts +1 -1
  83. package/src/plugins/table/pm-plugins/drag-and-drop/commands.ts +1 -4
  84. package/src/plugins/table/pm-plugins/drag-and-drop/plugin.ts +7 -2
  85. package/src/plugins/table/pm-plugins/drag-and-drop/utils/monitor.ts +5 -0
  86. package/src/plugins/table/types.ts +2 -1
  87. package/src/plugins/table/ui/DragHandle/index.tsx +3 -1
  88. package/src/plugins/table/ui/TableFloatingColumnControls/ColumnControls/index.tsx +92 -0
  89. package/src/plugins/table/ui/TableFloatingColumnControls/ColumnDropTargets/ColumnDropTarget.tsx +74 -0
  90. package/src/plugins/table/ui/TableFloatingColumnControls/ColumnDropTargets/index.tsx +12 -80
  91. package/src/plugins/table/ui/TableFloatingColumnControls/index.tsx +69 -17
  92. package/src/plugins/table/ui/common-styles.ts +2 -4
  93. package/src/plugins/table/ui/icons/index.ts +2 -0
  94. package/src/plugins/table/ui/ui-styles.ts +29 -30
  95. package/src/plugins/table/utils/decoration.ts +3 -45
  96. package/src/plugins/table/utils/dom.ts +0 -4
  97. package/src/plugins/table/utils/index.ts +0 -1
@@ -108,38 +108,88 @@ describe('decorations plugin', () => {
108
108
  });
109
109
 
110
110
  describe('when the hovered cell state changes', () => {
111
- describe('should add column control decorations', () => {
112
- ffTest('platform.editor.table.drag-and-drop', () => {
113
- const pluginState = DecorationSet.empty;
114
- const { editorView } = editor(
115
- doc(table()(tr(tdCursor, tdEmpty), tr(tdEmpty, tdEmpty))),
116
- );
117
-
118
- const transaction = editorView.state.tr.setMeta(pluginKey, {
119
- type: 'HOVER_CELL',
120
- data: {
121
- colIndex: 0,
122
- rowIndex: 0,
123
- },
124
- });
125
-
126
- const oldState = handleDocOrSelectionChanged(
127
- transaction,
128
- pluginState,
129
- editorView.state,
130
- editorView.state,
131
- );
132
-
133
- editorView.dispatch(transaction);
134
- const newState = handleDocOrSelectionChanged(
135
- transaction,
136
- oldState,
137
- editorView.state,
138
- editorView.state,
139
- );
140
-
141
- expect(oldState).not.toEqual(newState);
142
- });
111
+ describe('should not add column control decorations', () => {
112
+ ffTest(
113
+ 'platform.editor.table.drag-and-drop',
114
+ () => {
115
+ const pluginState = DecorationSet.empty;
116
+ const { editorView } = editor(
117
+ doc(table()(tr(tdCursor, tdEmpty), tr(tdEmpty, tdEmpty))),
118
+ );
119
+
120
+ const transaction = editorView.state.tr.setMeta(pluginKey, {
121
+ type: 'HOVER_CELL',
122
+ data: {
123
+ colIndex: 0,
124
+ rowIndex: 0,
125
+ },
126
+ });
127
+
128
+ const oldState = handleDocOrSelectionChanged(
129
+ transaction,
130
+ pluginState,
131
+ editorView.state,
132
+ editorView.state,
133
+ );
134
+
135
+ editorView.dispatch(transaction);
136
+ const newState = handleDocOrSelectionChanged(
137
+ transaction,
138
+ oldState,
139
+ editorView.state,
140
+ editorView.state,
141
+ );
142
+
143
+ const columnDecorations = newState.find(
144
+ undefined,
145
+ undefined,
146
+ (spec) =>
147
+ spec.key.indexOf(TableDecorations.COLUMN_CONTROLS_DECORATIONS) >
148
+ -1,
149
+ );
150
+
151
+ expect(columnDecorations).toHaveLength(0);
152
+ },
153
+ () => {
154
+ const pluginState = DecorationSet.empty;
155
+ const { editorView } = editor(
156
+ doc(table()(tr(tdCursor, tdEmpty), tr(tdEmpty, tdEmpty))),
157
+ );
158
+
159
+ const transaction = editorView.state.tr.setMeta(pluginKey, {
160
+ type: 'HOVER_CELL',
161
+ data: {
162
+ colIndex: 0,
163
+ rowIndex: 0,
164
+ },
165
+ });
166
+
167
+ const oldState = handleDocOrSelectionChanged(
168
+ transaction,
169
+ pluginState,
170
+ editorView.state,
171
+ editorView.state,
172
+ );
173
+
174
+ editorView.dispatch(transaction);
175
+ const newState = handleDocOrSelectionChanged(
176
+ transaction,
177
+ oldState,
178
+ editorView.state,
179
+ editorView.state,
180
+ );
181
+
182
+ const columnDecorations = newState.find(
183
+ undefined,
184
+ undefined,
185
+ (spec) =>
186
+ spec.key.indexOf(TableDecorations.COLUMN_CONTROLS_DECORATIONS) >
187
+ -1,
188
+ );
189
+
190
+ expect(columnDecorations).toHaveLength(2);
191
+ },
192
+ );
143
193
  });
144
194
  });
145
195
 
@@ -169,7 +219,7 @@ describe('decorations plugin', () => {
169
219
  });
170
220
 
171
221
  describe('when the table changed', () => {
172
- describe('should re-create the column controls decorations', () => {
222
+ describe('should not re-create the column controls decorations', () => {
173
223
  ffTest(
174
224
  'platform.editor.table.drag-and-drop',
175
225
  () => {
@@ -203,7 +253,7 @@ describe('decorations plugin', () => {
203
253
  -1,
204
254
  );
205
255
 
206
- expect(decorations).toHaveLength(3);
256
+ expect(decorations).toHaveLength(0);
207
257
  },
208
258
  () => {
209
259
  const { editorView } = editor(
@@ -1,9 +1,10 @@
1
1
  import React from 'react';
2
2
 
3
+ import { fireEvent } from '@testing-library/dom';
3
4
  import { render, screen } from '@testing-library/react';
4
5
  import { IntlProvider } from 'react-intl-next';
5
6
 
6
- import type { DocBuilder } from '@atlaskit/editor-common/types';
7
+ import type { DocBuilder, Refs } from '@atlaskit/editor-common/types';
7
8
  // eslint-disable-next-line import/no-extraneous-dependencies -- Removed import for fixing circular dependencies
8
9
  import { analyticsPlugin } from '@atlaskit/editor-plugin-analytics';
9
10
  import { contentInsertionPlugin } from '@atlaskit/editor-plugin-content-insertion';
@@ -12,6 +13,7 @@ import { guidelinePlugin } from '@atlaskit/editor-plugin-guideline';
12
13
  import { selectionPlugin } from '@atlaskit/editor-plugin-selection';
13
14
  import { widthPlugin } from '@atlaskit/editor-plugin-width';
14
15
  import type { PluginKey } from '@atlaskit/editor-prosemirror/state';
16
+ import type { EditorView } from '@atlaskit/editor-prosemirror/view';
15
17
  import type { LightEditorPlugin } from '@atlaskit/editor-test-helpers/create-prosemirror-editor';
16
18
  // eslint-disable-next-line import/no-extraneous-dependencies -- Removed import for fixing circular dependencies
17
19
  import {
@@ -56,13 +58,28 @@ describe('TableFloatingColumnControls', () => {
56
58
  });
57
59
  };
58
60
 
61
+ const getNodeFunc = (view: EditorView, refs: Refs) => () =>
62
+ view.state.doc.nodeAt(refs['<node>'])!;
63
+
64
+ afterEach(async () => {
65
+ // cleanup any pending drags
66
+ fireEvent.dragEnd(window);
67
+ // Optional: unwind a post-drop browser bug fix
68
+ // tick forward a micro task to flush a post-drag bug fix
69
+ await 1;
70
+ // this will trigger the fix to be released
71
+ fireEvent.pointerMove(window);
72
+ });
73
+
59
74
  it('should not render floating column controls when tableRef undefined and drag and drop is not enabled', () => {
60
- const { editorView } = editor(
61
- doc(p('text'), table()(tr(tdEmpty, tdEmpty, tdEmpty))),
75
+ const { editorView, refs } = editor(
76
+ doc(p('text'), '{<node>}', table()(tr(tdEmpty, tdEmpty, tdEmpty))),
62
77
  );
78
+
63
79
  const { container } = render(
64
80
  <TableFloatingColumnControls
65
81
  editorView={editorView}
82
+ getNode={getNodeFunc(editorView, refs)}
66
83
  getEditorFeatureFlags={fakeGetEditorFeatureFlags}
67
84
  />,
68
85
  );
@@ -70,8 +87,8 @@ describe('TableFloatingColumnControls', () => {
70
87
  });
71
88
 
72
89
  it('should not render floating column controls when tableRef undefined and drag and drop is enabled', () => {
73
- const { editorView } = editor(
74
- doc(p('text'), table()(tr(tdEmpty, tdEmpty, tdEmpty))),
90
+ const { editorView, refs } = editor(
91
+ doc(p('text'), '{<node>}', table()(tr(tdEmpty, tdEmpty, tdEmpty))),
75
92
  {
76
93
  dragAndDropEnabled: true,
77
94
  },
@@ -79,15 +96,23 @@ describe('TableFloatingColumnControls', () => {
79
96
  const { container } = render(
80
97
  <TableFloatingColumnControls
81
98
  editorView={editorView}
99
+ getNode={getNodeFunc(editorView, refs)}
82
100
  getEditorFeatureFlags={fakeGetEditorFeatureFlags}
83
101
  />,
84
102
  );
85
103
  expect(container.innerHTML).toEqual('');
86
104
  });
87
105
 
88
- it('should render a drop target per column', () => {
89
- const { editorView } = editor(
90
- doc(p('text'), table()(tr(tdEmpty, tdEmpty, tdEmpty, tdEmpty, tdEmpty))),
106
+ it.todo('should not render drop target when no drag is active');
107
+
108
+ it.todo(
109
+ 'should render a drop target per column when dragging' /*, () => {
110
+ const { editorView, refs } = editor(
111
+ doc(
112
+ p('text'),
113
+ '{<node>}',
114
+ table()(tr(tdEmpty, tdCursor, tdEmpty, tdEmpty, tdEmpty)),
115
+ ),
91
116
  {
92
117
  dragAndDropEnabled: true,
93
118
  },
@@ -97,23 +122,44 @@ describe('TableFloatingColumnControls', () => {
97
122
  render(
98
123
  <IntlProvider locale="en">
99
124
  <TableFloatingColumnControls
125
+ getNode={getNodeFunc(editorView, refs)}
100
126
  tableRef={ref}
101
127
  tableActive={true}
128
+ hoveredCell={{ colIndex: 1, rowIndex: 0}}
102
129
  editorView={editorView}
103
130
  getEditorFeatureFlags={fakeGetEditorFeatureFlags}
104
131
  />
105
132
  </IntlProvider>,
106
133
  );
107
134
 
135
+ screen.debug();
136
+
137
+ const dragHandle = screen.getByTestId(
138
+ 'table-floating-column-controls-drag-handle',
139
+ );
140
+
141
+ fireEvent.dragStart(dragHandle);
142
+
143
+ // ticking forward an animation frame will complete the lift
144
+ // @ts-expect-error
145
+ requestAnimationFrame.step();
146
+
108
147
  const dropTargets = screen.getAllByTestId(
109
148
  'table-floating-column-controls-drop-target',
110
149
  );
150
+
111
151
  expect(dropTargets).toHaveLength(5);
112
- });
152
+ }*/,
153
+ );
113
154
 
114
- it('should render a drop target per column regardless of row count', () => {
115
- const { editorView } = editor(
116
- doc(p('text'), table()(tr(tdEmpty), tr(tdEmpty), tr(tdEmpty))),
155
+ // FIXME and unskp: presumably doesn't work becuase TableFloatingColumnControls are now mounted via ReactDOM.createPortal
156
+ it.skip('should render a drop target per column regardless of row count', () => {
157
+ const { editorView, refs } = editor(
158
+ doc(
159
+ p('text'),
160
+ '{<node>}',
161
+ table()(tr(tdEmpty), tr(tdEmpty), tr(tdEmpty)),
162
+ ),
117
163
  {
118
164
  dragAndDropEnabled: true,
119
165
  },
@@ -123,6 +169,7 @@ describe('TableFloatingColumnControls', () => {
123
169
  render(
124
170
  <IntlProvider locale="en">
125
171
  <TableFloatingColumnControls
172
+ getNode={getNodeFunc(editorView, refs)}
126
173
  tableRef={ref}
127
174
  tableActive={true}
128
175
  editorView={editorView}
@@ -136,4 +183,6 @@ describe('TableFloatingColumnControls', () => {
136
183
  );
137
184
  expect(dropTargets).toHaveLength(1);
138
185
  });
186
+
187
+ it.todo('should remove column drop targets when dragging ends');
139
188
  });
@@ -436,21 +436,22 @@ class TableComponent extends React.Component<ComponentProps, TableState> {
436
436
  );
437
437
 
438
438
  const colControls = (
439
- <div className={ClassName.COLUMN_CONTROLS_WRAPPER}>
440
- <TableFloatingColumnControls
441
- editorView={view}
442
- tableRef={tableRef}
443
- tableActive={tableActive}
444
- hoveredRows={hoveredRows}
445
- ordering={ordering}
446
- hasHeaderRow={hasHeaderRow}
447
- // pass `selection` and `tableHeight` to control re-render
448
- selection={view.state.selection}
449
- headerRowHeight={headerRow ? headerRow.offsetHeight : undefined}
450
- stickyHeader={this.state.stickyHeader}
451
- getEditorFeatureFlags={this.props.getEditorFeatureFlags}
452
- />
453
- </div>
439
+ <TableFloatingColumnControls
440
+ editorView={view}
441
+ tableRef={tableRef}
442
+ getNode={getNode}
443
+ tableActive={tableActive}
444
+ hoveredRows={hoveredRows}
445
+ hoveredCell={hoveredCell}
446
+ isResizing={isResizing}
447
+ ordering={ordering}
448
+ hasHeaderRow={hasHeaderRow}
449
+ // pass `selection` to control re-render
450
+ selection={view.state.selection}
451
+ headerRowHeight={headerRow ? headerRow.offsetHeight : undefined}
452
+ stickyHeader={this.state.stickyHeader}
453
+ getEditorFeatureFlags={this.props.getEditorFeatureFlags}
454
+ />
454
455
  );
455
456
 
456
457
  const shadowPadding =
@@ -8,6 +8,7 @@ import type {
8
8
  import { PluginKey } from '@atlaskit/editor-prosemirror/state';
9
9
  import { DecorationSet } from '@atlaskit/editor-prosemirror/view';
10
10
  import { CellSelection } from '@atlaskit/editor-tables/cell-selection';
11
+ import { getBooleanFF } from '@atlaskit/platform-feature-flags';
11
12
 
12
13
  import { pluginKey as tablePluginKey } from '../plugin-key';
13
14
  import { pluginKey as tableWidthPluginKey } from '../table-width';
@@ -33,8 +34,8 @@ export const handleDocOrSelectionChanged = (
33
34
 
34
35
  const changedResizing = isResizing !== wasResizing;
35
36
 
36
- // Remove column controls when resizing
37
- if (isResizing) {
37
+ // Remove column controls when resizing and don't add column decoration controls when DnD enabled
38
+ if (isResizing || getBooleanFF('platform.editor.table.drag-and-drop')) {
38
39
  return DecorationSet.empty;
39
40
  } else if (
40
41
  tr.docChanged ||
@@ -60,7 +60,7 @@ const maybeUpdateColumnControlsDecoration: DecorationTransformer = ({
60
60
  return updateDecorations(
61
61
  tr.doc,
62
62
  decorationSet,
63
- createColumnControlsDecoration(tr.selection, meta?.data?.hoveredCell),
63
+ createColumnControlsDecoration(tr.selection),
64
64
  TableDecorations.COLUMN_CONTROLS_DECORATIONS,
65
65
  );
66
66
  };
@@ -110,9 +110,6 @@ export const moveSource = (
110
110
  }
111
111
 
112
112
  const move = sourceType === 'table-row' ? moveRow : moveColumn;
113
- return move(
114
- sourceIndex,
115
- targetIndex + (sourceIndex > targetIndex ? 0 : -1),
116
- )(tr);
113
+ return move(sourceIndex, targetIndex)(tr);
117
114
  },
118
115
  );
@@ -87,7 +87,12 @@ export const createPlugin = (
87
87
  return;
88
88
  }
89
89
 
90
- const { sourceType, sourceIndexes, targetAdjustedIndex } = data;
90
+ const {
91
+ sourceType,
92
+ sourceIndexes,
93
+ targetAdjustedIndex,
94
+ direction,
95
+ } = data;
91
96
 
92
97
  // If the drop target index contains merged cells then we should not allow the drop to occur.
93
98
  const hasMergedCells =
@@ -105,7 +110,7 @@ export const createPlugin = (
105
110
  moveSource(
106
111
  sourceType,
107
112
  sourceIndex,
108
- targetAdjustedIndex,
113
+ targetAdjustedIndex + (direction === -1 ? 0 : -1),
109
114
  )(editorView.state, editorView.dispatch);
110
115
  },
111
116
  }),
@@ -59,6 +59,10 @@ export const getDraggableDataFromEvent = ({
59
59
  const targetOffset =
60
60
  targetClosestEdge === 'right' || targetClosestEdge === 'bottom' ? 1 : 0;
61
61
 
62
+ // since only consecutive rows/cols can be moved we can assume that if the first index is greater then
63
+ // the target index, the then the direction of the DnD is decreasing
64
+ const direction = sourceIndexes[0] > targetIndex ? -1 : 1;
65
+
62
66
  return {
63
67
  sourceType,
64
68
  sourceLocalId,
@@ -68,5 +72,6 @@ export const getDraggableDataFromEvent = ({
68
72
  targetIndex,
69
73
  targetAdjustedIndex: targetIndex + targetOffset,
70
74
  targetClosestEdge,
75
+ direction,
71
76
  };
72
77
  };
@@ -299,7 +299,7 @@ export const TableCssClassName = {
299
299
  CONTROLS_CORNER_BUTTON: `${tablePrefixSelector}-corner-button`,
300
300
 
301
301
  /** Controls with drag handle */
302
- COLUMN_CONTROLS_DECORATIONS_WITH_DRAG: `${tablePrefixSelector}-column-controls-decoration-with-drag`,
302
+ COLUMN_CONTROLS_WITH_DRAG: `${tablePrefixSelector}-column-controls-with-drag`,
303
303
  ROW_CONTROLS_WITH_DRAG: `${tablePrefixSelector}-row-controls-with-drag`,
304
304
  DRAG_HANDLE_BUTTON_CONTAINER: `${tablePrefixSelector}-drag-handle-button-container`,
305
305
 
@@ -421,4 +421,5 @@ export interface DraggableData {
421
421
  targetIndex: number;
422
422
  targetAdjustedIndex: number;
423
423
  targetClosestEdge: Edge;
424
+ direction: 1 | -1;
424
425
  }
@@ -10,7 +10,7 @@ import { token } from '@atlaskit/tokens';
10
10
 
11
11
  import { TableCssClassName as ClassName } from '../../types';
12
12
  import { DragPreview } from '../DragPreview';
13
- import { DragHandleIcon } from '../icons/DragHandleIcon';
13
+ import { DragHandleIcon } from '../icons';
14
14
 
15
15
  type DragHandleState = 'default' | 'selected' | 'disabled' | 'danger';
16
16
 
@@ -99,7 +99,9 @@ export const DragHandle = ({
99
99
  borderRadius: '4px',
100
100
  border: `2px solid ${token('elevation.surface', 'white')}`,
101
101
  transform: direction === 'column' ? 'none' : 'rotate(90deg)',
102
+ pointerEvents: 'auto',
102
103
  }}
104
+ data-testid="table-floating-column-controls-drag-handle"
103
105
  >
104
106
  <DragHandleIcon {...iconProps} />
105
107
  {previewContainer &&
@@ -0,0 +1,92 @@
1
+ import React from 'react';
2
+
3
+ import type { EditorView } from '@atlaskit/editor-prosemirror/view';
4
+
5
+ import type { CellHoverCoordinates } from '../../../types';
6
+ import { TableCssClassName as ClassName } from '../../../types';
7
+ import { DragHandle } from '../../DragHandle';
8
+
9
+ export interface Props {
10
+ editorView: EditorView;
11
+ tableActive?: boolean;
12
+ tableRef: HTMLTableElement;
13
+ hoveredCell?: CellHoverCoordinates;
14
+ isResizing?: boolean;
15
+ stickyTop?: number;
16
+ localId?: string;
17
+ rowHeights?: number[];
18
+ colWidths?: (number | undefined)[];
19
+ }
20
+
21
+ export const ColumnControls: React.FC<Props> = ({
22
+ editorView,
23
+ tableActive,
24
+ tableRef,
25
+ hoveredCell,
26
+ isResizing,
27
+ stickyTop,
28
+ localId,
29
+ rowHeights,
30
+ colWidths,
31
+ }) => {
32
+ if (!tableRef) {
33
+ return null;
34
+ }
35
+
36
+ const firstRow = tableRef.querySelector('tr');
37
+ const hasHeaderRow = firstRow
38
+ ? firstRow.getAttribute('data-header-row')
39
+ : false;
40
+
41
+ const marginTop =
42
+ hasHeaderRow && stickyTop !== undefined ? rowHeights?.[0] ?? 0 : 0;
43
+
44
+ const widths =
45
+ colWidths?.map((width) => (width ? `${width - 1}px` : '0px')).join(' ') ??
46
+ '0px';
47
+
48
+ const colIndex = hoveredCell?.colIndex;
49
+
50
+ const onClick = (
51
+ index: number,
52
+ event: React.MouseEvent<Element, MouseEvent>,
53
+ ) => {};
54
+
55
+ const onMouseOver = () => {};
56
+ const onMouseOut = () => {};
57
+
58
+ return (
59
+ <div className={ClassName.COLUMN_CONTROLS_WITH_DRAG}>
60
+ <div
61
+ className={ClassName.COLUMN_CONTROLS_INNER}
62
+ data-testid="table-floating-column-controls"
63
+ style={{
64
+ gridTemplateColumns: widths,
65
+ marginTop,
66
+ }}
67
+ >
68
+ {tableActive && !isResizing && Number.isFinite(colIndex) && (
69
+ <div
70
+ style={{
71
+ gridColumn: `${(colIndex as number) + 1} / span 1`,
72
+ marginTop: `-15px`,
73
+ }}
74
+ data-column-control-index={colIndex}
75
+ data-testid="table-floating-column-control"
76
+ >
77
+ <DragHandle
78
+ direction="column"
79
+ indexes={[colIndex!]}
80
+ onClick={(event) => onClick(colIndex as number, event)}
81
+ onMouseOver={onMouseOver}
82
+ onMouseOut={onMouseOut}
83
+ tableLocalId={localId || ''}
84
+ />
85
+ </div>
86
+ )}
87
+ </div>
88
+ </div>
89
+ );
90
+ };
91
+
92
+ export default ColumnControls;
@@ -0,0 +1,74 @@
1
+ import React, { useEffect, useRef } from 'react';
2
+
3
+ import { attachClosestEdge } from '@atlaskit/pragmatic-drag-and-drop-hitbox/addon/closest-edge';
4
+ import { dropTargetForElements } from '@atlaskit/pragmatic-drag-and-drop/adapter/element';
5
+
6
+ import type { DraggableSourceData } from '../../../types';
7
+
8
+ export interface Props {
9
+ index: number;
10
+ localId?: string;
11
+ width?: number;
12
+ height?: number;
13
+ marginTop?: number;
14
+ }
15
+
16
+ export const ColumnDropTarget: React.FC<Props> = ({
17
+ index,
18
+ localId,
19
+ width,
20
+ height,
21
+ marginTop,
22
+ }) => {
23
+ const dropTargetRef = useRef<HTMLDivElement | null>(null);
24
+
25
+ useEffect(() => {
26
+ if (!dropTargetRef.current) {
27
+ return;
28
+ }
29
+
30
+ return dropTargetForElements({
31
+ element: dropTargetRef.current,
32
+ canDrop({ source }) {
33
+ const data = source.data as DraggableSourceData;
34
+ return (
35
+ // Only draggables of row type can be dropped on this target
36
+ data.type === 'table-column' &&
37
+ // Only draggables which came from the same table can be dropped on this target
38
+ data.localId === localId &&
39
+ // Only draggables which DO NOT include this drop targets index can be dropped
40
+ !!data.indexes?.length &&
41
+ data.indexes?.indexOf(index) === -1
42
+ );
43
+ },
44
+ getIsSticky: () => true,
45
+ getData({ input, element }) {
46
+ const data = {
47
+ localId,
48
+ type: 'table-column',
49
+ targetIndex: index,
50
+ };
51
+ return attachClosestEdge(data, {
52
+ input,
53
+ element,
54
+ allowedEdges: ['left', 'right'],
55
+ });
56
+ },
57
+ });
58
+ }, [index, localId]);
59
+
60
+ return (
61
+ <div
62
+ ref={dropTargetRef}
63
+ style={{
64
+ width: width && `${width - 1}px`,
65
+ height: height && `${height}px`,
66
+ marginTop: marginTop && `${marginTop}px`,
67
+ pointerEvents: 'auto',
68
+ }}
69
+ data-drop-target-index={index}
70
+ data-drop-target-localid={localId}
71
+ data-testid="table-floating-column-controls-drop-target"
72
+ />
73
+ );
74
+ };