@atlaskit/editor-plugin-table 5.5.2 → 5.5.4

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 (64) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/cjs/plugins/table/commands/index.js +12 -0
  3. package/dist/cjs/plugins/table/commands/misc.js +61 -1
  4. package/dist/cjs/plugins/table/index.js +1 -1
  5. package/dist/cjs/plugins/table/nodeviews/TableComponent.js +22 -26
  6. package/dist/cjs/plugins/table/pm-plugins/drag-and-drop/plugin.js +1 -0
  7. package/dist/cjs/plugins/table/pm-plugins/table-resizing/event-handlers.js +5 -7
  8. package/dist/cjs/plugins/table/ui/DragHandle/HandleIconComponent.js +4 -15
  9. package/dist/cjs/plugins/table/ui/DragHandle/index.js +8 -19
  10. package/dist/cjs/plugins/table/ui/TableFloatingColumnControls/ColumnControls/index.js +70 -36
  11. package/dist/cjs/plugins/table/ui/TableFloatingControls/RowControls/DragControls.js +67 -32
  12. package/dist/cjs/plugins/table/ui/TableFloatingControls/index.js +11 -0
  13. package/dist/es2019/plugins/table/commands/index.js +1 -1
  14. package/dist/es2019/plugins/table/commands/misc.js +46 -1
  15. package/dist/es2019/plugins/table/index.js +1 -1
  16. package/dist/es2019/plugins/table/nodeviews/TableComponent.js +25 -29
  17. package/dist/es2019/plugins/table/pm-plugins/drag-and-drop/plugin.js +1 -0
  18. package/dist/es2019/plugins/table/pm-plugins/table-resizing/event-handlers.js +5 -7
  19. package/dist/es2019/plugins/table/ui/DragHandle/HandleIconComponent.js +4 -15
  20. package/dist/es2019/plugins/table/ui/DragHandle/index.js +5 -18
  21. package/dist/es2019/plugins/table/ui/TableFloatingColumnControls/ColumnControls/index.js +71 -37
  22. package/dist/es2019/plugins/table/ui/TableFloatingControls/NumberColumn/index.js +3 -1
  23. package/dist/es2019/plugins/table/ui/TableFloatingControls/RowControls/DragControls.js +67 -32
  24. package/dist/es2019/plugins/table/ui/TableFloatingControls/index.js +16 -1
  25. package/dist/esm/plugins/table/commands/index.js +1 -1
  26. package/dist/esm/plugins/table/commands/misc.js +61 -1
  27. package/dist/esm/plugins/table/index.js +1 -1
  28. package/dist/esm/plugins/table/nodeviews/TableComponent.js +22 -26
  29. package/dist/esm/plugins/table/pm-plugins/drag-and-drop/plugin.js +1 -0
  30. package/dist/esm/plugins/table/pm-plugins/table-resizing/event-handlers.js +5 -7
  31. package/dist/esm/plugins/table/ui/DragHandle/HandleIconComponent.js +4 -15
  32. package/dist/esm/plugins/table/ui/DragHandle/index.js +6 -17
  33. package/dist/esm/plugins/table/ui/TableFloatingColumnControls/ColumnControls/index.js +71 -37
  34. package/dist/esm/plugins/table/ui/TableFloatingControls/RowControls/DragControls.js +67 -32
  35. package/dist/esm/plugins/table/ui/TableFloatingControls/index.js +12 -1
  36. package/dist/types/plugins/table/commands/index.d.ts +1 -1
  37. package/dist/types/plugins/table/commands/misc.d.ts +2 -0
  38. package/dist/types/plugins/table/types.d.ts +1 -0
  39. package/dist/types/plugins/table/ui/DragHandle/HandleIconComponent.d.ts +2 -7
  40. package/dist/types/plugins/table/ui/DragHandle/index.d.ts +2 -1
  41. package/dist/types/plugins/table/ui/TableFloatingControls/RowControls/DragControls.d.ts +1 -0
  42. package/dist/types/plugins/table/ui/TableFloatingControls/index.d.ts +1 -0
  43. package/dist/types-ts4.5/plugins/table/commands/index.d.ts +1 -1
  44. package/dist/types-ts4.5/plugins/table/commands/misc.d.ts +2 -0
  45. package/dist/types-ts4.5/plugins/table/types.d.ts +1 -0
  46. package/dist/types-ts4.5/plugins/table/ui/DragHandle/HandleIconComponent.d.ts +2 -7
  47. package/dist/types-ts4.5/plugins/table/ui/DragHandle/index.d.ts +2 -1
  48. package/dist/types-ts4.5/plugins/table/ui/TableFloatingControls/RowControls/DragControls.d.ts +1 -0
  49. package/dist/types-ts4.5/plugins/table/ui/TableFloatingControls/index.d.ts +1 -0
  50. package/package.json +1 -4
  51. package/src/__tests__/unit/ui/RowDragControls.tsx +2 -0
  52. package/src/plugins/table/commands/index.ts +2 -0
  53. package/src/plugins/table/commands/misc.ts +78 -0
  54. package/src/plugins/table/index.tsx +5 -7
  55. package/src/plugins/table/nodeviews/TableComponent.tsx +31 -38
  56. package/src/plugins/table/pm-plugins/drag-and-drop/plugin.ts +2 -0
  57. package/src/plugins/table/pm-plugins/table-resizing/event-handlers.ts +5 -7
  58. package/src/plugins/table/types.ts +2 -0
  59. package/src/plugins/table/ui/DragHandle/HandleIconComponent.tsx +5 -30
  60. package/src/plugins/table/ui/DragHandle/index.tsx +6 -23
  61. package/src/plugins/table/ui/TableFloatingColumnControls/ColumnControls/index.tsx +134 -49
  62. package/src/plugins/table/ui/TableFloatingControls/NumberColumn/index.tsx +3 -3
  63. package/src/plugins/table/ui/TableFloatingControls/RowControls/DragControls.tsx +137 -44
  64. package/src/plugins/table/ui/TableFloatingControls/index.tsx +12 -1
@@ -2,7 +2,7 @@ import { closestElement, isParagraph, isTextSelection, mapSlice } from '@atlaski
2
2
  import { TextSelection } from '@atlaskit/editor-prosemirror/state';
3
3
  import { CellSelection } from '@atlaskit/editor-tables/cell-selection';
4
4
  import { TableMap } from '@atlaskit/editor-tables/table-map';
5
- import { findCellClosestToPos, findTable, getCellsInColumn, getCellsInRow, getSelectionRect, isSelectionType, isTableSelected, removeTable, selectColumn as selectColumnTransform, selectionCell, selectRow as selectRowTransform, setCellAttrs } from '@atlaskit/editor-tables/utils';
5
+ import { findCellClosestToPos, findTable, getCellsInColumn, getCellsInRow, getSelectionRect, isSelectionType, isTableSelected, removeTable, selectColumns as selectColumnsTransform, selectColumn as selectColumnTransform, selectionCell, selectRows as selectRowsTransform, selectRow as selectRowTransform, setCellAttrs } from '@atlaskit/editor-tables/utils';
6
6
  import { getDecorations } from '../pm-plugins/decorations/plugin';
7
7
  import { buildColumnResizingDecorations, clearColumnResizingDecorations } from '../pm-plugins/decorations/utils';
8
8
  import { createCommand, getPluginState } from '../pm-plugins/plugin-factory';
@@ -350,6 +350,31 @@ export const selectColumn = (column, expand) => createCommand(state => {
350
350
  }
351
351
  };
352
352
  }, tr => selectColumnTransform(column, expand)(tr).setMeta('addToHistory', false));
353
+ export const selectColumns = columnIndexes => createCommand(state => {
354
+ if (!columnIndexes) {
355
+ return false;
356
+ }
357
+ const cells = columnIndexes.map(column => getCellsInColumn(column)(state.tr.selection)).flat();
358
+ if (!cells || !cells.length || cells.some(cell => cell && typeof cell.pos !== 'number')) {
359
+ return false;
360
+ }
361
+ const decorations = createColumnSelectedDecoration(selectColumnsTransform(columnIndexes)(state.tr));
362
+ const decorationSet = updatePluginStateDecorations(state, decorations, TableDecorations.COLUMN_SELECTED);
363
+ const cellsInFirstColumn = getCellsInColumn(Math.min(...columnIndexes))(state.tr.selection);
364
+ if (!cellsInFirstColumn || cellsInFirstColumn.length === 0) {
365
+ return false;
366
+ }
367
+ const targetCellPosition = cellsInFirstColumn[0].pos;
368
+ return {
369
+ type: 'SELECT_COLUMN',
370
+ data: {
371
+ targetCellPosition,
372
+ decorationSet
373
+ }
374
+ };
375
+ }, tr => {
376
+ return selectColumnsTransform(columnIndexes)(tr).setMeta('addToHistory', false);
377
+ });
353
378
  export const selectRow = (row, expand) => createCommand(state => {
354
379
  let targetCellPosition;
355
380
  const cells = getCellsInRow(row)(state.tr.selection);
@@ -363,6 +388,26 @@ export const selectRow = (row, expand) => createCommand(state => {
363
388
  }
364
389
  };
365
390
  }, tr => selectRowTransform(row, expand)(tr).setMeta('addToHistory', false));
391
+ export const selectRows = rowIndexes => createCommand(state => {
392
+ if (rowIndexes.length === 0) {
393
+ return false;
394
+ }
395
+ const cells = rowIndexes.map(row => getCellsInRow(row)(state.tr.selection)).flat();
396
+ if (!cells || !cells.length || cells.some(cell => cell && typeof cell.pos !== 'number')) {
397
+ return false;
398
+ }
399
+ const cellsInFirstRow = getCellsInRow(Math.min(...rowIndexes))(state.tr.selection);
400
+ if (!cellsInFirstRow || cellsInFirstRow.length === 0) {
401
+ return false;
402
+ }
403
+ const targetCellPosition = cellsInFirstRow[0].pos;
404
+ return {
405
+ type: 'SET_TARGET_CELL_POSITION',
406
+ data: {
407
+ targetCellPosition
408
+ }
409
+ };
410
+ }, tr => selectRowsTransform(rowIndexes)(tr).setMeta('addToHistory', false));
366
411
  export const showInsertColumnButton = columnIndex => createCommand(_ => columnIndex > -1 ? {
367
412
  type: 'SHOW_INSERT_COLUMN_BUTTON',
368
413
  data: {
@@ -199,7 +199,7 @@ const tablesPlugin = ({
199
199
  dispatchAnalyticsEvent
200
200
  }) => {
201
201
  var _options$tableResizin;
202
- return getBooleanFF('platform.editor.table.overflow-state-analytics') ? createTableOverflowAnalyticsPlugin(dispatch, dispatchAnalyticsEvent, (_options$tableResizin = options === null || options === void 0 ? void 0 : options.tableResizingEnabled) !== null && _options$tableResizin !== void 0 ? _options$tableResizin : false) : undefined;
202
+ return createTableOverflowAnalyticsPlugin(dispatch, dispatchAnalyticsEvent, (_options$tableResizin = options === null || options === void 0 ? void 0 : options.tableResizingEnabled) !== null && _options$tableResizin !== void 0 ? _options$tableResizin : false);
203
203
  }
204
204
  }, {
205
205
  name: 'tableAnalyticsPlugin',
@@ -395,10 +395,8 @@ class TableComponent extends React.Component {
395
395
  this.onStickyState(currentStickyState);
396
396
  }
397
397
  eventDispatcher.on(stickyHeadersPluginKey.key, this.onStickyState);
398
- if (getBooleanFF('platform.editor.table.overflow-state-analytics')) {
399
- const initialIsOveflowing = this.state[ShadowEvent.SHOW_BEFORE_SHADOW] || this.state[ShadowEvent.SHOW_AFTER_SHADOW];
400
- this.setTimerToSendInitialOverflowCaptured(initialIsOveflowing);
401
- }
398
+ const initialIsOveflowing = this.state[ShadowEvent.SHOW_BEFORE_SHADOW] || this.state[ShadowEvent.SHOW_AFTER_SHADOW];
399
+ this.setTimerToSendInitialOverflowCaptured(initialIsOveflowing);
402
400
  }
403
401
  componentWillUnmount() {
404
402
  const {
@@ -487,31 +485,29 @@ class TableComponent extends React.Component {
487
485
  }
488
486
  this.handleTableResizingDebounced();
489
487
  }
490
- if (getBooleanFF('platform.editor.table.overflow-state-analytics')) {
491
- const newIsOverflowing = this.state[ShadowEvent.SHOW_BEFORE_SHADOW] || this.state[ShadowEvent.SHOW_AFTER_SHADOW];
492
- const prevIsOverflowing = prevState[ShadowEvent.SHOW_BEFORE_SHADOW] || prevState[ShadowEvent.SHOW_AFTER_SHADOW];
493
- if (this.initialOverflowCaptureTimerId) {
494
- clearTimeout(this.initialOverflowCaptureTimerId);
495
- }
496
- if (!this.isInitialOverflowSent) {
497
- this.setTimerToSendInitialOverflowCaptured(newIsOverflowing);
498
- }
499
- if (this.isInitialOverflowSent && prevIsOverflowing !== newIsOverflowing) {
500
- var _this$state2;
501
- const {
502
- dispatch,
503
- state: {
504
- tr
505
- }
506
- } = this.props.view;
507
- dispatch(tr.setMeta(META_KEYS.OVERFLOW_STATE_CHANGED, {
508
- isOverflowing: newIsOverflowing,
509
- wasOverflowing: prevIsOverflowing,
510
- editorWidth: this.props.containerWidth.width || 0,
511
- width: this.node.attrs.width || 0,
512
- parentWidth: ((_this$state2 = this.state) === null || _this$state2 === void 0 ? void 0 : _this$state2.parentWidth) || 0
513
- }));
514
- }
488
+ const newIsOverflowing = this.state[ShadowEvent.SHOW_BEFORE_SHADOW] || this.state[ShadowEvent.SHOW_AFTER_SHADOW];
489
+ const prevIsOverflowing = prevState[ShadowEvent.SHOW_BEFORE_SHADOW] || prevState[ShadowEvent.SHOW_AFTER_SHADOW];
490
+ if (this.initialOverflowCaptureTimerId) {
491
+ clearTimeout(this.initialOverflowCaptureTimerId);
492
+ }
493
+ if (!this.isInitialOverflowSent) {
494
+ this.setTimerToSendInitialOverflowCaptured(newIsOverflowing);
495
+ }
496
+ if (this.isInitialOverflowSent && prevIsOverflowing !== newIsOverflowing) {
497
+ var _this$state2;
498
+ const {
499
+ dispatch,
500
+ state: {
501
+ tr
502
+ }
503
+ } = this.props.view;
504
+ dispatch(tr.setMeta(META_KEYS.OVERFLOW_STATE_CHANGED, {
505
+ isOverflowing: newIsOverflowing,
506
+ wasOverflowing: prevIsOverflowing,
507
+ editorWidth: this.props.containerWidth.width || 0,
508
+ width: this.node.attrs.width || 0,
509
+ parentWidth: ((_this$state2 = this.state) === null || _this$state2 === void 0 ? void 0 : _this$state2.parentWidth) || 0
510
+ }));
515
511
  }
516
512
  }
517
513
  render() {
@@ -192,6 +192,7 @@ export const createPlugin = (dispatch, eventDispatcher) => {
192
192
  const [sourceIndex] = sourceIndexes;
193
193
  requestAnimationFrame(() => {
194
194
  moveSource(sourceType, sourceIndex, targetAdjustedIndex + (direction === -1 ? 0 : -1), tr)(editorView.state, editorView.dispatch);
195
+ editorView.focus();
195
196
  });
196
197
  }
197
198
  })
@@ -23,13 +23,11 @@ export const handleMouseDown = (view, event, localResizeHandlePos, getEditorCont
23
23
  return false;
24
24
  }
25
25
  event.preventDefault();
26
- if (getBooleanFF('platform.editor.table.overflow-state-analytics')) {
27
- const tr = view.state.tr;
28
- tr.setMeta(META_KEYS.OVERFLOW_TRIGGER, {
29
- name: TABLE_OVERFLOW_CHANGE_TRIGGER.RESIZED_COLUMN
30
- });
31
- dispatch(tr);
32
- }
26
+ const tr = view.state.tr;
27
+ tr.setMeta(META_KEYS.OVERFLOW_TRIGGER, {
28
+ name: TABLE_OVERFLOW_CHANGE_TRIGGER.RESIZED_COLUMN
29
+ });
30
+ dispatch(tr);
33
31
  const mouseDownTime = event.timeStamp;
34
32
  const cell = state.doc.nodeAt(localResizeHandlePos);
35
33
  const $cell = state.doc.resolve(localResizeHandlePos);
@@ -2,25 +2,14 @@ import React from 'react';
2
2
  import { DragHandleDisabledIcon, DragHandleIcon, MinimisedHandleIcon } from '../icons';
3
3
  export const HandleIconComponent = props => {
4
4
  const {
5
- canDrag,
6
- direction,
7
- isDragMenuOpen,
5
+ forceDefaultHandle,
8
6
  isRowHandleHovered,
9
7
  isColumnHandleHovered,
10
- hasMergedCells,
11
- isCurrentRowSelected,
12
- isCurrentColumnSelected,
13
- dragMenuDirection
8
+ hasMergedCells
14
9
  } = props;
15
10
  const isHandleHovered = isRowHandleHovered || isColumnHandleHovered;
16
- const isCurrentRowOrColumnSelected = isCurrentRowSelected || isCurrentColumnSelected;
17
- const isDragMenuOpenOnCurrentRowOrColumn = isDragMenuOpen && dragMenuDirection === direction && isCurrentRowOrColumnSelected;
18
- const isDragPossible = canDrag && !hasMergedCells;
19
- const showNormalHandle = !isDragPossible ? /*#__PURE__*/React.createElement(DragHandleDisabledIcon, null) : /*#__PURE__*/React.createElement(DragHandleIcon, null);
20
-
21
- // hoverred handle or open drag menu
22
- if (isHandleHovered || isDragMenuOpenOnCurrentRowOrColumn) {
23
- return showNormalHandle;
11
+ if (isHandleHovered || forceDefaultHandle) {
12
+ return hasMergedCells ? /*#__PURE__*/React.createElement(DragHandleDisabledIcon, null) : /*#__PURE__*/React.createElement(DragHandleIcon, null);
24
13
  }
25
14
  return /*#__PURE__*/React.createElement(MinimisedHandleIcon, null);
26
15
  };
@@ -4,7 +4,6 @@ import ReactDOM from 'react-dom';
4
4
  import { browser } from '@atlaskit/editor-common/utils';
5
5
  import { draggable } from '@atlaskit/pragmatic-drag-and-drop/adapter/element';
6
6
  import { setCustomNativeDragPreview } from '@atlaskit/pragmatic-drag-and-drop/util/set-custom-native-drag-preview';
7
- import { getPluginState as getDragDropPluginState } from '../../pm-plugins/drag-and-drop/plugin-factory';
8
7
  import { getPluginState } from '../../pm-plugins/plugin-factory';
9
8
  import { TableCssClassName as ClassName } from '../../types';
10
9
  import { hasMergedCellsInColumn, hasMergedCellsInRow } from '../../utils';
@@ -15,6 +14,7 @@ export const DragHandle = ({
15
14
  direction = 'row',
16
15
  appearance = 'default',
17
16
  indexes,
17
+ forceDefaultHandle = false,
18
18
  previewWidth,
19
19
  previewHeight,
20
20
  onMouseOver,
@@ -28,32 +28,19 @@ export const DragHandle = ({
28
28
  const [previewContainer, setPreviewContainer] = useState(null);
29
29
  const {
30
30
  hoveredColumns,
31
- hoveredRows,
32
- hoveredCell
31
+ hoveredRows
33
32
  } = getPluginState(editorView.state);
34
- const {
35
- dragMenuDirection,
36
- isDragMenuOpen,
37
- dragMenuIndex
38
- } = getDragDropPluginState(editorView.state);
39
33
  const {
40
34
  selection
41
35
  } = editorView.state;
42
- const isCurrentRowSelected = isDragMenuOpen && direction === 'row' && hoveredCell.rowIndex === dragMenuIndex;
43
- const isCurrentColumnSelected = isDragMenuOpen && direction === 'column' && hoveredCell.colIndex === dragMenuIndex;
44
36
  const isRowHandleHovered = direction === 'row' && hoveredRows.length > 0;
45
37
  const isColumnHandleHovered = direction === 'column' && hoveredColumns.length > 0;
46
38
  const hasMergedCells = useMemo(() => direction === 'row' ? hasMergedCellsInRow(indexes[0])(selection) : hasMergedCellsInColumn(indexes[0])(selection), [indexes, direction, selection]);
47
39
  const handleIconProps = {
48
- canDrag,
49
- hasMergedCells,
50
- direction,
51
- isDragMenuOpen,
52
- isRowHandleHovered,
40
+ forceDefaultHandle,
53
41
  isColumnHandleHovered,
54
- isCurrentRowSelected,
55
- isCurrentColumnSelected,
56
- dragMenuDirection
42
+ isRowHandleHovered,
43
+ hasMergedCells
57
44
  };
58
45
  useEffect(() => {
59
46
  const dragHandleDivRefCurrent = dragHandleDivRef.current;
@@ -1,8 +1,10 @@
1
+ /* eslint-disable @atlaskit/design-system/prefer-primitives */
2
+
1
3
  import React, { useCallback, useMemo } from 'react';
2
4
  import { tableCellMinWidth } from '@atlaskit/editor-common/styles';
3
5
  import { CellSelection } from '@atlaskit/editor-tables';
4
6
  import { getSelectionRect } from '@atlaskit/editor-tables/utils';
5
- import { clearHoverSelection, hoverCell, hoverColumns, selectColumn } from '../../../commands';
7
+ import { clearHoverSelection, hoverCell, hoverColumns, selectColumn, selectColumns } from '../../../commands';
6
8
  import { toggleDragMenu } from '../../../pm-plugins/drag-and-drop/commands';
7
9
  import { TableCssClassName as ClassName } from '../../../types';
8
10
  import { getRowsParams, getSelectedColumnIndexes } from '../../../utils';
@@ -32,19 +34,12 @@ export const ColumnControls = ({
32
34
  isTableHovered,
33
35
  canDrag
34
36
  }) => {
35
- var _colWidths$map$join, _rowHeights$, _rowHeights$reduce, _colWidths;
37
+ var _colWidths$map$join, _rowHeights$, _rowHeights$reduce;
36
38
  const widths = (_colWidths$map$join = colWidths === null || colWidths === void 0 ? void 0 : colWidths.map(width => width ? `${width - 1}px` : '0px').join(' ')) !== null && _colWidths$map$join !== void 0 ? _colWidths$map$join : '0px';
37
39
  // TODO: reusing getRowsParams here because it's generic enough to work for columns -> rename
38
40
  const columnParams = getRowsParams(colWidths !== null && colWidths !== void 0 ? colWidths : []);
39
41
  const colIndex = hoveredCell === null || hoveredCell === void 0 ? void 0 : hoveredCell.colIndex;
40
42
  const selectedColIndexes = getSelectedColumns(editorView.state.selection);
41
- const gridColumnPosition = useMemo(() => {
42
- // if more than one row is selected, ensure the handle spans over the selected range
43
- if (selectedColIndexes.includes(colIndex)) {
44
- return `${selectedColIndexes[0] + 1} / span ${selectedColIndexes.length}`;
45
- }
46
- return `${colIndex + 1} / span 1`;
47
- }, [colIndex, selectedColIndexes]);
48
43
  const firstRow = tableRef.querySelector('tr');
49
44
  const hasHeaderRow = firstRow ? firstRow.getAttribute('data-header-row') : false;
50
45
  const marginTop = hasHeaderRow && stickyTop !== undefined ? (_rowHeights$ = rowHeights === null || rowHeights === void 0 ? void 0 : rowHeights[0]) !== null && _rowHeights$ !== void 0 ? _rowHeights$ : 0 : 0;
@@ -53,8 +48,14 @@ export const ColumnControls = ({
53
48
  state,
54
49
  dispatch
55
50
  } = editorView;
56
- selectColumn(colIndex, event.shiftKey)(state, dispatch);
57
- }, [colIndex, editorView]);
51
+ const isClickOutsideSelectedCols = selectedColIndexes.length >= 1 && !selectedColIndexes.includes(colIndex);
52
+ if (!selectedColIndexes || selectedColIndexes.length === 0 || isClickOutsideSelectedCols) {
53
+ selectColumn(colIndex, event.shiftKey)(state, dispatch);
54
+ }
55
+ if (selectedColIndexes.length > 1 && selectedColIndexes.includes(colIndex) && !event.shiftKey) {
56
+ selectColumns(selectedColIndexes)(state, dispatch);
57
+ }
58
+ }, [colIndex, selectedColIndexes, editorView]);
58
59
  const handleMouseOver = useCallback(() => {
59
60
  const {
60
61
  state,
@@ -104,6 +105,64 @@ export const ColumnControls = ({
104
105
  return [colIndex];
105
106
  }, [colIndex]);
106
107
  const previewHeight = (_rowHeights$reduce = rowHeights === null || rowHeights === void 0 ? void 0 : rowHeights.reduce((sum, cur) => sum + cur, 0)) !== null && _rowHeights$reduce !== void 0 ? _rowHeights$reduce : 0;
108
+ const generateHandleByType = type => {
109
+ var _colWidths;
110
+ if (!hoveredCell || !(colWidths !== null && colWidths !== void 0 && colWidths.length)) {
111
+ return null;
112
+ }
113
+ const isHover = type === 'hover';
114
+ const isColumnsSelected = selectedColIndexes.length > 0;
115
+ const showCondition = isHover ? isColumnsSelected && !selectedColIndexes.includes(colIndex) && Number.isFinite(hoveredCell === null || hoveredCell === void 0 ? void 0 : hoveredCell.colIndex) : selectedColIndexes.length < (colWidths === null || colWidths === void 0 ? void 0 : colWidths.length) && Number.isFinite(hoveredCell === null || hoveredCell === void 0 ? void 0 : hoveredCell.colIndex);
116
+ if (!showCondition) {
117
+ return null;
118
+ }
119
+ const gridColumnPosition = `${colIndex + 1} / span 1`;
120
+ const selectedColumnPosition = `${selectedColIndexes[0] + 1} / span ${selectedColIndexes.length}`;
121
+ const hoveredAppearance = selectedColIndexes.includes(colIndex) ? isInDanger ? 'danger' : 'selected' : 'default';
122
+ const currentSelectionApprearance = isColumnsSelected ? isInDanger ? 'danger' : 'selected' : hoveredAppearance;
123
+ const istSelecting = isColumnsSelected && !isHover;
124
+
125
+ // this indexes are used to calculate the drag and drop source
126
+ const indexes = isColumnsSelected ? isHover ? colIndexes : selectedColIndexes : colIndexes;
127
+ return showCondition && /*#__PURE__*/React.createElement("div", {
128
+ key: type,
129
+ style: {
130
+ gridColumn: istSelecting ? selectedColumnPosition : gridColumnPosition,
131
+ display: 'flex',
132
+ justifyContent: 'center',
133
+ alignItems: 'center',
134
+ height: 'fit-content',
135
+ placeSelf: 'center',
136
+ zIndex: 99
137
+ },
138
+ "data-column-control-index": hoveredCell.colIndex,
139
+ "data-testid": isHover ? 'table-floating-column-control-hover' : 'table-floating-column-control'
140
+ }, /*#__PURE__*/React.createElement(DragHandle, {
141
+ direction: "column",
142
+ tableLocalId: localId || '',
143
+ indexes: indexes,
144
+ forceDefaultHandle: isHover ? false : isColumnsSelected,
145
+ previewWidth: (_colWidths = colWidths === null || colWidths === void 0 ? void 0 : colWidths[colIndex]) !== null && _colWidths !== void 0 ? _colWidths : tableCellMinWidth,
146
+ previewHeight: previewHeight,
147
+ appearance: istSelecting ? currentSelectionApprearance : hoveredAppearance,
148
+ onClick: handleClick,
149
+ onMouseOver: handleMouseOver,
150
+ onMouseOut: handleMouseOut,
151
+ onMouseUp: handleMouseUp,
152
+ editorView: editorView,
153
+ canDrag: canDrag
154
+ }));
155
+ };
156
+ const columnHandles = hoveredCell => {
157
+ if (!hoveredCell) {
158
+ return null;
159
+ }
160
+ if (hoveredCell.colIndex === undefined) {
161
+ return generateHandleByType('selected');
162
+ }
163
+ const sortedHandles = [generateHandleByType('hover'), generateHandleByType('selected')];
164
+ return hoveredCell.colIndex < selectedColIndexes[0] ? sortedHandles : sortedHandles.reverse();
165
+ };
107
166
  return /*#__PURE__*/React.createElement("div", {
108
167
  className: ClassName.DRAG_COLUMN_CONTROLS,
109
168
  onMouseMove: handleMouseMove
@@ -131,31 +190,6 @@ export const ColumnControls = ({
131
190
  style: columnParams.length - 1 === index ? {
132
191
  right: '0'
133
192
  } : {}
134
- }))), tableActive && !isResizing && isTableHovered && !!hoveredCell && Number.isFinite(hoveredCell.colIndex) && /*#__PURE__*/React.createElement("div", {
135
- style: {
136
- gridColumn: gridColumnPosition,
137
- display: 'flex',
138
- justifyContent: 'center',
139
- alignItems: 'center',
140
- height: 'fit-content',
141
- placeSelf: 'center',
142
- zIndex: 99
143
- },
144
- "data-column-control-index": hoveredCell.colIndex,
145
- "data-testid": "table-floating-column-control"
146
- }, /*#__PURE__*/React.createElement(DragHandle, {
147
- direction: "column",
148
- tableLocalId: localId || '',
149
- indexes: colIndexes,
150
- previewWidth: (_colWidths = colWidths === null || colWidths === void 0 ? void 0 : colWidths[colIndex]) !== null && _colWidths !== void 0 ? _colWidths : tableCellMinWidth,
151
- previewHeight: previewHeight,
152
- appearance: selectedColIndexes.includes(hoveredCell.colIndex) ? isInDanger ? 'danger' : 'selected' : 'default',
153
- onClick: handleClick,
154
- onMouseOver: handleMouseOver,
155
- onMouseOut: handleMouseOut,
156
- onMouseUp: handleMouseUp,
157
- editorView: editorView,
158
- canDrag: canDrag
159
- }))));
193
+ }))), tableActive && isTableHovered && !isResizing && columnHandles(hoveredCell)));
160
194
  };
161
195
  export default ColumnControls;
@@ -10,7 +10,9 @@ import { tableBorderColor } from '../../consts';
10
10
  export default class NumberColumn extends Component {
11
11
  constructor(...args) {
12
12
  super(...args);
13
- _defineProperty(this, "hoverRows", index => this.props.tableActive ? this.props.hoverRows([index]) : null);
13
+ _defineProperty(this, "hoverRows", index => {
14
+ return this.props.tableActive ? this.props.hoverRows([index]) : null;
15
+ });
14
16
  _defineProperty(this, "selectRow", (index, event) => {
15
17
  const {
16
18
  tableActive,
@@ -1,3 +1,5 @@
1
+ /* eslint-disable @atlaskit/design-system/prefer-primitives */
2
+
1
3
  import React, { Fragment, useCallback, useEffect, useMemo, useState } from 'react';
2
4
  import { injectIntl } from 'react-intl-next';
3
5
  import { CellSelection } from '@atlaskit/editor-tables';
@@ -34,6 +36,7 @@ const DragControlsComponent = ({
34
36
  canDrag,
35
37
  hoverRows,
36
38
  selectRow,
39
+ selectRows,
37
40
  updateCellHoverLocation
38
41
  }) => {
39
42
  var _tableNode$attrs$loca, _tableNode$attrs;
@@ -75,13 +78,6 @@ const DragControlsComponent = ({
75
78
  toggleDragMenu(undefined, 'row', hoveredCell === null || hoveredCell === void 0 ? void 0 : hoveredCell.rowIndex)(editorView.state, editorView.dispatch);
76
79
  }, [editorView, hoveredCell === null || hoveredCell === void 0 ? void 0 : hoveredCell.rowIndex]);
77
80
  const rowIndex = hoveredCell === null || hoveredCell === void 0 ? void 0 : hoveredCell.rowIndex;
78
- const gridRowPosition = useMemo(() => {
79
- // if more than one row is selected, ensure the handle spans over the selected range
80
- if (selectedRowIndexes.includes(rowIndex)) {
81
- return `${selectedRowIndexes[0] + 1} / span ${selectedRowIndexes.length}`;
82
- }
83
- return `${rowIndex + 1} / span 1`;
84
- }, [rowIndex, selectedRowIndexes]);
85
81
  const handleMouseOut = useCallback(() => {
86
82
  if (tableActive) {
87
83
  const {
@@ -108,8 +104,69 @@ const DragControlsComponent = ({
108
104
  hoverRows([rowIndex]);
109
105
  }, [hoverRows, rowIndex]);
110
106
  const handleClick = useCallback(e => {
111
- selectRow(rowIndex, e === null || e === void 0 ? void 0 : e.shiftKey);
112
- }, [rowIndex, selectRow]);
107
+ const isClickOutsideSelectedRows = selectedRowIndexes.length >= 1 && !selectedRowIndexes.includes(rowIndex);
108
+ if (!selectedRowIndexes || selectedRowIndexes.length === 0 || isClickOutsideSelectedRows) {
109
+ selectRow(rowIndex, e.shiftKey);
110
+ }
111
+ if (selectedRowIndexes.length > 1 && selectedRowIndexes.includes(rowIndex) && !e.shiftKey) {
112
+ selectRows(selectedRowIndexes);
113
+ }
114
+ }, [rowIndex, selectRow, selectRows, selectedRowIndexes]);
115
+ const generateHandleByType = type => {
116
+ if (!hoveredCell) {
117
+ return null;
118
+ }
119
+ const isHover = type === 'hover';
120
+ const isRowsSelected = selectedRowIndexes.length > 0;
121
+ const 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);
122
+ if (!showCondition) {
123
+ return null;
124
+ }
125
+ const gridRowPosition = `${rowIndex + 1} / span 1`;
126
+
127
+ // if more than one row is selected, ensure the handle spans over the selected range
128
+ const selectedRowPosition = `${selectedRowIndexes[0] + 1} / span ${selectedRowIndexes.length}`;
129
+ const hoveredAppearance = selectedRowIndexes.includes(rowIndex) ? isInDanger ? 'danger' : 'selected' : 'default';
130
+ const currentSelectionAppearance = isRowsSelected ? isInDanger ? 'danger' : 'selected' : hoveredAppearance;
131
+ const isSelecting = isRowsSelected && !isHover;
132
+ const indexes = isRowsSelected ? isHover ? rowIndexes : selectedRowIndexes : rowIndexes;
133
+ return showCondition && /*#__PURE__*/React.createElement("div", {
134
+ key: type,
135
+ style: {
136
+ gridRow: isSelecting ? selectedRowPosition : gridRowPosition,
137
+ gridColumn: '2',
138
+ // 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
139
+ width: '9px',
140
+ position: 'relative',
141
+ right: '-0.5px'
142
+ },
143
+ "data-testid": isHover ? 'table-floating-row-drag-handle-hover' : 'table-floating-row-drag-handle'
144
+ }, /*#__PURE__*/React.createElement(DragHandle, {
145
+ direction: "row",
146
+ tableLocalId: currentNodeLocalId,
147
+ indexes: indexes,
148
+ forceDefaultHandle: isHover ? false : isRowsSelected,
149
+ previewWidth: tableWidth,
150
+ previewHeight: rowHeights[rowIndex],
151
+ appearance: isSelecting ? currentSelectionAppearance : hoveredAppearance,
152
+ onClick: handleClick,
153
+ onMouseOver: handleMouseOver,
154
+ onMouseOut: handleMouseOut,
155
+ onMouseUp: onMouseUp,
156
+ editorView: editorView,
157
+ canDrag: canDrag
158
+ }));
159
+ };
160
+ const rowHandles = hoveredCell => {
161
+ if (!hoveredCell) {
162
+ return null;
163
+ }
164
+ if (hoveredCell.rowIndex === undefined) {
165
+ return generateHandleByType('selected');
166
+ }
167
+ const sortedHandles = [generateHandleByType('hover'), generateHandleByType('selected')];
168
+ return hoveredCell.rowIndex < selectedRowIndexes[0] ? sortedHandles : sortedHandles.reverse();
169
+ };
113
170
  return /*#__PURE__*/React.createElement("div", {
114
171
  className: ClassName.DRAG_ROW_CONTROLS,
115
172
  style: {
@@ -148,28 +205,6 @@ const DragControlsComponent = ({
148
205
  position: 'relative',
149
206
  left: "var(--ds-space-negative-100, -8px)"
150
207
  }
151
- }))), !isResizing && isTableHovered && Number.isFinite(rowIndex) && /*#__PURE__*/React.createElement("div", {
152
- style: {
153
- gridRow: gridRowPosition,
154
- gridColumn: '2',
155
- // 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
156
- width: '9px',
157
- position: 'relative',
158
- right: '-0.5px'
159
- },
160
- "data-testid": "table-floating-row-drag-handle"
161
- }, /*#__PURE__*/React.createElement(DragHandle, {
162
- tableLocalId: currentNodeLocalId,
163
- indexes: rowIndexes,
164
- previewWidth: tableWidth,
165
- previewHeight: rowHeights[rowIndex],
166
- appearance: selectedRowIndexes.includes(rowIndex) ? isInDanger ? 'danger' : 'selected' : 'default',
167
- onClick: handleClick,
168
- onMouseOver: handleMouseOver,
169
- onMouseOut: handleMouseOut,
170
- onMouseUp: onMouseUp,
171
- editorView: editorView,
172
- canDrag: canDrag
173
- })));
208
+ }))), tableActive && isTableHovered && !isResizing && Number.isFinite(rowIndex) && rowHandles(hoveredCell));
174
209
  };
175
210
  export const DragControls = injectIntl(DragControlsComponent);
@@ -1,7 +1,7 @@
1
1
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
2
  import React, { Component } from 'react';
3
3
  import { browser } from '@atlaskit/editor-common/utils';
4
- import { hoverCell, hoverRows, selectRow } from '../../commands';
4
+ import { hoverCell, hoverRows, selectRow, selectRows } from '../../commands';
5
5
  import { TableCssClassName as ClassName } from '../../types';
6
6
  import { isSelectionUpdated } from '../../utils';
7
7
  import { CornerControls, DragCornerControls } from './CornerControls';
@@ -24,6 +24,20 @@ export default class TableFloatingControls extends Component {
24
24
  }
25
25
  selectRow(row, expand)(state, dispatch);
26
26
  });
27
+ _defineProperty(this, "selectRows", rowIndexes => {
28
+ const {
29
+ editorView
30
+ } = this.props;
31
+ const {
32
+ state,
33
+ dispatch
34
+ } = editorView;
35
+ // fix for issue ED-4665
36
+ if (browser.ie_version === 11) {
37
+ editorView.dom.blur();
38
+ }
39
+ selectRows(rowIndexes)(state, dispatch);
40
+ });
27
41
  _defineProperty(this, "hoverRows", (rows, danger) => {
28
42
  const {
29
43
  state,
@@ -167,6 +181,7 @@ export default class TableFloatingControls extends Component {
167
181
  tableWidth: this.state.tableWrapperWidth,
168
182
  hoverRows: this.hoverRows,
169
183
  selectRow: this.selectRow,
184
+ selectRows: this.selectRows,
170
185
  updateCellHoverLocation: this.updateCellHoverLocation,
171
186
  canDrag: canDrag
172
187
  })) : /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(CornerControls, {
@@ -2,7 +2,7 @@ export { hoverColumns, hoverRows, hoverTable, hoverCell, hoverMergedCells, clear
2
2
  export { insertColumn, insertRow, createTable } from './insert';
3
3
  export { getNextLayout, toggleContextualMenu, toggleHeaderColumn, toggleHeaderRow, toggleNumberColumn, toggleTableLayout } from './toggle';
4
4
  export { clearMultipleCells } from './clear';
5
- export { autoSizeTable, convertFirstRowToHeader, deleteTable, hideInsertColumnOrRowButton, moveCursorBackward, selectColumn, selectRow, setCellAttr, setEditorFocus, setMultipleCellAttrs, setTableRef, showInsertColumnButton, showInsertRowButton, transformSliceToAddTableHeaders, triggerUnlessTableHeader, addBoldInEmptyHeaderCells, addResizeHandleDecorations } from './misc';
5
+ export { autoSizeTable, convertFirstRowToHeader, deleteTable, hideInsertColumnOrRowButton, moveCursorBackward, selectColumn, selectColumns, selectRow, selectRows, setCellAttr, setEditorFocus, setMultipleCellAttrs, setTableRef, showInsertColumnButton, showInsertRowButton, transformSliceToAddTableHeaders, triggerUnlessTableHeader, addBoldInEmptyHeaderCells, addResizeHandleDecorations } from './misc';
6
6
  export { sortByColumn } from './sort';
7
7
  export { goToNextCell } from './go-to-next-cell';
8
8
  export { removeDescendantNodes } from './referentiality';