import {
- $createParagraphNode,
+ $createParagraphNode, $getRoot,
$getSelection,
$isTextNode,
- BaseSelection,
+ BaseSelection, ElementNode,
LexicalEditor, LexicalNode, TextFormatType
} from "lexical";
import {LexicalElementNodeCreator, LexicalNodeMatcher} from "./nodes";
import {$getNearestBlockElementAncestorOrThrow} from "@lexical/utils";
import {$setBlocksType} from "@lexical/selection";
+import {$createDetailsNode} from "./nodes/details";
export function el(tag: string, attrs: Record<string, string|null> = {}, children: (string|HTMLElement)[] = []): HTMLElement {
const el = document.createElement(tag);
$setBlocksType(selection, creator);
}
});
+}
+
+export function insertNewBlockNodeAtSelection(node: LexicalNode) {
+ const selection = $getSelection();
+ const blockElement = selection ? $getNearestBlockElementAncestorOrThrow(selection.getNodes()[0]) : null;
+
+ if (blockElement) {
+ blockElement.insertAfter(node);
+ } else {
+ $getRoot().append(node);
+ }
}
\ No newline at end of file
}
};
+export const table: EditorBasicButtonDefinition = {
+ label: 'Table',
+};
+
export const image: EditorButtonDefinition = {
label: 'Insert/Edit Image',
icon: imageIcon,
--- /dev/null
+import {el, insertNewBlockNodeAtSelection} from "../../../helpers";
+import {EditorUiElement} from "../core";
+import {$createTableNodeWithDimensions} from "@lexical/table";
+
+
+export class EditorTableCreator extends EditorUiElement {
+
+ buildDOM(): HTMLElement {
+ const size = 10;
+ const rows: HTMLElement[] = [];
+ const cells: HTMLElement[] = [];
+
+ for (let row = 1; row < size + 1; row++) {
+ const rowCells = [];
+ for (let column = 1; column < size + 1; column++) {
+ const cell = el('div', {
+ class: 'editor-table-creator-cell',
+ 'data-rows': String(row),
+ 'data-columns': String(column),
+ });
+ rowCells.push(cell);
+ cells.push(cell);
+ }
+ rows.push(el('div', {
+ class: 'editor-table-creator-row'
+ }, rowCells));
+ }
+
+ const display = el('div', {class: 'editor-table-creator-display'}, ['0 x 0']);
+ const grid = el('div', {class: 'editor-table-creator-grid'}, rows);
+ grid.addEventListener('mousemove', event => {
+ const cell = (event.target as HTMLElement).closest('.editor-table-creator-cell') as HTMLElement|null;
+ if (cell) {
+ const row = Number(cell.dataset.rows || 0);
+ const column = Number(cell.dataset.columns || 0);
+ this.updateGridSelection(row, column, cells, display)
+ }
+ });
+
+ grid.addEventListener('click', event => {
+ const cell = (event.target as HTMLElement).closest('.editor-table-creator-cell');
+ if (cell) {
+ this.onCellClick(cell as HTMLElement);
+ }
+ });
+
+ grid.addEventListener('mouseleave', event => {
+ this.updateGridSelection(0, 0, cells, display);
+ });
+
+ return el('div', {
+ class: 'editor-table-creator',
+ }, [
+ grid,
+ display,
+ ]);
+ }
+
+ updateGridSelection(rows: number, columns: number, cells: HTMLElement[], display: HTMLElement) {
+ for (const cell of cells) {
+ const active = Number(cell.dataset.rows) <= rows && Number(cell.dataset.columns) <= columns;
+ cell.classList.toggle('active', active);
+ }
+
+ display.textContent = `${rows} x ${columns}`;
+ }
+
+ onCellClick(cell: HTMLElement) {
+ const rows = Number(cell.dataset.rows || 0);
+ const columns = Number(cell.dataset.columns || 0);
+ if (rows < 1 || columns < 1) {
+ return;
+ }
+
+ this.getContext().editor.update(() => {
+ const table = $createTableNodeWithDimensions(rows, columns, false);
+ insertNewBlockNodeAtSelection(table);
+ });
+ }
+}
\ No newline at end of file
h2, h3, h4, h5, highlightColor, image,
infoCallout, italic, link, numberList, paragraph,
redo, source, strikethrough, subscript,
- successCallout, superscript, taskList, textColor, underline,
+ successCallout, superscript, table, taskList, textColor, underline,
undo,
warningCallout
} from "./defaults/button-definitions";
import {FormatPreviewButton} from "./framework/blocks/format-preview-button";
import {EditorDropdownButton} from "./framework/blocks/dropdown-button";
import {EditorColorPicker} from "./framework/blocks/color-picker";
-
-console.log(undo);
+import {EditorTableCreator} from "./framework/blocks/table-creator";
export function getMainEditorFullToolbar(): EditorContainerUiElement {
return new EditorSimpleClassContainer('editor-toolbar-main', [
// Insert types
new EditorButton(link),
+ new EditorDropdownButton(table, [
+ new EditorTableCreator(),
+ ]),
new EditorButton(image),
new EditorButton(details),
z-index: 3;
box-shadow: 0 0 4px 1px rgba(0, 0, 0, 0.25);
}
+.editor-table-creator-row {
+ display: flex;
+}
+.editor-table-creator-cell {
+ border: 1px solid #DDD;
+ width: 15px;
+ height: 15px;
+ cursor: pointer;
+ &.active {
+ background-color: var(--editor-color-primary);
+ }
+}
+.editor-table-creator-display {
+ text-align: center;
+ padding: 0.2em;
+}
// In-editor elements
.editor-image-wrap {