From f47f7dd9d255db85ff1254d51feb8d47476c784d Mon Sep 17 00:00:00 2001 From: Dan Brown Date: Fri, 21 Jun 2024 13:47:47 +0100 Subject: [PATCH] Lexical: Added base table support and started resize handling --- package-lock.json | 1 + package.json | 1 + resources/js/wysiwyg/index.ts | 2 + resources/js/wysiwyg/nodes/index.ts | 4 ++ .../ui/framework/helpers/table-resizer.ts | 68 +++++++++++++++++++ resources/sass/_editor.scss | 20 ++++++ .../pages/parts/wysiwyg-editor.blade.php | 19 ++++++ 7 files changed, 115 insertions(+) create mode 100644 resources/js/wysiwyg/ui/framework/helpers/table-resizer.ts diff --git a/package-lock.json b/package-lock.json index 0757e7868..646750df4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -24,6 +24,7 @@ "@lexical/list": "^0.15.0", "@lexical/rich-text": "^0.15.0", "@lexical/selection": "^0.15.0", + "@lexical/table": "^0.15.0", "@lexical/utils": "^0.15.0", "@lezer/highlight": "^1.2.0", "@ssddanbrown/codemirror-lang-smarty": "^1.0.0", diff --git a/package.json b/package.json index 732bb1759..d649b54e2 100644 --- a/package.json +++ b/package.json @@ -48,6 +48,7 @@ "@lexical/list": "^0.15.0", "@lexical/rich-text": "^0.15.0", "@lexical/selection": "^0.15.0", + "@lexical/table": "^0.15.0", "@lexical/utils": "^0.15.0", "@lezer/highlight": "^1.2.0", "@ssddanbrown/codemirror-lang-smarty": "^1.0.0", diff --git a/resources/js/wysiwyg/index.ts b/resources/js/wysiwyg/index.ts index 41207b706..b910b2eb6 100644 --- a/resources/js/wysiwyg/index.ts +++ b/resources/js/wysiwyg/index.ts @@ -5,6 +5,7 @@ import {mergeRegister} from '@lexical/utils'; import {getNodesForPageEditor} from './nodes'; import {buildEditorUI} from "./ui"; import {setEditorContentFromHtml} from "./actions"; +import {registerTableResizer} from "./ui/framework/helpers/table-resizer"; export function createPageEditorInstance(editArea: HTMLElement) { const config: CreateEditorArgs = { @@ -21,6 +22,7 @@ export function createPageEditorInstance(editArea: HTMLElement) { mergeRegister( registerRichText(editor), registerHistory(editor, createEmptyHistoryState(), 300), + registerTableResizer(editor, editArea), ); setEditorContentFromHtml(editor, startingHtml); diff --git a/resources/js/wysiwyg/nodes/index.ts b/resources/js/wysiwyg/nodes/index.ts index 03fcd33a5..ea6206ac2 100644 --- a/resources/js/wysiwyg/nodes/index.ts +++ b/resources/js/wysiwyg/nodes/index.ts @@ -6,6 +6,7 @@ import {LinkNode} from "@lexical/link"; import {ImageNode} from "./image"; import {DetailsNode, SummaryNode} from "./details"; import {ListItemNode, ListNode} from "@lexical/list"; +import {TableCellNode, TableNode, TableRowNode} from "@lexical/table"; /** * Load the nodes for lexical. @@ -17,6 +18,9 @@ export function getNodesForPageEditor(): (KlassConstructor | QuoteNode, // Todo - Create custom ListNode, // Todo - Create custom ListItemNode, + TableNode, // Todo - Create custom, + TableRowNode, + TableCellNode, ImageNode, DetailsNode, SummaryNode, CustomParagraphNode, diff --git a/resources/js/wysiwyg/ui/framework/helpers/table-resizer.ts b/resources/js/wysiwyg/ui/framework/helpers/table-resizer.ts new file mode 100644 index 000000000..53017e93b --- /dev/null +++ b/resources/js/wysiwyg/ui/framework/helpers/table-resizer.ts @@ -0,0 +1,68 @@ +import {LexicalEditor} from "lexical"; +import {el} from "../../../helpers"; + +type MarkerDomRecord = {x: HTMLElement, y: HTMLElement}; + +class TableResizer { + protected editor: LexicalEditor; + protected editArea: HTMLElement; + protected markerDom: MarkerDomRecord|null = null; + + constructor(editor: LexicalEditor, editArea: HTMLElement) { + this.editor = editor; + this.editArea = editArea; + this.setupListeners(); + } + + setupListeners() { + this.editArea.addEventListener('mousemove', event => { + const cell = (event.target as HTMLElement).closest('td,th'); + if (cell) { + this.onCellMouseMove(cell as HTMLElement, event); + } + }); + } + + onCellMouseMove(cell: HTMLElement, event: MouseEvent) { + 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.updateMarkersTo(cell, xMarkerPos, yMarkerPos); + } + + updateMarkersTo(cell: HTMLElement, xPos: number, yPos: number) { + const markers: MarkerDomRecord = this.getMarkers(); + const table = cell.closest('table') as HTMLElement; + const tableRect = table.getBoundingClientRect(); + + markers.x.style.left = xPos + 'px'; + markers.x.style.height = tableRect.height + 'px'; + markers.x.style.top = tableRect.top + 'px'; + + markers.y.style.top = yPos + 'px'; + markers.y.style.left = tableRect.left + 'px'; + markers.y.style.width = tableRect.width + 'px'; + } + + getMarkers(): MarkerDomRecord { + if (!this.markerDom) { + this.markerDom = { + x: el('div', {class: 'editor-table-marker-column'}), + y: el('div', {class: 'editor-table-marker-row'}), + } + this.editArea.after(this.markerDom.x, this.markerDom.y); + } + + return this.markerDom; + } +} + + +export function registerTableResizer(editor: LexicalEditor, editorArea: HTMLElement): (() => void) { + const resizer = new TableResizer(editor, editorArea); + + // TODO - Strip/close down resizer + return () => {}; +} \ No newline at end of file diff --git a/resources/sass/_editor.scss b/resources/sass/_editor.scss index f8c895afd..ad1f5a339 100644 --- a/resources/sass/_editor.scss +++ b/resources/sass/_editor.scss @@ -146,3 +146,23 @@ cursor: sw-resize; } } + +.editor-table-marker-row, +.editor-table-marker-column { + position: fixed; + background-color: var(--editor-color-primary); + z-index: 99; + user-select: none; + opacity: 0; + &:hover { + opacity: 0.4; + } +} +.editor-table-marker-column { + width: 4px; + cursor: col-resize; +} +.editor-table-marker-row { + height: 4px; + cursor: row-resize; +} \ No newline at end of file diff --git a/resources/views/pages/parts/wysiwyg-editor.blade.php b/resources/views/pages/parts/wysiwyg-editor.blade.php index 641402769..5cd60bbc6 100644 --- a/resources/views/pages/parts/wysiwyg-editor.blade.php +++ b/resources/views/pages/parts/wysiwyg-editor.blade.php @@ -26,6 +26,25 @@

Hello there, this is an info callout

+ +

Table

+ + + + + + + + + + + + + + + + +
Cell ACell BCell C
Cell DCell ECell F