mirror of
https://github.com/BookStackApp/BookStack.git
synced 2024-10-01 01:36:00 -04:00
Lexical: Added base table support and started resize handling
This commit is contained in:
parent
13d970c7ce
commit
f47f7dd9d2
1
package-lock.json
generated
1
package-lock.json
generated
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -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);
|
||||
|
@ -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<typeof LexicalNode> |
|
||||
QuoteNode, // Todo - Create custom
|
||||
ListNode, // Todo - Create custom
|
||||
ListItemNode,
|
||||
TableNode, // Todo - Create custom,
|
||||
TableRowNode,
|
||||
TableCellNode,
|
||||
ImageNode,
|
||||
DetailsNode, SummaryNode,
|
||||
CustomParagraphNode,
|
||||
|
68
resources/js/wysiwyg/ui/framework/helpers/table-resizer.ts
Normal file
68
resources/js/wysiwyg/ui/framework/helpers/table-resizer.ts
Normal file
@ -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 () => {};
|
||||
}
|
@ -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;
|
||||
}
|
@ -26,6 +26,25 @@
|
||||
<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>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user