@atlaskit/editor-plugin-table 7.1.0 → 7.1.2
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 +16 -0
- package/dist/cjs/event-handlers.js +4 -1
- package/dist/cjs/pm-plugins/drag-and-drop/commands-with-analytics.js +9 -9
- package/dist/cjs/pm-plugins/drag-and-drop/commands.js +4 -11
- package/dist/cjs/pm-plugins/drag-and-drop/plugin.js +1 -4
- package/dist/cjs/pm-plugins/drag-and-drop/utils/monitor.js +0 -5
- package/dist/cjs/types.js +1 -0
- package/dist/cjs/ui/DragHandle/index.js +27 -9
- package/dist/cjs/ui/FloatingContextualMenu/ContextualMenu.js +1 -1
- package/dist/cjs/ui/FloatingContextualMenu/index.js +4 -3
- package/dist/cjs/ui/FloatingContextualMenu/styles.js +3 -1
- package/dist/cjs/ui/TableFloatingColumnControls/ColumnControls/index.js +12 -4
- package/dist/cjs/ui/TableFloatingColumnControls/ColumnDropTargets/index.js +1 -7
- package/dist/cjs/ui/TableFloatingColumnControls/index.js +0 -2
- package/dist/cjs/ui/TableFloatingControls/RowControls/DragControls.js +10 -2
- package/dist/cjs/ui/common-styles.js +2 -1
- package/dist/cjs/ui/consts.js +3 -3
- package/dist/cjs/ui/ui-styles.js +8 -8
- package/dist/cjs/utils/drag-menu.js +42 -29
- package/dist/es2019/event-handlers.js +3 -2
- package/dist/es2019/pm-plugins/drag-and-drop/commands-with-analytics.js +8 -8
- package/dist/es2019/pm-plugins/drag-and-drop/commands.js +5 -10
- package/dist/es2019/pm-plugins/drag-and-drop/plugin.js +1 -4
- package/dist/es2019/pm-plugins/drag-and-drop/utils/monitor.js +0 -5
- package/dist/es2019/types.js +1 -0
- package/dist/es2019/ui/DragHandle/index.js +26 -8
- package/dist/es2019/ui/FloatingContextualMenu/ContextualMenu.js +2 -2
- package/dist/es2019/ui/FloatingContextualMenu/index.js +5 -4
- package/dist/es2019/ui/FloatingContextualMenu/styles.js +3 -3
- package/dist/es2019/ui/TableFloatingColumnControls/ColumnControls/index.js +10 -4
- package/dist/es2019/ui/TableFloatingColumnControls/ColumnDropTargets/index.js +1 -7
- package/dist/es2019/ui/TableFloatingColumnControls/index.js +0 -2
- package/dist/es2019/ui/TableFloatingControls/RowControls/DragControls.js +8 -2
- package/dist/es2019/ui/common-styles.js +24 -5
- package/dist/es2019/ui/consts.js +2 -2
- package/dist/es2019/ui/ui-styles.js +8 -8
- package/dist/es2019/utils/drag-menu.js +29 -24
- package/dist/esm/event-handlers.js +5 -2
- package/dist/esm/pm-plugins/drag-and-drop/commands-with-analytics.js +9 -9
- package/dist/esm/pm-plugins/drag-and-drop/commands.js +5 -12
- package/dist/esm/pm-plugins/drag-and-drop/plugin.js +1 -4
- package/dist/esm/pm-plugins/drag-and-drop/utils/monitor.js +0 -5
- package/dist/esm/types.js +1 -0
- package/dist/esm/ui/DragHandle/index.js +27 -9
- package/dist/esm/ui/FloatingContextualMenu/ContextualMenu.js +2 -2
- package/dist/esm/ui/FloatingContextualMenu/index.js +5 -4
- package/dist/esm/ui/FloatingContextualMenu/styles.js +4 -2
- package/dist/esm/ui/TableFloatingColumnControls/ColumnControls/index.js +12 -4
- package/dist/esm/ui/TableFloatingColumnControls/ColumnDropTargets/index.js +1 -7
- package/dist/esm/ui/TableFloatingColumnControls/index.js +0 -2
- package/dist/esm/ui/TableFloatingControls/RowControls/DragControls.js +10 -2
- package/dist/esm/ui/common-styles.js +2 -1
- package/dist/esm/ui/consts.js +2 -2
- package/dist/esm/ui/ui-styles.js +8 -8
- package/dist/esm/utils/drag-menu.js +41 -28
- package/dist/types/types.d.ts +1 -0
- package/dist/types/ui/FloatingContextualMenu/styles.d.ts +1 -1
- package/dist/types/ui/TableFloatingColumnControls/ColumnDropTargets/index.d.ts +0 -2
- package/dist/types/ui/consts.d.ts +2 -1
- package/dist/types/ui/ui-styles.d.ts +2 -2
- package/dist/types-ts4.5/types.d.ts +1 -0
- package/dist/types-ts4.5/ui/FloatingContextualMenu/styles.d.ts +1 -1
- package/dist/types-ts4.5/ui/TableFloatingColumnControls/ColumnDropTargets/index.d.ts +0 -2
- package/dist/types-ts4.5/ui/consts.d.ts +2 -1
- package/dist/types-ts4.5/ui/ui-styles.d.ts +2 -2
- package/package.json +3 -5
- package/src/__tests__/unit/event-handlers.ts +3 -17
- package/src/__tests__/unit/nodeviews/TableComponent.tsx +1 -1
- package/src/__tests__/unit/pm-plugins/decorations/column-controls.ts +46 -17
- package/src/event-handlers.ts +14 -2
- package/src/pm-plugins/drag-and-drop/commands-with-analytics.ts +11 -8
- package/src/pm-plugins/drag-and-drop/commands.ts +5 -33
- package/src/pm-plugins/drag-and-drop/plugin.ts +0 -3
- package/src/pm-plugins/drag-and-drop/utils/monitor.ts +0 -5
- package/src/types.ts +1 -0
- package/src/ui/DragHandle/index.tsx +33 -14
- package/src/ui/FloatingContextualMenu/ContextualMenu.tsx +9 -2
- package/src/ui/FloatingContextualMenu/index.tsx +10 -3
- package/src/ui/FloatingContextualMenu/styles.ts +10 -3
- package/src/ui/TableFloatingColumnControls/ColumnControls/index.tsx +21 -5
- package/src/ui/TableFloatingColumnControls/ColumnDropTargets/index.tsx +1 -13
- package/src/ui/TableFloatingColumnControls/index.tsx +0 -2
- package/src/ui/TableFloatingControls/RowControls/DragControls.tsx +22 -8
- package/src/ui/common-styles.ts +20 -4
- package/src/ui/consts.ts +2 -6
- package/src/ui/ui-styles.ts +12 -8
- package/src/utils/drag-menu.ts +48 -32
- package/tsconfig.json +273 -0
|
@@ -7,11 +7,11 @@ import type { EventDispatcher } from '@atlaskit/editor-common/event-dispatcher';
|
|
|
7
7
|
import type { Command, DocBuilder } from '@atlaskit/editor-common/types';
|
|
8
8
|
import { TextSelection } from '@atlaskit/editor-prosemirror/state';
|
|
9
9
|
import type { EditorView } from '@atlaskit/editor-prosemirror/view';
|
|
10
|
-
import { selectTableClosestToPos } from '@atlaskit/editor-tables/src/utils/select-nodes';
|
|
11
10
|
import {
|
|
12
11
|
findTable,
|
|
13
12
|
findTableClosestToPos,
|
|
14
13
|
selectTable,
|
|
14
|
+
selectTableClosestToPos,
|
|
15
15
|
} from '@atlaskit/editor-tables/utils';
|
|
16
16
|
// eslint-disable-next-line import/no-extraneous-dependencies -- Removed import for fixing circular dependencies
|
|
17
17
|
import { createEditorFactory } from '@atlaskit/editor-test-helpers/create-editor';
|
|
@@ -1,7 +1,19 @@
|
|
|
1
|
+
import type { DocBuilder } from '@atlaskit/editor-common/types';
|
|
2
|
+
import type { LightEditorPlugin } from '@atlaskit/editor-core/src/create-editor/get-plugins';
|
|
3
|
+
import { analyticsPlugin } from '@atlaskit/editor-plugin-analytics';
|
|
4
|
+
import { contentInsertionPlugin } from '@atlaskit/editor-plugin-content-insertion';
|
|
5
|
+
import { decorationsPlugin } from '@atlaskit/editor-plugin-decorations';
|
|
6
|
+
import { featureFlagsPlugin } from '@atlaskit/editor-plugin-feature-flags';
|
|
7
|
+
import { gridPlugin } from '@atlaskit/editor-plugin-grid';
|
|
8
|
+
import { guidelinePlugin } from '@atlaskit/editor-plugin-guideline';
|
|
9
|
+
import { selectionPlugin } from '@atlaskit/editor-plugin-selection';
|
|
10
|
+
import { widthPlugin } from '@atlaskit/editor-plugin-width';
|
|
1
11
|
import { DecorationSet } from '@atlaskit/editor-prosemirror/view';
|
|
2
12
|
// eslint-disable-next-line import/no-extraneous-dependencies -- Removed import for fixing circular dependencies
|
|
3
|
-
import {
|
|
4
|
-
|
|
13
|
+
import {
|
|
14
|
+
createProsemirrorEditorFactory,
|
|
15
|
+
Preset,
|
|
16
|
+
} from '@atlaskit/editor-test-helpers/create-prosemirror-editor';
|
|
5
17
|
import {
|
|
6
18
|
doc,
|
|
7
19
|
table,
|
|
@@ -9,27 +21,43 @@ import {
|
|
|
9
21
|
tdEmpty,
|
|
10
22
|
tr,
|
|
11
23
|
} from '@atlaskit/editor-test-helpers/doc-builder';
|
|
12
|
-
import { getBooleanFF } from '@atlaskit/platform-feature-flags';
|
|
13
24
|
|
|
25
|
+
import tablePlugin from '../../../../plugin';
|
|
14
26
|
import { buildColumnControlsDecorations } from '../../../../pm-plugins/decorations/utils';
|
|
27
|
+
import { pluginKey } from '../../../../pm-plugins/plugin-key';
|
|
15
28
|
import { TableDecorations } from '../../../../types';
|
|
16
29
|
|
|
17
|
-
// Mock Feature flags instead of using ffTest because we don't use the feature flag directly
|
|
18
|
-
jest.mock('@atlaskit/platform-feature-flags', () => ({
|
|
19
|
-
getBooleanFF: jest.fn().mockImplementation(() => false),
|
|
20
|
-
}));
|
|
21
|
-
|
|
22
|
-
afterEach(() => {
|
|
23
|
-
(getBooleanFF as jest.Mock).mockReset();
|
|
24
|
-
});
|
|
25
|
-
|
|
26
30
|
describe('tables: column controls decorations', () => {
|
|
31
|
+
const createEditor = createProsemirrorEditorFactory();
|
|
32
|
+
const editor = (doc: DocBuilder, isDragAndDropEnabled = false) =>
|
|
33
|
+
createEditor({
|
|
34
|
+
doc,
|
|
35
|
+
attachTo: document.body,
|
|
36
|
+
featureFlags: {
|
|
37
|
+
tableDragAndDrop: isDragAndDropEnabled,
|
|
38
|
+
},
|
|
39
|
+
preset: new Preset<LightEditorPlugin>()
|
|
40
|
+
.add([featureFlagsPlugin, {}])
|
|
41
|
+
.add([analyticsPlugin, {}])
|
|
42
|
+
.add(contentInsertionPlugin)
|
|
43
|
+
.add(decorationsPlugin)
|
|
44
|
+
.add(widthPlugin)
|
|
45
|
+
.add(guidelinePlugin)
|
|
46
|
+
.add(gridPlugin)
|
|
47
|
+
.add(selectionPlugin)
|
|
48
|
+
.add([
|
|
49
|
+
tablePlugin,
|
|
50
|
+
{
|
|
51
|
+
tableOptions: { advanced: true },
|
|
52
|
+
},
|
|
53
|
+
]),
|
|
54
|
+
pluginKey,
|
|
55
|
+
});
|
|
56
|
+
|
|
27
57
|
it(`should return an empty decorationSet ${TableDecorations.COLUMN_CONTROLS_DECORATIONS} type when drag and drop is enabled`, () => {
|
|
28
|
-
(getBooleanFF as jest.Mock).mockImplementation(
|
|
29
|
-
(name) => name === 'platform.editor.table.drag-and-drop',
|
|
30
|
-
);
|
|
31
58
|
const decorationKey = TableDecorations.COLUMN_CONTROLS_DECORATIONS;
|
|
32
|
-
const
|
|
59
|
+
const editorInstance = editor(doc(table()(tr(tdCursor, tdEmpty))), true);
|
|
60
|
+
const state = editorInstance.editorView.state;
|
|
33
61
|
const nextDecorationSet = buildColumnControlsDecorations({
|
|
34
62
|
decorationSet: DecorationSet.empty,
|
|
35
63
|
tr: state.tr,
|
|
@@ -47,7 +75,8 @@ describe('tables: column controls decorations', () => {
|
|
|
47
75
|
|
|
48
76
|
it(`should return an empty decorationSet ${TableDecorations.COLUMN_CONTROLS_DECORATIONS} type when drag and drop is disabled`, () => {
|
|
49
77
|
const decorationKey = TableDecorations.COLUMN_CONTROLS_DECORATIONS;
|
|
50
|
-
const
|
|
78
|
+
const editorInstance = editor(doc(table()(tr(tdCursor, tdEmpty))), false);
|
|
79
|
+
const state = editorInstance.editorView.state;
|
|
51
80
|
const nextDecorationSet = buildColumnControlsDecorations({
|
|
52
81
|
decorationSet: DecorationSet.empty,
|
|
53
82
|
tr: state.tr,
|
package/src/event-handlers.ts
CHANGED
|
@@ -47,7 +47,10 @@ import { getPluginState } from './pm-plugins/plugin-factory';
|
|
|
47
47
|
import { getPluginState as getResizePluginState } from './pm-plugins/table-resizing/plugin-factory';
|
|
48
48
|
import { deleteColumns, deleteRows } from './transforms';
|
|
49
49
|
import type { ElementContentRects } from './types';
|
|
50
|
-
import {
|
|
50
|
+
import {
|
|
51
|
+
TableCssClassName as ClassName,
|
|
52
|
+
RESIZE_HANDLE_AREA_DECORATION_GAP,
|
|
53
|
+
} from './types';
|
|
51
54
|
import {
|
|
52
55
|
convertHTMLCellIndexToColumnIndex,
|
|
53
56
|
getColumnIndexMappedToColumnIndexInFirstRow,
|
|
@@ -91,6 +94,14 @@ const isFocusingDragHandles = (event: Event) =>
|
|
|
91
94
|
event.relatedTarget.closest('button') &&
|
|
92
95
|
event.relatedTarget.getAttribute('draggable') === 'true';
|
|
93
96
|
|
|
97
|
+
const isFocusingDragHandlesClickableZone = (event: Event) =>
|
|
98
|
+
event instanceof FocusEvent &&
|
|
99
|
+
event.relatedTarget instanceof HTMLElement &&
|
|
100
|
+
event.relatedTarget.closest('button') &&
|
|
101
|
+
event.relatedTarget.classList.contains(
|
|
102
|
+
ClassName.DRAG_HANDLE_BUTTON_CLICKABLE_ZONE,
|
|
103
|
+
);
|
|
104
|
+
|
|
94
105
|
export const handleBlur = (view: EditorView, event: Event): boolean => {
|
|
95
106
|
const { state, dispatch } = view;
|
|
96
107
|
// IE version check for ED-4665
|
|
@@ -100,7 +111,8 @@ export const handleBlur = (view: EditorView, event: Event): boolean => {
|
|
|
100
111
|
!isFocusingCalendar(event) &&
|
|
101
112
|
!isFocusingModal(event) &&
|
|
102
113
|
!isFocusingFloatingToolbar(event) &&
|
|
103
|
-
!isFocusingDragHandles(event)
|
|
114
|
+
!isFocusingDragHandles(event) &&
|
|
115
|
+
!isFocusingDragHandlesClickableZone(event)
|
|
104
116
|
) {
|
|
105
117
|
setEditorFocus(false)(state, dispatch);
|
|
106
118
|
}
|
|
@@ -79,6 +79,7 @@ export const moveSourceWithAnalytics =
|
|
|
79
79
|
tr?: Transaction,
|
|
80
80
|
) => {
|
|
81
81
|
return withEditorAnalyticsAPI(({ selection }: EditorState) => {
|
|
82
|
+
const direction = sourceIndexes[0] > targetIndex ? -1 : 1;
|
|
82
83
|
const { totalRowCount, totalColumnCount } =
|
|
83
84
|
getSelectedTableInfo(selection);
|
|
84
85
|
return {
|
|
@@ -93,7 +94,9 @@ export const moveSourceWithAnalytics =
|
|
|
93
94
|
count: sourceIndexes.length,
|
|
94
95
|
// This identifies the total amount of row/cols the move operation covered. The distance covered should be a representaion
|
|
95
96
|
// of the minimum distance. This will account for large selection being moved causing a large distance travelled value.
|
|
96
|
-
distance:
|
|
97
|
+
distance:
|
|
98
|
+
Math.min(...sourceIndexes.map((v) => Math.abs(targetIndex - v))) *
|
|
99
|
+
direction,
|
|
97
100
|
// If a drop doesn't actually change anything then we're going to mark the event as cancelled.
|
|
98
101
|
status: sourceIndexes.includes(targetIndex)
|
|
99
102
|
? TABLE_STATUS.CANCELLED
|
|
@@ -130,15 +133,15 @@ export const moveSourceWithAnalyticsViaShortcut =
|
|
|
130
133
|
? getSelectedRowIndexes(selectionRect)
|
|
131
134
|
: getSelectedColumnIndexes(selectionRect);
|
|
132
135
|
|
|
133
|
-
|
|
134
|
-
if (selectedIndexes.length === 0 || selectedIndexes.length > 1) {
|
|
136
|
+
if (selectedIndexes.length === 0) {
|
|
135
137
|
return false;
|
|
136
138
|
}
|
|
137
139
|
|
|
138
|
-
const sourceIndex = selectedIndexes[0];
|
|
140
|
+
// const sourceIndex = selectedIndexes[0];
|
|
139
141
|
// we can move only by one row/column
|
|
140
142
|
// 'direction' can only be 1 (for right or down) or -1 (for left or up)
|
|
141
|
-
const targetIndex =
|
|
143
|
+
const targetIndex =
|
|
144
|
+
Math[direction < 0 ? 'min' : 'max'](...selectedIndexes) + direction;
|
|
142
145
|
|
|
143
146
|
// We can move only if targetIndex is a positive number and is not higher than the total number of rows/columns.
|
|
144
147
|
const { totalRowCount, totalColumnCount } = getSelectedTableInfo(selection);
|
|
@@ -155,8 +158,8 @@ export const moveSourceWithAnalyticsViaShortcut =
|
|
|
155
158
|
|
|
156
159
|
// We can move only if there are no merged cells in the source or target row/column
|
|
157
160
|
const hasMergedCellsInSource = isRow
|
|
158
|
-
? hasMergedCellsInRow(
|
|
159
|
-
: hasMergedCellsInColumn(
|
|
161
|
+
? hasMergedCellsInRow(selectedIndexes)(selection)
|
|
162
|
+
: hasMergedCellsInColumn(selectedIndexes)(selection);
|
|
160
163
|
if (hasMergedCellsInSource) {
|
|
161
164
|
return false;
|
|
162
165
|
}
|
|
@@ -171,7 +174,7 @@ export const moveSourceWithAnalyticsViaShortcut =
|
|
|
171
174
|
return moveSourceWithAnalytics(editorAnalyticsAPI)(
|
|
172
175
|
INPUT_METHOD.SHORTCUT,
|
|
173
176
|
sourceType,
|
|
174
|
-
|
|
177
|
+
selectedIndexes,
|
|
175
178
|
targetIndex,
|
|
176
179
|
)(state, dispatch);
|
|
177
180
|
};
|
|
@@ -2,15 +2,9 @@ import type {
|
|
|
2
2
|
EditorState,
|
|
3
3
|
Transaction,
|
|
4
4
|
} from '@atlaskit/editor-prosemirror/state';
|
|
5
|
-
import { TextSelection } from '@atlaskit/editor-prosemirror/state';
|
|
6
5
|
import type { Decoration } from '@atlaskit/editor-prosemirror/view';
|
|
7
6
|
import { DecorationSet } from '@atlaskit/editor-prosemirror/view';
|
|
8
|
-
import {
|
|
9
|
-
moveColumn,
|
|
10
|
-
moveRow,
|
|
11
|
-
selectColumn,
|
|
12
|
-
selectRow,
|
|
13
|
-
} from '@atlaskit/editor-tables/utils';
|
|
7
|
+
import { moveColumn, moveRow } from '@atlaskit/editor-tables/utils';
|
|
14
8
|
|
|
15
9
|
import type { DraggableType, TableDirection } from '../../types';
|
|
16
10
|
import { TableDecorations } from '../../types';
|
|
@@ -19,7 +13,6 @@ import {
|
|
|
19
13
|
createRowInsertLine,
|
|
20
14
|
updateDecorations,
|
|
21
15
|
} from '../../utils';
|
|
22
|
-
import { combineTransforms } from '../../utils/transforms';
|
|
23
16
|
|
|
24
17
|
import { DragAndDropActionType } from './actions';
|
|
25
18
|
import { DropTargetType } from './consts';
|
|
@@ -118,31 +111,10 @@ export const moveSource = (
|
|
|
118
111
|
if (sourceIndexes.includes(targetIndex)) {
|
|
119
112
|
return nextTr.setMeta('addToHistory', false);
|
|
120
113
|
}
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
const isTableRow = sourceType === 'table-row';
|
|
127
|
-
if (isTableRow) {
|
|
128
|
-
return combineTransforms(
|
|
129
|
-
[
|
|
130
|
-
moveRow(state, sourceIndexes, targetIndex),
|
|
131
|
-
selectStartOfTable,
|
|
132
|
-
selectRow(targetIndex),
|
|
133
|
-
],
|
|
134
|
-
nextTr,
|
|
135
|
-
);
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
return combineTransforms(
|
|
139
|
-
[
|
|
140
|
-
moveColumn(state, sourceIndexes, targetIndex),
|
|
141
|
-
selectStartOfTable,
|
|
142
|
-
selectColumn(targetIndex),
|
|
143
|
-
],
|
|
144
|
-
nextTr,
|
|
145
|
-
);
|
|
114
|
+
const move = sourceType === 'table-row' ? moveRow : moveColumn;
|
|
115
|
+
return move(state, sourceIndexes, targetIndex, {
|
|
116
|
+
selectAfterMove: true,
|
|
117
|
+
})(nextTr);
|
|
146
118
|
},
|
|
147
119
|
);
|
|
148
120
|
|
|
@@ -82,9 +82,6 @@ const destroyFn = (editorView: EditorView, editorAnalyticsAPI: any) => {
|
|
|
82
82
|
if (
|
|
83
83
|
!indexes ||
|
|
84
84
|
!localId ||
|
|
85
|
-
// FIXME: We currently don't support DragNDrop of multiple elements. For now we will not bother to monitor drags
|
|
86
|
-
// of more then 1 item.
|
|
87
|
-
indexes.length !== 1 ||
|
|
88
85
|
!(type === 'table-row' || type === 'table-column')
|
|
89
86
|
) {
|
|
90
87
|
return false;
|
|
@@ -45,11 +45,6 @@ export const getDraggableDataFromEvent = ({
|
|
|
45
45
|
return undefined;
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
// FIXME: currently we only support a single row/col index being moved, remove this clause when this is no longer the case.
|
|
49
|
-
if (sourceIndexes.length > 1) {
|
|
50
|
-
return undefined;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
48
|
const targetClosestEdge =
|
|
54
49
|
extractClosestEdge(destination.data) ??
|
|
55
50
|
((targetType === 'table-row' ? 'top' : 'left') as Edge);
|
package/src/types.ts
CHANGED
|
@@ -330,6 +330,7 @@ export const TableCssClassName = {
|
|
|
330
330
|
DRAG_COLUMN_CONTROLS_INNER: `${tablePrefixSelector}-col-controls__inner`,
|
|
331
331
|
|
|
332
332
|
DRAG_HANDLE_BUTTON_CONTAINER: `${tablePrefixSelector}-drag-handle-button-container`,
|
|
333
|
+
DRAG_HANDLE_BUTTON_CLICKABLE_ZONE: `${tablePrefixSelector}-drag-handle-button-clickable-zone`,
|
|
333
334
|
|
|
334
335
|
DRAG_CORNER_BUTTON: `${tablePrefixSelector}-drag-corner-button`,
|
|
335
336
|
DRAG_CORNER_BUTTON_INNER: `${tablePrefixSelector}-drag-corner-button-inner`,
|
|
@@ -11,11 +11,13 @@ import { browser } from '@atlaskit/editor-common/utils';
|
|
|
11
11
|
import type { EditorView } from '@atlaskit/editor-prosemirror/view';
|
|
12
12
|
import { draggable } from '@atlaskit/pragmatic-drag-and-drop/adapter/element';
|
|
13
13
|
import { setCustomNativeDragPreview } from '@atlaskit/pragmatic-drag-and-drop/util/set-custom-native-drag-preview';
|
|
14
|
+
import { token } from '@atlaskit/tokens';
|
|
14
15
|
|
|
15
16
|
import { getPluginState } from '../../pm-plugins/plugin-factory';
|
|
16
17
|
import type { TableDirection } from '../../types';
|
|
17
18
|
import { TableCssClassName as ClassName } from '../../types';
|
|
18
19
|
import { hasMergedCellsInColumn, hasMergedCellsInRow } from '../../utils';
|
|
20
|
+
import { dragTableInsertColumnButtonSize } from '../consts';
|
|
19
21
|
import { DragPreview } from '../DragPreview';
|
|
20
22
|
|
|
21
23
|
import { HandleIconComponent } from './HandleIconComponent';
|
|
@@ -64,17 +66,18 @@ const DragHandleComponent = ({
|
|
|
64
66
|
const { hoveredColumns, hoveredRows } = getPluginState(editorView.state);
|
|
65
67
|
|
|
66
68
|
const { selection } = editorView.state;
|
|
69
|
+
const isRow = direction === 'row';
|
|
70
|
+
const isColumn = direction === 'column';
|
|
67
71
|
|
|
68
|
-
const isRowHandleHovered =
|
|
69
|
-
const isColumnHandleHovered =
|
|
70
|
-
direction === 'column' && hoveredColumns.length > 0;
|
|
72
|
+
const isRowHandleHovered = isRow && hoveredRows.length > 0;
|
|
73
|
+
const isColumnHandleHovered = isColumn && hoveredColumns.length > 0;
|
|
71
74
|
|
|
72
75
|
const hasMergedCells = useMemo(
|
|
73
76
|
() =>
|
|
74
|
-
|
|
77
|
+
isRow
|
|
75
78
|
? hasMergedCellsInRow(indexes[0])(selection)
|
|
76
79
|
: hasMergedCellsInColumn(indexes[0])(selection),
|
|
77
|
-
[indexes,
|
|
80
|
+
[indexes, isRow, selection],
|
|
78
81
|
);
|
|
79
82
|
|
|
80
83
|
const handleIconProps = {
|
|
@@ -113,7 +116,7 @@ const DragHandleComponent = ({
|
|
|
113
116
|
// be generated.
|
|
114
117
|
container.style.left = `-${rect.width - 0.0001}px`;
|
|
115
118
|
}
|
|
116
|
-
if (
|
|
119
|
+
if (isRow) {
|
|
117
120
|
return { x: 12, y: rect.height / 2 };
|
|
118
121
|
} else {
|
|
119
122
|
return { x: rect.width / 2 + 4, y: 12 };
|
|
@@ -132,18 +135,35 @@ const DragHandleComponent = ({
|
|
|
132
135
|
tableLocalId,
|
|
133
136
|
direction,
|
|
134
137
|
indexes,
|
|
138
|
+
isRow,
|
|
135
139
|
editorView.state.selection,
|
|
136
140
|
hasMergedCells,
|
|
137
141
|
canDrag,
|
|
138
142
|
]);
|
|
139
143
|
|
|
140
|
-
const showDragMenuAnchorId =
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
: 'drag-handle-button-column';
|
|
144
|
+
const showDragMenuAnchorId = isRow
|
|
145
|
+
? 'drag-handle-button-row'
|
|
146
|
+
: 'drag-handle-button-column';
|
|
144
147
|
|
|
145
148
|
return (
|
|
146
149
|
<>
|
|
150
|
+
<button
|
|
151
|
+
className={ClassName.DRAG_HANDLE_BUTTON_CLICKABLE_ZONE}
|
|
152
|
+
data-testid="table-drag-handle-clickable-zone-button"
|
|
153
|
+
style={{
|
|
154
|
+
height: isRow
|
|
155
|
+
? `calc(100% - ${dragTableInsertColumnButtonSize}px)`
|
|
156
|
+
: `${token('space.200', '16px')}`, // 16px here because it's the size of drag handle button's large side
|
|
157
|
+
width: isRow
|
|
158
|
+
? `${token('space.200', '16px')}` // 16px here because it's the size of drag handle button's large side
|
|
159
|
+
: `calc(100% - ${dragTableInsertColumnButtonSize}px)`,
|
|
160
|
+
left: isRow ? '3px' : undefined,
|
|
161
|
+
bottom: isColumn ? '0' : undefined,
|
|
162
|
+
alignSelf: isColumn ? 'none' : 'center',
|
|
163
|
+
zIndex: isColumn ? '-1' : 'auto',
|
|
164
|
+
}}
|
|
165
|
+
onClick={onClick}
|
|
166
|
+
/>
|
|
147
167
|
<button
|
|
148
168
|
id={isDragMenuTarget ? showDragMenuAnchorId : undefined}
|
|
149
169
|
className={classnames(
|
|
@@ -155,13 +175,12 @@ const DragHandleComponent = ({
|
|
|
155
175
|
)}
|
|
156
176
|
ref={dragHandleDivRef}
|
|
157
177
|
style={{
|
|
158
|
-
transform:
|
|
178
|
+
transform: isColumn ? 'none' : 'rotate(90deg)',
|
|
179
|
+
alignSelf: isColumn ? 'none' : 'center',
|
|
159
180
|
}}
|
|
160
181
|
data-testid="table-drag-handle-button"
|
|
161
182
|
aria-label={formatMessage(
|
|
162
|
-
|
|
163
|
-
? messages.rowDragHandle
|
|
164
|
-
: messages.columnDragHandle,
|
|
183
|
+
isRow ? messages.rowDragHandle : messages.columnDragHandle,
|
|
165
184
|
)}
|
|
166
185
|
onMouseOver={onMouseOver}
|
|
167
186
|
onMouseOut={onMouseOut}
|
|
@@ -73,7 +73,10 @@ import {
|
|
|
73
73
|
getSelectedColumnIndexes,
|
|
74
74
|
getSelectedRowIndexes,
|
|
75
75
|
} from '../../utils';
|
|
76
|
-
import {
|
|
76
|
+
import {
|
|
77
|
+
contextualMenuDropdownWidth,
|
|
78
|
+
contextualMenuDropdownWidthDnD,
|
|
79
|
+
} from '../consts';
|
|
77
80
|
import {
|
|
78
81
|
AddColRightIcon,
|
|
79
82
|
AddRowBelowIcon,
|
|
@@ -145,7 +148,11 @@ export class ContextualMenu extends Component<
|
|
|
145
148
|
onMouseEnter={this.handleItemMouseEnter}
|
|
146
149
|
onMouseLeave={this.handleItemMouseLeave}
|
|
147
150
|
fitHeight={188}
|
|
148
|
-
fitWidth={
|
|
151
|
+
fitWidth={
|
|
152
|
+
isDragAndDropEnabled
|
|
153
|
+
? contextualMenuDropdownWidthDnD
|
|
154
|
+
: contextualMenuDropdownWidth
|
|
155
|
+
}
|
|
149
156
|
boundariesElement={boundariesElement}
|
|
150
157
|
offset={offset}
|
|
151
158
|
section={
|
|
@@ -23,6 +23,7 @@ import { getPluginState } from '../../pm-plugins/plugin-factory';
|
|
|
23
23
|
import type { PluginConfig } from '../../types';
|
|
24
24
|
import {
|
|
25
25
|
contextualMenuDropdownWidth,
|
|
26
|
+
contextualMenuDropdownWidthDnD,
|
|
26
27
|
contextualMenuTriggerSize,
|
|
27
28
|
} from '../consts';
|
|
28
29
|
|
|
@@ -53,7 +54,9 @@ const FloatingContextualMenu = ({
|
|
|
53
54
|
getEditorContainerWidth,
|
|
54
55
|
}: Props) => {
|
|
55
56
|
// TargetCellPosition could be outdated: https://product-fabric.atlassian.net/browse/ED-8129
|
|
56
|
-
const { targetCellPosition } = getPluginState(
|
|
57
|
+
const { targetCellPosition, isDragAndDropEnabled } = getPluginState(
|
|
58
|
+
editorView.state,
|
|
59
|
+
);
|
|
57
60
|
if (
|
|
58
61
|
!isOpen ||
|
|
59
62
|
!targetCellPosition ||
|
|
@@ -89,7 +92,11 @@ const FloatingContextualMenu = ({
|
|
|
89
92
|
boundariesElement={boundariesElement}
|
|
90
93
|
scrollableElement={scrollableElement}
|
|
91
94
|
fitHeight={188}
|
|
92
|
-
fitWidth={
|
|
95
|
+
fitWidth={
|
|
96
|
+
isDragAndDropEnabled
|
|
97
|
+
? contextualMenuDropdownWidthDnD
|
|
98
|
+
: contextualMenuDropdownWidth
|
|
99
|
+
}
|
|
93
100
|
// z-index value below is to ensure that this menu is above other floating menu
|
|
94
101
|
// in table, but below floating dialogs like typeaheads, pickers, etc.
|
|
95
102
|
zIndex={
|
|
@@ -101,7 +108,7 @@ const FloatingContextualMenu = ({
|
|
|
101
108
|
offset={[-7, 0]}
|
|
102
109
|
stick={true}
|
|
103
110
|
>
|
|
104
|
-
<div css={tablePopupStyles}>
|
|
111
|
+
<div css={tablePopupStyles(isDragAndDropEnabled)}>
|
|
105
112
|
<ContextualMenu
|
|
106
113
|
editorView={editorView}
|
|
107
114
|
offset={[contextualMenuTriggerSize / 2, -contextualMenuTriggerSize]}
|
|
@@ -5,7 +5,10 @@ import { N60A, N90 } from '@atlaskit/theme/colors';
|
|
|
5
5
|
import { token } from '@atlaskit/tokens';
|
|
6
6
|
|
|
7
7
|
import { TableCssClassName as ClassName } from '../../types';
|
|
8
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
contextualMenuDropdownWidth,
|
|
10
|
+
contextualMenuDropdownWidthDnD,
|
|
11
|
+
} from '../consts';
|
|
9
12
|
|
|
10
13
|
export const cellColourPreviewStyles = (selectedColor: string) => css`
|
|
11
14
|
&::before {
|
|
@@ -20,7 +23,9 @@ export const elementBeforeIconStyles = css`
|
|
|
20
23
|
|
|
21
24
|
// TODO Delete this comment after verifying space token -> previous value `padding: 8px`
|
|
22
25
|
// TODO Delete this comment after verifying space token -> previous value `margin-left: 4px`
|
|
23
|
-
export const tablePopupStyles =
|
|
26
|
+
export const tablePopupStyles = (
|
|
27
|
+
isDragAndDropEnabled: boolean | undefined,
|
|
28
|
+
) => css`
|
|
24
29
|
.${ClassName.CONTEXTUAL_SUBMENU} {
|
|
25
30
|
border-radius: ${token('border.radius', '3px')};
|
|
26
31
|
background: ${token('elevation.surface.overlay', 'white')};
|
|
@@ -31,7 +36,9 @@ export const tablePopupStyles = css`
|
|
|
31
36
|
display: block;
|
|
32
37
|
position: absolute;
|
|
33
38
|
top: 0;
|
|
34
|
-
left: ${
|
|
39
|
+
left: ${isDragAndDropEnabled
|
|
40
|
+
? contextualMenuDropdownWidthDnD
|
|
41
|
+
: contextualMenuDropdownWidth}px;
|
|
35
42
|
padding: ${token('space.100', '8px')};
|
|
36
43
|
|
|
37
44
|
> div {
|
|
@@ -159,10 +159,17 @@ export const ColumnControls = ({
|
|
|
159
159
|
}
|
|
160
160
|
}, [editorView, tableActive]);
|
|
161
161
|
|
|
162
|
-
const handleMouseUp = useCallback(
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
162
|
+
const handleMouseUp = useCallback(
|
|
163
|
+
(event) => {
|
|
164
|
+
const { state, dispatch } = editorView;
|
|
165
|
+
if (event.shiftKey) {
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
toggleDragMenu(undefined, 'column', colIndex)(state, dispatch);
|
|
170
|
+
},
|
|
171
|
+
[editorView, colIndex],
|
|
172
|
+
);
|
|
166
173
|
|
|
167
174
|
const colIndexes = useMemo(() => {
|
|
168
175
|
return [colIndex!];
|
|
@@ -240,6 +247,13 @@ export const ColumnControls = ({
|
|
|
240
247
|
: selectedColIndexes
|
|
241
248
|
: colIndexes;
|
|
242
249
|
|
|
250
|
+
const previewWidth =
|
|
251
|
+
colWidths?.reduce<number>(
|
|
252
|
+
(sum, v, i) =>
|
|
253
|
+
sum + (v ?? tableCellMinWidth) * (indexes.includes(i) ? 1 : 0),
|
|
254
|
+
0,
|
|
255
|
+
) ?? tableCellMinWidth;
|
|
256
|
+
|
|
243
257
|
return (
|
|
244
258
|
<div
|
|
245
259
|
key={type}
|
|
@@ -251,6 +265,8 @@ export const ColumnControls = ({
|
|
|
251
265
|
height: 'fit-content',
|
|
252
266
|
placeSelf: 'center',
|
|
253
267
|
zIndex: 99,
|
|
268
|
+
width: '100%',
|
|
269
|
+
position: 'relative',
|
|
254
270
|
}}
|
|
255
271
|
data-column-control-index={hoveredCell.colIndex}
|
|
256
272
|
data-testid={`table-floating-column-${
|
|
@@ -263,7 +279,7 @@ export const ColumnControls = ({
|
|
|
263
279
|
tableLocalId={localId || ''}
|
|
264
280
|
indexes={indexes}
|
|
265
281
|
forceDefaultHandle={isHover ? false : isColumnsSelected}
|
|
266
|
-
previewWidth={
|
|
282
|
+
previewWidth={previewWidth}
|
|
267
283
|
previewHeight={previewHeight}
|
|
268
284
|
appearance={
|
|
269
285
|
isSelecting ? currentSelectionAppearance : hoveredAppearance
|
|
@@ -6,33 +6,21 @@ import { ColumnDropTarget } from './ColumnDropTarget';
|
|
|
6
6
|
|
|
7
7
|
export interface Props {
|
|
8
8
|
tableRef: HTMLTableElement;
|
|
9
|
-
stickyTop?: number;
|
|
10
9
|
tableHeight?: number;
|
|
11
10
|
localId?: string;
|
|
12
|
-
rowHeights?: number[];
|
|
13
11
|
colWidths?: (number | undefined)[];
|
|
14
12
|
}
|
|
15
13
|
|
|
16
14
|
export const ColumnDropTargets: React.FC<Props> = ({
|
|
17
15
|
tableRef,
|
|
18
16
|
tableHeight,
|
|
19
|
-
stickyTop,
|
|
20
17
|
localId,
|
|
21
|
-
rowHeights,
|
|
22
18
|
colWidths,
|
|
23
19
|
}) => {
|
|
24
20
|
if (!tableRef) {
|
|
25
21
|
return null;
|
|
26
22
|
}
|
|
27
23
|
|
|
28
|
-
const firstRow = tableRef.querySelector('tr');
|
|
29
|
-
const hasHeaderRow = firstRow
|
|
30
|
-
? firstRow.getAttribute('data-header-row')
|
|
31
|
-
: false;
|
|
32
|
-
|
|
33
|
-
const marginTop =
|
|
34
|
-
hasHeaderRow && stickyTop !== undefined ? rowHeights?.[0] ?? 0 : 0;
|
|
35
|
-
|
|
36
24
|
return (
|
|
37
25
|
<div
|
|
38
26
|
className={ClassName.DRAG_COLUMN_DROP_TARGET_CONTROLS}
|
|
@@ -50,7 +38,7 @@ export const ColumnDropTargets: React.FC<Props> = ({
|
|
|
50
38
|
localId={localId}
|
|
51
39
|
width={width}
|
|
52
40
|
height={tableHeight}
|
|
53
|
-
marginTop={
|
|
41
|
+
marginTop={0}
|
|
54
42
|
/>
|
|
55
43
|
);
|
|
56
44
|
})}
|
|
@@ -165,10 +165,8 @@ export const TableFloatingColumnControls: React.FC<Props> = ({
|
|
|
165
165
|
{isDragging && (
|
|
166
166
|
<ColumnDropTargets
|
|
167
167
|
tableRef={tableRef}
|
|
168
|
-
stickyTop={tableActive ? stickyTop : undefined}
|
|
169
168
|
tableHeight={tableRect.height}
|
|
170
169
|
localId={currentNodeLocalId}
|
|
171
|
-
rowHeights={rowHeights}
|
|
172
170
|
colWidths={colWidths}
|
|
173
171
|
/>
|
|
174
172
|
)}
|
|
@@ -113,13 +113,20 @@ const DragControlsComponent = ({
|
|
|
113
113
|
});
|
|
114
114
|
}, [editorView]);
|
|
115
115
|
|
|
116
|
-
const onMouseUp = useCallback(
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
116
|
+
const onMouseUp = useCallback(
|
|
117
|
+
(event) => {
|
|
118
|
+
if (event.shiftKey) {
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
toggleDragMenu(
|
|
123
|
+
undefined,
|
|
124
|
+
'row',
|
|
125
|
+
hoveredCell?.rowIndex,
|
|
126
|
+
)(editorView.state, editorView.dispatch);
|
|
127
|
+
},
|
|
128
|
+
[editorView, hoveredCell?.rowIndex],
|
|
129
|
+
);
|
|
123
130
|
|
|
124
131
|
const rowIndex = hoveredCell?.rowIndex;
|
|
125
132
|
|
|
@@ -228,6 +235,11 @@ const DragControlsComponent = ({
|
|
|
228
235
|
: selectedRowIndexes
|
|
229
236
|
: rowIndexes;
|
|
230
237
|
|
|
238
|
+
const previewHeight = rowHeights.reduce(
|
|
239
|
+
(sum, v, i) => sum + v * (indexes.includes(i) ? 1 : 0),
|
|
240
|
+
0,
|
|
241
|
+
);
|
|
242
|
+
|
|
231
243
|
return (
|
|
232
244
|
<div
|
|
233
245
|
key={type}
|
|
@@ -235,7 +247,9 @@ const DragControlsComponent = ({
|
|
|
235
247
|
gridRow: isSelecting ? selectedRowPosition : gridRowPosition,
|
|
236
248
|
gridColumn: '2',
|
|
237
249
|
// 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
|
|
250
|
+
display: 'flex',
|
|
238
251
|
width: '9px',
|
|
252
|
+
height: '100%',
|
|
239
253
|
position: 'relative',
|
|
240
254
|
right: '-0.5px',
|
|
241
255
|
}}
|
|
@@ -250,7 +264,7 @@ const DragControlsComponent = ({
|
|
|
250
264
|
indexes={indexes}
|
|
251
265
|
forceDefaultHandle={isHover ? false : isRowsSelected}
|
|
252
266
|
previewWidth={tableWidth}
|
|
253
|
-
previewHeight={
|
|
267
|
+
previewHeight={previewHeight}
|
|
254
268
|
appearance={
|
|
255
269
|
isSelecting ? currentSelectionAppearance : hoveredAppearance
|
|
256
270
|
}
|