@atlaskit/editor-plugin-table 7.2.1 → 7.2.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 +14 -0
- package/dist/cjs/nodeviews/TableComponent.js +11 -7
- package/dist/cjs/pm-plugins/drag-and-drop/commands-with-analytics.js +3 -19
- package/dist/cjs/ui/TableFloatingColumnControls/ColumnControls/index.js +11 -25
- package/dist/cjs/ui/TableFloatingColumnControls/ColumnDropTargets/index.js +13 -3
- package/dist/cjs/ui/TableFloatingColumnControls/index.js +7 -3
- package/dist/cjs/utils/drag-menu.js +37 -23
- package/dist/cjs/utils/merged-cells.js +66 -1
- package/dist/es2019/nodeviews/TableComponent.js +9 -5
- package/dist/es2019/pm-plugins/drag-and-drop/commands-with-analytics.js +4 -20
- package/dist/es2019/ui/TableFloatingColumnControls/ColumnControls/index.js +7 -21
- package/dist/es2019/ui/TableFloatingColumnControls/ColumnDropTargets/index.js +10 -2
- package/dist/es2019/ui/TableFloatingColumnControls/index.js +7 -3
- package/dist/es2019/utils/drag-menu.js +38 -14
- package/dist/es2019/utils/merged-cells.js +73 -0
- package/dist/esm/nodeviews/TableComponent.js +11 -7
- package/dist/esm/pm-plugins/drag-and-drop/commands-with-analytics.js +4 -20
- package/dist/esm/ui/TableFloatingColumnControls/ColumnControls/index.js +7 -21
- package/dist/esm/ui/TableFloatingColumnControls/ColumnDropTargets/index.js +10 -2
- package/dist/esm/ui/TableFloatingColumnControls/index.js +7 -3
- package/dist/esm/utils/drag-menu.js +36 -22
- package/dist/esm/utils/merged-cells.js +65 -0
- package/dist/types/ui/TableFloatingColumnControls/ColumnControls/index.d.ts +2 -1
- package/dist/types/ui/TableFloatingColumnControls/ColumnDropTargets/index.d.ts +2 -0
- package/dist/types/ui/TableFloatingColumnControls/index.d.ts +1 -0
- package/dist/types/utils/drag-menu.d.ts +4 -1
- package/dist/types/utils/merged-cells.d.ts +2 -0
- package/dist/types-ts4.5/ui/TableFloatingColumnControls/ColumnControls/index.d.ts +2 -1
- package/dist/types-ts4.5/ui/TableFloatingColumnControls/ColumnDropTargets/index.d.ts +2 -0
- package/dist/types-ts4.5/ui/TableFloatingColumnControls/index.d.ts +1 -0
- package/dist/types-ts4.5/utils/drag-menu.d.ts +4 -1
- package/dist/types-ts4.5/utils/merged-cells.d.ts +2 -0
- package/package.json +9 -16
- package/src/nodeviews/TableComponent.tsx +1 -0
- package/src/pm-plugins/drag-and-drop/commands-with-analytics.ts +11 -32
- package/src/ui/TableFloatingColumnControls/ColumnControls/index.tsx +6 -27
- package/src/ui/TableFloatingColumnControls/ColumnDropTargets/index.tsx +12 -1
- package/src/ui/TableFloatingColumnControls/index.tsx +5 -0
- package/src/utils/drag-menu.ts +94 -20
- package/src/utils/merged-cells.ts +78 -0
- package/tsconfig.dev.json +0 -69
- package/tsconfig.json +2 -871
- package/examples/99-testing.tsx +0 -140
- package/examples/config.jsonc +0 -14
- package/src/__tests__/unit/analytics.ts +0 -888
- package/src/__tests__/unit/collab.ts +0 -93
- package/src/__tests__/unit/commands/go-to-next-cell.ts +0 -173
- package/src/__tests__/unit/commands/insert.ts +0 -137
- package/src/__tests__/unit/commands/misc.ts +0 -185
- package/src/__tests__/unit/commands/sort.ts +0 -128
- package/src/__tests__/unit/commands.ts +0 -745
- package/src/__tests__/unit/copy-button.ts +0 -22
- package/src/__tests__/unit/copy-paste.ts +0 -677
- package/src/__tests__/unit/event-handlers/index.ts +0 -125
- package/src/__tests__/unit/event-handlers.ts +0 -296
- package/src/__tests__/unit/fix-tables.ts +0 -164
- package/src/__tests__/unit/get-toolbar-config.ts +0 -127
- package/src/__tests__/unit/handlers.ts +0 -98
- package/src/__tests__/unit/hover-selection.ts +0 -230
- package/src/__tests__/unit/index-with-fake-timers.ts +0 -111
- package/src/__tests__/unit/index.ts +0 -912
- package/src/__tests__/unit/layout.ts +0 -146
- package/src/__tests__/unit/nodeviews/OverflowShadowsObserver.ts +0 -162
- package/src/__tests__/unit/nodeviews/TableComponent.tsx +0 -280
- package/src/__tests__/unit/nodeviews/TableContainer.tsx +0 -525
- package/src/__tests__/unit/nodeviews/cell.ts +0 -132
- package/src/__tests__/unit/nodeviews/table.ts +0 -129
- package/src/__tests__/unit/pm-plugins/analytics.ts +0 -327
- package/src/__tests__/unit/pm-plugins/decorations/column-controls.ts +0 -94
- package/src/__tests__/unit/pm-plugins/decorations/column-resizing.ts +0 -176
- package/src/__tests__/unit/pm-plugins/decorations/plugin.ts +0 -211
- package/src/__tests__/unit/pm-plugins/main.ts +0 -214
- package/src/__tests__/unit/pm-plugins/safari-delete-composition-text-issue-workaround.ts +0 -101
- package/src/__tests__/unit/pm-plugins/sticky-headers/tableRow.tsx +0 -562
- package/src/__tests__/unit/pm-plugins/table-local-id.ts +0 -507
- package/src/__tests__/unit/pm-plugins/table-resizing/colgroup.ts +0 -269
- package/src/__tests__/unit/pm-plugins/table-resizing/event-handlers.ts +0 -192
- package/src/__tests__/unit/pm-plugins/table-resizing/utils/resize-state.ts +0 -33
- package/src/__tests__/unit/pm-plugins/table-width.ts +0 -292
- package/src/__tests__/unit/sort-column.ts +0 -399
- package/src/__tests__/unit/toolbar.ts +0 -512
- package/src/__tests__/unit/transforms/delete-columns.ts +0 -597
- package/src/__tests__/unit/transforms/delete-rows.ts +0 -620
- package/src/__tests__/unit/transforms/merging.ts +0 -392
- package/src/__tests__/unit/ui/ContextualMenu.tsx +0 -71
- package/src/__tests__/unit/ui/CornerControls.tsx +0 -99
- package/src/__tests__/unit/ui/DeleteButton.tsx +0 -38
- package/src/__tests__/unit/ui/FixedButton.tsx +0 -217
- package/src/__tests__/unit/ui/FloatingContextualButton.tsx +0 -123
- package/src/__tests__/unit/ui/FloatingContextualMenu.tsx +0 -68
- package/src/__tests__/unit/ui/FloatingDeleteButton.tsx +0 -178
- package/src/__tests__/unit/ui/FloatingDragMenu.tsx +0 -511
- package/src/__tests__/unit/ui/FloatingInsertButton.tsx +0 -322
- package/src/__tests__/unit/ui/NumberColumn.tsx +0 -146
- package/src/__tests__/unit/ui/RowControls.tsx +0 -294
- package/src/__tests__/unit/ui/RowDragControls.tsx +0 -129
- package/src/__tests__/unit/ui/TableFloatingColumnControls.tsx +0 -189
- package/src/__tests__/unit/ui/TableFloatingControls.tsx +0 -118
- package/src/__tests__/unit/undo-redo.ts +0 -220
- package/src/__tests__/unit/utils/analytics.ts +0 -98
- package/src/__tests__/unit/utils/collapse.ts +0 -57
- package/src/__tests__/unit/utils/column-controls.ts +0 -205
- package/src/__tests__/unit/utils/dom.ts +0 -180
- package/src/__tests__/unit/utils/merged-cells.ts +0 -156
- package/src/__tests__/unit/utils/nodes.ts +0 -79
- package/src/__tests__/unit/utils/row-controls.ts +0 -195
- package/src/__tests__/unit/utils/table.ts +0 -96
- package/src/__tests__/unit/utils.ts +0 -670
- package/src/__tests__/visual-regression/__fixtures__/sticky-header-with-horizontal-scroll.json +0 -5228
- package/src/__tests__/visual-regression/__fixtures__/table-with-100-numbered-list-items.json +0 -20272
- package/src/__tests__/visual-regression/__image_snapshots__/cell-options-menu-ts-table-cell-options-menu-delete-column-menu-item-should-remove-the-table-column-on-click-1-snap.png +0 -3
- package/src/__tests__/visual-regression/__image_snapshots__/cell-options-menu-ts-table-cell-options-menu-delete-column-menu-item-visual-hints-should-be-added-to-the-table-column-on-hover-1-snap.png +0 -3
- package/src/__tests__/visual-regression/__image_snapshots__/cell-options-menu-ts-table-cell-options-menu-delete-row-menu-item-should-remove-the-table-row-on-click-1-snap.png +0 -3
- package/src/__tests__/visual-regression/__image_snapshots__/cell-options-menu-ts-table-cell-options-menu-delete-row-menu-item-visual-hints-should-be-added-to-the-table-row-on-hover-1-snap.png +0 -3
- package/src/__tests__/visual-regression/__image_snapshots__/copy-button-ts-floating-toolbar-copy-button-table-target-node-displays-blue-border-when-copy-button-is-hovered-1-snap.png +0 -3
- package/src/__tests__/visual-regression/__image_snapshots__/index-ts-snapshot-test-table-numbered-list-should-not-overflow-table-cell-when-there-are-more-than-100-ordered-list-items-1-snap.png +0 -3
- package/src/__tests__/visual-regression/__image_snapshots__/index-ts-snapshot-test-table-numbered-list-should-not-overflow-table-cell-when-there-are-more-than-100-ordered-list-items-2-snap.png +0 -3
- package/src/__tests__/visual-regression/__image_snapshots__/index-ts-snapshot-test-table-numbered-list-should-not-overflow-table-cell-when-there-are-more-than-100-ordered-list-items-3-snap.png +0 -3
- package/src/__tests__/visual-regression/__image_snapshots__/sticky-header-ts-snapshot-test-table-sticky-header-should-align-with-table-cell-when-active-1-snap.png +0 -3
- package/src/__tests__/visual-regression/__image_snapshots__/sticky-header-ts-snapshot-test-table-sticky-header-should-align-with-table-cell-when-active-2-snap.png +0 -3
- package/src/__tests__/visual-regression/cell-options-menu.ts +0 -101
- package/src/__tests__/visual-regression/copy-button.ts +0 -181
- package/src/__tests__/visual-regression/index.ts +0 -62
- package/src/__tests__/visual-regression/sticky-header.ts +0 -61
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
2
|
import type { EditorAnalyticsAPI } from '@atlaskit/editor-common/analytics';
|
|
3
3
|
import type { Command, DropdownOptionT, GetEditorContainerWidth, IconProps } from '@atlaskit/editor-common/types';
|
|
4
|
+
import type { Selection } from '@atlaskit/editor-prosemirror/state';
|
|
4
5
|
import type { EditorView } from '@atlaskit/editor-prosemirror/view';
|
|
5
6
|
import type { Rect, TableMap } from '@atlaskit/editor-tables/table-map';
|
|
6
|
-
import type { TableDirection } from '../types';
|
|
7
|
+
import type { DraggableData, DraggableType, TableDirection } from '../types';
|
|
8
|
+
export declare const getTargetIndex: (selectedIndexes: number[], direction: DraggableData['direction']) => number;
|
|
9
|
+
export declare const canMove: (sourceType: DraggableType, direction: DraggableData['direction'], totalItemsOfSourceTypeCount: number, selection: Selection, selectionRect?: Rect) => boolean;
|
|
7
10
|
export type DragMenuOptionIdType = 'add_row_above' | 'add_row_below' | 'add_column_left' | 'add_column_right' | 'distribute_columns' | 'clear_cells' | 'delete_row' | 'delete_column' | 'move_column_left' | 'move_column_right' | 'move_row_up' | 'move_row_down' | 'sort_column_asc' | 'sort_column_desc';
|
|
8
11
|
export interface DragMenuConfig extends DropdownOptionT<Command> {
|
|
9
12
|
id: DragMenuOptionIdType;
|
|
@@ -3,4 +3,6 @@ type MergeType = 'row' | 'column';
|
|
|
3
3
|
export declare const hasMergedCellsInColumn: (columnIndexes: number | number[]) => (selection: Selection) => boolean;
|
|
4
4
|
export declare const hasMergedCellsInRow: (rowIndexes: number | number[]) => (selection: Selection) => boolean;
|
|
5
5
|
export declare const hasMergedCellsInBetween: (indexes: number[], type: MergeType) => (selection: Selection) => boolean;
|
|
6
|
+
export declare const hasMergedCellsWithColumnNextToColumnIndex: (colIndex: number, selection: Selection) => boolean;
|
|
7
|
+
export declare const hasMergedCellsWithRowNextToRowIndex: (rowIndex: number, selection: Selection) => boolean;
|
|
6
8
|
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/editor-plugin-table",
|
|
3
|
-
"version": "7.2.
|
|
3
|
+
"version": "7.2.3",
|
|
4
4
|
"description": "Table plugin for the @atlaskit/editor",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"registry": "https://registry.npmjs.org/"
|
|
@@ -29,15 +29,15 @@
|
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
31
|
"@atlaskit/adf-schema": "^35.5.1",
|
|
32
|
-
"@atlaskit/custom-steps": "^0.0.
|
|
33
|
-
"@atlaskit/editor-common": "^77.
|
|
32
|
+
"@atlaskit/custom-steps": "^0.0.13",
|
|
33
|
+
"@atlaskit/editor-common": "^77.3.0",
|
|
34
34
|
"@atlaskit/editor-palette": "1.5.2",
|
|
35
35
|
"@atlaskit/editor-plugin-analytics": "^0.4.0",
|
|
36
36
|
"@atlaskit/editor-plugin-content-insertion": "^0.1.0",
|
|
37
37
|
"@atlaskit/editor-plugin-guideline": "^0.5.0",
|
|
38
38
|
"@atlaskit/editor-plugin-selection": "^0.2.0",
|
|
39
39
|
"@atlaskit/editor-plugin-width": "^0.2.0",
|
|
40
|
-
"@atlaskit/editor-prosemirror": "
|
|
40
|
+
"@atlaskit/editor-prosemirror": "3.0.0",
|
|
41
41
|
"@atlaskit/editor-shared-styles": "^2.9.0",
|
|
42
42
|
"@atlaskit/editor-tables": "^2.5.0",
|
|
43
43
|
"@atlaskit/icon": "^22.0.0",
|
|
@@ -64,19 +64,7 @@
|
|
|
64
64
|
"react-intl-next": "npm:react-intl@^5.18.1"
|
|
65
65
|
},
|
|
66
66
|
"devDependencies": {
|
|
67
|
-
"@atlaskit/analytics-next": "^9.2.0",
|
|
68
|
-
"@atlaskit/editor-plugin-decorations": "^0.2.0",
|
|
69
|
-
"@atlaskit/editor-plugin-feature-flags": "^1.0.0",
|
|
70
|
-
"@atlaskit/editor-plugin-grid": "^0.3.0",
|
|
71
|
-
"@atlaskit/editor-plugin-hyperlink": "^0.8.0",
|
|
72
|
-
"@atlaskit/editor-test-helpers": "^18.15.0",
|
|
73
|
-
"@atlaskit/visual-regression": "*",
|
|
74
67
|
"@atlassian/atlassian-frontend-prettier-config-1.0.1": "npm:@atlassian/atlassian-frontend-prettier-config@1.0.1",
|
|
75
|
-
"@atlassian/feature-flags-test-utils": "^0.2.0",
|
|
76
|
-
"@testing-library/dom": "^8.17.1",
|
|
77
|
-
"@testing-library/react": "^12.1.5",
|
|
78
|
-
"@testing-library/react-hooks": "^8.0.1",
|
|
79
|
-
"raf-stub": "^2.0.1",
|
|
80
68
|
"typescript": "~4.9.5"
|
|
81
69
|
},
|
|
82
70
|
"af:exports": {
|
|
@@ -107,6 +95,11 @@
|
|
|
107
95
|
]
|
|
108
96
|
}
|
|
109
97
|
},
|
|
98
|
+
"stricter": {
|
|
99
|
+
"no-unused-dependencies": {
|
|
100
|
+
"checkDevDependencies": true
|
|
101
|
+
}
|
|
102
|
+
},
|
|
110
103
|
"platform-feature-flags": {
|
|
111
104
|
"platform.editor.custom-table-width": {
|
|
112
105
|
"type": "boolean"
|
|
@@ -500,6 +500,7 @@ class TableComponent extends React.Component<ComponentProps, TableState> {
|
|
|
500
500
|
getEditorFeatureFlags={getEditorFeatureFlags}
|
|
501
501
|
tableContainerWidth={tableContainerWidth}
|
|
502
502
|
isNumberColumnEnabled={node.attrs.isNumberColumnEnabled}
|
|
503
|
+
getScrollOffset={() => this.wrapper?.scrollLeft || 0}
|
|
503
504
|
/>
|
|
504
505
|
) : null;
|
|
505
506
|
|
|
@@ -22,10 +22,9 @@ import {
|
|
|
22
22
|
getSelectedColumnIndexes,
|
|
23
23
|
getSelectedRowIndexes,
|
|
24
24
|
getSelectedTableInfo,
|
|
25
|
-
hasMergedCellsInColumn,
|
|
26
|
-
hasMergedCellsInRow,
|
|
27
25
|
} from '../../utils';
|
|
28
26
|
import { withEditorAnalyticsAPI } from '../../utils/analytics';
|
|
27
|
+
import { canMove, getTargetIndex } from '../../utils/drag-menu';
|
|
29
28
|
|
|
30
29
|
import { clearDropTarget, moveSource } from './commands';
|
|
31
30
|
|
|
@@ -132,44 +131,24 @@ export const moveSourceWithAnalyticsViaShortcut =
|
|
|
132
131
|
const selectedIndexes = isRow
|
|
133
132
|
? getSelectedRowIndexes(selectionRect)
|
|
134
133
|
: getSelectedColumnIndexes(selectionRect);
|
|
135
|
-
|
|
136
134
|
if (selectedIndexes.length === 0) {
|
|
137
135
|
return false;
|
|
138
136
|
}
|
|
139
137
|
|
|
140
|
-
// const sourceIndex = selectedIndexes[0];
|
|
141
|
-
// we can move only by one row/column
|
|
142
|
-
// 'direction' can only be 1 (for right or down) or -1 (for left or up)
|
|
143
|
-
const targetIndex =
|
|
144
|
-
Math[direction < 0 ? 'min' : 'max'](...selectedIndexes) + direction;
|
|
145
|
-
|
|
146
|
-
// We can move only if targetIndex is a positive number and is not higher than the total number of rows/columns.
|
|
147
138
|
const { totalRowCount, totalColumnCount } = getSelectedTableInfo(selection);
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
?
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
// We can move only if there are no merged cells in the source or target row/column
|
|
160
|
-
const hasMergedCellsInSource = isRow
|
|
161
|
-
? hasMergedCellsInRow(selectedIndexes)(selection)
|
|
162
|
-
: hasMergedCellsInColumn(selectedIndexes)(selection);
|
|
163
|
-
if (hasMergedCellsInSource) {
|
|
139
|
+
if (
|
|
140
|
+
!canMove(
|
|
141
|
+
sourceType,
|
|
142
|
+
direction,
|
|
143
|
+
isRow ? totalRowCount : totalColumnCount,
|
|
144
|
+
selection,
|
|
145
|
+
selectionRect,
|
|
146
|
+
)
|
|
147
|
+
) {
|
|
164
148
|
return false;
|
|
165
149
|
}
|
|
166
150
|
|
|
167
|
-
const
|
|
168
|
-
? hasMergedCellsInRow(targetIndex)(selection)
|
|
169
|
-
: hasMergedCellsInColumn(targetIndex)(selection);
|
|
170
|
-
if (hasMergedCellsInTarget) {
|
|
171
|
-
return false;
|
|
172
|
-
}
|
|
151
|
+
const targetIndex = getTargetIndex(selectedIndexes, direction);
|
|
173
152
|
|
|
174
153
|
return moveSourceWithAnalytics(editorAnalyticsAPI)(
|
|
175
154
|
INPUT_METHOD.SHORTCUT,
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
/* eslint-disable @atlaskit/design-system/prefer-primitives */
|
|
2
2
|
import type { MouseEvent } from 'react';
|
|
3
|
-
import React, { useCallback,
|
|
3
|
+
import React, { useCallback, useMemo, useRef } from 'react';
|
|
4
4
|
|
|
5
5
|
import { tableCellMinWidth } from '@atlaskit/editor-common/styles';
|
|
6
|
-
import { closestElement } from '@atlaskit/editor-common/utils';
|
|
7
6
|
import type { Selection } from '@atlaskit/editor-prosemirror/state';
|
|
8
7
|
import type { EditorView } from '@atlaskit/editor-prosemirror/view';
|
|
9
8
|
import { akEditorTableNumberColumnWidth } from '@atlaskit/editor-shared-styles';
|
|
@@ -39,6 +38,7 @@ export interface ColumnControlsProps {
|
|
|
39
38
|
tableContainerWidth?: number;
|
|
40
39
|
isNumberColumnEnabled?: boolean;
|
|
41
40
|
isDragging?: boolean;
|
|
41
|
+
getScrollOffset?: () => number;
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
const getSelectedColumns = (selection: Selection) => {
|
|
@@ -68,6 +68,7 @@ export const ColumnControls = ({
|
|
|
68
68
|
tableContainerWidth,
|
|
69
69
|
isNumberColumnEnabled,
|
|
70
70
|
isDragging,
|
|
71
|
+
getScrollOffset,
|
|
71
72
|
}: ColumnControlsProps) => {
|
|
72
73
|
const columnControlsRef = useRef<HTMLDivElement>(null);
|
|
73
74
|
const widths =
|
|
@@ -172,32 +173,10 @@ export const ColumnControls = ({
|
|
|
172
173
|
const colIndexes = useMemo(() => {
|
|
173
174
|
return [colIndex!];
|
|
174
175
|
}, [colIndex]);
|
|
175
|
-
const tableWrapper = closestElement(
|
|
176
|
-
tableRef,
|
|
177
|
-
`.${ClassName.TABLE_NODE_WRAPPER}`,
|
|
178
|
-
);
|
|
179
|
-
const handleScroll = useCallback(
|
|
180
|
-
(event?: Event) => {
|
|
181
|
-
if (stickyTop) {
|
|
182
|
-
if (columnControlsRef && columnControlsRef.current) {
|
|
183
|
-
columnControlsRef.current.scrollLeft = tableWrapper?.scrollLeft ?? 0;
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
},
|
|
187
|
-
[stickyTop, tableWrapper],
|
|
188
|
-
);
|
|
189
176
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
useEffect(() => {
|
|
195
|
-
tableWrapper?.addEventListener('scroll', handleScroll);
|
|
196
|
-
|
|
197
|
-
return () => {
|
|
198
|
-
tableWrapper?.removeEventListener('scroll', handleScroll);
|
|
199
|
-
};
|
|
200
|
-
}, [tableWrapper, handleScroll]);
|
|
177
|
+
if (stickyTop && columnControlsRef.current) {
|
|
178
|
+
columnControlsRef.current.scrollLeft = getScrollOffset?.() ?? 0;
|
|
179
|
+
}
|
|
201
180
|
|
|
202
181
|
const generateHandleByType = (type: HandleTypes): JSX.Element | null => {
|
|
203
182
|
if (!hoveredCell || !colWidths?.length) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React from 'react';
|
|
1
|
+
import React, { useRef } from 'react';
|
|
2
2
|
|
|
3
3
|
import { TableCssClassName as ClassName } from '../../../types';
|
|
4
4
|
|
|
@@ -9,6 +9,8 @@ export interface Props {
|
|
|
9
9
|
tableHeight?: number;
|
|
10
10
|
localId?: string;
|
|
11
11
|
colWidths?: (number | undefined)[];
|
|
12
|
+
isHeaderSticky?: boolean;
|
|
13
|
+
getScrollOffset?: () => number;
|
|
12
14
|
}
|
|
13
15
|
|
|
14
16
|
export const ColumnDropTargets: React.FC<Props> = ({
|
|
@@ -16,13 +18,22 @@ export const ColumnDropTargets: React.FC<Props> = ({
|
|
|
16
18
|
tableHeight,
|
|
17
19
|
localId,
|
|
18
20
|
colWidths,
|
|
21
|
+
isHeaderSticky,
|
|
22
|
+
getScrollOffset,
|
|
19
23
|
}) => {
|
|
24
|
+
const dropTargetRef = useRef<HTMLDivElement>(null);
|
|
25
|
+
|
|
20
26
|
if (!tableRef) {
|
|
21
27
|
return null;
|
|
22
28
|
}
|
|
23
29
|
|
|
30
|
+
if (isHeaderSticky && dropTargetRef.current) {
|
|
31
|
+
dropTargetRef.current.style.marginLeft = `-${getScrollOffset?.() ?? 0}px`;
|
|
32
|
+
}
|
|
33
|
+
|
|
24
34
|
return (
|
|
25
35
|
<div
|
|
36
|
+
ref={dropTargetRef}
|
|
26
37
|
className={ClassName.DRAG_COLUMN_DROP_TARGET_CONTROLS}
|
|
27
38
|
contentEditable={false}
|
|
28
39
|
>
|
|
@@ -37,6 +37,7 @@ export interface Props {
|
|
|
37
37
|
isTableHovered?: boolean;
|
|
38
38
|
tableContainerWidth?: number;
|
|
39
39
|
isNumberColumnEnabled?: boolean;
|
|
40
|
+
getScrollOffset?: () => number;
|
|
40
41
|
}
|
|
41
42
|
|
|
42
43
|
export const TableFloatingColumnControls: React.FC<Props> = ({
|
|
@@ -53,6 +54,7 @@ export const TableFloatingColumnControls: React.FC<Props> = ({
|
|
|
53
54
|
isTableHovered,
|
|
54
55
|
tableContainerWidth,
|
|
55
56
|
isNumberColumnEnabled,
|
|
57
|
+
getScrollOffset,
|
|
56
58
|
}) => {
|
|
57
59
|
const [tableRect, setTableRect] = useState<{ width: number; height: number }>(
|
|
58
60
|
{ width: 0, height: 0 },
|
|
@@ -158,13 +160,16 @@ export const TableFloatingColumnControls: React.FC<Props> = ({
|
|
|
158
160
|
tableContainerWidth={tableContainerWidth}
|
|
159
161
|
isNumberColumnEnabled={isNumberColumnEnabled}
|
|
160
162
|
isDragging={isDragging}
|
|
163
|
+
getScrollOffset={getScrollOffset}
|
|
161
164
|
/>
|
|
162
165
|
{isDragging && (
|
|
163
166
|
<ColumnDropTargets
|
|
164
167
|
tableRef={tableRef}
|
|
168
|
+
isHeaderSticky={stickyHeader?.sticky && hasHeaderRow}
|
|
165
169
|
tableHeight={tableRect.height}
|
|
166
170
|
localId={currentNodeLocalId}
|
|
167
171
|
colWidths={colWidths}
|
|
172
|
+
getScrollOffset={getScrollOffset}
|
|
168
173
|
/>
|
|
169
174
|
)}
|
|
170
175
|
</div>
|
package/src/utils/drag-menu.ts
CHANGED
|
@@ -22,7 +22,10 @@ import type {
|
|
|
22
22
|
GetEditorContainerWidth,
|
|
23
23
|
IconProps,
|
|
24
24
|
} from '@atlaskit/editor-common/types';
|
|
25
|
-
import type {
|
|
25
|
+
import type {
|
|
26
|
+
EditorState,
|
|
27
|
+
Selection,
|
|
28
|
+
} from '@atlaskit/editor-prosemirror/state';
|
|
26
29
|
import type { EditorView } from '@atlaskit/editor-prosemirror/view';
|
|
27
30
|
import type { Rect, TableMap } from '@atlaskit/editor-tables/table-map';
|
|
28
31
|
import ArrowDownIcon from '@atlaskit/icon/glyph/arrow-down';
|
|
@@ -47,7 +50,7 @@ import { distributeColumnsWidths } from '../pm-plugins/table-resizing/commands';
|
|
|
47
50
|
import { getNewResizeStateFromSelectedColumns } from '../pm-plugins/table-resizing/utils/resize-state';
|
|
48
51
|
import { getClosestSelectionRect } from '../toolbar';
|
|
49
52
|
import { deleteRows } from '../transforms';
|
|
50
|
-
import type { TableDirection } from '../types';
|
|
53
|
+
import type { DraggableData, DraggableType, TableDirection } from '../types';
|
|
51
54
|
import {
|
|
52
55
|
AddColLeftIcon,
|
|
53
56
|
AddColRightIcon,
|
|
@@ -55,12 +58,61 @@ import {
|
|
|
55
58
|
AddRowBelowIcon,
|
|
56
59
|
} from '../ui/icons';
|
|
57
60
|
|
|
61
|
+
import {
|
|
62
|
+
hasMergedCellsInColumn,
|
|
63
|
+
hasMergedCellsInRow,
|
|
64
|
+
hasMergedCellsWithColumnNextToColumnIndex,
|
|
65
|
+
hasMergedCellsWithRowNextToRowIndex,
|
|
66
|
+
} from './merged-cells';
|
|
58
67
|
import { getSelectedColumnIndexes, getSelectedRowIndexes } from './selection';
|
|
59
68
|
|
|
60
|
-
const
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
69
|
+
export const getTargetIndex = (
|
|
70
|
+
selectedIndexes: number[],
|
|
71
|
+
direction: DraggableData['direction'],
|
|
72
|
+
) => Math[direction < 0 ? 'min' : 'max'](...selectedIndexes) + direction;
|
|
73
|
+
|
|
74
|
+
export const canMove = (
|
|
75
|
+
sourceType: DraggableType,
|
|
76
|
+
direction: DraggableData['direction'],
|
|
77
|
+
totalItemsOfSourceTypeCount: number,
|
|
78
|
+
selection: Selection,
|
|
79
|
+
selectionRect?: Rect,
|
|
80
|
+
) => {
|
|
81
|
+
if (!selectionRect) {
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const isRow = sourceType === 'table-row';
|
|
86
|
+
const selectedIndexes = isRow
|
|
87
|
+
? getSelectedRowIndexes(selectionRect)
|
|
88
|
+
: getSelectedColumnIndexes(selectionRect);
|
|
89
|
+
const targetIndex = getTargetIndex(selectedIndexes, direction);
|
|
90
|
+
|
|
91
|
+
const isValidTargetIndex =
|
|
92
|
+
targetIndex >= 0 && targetIndex < totalItemsOfSourceTypeCount;
|
|
93
|
+
if (!isValidTargetIndex) {
|
|
94
|
+
return false;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// We can't move column when target has merges with other columns
|
|
98
|
+
// We can't move row when target has merges with other rows
|
|
99
|
+
const hasMergedCellsInTarget = isRow
|
|
100
|
+
? hasMergedCellsWithRowNextToRowIndex(targetIndex, selection)
|
|
101
|
+
: hasMergedCellsWithColumnNextToColumnIndex(targetIndex, selection);
|
|
102
|
+
if (hasMergedCellsInTarget) {
|
|
103
|
+
return false;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Currently we can't move in any direction if there are merged cells in the source
|
|
107
|
+
const hasMergedCellsInSource = isRow
|
|
108
|
+
? hasMergedCellsInRow(selectedIndexes)(selection)
|
|
109
|
+
: hasMergedCellsInColumn(selectedIndexes)(selection);
|
|
110
|
+
if (hasMergedCellsInSource) {
|
|
111
|
+
return false;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
return true;
|
|
115
|
+
};
|
|
64
116
|
|
|
65
117
|
const isDistributeColumnsEnabled = (state: EditorState) => {
|
|
66
118
|
const rect = getClosestSelectionRect(state);
|
|
@@ -135,6 +187,8 @@ export const getDragMenuConfig = (
|
|
|
135
187
|
keymap: addColumnAfter,
|
|
136
188
|
},
|
|
137
189
|
];
|
|
190
|
+
|
|
191
|
+
const { selection } = editorView.state;
|
|
138
192
|
const moveOptions =
|
|
139
193
|
direction === 'row'
|
|
140
194
|
? [
|
|
@@ -142,8 +196,15 @@ export const getDragMenuConfig = (
|
|
|
142
196
|
label: 'up',
|
|
143
197
|
icon: ArrowUpIcon,
|
|
144
198
|
keymap: moveRowUp,
|
|
145
|
-
canMove:
|
|
146
|
-
canDrag &&
|
|
199
|
+
canMove:
|
|
200
|
+
canDrag &&
|
|
201
|
+
canMove(
|
|
202
|
+
'table-row',
|
|
203
|
+
-1,
|
|
204
|
+
tableMap?.height ?? 0,
|
|
205
|
+
selection,
|
|
206
|
+
selectionRect,
|
|
207
|
+
),
|
|
147
208
|
getOriginIndexes: getSelectedRowIndexes,
|
|
148
209
|
getTargetIndex: (selectionRect: Rect) => selectionRect.top - 1,
|
|
149
210
|
},
|
|
@@ -151,11 +212,14 @@ export const getDragMenuConfig = (
|
|
|
151
212
|
label: 'down',
|
|
152
213
|
icon: ArrowDownIcon,
|
|
153
214
|
keymap: moveRowDown,
|
|
154
|
-
canMove:
|
|
215
|
+
canMove:
|
|
155
216
|
canDrag &&
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
217
|
+
canMove(
|
|
218
|
+
'table-row',
|
|
219
|
+
1,
|
|
220
|
+
tableMap?.height ?? 0,
|
|
221
|
+
selection,
|
|
222
|
+
selectionRect,
|
|
159
223
|
),
|
|
160
224
|
getOriginIndexes: getSelectedRowIndexes,
|
|
161
225
|
getTargetIndex: (selectionRect: Rect) => selectionRect.bottom,
|
|
@@ -166,8 +230,15 @@ export const getDragMenuConfig = (
|
|
|
166
230
|
label: 'left',
|
|
167
231
|
icon: ArrowLeftIcon,
|
|
168
232
|
keymap: moveColumnLeft,
|
|
169
|
-
canMove:
|
|
170
|
-
canDrag &&
|
|
233
|
+
canMove:
|
|
234
|
+
canDrag &&
|
|
235
|
+
canMove(
|
|
236
|
+
'table-column',
|
|
237
|
+
-1,
|
|
238
|
+
tableMap?.width ?? 0,
|
|
239
|
+
selection,
|
|
240
|
+
selectionRect,
|
|
241
|
+
),
|
|
171
242
|
getOriginIndexes: getSelectedColumnIndexes,
|
|
172
243
|
getTargetIndex: (selectionRect: Rect) => selectionRect.left - 1,
|
|
173
244
|
},
|
|
@@ -175,11 +246,14 @@ export const getDragMenuConfig = (
|
|
|
175
246
|
label: 'right',
|
|
176
247
|
icon: ArrowRightIcon,
|
|
177
248
|
keymap: moveColumnRight,
|
|
178
|
-
canMove:
|
|
249
|
+
canMove:
|
|
179
250
|
canDrag &&
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
251
|
+
canMove(
|
|
252
|
+
'table-column',
|
|
253
|
+
1,
|
|
254
|
+
tableMap?.width ?? 0,
|
|
255
|
+
selection,
|
|
256
|
+
selectionRect,
|
|
183
257
|
),
|
|
184
258
|
getOriginIndexes: getSelectedColumnIndexes,
|
|
185
259
|
getTargetIndex: (selectionRect: Rect) => selectionRect.right,
|
|
@@ -275,10 +349,10 @@ export const getDragMenuConfig = (
|
|
|
275
349
|
({ label, canMove, icon, keymap, getOriginIndexes, getTargetIndex }) => ({
|
|
276
350
|
id: `move_${direction}_${label}`,
|
|
277
351
|
title: `Move ${direction} ${label}`,
|
|
278
|
-
disabled: !canMove
|
|
352
|
+
disabled: !canMove,
|
|
279
353
|
icon,
|
|
280
354
|
onClick: (state: EditorState, dispatch?: CommandDispatch) => {
|
|
281
|
-
if (canMove
|
|
355
|
+
if (canMove) {
|
|
282
356
|
requestAnimationFrame(() => {
|
|
283
357
|
moveSourceWithAnalytics(editorAnalyticsAPI)(
|
|
284
358
|
INPUT_METHOD.TABLE_CONTEXT_MENU,
|
|
@@ -147,3 +147,81 @@ export const hasMergedCellsInBetween =
|
|
|
147
147
|
mergedCellsInRectArr[1].includes(cell),
|
|
148
148
|
);
|
|
149
149
|
};
|
|
150
|
+
|
|
151
|
+
// Checks if any cell in the column with colIndex is merged with a cell in a column to the left or to the right of it.
|
|
152
|
+
// colIndex is a logical index of the column. It starts at 0 and goes up to tableMap.width - 1.
|
|
153
|
+
export const hasMergedCellsWithColumnNextToColumnIndex = (
|
|
154
|
+
colIndex: number,
|
|
155
|
+
selection: Selection,
|
|
156
|
+
) => {
|
|
157
|
+
const table = findTable(selection);
|
|
158
|
+
if (!table) {
|
|
159
|
+
return false;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
const tableMap = TableMap.get(table.node);
|
|
163
|
+
const { width } = tableMap;
|
|
164
|
+
if (width <= 1) {
|
|
165
|
+
return false;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
if (colIndex < 0 || colIndex > width - 1) {
|
|
169
|
+
return false;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
const { map } = tableMap;
|
|
173
|
+
// j is an index in the tableMap.map array. tableMap.map is a flat array.
|
|
174
|
+
// Each item of this array contains a number.
|
|
175
|
+
// The number represents the position of the corresponding cell in the tableMap. It exists for each cell.
|
|
176
|
+
// If there are merged cells, their positions will be represented by the same number.
|
|
177
|
+
const isFirstColumn = colIndex === 0;
|
|
178
|
+
const isLastColumn = colIndex === width - 1;
|
|
179
|
+
for (let j = colIndex; j < map.length; j += width) {
|
|
180
|
+
if (
|
|
181
|
+
(!isFirstColumn && map[j] === map[j - 1]) || // compare with a cell in the column on the left
|
|
182
|
+
(!isLastColumn && map[j] === map[j + 1]) // compare with a cell in the column on the right
|
|
183
|
+
) {
|
|
184
|
+
return true;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
return false;
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
// Checks if any cell in the row with rowIndex is merged with a cell in a row above or below it.
|
|
192
|
+
export const hasMergedCellsWithRowNextToRowIndex = (
|
|
193
|
+
rowIndex: number, // logical row index in the table. It starts at 0 and goes up to tableMap.height - 1.
|
|
194
|
+
selection: Selection,
|
|
195
|
+
) => {
|
|
196
|
+
const table = findTable(selection);
|
|
197
|
+
if (!table) {
|
|
198
|
+
return false;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
const tableMap = TableMap.get(table.node);
|
|
202
|
+
const { height } = tableMap;
|
|
203
|
+
if (height <= 1) {
|
|
204
|
+
return false;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
if (rowIndex < 0 || rowIndex > height - 1) {
|
|
208
|
+
return false;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
const { map, width } = tableMap; // map is a flat array representing position of each cell in the table.
|
|
212
|
+
const indexOfFirstCellInTheRow = rowIndex * width;
|
|
213
|
+
const indexOfLastCellInTheRow = indexOfFirstCellInTheRow + width - 1;
|
|
214
|
+
const isFirstRow = rowIndex === 0;
|
|
215
|
+
const isLastRow = rowIndex === height - 1;
|
|
216
|
+
// j is an index of a cell in a row
|
|
217
|
+
for (let j = indexOfFirstCellInTheRow; j <= indexOfLastCellInTheRow; j++) {
|
|
218
|
+
if (
|
|
219
|
+
(!isFirstRow && map[j] === map[j - width]) || // compare with a cell in the row above
|
|
220
|
+
(!isLastRow && map[j] === map[j + width]) // compare with a cell in the row below
|
|
221
|
+
) {
|
|
222
|
+
return true;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
return false;
|
|
227
|
+
};
|
package/tsconfig.dev.json
CHANGED
|
@@ -36,83 +36,14 @@
|
|
|
36
36
|
{
|
|
37
37
|
"path": "tsconfig.app.json"
|
|
38
38
|
},
|
|
39
|
-
{
|
|
40
|
-
"path": "../../analytics/analytics-next/tsconfig.app.json"
|
|
41
|
-
},
|
|
42
|
-
{
|
|
43
|
-
"path": "../../design-system/button/tsconfig.app.json"
|
|
44
|
-
},
|
|
45
|
-
{
|
|
46
|
-
"path": "../custom-steps/tsconfig.app.json"
|
|
47
|
-
},
|
|
48
39
|
{
|
|
49
40
|
"path": "../../../build/website/docs/tsconfig.app.json"
|
|
50
41
|
},
|
|
51
|
-
{
|
|
52
|
-
"path": "../editor-common/tsconfig.app.json"
|
|
53
|
-
},
|
|
54
42
|
{
|
|
55
43
|
"path": "../editor-core/tsconfig.app.json"
|
|
56
44
|
},
|
|
57
|
-
{
|
|
58
|
-
"path": "../editor-plugin-analytics/tsconfig.app.json"
|
|
59
|
-
},
|
|
60
|
-
{
|
|
61
|
-
"path": "../editor-plugin-content-insertion/tsconfig.app.json"
|
|
62
|
-
},
|
|
63
|
-
{
|
|
64
|
-
"path": "../editor-plugin-decorations/tsconfig.app.json"
|
|
65
|
-
},
|
|
66
|
-
{
|
|
67
|
-
"path": "../editor-plugin-feature-flags/tsconfig.app.json"
|
|
68
|
-
},
|
|
69
|
-
{
|
|
70
|
-
"path": "../editor-plugin-grid/tsconfig.app.json"
|
|
71
|
-
},
|
|
72
|
-
{
|
|
73
|
-
"path": "../editor-plugin-guideline/tsconfig.app.json"
|
|
74
|
-
},
|
|
75
|
-
{
|
|
76
|
-
"path": "../editor-plugin-selection/tsconfig.app.json"
|
|
77
|
-
},
|
|
78
|
-
{
|
|
79
|
-
"path": "../editor-plugin-width/tsconfig.app.json"
|
|
80
|
-
},
|
|
81
|
-
{
|
|
82
|
-
"path": "../editor-shared-styles/tsconfig.app.json"
|
|
83
|
-
},
|
|
84
|
-
{
|
|
85
|
-
"path": "../editor-tables/tsconfig.app.json"
|
|
86
|
-
},
|
|
87
|
-
{
|
|
88
|
-
"path": "../editor-test-helpers/tsconfig.app.json"
|
|
89
|
-
},
|
|
90
|
-
{
|
|
91
|
-
"path": "../../linking-platform/link-provider/tsconfig.app.json"
|
|
92
|
-
},
|
|
93
|
-
{
|
|
94
|
-
"path": "../../design-system/logo/tsconfig.app.json"
|
|
95
|
-
},
|
|
96
|
-
{
|
|
97
|
-
"path": "../../media/media-integration-test-helpers/tsconfig.app.json"
|
|
98
|
-
},
|
|
99
|
-
{
|
|
100
|
-
"path": "../../platform/feature-flags/tsconfig.app.json"
|
|
101
|
-
},
|
|
102
|
-
{
|
|
103
|
-
"path": "../synchrony-test-helpers/tsconfig.app.json"
|
|
104
|
-
},
|
|
105
|
-
{
|
|
106
|
-
"path": "../../design-system/theme/tsconfig.app.json"
|
|
107
|
-
},
|
|
108
45
|
{
|
|
109
46
|
"path": "../../design-system/tokens/tsconfig.app.json"
|
|
110
|
-
},
|
|
111
|
-
{
|
|
112
|
-
"path": "../../../build/test-tooling/visual-regression/tsconfig.app.json"
|
|
113
|
-
},
|
|
114
|
-
{
|
|
115
|
-
"path": "../../platform/feature-flags-test-utils/tsconfig.app.json"
|
|
116
47
|
}
|
|
117
48
|
]
|
|
118
49
|
}
|