@atlaskit/editor-plugin-table 5.4.14 → 5.4.15
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 +10 -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/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 +16 -8
- package/dist/cjs/plugins/table/ui/TableFloatingColumnControls/index.js +3 -1
- package/dist/cjs/plugins/table/ui/TableFloatingControls/RowControls/DragControls.js +2 -1
- 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/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 +14 -8
- package/dist/es2019/plugins/table/ui/TableFloatingColumnControls/index.js +3 -1
- package/dist/es2019/plugins/table/ui/TableFloatingControls/RowControls/DragControls.js +2 -1
- 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/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 +16 -8
- package/dist/esm/plugins/table/ui/TableFloatingColumnControls/index.js +3 -1
- package/dist/esm/plugins/table/ui/TableFloatingControls/RowControls/DragControls.js +2 -1
- 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 +6 -2
- 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 +6 -2
- 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 +7 -2
- package/src/plugins/table/ui/TableFloatingColumnControls/ColumnControls/index.tsx +14 -5
- package/src/plugins/table/ui/TableFloatingColumnControls/index.tsx +3 -0
- package/src/plugins/table/ui/TableFloatingControls/RowControls/DragControls.tsx +3 -1
- 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
|
@@ -202,18 +202,48 @@ export const hideResizeHandleLine = () =>
|
|
|
202
202
|
},
|
|
203
203
|
}));
|
|
204
204
|
|
|
205
|
-
export const
|
|
206
|
-
rowIndex?: number,
|
|
207
|
-
colIndex?: number,
|
|
208
|
-
colWidth?: number,
|
|
209
|
-
colHeight?: number,
|
|
210
|
-
) =>
|
|
205
|
+
export const setTableHovered = (hovered: boolean) =>
|
|
211
206
|
createCommand(
|
|
212
207
|
() => {
|
|
208
|
+
return {
|
|
209
|
+
type: 'TABLE_HOVERED',
|
|
210
|
+
data: {
|
|
211
|
+
isTableHovered: hovered,
|
|
212
|
+
},
|
|
213
|
+
};
|
|
214
|
+
},
|
|
215
|
+
(tr) => tr.setMeta('addToHistory', false),
|
|
216
|
+
);
|
|
217
|
+
|
|
218
|
+
export const hoverCell = (rowIndex?: number, colIndex?: number) =>
|
|
219
|
+
createCommand(
|
|
220
|
+
(state) => {
|
|
221
|
+
const { hoveredCell: prevHoveredCell } = getPluginState(state);
|
|
222
|
+
|
|
223
|
+
// If no arguments have been passed then the intention it to reset the hover cell data
|
|
224
|
+
const clear = rowIndex === undefined && colIndex === undefined;
|
|
225
|
+
|
|
226
|
+
const nextRowIndex = clear
|
|
227
|
+
? undefined
|
|
228
|
+
: rowIndex ?? prevHoveredCell.rowIndex;
|
|
229
|
+
const nextColIndex = clear
|
|
230
|
+
? undefined
|
|
231
|
+
: colIndex ?? prevHoveredCell.colIndex;
|
|
232
|
+
|
|
233
|
+
if (
|
|
234
|
+
nextRowIndex === prevHoveredCell.rowIndex &&
|
|
235
|
+
nextColIndex === prevHoveredCell.colIndex
|
|
236
|
+
) {
|
|
237
|
+
return false;
|
|
238
|
+
}
|
|
239
|
+
|
|
213
240
|
return {
|
|
214
241
|
type: 'HOVER_CELL',
|
|
215
242
|
data: {
|
|
216
|
-
hoveredCell: {
|
|
243
|
+
hoveredCell: {
|
|
244
|
+
rowIndex: nextRowIndex,
|
|
245
|
+
colIndex: nextColIndex,
|
|
246
|
+
},
|
|
217
247
|
},
|
|
218
248
|
};
|
|
219
249
|
},
|
|
@@ -317,11 +317,17 @@ export const isInsideFirstCellOfRowOrColumn = (
|
|
|
317
317
|
const table = findTable(selection);
|
|
318
318
|
|
|
319
319
|
if (!table || !type) {
|
|
320
|
-
return;
|
|
320
|
+
return false;
|
|
321
321
|
}
|
|
322
|
+
|
|
322
323
|
const map = TableMap.get(table.node!);
|
|
323
|
-
const cell =
|
|
324
|
-
|
|
324
|
+
const cell = findCellClosestToPos(selection.$anchor);
|
|
325
|
+
if (!cell) {
|
|
326
|
+
return false;
|
|
327
|
+
}
|
|
328
|
+
const pos = cell.pos - table.pos - 1;
|
|
329
|
+
// cell positions in table map always start at 1, as they're offsets not positions
|
|
330
|
+
const index = map.map.findIndex((value) => value === pos);
|
|
325
331
|
|
|
326
332
|
return type === 'row' ? index % map.width === 0 : index < map.width;
|
|
327
333
|
};
|
|
@@ -37,6 +37,7 @@ import {
|
|
|
37
37
|
hoverColumns,
|
|
38
38
|
selectColumn,
|
|
39
39
|
setEditorFocus,
|
|
40
|
+
setTableHovered,
|
|
40
41
|
showInsertColumnButton,
|
|
41
42
|
showInsertRowButton,
|
|
42
43
|
showResizeHandleLine,
|
|
@@ -193,7 +194,7 @@ export const handleMouseOver = (
|
|
|
193
194
|
}
|
|
194
195
|
const { state, dispatch } = view;
|
|
195
196
|
const target = mouseEvent.target;
|
|
196
|
-
const { insertColumnButtonIndex, insertRowButtonIndex } =
|
|
197
|
+
const { insertColumnButtonIndex, insertRowButtonIndex, isTableHovered } =
|
|
197
198
|
getPluginState(state);
|
|
198
199
|
|
|
199
200
|
if (isInsertRowButton(target)) {
|
|
@@ -230,6 +231,10 @@ export const handleMouseOver = (
|
|
|
230
231
|
);
|
|
231
232
|
}
|
|
232
233
|
|
|
234
|
+
if (!isTableHovered) {
|
|
235
|
+
return setTableHovered(true)(state, dispatch);
|
|
236
|
+
}
|
|
237
|
+
|
|
233
238
|
return false;
|
|
234
239
|
};
|
|
235
240
|
|
|
@@ -284,6 +289,21 @@ export const handleMouseOut = (
|
|
|
284
289
|
return false;
|
|
285
290
|
};
|
|
286
291
|
|
|
292
|
+
export const handleMouseEnter = (
|
|
293
|
+
view: EditorView,
|
|
294
|
+
mouseEvent: Event,
|
|
295
|
+
): boolean => {
|
|
296
|
+
const { state, dispatch } = view;
|
|
297
|
+
|
|
298
|
+
const { isTableHovered } = getPluginState(state);
|
|
299
|
+
|
|
300
|
+
if (!isTableHovered) {
|
|
301
|
+
return setTableHovered(true)(state, dispatch);
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
return false;
|
|
305
|
+
};
|
|
306
|
+
|
|
287
307
|
export const handleMouseLeave = (view: EditorView, event: Event): boolean => {
|
|
288
308
|
if (!(event.target instanceof HTMLElement)) {
|
|
289
309
|
return false;
|
|
@@ -294,17 +314,27 @@ export const handleMouseLeave = (view: EditorView, event: Event): boolean => {
|
|
|
294
314
|
insertColumnButtonIndex,
|
|
295
315
|
insertRowButtonIndex,
|
|
296
316
|
isDragAndDropEnabled,
|
|
317
|
+
isTableHovered,
|
|
297
318
|
} = getPluginState(state);
|
|
298
319
|
|
|
299
|
-
|
|
300
|
-
|
|
320
|
+
if (isTableHovered) {
|
|
321
|
+
if (isDragAndDropEnabled) {
|
|
322
|
+
const { isDragMenuOpen } = getDragDropPluginState(state);
|
|
323
|
+
!isDragMenuOpen && setTableHovered(false)(state, dispatch);
|
|
324
|
+
} else {
|
|
325
|
+
setTableHovered(false)(state, dispatch);
|
|
326
|
+
}
|
|
301
327
|
return true;
|
|
302
328
|
}
|
|
303
329
|
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
330
|
+
// If this table doesn't have focus then we want to skip everything after this.
|
|
331
|
+
if (!isTableInFocus(view)) {
|
|
332
|
+
return false;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
const target = event.target;
|
|
336
|
+
if (isTableControlsButton(target)) {
|
|
337
|
+
return true;
|
|
308
338
|
}
|
|
309
339
|
|
|
310
340
|
if (
|
|
@@ -509,6 +539,13 @@ export const handleCut = (
|
|
|
509
539
|
return tr;
|
|
510
540
|
};
|
|
511
541
|
|
|
542
|
+
export const isTableInFocus = (view: EditorView) => {
|
|
543
|
+
return (
|
|
544
|
+
!!getPluginState(view.state)?.tableNode &&
|
|
545
|
+
!getResizePluginState(view.state)?.dragging
|
|
546
|
+
);
|
|
547
|
+
};
|
|
548
|
+
|
|
512
549
|
export const whenTableInFocus =
|
|
513
550
|
(
|
|
514
551
|
eventHandler: (
|
|
@@ -519,10 +556,7 @@ export const whenTableInFocus =
|
|
|
519
556
|
elementContentRects?: ElementContentRects,
|
|
520
557
|
) =>
|
|
521
558
|
(view: EditorView, mouseEvent: Event): boolean => {
|
|
522
|
-
if (
|
|
523
|
-
!getPluginState(view.state)?.tableNode ||
|
|
524
|
-
!!getResizePluginState(view.state)?.dragging
|
|
525
|
-
) {
|
|
559
|
+
if (!isTableInFocus(view)) {
|
|
526
560
|
return false;
|
|
527
561
|
}
|
|
528
562
|
|
|
@@ -534,8 +568,7 @@ const trackCellLocation = (view: EditorView, mouseEvent: Event) => {
|
|
|
534
568
|
const maybeTableCell = isElementInTableCell(
|
|
535
569
|
target as HTMLElement,
|
|
536
570
|
) as HTMLTableCellElement | null;
|
|
537
|
-
const tableRef = getPluginState(view.state)
|
|
538
|
-
const { hoveredCell, tableNode } = getPluginState(view.state);
|
|
571
|
+
const { tableNode, tableRef } = getPluginState(view.state);
|
|
539
572
|
|
|
540
573
|
const tableElement = closestElement(
|
|
541
574
|
target as HTMLElement,
|
|
@@ -561,9 +594,6 @@ const trackCellLocation = (view: EditorView, mouseEvent: Event) => {
|
|
|
561
594
|
) as HTMLTableRowElement;
|
|
562
595
|
const htmlRowIndex = rowElement && rowElement.rowIndex;
|
|
563
596
|
|
|
564
|
-
const colHeight = tableRef.offsetHeight;
|
|
565
|
-
const colWidth = maybeTableCell.offsetWidth;
|
|
566
|
-
|
|
567
597
|
const tableMap = tableNode && TableMap.get(tableNode);
|
|
568
598
|
let colIndex = htmlColIndex;
|
|
569
599
|
if (tableMap) {
|
|
@@ -580,19 +610,7 @@ const trackCellLocation = (view: EditorView, mouseEvent: Event) => {
|
|
|
580
610
|
);
|
|
581
611
|
}
|
|
582
612
|
|
|
583
|
-
|
|
584
|
-
hoveredCell.colIndex !== colIndex ||
|
|
585
|
-
hoveredCell.rowIndex !== htmlRowIndex ||
|
|
586
|
-
hoveredCell.colWidth !== colWidth ||
|
|
587
|
-
hoveredCell.colHeight !== colHeight
|
|
588
|
-
) {
|
|
589
|
-
hoverCell(
|
|
590
|
-
htmlRowIndex,
|
|
591
|
-
colIndex,
|
|
592
|
-
colWidth,
|
|
593
|
-
colHeight,
|
|
594
|
-
)(view.state, view.dispatch);
|
|
595
|
-
}
|
|
613
|
+
hoverCell(htmlRowIndex, colIndex)(view.state, view.dispatch);
|
|
596
614
|
};
|
|
597
615
|
|
|
598
616
|
export const withCellTracking =
|
|
@@ -474,7 +474,8 @@ class TableComponent extends React.Component<ComponentProps, TableState> {
|
|
|
474
474
|
const { showBeforeShadow, showAfterShadow } = this.state;
|
|
475
475
|
const node = getNode();
|
|
476
476
|
// doesn't work well with WithPluginState
|
|
477
|
-
const { isInDanger, hoveredRows, hoveredCell } =
|
|
477
|
+
const { isInDanger, hoveredRows, hoveredCell, isTableHovered } =
|
|
478
|
+
getPluginState(view.state);
|
|
478
479
|
|
|
479
480
|
const tableRef = this.table || undefined;
|
|
480
481
|
const headerRow = tableRef
|
|
@@ -490,6 +491,7 @@ class TableComponent extends React.Component<ComponentProps, TableState> {
|
|
|
490
491
|
tableActive={tableActive}
|
|
491
492
|
hoveredRows={hoveredRows}
|
|
492
493
|
hoveredCell={hoveredCell}
|
|
494
|
+
isTableHovered={isTableHovered}
|
|
493
495
|
isInDanger={isInDanger}
|
|
494
496
|
isResizing={isResizing}
|
|
495
497
|
isNumberColumnEnabled={node.attrs.isNumberColumnEnabled}
|
|
@@ -514,6 +516,7 @@ class TableComponent extends React.Component<ComponentProps, TableState> {
|
|
|
514
516
|
isInDanger={isInDanger}
|
|
515
517
|
hoveredRows={hoveredRows}
|
|
516
518
|
hoveredCell={hoveredCell}
|
|
519
|
+
isTableHovered={isTableHovered}
|
|
517
520
|
isResizing={isResizing}
|
|
518
521
|
ordering={ordering}
|
|
519
522
|
hasHeaderRow={hasHeaderRow}
|
|
@@ -101,6 +101,7 @@ export const moveSource = (
|
|
|
101
101
|
sourceType: DraggableType,
|
|
102
102
|
sourceIndex: number,
|
|
103
103
|
targetIndex: number,
|
|
104
|
+
tr?: Transaction,
|
|
104
105
|
) =>
|
|
105
106
|
createCommand(
|
|
106
107
|
(state) => {
|
|
@@ -111,12 +112,13 @@ export const moveSource = (
|
|
|
111
112
|
},
|
|
112
113
|
};
|
|
113
114
|
},
|
|
114
|
-
(
|
|
115
|
+
(originalTr: Transaction) => {
|
|
116
|
+
const nextTr = tr || originalTr;
|
|
115
117
|
if (sourceIndex === targetIndex) {
|
|
116
|
-
return
|
|
118
|
+
return nextTr.setMeta('addToHistory', false);
|
|
117
119
|
}
|
|
118
120
|
|
|
119
|
-
const anchor =
|
|
121
|
+
const anchor = nextTr.selection.anchor;
|
|
120
122
|
const selectStartOfTable = (newTr: Transaction) =>
|
|
121
123
|
newTr.setSelection(TextSelection.create(newTr.doc, anchor));
|
|
122
124
|
|
|
@@ -129,7 +131,7 @@ export const moveSource = (
|
|
|
129
131
|
selectStartOfTable,
|
|
130
132
|
selectRow(targetIndex),
|
|
131
133
|
],
|
|
132
|
-
|
|
134
|
+
nextTr,
|
|
133
135
|
);
|
|
134
136
|
}
|
|
135
137
|
|
|
@@ -139,7 +141,7 @@ export const moveSource = (
|
|
|
139
141
|
selectStartOfTable,
|
|
140
142
|
selectColumn(targetIndex),
|
|
141
143
|
],
|
|
142
|
-
|
|
144
|
+
nextTr,
|
|
143
145
|
);
|
|
144
146
|
},
|
|
145
147
|
);
|
|
@@ -10,11 +10,13 @@ import { getCellsInRow } from '@atlaskit/editor-tables/utils';
|
|
|
10
10
|
import { monitorForElements } from '@atlaskit/pragmatic-drag-and-drop/adapter/element';
|
|
11
11
|
|
|
12
12
|
import type { DraggableSourceData } from '../../types';
|
|
13
|
+
import { findNearestCellIndexToPoint } from '../../utils';
|
|
13
14
|
import {
|
|
14
15
|
hasMergedCellsInColumn,
|
|
15
16
|
hasMergedCellsInRow,
|
|
16
17
|
} from '../../utils/merged-cells';
|
|
17
18
|
import { getPluginState as getTablePluginState } from '../plugin-factory';
|
|
19
|
+
import { pluginKey as tablePluginKey } from '../plugin-key';
|
|
18
20
|
|
|
19
21
|
import { DragAndDropActionType } from './actions';
|
|
20
22
|
import {
|
|
@@ -135,19 +137,51 @@ export const createPlugin = (
|
|
|
135
137
|
onDrop(event) {
|
|
136
138
|
const data = getDraggableDataFromEvent(event);
|
|
137
139
|
|
|
140
|
+
// On Drop we need to update the table main plugin hoveredCell value with the current row/col that the mouse is
|
|
141
|
+
// over. This is so the drag handles update their positions to correctly align with the users mouse. Unfortunately
|
|
142
|
+
// at this point in time and during the drag opertation, the drop targets are eating all the mouse events so
|
|
143
|
+
// it's not possible to know what row/col the mouse is over (via mouse events). This attempts to locate the nearest cell and
|
|
144
|
+
// then tries to update the main table hoveredCell value by piggy-backing the transaction onto the command
|
|
145
|
+
// triggered by this on drop event.
|
|
146
|
+
const { hoveredCell } = getTablePluginState(editorView.state);
|
|
147
|
+
|
|
148
|
+
const cell = findNearestCellIndexToPoint(
|
|
149
|
+
event.location.current.input.clientX,
|
|
150
|
+
event.location.current.input.clientY,
|
|
151
|
+
);
|
|
152
|
+
const tr = editorView.state.tr;
|
|
153
|
+
const action = {
|
|
154
|
+
type: 'HOVER_CELL',
|
|
155
|
+
data: {
|
|
156
|
+
hoveredCell: {
|
|
157
|
+
rowIndex: cell?.row ?? hoveredCell.rowIndex,
|
|
158
|
+
colIndex: cell?.col ?? hoveredCell.colIndex,
|
|
159
|
+
},
|
|
160
|
+
},
|
|
161
|
+
};
|
|
162
|
+
tr.setMeta(tablePluginKey, action);
|
|
163
|
+
|
|
138
164
|
// If no data can be found then it's most like we do not want to perform any drop action
|
|
139
165
|
if (!data) {
|
|
140
|
-
clearDropTarget()(editorView.state, editorView.dispatch);
|
|
166
|
+
clearDropTarget(tr)(editorView.state, editorView.dispatch);
|
|
141
167
|
return;
|
|
142
168
|
}
|
|
143
169
|
|
|
144
170
|
const {
|
|
145
171
|
sourceType,
|
|
146
172
|
sourceIndexes,
|
|
173
|
+
targetIndex,
|
|
147
174
|
targetAdjustedIndex,
|
|
148
175
|
direction,
|
|
149
176
|
} = data;
|
|
150
177
|
|
|
178
|
+
// When we drop on a target we will know the targets row/col index for certain,
|
|
179
|
+
if (sourceType === 'table-row') {
|
|
180
|
+
action.data.hoveredCell.rowIndex = targetIndex;
|
|
181
|
+
} else {
|
|
182
|
+
action.data.hoveredCell.colIndex = targetIndex;
|
|
183
|
+
}
|
|
184
|
+
|
|
151
185
|
// If the drop target index contains merged cells then we should not allow the drop to occur.
|
|
152
186
|
const hasMergedCells =
|
|
153
187
|
sourceType === 'table-row'
|
|
@@ -156,7 +190,7 @@ export const createPlugin = (
|
|
|
156
190
|
if (
|
|
157
191
|
hasMergedCells(targetAdjustedIndex)(editorView.state.selection)
|
|
158
192
|
) {
|
|
159
|
-
clearDropTarget()(editorView.state, editorView.dispatch);
|
|
193
|
+
clearDropTarget(tr)(editorView.state, editorView.dispatch);
|
|
160
194
|
return;
|
|
161
195
|
}
|
|
162
196
|
|
|
@@ -167,6 +201,7 @@ export const createPlugin = (
|
|
|
167
201
|
sourceType,
|
|
168
202
|
sourceIndex,
|
|
169
203
|
targetAdjustedIndex + (direction === -1 ? 0 : -1),
|
|
204
|
+
tr,
|
|
170
205
|
)(editorView.state, editorView.dispatch);
|
|
171
206
|
});
|
|
172
207
|
},
|
|
@@ -57,6 +57,7 @@ import {
|
|
|
57
57
|
handleCut,
|
|
58
58
|
handleFocus,
|
|
59
59
|
handleMouseDown,
|
|
60
|
+
handleMouseEnter,
|
|
60
61
|
handleMouseLeave,
|
|
61
62
|
handleMouseMove,
|
|
62
63
|
handleMouseOut,
|
|
@@ -112,6 +113,7 @@ export const createPlugin = (
|
|
|
112
113
|
) => {
|
|
113
114
|
const state = createPluginState(dispatch, {
|
|
114
115
|
pluginConfig,
|
|
116
|
+
isTableHovered: false,
|
|
115
117
|
insertColumnButtonIndex: undefined,
|
|
116
118
|
insertRowButtonIndex: undefined,
|
|
117
119
|
isFullWidthModeEnabled: fullWidthModeEnabled,
|
|
@@ -382,11 +384,12 @@ export const createPlugin = (
|
|
|
382
384
|
focus: handleFocus,
|
|
383
385
|
blur: handleBlur,
|
|
384
386
|
mousedown: withCellTracking(handleMouseDown),
|
|
385
|
-
mouseover: whenTableInFocus(
|
|
386
|
-
mouseleave:
|
|
387
|
+
mouseover: withCellTracking(whenTableInFocus(handleMouseOver)),
|
|
388
|
+
mouseleave: handleMouseLeave,
|
|
387
389
|
mouseout: whenTableInFocus(handleMouseOut),
|
|
388
390
|
mousemove: whenTableInFocus(handleMouseMove, elementContentRects),
|
|
389
|
-
|
|
391
|
+
mouseenter: handleMouseEnter,
|
|
392
|
+
click: withCellTracking(whenTableInFocus(handleClick)),
|
|
390
393
|
},
|
|
391
394
|
|
|
392
395
|
handleTripleClick,
|
|
@@ -88,8 +88,6 @@ export type CellColumnPositioning = Pick<Rect, 'right' | 'left'>;
|
|
|
88
88
|
export interface CellHoverMeta {
|
|
89
89
|
colIndex?: number;
|
|
90
90
|
rowIndex?: number;
|
|
91
|
-
colWidth?: number;
|
|
92
|
-
colHeight?: number;
|
|
93
91
|
}
|
|
94
92
|
|
|
95
93
|
export interface TablePluginState {
|
|
@@ -130,6 +128,7 @@ export interface TablePluginState {
|
|
|
130
128
|
wasFullWidthModeEnabled?: boolean;
|
|
131
129
|
isTableResizingEnabled?: boolean;
|
|
132
130
|
isDragAndDropEnabled?: boolean;
|
|
131
|
+
isTableHovered?: boolean;
|
|
133
132
|
}
|
|
134
133
|
|
|
135
134
|
export type TablePluginAction =
|
|
@@ -210,6 +209,12 @@ export type TablePluginAction =
|
|
|
210
209
|
hoveredCell: CellHoverMeta;
|
|
211
210
|
};
|
|
212
211
|
}
|
|
212
|
+
| {
|
|
213
|
+
type: 'TABLE_HOVERED';
|
|
214
|
+
data: {
|
|
215
|
+
isTableHovered: boolean;
|
|
216
|
+
};
|
|
217
|
+
}
|
|
213
218
|
| { type: 'SET_TARGET_CELL_POSITION'; data: { targetCellPosition?: number } }
|
|
214
219
|
| {
|
|
215
220
|
type: 'SELECT_COLUMN';
|
|
@@ -30,6 +30,7 @@ export interface ColumnControlsProps {
|
|
|
30
30
|
rowHeights?: number[];
|
|
31
31
|
colWidths?: (number | undefined)[];
|
|
32
32
|
hasHeaderColumn?: boolean;
|
|
33
|
+
isTableHovered?: boolean;
|
|
33
34
|
}
|
|
34
35
|
|
|
35
36
|
const getSelectedColumns = (selection: Selection) => {
|
|
@@ -55,6 +56,7 @@ export const ColumnControls = ({
|
|
|
55
56
|
rowHeights,
|
|
56
57
|
colWidths,
|
|
57
58
|
hasHeaderColumn,
|
|
59
|
+
isTableHovered,
|
|
58
60
|
}: ColumnControlsProps) => {
|
|
59
61
|
const widths =
|
|
60
62
|
colWidths?.map((width) => (width ? `${width - 1}px` : '0px')).join(' ') ??
|
|
@@ -109,11 +111,15 @@ export const ColumnControls = ({
|
|
|
109
111
|
|
|
110
112
|
// update hovered cell location
|
|
111
113
|
const { state, dispatch } = editorView;
|
|
112
|
-
if (tableActive
|
|
113
|
-
|
|
114
|
+
if (tableActive) {
|
|
115
|
+
// For context: Whenever we mouse over a column or row drag handle, we will ALWAYS be hovering over the 0 index
|
|
116
|
+
// of the opposite dimension. For example; here when we mouse over the column drag handle then we're technically
|
|
117
|
+
// also hovering over row 0 index. And vice-versa with rows. This means we don't need to worry about knowing the
|
|
118
|
+
// current row index. We can just force it to 0.
|
|
119
|
+
hoverCell(0, Number(colIndex))(state, dispatch);
|
|
114
120
|
}
|
|
115
121
|
},
|
|
116
|
-
[editorView,
|
|
122
|
+
[editorView, tableActive],
|
|
117
123
|
);
|
|
118
124
|
|
|
119
125
|
const handleMouseOut = useCallback(() => {
|
|
@@ -132,6 +138,8 @@ export const ColumnControls = ({
|
|
|
132
138
|
return [colIndex!];
|
|
133
139
|
}, [colIndex]);
|
|
134
140
|
|
|
141
|
+
const previewHeight = rowHeights?.reduce((sum, cur) => sum + cur, 0) ?? 0;
|
|
142
|
+
|
|
135
143
|
return (
|
|
136
144
|
<div
|
|
137
145
|
className={ClassName.DRAG_COLUMN_CONTROLS}
|
|
@@ -175,6 +183,7 @@ export const ColumnControls = ({
|
|
|
175
183
|
))}
|
|
176
184
|
{tableActive &&
|
|
177
185
|
!isResizing &&
|
|
186
|
+
isTableHovered &&
|
|
178
187
|
!!hoveredCell &&
|
|
179
188
|
Number.isFinite(hoveredCell.colIndex) && (
|
|
180
189
|
<div
|
|
@@ -194,8 +203,8 @@ export const ColumnControls = ({
|
|
|
194
203
|
direction="column"
|
|
195
204
|
tableLocalId={localId || ''}
|
|
196
205
|
indexes={colIndexes}
|
|
197
|
-
previewWidth={
|
|
198
|
-
previewHeight={
|
|
206
|
+
previewWidth={colWidths?.[colIndex!] ?? 48}
|
|
207
|
+
previewHeight={previewHeight}
|
|
199
208
|
appearance={
|
|
200
209
|
selectedColIndexes.includes(hoveredCell.colIndex!)
|
|
201
210
|
? isInDanger
|
|
@@ -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}
|
|
@@ -41,6 +41,7 @@ type DragControlsProps = {
|
|
|
41
41
|
hoveredCell?: CellHoverMeta;
|
|
42
42
|
isInDanger?: boolean;
|
|
43
43
|
isResizing?: boolean;
|
|
44
|
+
isTableHovered?: boolean;
|
|
44
45
|
hoverRows: (rows: number[], danger?: boolean) => void;
|
|
45
46
|
selectRow: (row: number, expand: boolean) => void;
|
|
46
47
|
updateCellHoverLocation: (rowIndex: number) => void;
|
|
@@ -66,6 +67,7 @@ const DragControlsComponent = ({
|
|
|
66
67
|
editorView,
|
|
67
68
|
isInDanger,
|
|
68
69
|
isResizing,
|
|
70
|
+
isTableHovered,
|
|
69
71
|
hoverRows,
|
|
70
72
|
selectRow,
|
|
71
73
|
updateCellHoverLocation,
|
|
@@ -217,7 +219,7 @@ const DragControlsComponent = ({
|
|
|
217
219
|
)}
|
|
218
220
|
</Fragment>
|
|
219
221
|
))}
|
|
220
|
-
{!isResizing && Number.isFinite(rowIndex) && (
|
|
222
|
+
{!isResizing && isTableHovered && Number.isFinite(rowIndex) && (
|
|
221
223
|
<div
|
|
222
224
|
style={{
|
|
223
225
|
gridRow: gridRowPosition,
|
|
@@ -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
|
+
};
|