]> BookStack Code Mirror - bookstack/blob - resources/js/wysiwyg/ui/framework/helpers/table-resizer.ts
ccf269daa0fe0d6c0765d0fb4f99fc85bf4e2d95
[bookstack] / resources / js / wysiwyg / ui / framework / helpers / table-resizer.ts
1 import {LexicalEditor} from "lexical";
2 import {el} from "../../../helpers";
3 import {MouseDragTracker, MouseDragTrackerDistance} from "./mouse-drag-tracker";
4
5 type MarkerDomRecord = {x: HTMLElement, y: HTMLElement};
6
7 class TableResizer {
8     protected editor: LexicalEditor;
9     protected editArea: HTMLElement;
10     protected markerDom: MarkerDomRecord|null = null;
11     protected mouseTracker: MouseDragTracker|null = null;
12
13     constructor(editor: LexicalEditor, editArea: HTMLElement) {
14         this.editor = editor;
15         this.editArea = editArea;
16         this.setupListeners();
17     }
18
19     setupListeners() {
20         this.editArea.addEventListener('mousemove', event => {
21             const cell = (event.target as HTMLElement).closest('td,th');
22             if (cell) {
23                 this.onCellMouseMove(cell as HTMLElement, event);
24             }
25         });
26     }
27
28     onCellMouseMove(cell: HTMLElement, event: MouseEvent) {
29         const rect = cell.getBoundingClientRect();
30         const midX = rect.left + (rect.width / 2);
31         const midY = rect.top + (rect.height / 2);
32         const xMarkerPos = event.clientX <= midX ? rect.left : rect.right;
33         const yMarkerPos = event.clientY <= midY ? rect.top : rect.bottom;
34         this.updateMarkersTo(cell, xMarkerPos, yMarkerPos);
35     }
36
37     updateMarkersTo(cell: HTMLElement, xPos: number, yPos: number) {
38         const markers: MarkerDomRecord = this.getMarkers();
39         const table = cell.closest('table') as HTMLElement;
40         const tableRect = table.getBoundingClientRect();
41
42         markers.x.style.left = xPos + 'px';
43         markers.x.style.height = tableRect.height + 'px';
44         markers.x.style.top = tableRect.top + 'px';
45
46         markers.y.style.top = yPos + 'px';
47         markers.y.style.left = tableRect.left + 'px';
48         markers.y.style.width = tableRect.width + 'px';
49     }
50
51     getMarkers(): MarkerDomRecord {
52         if (!this.markerDom) {
53             this.markerDom = {
54                 x: el('div', {class: 'editor-table-marker editor-table-marker-column'}),
55                 y: el('div', {class: 'editor-table-marker editor-table-marker-row'}),
56             }
57             const wrapper = el('div', {
58                 class: 'editor-table-marker-wrap',
59             }, [this.markerDom.x, this.markerDom.y]);
60             this.editArea.after(wrapper);
61             this.watchMarkerMouseDrags(wrapper);
62         }
63
64         return this.markerDom;
65     }
66
67     watchMarkerMouseDrags(wrapper: HTMLElement) {
68         this.mouseTracker = new MouseDragTracker(wrapper, '.editor-table-marker', {
69             up(event: MouseEvent, marker: HTMLElement, distance: MouseDragTrackerDistance) {
70                 console.log('up', distance, marker);
71                 // TODO - Update row/column for distance
72             }
73         });
74     }
75 }
76
77
78 export function registerTableResizer(editor: LexicalEditor, editorArea: HTMLElement): (() => void) {
79     const resizer = new TableResizer(editor, editorArea);
80
81     // TODO - Strip/close down resizer
82     return () => {};
83 }