@atlaskit/editor-plugin-table 5.5.2 → 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 (39) hide show
  1. package/CHANGELOG.md +7 -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/es2019/plugins/table/index.js +1 -1
  10. package/dist/es2019/plugins/table/nodeviews/TableComponent.js +25 -29
  11. package/dist/es2019/plugins/table/pm-plugins/table-resizing/event-handlers.js +5 -7
  12. package/dist/es2019/plugins/table/ui/DragHandle/HandleIconComponent.js +4 -15
  13. package/dist/es2019/plugins/table/ui/DragHandle/index.js +5 -18
  14. package/dist/es2019/plugins/table/ui/TableFloatingColumnControls/ColumnControls/index.js +62 -34
  15. package/dist/es2019/plugins/table/ui/TableFloatingControls/NumberColumn/index.js +3 -1
  16. package/dist/es2019/plugins/table/ui/TableFloatingControls/RowControls/DragControls.js +58 -30
  17. package/dist/esm/plugins/table/index.js +1 -1
  18. package/dist/esm/plugins/table/nodeviews/TableComponent.js +22 -26
  19. package/dist/esm/plugins/table/pm-plugins/table-resizing/event-handlers.js +5 -7
  20. package/dist/esm/plugins/table/ui/DragHandle/HandleIconComponent.js +4 -15
  21. package/dist/esm/plugins/table/ui/DragHandle/index.js +6 -17
  22. package/dist/esm/plugins/table/ui/TableFloatingColumnControls/ColumnControls/index.js +62 -34
  23. package/dist/esm/plugins/table/ui/TableFloatingControls/RowControls/DragControls.js +58 -30
  24. package/dist/types/plugins/table/types.d.ts +1 -0
  25. package/dist/types/plugins/table/ui/DragHandle/HandleIconComponent.d.ts +2 -7
  26. package/dist/types/plugins/table/ui/DragHandle/index.d.ts +2 -1
  27. package/dist/types-ts4.5/plugins/table/types.d.ts +1 -0
  28. package/dist/types-ts4.5/plugins/table/ui/DragHandle/HandleIconComponent.d.ts +2 -7
  29. package/dist/types-ts4.5/plugins/table/ui/DragHandle/index.d.ts +2 -1
  30. package/package.json +1 -4
  31. package/src/plugins/table/index.tsx +5 -7
  32. package/src/plugins/table/nodeviews/TableComponent.tsx +31 -38
  33. package/src/plugins/table/pm-plugins/table-resizing/event-handlers.ts +5 -7
  34. package/src/plugins/table/types.ts +2 -0
  35. package/src/plugins/table/ui/DragHandle/HandleIconComponent.tsx +5 -30
  36. package/src/plugins/table/ui/DragHandle/index.tsx +6 -23
  37. package/src/plugins/table/ui/TableFloatingColumnControls/ColumnControls/index.tsx +112 -47
  38. package/src/plugins/table/ui/TableFloatingControls/NumberColumn/index.tsx +3 -3
  39. package/src/plugins/table/ui/TableFloatingControls/RowControls/DragControls.tsx +116 -42
@@ -1,4 +1,6 @@
1
1
  import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
2
+ /* eslint-disable @atlaskit/design-system/prefer-primitives */
3
+
2
4
  import React, { Fragment, useCallback, useEffect, useMemo, useState } from 'react';
3
5
  import { injectIntl } from 'react-intl-next';
4
6
  import { CellSelection } from '@atlaskit/editor-tables';
@@ -77,13 +79,6 @@ var DragControlsComponent = function DragControlsComponent(_ref) {
77
79
  toggleDragMenu(undefined, 'row', hoveredCell === null || hoveredCell === void 0 ? void 0 : hoveredCell.rowIndex)(editorView.state, editorView.dispatch);
78
80
  }, [editorView, hoveredCell === null || hoveredCell === void 0 ? void 0 : hoveredCell.rowIndex]);
79
81
  var rowIndex = hoveredCell === null || hoveredCell === void 0 ? void 0 : hoveredCell.rowIndex;
80
- var gridRowPosition = useMemo(function () {
81
- // if more than one row is selected, ensure the handle spans over the selected range
82
- if (selectedRowIndexes.includes(rowIndex)) {
83
- return "".concat(selectedRowIndexes[0] + 1, " / span ").concat(selectedRowIndexes.length);
84
- }
85
- return "".concat(rowIndex + 1, " / span 1");
86
- }, [rowIndex, selectedRowIndexes]);
87
82
  var handleMouseOut = useCallback(function () {
88
83
  if (tableActive) {
89
84
  var state = editorView.state,
@@ -110,6 +105,61 @@ var DragControlsComponent = function DragControlsComponent(_ref) {
110
105
  var handleClick = useCallback(function (e) {
111
106
  selectRow(rowIndex, e === null || e === void 0 ? void 0 : e.shiftKey);
112
107
  }, [rowIndex, selectRow]);
108
+ var generateHandleByType = function generateHandleByType(type) {
109
+ if (!hoveredCell) {
110
+ return null;
111
+ }
112
+ var isHover = type === 'hover';
113
+ var isRowsSelected = selectedRowIndexes.length > 0;
114
+ var showCondition = isHover ? isRowsSelected && !selectedRowIndexes.includes(rowIndex) && Number.isFinite(hoveredCell === null || hoveredCell === void 0 ? void 0 : hoveredCell.colIndex) : selectedRowIndexes.length < rowHeights.length && Number.isFinite(hoveredCell === null || hoveredCell === void 0 ? void 0 : hoveredCell.colIndex);
115
+ if (!showCondition) {
116
+ return null;
117
+ }
118
+ var gridRowPosition = "".concat(rowIndex + 1, " / span 1");
119
+
120
+ // if more than one row is selected, ensure the handle spans over the selected range
121
+ var selectedRowPosition = "".concat(selectedRowIndexes[0] + 1, " / span ").concat(selectedRowIndexes.length);
122
+ var hoveredAppearance = selectedRowIndexes.includes(rowIndex) ? isInDanger ? 'danger' : 'selected' : 'default';
123
+ var currentSelectionAppearance = isRowsSelected ? isInDanger ? 'danger' : 'selected' : hoveredAppearance;
124
+ var isSelecting = isRowsSelected && !isHover;
125
+ var indexes = isRowsSelected ? isHover ? rowIndexes : selectedRowIndexes : rowIndexes;
126
+ return showCondition && /*#__PURE__*/React.createElement("div", {
127
+ key: type,
128
+ style: {
129
+ gridRow: isSelecting ? selectedRowPosition : gridRowPosition,
130
+ gridColumn: '2',
131
+ // 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
132
+ width: '9px',
133
+ position: 'relative',
134
+ right: '-0.5px'
135
+ },
136
+ "data-testid": isHover ? 'table-floating-row-drag-handle-hover' : 'table-floating-row-drag-handle'
137
+ }, /*#__PURE__*/React.createElement(DragHandle, {
138
+ direction: "row",
139
+ tableLocalId: currentNodeLocalId,
140
+ indexes: indexes,
141
+ forceDefaultHandle: isHover ? false : isRowsSelected,
142
+ previewWidth: tableWidth,
143
+ previewHeight: rowHeights[rowIndex],
144
+ appearance: isSelecting ? currentSelectionAppearance : hoveredAppearance,
145
+ onClick: handleClick,
146
+ onMouseOver: handleMouseOver,
147
+ onMouseOut: handleMouseOut,
148
+ onMouseUp: onMouseUp,
149
+ editorView: editorView,
150
+ canDrag: canDrag
151
+ }));
152
+ };
153
+ var rowHandles = function rowHandles(hoveredCell) {
154
+ if (!hoveredCell) {
155
+ return null;
156
+ }
157
+ if (hoveredCell.rowIndex === undefined) {
158
+ return generateHandleByType('selected');
159
+ }
160
+ var sortedHandles = [generateHandleByType('hover'), generateHandleByType('selected')];
161
+ return hoveredCell.rowIndex < selectedRowIndexes[0] ? sortedHandles : sortedHandles.reverse();
162
+ };
113
163
  return /*#__PURE__*/React.createElement("div", {
114
164
  className: ClassName.DRAG_ROW_CONTROLS,
115
165
  style: {
@@ -149,28 +199,6 @@ var DragControlsComponent = function DragControlsComponent(_ref) {
149
199
  left: "var(--ds-space-negative-100, -8px)"
150
200
  }
151
201
  }));
152
- }), !isResizing && isTableHovered && Number.isFinite(rowIndex) && /*#__PURE__*/React.createElement("div", {
153
- style: {
154
- gridRow: gridRowPosition,
155
- gridColumn: '2',
156
- // 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
157
- width: '9px',
158
- position: 'relative',
159
- right: '-0.5px'
160
- },
161
- "data-testid": "table-floating-row-drag-handle"
162
- }, /*#__PURE__*/React.createElement(DragHandle, {
163
- tableLocalId: currentNodeLocalId,
164
- indexes: rowIndexes,
165
- previewWidth: tableWidth,
166
- previewHeight: rowHeights[rowIndex],
167
- appearance: selectedRowIndexes.includes(rowIndex) ? isInDanger ? 'danger' : 'selected' : 'default',
168
- onClick: handleClick,
169
- onMouseOver: handleMouseOver,
170
- onMouseOut: handleMouseOut,
171
- onMouseUp: onMouseUp,
172
- editorView: editorView,
173
- canDrag: canDrag
174
- })));
202
+ }), tableActive && isTableHovered && !isResizing && Number.isFinite(rowIndex) && rowHandles(hoveredCell));
175
203
  };
176
204
  export var DragControls = injectIntl(DragControlsComponent);
@@ -421,3 +421,4 @@ export interface DraggableData {
421
421
  targetClosestEdge: Edge;
422
422
  direction: 1 | -1;
423
423
  }
424
+ export type HandleTypes = 'hover' | 'selected';
@@ -1,14 +1,9 @@
1
1
  /// <reference types="react" />
2
2
  type HandleIconProps = {
3
- canDrag: boolean;
4
- hasMergedCells: boolean;
5
- direction: 'row' | 'column';
6
- isDragMenuOpen: boolean | undefined;
3
+ forceDefaultHandle: boolean;
7
4
  isRowHandleHovered: boolean;
8
5
  isColumnHandleHovered: boolean;
9
- isCurrentRowSelected: boolean;
10
- isCurrentColumnSelected: boolean;
11
- dragMenuDirection: 'row' | 'column' | undefined;
6
+ hasMergedCells: boolean;
12
7
  };
13
8
  export declare const HandleIconComponent: (props: HandleIconProps) => JSX.Element;
14
9
  export {};
@@ -5,6 +5,7 @@ type DragHandleAppearance = 'default' | 'selected' | 'disabled' | 'danger';
5
5
  type DragHandleProps = {
6
6
  tableLocalId: string;
7
7
  indexes: number[];
8
+ forceDefaultHandle?: boolean;
8
9
  previewWidth?: number;
9
10
  previewHeight?: number;
10
11
  direction?: TableDirection;
@@ -16,5 +17,5 @@ type DragHandleProps = {
16
17
  editorView: EditorView;
17
18
  canDrag?: boolean;
18
19
  };
19
- export declare const DragHandle: ({ tableLocalId, direction, appearance, indexes, previewWidth, previewHeight, onMouseOver, onMouseOut, onMouseUp, onClick, editorView, canDrag, }: DragHandleProps) => JSX.Element;
20
+ export declare const DragHandle: ({ tableLocalId, direction, appearance, indexes, forceDefaultHandle, previewWidth, previewHeight, onMouseOver, onMouseOut, onMouseUp, onClick, editorView, canDrag, }: DragHandleProps) => JSX.Element;
20
21
  export {};
@@ -421,3 +421,4 @@ export interface DraggableData {
421
421
  targetClosestEdge: Edge;
422
422
  direction: 1 | -1;
423
423
  }
424
+ export type HandleTypes = 'hover' | 'selected';
@@ -1,14 +1,9 @@
1
1
  /// <reference types="react" />
2
2
  type HandleIconProps = {
3
- canDrag: boolean;
4
- hasMergedCells: boolean;
5
- direction: 'row' | 'column';
6
- isDragMenuOpen: boolean | undefined;
3
+ forceDefaultHandle: boolean;
7
4
  isRowHandleHovered: boolean;
8
5
  isColumnHandleHovered: boolean;
9
- isCurrentRowSelected: boolean;
10
- isCurrentColumnSelected: boolean;
11
- dragMenuDirection: 'row' | 'column' | undefined;
6
+ hasMergedCells: boolean;
12
7
  };
13
8
  export declare const HandleIconComponent: (props: HandleIconProps) => JSX.Element;
14
9
  export {};
@@ -5,6 +5,7 @@ type DragHandleAppearance = 'default' | 'selected' | 'disabled' | 'danger';
5
5
  type DragHandleProps = {
6
6
  tableLocalId: string;
7
7
  indexes: number[];
8
+ forceDefaultHandle?: boolean;
8
9
  previewWidth?: number;
9
10
  previewHeight?: number;
10
11
  direction?: TableDirection;
@@ -16,5 +17,5 @@ type DragHandleProps = {
16
17
  editorView: EditorView;
17
18
  canDrag?: boolean;
18
19
  };
19
- export declare const DragHandle: ({ tableLocalId, direction, appearance, indexes, previewWidth, previewHeight, onMouseOver, onMouseOut, onMouseUp, onClick, editorView, canDrag, }: DragHandleProps) => JSX.Element;
20
+ export declare const DragHandle: ({ tableLocalId, direction, appearance, indexes, forceDefaultHandle, previewWidth, previewHeight, onMouseOver, onMouseOut, onMouseUp, onClick, editorView, canDrag, }: DragHandleProps) => JSX.Element;
20
21
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-table",
3
- "version": "5.5.2",
3
+ "version": "5.5.3",
4
4
  "description": "Table plugin for the @atlaskit/editor",
5
5
  "publishConfig": {
6
6
  "registry": "https://registry.npmjs.org/"
@@ -121,9 +121,6 @@
121
121
  "platform.editor.table-remove-update-resize-handles_djvab": {
122
122
  "type": "boolean"
123
123
  },
124
- "platform.editor.table.overflow-state-analytics": {
125
- "type": "boolean"
126
- },
127
124
  "platform.editor.table.increase-shadow-visibility_lh89r": {
128
125
  "type": "boolean"
129
126
  },
@@ -303,13 +303,11 @@ const tablesPlugin: TablePlugin = ({ config: options, api }) => {
303
303
  {
304
304
  name: 'tableOverflowAnalyticsPlugin',
305
305
  plugin: ({ dispatch, dispatchAnalyticsEvent }) =>
306
- getBooleanFF('platform.editor.table.overflow-state-analytics')
307
- ? createTableOverflowAnalyticsPlugin(
308
- dispatch,
309
- dispatchAnalyticsEvent,
310
- options?.tableResizingEnabled ?? false,
311
- )
312
- : undefined,
306
+ createTableOverflowAnalyticsPlugin(
307
+ dispatch,
308
+ dispatchAnalyticsEvent,
309
+ options?.tableResizingEnabled ?? false,
310
+ ),
313
311
  },
314
312
  {
315
313
  name: 'tableAnalyticsPlugin',
@@ -263,13 +263,11 @@ class TableComponent extends React.Component<ComponentProps, TableState> {
263
263
 
264
264
  eventDispatcher.on((stickyHeadersPluginKey as any).key, this.onStickyState);
265
265
 
266
- if (getBooleanFF('platform.editor.table.overflow-state-analytics')) {
267
- const initialIsOveflowing =
268
- this.state[ShadowEvent.SHOW_BEFORE_SHADOW] ||
269
- this.state[ShadowEvent.SHOW_AFTER_SHADOW];
266
+ const initialIsOveflowing =
267
+ this.state[ShadowEvent.SHOW_BEFORE_SHADOW] ||
268
+ this.state[ShadowEvent.SHOW_AFTER_SHADOW];
270
269
 
271
- this.setTimerToSendInitialOverflowCaptured(initialIsOveflowing);
272
- }
270
+ this.setTimerToSendInitialOverflowCaptured(initialIsOveflowing);
273
271
  }
274
272
 
275
273
  componentWillUnmount() {
@@ -389,42 +387,37 @@ class TableComponent extends React.Component<ComponentProps, TableState> {
389
387
  this.handleTableResizingDebounced();
390
388
  }
391
389
 
392
- if (getBooleanFF('platform.editor.table.overflow-state-analytics')) {
393
- const newIsOverflowing =
394
- this.state[ShadowEvent.SHOW_BEFORE_SHADOW] ||
395
- this.state[ShadowEvent.SHOW_AFTER_SHADOW];
390
+ const newIsOverflowing =
391
+ this.state[ShadowEvent.SHOW_BEFORE_SHADOW] ||
392
+ this.state[ShadowEvent.SHOW_AFTER_SHADOW];
396
393
 
397
- const prevIsOverflowing =
398
- prevState[ShadowEvent.SHOW_BEFORE_SHADOW] ||
399
- prevState[ShadowEvent.SHOW_AFTER_SHADOW];
394
+ const prevIsOverflowing =
395
+ prevState[ShadowEvent.SHOW_BEFORE_SHADOW] ||
396
+ prevState[ShadowEvent.SHOW_AFTER_SHADOW];
400
397
 
401
- if (this.initialOverflowCaptureTimerId) {
402
- clearTimeout(this.initialOverflowCaptureTimerId);
403
- }
398
+ if (this.initialOverflowCaptureTimerId) {
399
+ clearTimeout(this.initialOverflowCaptureTimerId);
400
+ }
404
401
 
405
- if (!this.isInitialOverflowSent) {
406
- this.setTimerToSendInitialOverflowCaptured(newIsOverflowing);
407
- }
402
+ if (!this.isInitialOverflowSent) {
403
+ this.setTimerToSendInitialOverflowCaptured(newIsOverflowing);
404
+ }
408
405
 
409
- if (
410
- this.isInitialOverflowSent &&
411
- prevIsOverflowing !== newIsOverflowing
412
- ) {
413
- const {
414
- dispatch,
415
- state: { tr },
416
- } = this.props.view;
417
-
418
- dispatch(
419
- tr.setMeta(META_KEYS.OVERFLOW_STATE_CHANGED, {
420
- isOverflowing: newIsOverflowing,
421
- wasOverflowing: prevIsOverflowing,
422
- editorWidth: this.props.containerWidth.width || 0,
423
- width: this.node.attrs.width || 0,
424
- parentWidth: this.state?.parentWidth || 0,
425
- }),
426
- );
427
- }
406
+ if (this.isInitialOverflowSent && prevIsOverflowing !== newIsOverflowing) {
407
+ const {
408
+ dispatch,
409
+ state: { tr },
410
+ } = this.props.view;
411
+
412
+ dispatch(
413
+ tr.setMeta(META_KEYS.OVERFLOW_STATE_CHANGED, {
414
+ isOverflowing: newIsOverflowing,
415
+ wasOverflowing: prevIsOverflowing,
416
+ editorWidth: this.props.containerWidth.width || 0,
417
+ width: this.node.attrs.width || 0,
418
+ parentWidth: this.state?.parentWidth || 0,
419
+ }),
420
+ );
428
421
  }
429
422
  }
430
423
 
@@ -55,13 +55,11 @@ export const handleMouseDown = (
55
55
  }
56
56
  event.preventDefault();
57
57
 
58
- if (getBooleanFF('platform.editor.table.overflow-state-analytics')) {
59
- const tr = view.state.tr;
60
- tr.setMeta(META_KEYS.OVERFLOW_TRIGGER, {
61
- name: TABLE_OVERFLOW_CHANGE_TRIGGER.RESIZED_COLUMN,
62
- });
63
- dispatch(tr);
64
- }
58
+ const tr = view.state.tr;
59
+ tr.setMeta(META_KEYS.OVERFLOW_TRIGGER, {
60
+ name: TABLE_OVERFLOW_CHANGE_TRIGGER.RESIZED_COLUMN,
61
+ });
62
+ dispatch(tr);
65
63
 
66
64
  const mouseDownTime = event.timeStamp;
67
65
  const cell = state.doc.nodeAt(localResizeHandlePos);
@@ -463,3 +463,5 @@ export interface DraggableData {
463
463
  targetClosestEdge: Edge;
464
464
  direction: 1 | -1;
465
465
  }
466
+
467
+ export type HandleTypes = 'hover' | 'selected';
@@ -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>,