From 23887c7050f2e2c916062781ee90b66c2f2a12da Mon Sep 17 00:00:00 2001 From: Frederic Cabassut Date: Mon, 9 Mar 2026 23:15:17 +0100 Subject: [PATCH] feat: add table support to TipTap editor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Install @tiptap/extension-table packages, register Table/TableRow/ TableHeader/TableCell extensions, add Table button to the More dropdown (inserts a 3×3 grid), and style tables to match the parchment theme. Co-Authored-By: Claude Opus 4.6 --- docs/FEATURES.md | 1 + package.json | 4 ++ pnpm-lock.yaml | 50 +++++++++++++++++++++ src/app.css | 30 +++++++++++++ src/lib/components/FormattingToolbar.svelte | 11 ++++- src/lib/components/TiptapEditor.svelte | 8 ++++ 6 files changed, 103 insertions(+), 1 deletion(-) diff --git a/docs/FEATURES.md b/docs/FEATURES.md index 04322a4..ff1a8da 100644 --- a/docs/FEATURES.md +++ b/docs/FEATURES.md @@ -26,6 +26,7 @@ - Code blocks (triple backtick) - Inline code (single backtick) - Links — insert, edit, and remove with URL input +- Tables (insert 3×3 via toolbar) - Dividers (horizontal rules) - Text alignment (left, center, right, justify) - Line breaks diff --git a/package.json b/package.json index b1fc054..8ed89ae 100644 --- a/package.json +++ b/package.json @@ -34,6 +34,10 @@ "@tiptap/core": "^3.20.1", "@tiptap/extension-link": "^3.20.1", "@tiptap/extension-placeholder": "^3.20.1", + "@tiptap/extension-table": "^3.20.1", + "@tiptap/extension-table-cell": "^3.20.1", + "@tiptap/extension-table-header": "^3.20.1", + "@tiptap/extension-table-row": "^3.20.1", "@tiptap/extension-task-item": "^3.20.1", "@tiptap/extension-task-list": "^3.20.1", "@tiptap/extension-text-align": "^3.20.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ab4a5c7..cc0ec01 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -28,6 +28,18 @@ importers: '@tiptap/extension-placeholder': specifier: ^3.20.1 version: 3.20.1(@tiptap/extensions@3.20.1(@tiptap/core@3.20.1(@tiptap/pm@3.20.1))(@tiptap/pm@3.20.1)) + '@tiptap/extension-table': + specifier: ^3.20.1 + version: 3.20.1(@tiptap/core@3.20.1(@tiptap/pm@3.20.1))(@tiptap/pm@3.20.1) + '@tiptap/extension-table-cell': + specifier: ^3.20.1 + version: 3.20.1(@tiptap/extension-table@3.20.1(@tiptap/core@3.20.1(@tiptap/pm@3.20.1))(@tiptap/pm@3.20.1)) + '@tiptap/extension-table-header': + specifier: ^3.20.1 + version: 3.20.1(@tiptap/extension-table@3.20.1(@tiptap/core@3.20.1(@tiptap/pm@3.20.1))(@tiptap/pm@3.20.1)) + '@tiptap/extension-table-row': + specifier: ^3.20.1 + version: 3.20.1(@tiptap/extension-table@3.20.1(@tiptap/core@3.20.1(@tiptap/pm@3.20.1))(@tiptap/pm@3.20.1)) '@tiptap/extension-task-item': specifier: ^3.20.1 version: 3.20.1(@tiptap/extension-list@3.20.1(@tiptap/core@3.20.1(@tiptap/pm@3.20.1))(@tiptap/pm@3.20.1)) @@ -1508,6 +1520,27 @@ packages: peerDependencies: '@tiptap/core': ^3.20.1 + '@tiptap/extension-table-cell@3.20.1': + resolution: {integrity: sha512-nSeboFey+MJqZuCQSbVUajQVaGiypeoUPiGd0CJdyfc0oPsBGGqp7XFJtw5HHEbDqEvSHvGNDoZDFsUTAxUyIg==} + peerDependencies: + '@tiptap/extension-table': ^3.20.1 + + '@tiptap/extension-table-header@3.20.1': + resolution: {integrity: sha512-Xsdgik3Bh5xWSkLaPR/6NDLZR5lgUDIN/yiZ7bLtfTsyGxqEvuW2Y9/j/XP3AfsZzGy2/SuA9bM9zxPcFQxwFA==} + peerDependencies: + '@tiptap/extension-table': ^3.20.1 + + '@tiptap/extension-table-row@3.20.1': + resolution: {integrity: sha512-uYE0SdY4J81wn/fg8Gum0TVSTTBekQhRGeSwDnRfBBd9JILBsLotBTt4ucM7JOUjrP9BjS+QFCT9EstAchPHfQ==} + peerDependencies: + '@tiptap/extension-table': ^3.20.1 + + '@tiptap/extension-table@3.20.1': + resolution: {integrity: sha512-y2o1De3P/FH80nst1D9pYSwtRvxF87WkNAYGurqCkZ6SjwFq1Ifeh9eY+o79R6SCwcfpvQRytCYd+Yw9o5XAtA==} + peerDependencies: + '@tiptap/core': ^3.20.1 + '@tiptap/pm': ^3.20.1 + '@tiptap/extension-task-item@3.20.1': resolution: {integrity: sha512-ZdQld5Jzw/b/zl9TSA3KNkucmQhW5lHS/0YEKb+eFvxMwdHTKSpsTQzrfzbJixcdSqsuKJB+uUCwDDB+l0CRlA==} peerDependencies: @@ -4811,6 +4844,23 @@ snapshots: dependencies: '@tiptap/core': 3.20.1(@tiptap/pm@3.20.1) + '@tiptap/extension-table-cell@3.20.1(@tiptap/extension-table@3.20.1(@tiptap/core@3.20.1(@tiptap/pm@3.20.1))(@tiptap/pm@3.20.1))': + dependencies: + '@tiptap/extension-table': 3.20.1(@tiptap/core@3.20.1(@tiptap/pm@3.20.1))(@tiptap/pm@3.20.1) + + '@tiptap/extension-table-header@3.20.1(@tiptap/extension-table@3.20.1(@tiptap/core@3.20.1(@tiptap/pm@3.20.1))(@tiptap/pm@3.20.1))': + dependencies: + '@tiptap/extension-table': 3.20.1(@tiptap/core@3.20.1(@tiptap/pm@3.20.1))(@tiptap/pm@3.20.1) + + '@tiptap/extension-table-row@3.20.1(@tiptap/extension-table@3.20.1(@tiptap/core@3.20.1(@tiptap/pm@3.20.1))(@tiptap/pm@3.20.1))': + dependencies: + '@tiptap/extension-table': 3.20.1(@tiptap/core@3.20.1(@tiptap/pm@3.20.1))(@tiptap/pm@3.20.1) + + '@tiptap/extension-table@3.20.1(@tiptap/core@3.20.1(@tiptap/pm@3.20.1))(@tiptap/pm@3.20.1)': + dependencies: + '@tiptap/core': 3.20.1(@tiptap/pm@3.20.1) + '@tiptap/pm': 3.20.1 + '@tiptap/extension-task-item@3.20.1(@tiptap/extension-list@3.20.1(@tiptap/core@3.20.1(@tiptap/pm@3.20.1))(@tiptap/pm@3.20.1))': dependencies: '@tiptap/extension-list': 3.20.1(@tiptap/core@3.20.1(@tiptap/pm@3.20.1))(@tiptap/pm@3.20.1) diff --git a/src/app.css b/src/app.css index 9e0a08e..79453ec 100644 --- a/src/app.css +++ b/src/app.css @@ -72,3 +72,33 @@ body::before { .prose :where(a):not(:where([class~="not-prose"] *)):hover { color: var(--primary-hover); } + +/* Table styles for TipTap editor */ +.tiptap table { + border-collapse: collapse; + width: 100%; + margin: 0.5rem 0; +} + +.tiptap th, +.tiptap td { + border: 1px solid var(--border-subtle); + padding: 0.375rem 0.625rem; + text-align: left; + vertical-align: top; + min-width: 4rem; +} + +.tiptap th { + font-weight: 600; + background-color: color-mix(in srgb, var(--bg-base) 60%, transparent); +} + +.tiptap td p, +.tiptap th p { + margin: 0; +} + +.tiptap .selectedCell { + background-color: color-mix(in srgb, var(--primary) 12%, transparent); +} diff --git a/src/lib/components/FormattingToolbar.svelte b/src/lib/components/FormattingToolbar.svelte index 350d6d4..4eb98e8 100644 --- a/src/lib/components/FormattingToolbar.svelte +++ b/src/lib/components/FormattingToolbar.svelte @@ -23,7 +23,8 @@ AlignJustify, Minus, ChevronDown, - Ellipsis + Ellipsis, + Table2 } from 'lucide-svelte'; interface Props { @@ -338,6 +339,14 @@ Code block +