@atlaskit/editor-plugin-table 5.3.13 → 5.3.15

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 (139) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/cjs/plugins/table/event-handlers.js +6 -3
  3. package/dist/cjs/plugins/table/index.js +6 -4
  4. package/dist/cjs/plugins/table/pm-plugins/decorations/plugin.js +3 -7
  5. package/dist/cjs/plugins/table/pm-plugins/decorations/utils/column-controls.js +1 -3
  6. package/dist/cjs/plugins/table/pm-plugins/drag-and-drop/plugin.js +11 -0
  7. package/dist/cjs/plugins/table/types.js +9 -2
  8. package/dist/cjs/plugins/table/ui/FloatingDragMenu/DragMenu.js +49 -11
  9. package/dist/cjs/plugins/table/ui/FloatingDragMenu/index.js +10 -5
  10. package/dist/cjs/plugins/table/ui/FloatingInsertButton/InsertButton.js +57 -9
  11. package/dist/cjs/plugins/table/ui/FloatingInsertButton/getPopupOptions.js +9 -7
  12. package/dist/cjs/plugins/table/ui/FloatingInsertButton/index.js +13 -4
  13. package/dist/cjs/plugins/table/ui/TableFloatingColumnControls/ColumnControls/index.js +44 -5
  14. package/dist/cjs/plugins/table/ui/TableFloatingColumnControls/index.js +6 -4
  15. package/dist/cjs/plugins/table/ui/TableFloatingControls/RowControls/DragControls.js +35 -13
  16. package/dist/cjs/plugins/table/ui/TableFloatingControls/index.js +2 -0
  17. package/dist/cjs/plugins/table/ui/common-styles.js +1 -1
  18. package/dist/cjs/plugins/table/ui/icons/AddColLeftIcon.js +44 -0
  19. package/dist/cjs/plugins/table/ui/icons/AddColRightIcon.js +44 -0
  20. package/dist/cjs/plugins/table/ui/icons/AddRowAboveIcon.js +45 -0
  21. package/dist/cjs/plugins/table/ui/icons/AddRowBelowIcon.js +40 -0
  22. package/dist/cjs/plugins/table/ui/icons/index.js +29 -1
  23. package/dist/cjs/plugins/table/ui/ui-styles.js +27 -24
  24. package/dist/cjs/plugins/table/utils/dom.js +12 -4
  25. package/dist/cjs/plugins/table/utils/drag-menu.js +122 -10
  26. package/dist/cjs/plugins/table/utils/index.js +12 -0
  27. package/dist/es2019/plugins/table/event-handlers.js +5 -4
  28. package/dist/es2019/plugins/table/index.js +6 -4
  29. package/dist/es2019/plugins/table/pm-plugins/decorations/plugin.js +3 -7
  30. package/dist/es2019/plugins/table/pm-plugins/decorations/utils/column-controls.js +1 -3
  31. package/dist/es2019/plugins/table/pm-plugins/drag-and-drop/plugin.js +12 -0
  32. package/dist/es2019/plugins/table/types.js +9 -2
  33. package/dist/es2019/plugins/table/ui/FloatingDragMenu/DragMenu.js +52 -8
  34. package/dist/es2019/plugins/table/ui/FloatingDragMenu/index.js +10 -5
  35. package/dist/es2019/plugins/table/ui/FloatingInsertButton/InsertButton.js +58 -7
  36. package/dist/es2019/plugins/table/ui/FloatingInsertButton/getPopupOptions.js +9 -7
  37. package/dist/es2019/plugins/table/ui/FloatingInsertButton/index.js +10 -4
  38. package/dist/es2019/plugins/table/ui/TableFloatingColumnControls/ColumnControls/index.js +46 -6
  39. package/dist/es2019/plugins/table/ui/TableFloatingColumnControls/index.js +7 -5
  40. package/dist/es2019/plugins/table/ui/TableFloatingControls/RowControls/DragControls.js +35 -14
  41. package/dist/es2019/plugins/table/ui/TableFloatingControls/index.js +2 -0
  42. package/dist/es2019/plugins/table/ui/common-styles.js +51 -3
  43. package/dist/es2019/plugins/table/ui/icons/AddColLeftIcon.js +35 -0
  44. package/dist/es2019/plugins/table/ui/icons/AddColRightIcon.js +35 -0
  45. package/dist/es2019/plugins/table/ui/icons/AddRowAboveIcon.js +36 -0
  46. package/dist/es2019/plugins/table/ui/icons/AddRowBelowIcon.js +31 -0
  47. package/dist/es2019/plugins/table/ui/icons/index.js +5 -1
  48. package/dist/es2019/plugins/table/ui/ui-styles.js +23 -1
  49. package/dist/es2019/plugins/table/utils/dom.js +5 -1
  50. package/dist/es2019/plugins/table/utils/drag-menu.js +118 -8
  51. package/dist/es2019/plugins/table/utils/index.js +1 -1
  52. package/dist/esm/plugins/table/event-handlers.js +7 -4
  53. package/dist/esm/plugins/table/index.js +6 -4
  54. package/dist/esm/plugins/table/pm-plugins/decorations/plugin.js +3 -7
  55. package/dist/esm/plugins/table/pm-plugins/decorations/utils/column-controls.js +1 -3
  56. package/dist/esm/plugins/table/pm-plugins/drag-and-drop/plugin.js +11 -0
  57. package/dist/esm/plugins/table/types.js +9 -2
  58. package/dist/esm/plugins/table/ui/FloatingDragMenu/DragMenu.js +46 -8
  59. package/dist/esm/plugins/table/ui/FloatingDragMenu/index.js +10 -5
  60. package/dist/esm/plugins/table/ui/FloatingInsertButton/InsertButton.js +56 -8
  61. package/dist/esm/plugins/table/ui/FloatingInsertButton/getPopupOptions.js +9 -7
  62. package/dist/esm/plugins/table/ui/FloatingInsertButton/index.js +10 -4
  63. package/dist/esm/plugins/table/ui/TableFloatingColumnControls/ColumnControls/index.js +45 -6
  64. package/dist/esm/plugins/table/ui/TableFloatingColumnControls/index.js +7 -5
  65. package/dist/esm/plugins/table/ui/TableFloatingControls/RowControls/DragControls.js +36 -14
  66. package/dist/esm/plugins/table/ui/TableFloatingControls/index.js +2 -0
  67. package/dist/esm/plugins/table/ui/common-styles.js +2 -2
  68. package/dist/esm/plugins/table/ui/icons/AddColLeftIcon.js +37 -0
  69. package/dist/esm/plugins/table/ui/icons/AddColRightIcon.js +37 -0
  70. package/dist/esm/plugins/table/ui/icons/AddRowAboveIcon.js +38 -0
  71. package/dist/esm/plugins/table/ui/icons/AddRowBelowIcon.js +33 -0
  72. package/dist/esm/plugins/table/ui/icons/index.js +5 -1
  73. package/dist/esm/plugins/table/ui/ui-styles.js +26 -23
  74. package/dist/esm/plugins/table/utils/dom.js +11 -3
  75. package/dist/esm/plugins/table/utils/drag-menu.js +120 -8
  76. package/dist/esm/plugins/table/utils/index.js +1 -1
  77. package/dist/types/plugins/table/types.d.ts +9 -2
  78. package/dist/types/plugins/table/ui/FloatingDragMenu/DragMenu.d.ts +5 -2
  79. package/dist/types/plugins/table/ui/FloatingDragMenu/index.d.ts +3 -1
  80. package/dist/types/plugins/table/ui/FloatingInsertButton/InsertButton.d.ts +5 -1
  81. package/dist/types/plugins/table/ui/FloatingInsertButton/getPopupOptions.d.ts +1 -1
  82. package/dist/types/plugins/table/ui/FloatingInsertButton/index.d.ts +1 -0
  83. package/dist/types/plugins/table/ui/TableFloatingColumnControls/ColumnControls/index.d.ts +2 -1
  84. package/dist/types/plugins/table/ui/TableFloatingControls/RowControls/DragControls.d.ts +2 -0
  85. package/dist/types/plugins/table/ui/icons/AddColLeftIcon.d.ts +2 -0
  86. package/dist/types/plugins/table/ui/icons/AddColRightIcon.d.ts +2 -0
  87. package/dist/types/plugins/table/ui/icons/AddRowAboveIcon.d.ts +2 -0
  88. package/dist/types/plugins/table/ui/icons/AddRowBelowIcon.d.ts +2 -0
  89. package/dist/types/plugins/table/ui/icons/index.d.ts +4 -0
  90. package/dist/types/plugins/table/ui/ui-styles.d.ts +1 -0
  91. package/dist/types/plugins/table/utils/dom.d.ts +4 -1
  92. package/dist/types/plugins/table/utils/drag-menu.d.ts +6 -3
  93. package/dist/types/plugins/table/utils/index.d.ts +1 -1
  94. package/dist/types-ts4.5/plugins/table/types.d.ts +9 -2
  95. package/dist/types-ts4.5/plugins/table/ui/FloatingDragMenu/DragMenu.d.ts +5 -2
  96. package/dist/types-ts4.5/plugins/table/ui/FloatingDragMenu/index.d.ts +3 -1
  97. package/dist/types-ts4.5/plugins/table/ui/FloatingInsertButton/InsertButton.d.ts +5 -1
  98. package/dist/types-ts4.5/plugins/table/ui/FloatingInsertButton/getPopupOptions.d.ts +1 -1
  99. package/dist/types-ts4.5/plugins/table/ui/FloatingInsertButton/index.d.ts +1 -0
  100. package/dist/types-ts4.5/plugins/table/ui/TableFloatingColumnControls/ColumnControls/index.d.ts +2 -1
  101. package/dist/types-ts4.5/plugins/table/ui/TableFloatingControls/RowControls/DragControls.d.ts +2 -0
  102. package/dist/types-ts4.5/plugins/table/ui/icons/AddColLeftIcon.d.ts +2 -0
  103. package/dist/types-ts4.5/plugins/table/ui/icons/AddColRightIcon.d.ts +2 -0
  104. package/dist/types-ts4.5/plugins/table/ui/icons/AddRowAboveIcon.d.ts +2 -0
  105. package/dist/types-ts4.5/plugins/table/ui/icons/AddRowBelowIcon.d.ts +2 -0
  106. package/dist/types-ts4.5/plugins/table/ui/icons/index.d.ts +4 -0
  107. package/dist/types-ts4.5/plugins/table/ui/ui-styles.d.ts +1 -0
  108. package/dist/types-ts4.5/plugins/table/utils/dom.d.ts +4 -1
  109. package/dist/types-ts4.5/plugins/table/utils/drag-menu.d.ts +6 -3
  110. package/dist/types-ts4.5/plugins/table/utils/index.d.ts +1 -1
  111. package/package.json +2 -1
  112. package/src/__tests__/unit/pm-plugins/decorations/plugin.ts +40 -194
  113. package/src/__tests__/unit/ui/RowDragControls.tsx +9 -11
  114. package/src/plugins/table/event-handlers.ts +15 -3
  115. package/src/plugins/table/index.tsx +4 -2
  116. package/src/plugins/table/pm-plugins/decorations/plugin.ts +2 -9
  117. package/src/plugins/table/pm-plugins/decorations/utils/column-controls.ts +1 -3
  118. package/src/plugins/table/pm-plugins/drag-and-drop/plugin.ts +9 -0
  119. package/src/plugins/table/types.ts +12 -2
  120. package/src/plugins/table/ui/FloatingDragMenu/DragMenu.tsx +73 -6
  121. package/src/plugins/table/ui/FloatingDragMenu/index.tsx +15 -3
  122. package/src/plugins/table/ui/FloatingInsertButton/InsertButton.tsx +82 -8
  123. package/src/plugins/table/ui/FloatingInsertButton/getPopupOptions.ts +28 -5
  124. package/src/plugins/table/ui/FloatingInsertButton/index.tsx +19 -7
  125. package/src/plugins/table/ui/TableFloatingColumnControls/ColumnControls/index.tsx +47 -3
  126. package/src/plugins/table/ui/TableFloatingColumnControls/index.tsx +11 -4
  127. package/src/plugins/table/ui/TableFloatingControls/RowControls/DragControls.tsx +49 -18
  128. package/src/plugins/table/ui/TableFloatingControls/index.tsx +2 -0
  129. package/src/plugins/table/ui/common-styles.ts +57 -2
  130. package/src/plugins/table/ui/icons/AddColLeftIcon.tsx +43 -0
  131. package/src/plugins/table/ui/icons/AddColRightIcon.tsx +43 -0
  132. package/src/plugins/table/ui/icons/AddRowAboveIcon.tsx +42 -0
  133. package/src/plugins/table/ui/icons/AddRowBelowIcon.tsx +36 -0
  134. package/src/plugins/table/ui/icons/index.ts +4 -0
  135. package/src/plugins/table/ui/ui-styles.ts +27 -1
  136. package/src/plugins/table/utils/dom.ts +11 -4
  137. package/src/plugins/table/utils/drag-menu.ts +158 -5
  138. package/src/plugins/table/utils/index.ts +2 -0
  139. package/tsconfig.app.json +3 -0
@@ -1,10 +1,12 @@
1
1
  import React from 'react';
2
2
 
3
+ import type { GetEditorContainerWidth } from '@atlaskit/editor-common/types';
3
4
  import { Popup } from '@atlaskit/editor-common/ui';
4
5
  import type { Node as PmNode } from '@atlaskit/editor-prosemirror/model';
5
6
  import { findDomRefAtPos } from '@atlaskit/editor-prosemirror/utils';
6
7
  import type { EditorView } from '@atlaskit/editor-prosemirror/view';
7
8
  import { akEditorFloatingOverlapPanelZIndex } from '@atlaskit/editor-shared-styles';
9
+ import { TableMap } from '@atlaskit/editor-tables/table-map';
8
10
 
9
11
  import type { TableDirection } from '../../types';
10
12
  import { dragMenuDropdownWidth } from '../consts';
@@ -22,6 +24,7 @@ export interface Props {
22
24
  direction?: TableDirection;
23
25
  index?: number;
24
26
  targetCellPosition?: number;
27
+ getEditorContainerWidth: GetEditorContainerWidth;
25
28
  }
26
29
 
27
30
  const FloatingDragMenu = ({
@@ -35,6 +38,7 @@ const FloatingDragMenu = ({
35
38
  direction,
36
39
  index,
37
40
  targetCellPosition,
41
+ getEditorContainerWidth,
38
42
  }: Props) => {
39
43
  if (
40
44
  !isOpen ||
@@ -49,11 +53,17 @@ const FloatingDragMenu = ({
49
53
  if (!targetCellRef) {
50
54
  return null;
51
55
  }
52
-
56
+ const tableMap = tableNode ? TableMap.get(tableNode) : undefined;
57
+ const offset =
58
+ direction === 'row'
59
+ ? [7, 0]
60
+ : index === (tableMap?.width || 1) - 1
61
+ ? [14, 0]
62
+ : [-14, 0];
53
63
  // TODO: we will need to adjust the alignment and offset values depending on whether this is a row or column menu.
54
64
  return (
55
65
  <Popup
56
- alignX="left"
66
+ alignX={direction === 'row' ? 'left' : 'center'}
57
67
  alignY="top"
58
68
  target={targetCellRef as HTMLElement}
59
69
  mountTo={mountPoint}
@@ -64,7 +74,7 @@ const FloatingDragMenu = ({
64
74
  // in table, but below floating dialogs like typeaheads, pickers, etc.
65
75
  zIndex={akEditorFloatingOverlapPanelZIndex}
66
76
  forcePlacement={true}
67
- offset={[7, 0]}
77
+ offset={offset}
68
78
  stick={true}
69
79
  >
70
80
  <DragMenu
@@ -74,6 +84,8 @@ const FloatingDragMenu = ({
74
84
  tableNode={tableNode}
75
85
  direction={direction}
76
86
  index={index}
87
+ targetCellPosition={targetCellPosition}
88
+ getEditorContainerWidth={getEditorContainerWidth}
77
89
  />
78
90
  </Popup>
79
91
  );
@@ -1,3 +1,4 @@
1
+ /* eslint-disable @atlaskit/design-system/ensure-design-token-usage */
1
2
  import type { SyntheticEvent } from 'react';
2
3
  import React from 'react';
3
4
 
@@ -20,7 +21,7 @@ import { tableToolbarSize } from '../consts';
20
21
  import tableMessages from '../messages';
21
22
 
22
23
  export interface ButtonProps {
23
- direction: TableDirection;
24
+ type: TableDirection;
24
25
  tableRef: HTMLElement;
25
26
  onMouseDown: (event: SyntheticEvent<HTMLButtonElement>) => void;
26
27
  hasStickyHeaders: boolean;
@@ -52,7 +53,10 @@ const getToolbarSize = (tableRef: HTMLElement): number => {
52
53
  return tableToolbarSize;
53
54
  };
54
55
 
55
- const getInsertLineWidth = (tableRef: HTMLElement) => {
56
+ const getInsertLineWidth = (
57
+ tableRef: HTMLElement,
58
+ isDragAndDropEnabled?: boolean,
59
+ ) => {
56
60
  // The line gets width 100% from the table,
57
61
  // but since we have an overflow on the left,
58
62
  // we should add an offset to make up for it.
@@ -61,7 +65,7 @@ const getInsertLineWidth = (tableRef: HTMLElement) => {
61
65
  const parentOffsetWidth = parentElement!.offsetWidth;
62
66
  const { scrollLeft } = parentElement!;
63
67
  const diff = offsetWidth - parentOffsetWidth;
64
- const toolbarSize = getToolbarSize(tableRef);
68
+ const toolbarSize = isDragAndDropEnabled ? 0 : getToolbarSize(tableRef);
65
69
  return (
66
70
  Math.min(
67
71
  offsetWidth + toolbarSize,
@@ -74,10 +78,80 @@ const tooltipMessageByType = (type: TableDirection) => {
74
78
  return type === 'row' ? tableMessages.insertRow : tableMessages.insertColumn;
75
79
  };
76
80
 
81
+ export const InsertButtonForDragAndDrop = ({
82
+ onMouseDown,
83
+ tableRef,
84
+ type,
85
+ intl: { formatMessage },
86
+ hasStickyHeaders,
87
+ }: ButtonProps & WrappedComponentProps) => {
88
+ const content = (
89
+ <Tooltip
90
+ content={
91
+ <ToolTipContent
92
+ description={formatMessage(tooltipMessageByType(type))}
93
+ keymap={type === 'row' ? addRowAfter : addColumnAfter}
94
+ />
95
+ }
96
+ position="top"
97
+ >
98
+ <>
99
+ <div className={ClassName.DRAG_CONTROLS_INSERT_BUTTON_INNER}>
100
+ <button
101
+ type="button"
102
+ className={ClassName.DRAG_CONTROLS_INSERT_BUTTON}
103
+ onMouseDown={onMouseDown}
104
+ >
105
+ <svg
106
+ width="10"
107
+ height="10"
108
+ viewBox="0 0 10 10"
109
+ fill="none"
110
+ xmlns="http://www.w3.org/2000/svg"
111
+ >
112
+ <path
113
+ fillRule="evenodd"
114
+ clipRule="evenodd"
115
+ d="M5.41667 4.58333V2.91667C5.41667 2.80616 5.37277 2.70018 5.29463 2.62204C5.21649 2.5439 5.11051 2.5 5 2.5C4.88949 2.5 4.78351 2.5439 4.70537 2.62204C4.62723 2.70018 4.58333 2.80616 4.58333 2.91667V4.58333H2.91667C2.80616 4.58333 2.70018 4.62723 2.62204 4.70537C2.5439 4.78351 2.5 4.88949 2.5 5C2.5 5.11051 2.5439 5.21649 2.62204 5.29463C2.70018 5.37277 2.80616 5.41667 2.91667 5.41667H4.58333V7.08333C4.58333 7.19384 4.62723 7.29982 4.70537 7.37796C4.78351 7.4561 4.88949 7.5 5 7.5C5.11051 7.5 5.21649 7.4561 5.29463 7.37796C5.37277 7.29982 5.41667 7.19384 5.41667 7.08333V5.41667H7.08333C7.19384 5.41667 7.29982 5.37277 7.37796 5.29463C7.4561 5.21649 7.5 5.11051 7.5 5C7.5 4.88949 7.4561 4.78351 7.37796 4.70537C7.29982 4.62723 7.19384 4.58333 7.08333 4.58333H5.41667Z"
116
+ fill="currentColor"
117
+ />
118
+ </svg>
119
+ </button>
120
+ </div>
121
+ <div
122
+ className={ClassName.CONTROLS_INSERT_LINE}
123
+ style={
124
+ type === 'row'
125
+ ? { width: getInsertLineWidth(tableRef, true), left: '14px' }
126
+ : { height: getInsertLineHeight(tableRef, hasStickyHeaders) - 11 }
127
+ }
128
+ />
129
+ </>
130
+ </Tooltip>
131
+ );
132
+
133
+ const floatingButtonClassName =
134
+ type === 'column'
135
+ ? ClassName.CONTROLS_FLOATING_BUTTON_COLUMN
136
+ : ClassName.CONTROLS_FLOATING_BUTTON_ROW;
137
+
138
+ return (
139
+ <div className={floatingButtonClassName}>
140
+ <div
141
+ className={`${ClassName.CONTROLS_INSERT_BUTTON_WRAP} ${ClassName.CONTROLS_INSERT_ROW}`}
142
+ >
143
+ {content}
144
+ </div>
145
+ </div>
146
+ );
147
+ };
148
+
149
+ export const DragAndDropInsertButton = injectIntl(InsertButtonForDragAndDrop);
150
+
77
151
  const InsertButton = ({
78
152
  onMouseDown,
79
153
  tableRef,
80
- direction,
154
+ type,
81
155
  intl: { formatMessage },
82
156
  hasStickyHeaders,
83
157
  }: ButtonProps & WrappedComponentProps) => {
@@ -85,8 +159,8 @@ const InsertButton = ({
85
159
  <Tooltip
86
160
  content={
87
161
  <ToolTipContent
88
- description={formatMessage(tooltipMessageByType(direction))}
89
- keymap={direction === 'row' ? addRowAfter : addColumnAfter}
162
+ description={formatMessage(tooltipMessageByType(type))}
163
+ keymap={type === 'row' ? addRowAfter : addColumnAfter}
90
164
  />
91
165
  }
92
166
  position="top"
@@ -110,7 +184,7 @@ const InsertButton = ({
110
184
  <div
111
185
  className={ClassName.CONTROLS_INSERT_LINE}
112
186
  style={
113
- direction === 'row'
187
+ type === 'row'
114
188
  ? { width: getInsertLineWidth(tableRef) }
115
189
  : { height: getInsertLineHeight(tableRef, hasStickyHeaders) }
116
190
  }
@@ -120,7 +194,7 @@ const InsertButton = ({
120
194
  );
121
195
 
122
196
  const floatingButtonClassName =
123
- direction === 'column'
197
+ type === 'column'
124
198
  ? ClassName.CONTROLS_FLOATING_BUTTON_COLUMN
125
199
  : ClassName.CONTROLS_FLOATING_BUTTON_ROW;
126
200
 
@@ -11,17 +11,26 @@ import {
11
11
  const HORIZONTAL_ALIGN_COLUMN_BUTTON = -(tableInsertColumnButtonSize / 2);
12
12
  const HORIZONTAL_ALIGN_NUMBERED_COLUMN_BUTTON =
13
13
  HORIZONTAL_ALIGN_COLUMN_BUTTON + akEditorTableNumberColumnWidth;
14
+
14
15
  const VERTICAL_ALIGN_COLUMN_BUTTON =
15
16
  tableToolbarSize + tableInsertColumnButtonOffset;
16
17
 
18
+ const VERTICAL_ALIGN_COLUMN_BUTTON_DRAG = tableInsertColumnButtonOffset;
19
+
17
20
  const HORIZONTAL_ALIGN_ROW_BUTTON = -(
18
21
  tableToolbarSize +
19
22
  tableInsertColumnButtonOffset +
20
23
  tableInsertColumnButtonSize
21
24
  );
25
+
26
+ const HORIZONTAL_ALIGN_ROW_BUTTON_DRAG = -18;
27
+
22
28
  const VERTICAL_ALIGN_ROW_BUTTON = tableInsertColumnButtonSize / 2;
23
29
 
24
- function getRowOptions(index: number): Partial<PopupProps> {
30
+ function getRowOptions(
31
+ index: number,
32
+ isDragAndDropEnabled: boolean,
33
+ ): Partial<PopupProps> {
25
34
  let defaultOptions = {
26
35
  alignX: 'left',
27
36
  alignY: 'bottom',
@@ -43,7 +52,9 @@ function getRowOptions(index: number): Partial<PopupProps> {
43
52
  return {
44
53
  ...position,
45
54
  // Left position should be always the offset (To place in the correct position even if the table has overflow).
46
- left: HORIZONTAL_ALIGN_ROW_BUTTON,
55
+ left: isDragAndDropEnabled
56
+ ? HORIZONTAL_ALIGN_ROW_BUTTON_DRAG
57
+ : HORIZONTAL_ALIGN_ROW_BUTTON,
47
58
  };
48
59
  },
49
60
  };
@@ -53,11 +64,17 @@ function getColumnOptions(
53
64
  index: number,
54
65
  tableContainer: HTMLElement | null,
55
66
  hasNumberedColumns: boolean,
67
+ isDragAndDropEnabled: boolean,
56
68
  ): Partial<PopupProps> {
57
69
  const options: Partial<PopupProps> = {
58
70
  alignX: 'end',
59
71
  alignY: 'top',
60
- offset: [HORIZONTAL_ALIGN_COLUMN_BUTTON, VERTICAL_ALIGN_COLUMN_BUTTON],
72
+ offset: [
73
+ HORIZONTAL_ALIGN_COLUMN_BUTTON,
74
+ isDragAndDropEnabled
75
+ ? VERTICAL_ALIGN_COLUMN_BUTTON_DRAG
76
+ : VERTICAL_ALIGN_COLUMN_BUTTON,
77
+ ],
61
78
  // :: (position: PopupPosition) -> PopupPosition
62
79
  // Limit the InsertButton position to the table container
63
80
  // if the left position starts before it
@@ -108,13 +125,19 @@ function getPopupOptions(
108
125
  direction: TableDirection,
109
126
  index: number,
110
127
  hasNumberedColumns: boolean,
128
+ isDragAndDropEnabled: boolean,
111
129
  tableContainer: HTMLElement | null,
112
130
  ): Partial<PopupProps> {
113
131
  switch (direction) {
114
132
  case 'column':
115
- return getColumnOptions(index, tableContainer, hasNumberedColumns);
133
+ return getColumnOptions(
134
+ index,
135
+ tableContainer,
136
+ hasNumberedColumns,
137
+ isDragAndDropEnabled,
138
+ );
116
139
  case 'row':
117
- return getRowOptions(index);
140
+ return getRowOptions(index, isDragAndDropEnabled);
118
141
  default:
119
142
  return {};
120
143
  }
@@ -34,7 +34,7 @@ import { TableCssClassName as ClassName } from '../../types';
34
34
  import { checkIfNumberColumnEnabled } from '../../utils';
35
35
 
36
36
  import getPopupOptions from './getPopupOptions';
37
- import InsertButton from './InsertButton';
37
+ import InsertButton, { DragAndDropInsertButton } from './InsertButton';
38
38
 
39
39
  export interface Props {
40
40
  editorView: EditorView;
@@ -45,6 +45,7 @@ export interface Props {
45
45
  insertRowButtonIndex?: number;
46
46
  isHeaderColumnEnabled?: boolean;
47
47
  isHeaderRowEnabled?: boolean;
48
+ isDragAndDropEnabled?: boolean;
48
49
  mountPoint?: HTMLElement;
49
50
  boundariesElement?: HTMLElement;
50
51
  scrollableElement?: HTMLElement;
@@ -76,6 +77,7 @@ export class FloatingInsertButton extends React.Component<
76
77
  boundariesElement,
77
78
  isHeaderColumnEnabled,
78
79
  isHeaderRowEnabled,
80
+ isDragAndDropEnabled,
79
81
  dispatchAnalyticsEvent,
80
82
  } = this.props;
81
83
 
@@ -199,16 +201,26 @@ export class FloatingInsertButton extends React.Component<
199
201
  type,
200
202
  index,
201
203
  hasNumberedColumns,
204
+ !!isDragAndDropEnabled,
202
205
  tableContainerWrapper,
203
206
  )}
204
207
  zIndex={zIndex}
205
208
  >
206
- <InsertButton
207
- direction={type}
208
- tableRef={tableRef}
209
- onMouseDown={type === 'column' ? this.insertColumn : this.insertRow}
210
- hasStickyHeaders={this.props.hasStickyHeaders || false}
211
- />
209
+ {isDragAndDropEnabled ? (
210
+ <DragAndDropInsertButton
211
+ type={type}
212
+ tableRef={tableRef}
213
+ onMouseDown={type === 'column' ? this.insertColumn : this.insertRow}
214
+ hasStickyHeaders={this.props.hasStickyHeaders || false}
215
+ />
216
+ ) : (
217
+ <InsertButton
218
+ type={type}
219
+ tableRef={tableRef}
220
+ onMouseDown={type === 'column' ? this.insertColumn : this.insertRow}
221
+ hasStickyHeaders={this.props.hasStickyHeaders || false}
222
+ />
223
+ )}
212
224
  </Popup>
213
225
  );
214
226
  }
@@ -5,15 +5,17 @@ import type { Selection } from '@atlaskit/editor-prosemirror/state';
5
5
  import type { EditorView } from '@atlaskit/editor-prosemirror/view';
6
6
  import { CellSelection } from '@atlaskit/editor-tables';
7
7
  import { getSelectionRect } from '@atlaskit/editor-tables/utils';
8
+ import { token } from '@atlaskit/tokens';
8
9
 
9
10
  import {
10
11
  clearHoverSelection,
11
12
  hoverColumns,
12
13
  selectColumn,
13
14
  } from '../../../commands';
15
+ import { toggleDragMenu } from '../../../pm-plugins/drag-and-drop/commands';
14
16
  import type { CellHoverMeta } from '../../../types';
15
17
  import { TableCssClassName as ClassName } from '../../../types';
16
- import { getSelectedColumnIndexes } from '../../../utils';
18
+ import { getRowsParams, getSelectedColumnIndexes } from '../../../utils';
17
19
  import { DragHandle } from '../../DragHandle';
18
20
 
19
21
  export interface ColumnControlsProps {
@@ -27,6 +29,7 @@ export interface ColumnControlsProps {
27
29
  localId?: string;
28
30
  rowHeights?: number[];
29
31
  colWidths?: (number | undefined)[];
32
+ hasHeaderColumn?: boolean;
30
33
  }
31
34
 
32
35
  const getSelectedColumns = (selection: Selection) => {
@@ -51,10 +54,13 @@ export const ColumnControls = ({
51
54
  isInDanger,
52
55
  rowHeights,
53
56
  colWidths,
57
+ hasHeaderColumn,
54
58
  }: ColumnControlsProps) => {
55
59
  const widths =
56
60
  colWidths?.map((width) => (width ? `${width - 1}px` : '0px')).join(' ') ??
57
61
  '0px';
62
+ // TODO: reusing getRowsParams here because it's generic enough to work for columns -> rename
63
+ const columnParams = getRowsParams(colWidths ?? []);
58
64
  const colIndex = hoveredCell?.colIndex;
59
65
  const selectedColIndexes = getSelectedColumns(editorView.state.selection);
60
66
 
@@ -94,8 +100,13 @@ export const ColumnControls = ({
94
100
  }
95
101
  }, [editorView, tableActive]);
96
102
 
103
+ const handleMouseUp = useCallback(() => {
104
+ const { state, dispatch } = editorView;
105
+ toggleDragMenu(undefined, 'column', colIndex)(state, dispatch);
106
+ }, [editorView, colIndex]);
107
+
97
108
  return (
98
- <div className={ClassName.COLUMN_CONTROLS_WITH_DRAG}>
109
+ <div className={ClassName.DRAG_COLUMN_CONTROLS}>
99
110
  <div
100
111
  className={ClassName.COLUMN_CONTROLS_INNER}
101
112
  data-testid="table-floating-column-controls"
@@ -104,6 +115,33 @@ export const ColumnControls = ({
104
115
  marginTop,
105
116
  }}
106
117
  >
118
+ {!isResizing &&
119
+ columnParams.map(({ startIndex, endIndex }, index) => (
120
+ <div
121
+ style={{
122
+ gridColumn: `${index + 1} / span 1`,
123
+ }}
124
+ data-start-index={startIndex}
125
+ data-end-index={endIndex}
126
+ className={ClassName.DRAG_COLUMN_FLOATING_INSERT_DOT_WRAPPER}
127
+ contentEditable={false}
128
+ key={index}
129
+ >
130
+ {!hasHeaderColumn && index === 0 && (
131
+ <div
132
+ style={{
133
+ left: '0px',
134
+ right: 'unset',
135
+ }}
136
+ className={ClassName.DRAG_COLUMN_FLOATING_INSERT_DOT}
137
+ />
138
+ )}
139
+ <div
140
+ className={ClassName.DRAG_COLUMN_FLOATING_INSERT_DOT}
141
+ style={columnParams.length - 1 === index ? { right: '0' } : {}}
142
+ />
143
+ </div>
144
+ ))}
107
145
  {tableActive &&
108
146
  !isResizing &&
109
147
  !!hoveredCell &&
@@ -111,7 +149,12 @@ export const ColumnControls = ({
111
149
  <div
112
150
  style={{
113
151
  gridColumn: gridColumnPosition,
114
- marginTop: `-15px`,
152
+ zIndex: 99,
153
+ display: 'flex',
154
+ width: '100%',
155
+ justifyContent: 'center',
156
+ alignItems: 'center',
157
+ marginTop: token('space.negative.025', '-2px'),
115
158
  }}
116
159
  data-column-control-index={hoveredCell.colIndex}
117
160
  data-testid="table-floating-column-control"
@@ -132,6 +175,7 @@ export const ColumnControls = ({
132
175
  onClick={handleClick}
133
176
  onMouseOver={handleMouseOver}
134
177
  onMouseOut={handleMouseOut}
178
+ onMouseUp={handleMouseUp}
135
179
  />
136
180
  </div>
137
181
  )}
@@ -12,7 +12,11 @@ import { monitorForElements } from '@atlaskit/pragmatic-drag-and-drop/adapter/el
12
12
  import type { RowStickyState } from '../../pm-plugins/sticky-headers';
13
13
  import type { CellHoverMeta, DraggableSourceData } from '../../types';
14
14
  import { TableCssClassName as ClassName } from '../../types';
15
- import { getColumnsWidths, getRowHeights } from '../../utils';
15
+ import {
16
+ containsHeaderColumn,
17
+ getColumnsWidths,
18
+ getRowHeights,
19
+ } from '../../utils';
16
20
 
17
21
  import { ColumnControls } from './ColumnControls';
18
22
  import { ColumnDropTargets } from './ColumnDropTargets';
@@ -53,6 +57,7 @@ export const TableFloatingColumnControls: React.FC<Props> = ({
53
57
  const [hasDropTargets, setHasDropTargets] = useState(false);
54
58
  const node = getNode();
55
59
  const currentNodeLocalId = node?.attrs.localId;
60
+ const hasHeaderColumn = containsHeaderColumn(node);
56
61
 
57
62
  useEffect(() => {
58
63
  if (tableRef && window?.ResizeObserver) {
@@ -118,12 +123,13 @@ export const TableFloatingColumnControls: React.FC<Props> = ({
118
123
 
119
124
  const mountTo = (tableRef && tableRef?.parentElement) || document.body;
120
125
 
126
+ if (!tableActive) {
127
+ return null;
128
+ }
129
+
121
130
  return ReactDOM.createPortal(
122
131
  <div
123
132
  className={ClassName.COLUMN_CONTROLS_WRAPPER}
124
- style={{
125
- pointerEvents: 'none',
126
- }}
127
133
  data-testid="table-floating-column-controls-wrapper"
128
134
  >
129
135
  <ColumnControls
@@ -137,6 +143,7 @@ export const TableFloatingColumnControls: React.FC<Props> = ({
137
143
  isInDanger={isInDanger}
138
144
  rowHeights={rowHeights}
139
145
  colWidths={colWidths}
146
+ hasHeaderColumn={hasHeaderColumn}
140
147
  />
141
148
  {hasDropTargets && (
142
149
  <ColumnDropTargets
@@ -9,12 +9,17 @@ import type { Selection } from '@atlaskit/editor-prosemirror/state';
9
9
  import type { EditorView } from '@atlaskit/editor-prosemirror/view';
10
10
  import { CellSelection } from '@atlaskit/editor-tables';
11
11
  import { getSelectionRect } from '@atlaskit/editor-tables/utils';
12
+ import { token } from '@atlaskit/tokens';
12
13
 
13
14
  import { clearHoverSelection } from '../../../commands';
14
15
  import { toggleDragMenu } from '../../../pm-plugins/drag-and-drop/commands';
15
16
  import type { CellHoverMeta } from '../../../types';
16
17
  import { TableCssClassName as ClassName } from '../../../types';
17
- import { getRowHeights, getSelectedRowIndexes } from '../../../utils';
18
+ import {
19
+ getRowHeights,
20
+ getRowsParams,
21
+ getSelectedRowIndexes,
22
+ } from '../../../utils';
18
23
  import { DragHandle } from '../../DragHandle';
19
24
 
20
25
  type DragControlsProps = {
@@ -24,6 +29,8 @@ type DragControlsProps = {
24
29
  tableActive?: boolean;
25
30
  hoveredCell?: CellHoverMeta;
26
31
  isInDanger?: boolean;
32
+ isResizing?: boolean;
33
+ hasHeaderRow?: boolean;
27
34
  hoverRows: (rows: number[], danger?: boolean) => void;
28
35
  selectRow: (row: number, expand: boolean) => void;
29
36
  updateCellHoverLocation: (rowIndex: number) => void;
@@ -47,11 +54,14 @@ const DragControlsComponent = ({
47
54
  tableActive,
48
55
  editorView,
49
56
  isInDanger,
57
+ isResizing,
58
+ hasHeaderRow,
50
59
  hoverRows,
51
60
  selectRow,
52
61
  updateCellHoverLocation,
53
62
  }: DragControlsProps & WrappedComponentProps) => {
54
63
  const rowHeights = getRowHeights(tableRef);
64
+ const rowsParams = getRowsParams(rowHeights);
55
65
  const heights = rowHeights.map((height) => `${height - 1}px`).join(' ');
56
66
  const selectedRowIndexes = getSelectedRows(editorView.state.selection);
57
67
  const rowWidth = tableRef.offsetWidth;
@@ -83,25 +93,21 @@ const DragControlsComponent = ({
83
93
 
84
94
  const handleMouseMove = useCallback(
85
95
  (e: MouseEvent) => {
86
- // avoid updating if event target is drag handle
87
- if (
88
- !(e.nativeEvent.target as Element).classList.contains(
89
- ClassName.ROW_CONTROLS_WITH_DRAG,
90
- )
91
- ) {
96
+ const isParentDragControls = (e.nativeEvent.target as Element).closest(
97
+ `.${ClassName.DRAG_ROW_CONTROLS}`,
98
+ );
99
+ const rowIndex = (e.nativeEvent.target as Element).getAttribute(
100
+ 'data-start-index',
101
+ );
102
+
103
+ // avoid updating if event target is not related
104
+ if (!isParentDragControls || !rowIndex) {
92
105
  return;
93
106
  }
94
107
 
95
- const hoverHeight = e.nativeEvent.offsetY;
96
- let totalHeight = 0;
97
- const rowIndex = rowHeights.findIndex((row) => {
98
- totalHeight += row;
99
- return hoverHeight <= totalHeight;
100
- });
101
-
102
- updateCellHoverLocation(rowIndex);
108
+ updateCellHoverLocation(Number(rowIndex));
103
109
  },
104
- [updateCellHoverLocation, rowHeights],
110
+ [updateCellHoverLocation],
105
111
  );
106
112
 
107
113
  const handleMouseOver = useCallback(() => {
@@ -117,13 +123,37 @@ const DragControlsComponent = ({
117
123
 
118
124
  return (
119
125
  <div
120
- className={ClassName.ROW_CONTROLS_WITH_DRAG}
126
+ className={ClassName.DRAG_ROW_CONTROLS}
121
127
  style={{
122
128
  gridTemplateRows: heights,
123
129
  }}
124
130
  onMouseMove={handleMouseMove}
125
131
  >
126
- {Number.isFinite(rowIndex) && (
132
+ {!isResizing &&
133
+ rowsParams.map(({ startIndex, endIndex }, index) => (
134
+ <div
135
+ style={{
136
+ gridRow: `${index + 1} / span 1`,
137
+ }}
138
+ data-start-index={startIndex}
139
+ data-end-index={endIndex}
140
+ className={ClassName.DRAG_ROW_FLOATING_INSERT_DOT_WRAPPER}
141
+ contentEditable={false}
142
+ key={index}
143
+ >
144
+ {!hasHeaderRow && index === 0 && (
145
+ <div
146
+ style={{
147
+ top: '0px',
148
+ left: token('space.075', '6px'),
149
+ }}
150
+ className={ClassName.DRAG_ROW_FLOATING_INSERT_DOT}
151
+ />
152
+ )}
153
+ <div className={ClassName.DRAG_ROW_FLOATING_INSERT_DOT} />
154
+ </div>
155
+ ))}
156
+ {!isResizing && Number.isFinite(rowIndex) && (
127
157
  <div
128
158
  style={{
129
159
  gridRow: gridRowPosition,
@@ -132,6 +162,7 @@ const DragControlsComponent = ({
132
162
  alignItems: 'center',
133
163
  justifyContent: 'center',
134
164
  }}
165
+ data-testid="table-floating-row-drag-handle"
135
166
  >
136
167
  <DragHandle
137
168
  tableLocalId={tableNode?.attrs?.localId ?? ''}
@@ -166,6 +166,8 @@ export default class TableFloatingControls extends Component<Props, State> {
166
166
  editorView={editorView}
167
167
  tableActive={tableActive}
168
168
  isInDanger={isInDanger}
169
+ isResizing={isResizing}
170
+ hasHeaderRow={hasHeaderRow}
169
171
  hoverRows={this.hoverRows}
170
172
  selectRow={this.selectRow}
171
173
  updateCellHoverLocation={this.updateCellHoverLocation}