@atlaskit/editor-plugin-table 7.4.1 → 7.4.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.
- package/CHANGELOG.md +12 -0
- package/dist/cjs/nodeviews/TableComponent.js +2 -4
- package/dist/cjs/nodeviews/TableContainer.js +5 -10
- package/dist/cjs/nodeviews/TableResizer.js +3 -7
- package/dist/cjs/ui/DragHandle/index.js +34 -2
- package/dist/cjs/ui/TableFloatingColumnControls/ColumnControls/index.js +1 -0
- package/dist/cjs/ui/TableFloatingControls/RowControls/DragControls.js +1 -0
- package/dist/cjs/utils/analytics.js +1 -2
- package/dist/cjs/utils/index.js +18 -0
- package/dist/cjs/utils/merged-cells.js +95 -1
- package/dist/es2019/nodeviews/TableComponent.js +2 -4
- package/dist/es2019/nodeviews/TableContainer.js +5 -10
- package/dist/es2019/nodeviews/TableResizer.js +3 -7
- package/dist/es2019/ui/DragHandle/index.js +36 -2
- package/dist/es2019/ui/TableFloatingColumnControls/ColumnControls/index.js +1 -0
- package/dist/es2019/ui/TableFloatingControls/RowControls/DragControls.js +1 -0
- package/dist/es2019/utils/analytics.js +1 -2
- package/dist/es2019/utils/index.js +1 -1
- package/dist/es2019/utils/merged-cells.js +91 -0
- package/dist/esm/nodeviews/TableComponent.js +2 -4
- package/dist/esm/nodeviews/TableContainer.js +5 -10
- package/dist/esm/nodeviews/TableResizer.js +3 -7
- package/dist/esm/ui/DragHandle/index.js +35 -3
- package/dist/esm/ui/TableFloatingColumnControls/ColumnControls/index.js +1 -0
- package/dist/esm/ui/TableFloatingControls/RowControls/DragControls.js +1 -0
- package/dist/esm/utils/analytics.js +1 -2
- package/dist/esm/utils/index.js +1 -1
- package/dist/esm/utils/merged-cells.js +94 -0
- package/dist/types/nodeviews/TableContainer.d.ts +2 -4
- package/dist/types/nodeviews/TableResizer.d.ts +1 -2
- package/dist/types/ui/DragHandle/index.d.ts +2 -1
- package/dist/types/utils/analytics.d.ts +0 -1
- package/dist/types/utils/index.d.ts +1 -1
- package/dist/types/utils/merged-cells.d.ts +28 -0
- package/dist/types-ts4.5/nodeviews/TableContainer.d.ts +2 -4
- package/dist/types-ts4.5/nodeviews/TableResizer.d.ts +1 -2
- package/dist/types-ts4.5/ui/DragHandle/index.d.ts +2 -1
- package/dist/types-ts4.5/utils/analytics.d.ts +0 -1
- package/dist/types-ts4.5/utils/index.d.ts +1 -1
- package/dist/types-ts4.5/utils/merged-cells.d.ts +28 -0
- package/package.json +3 -3
- package/src/nodeviews/TableComponent.tsx +1 -2
- package/src/nodeviews/TableContainer.tsx +0 -9
- package/src/nodeviews/TableResizer.tsx +0 -6
- package/src/ui/DragHandle/index.tsx +64 -9
- package/src/ui/TableFloatingColumnControls/ColumnControls/index.tsx +1 -0
- package/src/ui/TableFloatingControls/RowControls/DragControls.tsx +1 -0
- package/src/utils/analytics.ts +0 -2
- package/src/utils/index.ts +3 -0
- package/src/utils/merged-cells.ts +104 -0
|
@@ -8,7 +8,9 @@ import { injectIntl } from 'react-intl-next';
|
|
|
8
8
|
|
|
9
9
|
import { tableMessages as messages } from '@atlaskit/editor-common/messages';
|
|
10
10
|
import { browser } from '@atlaskit/editor-common/utils';
|
|
11
|
+
import { TextSelection } from '@atlaskit/editor-prosemirror/state';
|
|
11
12
|
import type { EditorView } from '@atlaskit/editor-prosemirror/view';
|
|
13
|
+
import { findTable, TableMap } from '@atlaskit/editor-tables';
|
|
12
14
|
import { draggable } from '@atlaskit/pragmatic-drag-and-drop/element/adapter';
|
|
13
15
|
import { setCustomNativeDragPreview } from '@atlaskit/pragmatic-drag-and-drop/element/set-custom-native-drag-preview';
|
|
14
16
|
import { token } from '@atlaskit/tokens';
|
|
@@ -16,9 +18,9 @@ import { token } from '@atlaskit/tokens';
|
|
|
16
18
|
import { getPluginState as getDnDPluginState } from '../../pm-plugins/drag-and-drop/plugin-factory';
|
|
17
19
|
import type { TriggerType } from '../../pm-plugins/drag-and-drop/types';
|
|
18
20
|
import { getPluginState } from '../../pm-plugins/plugin-factory';
|
|
19
|
-
import type { TableDirection } from '../../types';
|
|
20
21
|
import { TableCssClassName as ClassName } from '../../types';
|
|
21
|
-
import {
|
|
22
|
+
import type { CellHoverMeta, TableDirection } from '../../types';
|
|
23
|
+
import { findDuplicatePosition, hasMergedCellsInSelection } from '../../utils';
|
|
22
24
|
import { dragTableInsertColumnButtonSize } from '../consts';
|
|
23
25
|
import { DragPreview } from '../DragPreview';
|
|
24
26
|
|
|
@@ -37,6 +39,7 @@ type DragHandleProps = {
|
|
|
37
39
|
forceDefaultHandle?: boolean;
|
|
38
40
|
previewWidth?: number;
|
|
39
41
|
previewHeight?: number;
|
|
42
|
+
hoveredCell?: CellHoverMeta;
|
|
40
43
|
direction?: TableDirection;
|
|
41
44
|
appearance?: DragHandleAppearance;
|
|
42
45
|
onClick?: MouseEventHandler;
|
|
@@ -62,6 +65,7 @@ const DragHandleComponent = ({
|
|
|
62
65
|
onMouseOver,
|
|
63
66
|
onMouseOut,
|
|
64
67
|
toggleDragMenu,
|
|
68
|
+
hoveredCell,
|
|
65
69
|
onClick,
|
|
66
70
|
editorView,
|
|
67
71
|
intl: { formatMessage },
|
|
@@ -83,13 +87,64 @@ const DragHandleComponent = ({
|
|
|
83
87
|
const isRowHandleHovered = isRow && hoveredRows.length > 0;
|
|
84
88
|
const isColumnHandleHovered = isColumn && hoveredColumns.length > 0;
|
|
85
89
|
|
|
86
|
-
const hasMergedCells = useMemo(
|
|
87
|
-
()
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
90
|
+
const hasMergedCells = useMemo(() => {
|
|
91
|
+
const table = findTable(selection);
|
|
92
|
+
if (!table) {
|
|
93
|
+
return false;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const map = TableMap.get(table?.node);
|
|
97
|
+
|
|
98
|
+
if (!map.hasMergedCells() || indexes.length < 1) {
|
|
99
|
+
return false;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const { mapByColumn, mapByRow } = map;
|
|
103
|
+
|
|
104
|
+
// this handle when hover to first column or row which has merged cells.
|
|
105
|
+
if (
|
|
106
|
+
hoveredCell &&
|
|
107
|
+
hoveredCell.rowIndex !== undefined &&
|
|
108
|
+
hoveredCell.colIndex !== undefined &&
|
|
109
|
+
selection instanceof TextSelection
|
|
110
|
+
) {
|
|
111
|
+
const { rowIndex, colIndex } = hoveredCell;
|
|
112
|
+
|
|
113
|
+
const mergedPositionInRow = findDuplicatePosition(mapByRow[rowIndex]);
|
|
114
|
+
const mergedPositionInCol = findDuplicatePosition(mapByColumn[colIndex]);
|
|
115
|
+
|
|
116
|
+
const hasMergedCellsInFirstRowOrColumn =
|
|
117
|
+
direction === 'column'
|
|
118
|
+
? mergedPositionInRow.includes(mapByRow[0][colIndex])
|
|
119
|
+
: mergedPositionInCol.includes(mapByColumn[0][rowIndex]);
|
|
120
|
+
|
|
121
|
+
const isHoveredOnFirstRowOrColumn =
|
|
122
|
+
direction === 'column'
|
|
123
|
+
? hoveredCell.rowIndex === 0 && hasMergedCellsInFirstRowOrColumn
|
|
124
|
+
: hoveredCell.colIndex === 0 && hasMergedCellsInFirstRowOrColumn;
|
|
125
|
+
|
|
126
|
+
if (isHoveredOnFirstRowOrColumn) {
|
|
127
|
+
const mergedSizes =
|
|
128
|
+
direction === 'column'
|
|
129
|
+
? mapByRow[0].filter((el: number) => el === mapByRow[0][colIndex])
|
|
130
|
+
.length
|
|
131
|
+
: mapByColumn[0].filter(
|
|
132
|
+
(el: number) => el === mapByColumn[0][rowIndex],
|
|
133
|
+
).length;
|
|
134
|
+
|
|
135
|
+
const mergedSelection = hasMergedCellsInSelection(
|
|
136
|
+
direction === 'column'
|
|
137
|
+
? [colIndex, colIndex + mergedSizes - 1]
|
|
138
|
+
: [rowIndex, rowIndex + mergedSizes - 1],
|
|
139
|
+
direction,
|
|
140
|
+
)(selection);
|
|
141
|
+
|
|
142
|
+
return mergedSelection;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
return hasMergedCellsInSelection(indexes, direction)(selection);
|
|
147
|
+
}, [indexes, selection, direction, hoveredCell]);
|
|
93
148
|
|
|
94
149
|
const handleIconProps = {
|
|
95
150
|
forceDefaultHandle,
|
package/src/utils/analytics.ts
CHANGED
|
@@ -144,7 +144,6 @@ export const generateResizeFrameRatePayloads = (props: {
|
|
|
144
144
|
docSize: number;
|
|
145
145
|
frameRateSamples: number[];
|
|
146
146
|
originalNode: PMNode;
|
|
147
|
-
experiments?: Record<string, boolean | undefined>;
|
|
148
147
|
}): TableEventPayload[] => {
|
|
149
148
|
const reducedResizeFrameRateSamples = reduceResizeFrameRateSamples(
|
|
150
149
|
props.frameRateSamples,
|
|
@@ -158,7 +157,6 @@ export const generateResizeFrameRatePayloads = (props: {
|
|
|
158
157
|
nodeSize: props.originalNode.nodeSize,
|
|
159
158
|
docSize: props.docSize,
|
|
160
159
|
isInitialSample: index === 0,
|
|
161
|
-
experiments: props.experiments,
|
|
162
160
|
},
|
|
163
161
|
}));
|
|
164
162
|
};
|
package/src/utils/index.ts
CHANGED
|
@@ -225,3 +225,107 @@ export const hasMergedCellsWithRowNextToRowIndex = (
|
|
|
225
225
|
|
|
226
226
|
return false;
|
|
227
227
|
};
|
|
228
|
+
|
|
229
|
+
export const hasMergedCellsInSelection =
|
|
230
|
+
(indexes: number[], type: MergeType) =>
|
|
231
|
+
(selection: Selection): boolean => {
|
|
232
|
+
const table = findTable(selection);
|
|
233
|
+
if (!table) {
|
|
234
|
+
return false;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
const map = TableMap.get(table.node);
|
|
238
|
+
|
|
239
|
+
if (!map.hasMergedCells()) {
|
|
240
|
+
return false;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
return checkEdgeHasMergedCells(indexes, map, type);
|
|
244
|
+
};
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* handle table map by preprocess table's map row or column.
|
|
248
|
+
*
|
|
249
|
+
* @param map TableMap
|
|
250
|
+
* @returns object including mapByRow and mapByColumn
|
|
251
|
+
*/
|
|
252
|
+
export const getTableMapByRowOrColumn = (map: TableMap) => {
|
|
253
|
+
let mapByRow = Array(map.height);
|
|
254
|
+
let mapByColumn = Array(map.width);
|
|
255
|
+
|
|
256
|
+
const mapCopy = [...map.map];
|
|
257
|
+
|
|
258
|
+
for (let i = 0; i < mapCopy.length; i++) {
|
|
259
|
+
const columnIndex = i % map.width;
|
|
260
|
+
mapByColumn[columnIndex] = [
|
|
261
|
+
...(mapByColumn[columnIndex] ?? []),
|
|
262
|
+
mapCopy[i],
|
|
263
|
+
];
|
|
264
|
+
const rowIndex = Math.trunc(i / map.width);
|
|
265
|
+
mapByRow[rowIndex] = [...(mapByRow[rowIndex] ?? []), mapCopy[i]];
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
return { mapByRow, mapByColumn };
|
|
269
|
+
};
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* this check the selection has merged cells with previous/next col or row.
|
|
273
|
+
*
|
|
274
|
+
* @param indexes - this get the indexes of the selection,e.g. [0,1] for selecting first two rows or columns.
|
|
275
|
+
* @param tableMap - this return a TableMap object.
|
|
276
|
+
* @param direction - check selection is selected by row or column
|
|
277
|
+
* @returns boolean
|
|
278
|
+
*/
|
|
279
|
+
export const checkEdgeHasMergedCells = (
|
|
280
|
+
indexes: number[],
|
|
281
|
+
tableMap: TableMap,
|
|
282
|
+
direction: 'row' | 'column',
|
|
283
|
+
): boolean => {
|
|
284
|
+
const { mapByRow, mapByColumn } = getTableMapByRowOrColumn(tableMap);
|
|
285
|
+
const map = 'row' === direction ? mapByRow : mapByColumn;
|
|
286
|
+
const lengthLimiter = direction === 'row' ? tableMap.width : tableMap.height;
|
|
287
|
+
|
|
288
|
+
let minIndex = Math.min(...indexes);
|
|
289
|
+
let maxIndex = Math.max(...indexes);
|
|
290
|
+
let isTopSideHaveMergedCells = false;
|
|
291
|
+
let isBottomSideHaveMergedCells = false;
|
|
292
|
+
let isOldMinIndex = !map[minIndex - 1] && !map[minIndex];
|
|
293
|
+
let isOldMaxIndex = !map[maxIndex + 1] && !map[maxIndex];
|
|
294
|
+
|
|
295
|
+
if (minIndex > 0 && !isOldMinIndex) {
|
|
296
|
+
const prevSelectionSet = map[minIndex - 1];
|
|
297
|
+
const minSelectionSet = map[minIndex];
|
|
298
|
+
for (let i = 0; i < lengthLimiter; i++) {
|
|
299
|
+
if (prevSelectionSet[i] === minSelectionSet[i]) {
|
|
300
|
+
isTopSideHaveMergedCells = true;
|
|
301
|
+
break;
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
if (maxIndex < map.length - 1 && !isOldMaxIndex) {
|
|
307
|
+
const afterSelectionSet = map[maxIndex + 1];
|
|
308
|
+
const maxSelectionSet = map[maxIndex];
|
|
309
|
+
|
|
310
|
+
for (let i = 0; i < lengthLimiter; i++) {
|
|
311
|
+
if (afterSelectionSet[i] === maxSelectionSet[i]) {
|
|
312
|
+
isBottomSideHaveMergedCells = true;
|
|
313
|
+
break;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
return isTopSideHaveMergedCells || isBottomSideHaveMergedCells;
|
|
318
|
+
};
|
|
319
|
+
|
|
320
|
+
/**
|
|
321
|
+
* this function will find the duplicate position in the array(table map position array).
|
|
322
|
+
*
|
|
323
|
+
* @param array this usually be the array including positions of the table map.
|
|
324
|
+
* @returns []
|
|
325
|
+
*/
|
|
326
|
+
export const findDuplicatePosition = (array: number[]): number[] => {
|
|
327
|
+
if (!array) {
|
|
328
|
+
return [];
|
|
329
|
+
}
|
|
330
|
+
return array.filter((item, index) => array.indexOf(item) !== index);
|
|
331
|
+
};
|