1
0
mirror of https://github.com/BookStackApp/BookStack.git synced 2026-01-03 23:42:28 +03:00

Lexical: Linked up table resize handler (unfinished)

This commit is contained in:
Dan Brown
2024-06-26 13:52:00 +01:00
parent 59936631ec
commit b1130cb1c3
3 changed files with 110 additions and 22 deletions

View File

@@ -1,6 +1,7 @@
import {LexicalEditor} from "lexical";
import {$getNearestNodeFromDOMNode, LexicalEditor} from "lexical";
import {el} from "../../../helpers";
import {MouseDragTracker, MouseDragTrackerDistance} from "./mouse-drag-tracker";
import {$getTableColumnWidth, $setTableColumnWidth, CustomTableNode} from "../../../nodes/custom-table";
type MarkerDomRecord = {x: HTMLElement, y: HTMLElement};
@@ -9,6 +10,10 @@ class TableResizer {
protected editArea: HTMLElement;
protected markerDom: MarkerDomRecord|null = null;
protected mouseTracker: MouseDragTracker|null = null;
protected dragging: boolean = false;
protected targetCell: HTMLElement|null = null;
protected xMarkerAtStart : boolean = false;
protected yMarkerAtStart : boolean = false;
constructor(editor: LexicalEditor, editArea: HTMLElement) {
this.editor = editor;
@@ -19,7 +24,7 @@ class TableResizer {
setupListeners() {
this.editArea.addEventListener('mousemove', event => {
const cell = (event.target as HTMLElement).closest('td,th');
if (cell) {
if (cell && !this.dragging) {
this.onCellMouseMove(cell as HTMLElement, event);
}
});
@@ -29,8 +34,13 @@ class TableResizer {
const rect = cell.getBoundingClientRect();
const midX = rect.left + (rect.width / 2);
const midY = rect.top + (rect.height / 2);
const xMarkerPos = event.clientX <= midX ? rect.left : rect.right;
const yMarkerPos = event.clientY <= midY ? rect.top : rect.bottom;
this.targetCell = cell;
this.xMarkerAtStart = event.clientX <= midX;
this.yMarkerAtStart = event.clientY <= midY;
const xMarkerPos = this.xMarkerAtStart ? rect.left : rect.right;
const yMarkerPos = this.yMarkerAtStart ? rect.top : rect.bottom;
this.updateMarkersTo(cell, xMarkerPos, yMarkerPos);
}
@@ -65,13 +75,68 @@ class TableResizer {
}
watchMarkerMouseDrags(wrapper: HTMLElement) {
const _this = this;
let markerStart: number = 0;
let markerProp: 'left' | 'top' = 'left';
this.mouseTracker = new MouseDragTracker(wrapper, '.editor-table-marker', {
down(event: MouseEvent, marker: HTMLElement) {
marker.classList.add('active');
_this.dragging = true;
markerProp = marker.classList.contains('editor-table-marker-column') ? 'left' : 'top';
markerStart = Number(marker.style[markerProp].replace('px', ''));
},
move(event: MouseEvent, marker: HTMLElement, distance: MouseDragTrackerDistance) {
marker.style[markerProp] = (markerStart + distance[markerProp === 'left' ? 'x' : 'y']) + 'px';
},
up(event: MouseEvent, marker: HTMLElement, distance: MouseDragTrackerDistance) {
console.log('up', distance, marker);
// TODO - Update row/column for distance
marker.classList.remove('active');
marker.style.left = '0';
marker.style.top = '0';
_this.dragging = false;
console.log('up', distance, marker, markerProp, _this.targetCell);
const parentTable = _this.targetCell?.closest('table');
if (markerProp === 'left' && _this.targetCell && parentTable) {
const cellIndex = _this.getTargetCellColumnIndex();
_this.editor.update(() => {
const table = $getNearestNodeFromDOMNode(parentTable);
if (table instanceof CustomTableNode) {
const originalWidth = $getTableColumnWidth(_this.editor, table, cellIndex);
const newWidth = Math.max(originalWidth + distance.x, 10);
$setTableColumnWidth(table, cellIndex, newWidth);
}
});
}
}
});
}
getTargetCellColumnIndex(): number {
const cell = this.targetCell;
if (cell === null) {
return -1;
}
let index = 0;
const row = cell.parentElement;
for (const rowCell of row?.children || []) {
let size = Number(rowCell.getAttribute('colspan'));
if (Number.isNaN(size) || size < 1) {
size = 1;
}
index += size;
if (rowCell === cell) {
return index - 1;
}
}
return -1;
}
}