diff --git a/resources/js/wysiwyg/helpers.ts b/resources/js/wysiwyg/helpers.ts
index d7cd23a35..62e945721 100644
--- a/resources/js/wysiwyg/helpers.ts
+++ b/resources/js/wysiwyg/helpers.ts
@@ -1,13 +1,14 @@
 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);
@@ -77,4 +78,15 @@ export function toggleSelectionBlockNodeType(editor: LexicalEditor, matcher: Lex
             $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
diff --git a/resources/js/wysiwyg/ui/defaults/button-definitions.ts b/resources/js/wysiwyg/ui/defaults/button-definitions.ts
index 7fa1fb5f8..bf1846b8f 100644
--- a/resources/js/wysiwyg/ui/defaults/button-definitions.ts
+++ b/resources/js/wysiwyg/ui/defaults/button-definitions.ts
@@ -236,6 +236,10 @@ export const link: EditorButtonDefinition = {
     }
 };
 
+export const table: EditorBasicButtonDefinition = {
+    label: 'Table',
+};
+
 export const image: EditorButtonDefinition = {
     label: 'Insert/Edit Image',
     icon: imageIcon,
diff --git a/resources/js/wysiwyg/ui/framework/blocks/table-creator.ts b/resources/js/wysiwyg/ui/framework/blocks/table-creator.ts
new file mode 100644
index 000000000..c54645856
--- /dev/null
+++ b/resources/js/wysiwyg/ui/framework/blocks/table-creator.ts
@@ -0,0 +1,80 @@
+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
diff --git a/resources/js/wysiwyg/ui/toolbars.ts b/resources/js/wysiwyg/ui/toolbars.ts
index 559e9a87c..4dbf9bb7e 100644
--- a/resources/js/wysiwyg/ui/toolbars.ts
+++ b/resources/js/wysiwyg/ui/toolbars.ts
@@ -5,7 +5,7 @@ import {
     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";
@@ -15,8 +15,7 @@ import {EditorFormatMenu} from "./framework/blocks/format-menu";
 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', [
@@ -61,6 +60,9 @@ export function getMainEditorFullToolbar(): EditorContainerUiElement {
 
         // Insert types
         new EditorButton(link),
+        new EditorDropdownButton(table, [
+            new EditorTableCreator(),
+        ]),
         new EditorButton(image),
         new EditorButton(details),
 
diff --git a/resources/sass/_editor.scss b/resources/sass/_editor.scss
index ad1f5a339..69027ea69 100644
--- a/resources/sass/_editor.scss
+++ b/resources/sass/_editor.scss
@@ -100,6 +100,22 @@
   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 {