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
+