@atlaskit/editor-plugin-table 5.3.0 → 5.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/dist/cjs/plugins/table/pm-plugins/drag-and-drop/commands.js +36 -7
  3. package/dist/cjs/plugins/table/pm-plugins/drag-and-drop/plugin.js +69 -7
  4. package/dist/cjs/plugins/table/pm-plugins/drag-and-drop/reducer.js +2 -0
  5. package/dist/cjs/plugins/table/pm-plugins/drag-and-drop/utils/index.js +12 -0
  6. package/dist/cjs/plugins/table/pm-plugins/drag-and-drop/utils/monitor.js +59 -0
  7. package/dist/cjs/plugins/table/types.js +8 -1
  8. package/dist/cjs/plugins/table/ui/common-styles.js +1 -1
  9. package/dist/cjs/plugins/table/ui/consts.js +2 -1
  10. package/dist/cjs/plugins/table/ui/ui-styles.js +5 -2
  11. package/dist/cjs/plugins/table/utils/decoration.js +67 -1
  12. package/dist/cjs/plugins/table/utils/index.js +26 -1
  13. package/dist/cjs/plugins/table/utils/merged-cells.js +66 -0
  14. package/dist/es2019/plugins/table/pm-plugins/drag-and-drop/commands.js +35 -7
  15. package/dist/es2019/plugins/table/pm-plugins/drag-and-drop/plugin.js +69 -4
  16. package/dist/es2019/plugins/table/pm-plugins/drag-and-drop/reducer.js +2 -0
  17. package/dist/es2019/plugins/table/pm-plugins/drag-and-drop/utils/index.js +1 -0
  18. package/dist/es2019/plugins/table/pm-plugins/drag-and-drop/utils/monitor.js +56 -0
  19. package/dist/es2019/plugins/table/types.js +8 -1
  20. package/dist/es2019/plugins/table/ui/common-styles.js +2 -1
  21. package/dist/es2019/plugins/table/ui/consts.js +1 -0
  22. package/dist/es2019/plugins/table/ui/ui-styles.js +114 -1
  23. package/dist/es2019/plugins/table/utils/decoration.js +62 -0
  24. package/dist/es2019/plugins/table/utils/index.js +3 -2
  25. package/dist/es2019/plugins/table/utils/merged-cells.js +48 -0
  26. package/dist/esm/plugins/table/pm-plugins/drag-and-drop/commands.js +36 -7
  27. package/dist/esm/plugins/table/pm-plugins/drag-and-drop/plugin.js +65 -4
  28. package/dist/esm/plugins/table/pm-plugins/drag-and-drop/reducer.js +2 -0
  29. package/dist/esm/plugins/table/pm-plugins/drag-and-drop/utils/index.js +1 -0
  30. package/dist/esm/plugins/table/pm-plugins/drag-and-drop/utils/monitor.js +53 -0
  31. package/dist/esm/plugins/table/types.js +8 -1
  32. package/dist/esm/plugins/table/ui/common-styles.js +2 -2
  33. package/dist/esm/plugins/table/ui/consts.js +1 -0
  34. package/dist/esm/plugins/table/ui/ui-styles.js +5 -2
  35. package/dist/esm/plugins/table/utils/decoration.js +66 -0
  36. package/dist/esm/plugins/table/utils/index.js +3 -2
  37. package/dist/esm/plugins/table/utils/merged-cells.js +60 -0
  38. package/dist/types/plugins/table/pm-plugins/drag-and-drop/actions.d.ts +5 -1
  39. package/dist/types/plugins/table/pm-plugins/drag-and-drop/commands.d.ts +6 -1
  40. package/dist/types/plugins/table/pm-plugins/drag-and-drop/utils/index.d.ts +1 -0
  41. package/dist/types/plugins/table/pm-plugins/drag-and-drop/utils/monitor.d.ts +3 -0
  42. package/dist/types/plugins/table/types.d.ts +19 -1
  43. package/dist/types/plugins/table/ui/consts.d.ts +1 -0
  44. package/dist/types/plugins/table/ui/ui-styles.d.ts +1 -0
  45. package/dist/types/plugins/table/utils/decoration.d.ts +2 -0
  46. package/dist/types/plugins/table/utils/index.d.ts +2 -1
  47. package/dist/types/plugins/table/utils/merged-cells.d.ts +3 -0
  48. package/dist/types-ts4.5/plugins/table/pm-plugins/drag-and-drop/actions.d.ts +5 -1
  49. package/dist/types-ts4.5/plugins/table/pm-plugins/drag-and-drop/commands.d.ts +6 -1
  50. package/dist/types-ts4.5/plugins/table/pm-plugins/drag-and-drop/utils/index.d.ts +1 -0
  51. package/dist/types-ts4.5/plugins/table/pm-plugins/drag-and-drop/utils/monitor.d.ts +3 -0
  52. package/dist/types-ts4.5/plugins/table/types.d.ts +19 -1
  53. package/dist/types-ts4.5/plugins/table/ui/consts.d.ts +1 -0
  54. package/dist/types-ts4.5/plugins/table/ui/ui-styles.d.ts +1 -0
  55. package/dist/types-ts4.5/plugins/table/utils/decoration.d.ts +2 -0
  56. package/dist/types-ts4.5/plugins/table/utils/index.d.ts +2 -1
  57. package/dist/types-ts4.5/plugins/table/utils/merged-cells.d.ts +3 -0
  58. package/package.json +4 -1
  59. package/src/plugins/table/pm-plugins/drag-and-drop/actions.ts +6 -1
  60. package/src/plugins/table/pm-plugins/drag-and-drop/commands.ts +58 -8
  61. package/src/plugins/table/pm-plugins/drag-and-drop/plugin.ts +77 -4
  62. package/src/plugins/table/pm-plugins/drag-and-drop/reducer.ts +2 -0
  63. package/src/plugins/table/pm-plugins/drag-and-drop/utils/index.ts +1 -0
  64. package/src/plugins/table/pm-plugins/drag-and-drop/utils/monitor.ts +72 -0
  65. package/src/plugins/table/types.ts +23 -1
  66. package/src/plugins/table/ui/common-styles.ts +2 -0
  67. package/src/plugins/table/ui/consts.ts +1 -0
  68. package/src/plugins/table/ui/ui-styles.ts +115 -0
  69. package/src/plugins/table/utils/decoration.ts +101 -0
  70. package/src/plugins/table/utils/index.ts +3 -0
  71. package/src/plugins/table/utils/merged-cells.ts +67 -0
@@ -1,5 +1,5 @@
1
1
  export { getSelectedColumnIndexes, getSelectedRowIndexes, normalizeSelection, isSelectionUpdated, } from './selection';
2
- export { findControlsHoverDecoration, createControlsHoverDecoration, createColumnControlsDecoration, createColumnSelectedDecoration, createCellHoverDecoration, updateDecorations, createResizeHandleDecoration, createColumnLineResize, } from './decoration';
2
+ export { findControlsHoverDecoration, createControlsHoverDecoration, createColumnControlsDecoration, createColumnSelectedDecoration, createCellHoverDecoration, updateDecorations, createResizeHandleDecoration, createColumnInsertLine, createColumnLineResize, createRowInsertLine, } from './decoration';
3
3
  export { isIsolating, containsHeaderColumn, containsHeaderRow, checkIfHeaderColumnEnabled, checkIfHeaderRowEnabled, checkIfNumberColumnEnabled, isLayoutSupported, getTableWidth, tablesHaveDifferentColumnWidths, tablesHaveDifferentNoOfColumns, isTableNested, anyChildCellMergedAcrossRow, supportedHeaderRow, } from './nodes';
4
4
  export { unwrapContentFromTable, removeTableFromFirstChild, removeTableFromLastChild, transformSliceToRemoveOpenTable, transformSliceToCorrectEmptyTableCells, transformSliceToFixHardBreakProblemOnCopyFromCell, } from './paste';
5
5
  export { isCell, isCornerButton, isInsertRowButton, isColumnControlsDecorations, isTableControlsButton, isTableContainerOrWrapper, isRowControlsButton, getColumnOrRowIndex, getMousePositionHorizontalRelativeByElement, getMousePositionVerticalRelativeByElement, updateResizeHandles, isResizeHandleDecoration, hasResizeHandler, } from './dom';
@@ -9,3 +9,4 @@ export type { RowParams } from './row-controls';
9
9
  export { getSelectedTableInfo, getSelectedCellInfo } from './analytics';
10
10
  export { getMergedCellsPositions } from './table';
11
11
  export { updatePluginStateDecorations } from './update-plugin-state-decorations';
12
+ export { hasMergedCellsInColumn, hasMergedCellsInRow } from './merged-cells';
@@ -0,0 +1,3 @@
1
+ import type { Selection } from '@atlaskit/editor-prosemirror/state';
2
+ export declare const hasMergedCellsInColumn: (columnIndexes: number | number[]) => (selection: Selection) => boolean;
3
+ export declare const hasMergedCellsInRow: (rowIndexes: number | number[]) => (selection: Selection) => boolean;
@@ -1,3 +1,4 @@
1
+ import type { DecorationSet } from '@atlaskit/editor-prosemirror/view';
1
2
  import type { DropTargetType } from './consts';
2
3
  export interface DragAndDropAction<T, D> {
3
4
  type: T;
@@ -10,6 +11,9 @@ export declare const DragAndDropActionType: {
10
11
  export type DragAndDropSetDropTargetAction = DragAndDropAction<typeof DragAndDropActionType.SET_DROP_TARGET, {
11
12
  type: DropTargetType;
12
13
  index: number;
14
+ decorationSet: DecorationSet;
15
+ }>;
16
+ export type DragAndDropClearDropTargetAction = DragAndDropAction<typeof DragAndDropActionType.CLEAR_DROP_TARGET, {
17
+ decorationSet: DecorationSet;
13
18
  }>;
14
- export type DragAndDropClearDropTargetAction = DragAndDropAction<typeof DragAndDropActionType.CLEAR_DROP_TARGET, undefined>;
15
19
  export type DragAndDropPluginAction = DragAndDropSetDropTargetAction | DragAndDropClearDropTargetAction;
@@ -1,4 +1,9 @@
1
- import type { Transaction } from '@atlaskit/editor-prosemirror/state';
1
+ import type { EditorState, Transaction } from '@atlaskit/editor-prosemirror/state';
2
+ import type { Decoration } from '@atlaskit/editor-prosemirror/view';
3
+ import { DecorationSet } from '@atlaskit/editor-prosemirror/view';
4
+ import { TableDecorations } from '../../types';
2
5
  import type { DropTargetType } from './consts';
6
+ export declare const getDecorations: (state: EditorState) => DecorationSet;
7
+ export declare const updatePluginStateDecorations: (state: EditorState, decorations: Decoration[], key: TableDecorations) => DecorationSet;
3
8
  export declare const setDropTarget: (type: DropTargetType, index: number, tr?: Transaction) => import("@atlaskit/editor-common/types").Command;
4
9
  export declare const clearDropTarget: (tr?: Transaction) => import("@atlaskit/editor-common/types").Command;
@@ -0,0 +1 @@
1
+ export { getDraggableDataFromEvent } from './monitor';
@@ -0,0 +1,3 @@
1
+ import type { ElementEventBasePayload } from '@atlaskit/pragmatic-drag-and-drop/adapter/element';
2
+ import type { DraggableData } from '../../../types';
3
+ export declare const getDraggableDataFromEvent: ({ location, source, }: ElementEventBasePayload) => DraggableData | undefined;
@@ -7,6 +7,7 @@ import type { Node as PmNode } from '@atlaskit/editor-prosemirror/model';
7
7
  import type { Transaction } from '@atlaskit/editor-prosemirror/state';
8
8
  import type { DecorationSet } from '@atlaskit/editor-prosemirror/view';
9
9
  import type { Rect } from '@atlaskit/editor-tables/table-map';
10
+ import type { Edge } from '@atlaskit/pragmatic-drag-and-drop-hitbox/addon/closest-edge';
10
11
  import type tablePlugin from './index';
11
12
  export declare const RESIZE_HANDLE_AREA_DECORATION_GAP = 30;
12
13
  export type RowInsertPosition = 'TOP' | 'BOTTOM';
@@ -230,6 +231,8 @@ export declare enum TableDecorations {
230
231
  COLUMN_RESIZING_HANDLE = "COLUMN_RESIZING_HANDLE",
231
232
  COLUMN_RESIZING_HANDLE_WIDGET = "COLUMN_RESIZING_HANDLE_WIDGET",
232
233
  COLUMN_RESIZING_HANDLE_LINE = "COLUMN_RESIZING_HANDLE_LINE",
234
+ COLUMN_INSERT_LINE = "COLUMN_INSERT_LINE",
235
+ ROW_INSERT_LINE = "ROW_INSERT_LINE",
233
236
  LAST_CELL_ELEMENT = "LAST_CELL_ELEMENT"
234
237
  }
235
238
  export declare const TableCssClassName: {
@@ -292,8 +295,13 @@ export declare const TableCssClassName: {
292
295
  TABLE_STICKY: string;
293
296
  TOP_LEFT_CELL: string;
294
297
  LAST_ITEM_IN_CELL: string;
298
+ WITH_COLUMN_INSERT_LINE: string;
299
+ WITH_FIRST_COLUMN_INSERT_LINE: string;
300
+ WITH_LAST_COLUMN_INSERT_LINE: string;
295
301
  WITH_RESIZE_LINE: string;
296
302
  WITH_RESIZE_LINE_LAST_COLUMN: string;
303
+ WITH_ROW_INSERT_LINE: string;
304
+ WITH_LAST_ROW_INSERT_LINE: string;
297
305
  TABLE_CONTAINER: string;
298
306
  TABLE_NODE_WRAPPER: string;
299
307
  TABLE_LEFT_SHADOW: string;
@@ -354,8 +362,18 @@ export interface DraggableSourceData extends Record<string, unknown> {
354
362
  localId: string;
355
363
  indexes: number[];
356
364
  }
357
- export interface DraggableTargetData extends Record<string, unknown> {
365
+ export interface DraggableTargetData extends Record<string | symbol, unknown> {
358
366
  type: DraggableType;
359
367
  localId: string;
360
368
  targetIndex: number;
361
369
  }
370
+ export interface DraggableData {
371
+ sourceType: DraggableType;
372
+ sourceLocalId: string;
373
+ sourceIndexes: number[];
374
+ targetType: DraggableType;
375
+ targetLocalId: string;
376
+ targetIndex: number;
377
+ targetAdjustedIndex: number;
378
+ targetClosestEdge: Edge;
379
+ }
@@ -34,6 +34,7 @@ export declare const columnControlsDecorationHeight = 25;
34
34
  export declare const columnControlsZIndex: number;
35
35
  export declare const columnControlsSelectedZIndex: number;
36
36
  export declare const columnResizeHandleZIndex: number;
37
+ export declare const insertLineWidth = 3;
37
38
  export declare const resizeHandlerAreaWidth: number;
38
39
  export declare const resizeLineWidth = 2;
39
40
  export declare const resizeHandlerZIndex: number;
@@ -14,3 +14,4 @@ export declare const hoveredDeleteButton: (props: ThemeProps) => import("@emotio
14
14
  export declare const hoveredCell: (props: ThemeProps) => import("@emotion/react").SerializedStyles;
15
15
  export declare const hoveredWarningCell: import("@emotion/react").SerializedStyles;
16
16
  export declare const resizeHandle: (props: ThemeProps) => import("@emotion/react").SerializedStyles;
17
+ export declare const insertLine: (props: ThemeProps) => import("@emotion/react").SerializedStyles;
@@ -17,3 +17,5 @@ export declare const createResizeHandleDecoration: (tr: Transaction | ReadonlyTr
17
17
  Decoration[]
18
18
  ];
19
19
  export declare const createColumnLineResize: (selection: Selection, cellColumnPositioning: Omit<CellColumnPositioning, 'left'>) => Decoration[];
20
+ export declare const createColumnInsertLine: (columnIndex: number, selection: Selection) => Decoration[];
21
+ export declare const createRowInsertLine: (rowIndex: number, selection: Selection) => Decoration[];
@@ -1,5 +1,5 @@
1
1
  export { getSelectedColumnIndexes, getSelectedRowIndexes, normalizeSelection, isSelectionUpdated, } from './selection';
2
- export { findControlsHoverDecoration, createControlsHoverDecoration, createColumnControlsDecoration, createColumnSelectedDecoration, createCellHoverDecoration, updateDecorations, createResizeHandleDecoration, createColumnLineResize, } from './decoration';
2
+ export { findControlsHoverDecoration, createControlsHoverDecoration, createColumnControlsDecoration, createColumnSelectedDecoration, createCellHoverDecoration, updateDecorations, createResizeHandleDecoration, createColumnInsertLine, createColumnLineResize, createRowInsertLine, } from './decoration';
3
3
  export { isIsolating, containsHeaderColumn, containsHeaderRow, checkIfHeaderColumnEnabled, checkIfHeaderRowEnabled, checkIfNumberColumnEnabled, isLayoutSupported, getTableWidth, tablesHaveDifferentColumnWidths, tablesHaveDifferentNoOfColumns, isTableNested, anyChildCellMergedAcrossRow, supportedHeaderRow, } from './nodes';
4
4
  export { unwrapContentFromTable, removeTableFromFirstChild, removeTableFromLastChild, transformSliceToRemoveOpenTable, transformSliceToCorrectEmptyTableCells, transformSliceToFixHardBreakProblemOnCopyFromCell, } from './paste';
5
5
  export { isCell, isCornerButton, isInsertRowButton, isColumnControlsDecorations, isTableControlsButton, isTableContainerOrWrapper, isRowControlsButton, getColumnOrRowIndex, getMousePositionHorizontalRelativeByElement, getMousePositionVerticalRelativeByElement, updateResizeHandles, isResizeHandleDecoration, hasResizeHandler, } from './dom';
@@ -9,3 +9,4 @@ export type { RowParams } from './row-controls';
9
9
  export { getSelectedTableInfo, getSelectedCellInfo } from './analytics';
10
10
  export { getMergedCellsPositions } from './table';
11
11
  export { updatePluginStateDecorations } from './update-plugin-state-decorations';
12
+ export { hasMergedCellsInColumn, hasMergedCellsInRow } from './merged-cells';
@@ -0,0 +1,3 @@
1
+ import type { Selection } from '@atlaskit/editor-prosemirror/state';
2
+ export declare const hasMergedCellsInColumn: (columnIndexes: number | number[]) => (selection: Selection) => boolean;
3
+ export declare const hasMergedCellsInRow: (rowIndexes: number | number[]) => (selection: Selection) => boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-table",
3
- "version": "5.3.0",
3
+ "version": "5.3.1",
4
4
  "description": "Table plugin for the @atlaskit/editor",
5
5
  "publishConfig": {
6
6
  "registry": "https://registry.npmjs.org/"
@@ -106,6 +106,9 @@
106
106
  "platform.editor.custom-table-width": {
107
107
  "type": "boolean"
108
108
  },
109
+ "platform.editor.table.drag-and-drop": {
110
+ "type": "boolean"
111
+ },
109
112
  "platform.editor.table-sticky-scrollbar": {
110
113
  "type": "boolean"
111
114
  },
@@ -1,3 +1,5 @@
1
+ import type { DecorationSet } from '@atlaskit/editor-prosemirror/view';
2
+
1
3
  import type { DropTargetType } from './consts';
2
4
 
3
5
  export interface DragAndDropAction<T, D> {
@@ -15,12 +17,15 @@ export type DragAndDropSetDropTargetAction = DragAndDropAction<
15
17
  {
16
18
  type: DropTargetType;
17
19
  index: number;
20
+ decorationSet: DecorationSet;
18
21
  }
19
22
  >;
20
23
 
21
24
  export type DragAndDropClearDropTargetAction = DragAndDropAction<
22
25
  typeof DragAndDropActionType.CLEAR_DROP_TARGET,
23
- undefined
26
+ {
27
+ decorationSet: DecorationSet;
28
+ }
24
29
  >;
25
30
 
26
31
  // NOTE: This should be a Union of all possible actions
@@ -1,22 +1,69 @@
1
- import type { Transaction } from '@atlaskit/editor-prosemirror/state';
1
+ import type {
2
+ EditorState,
3
+ Transaction,
4
+ } from '@atlaskit/editor-prosemirror/state';
5
+ import type { Decoration } from '@atlaskit/editor-prosemirror/view';
6
+ import { DecorationSet } from '@atlaskit/editor-prosemirror/view';
7
+
8
+ import { TableDecorations } from '../../types';
9
+ import {
10
+ createColumnInsertLine,
11
+ createRowInsertLine,
12
+ updateDecorations,
13
+ } from '../../utils';
2
14
 
3
15
  import { DragAndDropActionType } from './actions';
4
16
  import type { DropTargetType } from './consts';
5
- import { createCommand } from './plugin-factory';
17
+ import { createCommand, getPluginState } from './plugin-factory';
18
+ import { pluginKey } from './plugin-key';
6
19
 
7
20
  // TODO: This command is a placeholder example. Please replace this if required.
21
+ export const getDecorations = (state: EditorState): DecorationSet => {
22
+ return pluginKey.getState(state)?.decorationSet || DecorationSet.empty;
23
+ };
24
+
25
+ export const updatePluginStateDecorations = (
26
+ state: EditorState,
27
+ decorations: Decoration[],
28
+ key: TableDecorations,
29
+ ): DecorationSet =>
30
+ updateDecorations(state.doc, getDecorations(state), decorations, key);
31
+
8
32
  export const setDropTarget = (
9
33
  type: DropTargetType,
10
34
  index: number,
11
35
  tr?: Transaction,
12
36
  ) =>
13
37
  createCommand(
14
- {
15
- type: DragAndDropActionType.SET_DROP_TARGET,
16
- data: {
17
- type,
18
- index,
19
- },
38
+ (state) => {
39
+ const { dropTargetType, dropTargetIndex } = getPluginState(state);
40
+ if (dropTargetType === type && dropTargetIndex === index) {
41
+ return false;
42
+ }
43
+
44
+ let decorationSet = DecorationSet.empty;
45
+ if (type === 'column') {
46
+ decorationSet = updatePluginStateDecorations(
47
+ state,
48
+ createColumnInsertLine(index, state.selection),
49
+ TableDecorations.COLUMN_INSERT_LINE,
50
+ );
51
+ } else if (type === 'row') {
52
+ decorationSet = updatePluginStateDecorations(
53
+ state,
54
+ createRowInsertLine(index, state.selection),
55
+ TableDecorations.ROW_INSERT_LINE,
56
+ );
57
+ }
58
+
59
+ return {
60
+ type: DragAndDropActionType.SET_DROP_TARGET,
61
+ data: {
62
+ decorationSet,
63
+ type,
64
+ index,
65
+ },
66
+ };
20
67
  },
21
68
  (originalTr: Transaction) =>
22
69
  (tr || originalTr).setMeta('addToHistory', false),
@@ -26,6 +73,9 @@ export const clearDropTarget = (tr?: Transaction) =>
26
73
  createCommand(
27
74
  {
28
75
  type: DragAndDropActionType.CLEAR_DROP_TARGET,
76
+ data: {
77
+ decorationSet: DecorationSet.empty,
78
+ },
29
79
  },
30
80
  (originalTr: Transaction) =>
31
81
  (tr || originalTr).setMeta('addToHistory', false),
@@ -5,10 +5,20 @@ import type {
5
5
  import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
6
6
  import type { EditorView } from '@atlaskit/editor-prosemirror/view';
7
7
  import { DecorationSet } from '@atlaskit/editor-prosemirror/view';
8
+ import { moveColumn, moveRow } from '@atlaskit/editor-tables/utils';
9
+ import { monitorForElements } from '@atlaskit/pragmatic-drag-and-drop/adapter/element';
10
+
11
+ import type { DraggableSourceData } from '../../types';
12
+ import {
13
+ hasMergedCellsInColumn,
14
+ hasMergedCellsInRow,
15
+ } from '../../utils/merged-cells';
16
+ import { getPluginState as getTablePluginState } from '../plugin-factory';
8
17
 
9
18
  import { DropTargetType } from './consts';
10
19
  import { createPluginState, getPluginState } from './plugin-factory';
11
20
  import { pluginKey } from './plugin-key';
21
+ import { getDraggableDataFromEvent } from './utils/monitor';
12
22
 
13
23
  export const createPlugin = (
14
24
  dispatch: Dispatch,
@@ -24,11 +34,74 @@ export const createPlugin = (
24
34
  })),
25
35
  key: pluginKey,
26
36
  view: (editorView: EditorView) => {
27
- // TODO: Add Pragmatic DnD monitor when the view is constructed.
28
-
29
37
  return {
30
- // TODO: Cleanup monitor instance
31
- // destroy: cleanup,
38
+ destroy: monitorForElements({
39
+ canMonitor({ source }) {
40
+ const { type, localId, indexes } =
41
+ source.data as Partial<DraggableSourceData>;
42
+
43
+ // First; Perform any quick checks so we can abort early.
44
+ if (
45
+ !indexes ||
46
+ !localId ||
47
+ // FIXME: We currently don't support DragNDrop of multiple elements. For now we will not bother to monitor drags
48
+ // of more then 1 item.
49
+ indexes.length !== 1 ||
50
+ !(type === 'table-row' || type === 'table-column')
51
+ ) {
52
+ return false;
53
+ }
54
+
55
+ const { tableNode } = getTablePluginState(editorView.state);
56
+ // If the draggable localId is the same as the current selected table localId then we will allow the monitor
57
+ // watch for changes
58
+ return localId === tableNode?.attrs.localId;
59
+ },
60
+ onDrag(event) {
61
+ const data = getDraggableDataFromEvent(event);
62
+
63
+ // If no data can be found then it's most like we do not want to perform any drag actions
64
+ if (!data) {
65
+ return;
66
+ }
67
+
68
+ // TODO: as we drag an element around we are going to want to update the state to acurately reflect the current
69
+ // insert location as to where the draggable will most likely be go. For example;
70
+ // const { sourceType, targetAdjustedIndex } = data;
71
+ // const highlight = sourceType === 'table-row' ? highlightRow : highlightColumn;
72
+ // return editorView.dispatch(
73
+ // highlight(targetAdjustedIndex)(editorView.state.tr),
74
+ // );
75
+ },
76
+ onDrop(event) {
77
+ const data = getDraggableDataFromEvent(event);
78
+
79
+ // If no data can be found then it's most like we do not want to perform any drop action
80
+ if (!data) {
81
+ return;
82
+ }
83
+
84
+ const { sourceType, sourceIndexes, targetAdjustedIndex } = data;
85
+
86
+ // If the drop target index contains merged cells then we should not allow the drop to occur.
87
+ const hasMergedCells =
88
+ sourceType === 'table-row'
89
+ ? hasMergedCellsInRow
90
+ : hasMergedCellsInColumn;
91
+ if (
92
+ hasMergedCells(targetAdjustedIndex)(editorView.state.selection)
93
+ ) {
94
+ return;
95
+ }
96
+
97
+ const move = sourceType === 'table-row' ? moveRow : moveColumn;
98
+
99
+ const [sourceIndex] = sourceIndexes;
100
+ return editorView.dispatch(
101
+ move(sourceIndex, targetAdjustedIndex)(editorView.state.tr),
102
+ );
103
+ },
104
+ }),
32
105
  };
33
106
  },
34
107
  props: {
@@ -11,12 +11,14 @@ export default (
11
11
  case DragAndDropActionType.SET_DROP_TARGET:
12
12
  return {
13
13
  ...pluginState,
14
+ decorationSet: action.data.decorationSet,
14
15
  dropTargetType: action.data.type,
15
16
  dropTargetIndex: action.data.index,
16
17
  };
17
18
  case DragAndDropActionType.CLEAR_DROP_TARGET:
18
19
  return {
19
20
  ...pluginState,
21
+ decorationSet: action.data.decorationSet,
20
22
  dropTargetType: DropTargetType.NONE,
21
23
  dropTargetIndex: 0,
22
24
  };
@@ -0,0 +1 @@
1
+ export { getDraggableDataFromEvent } from './monitor';
@@ -0,0 +1,72 @@
1
+ import { extractClosestEdge } from '@atlaskit/pragmatic-drag-and-drop-hitbox/addon/closest-edge';
2
+ import type { Edge } from '@atlaskit/pragmatic-drag-and-drop-hitbox/addon/closest-edge';
3
+ import type { ElementEventBasePayload } from '@atlaskit/pragmatic-drag-and-drop/adapter/element';
4
+
5
+ import type {
6
+ DraggableData,
7
+ DraggableSourceData,
8
+ DraggableTargetData,
9
+ } from '../../../types';
10
+
11
+ export const getDraggableDataFromEvent = ({
12
+ location,
13
+ source,
14
+ }: ElementEventBasePayload): DraggableData | undefined => {
15
+ const destination = location.current.dropTargets.at(0);
16
+ // If no target exists at the current location, then the current draggable is not over a target or the target doesn't support
17
+ // the current draggable.
18
+ if (!destination) {
19
+ return undefined;
20
+ }
21
+
22
+ // This is the draggable elements data
23
+ const {
24
+ indexes: sourceIndexes,
25
+ type: sourceType,
26
+ localId: sourceLocalId,
27
+ } = source.data as DraggableSourceData;
28
+
29
+ // This is the drop target's data
30
+ const {
31
+ targetIndex,
32
+ type: targetType,
33
+ localId: targetLocalId,
34
+ } = destination.data as DraggableTargetData;
35
+
36
+ // Some basic check to abort early with...
37
+ if (
38
+ !sourceIndexes ||
39
+ targetIndex < 0 ||
40
+ // abort if the type of the draggable is different to the target, for eg. rows cannot be dropped onto column targets.
41
+ sourceType !== targetType ||
42
+ // abort if the draggable is coming from a different table that the target is on.
43
+ sourceLocalId !== targetLocalId
44
+ ) {
45
+ return undefined;
46
+ }
47
+
48
+ // FIXME: currently we only support a single row/col index being moved, remove this clause when this is no longer the case.
49
+ if (sourceIndexes.length > 1) {
50
+ return undefined;
51
+ }
52
+
53
+ const targetClosestEdge =
54
+ extractClosestEdge(destination.data) ??
55
+ ((targetType === 'table-row' ? 'top' : 'left') as Edge);
56
+ // NOTE: By default we always insert row/cols at the target index to the top/left (retrospectively of row/cols).
57
+ // This introduces an offset in the event the drop occured closer to the bottom/right of the target. We want
58
+ // the new target index to be 1 index higher.
59
+ const targetOffset =
60
+ targetClosestEdge === 'right' || targetClosestEdge === 'bottom' ? 1 : 0;
61
+
62
+ return {
63
+ sourceType,
64
+ sourceLocalId,
65
+ sourceIndexes,
66
+ targetType,
67
+ targetLocalId,
68
+ targetIndex,
69
+ targetAdjustedIndex: targetIndex + targetOffset,
70
+ targetClosestEdge,
71
+ };
72
+ };
@@ -14,6 +14,7 @@ import type { Node as PmNode } from '@atlaskit/editor-prosemirror/model';
14
14
  import type { Transaction } from '@atlaskit/editor-prosemirror/state';
15
15
  import type { DecorationSet } from '@atlaskit/editor-prosemirror/view';
16
16
  import type { Rect } from '@atlaskit/editor-tables/table-map';
17
+ import type { Edge } from '@atlaskit/pragmatic-drag-and-drop-hitbox/addon/closest-edge';
17
18
 
18
19
  import type tablePlugin from './index';
19
20
 
@@ -245,6 +246,9 @@ export enum TableDecorations {
245
246
  COLUMN_RESIZING_HANDLE_WIDGET = 'COLUMN_RESIZING_HANDLE_WIDGET',
246
247
  COLUMN_RESIZING_HANDLE_LINE = 'COLUMN_RESIZING_HANDLE_LINE',
247
248
 
249
+ COLUMN_INSERT_LINE = 'COLUMN_INSERT_LINE',
250
+ ROW_INSERT_LINE = 'ROW_INSERT_LINE',
251
+
248
252
  LAST_CELL_ELEMENT = 'LAST_CELL_ELEMENT',
249
253
  }
250
254
 
@@ -329,8 +333,15 @@ export const TableCssClassName = {
329
333
  TOP_LEFT_CELL: 'table > tbody > tr:nth-child(2) > td:nth-child(1)',
330
334
  LAST_ITEM_IN_CELL: `${tablePrefixSelector}-last-item-in-cell`,
331
335
 
336
+ WITH_COLUMN_INSERT_LINE: `${tablePrefixSelector}-column-insert-line`,
337
+ WITH_FIRST_COLUMN_INSERT_LINE: `${tablePrefixSelector}-first-column-insert-line`,
338
+ WITH_LAST_COLUMN_INSERT_LINE: `${tablePrefixSelector}-last-column-insert-line`,
339
+
332
340
  WITH_RESIZE_LINE: `${tablePrefixSelector}-column-resize-line`,
333
341
  WITH_RESIZE_LINE_LAST_COLUMN: `${tablePrefixSelector}-column-resize-line-last-column`,
342
+
343
+ WITH_ROW_INSERT_LINE: `${tablePrefixSelector}-row-insert-line`,
344
+ WITH_LAST_ROW_INSERT_LINE: `${tablePrefixSelector}-last-row-insert-line`,
334
345
  };
335
346
 
336
347
  export interface ToolbarMenuConfig {
@@ -383,8 +394,19 @@ export interface DraggableSourceData extends Record<string, unknown> {
383
394
  indexes: number[];
384
395
  }
385
396
 
386
- export interface DraggableTargetData extends Record<string, unknown> {
397
+ export interface DraggableTargetData extends Record<string | symbol, unknown> {
387
398
  type: DraggableType;
388
399
  localId: string;
389
400
  targetIndex: number;
390
401
  }
402
+
403
+ export interface DraggableData {
404
+ sourceType: DraggableType;
405
+ sourceLocalId: string;
406
+ sourceIndexes: number[];
407
+ targetType: DraggableType;
408
+ targetLocalId: string;
409
+ targetIndex: number;
410
+ targetAdjustedIndex: number;
411
+ targetClosestEdge: Edge;
412
+ }
@@ -63,6 +63,7 @@ import {
63
63
  hoveredDeleteButton,
64
64
  hoveredWarningCell,
65
65
  insertColumnButtonWrapper,
66
+ insertLine,
66
67
  InsertMarker,
67
68
  insertRowButtonWrapper,
68
69
  OverflowShadow,
@@ -291,6 +292,7 @@ export const tableStyles = (
291
292
  ${hoveredDeleteButton(props)};
292
293
  ${hoveredCell(props)};
293
294
  ${hoveredWarningCell};
295
+ ${getBooleanFF('platform.editor.table.drag-and-drop') && insertLine(props)};
294
296
  ${resizeHandle(props)};
295
297
  ${rangeSelectionStyles};
296
298
 
@@ -131,6 +131,7 @@ export const columnControlsDecorationHeight = 25;
131
131
  export const columnControlsZIndex = akEditorUnitZIndex * 10;
132
132
  export const columnControlsSelectedZIndex = columnControlsZIndex + 1;
133
133
  export const columnResizeHandleZIndex = columnControlsSelectedZIndex + 1;
134
+ export const insertLineWidth = 3;
134
135
  export const resizeHandlerAreaWidth = RESIZE_HANDLE_AREA_DECORATION_GAP / 3;
135
136
  export const resizeLineWidth = 2;
136
137
  export const resizeHandlerZIndex =