@atlaskit/editor-plugin-table 5.4.14 → 5.4.16
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/afm-cc/tsconfig.json +70 -0
- package/dist/cjs/plugins/table/commands/hover.js +26 -6
- package/dist/cjs/plugins/table/commands/index.js +6 -0
- package/dist/cjs/plugins/table/commands/misc.js +8 -3
- package/dist/cjs/plugins/table/event-handlers.js +56 -34
- package/dist/cjs/plugins/table/nodeviews/TableComponent.js +4 -1
- package/dist/cjs/plugins/table/pm-plugins/drag-and-drop/commands.js +7 -6
- package/dist/cjs/plugins/table/pm-plugins/drag-and-drop/plugin.js +39 -7
- package/dist/cjs/plugins/table/pm-plugins/main.js +5 -3
- package/dist/cjs/plugins/table/reducer.js +1 -0
- package/dist/cjs/plugins/table/toolbar.js +6 -3
- package/dist/cjs/plugins/table/ui/ColumnResizeWidget/index.js +6 -3
- package/dist/cjs/plugins/table/ui/DragHandle/HandleIconComponent.js +3 -5
- package/dist/cjs/plugins/table/ui/DragHandle/index.js +3 -0
- package/dist/cjs/plugins/table/ui/DragPreview/index.js +0 -2
- package/dist/cjs/plugins/table/ui/FloatingContextualButton/index.js +10 -7
- package/dist/cjs/plugins/table/ui/FloatingContextualMenu/ContextualMenu.js +11 -10
- package/dist/cjs/plugins/table/ui/FloatingContextualMenu/index.js +6 -3
- package/dist/cjs/plugins/table/ui/FloatingDragMenu/DragMenu.js +7 -4
- package/dist/cjs/plugins/table/ui/TableFloatingColumnControls/ColumnControls/index.js +74 -37
- package/dist/cjs/plugins/table/ui/TableFloatingColumnControls/index.js +3 -1
- package/dist/cjs/plugins/table/ui/TableFloatingControls/RowControls/DragControls.js +63 -31
- package/dist/cjs/plugins/table/ui/TableFloatingControls/index.js +12 -8
- package/dist/cjs/plugins/table/utils/dom.js +16 -1
- package/dist/cjs/plugins/table/utils/index.js +6 -0
- package/dist/es2019/plugins/table/commands/hover.js +22 -5
- package/dist/es2019/plugins/table/commands/index.js +1 -1
- package/dist/es2019/plugins/table/commands/misc.js +8 -3
- package/dist/es2019/plugins/table/event-handlers.js +45 -20
- package/dist/es2019/plugins/table/nodeviews/TableComponent.js +4 -1
- package/dist/es2019/plugins/table/pm-plugins/drag-and-drop/commands.js +7 -6
- package/dist/es2019/plugins/table/pm-plugins/drag-and-drop/plugin.js +36 -3
- package/dist/es2019/plugins/table/pm-plugins/main.js +6 -4
- package/dist/es2019/plugins/table/reducer.js +1 -0
- package/dist/es2019/plugins/table/toolbar.js +5 -3
- package/dist/es2019/plugins/table/ui/ColumnResizeWidget/index.js +5 -3
- package/dist/es2019/plugins/table/ui/DragHandle/HandleIconComponent.js +3 -5
- package/dist/es2019/plugins/table/ui/DragHandle/index.js +2 -0
- package/dist/es2019/plugins/table/ui/DragPreview/index.js +0 -2
- package/dist/es2019/plugins/table/ui/FloatingContextualButton/index.js +9 -7
- package/dist/es2019/plugins/table/ui/FloatingContextualMenu/ContextualMenu.js +11 -9
- package/dist/es2019/plugins/table/ui/FloatingContextualMenu/index.js +5 -3
- package/dist/es2019/plugins/table/ui/FloatingDragMenu/DragMenu.js +6 -4
- package/dist/es2019/plugins/table/ui/TableFloatingColumnControls/ColumnControls/index.js +73 -37
- package/dist/es2019/plugins/table/ui/TableFloatingColumnControls/index.js +3 -1
- package/dist/es2019/plugins/table/ui/TableFloatingControls/RowControls/DragControls.js +62 -29
- package/dist/es2019/plugins/table/ui/TableFloatingControls/index.js +12 -9
- package/dist/es2019/plugins/table/utils/dom.js +13 -0
- package/dist/es2019/plugins/table/utils/index.js +1 -1
- package/dist/esm/plugins/table/commands/hover.js +25 -5
- package/dist/esm/plugins/table/commands/index.js +1 -1
- package/dist/esm/plugins/table/commands/misc.js +8 -3
- package/dist/esm/plugins/table/event-handlers.js +55 -33
- package/dist/esm/plugins/table/nodeviews/TableComponent.js +4 -1
- package/dist/esm/plugins/table/pm-plugins/drag-and-drop/commands.js +7 -6
- package/dist/esm/plugins/table/pm-plugins/drag-and-drop/plugin.js +35 -3
- package/dist/esm/plugins/table/pm-plugins/main.js +6 -4
- package/dist/esm/plugins/table/reducer.js +1 -0
- package/dist/esm/plugins/table/toolbar.js +5 -3
- package/dist/esm/plugins/table/ui/ColumnResizeWidget/index.js +5 -3
- package/dist/esm/plugins/table/ui/DragHandle/HandleIconComponent.js +3 -5
- package/dist/esm/plugins/table/ui/DragHandle/index.js +3 -0
- package/dist/esm/plugins/table/ui/DragPreview/index.js +0 -2
- package/dist/esm/plugins/table/ui/FloatingContextualButton/index.js +9 -7
- package/dist/esm/plugins/table/ui/FloatingContextualMenu/ContextualMenu.js +11 -9
- package/dist/esm/plugins/table/ui/FloatingContextualMenu/index.js +5 -3
- package/dist/esm/plugins/table/ui/FloatingDragMenu/DragMenu.js +6 -4
- package/dist/esm/plugins/table/ui/TableFloatingColumnControls/ColumnControls/index.js +74 -37
- package/dist/esm/plugins/table/ui/TableFloatingColumnControls/index.js +3 -1
- package/dist/esm/plugins/table/ui/TableFloatingControls/RowControls/DragControls.js +61 -29
- package/dist/esm/plugins/table/ui/TableFloatingControls/index.js +12 -8
- package/dist/esm/plugins/table/utils/dom.js +15 -0
- package/dist/esm/plugins/table/utils/index.js +1 -1
- package/dist/types/plugins/table/commands/hover.d.ts +2 -1
- package/dist/types/plugins/table/commands/index.d.ts +1 -1
- package/dist/types/plugins/table/commands/misc.d.ts +1 -1
- package/dist/types/plugins/table/event-handlers.d.ts +2 -0
- package/dist/types/plugins/table/pm-plugins/drag-and-drop/commands.d.ts +1 -1
- package/dist/types/plugins/table/types.d.ts +7 -2
- package/dist/types/plugins/table/ui/DragHandle/HandleIconComponent.d.ts +1 -0
- package/dist/types/plugins/table/ui/DragHandle/index.d.ts +2 -1
- package/dist/types/plugins/table/ui/TableFloatingColumnControls/ColumnControls/index.d.ts +2 -1
- package/dist/types/plugins/table/ui/TableFloatingColumnControls/index.d.ts +1 -0
- package/dist/types/plugins/table/ui/TableFloatingControls/RowControls/DragControls.d.ts +1 -0
- package/dist/types/plugins/table/ui/TableFloatingControls/index.d.ts +1 -0
- package/dist/types/plugins/table/utils/dom.d.ts +4 -0
- package/dist/types/plugins/table/utils/index.d.ts +1 -1
- package/dist/types-ts4.5/plugins/table/commands/hover.d.ts +2 -1
- package/dist/types-ts4.5/plugins/table/commands/index.d.ts +1 -1
- package/dist/types-ts4.5/plugins/table/commands/misc.d.ts +1 -1
- package/dist/types-ts4.5/plugins/table/event-handlers.d.ts +2 -0
- package/dist/types-ts4.5/plugins/table/pm-plugins/drag-and-drop/commands.d.ts +1 -1
- package/dist/types-ts4.5/plugins/table/types.d.ts +7 -2
- package/dist/types-ts4.5/plugins/table/ui/DragHandle/HandleIconComponent.d.ts +1 -0
- package/dist/types-ts4.5/plugins/table/ui/DragHandle/index.d.ts +2 -1
- package/dist/types-ts4.5/plugins/table/ui/TableFloatingColumnControls/ColumnControls/index.d.ts +2 -1
- package/dist/types-ts4.5/plugins/table/ui/TableFloatingColumnControls/index.d.ts +1 -0
- package/dist/types-ts4.5/plugins/table/ui/TableFloatingControls/RowControls/DragControls.d.ts +1 -0
- package/dist/types-ts4.5/plugins/table/ui/TableFloatingControls/index.d.ts +1 -0
- package/dist/types-ts4.5/plugins/table/utils/dom.d.ts +4 -0
- package/dist/types-ts4.5/plugins/table/utils/index.d.ts +1 -1
- package/package.json +2 -2
- package/src/__tests__/unit/event-handlers.ts +2 -2
- package/src/__tests__/unit/ui/RowDragControls.tsx +1 -0
- package/src/plugins/table/commands/hover.ts +37 -7
- package/src/plugins/table/commands/index.ts +1 -0
- package/src/plugins/table/commands/misc.ts +9 -3
- package/src/plugins/table/event-handlers.ts +47 -29
- package/src/plugins/table/nodeviews/TableComponent.tsx +4 -1
- package/src/plugins/table/pm-plugins/drag-and-drop/commands.ts +7 -5
- package/src/plugins/table/pm-plugins/drag-and-drop/plugin.ts +37 -2
- package/src/plugins/table/pm-plugins/main.ts +6 -3
- package/src/plugins/table/reducer.ts +1 -0
- package/src/plugins/table/types.ts +9 -2
- package/src/plugins/table/ui/DragHandle/HandleIconComponent.tsx +10 -9
- package/src/plugins/table/ui/DragHandle/index.tsx +4 -0
- package/src/plugins/table/ui/TableFloatingColumnControls/ColumnControls/index.tsx +129 -50
- package/src/plugins/table/ui/TableFloatingColumnControls/index.tsx +3 -0
- package/src/plugins/table/ui/TableFloatingControls/RowControls/DragControls.tsx +128 -41
- package/src/plugins/table/ui/TableFloatingControls/index.tsx +12 -5
- package/src/plugins/table/utils/dom.ts +22 -0
- package/src/plugins/table/utils/index.ts +1 -0
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
type HandleIconProps = {
|
|
10
10
|
hasMergedCells: boolean;
|
|
11
11
|
direction: 'row' | 'column';
|
|
12
|
+
forceDefaultHandle: boolean;
|
|
12
13
|
isDragMenuOpen: boolean | undefined;
|
|
13
14
|
isRowHandleHovered: boolean;
|
|
14
15
|
isColumnHandleHovered: boolean;
|
|
@@ -20,6 +21,7 @@ type HandleIconProps = {
|
|
|
20
21
|
export const HandleIconComponent = (props: HandleIconProps) => {
|
|
21
22
|
const {
|
|
22
23
|
direction,
|
|
24
|
+
forceDefaultHandle,
|
|
23
25
|
isDragMenuOpen,
|
|
24
26
|
isRowHandleHovered,
|
|
25
27
|
isColumnHandleHovered,
|
|
@@ -29,22 +31,21 @@ export const HandleIconComponent = (props: HandleIconProps) => {
|
|
|
29
31
|
dragMenuDirection,
|
|
30
32
|
} = props;
|
|
31
33
|
const isHandleHovered = isRowHandleHovered || isColumnHandleHovered;
|
|
34
|
+
|
|
32
35
|
const isCurrentRowOrColumnSelected =
|
|
33
36
|
isCurrentRowSelected || isCurrentColumnSelected;
|
|
37
|
+
|
|
34
38
|
const isDragMenuOpenOnCurrentRowOrColumn =
|
|
35
39
|
isDragMenuOpen &&
|
|
36
40
|
dragMenuDirection === direction &&
|
|
37
41
|
isCurrentRowOrColumnSelected;
|
|
38
42
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
)
|
|
44
|
-
|
|
45
|
-
// hoverred handle or open drag menu
|
|
46
|
-
if (isHandleHovered || isDragMenuOpenOnCurrentRowOrColumn) {
|
|
47
|
-
return showNormalHandle;
|
|
43
|
+
if (
|
|
44
|
+
forceDefaultHandle ||
|
|
45
|
+
isHandleHovered ||
|
|
46
|
+
isDragMenuOpenOnCurrentRowOrColumn
|
|
47
|
+
) {
|
|
48
|
+
return hasMergedCells ? <DragHandleDisabledIcon /> : <DragHandleIcon />;
|
|
48
49
|
}
|
|
49
50
|
|
|
50
51
|
return <MinimisedHandleIcon />;
|
|
@@ -22,6 +22,7 @@ type DragHandleAppearance = 'default' | 'selected' | 'disabled' | 'danger';
|
|
|
22
22
|
type DragHandleProps = {
|
|
23
23
|
tableLocalId: string;
|
|
24
24
|
indexes: number[];
|
|
25
|
+
forceDefaultHandle?: boolean;
|
|
25
26
|
previewWidth?: number;
|
|
26
27
|
previewHeight?: number;
|
|
27
28
|
direction?: TableDirection;
|
|
@@ -38,6 +39,7 @@ export const DragHandle = ({
|
|
|
38
39
|
direction = 'row',
|
|
39
40
|
appearance = 'default',
|
|
40
41
|
indexes,
|
|
42
|
+
forceDefaultHandle = false,
|
|
41
43
|
previewWidth,
|
|
42
44
|
previewHeight,
|
|
43
45
|
onMouseOver,
|
|
@@ -63,6 +65,7 @@ export const DragHandle = ({
|
|
|
63
65
|
isDragMenuOpen &&
|
|
64
66
|
direction === 'row' &&
|
|
65
67
|
hoveredCell.rowIndex === dragMenuIndex;
|
|
68
|
+
|
|
66
69
|
const isCurrentColumnSelected =
|
|
67
70
|
isDragMenuOpen &&
|
|
68
71
|
direction === 'column' &&
|
|
@@ -83,6 +86,7 @@ export const DragHandle = ({
|
|
|
83
86
|
const handleIconProps = {
|
|
84
87
|
hasMergedCells,
|
|
85
88
|
direction,
|
|
89
|
+
forceDefaultHandle,
|
|
86
90
|
isDragMenuOpen,
|
|
87
91
|
isRowHandleHovered,
|
|
88
92
|
isColumnHandleHovered,
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/* eslint-disable @atlaskit/design-system/prefer-primitives */
|
|
1
2
|
import type { MouseEvent } from 'react';
|
|
2
3
|
import React, { useCallback, useMemo } from 'react';
|
|
3
4
|
|
|
@@ -13,7 +14,8 @@ import {
|
|
|
13
14
|
selectColumn,
|
|
14
15
|
} from '../../../commands';
|
|
15
16
|
import { toggleDragMenu } from '../../../pm-plugins/drag-and-drop/commands';
|
|
16
|
-
import
|
|
17
|
+
import { getPluginState as getDragDropPluginState } from '../../../pm-plugins/drag-and-drop/plugin-factory';
|
|
18
|
+
import type { CellHoverMeta, HandleTypes } from '../../../types';
|
|
17
19
|
import { TableCssClassName as ClassName } from '../../../types';
|
|
18
20
|
import { getRowsParams, getSelectedColumnIndexes } from '../../../utils';
|
|
19
21
|
import { DragHandle } from '../../DragHandle';
|
|
@@ -30,6 +32,7 @@ export interface ColumnControlsProps {
|
|
|
30
32
|
rowHeights?: number[];
|
|
31
33
|
colWidths?: (number | undefined)[];
|
|
32
34
|
hasHeaderColumn?: boolean;
|
|
35
|
+
isTableHovered?: boolean;
|
|
33
36
|
}
|
|
34
37
|
|
|
35
38
|
const getSelectedColumns = (selection: Selection) => {
|
|
@@ -55,6 +58,7 @@ export const ColumnControls = ({
|
|
|
55
58
|
rowHeights,
|
|
56
59
|
colWidths,
|
|
57
60
|
hasHeaderColumn,
|
|
61
|
+
isTableHovered,
|
|
58
62
|
}: ColumnControlsProps) => {
|
|
59
63
|
const widths =
|
|
60
64
|
colWidths?.map((width) => (width ? `${width - 1}px` : '0px')).join(' ') ??
|
|
@@ -64,14 +68,6 @@ export const ColumnControls = ({
|
|
|
64
68
|
const colIndex = hoveredCell?.colIndex;
|
|
65
69
|
const selectedColIndexes = getSelectedColumns(editorView.state.selection);
|
|
66
70
|
|
|
67
|
-
const gridColumnPosition = useMemo(() => {
|
|
68
|
-
// if more than one row is selected, ensure the handle spans over the selected range
|
|
69
|
-
if (selectedColIndexes.includes(colIndex!)) {
|
|
70
|
-
return `${selectedColIndexes[0] + 1} / span ${selectedColIndexes.length}`;
|
|
71
|
-
}
|
|
72
|
-
return `${colIndex! + 1} / span 1`;
|
|
73
|
-
}, [colIndex, selectedColIndexes]);
|
|
74
|
-
|
|
75
71
|
const firstRow = tableRef.querySelector('tr');
|
|
76
72
|
const hasHeaderRow = firstRow
|
|
77
73
|
? firstRow.getAttribute('data-header-row')
|
|
@@ -109,11 +105,15 @@ export const ColumnControls = ({
|
|
|
109
105
|
|
|
110
106
|
// update hovered cell location
|
|
111
107
|
const { state, dispatch } = editorView;
|
|
112
|
-
if (tableActive
|
|
113
|
-
|
|
108
|
+
if (tableActive) {
|
|
109
|
+
// For context: Whenever we mouse over a column or row drag handle, we will ALWAYS be hovering over the 0 index
|
|
110
|
+
// of the opposite dimension. For example; here when we mouse over the column drag handle then we're technically
|
|
111
|
+
// also hovering over row 0 index. And vice-versa with rows. This means we don't need to worry about knowing the
|
|
112
|
+
// current row index. We can just force it to 0.
|
|
113
|
+
hoverCell(0, Number(colIndex))(state, dispatch);
|
|
114
114
|
}
|
|
115
115
|
},
|
|
116
|
-
[editorView,
|
|
116
|
+
[editorView, tableActive],
|
|
117
117
|
);
|
|
118
118
|
|
|
119
119
|
const handleMouseOut = useCallback(() => {
|
|
@@ -132,6 +132,122 @@ export const ColumnControls = ({
|
|
|
132
132
|
return [colIndex!];
|
|
133
133
|
}, [colIndex]);
|
|
134
134
|
|
|
135
|
+
const previewHeight = rowHeights?.reduce((sum, cur) => sum + cur, 0) ?? 0;
|
|
136
|
+
|
|
137
|
+
const generateHandleByType = useCallback(
|
|
138
|
+
(type: HandleTypes): JSX.Element | null => {
|
|
139
|
+
if (!hoveredCell) {
|
|
140
|
+
return null;
|
|
141
|
+
}
|
|
142
|
+
const { isDragMenuOpen, dragMenuIndex, dragMenuDirection } =
|
|
143
|
+
getDragDropPluginState(editorView.state);
|
|
144
|
+
const isHover = type === 'hover';
|
|
145
|
+
|
|
146
|
+
const isHoveredOnSelectedColumn =
|
|
147
|
+
isDragMenuOpen &&
|
|
148
|
+
dragMenuDirection === 'column' &&
|
|
149
|
+
dragMenuIndex === colIndex;
|
|
150
|
+
|
|
151
|
+
const showCondition = isHover
|
|
152
|
+
? !isHoveredOnSelectedColumn && Number.isFinite(hoveredCell?.colIndex)
|
|
153
|
+
: isDragMenuOpen && dragMenuDirection === 'column';
|
|
154
|
+
|
|
155
|
+
if (!showCondition) {
|
|
156
|
+
return null;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
const selectedColumnPosition = `${dragMenuIndex + 1} / span ${
|
|
160
|
+
selectedColIndexes.length
|
|
161
|
+
}`;
|
|
162
|
+
|
|
163
|
+
const gridColumnPosition = selectedColIndexes.includes(colIndex!)
|
|
164
|
+
? `${selectedColIndexes[0] + 1} / span ${selectedColIndexes.length}`
|
|
165
|
+
: `${colIndex! + 1} / span 1`;
|
|
166
|
+
|
|
167
|
+
const selectedApprearance = isInDanger ? 'danger' : 'selected';
|
|
168
|
+
const hoveredAppearance = selectedColIndexes.includes(colIndex!)
|
|
169
|
+
? isInDanger
|
|
170
|
+
? 'danger'
|
|
171
|
+
: 'selected'
|
|
172
|
+
: 'default';
|
|
173
|
+
|
|
174
|
+
return (
|
|
175
|
+
showCondition && (
|
|
176
|
+
<div
|
|
177
|
+
key={type}
|
|
178
|
+
style={{
|
|
179
|
+
gridColumn: isHover ? gridColumnPosition : selectedColumnPosition,
|
|
180
|
+
display: 'flex',
|
|
181
|
+
justifyContent: 'center',
|
|
182
|
+
alignItems: 'center',
|
|
183
|
+
height: 'fit-content',
|
|
184
|
+
placeSelf: 'center',
|
|
185
|
+
zIndex: 99,
|
|
186
|
+
}}
|
|
187
|
+
data-column-control-index={hoveredCell.colIndex}
|
|
188
|
+
data-testid={
|
|
189
|
+
isHover
|
|
190
|
+
? 'table-floating-column-control'
|
|
191
|
+
: 'table-floating-column-control-selected'
|
|
192
|
+
}
|
|
193
|
+
>
|
|
194
|
+
<DragHandle
|
|
195
|
+
direction="column"
|
|
196
|
+
tableLocalId={localId || ''}
|
|
197
|
+
indexes={isHover ? colIndexes : selectedColIndexes}
|
|
198
|
+
forceDefaultHandle={!isHover}
|
|
199
|
+
previewWidth={colWidths?.[colIndex!] ?? 48}
|
|
200
|
+
previewHeight={previewHeight}
|
|
201
|
+
appearance={isHover ? hoveredAppearance : selectedApprearance}
|
|
202
|
+
onClick={handleClick}
|
|
203
|
+
onMouseOver={handleMouseOver}
|
|
204
|
+
onMouseOut={handleMouseOut}
|
|
205
|
+
onMouseUp={handleMouseUp}
|
|
206
|
+
editorView={editorView}
|
|
207
|
+
/>
|
|
208
|
+
</div>
|
|
209
|
+
)
|
|
210
|
+
);
|
|
211
|
+
},
|
|
212
|
+
[
|
|
213
|
+
colIndex,
|
|
214
|
+
previewHeight,
|
|
215
|
+
colWidths,
|
|
216
|
+
colIndexes,
|
|
217
|
+
editorView,
|
|
218
|
+
handleClick,
|
|
219
|
+
handleMouseOut,
|
|
220
|
+
handleMouseOver,
|
|
221
|
+
handleMouseUp,
|
|
222
|
+
hoveredCell,
|
|
223
|
+
isInDanger,
|
|
224
|
+
localId,
|
|
225
|
+
selectedColIndexes,
|
|
226
|
+
],
|
|
227
|
+
);
|
|
228
|
+
|
|
229
|
+
const columnHandles = useCallback(
|
|
230
|
+
(hoveredCell: CellHoverMeta | undefined) => {
|
|
231
|
+
if (!hoveredCell) {
|
|
232
|
+
return null;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
if (hoveredCell.colIndex === undefined) {
|
|
236
|
+
return generateHandleByType('selected');
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
const sortedHandles = [
|
|
240
|
+
generateHandleByType('hover'),
|
|
241
|
+
generateHandleByType('selected'),
|
|
242
|
+
];
|
|
243
|
+
|
|
244
|
+
return hoveredCell.colIndex < selectedColIndexes[0]
|
|
245
|
+
? sortedHandles
|
|
246
|
+
: sortedHandles.reverse();
|
|
247
|
+
},
|
|
248
|
+
[generateHandleByType, selectedColIndexes],
|
|
249
|
+
);
|
|
250
|
+
|
|
135
251
|
return (
|
|
136
252
|
<div
|
|
137
253
|
className={ClassName.DRAG_COLUMN_CONTROLS}
|
|
@@ -173,44 +289,7 @@ export const ColumnControls = ({
|
|
|
173
289
|
/>
|
|
174
290
|
</div>
|
|
175
291
|
))}
|
|
176
|
-
{tableActive &&
|
|
177
|
-
!isResizing &&
|
|
178
|
-
!!hoveredCell &&
|
|
179
|
-
Number.isFinite(hoveredCell.colIndex) && (
|
|
180
|
-
<div
|
|
181
|
-
style={{
|
|
182
|
-
gridColumn: gridColumnPosition,
|
|
183
|
-
display: 'flex',
|
|
184
|
-
justifyContent: 'center',
|
|
185
|
-
alignItems: 'center',
|
|
186
|
-
height: 'fit-content',
|
|
187
|
-
placeSelf: 'center',
|
|
188
|
-
zIndex: 99,
|
|
189
|
-
}}
|
|
190
|
-
data-column-control-index={hoveredCell.colIndex}
|
|
191
|
-
data-testid="table-floating-column-control"
|
|
192
|
-
>
|
|
193
|
-
<DragHandle
|
|
194
|
-
direction="column"
|
|
195
|
-
tableLocalId={localId || ''}
|
|
196
|
-
indexes={colIndexes}
|
|
197
|
-
previewWidth={hoveredCell.colWidth}
|
|
198
|
-
previewHeight={hoveredCell.colHeight}
|
|
199
|
-
appearance={
|
|
200
|
-
selectedColIndexes.includes(hoveredCell.colIndex!)
|
|
201
|
-
? isInDanger
|
|
202
|
-
? 'danger'
|
|
203
|
-
: 'selected'
|
|
204
|
-
: 'default'
|
|
205
|
-
}
|
|
206
|
-
onClick={handleClick}
|
|
207
|
-
onMouseOver={handleMouseOver}
|
|
208
|
-
onMouseOut={handleMouseOut}
|
|
209
|
-
onMouseUp={handleMouseUp}
|
|
210
|
-
editorView={editorView}
|
|
211
|
-
/>
|
|
212
|
-
</div>
|
|
213
|
-
)}
|
|
292
|
+
{tableActive && !isResizing && columnHandles(hoveredCell)}
|
|
214
293
|
</div>
|
|
215
294
|
</div>
|
|
216
295
|
);
|
|
@@ -34,6 +34,7 @@ export interface Props {
|
|
|
34
34
|
isResizing?: boolean;
|
|
35
35
|
ordering?: TableColumnOrdering;
|
|
36
36
|
stickyHeader?: RowStickyState;
|
|
37
|
+
isTableHovered?: boolean;
|
|
37
38
|
}
|
|
38
39
|
|
|
39
40
|
export const TableFloatingColumnControls: React.FC<Props> = ({
|
|
@@ -47,6 +48,7 @@ export const TableFloatingColumnControls: React.FC<Props> = ({
|
|
|
47
48
|
stickyHeader,
|
|
48
49
|
selection,
|
|
49
50
|
isInDanger,
|
|
51
|
+
isTableHovered,
|
|
50
52
|
}) => {
|
|
51
53
|
const [tableRect, setTableRect] = useState<{ width: number; height: number }>(
|
|
52
54
|
{ width: 0, height: 0 },
|
|
@@ -130,6 +132,7 @@ export const TableFloatingColumnControls: React.FC<Props> = ({
|
|
|
130
132
|
tableRef={tableRef}
|
|
131
133
|
isResizing={isResizing}
|
|
132
134
|
tableActive={tableActive}
|
|
135
|
+
isTableHovered={isTableHovered}
|
|
133
136
|
stickyTop={tableActive ? stickyTop : undefined}
|
|
134
137
|
localId={currentNodeLocalId}
|
|
135
138
|
isInDanger={isInDanger}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/* eslint-disable @atlaskit/design-system/prefer-primitives */
|
|
1
2
|
import type { MouseEvent } from 'react';
|
|
2
3
|
import React, {
|
|
3
4
|
Fragment,
|
|
@@ -20,9 +21,14 @@ import { token } from '@atlaskit/tokens';
|
|
|
20
21
|
|
|
21
22
|
import { clearHoverSelection } from '../../../commands';
|
|
22
23
|
import { toggleDragMenu } from '../../../pm-plugins/drag-and-drop/commands';
|
|
24
|
+
import { getPluginState as getDragDropPluginState } from '../../../pm-plugins/drag-and-drop/plugin-factory';
|
|
23
25
|
import { getPluginState as getTablePluginState } from '../../../pm-plugins/plugin-factory';
|
|
24
26
|
import { TableCssClassName as ClassName } from '../../../types';
|
|
25
|
-
import type {
|
|
27
|
+
import type {
|
|
28
|
+
CellHoverMeta,
|
|
29
|
+
DraggableSourceData,
|
|
30
|
+
HandleTypes,
|
|
31
|
+
} from '../../../types';
|
|
26
32
|
import {
|
|
27
33
|
getRowHeights,
|
|
28
34
|
getRowsParams,
|
|
@@ -41,6 +47,7 @@ type DragControlsProps = {
|
|
|
41
47
|
hoveredCell?: CellHoverMeta;
|
|
42
48
|
isInDanger?: boolean;
|
|
43
49
|
isResizing?: boolean;
|
|
50
|
+
isTableHovered?: boolean;
|
|
44
51
|
hoverRows: (rows: number[], danger?: boolean) => void;
|
|
45
52
|
selectRow: (row: number, expand: boolean) => void;
|
|
46
53
|
updateCellHoverLocation: (rowIndex: number) => void;
|
|
@@ -66,6 +73,7 @@ const DragControlsComponent = ({
|
|
|
66
73
|
editorView,
|
|
67
74
|
isInDanger,
|
|
68
75
|
isResizing,
|
|
76
|
+
isTableHovered,
|
|
69
77
|
hoverRows,
|
|
70
78
|
selectRow,
|
|
71
79
|
updateCellHoverLocation,
|
|
@@ -112,14 +120,6 @@ const DragControlsComponent = ({
|
|
|
112
120
|
|
|
113
121
|
const rowIndex = hoveredCell?.rowIndex;
|
|
114
122
|
|
|
115
|
-
const gridRowPosition = useMemo(() => {
|
|
116
|
-
// if more than one row is selected, ensure the handle spans over the selected range
|
|
117
|
-
if (selectedRowIndexes.includes(rowIndex!)) {
|
|
118
|
-
return `${selectedRowIndexes[0] + 1} / span ${selectedRowIndexes.length}`;
|
|
119
|
-
}
|
|
120
|
-
return `${rowIndex! + 1} / span 1`;
|
|
121
|
-
}, [rowIndex, selectedRowIndexes]);
|
|
122
|
-
|
|
123
123
|
const handleMouseOut = useCallback(() => {
|
|
124
124
|
if (tableActive) {
|
|
125
125
|
const { state, dispatch } = editorView;
|
|
@@ -161,6 +161,124 @@ const DragControlsComponent = ({
|
|
|
161
161
|
[rowIndex, selectRow],
|
|
162
162
|
);
|
|
163
163
|
|
|
164
|
+
const generateHandleByType = useCallback(
|
|
165
|
+
(type: HandleTypes): JSX.Element | null => {
|
|
166
|
+
if (!hoveredCell) {
|
|
167
|
+
return null;
|
|
168
|
+
}
|
|
169
|
+
const { isDragMenuOpen, dragMenuIndex, dragMenuDirection } =
|
|
170
|
+
getDragDropPluginState(editorView.state);
|
|
171
|
+
const isHover = type === 'hover';
|
|
172
|
+
|
|
173
|
+
const isHoveredOnSelectedRow =
|
|
174
|
+
isDragMenuOpen &&
|
|
175
|
+
dragMenuDirection === 'row' &&
|
|
176
|
+
dragMenuIndex === rowIndex;
|
|
177
|
+
|
|
178
|
+
const showCondition = isHover
|
|
179
|
+
? !isHoveredOnSelectedRow &&
|
|
180
|
+
!selectedRowIndexes.includes(rowIndex!) &&
|
|
181
|
+
Number.isFinite(hoveredCell?.colIndex)
|
|
182
|
+
: isDragMenuOpen &&
|
|
183
|
+
dragMenuDirection === 'row' &&
|
|
184
|
+
Number.isFinite(hoveredCell?.colIndex);
|
|
185
|
+
|
|
186
|
+
if (!showCondition) {
|
|
187
|
+
return null;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
const gridRowPosition =
|
|
191
|
+
// if more than one row is selected, ensure the handle spans over the selected range
|
|
192
|
+
selectedRowIndexes.includes(rowIndex!)
|
|
193
|
+
? `${selectedRowIndexes[0] + 1} / span ${selectedRowIndexes.length}`
|
|
194
|
+
: `${rowIndex! + 1} / span 1`;
|
|
195
|
+
|
|
196
|
+
const selectedRowPosition = `${dragMenuIndex + 1} / span ${
|
|
197
|
+
selectedRowIndexes.length
|
|
198
|
+
}`;
|
|
199
|
+
|
|
200
|
+
const selectedApprearance = isInDanger ? 'danger' : 'selected';
|
|
201
|
+
const hoveredAppearance = selectedRowIndexes.includes(rowIndex!)
|
|
202
|
+
? isInDanger
|
|
203
|
+
? 'danger'
|
|
204
|
+
: 'selected'
|
|
205
|
+
: 'default';
|
|
206
|
+
|
|
207
|
+
return (
|
|
208
|
+
showCondition && (
|
|
209
|
+
<div
|
|
210
|
+
key={type}
|
|
211
|
+
style={{
|
|
212
|
+
gridRow: isHover ? gridRowPosition : selectedRowPosition,
|
|
213
|
+
gridColumn: '2',
|
|
214
|
+
display: 'flex',
|
|
215
|
+
height: '100%',
|
|
216
|
+
alignItems: 'center',
|
|
217
|
+
justifyContent: 'center',
|
|
218
|
+
}}
|
|
219
|
+
data-testid={
|
|
220
|
+
isHover
|
|
221
|
+
? 'table-floating-row-drag-handle'
|
|
222
|
+
: 'table-floating-row-control-selected'
|
|
223
|
+
}
|
|
224
|
+
>
|
|
225
|
+
<DragHandle
|
|
226
|
+
direction="row"
|
|
227
|
+
tableLocalId={currentNodeLocalId}
|
|
228
|
+
indexes={isHover ? rowIndexes : selectedRowIndexes}
|
|
229
|
+
forceDefaultHandle={!isHover}
|
|
230
|
+
previewWidth={tableWidth}
|
|
231
|
+
previewHeight={rowHeights[rowIndex!]}
|
|
232
|
+
appearance={isHover ? hoveredAppearance : selectedApprearance}
|
|
233
|
+
onClick={handleClick}
|
|
234
|
+
onMouseOver={handleMouseOver}
|
|
235
|
+
onMouseOut={handleMouseOut}
|
|
236
|
+
onMouseUp={onMouseUp}
|
|
237
|
+
editorView={editorView}
|
|
238
|
+
/>
|
|
239
|
+
</div>
|
|
240
|
+
)
|
|
241
|
+
);
|
|
242
|
+
},
|
|
243
|
+
[
|
|
244
|
+
currentNodeLocalId,
|
|
245
|
+
editorView,
|
|
246
|
+
handleClick,
|
|
247
|
+
handleMouseOut,
|
|
248
|
+
handleMouseOver,
|
|
249
|
+
hoveredCell,
|
|
250
|
+
isInDanger,
|
|
251
|
+
onMouseUp,
|
|
252
|
+
rowHeights,
|
|
253
|
+
rowIndex,
|
|
254
|
+
rowIndexes,
|
|
255
|
+
selectedRowIndexes,
|
|
256
|
+
tableWidth,
|
|
257
|
+
],
|
|
258
|
+
);
|
|
259
|
+
|
|
260
|
+
const rowHandles = useCallback(
|
|
261
|
+
(hoveredCell: CellHoverMeta | undefined) => {
|
|
262
|
+
if (!hoveredCell) {
|
|
263
|
+
return null;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
if (hoveredCell.rowIndex === undefined) {
|
|
267
|
+
return generateHandleByType('selected');
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
const sortedHandles = [
|
|
271
|
+
generateHandleByType('hover'),
|
|
272
|
+
generateHandleByType('selected'),
|
|
273
|
+
];
|
|
274
|
+
|
|
275
|
+
return hoveredCell.rowIndex < selectedRowIndexes[0]
|
|
276
|
+
? sortedHandles
|
|
277
|
+
: sortedHandles.reverse();
|
|
278
|
+
},
|
|
279
|
+
[generateHandleByType, selectedRowIndexes],
|
|
280
|
+
);
|
|
281
|
+
|
|
164
282
|
return (
|
|
165
283
|
<div
|
|
166
284
|
className={ClassName.DRAG_ROW_CONTROLS}
|
|
@@ -217,38 +335,7 @@ const DragControlsComponent = ({
|
|
|
217
335
|
)}
|
|
218
336
|
</Fragment>
|
|
219
337
|
))}
|
|
220
|
-
{!isResizing && Number.isFinite(rowIndex) && (
|
|
221
|
-
<div
|
|
222
|
-
style={{
|
|
223
|
-
gridRow: gridRowPosition,
|
|
224
|
-
gridColumn: '2',
|
|
225
|
-
display: 'flex',
|
|
226
|
-
height: '100%',
|
|
227
|
-
alignItems: 'center',
|
|
228
|
-
justifyContent: 'center',
|
|
229
|
-
}}
|
|
230
|
-
data-testid="table-floating-row-drag-handle"
|
|
231
|
-
>
|
|
232
|
-
<DragHandle
|
|
233
|
-
tableLocalId={currentNodeLocalId}
|
|
234
|
-
indexes={rowIndexes}
|
|
235
|
-
previewWidth={tableWidth}
|
|
236
|
-
previewHeight={rowHeights[rowIndex!]}
|
|
237
|
-
appearance={
|
|
238
|
-
selectedRowIndexes.includes(rowIndex!)
|
|
239
|
-
? isInDanger
|
|
240
|
-
? 'danger'
|
|
241
|
-
: 'selected'
|
|
242
|
-
: 'default'
|
|
243
|
-
}
|
|
244
|
-
onClick={handleClick}
|
|
245
|
-
onMouseOver={handleMouseOver}
|
|
246
|
-
onMouseOut={handleMouseOut}
|
|
247
|
-
onMouseUp={onMouseUp}
|
|
248
|
-
editorView={editorView}
|
|
249
|
-
/>
|
|
250
|
-
</div>
|
|
251
|
-
)}
|
|
338
|
+
{!isResizing && Number.isFinite(rowIndex) && rowHandles(hoveredCell)}
|
|
252
339
|
</div>
|
|
253
340
|
);
|
|
254
341
|
};
|
|
@@ -7,7 +7,6 @@ import type { Selection } from '@atlaskit/editor-prosemirror/state';
|
|
|
7
7
|
import type { EditorView } from '@atlaskit/editor-prosemirror/view';
|
|
8
8
|
|
|
9
9
|
import { hoverCell, hoverRows, selectRow } from '../../commands';
|
|
10
|
-
import { getPluginState } from '../../pm-plugins/plugin-factory';
|
|
11
10
|
import type { RowStickyState } from '../../pm-plugins/sticky-headers';
|
|
12
11
|
import { TableCssClassName as ClassName } from '../../types';
|
|
13
12
|
import type { CellHoverMeta } from '../../types';
|
|
@@ -24,6 +23,7 @@ export interface Props {
|
|
|
24
23
|
tableNode?: PmNode;
|
|
25
24
|
tableActive?: boolean;
|
|
26
25
|
isInDanger?: boolean;
|
|
26
|
+
isTableHovered?: boolean;
|
|
27
27
|
isResizing?: boolean;
|
|
28
28
|
isHeaderRowEnabled?: boolean;
|
|
29
29
|
isHeaderColumnEnabled?: boolean;
|
|
@@ -105,6 +105,7 @@ export default class TableFloatingControls extends Component<Props, State> {
|
|
|
105
105
|
headerRowHeight,
|
|
106
106
|
stickyHeader,
|
|
107
107
|
hoveredCell,
|
|
108
|
+
isTableHovered,
|
|
108
109
|
} = this.props;
|
|
109
110
|
return (
|
|
110
111
|
this.state.tableWrapperWidth !== nextState.tableWrapperWidth ||
|
|
@@ -121,7 +122,8 @@ export default class TableFloatingControls extends Component<Props, State> {
|
|
|
121
122
|
isSelectionUpdated(selection!, nextProps.selection) ||
|
|
122
123
|
headerRowHeight !== nextProps.headerRowHeight ||
|
|
123
124
|
stickyHeader !== nextProps.stickyHeader ||
|
|
124
|
-
hoveredCell !== nextProps.hoveredCell
|
|
125
|
+
hoveredCell !== nextProps.hoveredCell ||
|
|
126
|
+
isTableHovered !== nextProps.isTableHovered
|
|
125
127
|
);
|
|
126
128
|
}
|
|
127
129
|
|
|
@@ -147,6 +149,7 @@ export default class TableFloatingControls extends Component<Props, State> {
|
|
|
147
149
|
stickyHeader,
|
|
148
150
|
isDragAndDropEnabled,
|
|
149
151
|
hoveredCell,
|
|
152
|
+
isTableHovered,
|
|
150
153
|
} = this.props;
|
|
151
154
|
|
|
152
155
|
if (!tableRef) {
|
|
@@ -196,6 +199,7 @@ export default class TableFloatingControls extends Component<Props, State> {
|
|
|
196
199
|
tableRef={tableRef}
|
|
197
200
|
tableNode={tableNode}
|
|
198
201
|
hoveredCell={hoveredCell}
|
|
202
|
+
isTableHovered={isTableHovered}
|
|
199
203
|
editorView={editorView}
|
|
200
204
|
tableActive={tableActive}
|
|
201
205
|
isInDanger={isInDanger}
|
|
@@ -256,10 +260,13 @@ export default class TableFloatingControls extends Component<Props, State> {
|
|
|
256
260
|
private updateCellHoverLocation = (rowIndex: number) => {
|
|
257
261
|
const { editorView, tableActive } = this.props;
|
|
258
262
|
const { state, dispatch } = editorView;
|
|
259
|
-
const { hoveredCell } = getPluginState(state);
|
|
260
263
|
|
|
261
|
-
if (tableActive
|
|
262
|
-
|
|
264
|
+
if (tableActive) {
|
|
265
|
+
// For context: Whenever we mouse over a column or row drag handle, we will ALWAYS be hovering over the 0 index
|
|
266
|
+
// of the opposite dimension. For example; here when we mouse over the row drag handle then we're technically
|
|
267
|
+
// also hovering over column 0 index. And vice-versa with columns. This means we don't need to worry about knowing the
|
|
268
|
+
// current column index. We can just force it to 0.
|
|
269
|
+
hoverCell(rowIndex, 0)(state, dispatch);
|
|
263
270
|
}
|
|
264
271
|
};
|
|
265
272
|
}
|
|
@@ -264,3 +264,25 @@ export const getTop = (element: HTMLElement | Window | undefined): number => {
|
|
|
264
264
|
|
|
265
265
|
return element?.getBoundingClientRect?.()?.top ?? 0;
|
|
266
266
|
};
|
|
267
|
+
|
|
268
|
+
export const findNearestCellIndexToPoint = (
|
|
269
|
+
x: number,
|
|
270
|
+
y: number,
|
|
271
|
+
): { row: number; col: number } | undefined => {
|
|
272
|
+
const elements = document.elementsFromPoint(x, y);
|
|
273
|
+
const cell = elements.find(
|
|
274
|
+
(el) =>
|
|
275
|
+
el.nodeName.toUpperCase() === 'TD' || el.nodeName.toUpperCase() === 'TH',
|
|
276
|
+
) as HTMLTableCellElement | undefined;
|
|
277
|
+
const row = (cell?.parentElement ?? undefined) as
|
|
278
|
+
| HTMLTableRowElement
|
|
279
|
+
| undefined;
|
|
280
|
+
|
|
281
|
+
if (!Number.isFinite(row?.rowIndex) || !Number.isFinite(cell?.cellIndex)) {
|
|
282
|
+
return undefined;
|
|
283
|
+
}
|
|
284
|
+
return {
|
|
285
|
+
row: row!.rowIndex,
|
|
286
|
+
col: cell!.cellIndex,
|
|
287
|
+
};
|
|
288
|
+
};
|