"@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",
"@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",
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 = {
mergeRegister(
registerRichText(editor),
registerHistory(editor, createEmptyHistoryState(), 300),
+ registerTableResizer(editor, editArea),
);
setEditorContentFromHtml(editor, startingHtml);
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.
QuoteNode, // Todo - Create custom
ListNode, // Todo - Create custom
ListItemNode,
+ TableNode, // Todo - Create custom,
+ TableRowNode,
+ TableCellNode,
ImageNode,
DetailsNode, SummaryNode,
CustomParagraphNode,
--- /dev/null
+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
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
<p class="callout info">
Hello there, this is an info callout
</p>
+
+ <h3>Table</h3>
+
+ <table>
+ <thead>
+ <tr>
+ <th>Cell A</th>
+ <th>Cell B</th>
+ <th>Cell C</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>Cell D</td>
+ <td>Cell E</td>
+ <td>Cell F</td>
+ </tr>
+ </tbody>
+ </table>
</div>
</div>