@atlaskit/editor-plugin-table 5.5.1 → 5.5.3

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 (43) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/dist/cjs/plugins/table/index.js +1 -1
  3. package/dist/cjs/plugins/table/nodeviews/TableComponent.js +22 -26
  4. package/dist/cjs/plugins/table/pm-plugins/table-resizing/event-handlers.js +5 -7
  5. package/dist/cjs/plugins/table/ui/DragHandle/HandleIconComponent.js +4 -15
  6. package/dist/cjs/plugins/table/ui/DragHandle/index.js +8 -19
  7. package/dist/cjs/plugins/table/ui/TableFloatingColumnControls/ColumnControls/index.js +62 -34
  8. package/dist/cjs/plugins/table/ui/TableFloatingControls/RowControls/DragControls.js +58 -30
  9. package/dist/cjs/plugins/table/ui/common-styles.js +1 -1
  10. package/dist/es2019/plugins/table/index.js +1 -1
  11. package/dist/es2019/plugins/table/nodeviews/TableComponent.js +25 -29
  12. package/dist/es2019/plugins/table/pm-plugins/table-resizing/event-handlers.js +5 -7
  13. package/dist/es2019/plugins/table/ui/DragHandle/HandleIconComponent.js +4 -15
  14. package/dist/es2019/plugins/table/ui/DragHandle/index.js +5 -18
  15. package/dist/es2019/plugins/table/ui/TableFloatingColumnControls/ColumnControls/index.js +62 -34
  16. package/dist/es2019/plugins/table/ui/TableFloatingControls/NumberColumn/index.js +3 -1
  17. package/dist/es2019/plugins/table/ui/TableFloatingControls/RowControls/DragControls.js +58 -30
  18. package/dist/es2019/plugins/table/ui/common-styles.js +2 -1
  19. package/dist/esm/plugins/table/index.js +1 -1
  20. package/dist/esm/plugins/table/nodeviews/TableComponent.js +22 -26
  21. package/dist/esm/plugins/table/pm-plugins/table-resizing/event-handlers.js +5 -7
  22. package/dist/esm/plugins/table/ui/DragHandle/HandleIconComponent.js +4 -15
  23. package/dist/esm/plugins/table/ui/DragHandle/index.js +6 -17
  24. package/dist/esm/plugins/table/ui/TableFloatingColumnControls/ColumnControls/index.js +62 -34
  25. package/dist/esm/plugins/table/ui/TableFloatingControls/RowControls/DragControls.js +58 -30
  26. package/dist/esm/plugins/table/ui/common-styles.js +1 -1
  27. package/dist/types/plugins/table/types.d.ts +1 -0
  28. package/dist/types/plugins/table/ui/DragHandle/HandleIconComponent.d.ts +2 -7
  29. package/dist/types/plugins/table/ui/DragHandle/index.d.ts +2 -1
  30. package/dist/types-ts4.5/plugins/table/types.d.ts +1 -0
  31. package/dist/types-ts4.5/plugins/table/ui/DragHandle/HandleIconComponent.d.ts +2 -7
  32. package/dist/types-ts4.5/plugins/table/ui/DragHandle/index.d.ts +2 -1
  33. package/package.json +1 -4
  34. package/src/plugins/table/index.tsx +5 -7
  35. package/src/plugins/table/nodeviews/TableComponent.tsx +31 -38
  36. package/src/plugins/table/pm-plugins/table-resizing/event-handlers.ts +5 -7
  37. package/src/plugins/table/types.ts +2 -0
  38. package/src/plugins/table/ui/DragHandle/HandleIconComponent.tsx +5 -30
  39. package/src/plugins/table/ui/DragHandle/index.tsx +6 -23
  40. package/src/plugins/table/ui/TableFloatingColumnControls/ColumnControls/index.tsx +112 -47
  41. package/src/plugins/table/ui/TableFloatingControls/NumberColumn/index.tsx +3 -3
  42. package/src/plugins/table/ui/TableFloatingControls/RowControls/DragControls.tsx +116 -42
  43. package/src/plugins/table/ui/common-styles.ts +2 -1
@@ -7,48 +7,23 @@ import {
7
7
  } from '../icons';
8
8
 
9
9
  type HandleIconProps = {
10
- canDrag: boolean;
11
- hasMergedCells: boolean;
12
- direction: 'row' | 'column';
13
- isDragMenuOpen: boolean | undefined;
10
+ forceDefaultHandle: boolean;
14
11
  isRowHandleHovered: boolean;
15
12
  isColumnHandleHovered: boolean;
16
- isCurrentRowSelected: boolean;
17
- isCurrentColumnSelected: boolean;
18
- dragMenuDirection: 'row' | 'column' | undefined;
13
+ hasMergedCells: boolean;
19
14
  };
20
15
 
21
16
  export const HandleIconComponent = (props: HandleIconProps) => {
22
17
  const {
23
- canDrag,
24
- direction,
25
- isDragMenuOpen,
18
+ forceDefaultHandle,
26
19
  isRowHandleHovered,
27
20
  isColumnHandleHovered,
28
21
  hasMergedCells,
29
- isCurrentRowSelected,
30
- isCurrentColumnSelected,
31
- dragMenuDirection,
32
22
  } = props;
33
23
  const isHandleHovered = isRowHandleHovered || isColumnHandleHovered;
34
- const isCurrentRowOrColumnSelected =
35
- isCurrentRowSelected || isCurrentColumnSelected;
36
- const isDragMenuOpenOnCurrentRowOrColumn =
37
- isDragMenuOpen &&
38
- dragMenuDirection === direction &&
39
- isCurrentRowOrColumnSelected;
40
-
41
- const isDragPossible = canDrag && !hasMergedCells;
42
-
43
- const showNormalHandle = !isDragPossible ? (
44
- <DragHandleDisabledIcon />
45
- ) : (
46
- <DragHandleIcon />
47
- );
48
24
 
49
- // hoverred handle or open drag menu
50
- if (isHandleHovered || isDragMenuOpenOnCurrentRowOrColumn) {
51
- return showNormalHandle;
25
+ if (isHandleHovered || forceDefaultHandle) {
26
+ return hasMergedCells ? <DragHandleDisabledIcon /> : <DragHandleIcon />;
52
27
  }
53
28
 
54
29
  return <MinimisedHandleIcon />;
@@ -9,7 +9,6 @@ import type { EditorView } from '@atlaskit/editor-prosemirror/view';
9
9
  import { draggable } from '@atlaskit/pragmatic-drag-and-drop/adapter/element';
10
10
  import { setCustomNativeDragPreview } from '@atlaskit/pragmatic-drag-and-drop/util/set-custom-native-drag-preview';
11
11
 
12
- import { getPluginState as getDragDropPluginState } from '../../pm-plugins/drag-and-drop/plugin-factory';
13
12
  import { getPluginState } from '../../pm-plugins/plugin-factory';
14
13
  import type { TableDirection } from '../../types';
15
14
  import { TableCssClassName as ClassName } from '../../types';
@@ -23,6 +22,7 @@ type DragHandleAppearance = 'default' | 'selected' | 'disabled' | 'danger';
23
22
  type DragHandleProps = {
24
23
  tableLocalId: string;
25
24
  indexes: number[];
25
+ forceDefaultHandle?: boolean;
26
26
  previewWidth?: number;
27
27
  previewHeight?: number;
28
28
  direction?: TableDirection;
@@ -40,6 +40,7 @@ export const DragHandle = ({
40
40
  direction = 'row',
41
41
  appearance = 'default',
42
42
  indexes,
43
+ forceDefaultHandle = false,
43
44
  previewWidth,
44
45
  previewHeight,
45
46
  onMouseOver,
@@ -53,24 +54,11 @@ export const DragHandle = ({
53
54
  const [previewContainer, setPreviewContainer] = useState<HTMLElement | null>(
54
55
  null,
55
56
  );
56
- const { hoveredColumns, hoveredRows, hoveredCell } = getPluginState(
57
- editorView.state,
58
- );
59
57
 
60
- const { dragMenuDirection, isDragMenuOpen, dragMenuIndex } =
61
- getDragDropPluginState(editorView.state);
58
+ const { hoveredColumns, hoveredRows } = getPluginState(editorView.state);
62
59
 
63
60
  const { selection } = editorView.state;
64
61
 
65
- const isCurrentRowSelected =
66
- isDragMenuOpen &&
67
- direction === 'row' &&
68
- hoveredCell.rowIndex === dragMenuIndex;
69
- const isCurrentColumnSelected =
70
- isDragMenuOpen &&
71
- direction === 'column' &&
72
- hoveredCell.colIndex === dragMenuIndex;
73
-
74
62
  const isRowHandleHovered = direction === 'row' && hoveredRows.length > 0;
75
63
  const isColumnHandleHovered =
76
64
  direction === 'column' && hoveredColumns.length > 0;
@@ -84,15 +72,10 @@ export const DragHandle = ({
84
72
  );
85
73
 
86
74
  const handleIconProps = {
87
- canDrag,
88
- hasMergedCells,
89
- direction,
90
- isDragMenuOpen,
91
- isRowHandleHovered,
75
+ forceDefaultHandle,
92
76
  isColumnHandleHovered,
93
- isCurrentRowSelected,
94
- isCurrentColumnSelected,
95
- dragMenuDirection,
77
+ isRowHandleHovered,
78
+ hasMergedCells,
96
79
  };
97
80
 
98
81
  useEffect(() => {
@@ -1,3 +1,4 @@
1
+ /* eslint-disable @atlaskit/design-system/prefer-primitives */
1
2
  import type { MouseEvent } from 'react';
2
3
  import React, { useCallback, useMemo } from 'react';
3
4
 
@@ -14,7 +15,7 @@ import {
14
15
  selectColumn,
15
16
  } from '../../../commands';
16
17
  import { toggleDragMenu } from '../../../pm-plugins/drag-and-drop/commands';
17
- import type { CellHoverMeta } from '../../../types';
18
+ import type { CellHoverMeta, HandleTypes } from '../../../types';
18
19
  import { TableCssClassName as ClassName } from '../../../types';
19
20
  import { getRowsParams, getSelectedColumnIndexes } from '../../../utils';
20
21
  import { DragHandle } from '../../DragHandle';
@@ -69,14 +70,6 @@ export const ColumnControls = ({
69
70
  const colIndex = hoveredCell?.colIndex;
70
71
  const selectedColIndexes = getSelectedColumns(editorView.state.selection);
71
72
 
72
- const gridColumnPosition = useMemo(() => {
73
- // if more than one row is selected, ensure the handle spans over the selected range
74
- if (selectedColIndexes.includes(colIndex!)) {
75
- return `${selectedColIndexes[0] + 1} / span ${selectedColIndexes.length}`;
76
- }
77
- return `${colIndex! + 1} / span 1`;
78
- }, [colIndex, selectedColIndexes]);
79
-
80
73
  const firstRow = tableRef.querySelector('tr');
81
74
  const hasHeaderRow = firstRow
82
75
  ? firstRow.getAttribute('data-header-row')
@@ -143,6 +136,114 @@ export const ColumnControls = ({
143
136
 
144
137
  const previewHeight = rowHeights?.reduce((sum, cur) => sum + cur, 0) ?? 0;
145
138
 
139
+ const generateHandleByType = (type: HandleTypes): JSX.Element | null => {
140
+ if (!hoveredCell || !colWidths?.length) {
141
+ return null;
142
+ }
143
+ const isHover = type === 'hover';
144
+
145
+ const isColumnsSelected = selectedColIndexes.length > 0;
146
+
147
+ const showCondition = isHover
148
+ ? isColumnsSelected &&
149
+ !selectedColIndexes.includes(colIndex!) &&
150
+ Number.isFinite(hoveredCell?.colIndex)
151
+ : selectedColIndexes.length < colWidths?.length &&
152
+ Number.isFinite(hoveredCell?.colIndex);
153
+
154
+ if (!showCondition) {
155
+ return null;
156
+ }
157
+
158
+ const gridColumnPosition = `${colIndex! + 1} / span 1`;
159
+ const selectedColumnPosition = `${selectedColIndexes[0] + 1} / span ${
160
+ selectedColIndexes.length
161
+ }`;
162
+
163
+ const hoveredAppearance = selectedColIndexes.includes(colIndex!)
164
+ ? isInDanger
165
+ ? 'danger'
166
+ : 'selected'
167
+ : 'default';
168
+
169
+ const currentSelectionApprearance = isColumnsSelected
170
+ ? isInDanger
171
+ ? 'danger'
172
+ : 'selected'
173
+ : hoveredAppearance;
174
+
175
+ const istSelecting = isColumnsSelected && !isHover;
176
+
177
+ // this indexes are used to calculate the drag and drop source
178
+ const indexes = isColumnsSelected
179
+ ? isHover
180
+ ? colIndexes
181
+ : selectedColIndexes
182
+ : colIndexes;
183
+
184
+ return (
185
+ showCondition && (
186
+ <div
187
+ key={type}
188
+ style={{
189
+ gridColumn: istSelecting
190
+ ? selectedColumnPosition
191
+ : gridColumnPosition,
192
+ display: 'flex',
193
+ justifyContent: 'center',
194
+ alignItems: 'center',
195
+ height: 'fit-content',
196
+ placeSelf: 'center',
197
+ zIndex: 99,
198
+ }}
199
+ data-column-control-index={hoveredCell.colIndex}
200
+ data-testid={
201
+ isHover
202
+ ? 'table-floating-column-control-hover'
203
+ : 'table-floating-column-control'
204
+ }
205
+ >
206
+ <DragHandle
207
+ direction="column"
208
+ tableLocalId={localId || ''}
209
+ indexes={indexes}
210
+ forceDefaultHandle={isHover ? false : isColumnsSelected}
211
+ previewWidth={colWidths?.[colIndex!] ?? tableCellMinWidth}
212
+ previewHeight={previewHeight}
213
+ appearance={
214
+ istSelecting ? currentSelectionApprearance : hoveredAppearance
215
+ }
216
+ onClick={handleClick}
217
+ onMouseOver={handleMouseOver}
218
+ onMouseOut={handleMouseOut}
219
+ onMouseUp={handleMouseUp}
220
+ editorView={editorView}
221
+ canDrag={canDrag}
222
+ />
223
+ </div>
224
+ )
225
+ );
226
+ };
227
+
228
+ const columnHandles = (hoveredCell: CellHoverMeta | undefined) => {
229
+ if (!hoveredCell) {
230
+ return null;
231
+ }
232
+
233
+ if (hoveredCell.colIndex === undefined) {
234
+ return generateHandleByType('selected');
235
+ }
236
+
237
+ const sortedHandles = [
238
+ generateHandleByType('hover'),
239
+ generateHandleByType('selected'),
240
+ ];
241
+
242
+ return hoveredCell.colIndex < selectedColIndexes[0]
243
+ ? sortedHandles
244
+ : sortedHandles.reverse();
245
+ };
246
+
146
247
  return (
147
248
  <div
148
249
  className={ClassName.DRAG_COLUMN_CONTROLS}
@@ -185,45 +286,9 @@ export const ColumnControls = ({
185
286
  </div>
186
287
  ))}
187
288
  {tableActive &&
188
- !isResizing &&
189
289
  isTableHovered &&
190
- !!hoveredCell &&
191
- Number.isFinite(hoveredCell.colIndex) && (
192
- <div
193
- style={{
194
- gridColumn: gridColumnPosition,
195
- display: 'flex',
196
- justifyContent: 'center',
197
- alignItems: 'center',
198
- height: 'fit-content',
199
- placeSelf: 'center',
200
- zIndex: 99,
201
- }}
202
- data-column-control-index={hoveredCell.colIndex}
203
- data-testid="table-floating-column-control"
204
- >
205
- <DragHandle
206
- direction="column"
207
- tableLocalId={localId || ''}
208
- indexes={colIndexes}
209
- previewWidth={colWidths?.[colIndex!] ?? tableCellMinWidth}
210
- previewHeight={previewHeight}
211
- appearance={
212
- selectedColIndexes.includes(hoveredCell.colIndex!)
213
- ? isInDanger
214
- ? 'danger'
215
- : 'selected'
216
- : 'default'
217
- }
218
- onClick={handleClick}
219
- onMouseOver={handleMouseOver}
220
- onMouseOut={handleMouseOut}
221
- onMouseUp={handleMouseUp}
222
- editorView={editorView}
223
- canDrag={canDrag}
224
- />
225
- </div>
226
- )}
290
+ !isResizing &&
291
+ columnHandles(hoveredCell)}
227
292
  </div>
228
293
  </div>
229
294
  );
@@ -81,9 +81,9 @@ export default class NumberColumn extends Component<Props, any> {
81
81
  );
82
82
  }
83
83
 
84
- private hoverRows = (index: number) =>
85
- this.props.tableActive ? this.props.hoverRows([index]) : null;
86
-
84
+ private hoverRows = (index: number) => {
85
+ return this.props.tableActive ? this.props.hoverRows([index]) : null;
86
+ };
87
87
  private selectRow = (
88
88
  index: number,
89
89
  event: React.MouseEvent<HTMLDivElement, MouseEvent>,
@@ -1,3 +1,4 @@
1
+ /* eslint-disable @atlaskit/design-system/prefer-primitives */
1
2
  import type { MouseEvent } from 'react';
2
3
  import React, {
3
4
  Fragment,
@@ -22,7 +23,11 @@ import { clearHoverSelection } from '../../../commands';
22
23
  import { toggleDragMenu } from '../../../pm-plugins/drag-and-drop/commands';
23
24
  import { getPluginState as getTablePluginState } from '../../../pm-plugins/plugin-factory';
24
25
  import { TableCssClassName as ClassName } from '../../../types';
25
- import type { CellHoverMeta, DraggableSourceData } from '../../../types';
26
+ import type {
27
+ CellHoverMeta,
28
+ DraggableSourceData,
29
+ HandleTypes,
30
+ } from '../../../types';
26
31
  import {
27
32
  getRowHeights,
28
33
  getRowsParams,
@@ -116,14 +121,6 @@ const DragControlsComponent = ({
116
121
 
117
122
  const rowIndex = hoveredCell?.rowIndex;
118
123
 
119
- const gridRowPosition = useMemo(() => {
120
- // if more than one row is selected, ensure the handle spans over the selected range
121
- if (selectedRowIndexes.includes(rowIndex!)) {
122
- return `${selectedRowIndexes[0] + 1} / span ${selectedRowIndexes.length}`;
123
- }
124
- return `${rowIndex! + 1} / span 1`;
125
- }, [rowIndex, selectedRowIndexes]);
126
-
127
124
  const handleMouseOut = useCallback(() => {
128
125
  if (tableActive) {
129
126
  const { state, dispatch } = editorView;
@@ -165,6 +162,111 @@ const DragControlsComponent = ({
165
162
  [rowIndex, selectRow],
166
163
  );
167
164
 
165
+ const generateHandleByType = (type: HandleTypes): JSX.Element | null => {
166
+ if (!hoveredCell) {
167
+ return null;
168
+ }
169
+ const isHover = type === 'hover';
170
+
171
+ const isRowsSelected = selectedRowIndexes.length > 0;
172
+
173
+ const showCondition = isHover
174
+ ? isRowsSelected &&
175
+ !selectedRowIndexes.includes(rowIndex!) &&
176
+ Number.isFinite(hoveredCell?.colIndex)
177
+ : selectedRowIndexes.length < rowHeights.length &&
178
+ Number.isFinite(hoveredCell?.colIndex);
179
+
180
+ if (!showCondition) {
181
+ return null;
182
+ }
183
+
184
+ const gridRowPosition = `${rowIndex! + 1} / span 1`;
185
+
186
+ // if more than one row is selected, ensure the handle spans over the selected range
187
+ const selectedRowPosition = `${selectedRowIndexes[0] + 1} / span ${
188
+ selectedRowIndexes.length
189
+ }`;
190
+
191
+ const hoveredAppearance = selectedRowIndexes.includes(rowIndex!)
192
+ ? isInDanger
193
+ ? 'danger'
194
+ : 'selected'
195
+ : 'default';
196
+
197
+ const currentSelectionAppearance = isRowsSelected
198
+ ? isInDanger
199
+ ? 'danger'
200
+ : 'selected'
201
+ : hoveredAppearance;
202
+
203
+ const isSelecting = isRowsSelected && !isHover;
204
+
205
+ const indexes = isRowsSelected
206
+ ? isHover
207
+ ? rowIndexes
208
+ : selectedRowIndexes
209
+ : rowIndexes;
210
+
211
+ return (
212
+ showCondition && (
213
+ <div
214
+ key={type}
215
+ style={{
216
+ gridRow: isSelecting ? selectedRowPosition : gridRowPosition,
217
+ gridColumn: '2',
218
+ // DragHandle uses `transform: rotate(90)`, which doesn't affect its parent (this div) causing the width of this element to be the true height of the drag handle
219
+ width: '9px',
220
+ position: 'relative',
221
+ right: '-0.5px',
222
+ }}
223
+ data-testid={
224
+ isHover
225
+ ? 'table-floating-row-drag-handle-hover'
226
+ : 'table-floating-row-drag-handle'
227
+ }
228
+ >
229
+ <DragHandle
230
+ direction="row"
231
+ tableLocalId={currentNodeLocalId}
232
+ indexes={indexes}
233
+ forceDefaultHandle={isHover ? false : isRowsSelected}
234
+ previewWidth={tableWidth}
235
+ previewHeight={rowHeights[rowIndex!]}
236
+ appearance={
237
+ isSelecting ? currentSelectionAppearance : hoveredAppearance
238
+ }
239
+ onClick={handleClick}
240
+ onMouseOver={handleMouseOver}
241
+ onMouseOut={handleMouseOut}
242
+ onMouseUp={onMouseUp}
243
+ editorView={editorView}
244
+ canDrag={canDrag}
245
+ />
246
+ </div>
247
+ )
248
+ );
249
+ };
250
+
251
+ const rowHandles = (hoveredCell: CellHoverMeta | undefined) => {
252
+ if (!hoveredCell) {
253
+ return null;
254
+ }
255
+
256
+ if (hoveredCell.rowIndex === undefined) {
257
+ return generateHandleByType('selected');
258
+ }
259
+
260
+ const sortedHandles = [
261
+ generateHandleByType('hover'),
262
+ generateHandleByType('selected'),
263
+ ];
264
+
265
+ return hoveredCell.rowIndex < selectedRowIndexes[0]
266
+ ? sortedHandles
267
+ : sortedHandles.reverse();
268
+ };
269
+
168
270
  return (
169
271
  <div
170
272
  className={ClassName.DRAG_ROW_CONTROLS}
@@ -221,39 +323,11 @@ const DragControlsComponent = ({
221
323
  )}
222
324
  </Fragment>
223
325
  ))}
224
- {!isResizing && isTableHovered && Number.isFinite(rowIndex) && (
225
- <div
226
- style={{
227
- gridRow: gridRowPosition,
228
- gridColumn: '2',
229
- // DragHandle uses `transform: rotate(90)`, which doesn't affect its parent (this div) causing the width of this element to be the true height of the drag handle
230
- width: '9px',
231
- position: 'relative',
232
- right: '-0.5px',
233
- }}
234
- data-testid="table-floating-row-drag-handle"
235
- >
236
- <DragHandle
237
- tableLocalId={currentNodeLocalId}
238
- indexes={rowIndexes}
239
- previewWidth={tableWidth}
240
- previewHeight={rowHeights[rowIndex!]}
241
- appearance={
242
- selectedRowIndexes.includes(rowIndex!)
243
- ? isInDanger
244
- ? 'danger'
245
- : 'selected'
246
- : 'default'
247
- }
248
- onClick={handleClick}
249
- onMouseOver={handleMouseOver}
250
- onMouseOut={handleMouseOut}
251
- onMouseUp={onMouseUp}
252
- editorView={editorView}
253
- canDrag={canDrag}
254
- />
255
- </div>
256
- )}
326
+ {tableActive &&
327
+ isTableHovered &&
328
+ !isResizing &&
329
+ Number.isFinite(rowIndex) &&
330
+ rowHandles(hoveredCell)}
257
331
  </div>
258
332
  );
259
333
  };
@@ -717,9 +717,10 @@ export const tableStyles = (
717
717
  z-index: ${akEditorUnitZIndex};
718
718
 
719
719
  .${ClassName.DRAG_ROW_FLOATING_INSERT_DOT_WRAPPER} {
720
- position: relative;
720
+ position: absolute;
721
721
  align-self: end;
722
722
  height: 100%;
723
+ width: 18px;
723
724
  }
724
725
 
725
726
  .${ClassName.DRAG_ROW_FLOATING_INSERT_DOT} {