@atlaskit/editor-plugin-table 5.3.8 → 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 (60) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/cjs/plugins/table/nodeviews/TableComponent.js +2 -1
  3. package/dist/cjs/plugins/table/pm-plugins/drag-and-drop/commands.js +1 -1
  4. package/dist/cjs/plugins/table/pm-plugins/drag-and-drop/plugin.js +3 -2
  5. package/dist/cjs/plugins/table/pm-plugins/drag-and-drop/utils/monitor.js +6 -1
  6. package/dist/cjs/plugins/table/ui/DragHandle/index.js +6 -4
  7. package/dist/cjs/plugins/table/ui/TableFloatingColumnControls/ColumnControls/index.js +9 -19
  8. package/dist/cjs/plugins/table/ui/TableFloatingColumnControls/ColumnDropTargets/ColumnDropTarget.js +70 -0
  9. package/dist/cjs/plugins/table/ui/TableFloatingColumnControls/ColumnDropTargets/index.js +12 -77
  10. package/dist/cjs/plugins/table/ui/TableFloatingColumnControls/index.js +45 -20
  11. package/dist/cjs/plugins/table/ui/icons/index.js +19 -0
  12. package/dist/cjs/plugins/table/ui/ui-styles.js +1 -1
  13. package/dist/es2019/plugins/table/nodeviews/TableComponent.js +2 -1
  14. package/dist/es2019/plugins/table/pm-plugins/drag-and-drop/commands.js +1 -1
  15. package/dist/es2019/plugins/table/pm-plugins/drag-and-drop/plugin.js +3 -2
  16. package/dist/es2019/plugins/table/pm-plugins/drag-and-drop/utils/monitor.js +6 -1
  17. package/dist/es2019/plugins/table/ui/DragHandle/index.js +5 -3
  18. package/dist/es2019/plugins/table/ui/TableFloatingColumnControls/ColumnControls/index.js +7 -15
  19. package/dist/es2019/plugins/table/ui/TableFloatingColumnControls/ColumnDropTargets/ColumnDropTarget.js +62 -0
  20. package/dist/es2019/plugins/table/ui/TableFloatingColumnControls/ColumnDropTargets/index.js +8 -74
  21. package/dist/es2019/plugins/table/ui/TableFloatingColumnControls/index.js +45 -19
  22. package/dist/es2019/plugins/table/ui/icons/index.js +2 -0
  23. package/dist/es2019/plugins/table/ui/ui-styles.js +0 -1
  24. package/dist/esm/plugins/table/nodeviews/TableComponent.js +2 -1
  25. package/dist/esm/plugins/table/pm-plugins/drag-and-drop/commands.js +1 -1
  26. package/dist/esm/plugins/table/pm-plugins/drag-and-drop/plugin.js +3 -2
  27. package/dist/esm/plugins/table/pm-plugins/drag-and-drop/utils/monitor.js +6 -1
  28. package/dist/esm/plugins/table/ui/DragHandle/index.js +5 -3
  29. package/dist/esm/plugins/table/ui/TableFloatingColumnControls/ColumnControls/index.js +8 -16
  30. package/dist/esm/plugins/table/ui/TableFloatingColumnControls/ColumnDropTargets/ColumnDropTarget.js +61 -0
  31. package/dist/esm/plugins/table/ui/TableFloatingColumnControls/ColumnDropTargets/index.js +9 -72
  32. package/dist/esm/plugins/table/ui/TableFloatingColumnControls/index.js +45 -20
  33. package/dist/esm/plugins/table/ui/icons/index.js +2 -0
  34. package/dist/esm/plugins/table/ui/ui-styles.js +1 -1
  35. package/dist/types/plugins/table/types.d.ts +1 -0
  36. package/dist/types/plugins/table/ui/TableFloatingColumnControls/ColumnControls/index.d.ts +2 -1
  37. package/dist/types/plugins/table/ui/TableFloatingColumnControls/ColumnDropTargets/ColumnDropTarget.d.ts +9 -0
  38. package/dist/types/plugins/table/ui/TableFloatingColumnControls/ColumnDropTargets/index.d.ts +2 -3
  39. package/dist/types/plugins/table/ui/TableFloatingColumnControls/index.d.ts +2 -0
  40. package/dist/types/plugins/table/ui/icons/index.d.ts +2 -0
  41. package/dist/types-ts4.5/plugins/table/types.d.ts +1 -0
  42. package/dist/types-ts4.5/plugins/table/ui/TableFloatingColumnControls/ColumnControls/index.d.ts +2 -1
  43. package/dist/types-ts4.5/plugins/table/ui/TableFloatingColumnControls/ColumnDropTargets/ColumnDropTarget.d.ts +9 -0
  44. package/dist/types-ts4.5/plugins/table/ui/TableFloatingColumnControls/ColumnDropTargets/index.d.ts +2 -3
  45. package/dist/types-ts4.5/plugins/table/ui/TableFloatingColumnControls/index.d.ts +2 -0
  46. package/dist/types-ts4.5/plugins/table/ui/icons/index.d.ts +2 -0
  47. package/package.json +2 -1
  48. package/src/__tests__/unit/ui/TableFloatingColumnControls.tsx +58 -12
  49. package/src/plugins/table/nodeviews/TableComponent.tsx +2 -1
  50. package/src/plugins/table/pm-plugins/drag-and-drop/commands.ts +1 -4
  51. package/src/plugins/table/pm-plugins/drag-and-drop/plugin.ts +7 -2
  52. package/src/plugins/table/pm-plugins/drag-and-drop/utils/monitor.ts +5 -0
  53. package/src/plugins/table/types.ts +1 -0
  54. package/src/plugins/table/ui/DragHandle/index.tsx +3 -1
  55. package/src/plugins/table/ui/TableFloatingColumnControls/ColumnControls/index.tsx +9 -17
  56. package/src/plugins/table/ui/TableFloatingColumnControls/ColumnDropTargets/ColumnDropTarget.tsx +74 -0
  57. package/src/plugins/table/ui/TableFloatingColumnControls/ColumnDropTargets/index.tsx +12 -80
  58. package/src/plugins/table/ui/TableFloatingColumnControls/index.tsx +61 -31
  59. package/src/plugins/table/ui/icons/index.ts +2 -0
  60. package/src/plugins/table/ui/ui-styles.ts +0 -1
@@ -4,13 +4,15 @@ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o =
4
4
  function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
5
5
  import React, { useEffect, useMemo, useState } from 'react';
6
6
  import ReactDOM from 'react-dom';
7
- import { findTable } from '@atlaskit/editor-tables';
7
+ import { monitorForElements } from '@atlaskit/pragmatic-drag-and-drop/adapter/element';
8
8
  import { TableCssClassName as ClassName } from '../../types';
9
+ import { getColumnsWidths, getRowHeights } from '../../utils';
9
10
  import { ColumnControls } from './ColumnControls';
10
11
  import { ColumnDropTargets } from './ColumnDropTargets';
11
12
  export var TableFloatingColumnControls = function TableFloatingColumnControls(_ref) {
12
13
  var editorView = _ref.editorView,
13
14
  tableRef = _ref.tableRef,
15
+ getNode = _ref.getNode,
14
16
  tableActive = _ref.tableActive,
15
17
  hasHeaderRow = _ref.hasHeaderRow,
16
18
  hoveredCell = _ref.hoveredCell,
@@ -24,6 +26,12 @@ export var TableFloatingColumnControls = function TableFloatingColumnControls(_r
24
26
  _useState2 = _slicedToArray(_useState, 2),
25
27
  tableRect = _useState2[0],
26
28
  setTableRect = _useState2[1];
29
+ var _useState3 = useState(false),
30
+ _useState4 = _slicedToArray(_useState3, 2),
31
+ hasDropTargets = _useState4[0],
32
+ setHasDropTargets = _useState4[1];
33
+ var node = getNode();
34
+ var currentNodeLocalId = node === null || node === void 0 ? void 0 : node.attrs.localId;
27
35
  useEffect(function () {
28
36
  var _window;
29
37
  if (tableRef && (_window = window) !== null && _window !== void 0 && _window.ResizeObserver) {
@@ -55,26 +63,41 @@ export var TableFloatingColumnControls = function TableFloatingColumnControls(_r
55
63
  };
56
64
  }
57
65
  }, [tableRef]);
58
- var selectedLocalId = useMemo(function () {
59
- if (!selection) {
60
- return undefined;
61
- }
62
- var tableNode = findTable(selection);
63
- if (!tableNode) {
64
- return undefined;
66
+ useEffect(function () {
67
+ return monitorForElements({
68
+ canMonitor: function canMonitor(_ref2) {
69
+ var source = _ref2.source;
70
+ var _ref3 = source.data,
71
+ type = _ref3.type,
72
+ localId = _ref3.localId,
73
+ indexes = _ref3.indexes;
74
+ return type === 'table-column' && !!(indexes !== null && indexes !== void 0 && indexes.length) && localId === currentNodeLocalId;
75
+ },
76
+ onDragStart: function onDragStart() {
77
+ setHasDropTargets(true);
78
+ },
79
+ onDrop: function onDrop() {
80
+ setHasDropTargets(false);
81
+ }
82
+ });
83
+ }, [editorView, currentNodeLocalId]);
84
+ var rowHeights = useMemo(function () {
85
+ // NOTE: we don't care so much as to what tableHeight is, we only care that it changed and is a sane value.
86
+ if (tableRef && !!tableRect.height) {
87
+ return getRowHeights(tableRef);
65
88
  }
66
- return tableNode.node.attrs.localId;
67
- }, [selection]);
89
+ return [0];
90
+ }, [tableRef, tableRect.height]);
68
91
  if (!tableRef) {
69
92
  return null;
70
93
  }
94
+ var colWidths = getColumnsWidths(editorView);
71
95
  var stickyTop = stickyHeader && stickyHeader.sticky && hasHeaderRow ? stickyHeader.top : undefined;
72
96
  var mountTo = tableRef && (tableRef === null || tableRef === void 0 ? void 0 : tableRef.parentElement) || document.body;
73
97
  return /*#__PURE__*/ReactDOM.createPortal( /*#__PURE__*/React.createElement("div", {
74
- className: ClassName.COLUMN_CONTROLS_WRAPPER
75
- }, /*#__PURE__*/React.createElement("div", {
76
- onMouseDown: function onMouseDown(e) {
77
- return e.preventDefault();
98
+ className: ClassName.COLUMN_CONTROLS_WRAPPER,
99
+ style: {
100
+ pointerEvents: 'none'
78
101
  },
79
102
  "data-testid": "table-floating-column-controls-wrapper"
80
103
  }, /*#__PURE__*/React.createElement(ColumnControls, {
@@ -84,14 +107,16 @@ export var TableFloatingColumnControls = function TableFloatingColumnControls(_r
84
107
  isResizing: isResizing,
85
108
  tableActive: tableActive,
86
109
  stickyTop: tableActive ? stickyTop : undefined,
87
- tableHeight: tableRect.height,
88
- localId: selectedLocalId
89
- }), /*#__PURE__*/React.createElement(ColumnDropTargets, {
90
- editorView: editorView,
110
+ localId: currentNodeLocalId,
111
+ rowHeights: rowHeights,
112
+ colWidths: colWidths
113
+ }), hasDropTargets && /*#__PURE__*/React.createElement(ColumnDropTargets, {
91
114
  tableRef: tableRef,
92
115
  stickyTop: tableActive ? stickyTop : undefined,
93
116
  tableHeight: tableRect.height,
94
- localId: selectedLocalId
95
- }))), mountTo);
117
+ localId: currentNodeLocalId,
118
+ rowHeights: rowHeights,
119
+ colWidths: colWidths
120
+ })), mountTo);
96
121
  };
97
122
  export default TableFloatingColumnControls;
@@ -0,0 +1,2 @@
1
+ export { DragHandleIcon } from './DragHandleIcon';
2
+ export { DragInMotionIcon } from './DragInMotionIcon';
@@ -64,7 +64,7 @@ var getFloatingDotOverrides = function getFloatingDotOverrides(props) {
64
64
  return getBooleanFF('platform.editor.custom-table-width') ? css(_templateObject18 || (_templateObject18 = _taggedTemplateLiteral(["\n tr\n th:last-child\n .", "::before,\n tr\n td:last-child\n .", "::before {\n content: '';\n background-color: ", ";\n position: absolute;\n height: ", "px;\n width: ", "px;\n border-radius: 50%;\n pointer-events: none;\n top: ", ";\n right: 0px;\n }\n "])), ClassName.COLUMN_CONTROLS_DECORATIONS, ClassName.COLUMN_CONTROLS_DECORATIONS, tableBorderColor(props), lineMarkerSize, lineMarkerSize, "var(--ds-space-025, 2px)") : '';
65
65
  };
66
66
  export var floatingColumnControls = function floatingColumnControls(props) {
67
- return css(_templateObject19 || (_templateObject19 = _taggedTemplateLiteral(["\n .", " {\n box-sizing: border-box;\n position: absolute;\n top: 0;\n z-index: -1;\n\n .", " {\n display: flex;\n flex-direction: row;\n }\n }\n\n .", " {\n box-sizing: border-box;\n\n .", " {\n display: grid;\n justify-items: center;\n }\n }\n "])), ClassName.COLUMN_DROP_TARGET_CONTROLS, ClassName.COLUMN_CONTROLS_INNER, ClassName.COLUMN_CONTROLS_WITH_DRAG, ClassName.COLUMN_CONTROLS_INNER);
67
+ return css(_templateObject19 || (_templateObject19 = _taggedTemplateLiteral(["\n .", " {\n box-sizing: border-box;\n position: absolute;\n top: 0;\n\n .", " {\n display: flex;\n flex-direction: row;\n }\n }\n\n .", " {\n box-sizing: border-box;\n\n .", " {\n display: grid;\n justify-items: center;\n }\n }\n "])), ClassName.COLUMN_DROP_TARGET_CONTROLS, ClassName.COLUMN_CONTROLS_INNER, ClassName.COLUMN_CONTROLS_WITH_DRAG, ClassName.COLUMN_CONTROLS_INNER);
68
68
  };
69
69
  export var rowControlsWrapperDotStyle = function rowControlsWrapperDotStyle(props) {
70
70
  if (getBooleanFF('platform.editor.table.drag-and-drop')) {
@@ -392,4 +392,5 @@ export interface DraggableData {
392
392
  targetIndex: number;
393
393
  targetAdjustedIndex: number;
394
394
  targetClosestEdge: Edge;
395
+ direction: 1 | -1;
395
396
  }
@@ -8,8 +8,9 @@ export interface Props {
8
8
  hoveredCell?: CellHoverCoordinates;
9
9
  isResizing?: boolean;
10
10
  stickyTop?: number;
11
- tableHeight?: number;
12
11
  localId?: string;
12
+ rowHeights?: number[];
13
+ colWidths?: (number | undefined)[];
13
14
  }
14
15
  export declare const ColumnControls: React.FC<Props>;
15
16
  export default ColumnControls;
@@ -0,0 +1,9 @@
1
+ import React from 'react';
2
+ export interface Props {
3
+ index: number;
4
+ localId?: string;
5
+ width?: number;
6
+ height?: number;
7
+ marginTop?: number;
8
+ }
9
+ export declare const ColumnDropTarget: React.FC<Props>;
@@ -1,11 +1,10 @@
1
1
  import React from 'react';
2
- import type { EditorView } from '@atlaskit/editor-prosemirror/view';
3
2
  export interface Props {
4
- editorView: EditorView;
5
3
  tableRef: HTMLTableElement;
6
4
  stickyTop?: number;
7
5
  tableHeight?: number;
8
6
  localId?: string;
7
+ rowHeights?: number[];
8
+ colWidths?: (number | undefined)[];
9
9
  }
10
10
  export declare const ColumnDropTargets: React.FC<Props>;
11
- export default ColumnDropTargets;
@@ -1,6 +1,7 @@
1
1
  import React from 'react';
2
2
  import type { TableColumnOrdering } from '@atlaskit/custom-steps';
3
3
  import type { GetEditorFeatureFlags } from '@atlaskit/editor-common/types';
4
+ import type { Node as PmNode } from '@atlaskit/editor-prosemirror/model';
4
5
  import type { Selection } from '@atlaskit/editor-prosemirror/state';
5
6
  import type { EditorView } from '@atlaskit/editor-prosemirror/view';
6
7
  import type { RowStickyState } from '../../pm-plugins/sticky-headers';
@@ -10,6 +11,7 @@ export interface Props {
10
11
  getEditorFeatureFlags: GetEditorFeatureFlags;
11
12
  selection?: Selection;
12
13
  tableRef?: HTMLTableElement;
14
+ getNode: () => PmNode;
13
15
  tableActive?: boolean;
14
16
  hasHeaderRow?: boolean;
15
17
  headerRowHeight?: number;
@@ -0,0 +1,2 @@
1
+ export { DragHandleIcon } from './DragHandleIcon';
2
+ export { DragInMotionIcon } from './DragInMotionIcon';
@@ -392,4 +392,5 @@ export interface DraggableData {
392
392
  targetIndex: number;
393
393
  targetAdjustedIndex: number;
394
394
  targetClosestEdge: Edge;
395
+ direction: 1 | -1;
395
396
  }
@@ -8,8 +8,9 @@ export interface Props {
8
8
  hoveredCell?: CellHoverCoordinates;
9
9
  isResizing?: boolean;
10
10
  stickyTop?: number;
11
- tableHeight?: number;
12
11
  localId?: string;
12
+ rowHeights?: number[];
13
+ colWidths?: (number | undefined)[];
13
14
  }
14
15
  export declare const ColumnControls: React.FC<Props>;
15
16
  export default ColumnControls;
@@ -0,0 +1,9 @@
1
+ import React from 'react';
2
+ export interface Props {
3
+ index: number;
4
+ localId?: string;
5
+ width?: number;
6
+ height?: number;
7
+ marginTop?: number;
8
+ }
9
+ export declare const ColumnDropTarget: React.FC<Props>;
@@ -1,11 +1,10 @@
1
1
  import React from 'react';
2
- import type { EditorView } from '@atlaskit/editor-prosemirror/view';
3
2
  export interface Props {
4
- editorView: EditorView;
5
3
  tableRef: HTMLTableElement;
6
4
  stickyTop?: number;
7
5
  tableHeight?: number;
8
6
  localId?: string;
7
+ rowHeights?: number[];
8
+ colWidths?: (number | undefined)[];
9
9
  }
10
10
  export declare const ColumnDropTargets: React.FC<Props>;
11
- export default ColumnDropTargets;
@@ -1,6 +1,7 @@
1
1
  import React from 'react';
2
2
  import type { TableColumnOrdering } from '@atlaskit/custom-steps';
3
3
  import type { GetEditorFeatureFlags } from '@atlaskit/editor-common/types';
4
+ import type { Node as PmNode } from '@atlaskit/editor-prosemirror/model';
4
5
  import type { Selection } from '@atlaskit/editor-prosemirror/state';
5
6
  import type { EditorView } from '@atlaskit/editor-prosemirror/view';
6
7
  import type { RowStickyState } from '../../pm-plugins/sticky-headers';
@@ -10,6 +11,7 @@ export interface Props {
10
11
  getEditorFeatureFlags: GetEditorFeatureFlags;
11
12
  selection?: Selection;
12
13
  tableRef?: HTMLTableElement;
14
+ getNode: () => PmNode;
13
15
  tableActive?: boolean;
14
16
  hasHeaderRow?: boolean;
15
17
  headerRowHeight?: number;
@@ -0,0 +1,2 @@
1
+ export { DragHandleIcon } from './DragHandleIcon';
2
+ export { DragInMotionIcon } from './DragInMotionIcon';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-table",
3
- "version": "5.3.8",
3
+ "version": "5.3.9",
4
4
  "description": "Table plugin for the @atlaskit/editor",
5
5
  "publishConfig": {
6
6
  "registry": "https://registry.npmjs.org/"
@@ -70,6 +70,7 @@
70
70
  "@atlaskit/webdriver-runner": "*",
71
71
  "@atlassian/atlassian-frontend-prettier-config-1.0.1": "npm:@atlassian/atlassian-frontend-prettier-config@1.0.1",
72
72
  "@atlassian/feature-flags-test-utils": "^0.1.2",
73
+ "@testing-library/dom": "^8.17.1",
73
74
  "@testing-library/react": "^12.1.5",
74
75
  "@testing-library/react-hooks": "^8.0.1",
75
76
  "raf-stub": "^2.0.1",
@@ -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,16 +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
- // FIXME and unskip: presumably doesn't work becuase TableFloatingColumnControls are now mounted via ReactDOM.createPortal
89
- it.skip('should render a drop target per column', () => {
90
- const { editorView } = editor(
91
- 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
+ ),
92
116
  {
93
117
  dragAndDropEnabled: true,
94
118
  },
@@ -98,25 +122,44 @@ describe('TableFloatingColumnControls', () => {
98
122
  render(
99
123
  <IntlProvider locale="en">
100
124
  <TableFloatingColumnControls
125
+ getNode={getNodeFunc(editorView, refs)}
101
126
  tableRef={ref}
102
127
  tableActive={true}
128
+ hoveredCell={{ colIndex: 1, rowIndex: 0}}
103
129
  editorView={editorView}
104
130
  getEditorFeatureFlags={fakeGetEditorFeatureFlags}
105
131
  />
106
132
  </IntlProvider>,
107
133
  );
108
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
+
109
147
  const dropTargets = screen.getAllByTestId(
110
148
  'table-floating-column-controls-drop-target',
111
149
  );
112
150
 
113
151
  expect(dropTargets).toHaveLength(5);
114
- });
152
+ }*/,
153
+ );
115
154
 
116
155
  // FIXME and unskp: presumably doesn't work becuase TableFloatingColumnControls are now mounted via ReactDOM.createPortal
117
156
  it.skip('should render a drop target per column regardless of row count', () => {
118
- const { editorView } = editor(
119
- doc(p('text'), table()(tr(tdEmpty), tr(tdEmpty), tr(tdEmpty))),
157
+ const { editorView, refs } = editor(
158
+ doc(
159
+ p('text'),
160
+ '{<node>}',
161
+ table()(tr(tdEmpty), tr(tdEmpty), tr(tdEmpty)),
162
+ ),
120
163
  {
121
164
  dragAndDropEnabled: true,
122
165
  },
@@ -126,6 +169,7 @@ describe('TableFloatingColumnControls', () => {
126
169
  render(
127
170
  <IntlProvider locale="en">
128
171
  <TableFloatingColumnControls
172
+ getNode={getNodeFunc(editorView, refs)}
129
173
  tableRef={ref}
130
174
  tableActive={true}
131
175
  editorView={editorView}
@@ -139,4 +183,6 @@ describe('TableFloatingColumnControls', () => {
139
183
  );
140
184
  expect(dropTargets).toHaveLength(1);
141
185
  });
186
+
187
+ it.todo('should remove column drop targets when dragging ends');
142
188
  });
@@ -439,13 +439,14 @@ class TableComponent extends React.Component<ComponentProps, TableState> {
439
439
  <TableFloatingColumnControls
440
440
  editorView={view}
441
441
  tableRef={tableRef}
442
+ getNode={getNode}
442
443
  tableActive={tableActive}
443
444
  hoveredRows={hoveredRows}
444
445
  hoveredCell={hoveredCell}
445
446
  isResizing={isResizing}
446
447
  ordering={ordering}
447
448
  hasHeaderRow={hasHeaderRow}
448
- // pass `selection` and `tableHeight` to control re-render
449
+ // pass `selection` to control re-render
449
450
  selection={view.state.selection}
450
451
  headerRowHeight={headerRow ? headerRow.offsetHeight : undefined}
451
452
  stickyHeader={this.state.stickyHeader}
@@ -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
  };
@@ -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 &&
@@ -1,10 +1,9 @@
1
- import React, { useMemo } from 'react';
1
+ import React from 'react';
2
2
 
3
3
  import type { EditorView } from '@atlaskit/editor-prosemirror/view';
4
4
 
5
5
  import type { CellHoverCoordinates } from '../../../types';
6
6
  import { TableCssClassName as ClassName } from '../../../types';
7
- import { getColumnsWidths, getRowHeights } from '../../../utils';
8
7
  import { DragHandle } from '../../DragHandle';
9
8
 
10
9
  export interface Props {
@@ -14,8 +13,9 @@ export interface Props {
14
13
  hoveredCell?: CellHoverCoordinates;
15
14
  isResizing?: boolean;
16
15
  stickyTop?: number;
17
- tableHeight?: number;
18
16
  localId?: string;
17
+ rowHeights?: number[];
18
+ colWidths?: (number | undefined)[];
19
19
  }
20
20
 
21
21
  export const ColumnControls: React.FC<Props> = ({
@@ -24,18 +24,11 @@ export const ColumnControls: React.FC<Props> = ({
24
24
  tableRef,
25
25
  hoveredCell,
26
26
  isResizing,
27
- tableHeight,
28
27
  stickyTop,
29
28
  localId,
29
+ rowHeights,
30
+ colWidths,
30
31
  }) => {
31
- const rowHeights = useMemo(() => {
32
- // NOTE: we don't care so much as to what tableHeight is, we only care that it changed and is a sane value.
33
- if (tableRef && !!tableHeight) {
34
- return getRowHeights(tableRef);
35
- }
36
- return [0];
37
- }, [tableRef, tableHeight]);
38
-
39
32
  if (!tableRef) {
40
33
  return null;
41
34
  }
@@ -48,10 +41,9 @@ export const ColumnControls: React.FC<Props> = ({
48
41
  const marginTop =
49
42
  hasHeaderRow && stickyTop !== undefined ? rowHeights?.[0] ?? 0 : 0;
50
43
 
51
- const colWidths = getColumnsWidths(editorView);
52
- const widths = colWidths
53
- .map((width) => (width ? `${width - 1}px` : '0px'))
54
- .join(' ');
44
+ const widths =
45
+ colWidths?.map((width) => (width ? `${width - 1}px` : '0px')).join(' ') ??
46
+ '0px';
55
47
 
56
48
  const colIndex = hoveredCell?.colIndex;
57
49
 
@@ -84,7 +76,7 @@ export const ColumnControls: React.FC<Props> = ({
84
76
  >
85
77
  <DragHandle
86
78
  direction="column"
87
- indexes={[]}
79
+ indexes={[colIndex!]}
88
80
  onClick={(event) => onClick(colIndex as number, event)}
89
81
  onMouseOver={onMouseOver}
90
82
  onMouseOut={onMouseOut}
@@ -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
+ };