@atlaskit/editor-plugin-table 5.3.10 → 5.3.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/dist/cjs/plugins/table/nodeviews/TableComponent.js +3 -2
- package/dist/cjs/plugins/table/pm-plugins/drag-and-drop/commands.js +5 -2
- package/dist/cjs/plugins/table/ui/DragHandle/index.js +11 -25
- package/dist/cjs/plugins/table/ui/TableFloatingColumnControls/ColumnControls/index.js +56 -20
- package/dist/cjs/plugins/table/ui/TableFloatingColumnControls/index.js +3 -1
- package/dist/cjs/plugins/table/ui/TableFloatingControls/NumberColumn/index.js +15 -27
- package/dist/cjs/plugins/table/ui/TableFloatingControls/RowControls/DragControls.js +68 -18
- package/dist/cjs/plugins/table/ui/TableFloatingControls/index.js +47 -29
- package/dist/cjs/plugins/table/ui/common-styles.js +2 -2
- package/dist/cjs/plugins/table/ui/icons/DragHandleIcon.js +11 -52
- package/dist/es2019/plugins/table/nodeviews/TableComponent.js +3 -2
- package/dist/es2019/plugins/table/pm-plugins/drag-and-drop/commands.js +6 -3
- package/dist/es2019/plugins/table/ui/DragHandle/index.js +10 -24
- package/dist/es2019/plugins/table/ui/TableFloatingColumnControls/ColumnControls/index.js +57 -15
- package/dist/es2019/plugins/table/ui/TableFloatingColumnControls/index.js +3 -1
- package/dist/es2019/plugins/table/ui/TableFloatingControls/NumberColumn/index.js +4 -20
- package/dist/es2019/plugins/table/ui/TableFloatingControls/RowControls/DragControls.js +69 -17
- package/dist/es2019/plugins/table/ui/TableFloatingControls/index.js +24 -2
- package/dist/es2019/plugins/table/ui/common-styles.js +64 -4
- package/dist/es2019/plugins/table/ui/icons/DragHandleIcon.js +11 -52
- package/dist/esm/plugins/table/nodeviews/TableComponent.js +3 -2
- package/dist/esm/plugins/table/pm-plugins/drag-and-drop/commands.js +6 -3
- package/dist/esm/plugins/table/ui/DragHandle/index.js +11 -25
- package/dist/esm/plugins/table/ui/TableFloatingColumnControls/ColumnControls/index.js +53 -19
- package/dist/esm/plugins/table/ui/TableFloatingColumnControls/index.js +3 -1
- package/dist/esm/plugins/table/ui/TableFloatingControls/NumberColumn/index.js +16 -28
- package/dist/esm/plugins/table/ui/TableFloatingControls/RowControls/DragControls.js +67 -19
- package/dist/esm/plugins/table/ui/TableFloatingControls/index.js +48 -30
- package/dist/esm/plugins/table/ui/common-styles.js +2 -2
- package/dist/esm/plugins/table/ui/icons/DragHandleIcon.js +11 -51
- package/dist/types/plugins/table/ui/DragHandle/index.d.ts +3 -3
- package/dist/types/plugins/table/ui/TableFloatingColumnControls/ColumnControls/index.d.ts +4 -3
- package/dist/types/plugins/table/ui/TableFloatingColumnControls/index.d.ts +1 -0
- package/dist/types/plugins/table/ui/TableFloatingControls/NumberColumn/index.d.ts +1 -1
- package/dist/types/plugins/table/ui/TableFloatingControls/RowControls/DragControls.d.ts +4 -2
- package/dist/types/plugins/table/ui/TableFloatingControls/index.d.ts +1 -0
- package/dist/types/plugins/table/ui/icons/DragHandleIcon.d.ts +1 -6
- package/dist/types-ts4.5/plugins/table/ui/DragHandle/index.d.ts +3 -3
- package/dist/types-ts4.5/plugins/table/ui/TableFloatingColumnControls/ColumnControls/index.d.ts +4 -3
- package/dist/types-ts4.5/plugins/table/ui/TableFloatingColumnControls/index.d.ts +1 -0
- package/dist/types-ts4.5/plugins/table/ui/TableFloatingControls/NumberColumn/index.d.ts +1 -1
- package/dist/types-ts4.5/plugins/table/ui/TableFloatingControls/RowControls/DragControls.d.ts +4 -2
- package/dist/types-ts4.5/plugins/table/ui/TableFloatingControls/index.d.ts +1 -0
- package/dist/types-ts4.5/plugins/table/ui/icons/DragHandleIcon.d.ts +1 -6
- package/package.json +2 -2
- package/src/__tests__/unit/ui/NumberColumn.tsx +5 -8
- package/src/__tests__/unit/ui/RowDragControls.tsx +6 -0
- package/src/plugins/table/nodeviews/TableComponent.tsx +3 -2
- package/src/plugins/table/pm-plugins/drag-and-drop/commands.ts +11 -3
- package/src/plugins/table/ui/DragHandle/index.tsx +10 -26
- package/src/plugins/table/ui/TableFloatingColumnControls/ColumnControls/index.tsx +69 -23
- package/src/plugins/table/ui/TableFloatingColumnControls/index.tsx +3 -0
- package/src/plugins/table/ui/TableFloatingControls/NumberColumn/index.tsx +10 -15
- package/src/plugins/table/ui/TableFloatingControls/RowControls/DragControls.tsx +95 -26
- package/src/plugins/table/ui/TableFloatingControls/index.tsx +17 -1
- package/src/plugins/table/ui/common-styles.ts +67 -4
- package/src/plugins/table/ui/icons/DragHandleIcon.tsx +5 -69
|
@@ -435,12 +435,13 @@ class TableComponent extends React.Component<ComponentProps, TableState> {
|
|
|
435
435
|
</div>
|
|
436
436
|
);
|
|
437
437
|
|
|
438
|
-
const colControls = (
|
|
438
|
+
const colControls = isDragAndDropEnabled ? (
|
|
439
439
|
<TableFloatingColumnControls
|
|
440
440
|
editorView={view}
|
|
441
441
|
tableRef={tableRef}
|
|
442
442
|
getNode={getNode}
|
|
443
443
|
tableActive={tableActive}
|
|
444
|
+
isInDanger={isInDanger}
|
|
444
445
|
hoveredRows={hoveredRows}
|
|
445
446
|
hoveredCell={hoveredCell}
|
|
446
447
|
isResizing={isResizing}
|
|
@@ -452,7 +453,7 @@ class TableComponent extends React.Component<ComponentProps, TableState> {
|
|
|
452
453
|
stickyHeader={this.state.stickyHeader}
|
|
453
454
|
getEditorFeatureFlags={this.props.getEditorFeatureFlags}
|
|
454
455
|
/>
|
|
455
|
-
);
|
|
456
|
+
) : null;
|
|
456
457
|
|
|
457
458
|
const shadowPadding =
|
|
458
459
|
allowControls && tableActive ? -tableToolbarSize : tableMarginSides;
|
|
@@ -4,7 +4,12 @@ import type {
|
|
|
4
4
|
} from '@atlaskit/editor-prosemirror/state';
|
|
5
5
|
import type { Decoration } from '@atlaskit/editor-prosemirror/view';
|
|
6
6
|
import { DecorationSet } from '@atlaskit/editor-prosemirror/view';
|
|
7
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
moveColumn,
|
|
9
|
+
moveRow,
|
|
10
|
+
selectColumn,
|
|
11
|
+
selectRow,
|
|
12
|
+
} from '@atlaskit/editor-tables/utils';
|
|
8
13
|
|
|
9
14
|
import type { DraggableType } from '../../types';
|
|
10
15
|
import { TableDecorations } from '../../types';
|
|
@@ -109,7 +114,10 @@ export const moveSource = (
|
|
|
109
114
|
return tr.setMeta('addToHistory', false);
|
|
110
115
|
}
|
|
111
116
|
|
|
112
|
-
const
|
|
113
|
-
|
|
117
|
+
const isTableRow = sourceType === 'table-row';
|
|
118
|
+
const move = isTableRow ? moveRow : moveColumn;
|
|
119
|
+
const newTr = move(sourceIndex, targetIndex)(tr);
|
|
120
|
+
const select = isTableRow ? selectRow : selectColumn;
|
|
121
|
+
return select(targetIndex)(newTr);
|
|
114
122
|
},
|
|
115
123
|
);
|
|
@@ -1,18 +1,17 @@
|
|
|
1
1
|
import type { MouseEventHandler } from 'react';
|
|
2
2
|
import React, { useEffect, useRef, useState } from 'react';
|
|
3
3
|
|
|
4
|
+
import classnames from 'classnames';
|
|
4
5
|
import ReactDOM from 'react-dom';
|
|
5
6
|
|
|
6
7
|
import { draggable } from '@atlaskit/pragmatic-drag-and-drop/adapter/element';
|
|
7
8
|
import { setCustomNativeDragPreview } from '@atlaskit/pragmatic-drag-and-drop/util/set-custom-native-drag-preview';
|
|
8
|
-
import { N200, N700 } from '@atlaskit/theme/colors';
|
|
9
|
-
import { token } from '@atlaskit/tokens';
|
|
10
9
|
|
|
11
10
|
import { TableCssClassName as ClassName } from '../../types';
|
|
12
11
|
import { DragPreview } from '../DragPreview';
|
|
13
12
|
import { DragHandleIcon } from '../icons';
|
|
14
13
|
|
|
15
|
-
type
|
|
14
|
+
type DragHandleAppearance = 'default' | 'selected' | 'disabled' | 'danger';
|
|
16
15
|
|
|
17
16
|
type DragHandleProps = {
|
|
18
17
|
tableLocalId: string;
|
|
@@ -20,39 +19,24 @@ type DragHandleProps = {
|
|
|
20
19
|
previewWidth?: number;
|
|
21
20
|
previewHeight?: number;
|
|
22
21
|
direction?: 'column' | 'row';
|
|
23
|
-
|
|
22
|
+
appearance?: DragHandleAppearance;
|
|
24
23
|
onClick?: MouseEventHandler;
|
|
25
24
|
onMouseOver?: MouseEventHandler;
|
|
26
25
|
onMouseOut?: MouseEventHandler;
|
|
27
26
|
};
|
|
28
27
|
|
|
29
|
-
const mapStateToProps = (state: DragHandleState) => {
|
|
30
|
-
switch (state) {
|
|
31
|
-
case 'danger':
|
|
32
|
-
case 'disabled':
|
|
33
|
-
case 'selected':
|
|
34
|
-
case 'default':
|
|
35
|
-
default:
|
|
36
|
-
return {
|
|
37
|
-
backgroundColor: token('color.background.accent.gray.subtlest', N200),
|
|
38
|
-
foregroundColor: token('color.icon.subtle', N700),
|
|
39
|
-
};
|
|
40
|
-
}
|
|
41
|
-
};
|
|
42
|
-
|
|
43
28
|
export const DragHandle = ({
|
|
44
29
|
tableLocalId,
|
|
45
30
|
direction = 'row',
|
|
46
|
-
|
|
31
|
+
appearance = 'default',
|
|
47
32
|
indexes,
|
|
48
33
|
previewWidth,
|
|
49
34
|
previewHeight,
|
|
50
|
-
onClick,
|
|
51
35
|
onMouseOver,
|
|
52
36
|
onMouseOut,
|
|
37
|
+
onClick,
|
|
53
38
|
}: DragHandleProps) => {
|
|
54
39
|
const dragHandleDivRef = useRef<HTMLButtonElement>(null);
|
|
55
|
-
const iconProps = mapStateToProps(state);
|
|
56
40
|
const [previewContainer, setPreviewContainer] = useState<HTMLElement | null>(
|
|
57
41
|
null,
|
|
58
42
|
);
|
|
@@ -92,18 +76,18 @@ export const DragHandle = ({
|
|
|
92
76
|
|
|
93
77
|
return (
|
|
94
78
|
<button
|
|
95
|
-
className={ClassName.DRAG_HANDLE_BUTTON_CONTAINER}
|
|
79
|
+
className={classnames(ClassName.DRAG_HANDLE_BUTTON_CONTAINER, appearance)}
|
|
96
80
|
ref={dragHandleDivRef}
|
|
97
81
|
style={{
|
|
98
|
-
backgroundColor: `${token('elevation.surface', 'white')}`,
|
|
99
|
-
borderRadius: '4px',
|
|
100
|
-
border: `2px solid ${token('elevation.surface', 'white')}`,
|
|
101
82
|
transform: direction === 'column' ? 'none' : 'rotate(90deg)',
|
|
102
83
|
pointerEvents: 'auto',
|
|
103
84
|
}}
|
|
104
85
|
data-testid="table-floating-column-controls-drag-handle"
|
|
86
|
+
onMouseOver={onMouseOver}
|
|
87
|
+
onMouseOut={onMouseOut}
|
|
88
|
+
onClick={onClick}
|
|
105
89
|
>
|
|
106
|
-
<DragHandleIcon
|
|
90
|
+
<DragHandleIcon />
|
|
107
91
|
{previewContainer &&
|
|
108
92
|
previewWidth !== undefined &&
|
|
109
93
|
previewHeight !== undefined &&
|
|
@@ -1,14 +1,25 @@
|
|
|
1
|
-
import
|
|
1
|
+
import type { MouseEvent } from 'react';
|
|
2
|
+
import React, { useCallback, useMemo } from 'react';
|
|
2
3
|
|
|
4
|
+
import type { Selection } from '@atlaskit/editor-prosemirror/state';
|
|
3
5
|
import type { EditorView } from '@atlaskit/editor-prosemirror/view';
|
|
6
|
+
import { CellSelection } from '@atlaskit/editor-tables';
|
|
7
|
+
import { getSelectionRect } from '@atlaskit/editor-tables/utils';
|
|
4
8
|
|
|
9
|
+
import {
|
|
10
|
+
clearHoverSelection,
|
|
11
|
+
hoverColumns,
|
|
12
|
+
selectColumn,
|
|
13
|
+
} from '../../../commands';
|
|
5
14
|
import type { CellHoverMeta } from '../../../types';
|
|
6
15
|
import { TableCssClassName as ClassName } from '../../../types';
|
|
16
|
+
import { getSelectedColumnIndexes } from '../../../utils';
|
|
7
17
|
import { DragHandle } from '../../DragHandle';
|
|
8
18
|
|
|
9
|
-
export interface
|
|
19
|
+
export interface ColumnControlsProps {
|
|
10
20
|
editorView: EditorView;
|
|
11
21
|
tableActive?: boolean;
|
|
22
|
+
isInDanger?: boolean;
|
|
12
23
|
tableRef: HTMLTableElement;
|
|
13
24
|
hoveredCell?: CellHoverMeta;
|
|
14
25
|
isResizing?: boolean;
|
|
@@ -18,7 +29,18 @@ export interface Props {
|
|
|
18
29
|
colWidths?: (number | undefined)[];
|
|
19
30
|
}
|
|
20
31
|
|
|
21
|
-
|
|
32
|
+
const getSelectedColumns = (selection: Selection) => {
|
|
33
|
+
if (selection instanceof CellSelection && selection.isColSelection()) {
|
|
34
|
+
const rect = getSelectionRect(selection);
|
|
35
|
+
if (!rect) {
|
|
36
|
+
return [];
|
|
37
|
+
}
|
|
38
|
+
return getSelectedColumnIndexes(rect);
|
|
39
|
+
}
|
|
40
|
+
return [];
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
export const ColumnControls = ({
|
|
22
44
|
editorView,
|
|
23
45
|
tableActive,
|
|
24
46
|
tableRef,
|
|
@@ -26,12 +48,23 @@ export const ColumnControls: React.FC<Props> = ({
|
|
|
26
48
|
isResizing,
|
|
27
49
|
stickyTop,
|
|
28
50
|
localId,
|
|
51
|
+
isInDanger,
|
|
29
52
|
rowHeights,
|
|
30
53
|
colWidths,
|
|
31
|
-
}) => {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
54
|
+
}: ColumnControlsProps) => {
|
|
55
|
+
const widths =
|
|
56
|
+
colWidths?.map((width) => (width ? `${width - 1}px` : '0px')).join(' ') ??
|
|
57
|
+
'0px';
|
|
58
|
+
const colIndex = hoveredCell?.colIndex;
|
|
59
|
+
const selectedColIndexes = getSelectedColumns(editorView.state.selection);
|
|
60
|
+
|
|
61
|
+
const gridColumnPosition = useMemo(() => {
|
|
62
|
+
// if more than one row is selected, ensure the handle spans over the selected range
|
|
63
|
+
if (selectedColIndexes.includes(colIndex!)) {
|
|
64
|
+
return `${selectedColIndexes[0] + 1} / span ${selectedColIndexes.length}`;
|
|
65
|
+
}
|
|
66
|
+
return `${colIndex! + 1} / span 1`;
|
|
67
|
+
}, [colIndex, selectedColIndexes]);
|
|
35
68
|
|
|
36
69
|
const firstRow = tableRef.querySelector('tr');
|
|
37
70
|
const hasHeaderRow = firstRow
|
|
@@ -41,17 +74,25 @@ export const ColumnControls: React.FC<Props> = ({
|
|
|
41
74
|
const marginTop =
|
|
42
75
|
hasHeaderRow && stickyTop !== undefined ? rowHeights?.[0] ?? 0 : 0;
|
|
43
76
|
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
|
|
77
|
+
const handleClick = useCallback(
|
|
78
|
+
(event: MouseEvent) => {
|
|
79
|
+
const { state, dispatch } = editorView;
|
|
80
|
+
selectColumn(colIndex!, event.shiftKey)(state, dispatch);
|
|
81
|
+
},
|
|
82
|
+
[colIndex, editorView],
|
|
83
|
+
);
|
|
47
84
|
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
85
|
+
const handleMouseOver = useCallback(() => {
|
|
86
|
+
const { state, dispatch } = editorView;
|
|
87
|
+
hoverColumns([colIndex!])(state, dispatch);
|
|
88
|
+
}, [colIndex, editorView]);
|
|
52
89
|
|
|
53
|
-
const
|
|
54
|
-
|
|
90
|
+
const handleMouseOut = useCallback(() => {
|
|
91
|
+
if (tableActive) {
|
|
92
|
+
const { state, dispatch } = editorView;
|
|
93
|
+
clearHoverSelection()(state, dispatch);
|
|
94
|
+
}
|
|
95
|
+
}, [editorView, tableActive]);
|
|
55
96
|
|
|
56
97
|
return (
|
|
57
98
|
<div className={ClassName.COLUMN_CONTROLS_WITH_DRAG}>
|
|
@@ -69,7 +110,7 @@ export const ColumnControls: React.FC<Props> = ({
|
|
|
69
110
|
Number.isFinite(hoveredCell.colIndex) && (
|
|
70
111
|
<div
|
|
71
112
|
style={{
|
|
72
|
-
gridColumn:
|
|
113
|
+
gridColumn: gridColumnPosition,
|
|
73
114
|
marginTop: `-15px`,
|
|
74
115
|
}}
|
|
75
116
|
data-column-control-index={hoveredCell.colIndex}
|
|
@@ -77,15 +118,20 @@ export const ColumnControls: React.FC<Props> = ({
|
|
|
77
118
|
>
|
|
78
119
|
<DragHandle
|
|
79
120
|
direction="column"
|
|
80
|
-
indexes={[hoveredCell.colIndex!]}
|
|
81
|
-
onClick={(event) =>
|
|
82
|
-
onClick(hoveredCell.colIndex as number, event)
|
|
83
|
-
}
|
|
84
|
-
onMouseOver={onMouseOver}
|
|
85
|
-
onMouseOut={onMouseOut}
|
|
86
121
|
tableLocalId={localId || ''}
|
|
122
|
+
indexes={[hoveredCell.colIndex!]}
|
|
87
123
|
previewWidth={hoveredCell.colWidth}
|
|
88
124
|
previewHeight={hoveredCell.colHeight}
|
|
125
|
+
appearance={
|
|
126
|
+
selectedColIndexes.includes(hoveredCell.colIndex!)
|
|
127
|
+
? isInDanger
|
|
128
|
+
? 'danger'
|
|
129
|
+
: 'selected'
|
|
130
|
+
: 'default'
|
|
131
|
+
}
|
|
132
|
+
onClick={handleClick}
|
|
133
|
+
onMouseOver={handleMouseOver}
|
|
134
|
+
onMouseOut={handleMouseOut}
|
|
89
135
|
/>
|
|
90
136
|
</div>
|
|
91
137
|
)}
|
|
@@ -24,6 +24,7 @@ export interface Props {
|
|
|
24
24
|
tableRef?: HTMLTableElement;
|
|
25
25
|
getNode: () => PmNode;
|
|
26
26
|
tableActive?: boolean;
|
|
27
|
+
isInDanger?: boolean;
|
|
27
28
|
hasHeaderRow?: boolean;
|
|
28
29
|
headerRowHeight?: number;
|
|
29
30
|
hoveredRows?: number[];
|
|
@@ -43,6 +44,7 @@ export const TableFloatingColumnControls: React.FC<Props> = ({
|
|
|
43
44
|
isResizing,
|
|
44
45
|
stickyHeader,
|
|
45
46
|
selection,
|
|
47
|
+
isInDanger,
|
|
46
48
|
}) => {
|
|
47
49
|
const [tableRect, setTableRect] = useState<{ width: number; height: number }>(
|
|
48
50
|
{ width: 0, height: 0 },
|
|
@@ -132,6 +134,7 @@ export const TableFloatingColumnControls: React.FC<Props> = ({
|
|
|
132
134
|
tableActive={tableActive}
|
|
133
135
|
stickyTop={tableActive ? stickyTop : undefined}
|
|
134
136
|
localId={currentNodeLocalId}
|
|
137
|
+
isInDanger={isInDanger}
|
|
135
138
|
rowHeights={rowHeights}
|
|
136
139
|
colWidths={colWidths}
|
|
137
140
|
/>
|
|
@@ -6,8 +6,7 @@ import { Selection } from '@atlaskit/editor-prosemirror/state';
|
|
|
6
6
|
import type { EditorView } from '@atlaskit/editor-prosemirror/view';
|
|
7
7
|
import { isRowSelected } from '@atlaskit/editor-tables/utils';
|
|
8
8
|
|
|
9
|
-
import { clearHoverSelection
|
|
10
|
-
import { getPluginState } from '../../../pm-plugins/plugin-factory';
|
|
9
|
+
import { clearHoverSelection } from '../../../commands';
|
|
11
10
|
import { TableCssClassName as ClassName } from '../../../types';
|
|
12
11
|
import { getRowHeights } from '../../../utils';
|
|
13
12
|
import { tableBorderColor } from '../../consts';
|
|
@@ -19,6 +18,7 @@ export interface Props {
|
|
|
19
18
|
hoverRows: (rows: number[], danger?: boolean) => void;
|
|
20
19
|
hoveredRows?: number[];
|
|
21
20
|
selectRow: (row: number, expand: boolean) => void;
|
|
21
|
+
updateCellHoverLocation: (rowIndex: number) => void;
|
|
22
22
|
hasHeaderRow?: boolean;
|
|
23
23
|
isInDanger?: boolean;
|
|
24
24
|
isResizing?: boolean;
|
|
@@ -28,8 +28,13 @@ export interface Props {
|
|
|
28
28
|
|
|
29
29
|
export default class NumberColumn extends Component<Props, any> {
|
|
30
30
|
render() {
|
|
31
|
-
const {
|
|
32
|
-
|
|
31
|
+
const {
|
|
32
|
+
tableRef,
|
|
33
|
+
hasHeaderRow,
|
|
34
|
+
isDragAndDropEnabled,
|
|
35
|
+
tableActive,
|
|
36
|
+
updateCellHoverLocation,
|
|
37
|
+
} = this.props;
|
|
33
38
|
const rowHeights = getRowHeights(tableRef);
|
|
34
39
|
|
|
35
40
|
return (
|
|
@@ -54,7 +59,7 @@ export default class NumberColumn extends Component<Props, any> {
|
|
|
54
59
|
className={this.getClassNames(index, true)}
|
|
55
60
|
data-index={index}
|
|
56
61
|
style={this.getCellStyles(index, rowHeight)}
|
|
57
|
-
onMouseOver={() =>
|
|
62
|
+
onMouseOver={() => updateCellHoverLocation(index)}
|
|
58
63
|
>
|
|
59
64
|
{hasHeaderRow ? (index > 0 ? index : null) : index + 1}
|
|
60
65
|
</div>
|
|
@@ -109,16 +114,6 @@ export default class NumberColumn extends Component<Props, any> {
|
|
|
109
114
|
}
|
|
110
115
|
};
|
|
111
116
|
|
|
112
|
-
private updateDragHandleLocation = (rowIndex: number) => {
|
|
113
|
-
const { editorView, tableActive } = this.props;
|
|
114
|
-
const { state, dispatch } = editorView;
|
|
115
|
-
const { hoveredCell } = getPluginState(state);
|
|
116
|
-
|
|
117
|
-
if (tableActive && hoveredCell.rowIndex !== rowIndex) {
|
|
118
|
-
hoverCell(rowIndex, hoveredCell.colIndex)(state, dispatch);
|
|
119
|
-
}
|
|
120
|
-
};
|
|
121
|
-
|
|
122
117
|
private getCellStyles = (index: number, rowHeight: number) => {
|
|
123
118
|
const { stickyTop, hasHeaderRow } = this.props;
|
|
124
119
|
if (stickyTop && hasHeaderRow && index === 0) {
|
|
@@ -1,14 +1,18 @@
|
|
|
1
|
-
import
|
|
1
|
+
import type { MouseEvent } from 'react';
|
|
2
|
+
import React, { useCallback, useMemo } from 'react';
|
|
2
3
|
|
|
3
4
|
import { injectIntl } from 'react-intl-next';
|
|
4
5
|
import type { WrappedComponentProps } from 'react-intl-next';
|
|
5
6
|
|
|
7
|
+
import type { Selection } from '@atlaskit/editor-prosemirror/state';
|
|
6
8
|
import type { EditorView } from '@atlaskit/editor-prosemirror/view';
|
|
7
|
-
import {
|
|
9
|
+
import { CellSelection } from '@atlaskit/editor-tables';
|
|
10
|
+
import { findTable, getSelectionRect } from '@atlaskit/editor-tables/utils';
|
|
8
11
|
|
|
12
|
+
import { clearHoverSelection } from '../../../commands';
|
|
9
13
|
import type { CellHoverMeta } from '../../../types';
|
|
10
14
|
import { TableCssClassName as ClassName } from '../../../types';
|
|
11
|
-
import { getRowHeights } from '../../../utils';
|
|
15
|
+
import { getRowHeights, getSelectedRowIndexes } from '../../../utils';
|
|
12
16
|
import { DragHandle } from '../../DragHandle';
|
|
13
17
|
|
|
14
18
|
type DragControlsProps = {
|
|
@@ -16,61 +20,126 @@ type DragControlsProps = {
|
|
|
16
20
|
tableRef: HTMLTableElement;
|
|
17
21
|
tableActive?: boolean;
|
|
18
22
|
hoveredCell?: CellHoverMeta;
|
|
19
|
-
|
|
20
|
-
|
|
23
|
+
isInDanger?: boolean;
|
|
24
|
+
hoverRows: (rows: number[], danger?: boolean) => void;
|
|
25
|
+
selectRow: (row: number, expand: boolean) => void;
|
|
26
|
+
updateCellHoverLocation: (rowIndex: number) => void;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const getSelectedRows = (selection: Selection) => {
|
|
30
|
+
if (selection instanceof CellSelection && selection.isRowSelection()) {
|
|
31
|
+
const rect = getSelectionRect(selection);
|
|
32
|
+
if (!rect) {
|
|
33
|
+
return [];
|
|
34
|
+
}
|
|
35
|
+
return getSelectedRowIndexes(rect);
|
|
36
|
+
}
|
|
37
|
+
return [];
|
|
21
38
|
};
|
|
22
39
|
|
|
23
40
|
const DragControlsComponent = ({
|
|
24
41
|
tableRef,
|
|
25
42
|
hoveredCell,
|
|
26
|
-
hoverRows,
|
|
27
|
-
selectRow,
|
|
28
43
|
tableActive,
|
|
29
44
|
editorView,
|
|
45
|
+
isInDanger,
|
|
46
|
+
hoverRows,
|
|
47
|
+
selectRow,
|
|
48
|
+
updateCellHoverLocation,
|
|
30
49
|
}: DragControlsProps & WrappedComponentProps) => {
|
|
31
50
|
const rowHeights = getRowHeights(tableRef);
|
|
32
|
-
const heights = rowHeights
|
|
33
|
-
|
|
34
|
-
.join(' ');
|
|
51
|
+
const heights = rowHeights.map((height) => `${height - 1}px`).join(' ');
|
|
52
|
+
const selectedRowIndexes = getSelectedRows(editorView.state.selection);
|
|
35
53
|
const rowWidth = tableRef.offsetWidth;
|
|
36
|
-
|
|
37
|
-
const onClick = (
|
|
38
|
-
index: number,
|
|
39
|
-
event: React.MouseEvent<Element, MouseEvent>,
|
|
40
|
-
) => {};
|
|
41
|
-
|
|
42
|
-
const onMouseOver = () => {};
|
|
43
|
-
const onMouseOut = () => {};
|
|
44
|
-
|
|
45
54
|
const rowIndex = hoveredCell?.rowIndex;
|
|
46
55
|
|
|
56
|
+
const gridRowPosition = useMemo(() => {
|
|
57
|
+
// if more than one row is selected, ensure the handle spans over the selected range
|
|
58
|
+
if (selectedRowIndexes.includes(rowIndex!)) {
|
|
59
|
+
return `${selectedRowIndexes[0] + 1} / span ${selectedRowIndexes.length}`;
|
|
60
|
+
}
|
|
61
|
+
return `${rowIndex! + 1} / span 1`;
|
|
62
|
+
}, [rowIndex, selectedRowIndexes]);
|
|
63
|
+
|
|
47
64
|
const getLocalId = () => {
|
|
48
65
|
const tableNode = findTable(editorView.state.selection);
|
|
49
66
|
return tableNode?.node?.attrs?.localId || '';
|
|
50
67
|
};
|
|
51
68
|
|
|
69
|
+
const handleMouseOut = useCallback(() => {
|
|
70
|
+
if (tableActive) {
|
|
71
|
+
const { state, dispatch } = editorView;
|
|
72
|
+
clearHoverSelection()(state, dispatch);
|
|
73
|
+
}
|
|
74
|
+
}, [editorView, tableActive]);
|
|
75
|
+
|
|
76
|
+
const handleMouseMove = useCallback(
|
|
77
|
+
(e: MouseEvent) => {
|
|
78
|
+
// avoid updating if event target is drag handle
|
|
79
|
+
if (
|
|
80
|
+
!(e.nativeEvent.target as Element).classList.contains(
|
|
81
|
+
ClassName.ROW_CONTROLS_WITH_DRAG,
|
|
82
|
+
)
|
|
83
|
+
) {
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const hoverHeight = e.nativeEvent.offsetY;
|
|
88
|
+
let totalHeight = 0;
|
|
89
|
+
const rowIndex = rowHeights.findIndex((row) => {
|
|
90
|
+
totalHeight += row;
|
|
91
|
+
return hoverHeight <= totalHeight;
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
updateCellHoverLocation(rowIndex);
|
|
95
|
+
},
|
|
96
|
+
[updateCellHoverLocation, rowHeights],
|
|
97
|
+
);
|
|
98
|
+
|
|
99
|
+
const handleMouseOver = useCallback(() => {
|
|
100
|
+
hoverRows([rowIndex!]);
|
|
101
|
+
}, [hoverRows, rowIndex]);
|
|
102
|
+
|
|
103
|
+
const handleClick = useCallback(
|
|
104
|
+
(e: MouseEvent) => {
|
|
105
|
+
selectRow(rowIndex!, e?.shiftKey);
|
|
106
|
+
},
|
|
107
|
+
[rowIndex, selectRow],
|
|
108
|
+
);
|
|
109
|
+
|
|
52
110
|
return (
|
|
53
111
|
<div
|
|
54
112
|
className={ClassName.ROW_CONTROLS_WITH_DRAG}
|
|
55
113
|
style={{
|
|
56
114
|
gridTemplateRows: heights,
|
|
57
115
|
}}
|
|
116
|
+
onMouseMove={handleMouseMove}
|
|
58
117
|
>
|
|
59
|
-
{
|
|
118
|
+
{Number.isFinite(rowIndex) && (
|
|
60
119
|
<div
|
|
61
120
|
style={{
|
|
62
|
-
gridRow:
|
|
121
|
+
gridRow: gridRowPosition,
|
|
63
122
|
display: 'flex',
|
|
123
|
+
height: '100%',
|
|
124
|
+
alignItems: 'center',
|
|
125
|
+
justifyContent: 'center',
|
|
64
126
|
}}
|
|
65
127
|
>
|
|
66
128
|
<DragHandle
|
|
67
|
-
onClick={(event) => onClick(rowIndex as number, event)}
|
|
68
|
-
onMouseOver={onMouseOver}
|
|
69
|
-
onMouseOut={onMouseOut}
|
|
70
129
|
tableLocalId={getLocalId()}
|
|
71
|
-
indexes={[rowIndex]}
|
|
130
|
+
indexes={[rowIndex!]}
|
|
72
131
|
previewWidth={rowWidth}
|
|
73
|
-
previewHeight={rowHeights[rowIndex]}
|
|
132
|
+
previewHeight={rowHeights[rowIndex!]}
|
|
133
|
+
appearance={
|
|
134
|
+
selectedRowIndexes.includes(rowIndex!)
|
|
135
|
+
? isInDanger
|
|
136
|
+
? 'danger'
|
|
137
|
+
: 'selected'
|
|
138
|
+
: 'default'
|
|
139
|
+
}
|
|
140
|
+
onClick={handleClick}
|
|
141
|
+
onMouseOver={handleMouseOver}
|
|
142
|
+
onMouseOut={handleMouseOut}
|
|
74
143
|
/>
|
|
75
144
|
</div>
|
|
76
145
|
)}
|
|
@@ -5,7 +5,8 @@ import { browser } from '@atlaskit/editor-common/utils';
|
|
|
5
5
|
import type { Selection } from '@atlaskit/editor-prosemirror/state';
|
|
6
6
|
import type { EditorView } from '@atlaskit/editor-prosemirror/view';
|
|
7
7
|
|
|
8
|
-
import { hoverRows, selectRow } from '../../commands';
|
|
8
|
+
import { hoverCell, hoverRows, selectRow } from '../../commands';
|
|
9
|
+
import { getPluginState } from '../../pm-plugins/plugin-factory';
|
|
9
10
|
import type { RowStickyState } from '../../pm-plugins/sticky-headers';
|
|
10
11
|
import type { CellHoverMeta } from '../../types';
|
|
11
12
|
import { isSelectionUpdated } from '../../utils';
|
|
@@ -145,6 +146,7 @@ export default class TableFloatingControls extends Component<Props, State> {
|
|
|
145
146
|
isInDanger={isInDanger}
|
|
146
147
|
isResizing={isResizing}
|
|
147
148
|
selectRow={this.selectRow}
|
|
149
|
+
updateCellHoverLocation={this.updateCellHoverLocation}
|
|
148
150
|
stickyTop={stickyTop}
|
|
149
151
|
isDragAndDropEnabled={isDragAndDropEnabled}
|
|
150
152
|
/>
|
|
@@ -157,8 +159,11 @@ export default class TableFloatingControls extends Component<Props, State> {
|
|
|
157
159
|
tableRef={tableRef}
|
|
158
160
|
hoveredCell={hoveredCell}
|
|
159
161
|
editorView={editorView}
|
|
162
|
+
tableActive={tableActive}
|
|
163
|
+
isInDanger={isInDanger}
|
|
160
164
|
hoverRows={this.hoverRows}
|
|
161
165
|
selectRow={this.selectRow}
|
|
166
|
+
updateCellHoverLocation={this.updateCellHoverLocation}
|
|
162
167
|
/>
|
|
163
168
|
) : (
|
|
164
169
|
<>
|
|
@@ -204,4 +209,15 @@ export default class TableFloatingControls extends Component<Props, State> {
|
|
|
204
209
|
const { state, dispatch } = this.props.editorView;
|
|
205
210
|
hoverRows(rows, danger)(state, dispatch);
|
|
206
211
|
};
|
|
212
|
+
|
|
213
|
+
// re-use across numbered columns and row controls
|
|
214
|
+
private updateCellHoverLocation = (rowIndex: number) => {
|
|
215
|
+
const { editorView, tableActive } = this.props;
|
|
216
|
+
const { state, dispatch } = editorView;
|
|
217
|
+
const { hoveredCell } = getPluginState(state);
|
|
218
|
+
|
|
219
|
+
if (tableActive && hoveredCell.rowIndex !== rowIndex) {
|
|
220
|
+
hoverCell(rowIndex, hoveredCell.colIndex)(state, dispatch);
|
|
221
|
+
}
|
|
222
|
+
};
|
|
207
223
|
}
|
|
@@ -249,7 +249,7 @@ const tableRowControlStyles = () => {
|
|
|
249
249
|
position: absolute;
|
|
250
250
|
margin-top: ${tableMarginTop}px;
|
|
251
251
|
left: -${tableToolbarSize + 1}px;
|
|
252
|
-
z-index: ${rowControlsZIndex};
|
|
252
|
+
z-index: ${rowControlsZIndex + 4};
|
|
253
253
|
}
|
|
254
254
|
`
|
|
255
255
|
: css`
|
|
@@ -705,14 +705,77 @@ export const tableStyles = (
|
|
|
705
705
|
align-items: center;
|
|
706
706
|
position: absolute;
|
|
707
707
|
left: -4px;
|
|
708
|
+
z-index: ${akEditorUnitZIndex};
|
|
708
709
|
}
|
|
709
710
|
|
|
710
711
|
.${ClassName.DRAG_HANDLE_BUTTON_CONTAINER} {
|
|
711
712
|
cursor: grab;
|
|
712
|
-
width: max-content;
|
|
713
713
|
padding: 0;
|
|
714
|
-
|
|
715
|
-
|
|
714
|
+
|
|
715
|
+
border-radius: 6px;
|
|
716
|
+
width: max-content;
|
|
717
|
+
height: max-content;
|
|
718
|
+
border: 2px solid ${token('elevation.surface', N0)};
|
|
719
|
+
display: flex;
|
|
720
|
+
justify-content: center;
|
|
721
|
+
align-items: center;
|
|
722
|
+
|
|
723
|
+
svg {
|
|
724
|
+
rect {
|
|
725
|
+
//
|
|
726
|
+
fill: ${token('color.background.accent.gray.subtlest', '#F1F2F4')};
|
|
727
|
+
}
|
|
728
|
+
g {
|
|
729
|
+
fill: ${token('color.icon.subtle', '#626F86')};
|
|
730
|
+
}
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
&:hover {
|
|
734
|
+
svg {
|
|
735
|
+
rect {
|
|
736
|
+
fill: ${token('color.background.accent.blue.subtle', '#579DFF')};
|
|
737
|
+
}
|
|
738
|
+
g {
|
|
739
|
+
fill: ${token('color.icon.inverse', '#FFF')};
|
|
740
|
+
}
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
&.selected {
|
|
745
|
+
svg {
|
|
746
|
+
rect {
|
|
747
|
+
fill: ${token('color.background.accent.blue.subtle', '#579DFF')};
|
|
748
|
+
}
|
|
749
|
+
g {
|
|
750
|
+
fill: ${token('color.icon.inverse', '#FFF')};
|
|
751
|
+
}
|
|
752
|
+
}
|
|
753
|
+
}
|
|
754
|
+
|
|
755
|
+
&.danger {
|
|
756
|
+
svg {
|
|
757
|
+
rect {
|
|
758
|
+
fill: ${token(
|
|
759
|
+
'color.background.accent.red.subtler.pressed',
|
|
760
|
+
'#F87462',
|
|
761
|
+
)};
|
|
762
|
+
}
|
|
763
|
+
g {
|
|
764
|
+
fill: ${token('color.border.inverse', '#FFF')};
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
&.disabled {
|
|
770
|
+
svg {
|
|
771
|
+
rect {
|
|
772
|
+
fill: ${token('color.background.accent.gray.subtlest', '#F1F2F4')};
|
|
773
|
+
}
|
|
774
|
+
g {
|
|
775
|
+
fill: ${token('color.border.inverse', '#FFF')};
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
}
|
|
716
779
|
}
|
|
717
780
|
|
|
718
781
|
${floatingColumnControls(props)}
|