Browse Source

Merge pull request #14284 from diwakar-s-maurya/patch-7

feat: add support for table formatting in knowledge collection
Tim Jaeryang Baek 1 month ago
parent
commit
17263a294f
4 changed files with 119 additions and 12 deletions
  1. 74 9
      package-lock.json
  2. 6 0
      package.json
  3. 25 0
      src/app.css
  4. 14 3
      src/lib/components/common/RichTextInput.svelte

+ 74 - 9
package-lock.json

@@ -22,6 +22,10 @@
 				"@tiptap/extension-code-block-lowlight": "^2.11.9",
 				"@tiptap/extension-highlight": "^2.10.0",
 				"@tiptap/extension-placeholder": "^2.10.0",
+				"@tiptap/extension-table": "^2.12.0",
+				"@tiptap/extension-table-cell": "^2.12.0",
+				"@tiptap/extension-table-header": "^2.12.0",
+				"@tiptap/extension-table-row": "^2.12.0",
 				"@tiptap/extension-typography": "^2.10.0",
 				"@tiptap/pm": "^2.11.7",
 				"@tiptap/starter-kit": "^2.10.0",
@@ -62,6 +66,7 @@
 				"prosemirror-schema-basic": "^1.2.3",
 				"prosemirror-schema-list": "^1.5.1",
 				"prosemirror-state": "^1.4.3",
+				"prosemirror-tables": "^1.7.1",
 				"prosemirror-view": "^1.34.3",
 				"pyodide": "^0.27.3",
 				"socket.io-client": "^4.2.0",
@@ -69,6 +74,7 @@
 				"svelte-sonner": "^0.3.19",
 				"tippy.js": "^6.3.7",
 				"turndown": "^7.2.0",
+				"turndown-plugin-gfm": "^1.0.2",
 				"undici": "^7.3.0",
 				"uuid": "^9.0.1",
 				"vite-plugin-static-copy": "^2.2.0",
@@ -3173,6 +3179,59 @@
 				"@tiptap/core": "^2.7.0"
 			}
 		},
+		"node_modules/@tiptap/extension-table": {
+			"version": "2.12.0",
+			"resolved": "https://registry.npmjs.org/@tiptap/extension-table/-/extension-table-2.12.0.tgz",
+			"integrity": "sha512-tT3IbbBal0vPQ1Bc/3Xl+tmqqZQCYWxnycBPl/WZBqhd57DWzfJqRPESwCGUIJgjOtTnipy/ulvj0FxHi1j9JA==",
+			"license": "MIT",
+			"funding": {
+				"type": "github",
+				"url": "https://github.com/sponsors/ueberdosis"
+			},
+			"peerDependencies": {
+				"@tiptap/core": "^2.7.0",
+				"@tiptap/pm": "^2.7.0"
+			}
+		},
+		"node_modules/@tiptap/extension-table-cell": {
+			"version": "2.12.0",
+			"resolved": "https://registry.npmjs.org/@tiptap/extension-table-cell/-/extension-table-cell-2.12.0.tgz",
+			"integrity": "sha512-8i35uCkmkSiQxMiZ+DLgT/wj24P5U/Zo3jr1e0tMAAMG7sRO1MljjLmkpV8WCdBo0xoRqzkz4J7Nkq+DtzZv9Q==",
+			"license": "MIT",
+			"funding": {
+				"type": "github",
+				"url": "https://github.com/sponsors/ueberdosis"
+			},
+			"peerDependencies": {
+				"@tiptap/core": "^2.7.0"
+			}
+		},
+		"node_modules/@tiptap/extension-table-header": {
+			"version": "2.12.0",
+			"resolved": "https://registry.npmjs.org/@tiptap/extension-table-header/-/extension-table-header-2.12.0.tgz",
+			"integrity": "sha512-gRKEsy13KKLpg9RxyPeUGqh4BRFSJ2Bc2KQP1ldhef6CPRYHCbGycxXCVQ5aAb7Mhpo54L+AAkmAv1iMHUTflw==",
+			"license": "MIT",
+			"funding": {
+				"type": "github",
+				"url": "https://github.com/sponsors/ueberdosis"
+			},
+			"peerDependencies": {
+				"@tiptap/core": "^2.7.0"
+			}
+		},
+		"node_modules/@tiptap/extension-table-row": {
+			"version": "2.12.0",
+			"resolved": "https://registry.npmjs.org/@tiptap/extension-table-row/-/extension-table-row-2.12.0.tgz",
+			"integrity": "sha512-AEW/Zl9V0IoaYDBLMhF5lVl0xgoIJs3IuKCsIYxGDlxBfTVFC6PfQzvuy296CMjO5ZcZ0xalVipPV9ggsMRD+w==",
+			"license": "MIT",
+			"funding": {
+				"type": "github",
+				"url": "https://github.com/sponsors/ueberdosis"
+			},
+			"peerDependencies": {
+				"@tiptap/core": "^2.7.0"
+			}
+		},
 		"node_modules/@tiptap/extension-text": {
 			"version": "2.10.0",
 			"resolved": "https://registry.npmjs.org/@tiptap/extension-text/-/extension-text-2.10.0.tgz",
@@ -9809,16 +9868,16 @@
 			}
 		},
 		"node_modules/prosemirror-tables": {
-			"version": "1.6.4",
-			"resolved": "https://registry.npmjs.org/prosemirror-tables/-/prosemirror-tables-1.6.4.tgz",
-			"integrity": "sha512-TkDY3Gw52gRFRfRn2f4wJv5WOgAOXLJA2CQJYIJ5+kdFbfj3acR4JUW6LX2e1hiEBiUwvEhzH5a3cZ5YSztpIA==",
+			"version": "1.7.1",
+			"resolved": "https://registry.npmjs.org/prosemirror-tables/-/prosemirror-tables-1.7.1.tgz",
+			"integrity": "sha512-eRQ97Bf+i9Eby99QbyAiyov43iOKgWa7QCGly+lrDt7efZ1v8NWolhXiB43hSDGIXT1UXgbs4KJN3a06FGpr1Q==",
 			"license": "MIT",
 			"dependencies": {
 				"prosemirror-keymap": "^1.2.2",
-				"prosemirror-model": "^1.24.1",
+				"prosemirror-model": "^1.25.0",
 				"prosemirror-state": "^1.4.3",
-				"prosemirror-transform": "^1.10.2",
-				"prosemirror-view": "^1.37.2"
+				"prosemirror-transform": "^1.10.3",
+				"prosemirror-view": "^1.39.1"
 			}
 		},
 		"node_modules/prosemirror-trailing-node": {
@@ -9837,9 +9896,9 @@
 			}
 		},
 		"node_modules/prosemirror-transform": {
-			"version": "1.10.2",
-			"resolved": "https://registry.npmjs.org/prosemirror-transform/-/prosemirror-transform-1.10.2.tgz",
-			"integrity": "sha512-2iUq0wv2iRoJO/zj5mv8uDUriOHWzXRnOTVgCzSXnktS/2iQRa3UUQwVlkBlYZFtygw6Nh1+X4mGqoYBINn5KQ==",
+			"version": "1.10.4",
+			"resolved": "https://registry.npmjs.org/prosemirror-transform/-/prosemirror-transform-1.10.4.tgz",
+			"integrity": "sha512-pwDy22nAnGqNR1feOQKHxoFkkUtepoFAd3r2hbEDsnf4wp57kKA36hXsB3njA9FtONBEwSDnDeCiJe+ItD+ykw==",
 			"license": "MIT",
 			"dependencies": {
 				"prosemirror-model": "^1.21.0"
@@ -11808,6 +11867,12 @@
 				"@mixmark-io/domino": "^2.2.0"
 			}
 		},
+		"node_modules/turndown-plugin-gfm": {
+			"version": "1.0.2",
+			"resolved": "https://registry.npmjs.org/turndown-plugin-gfm/-/turndown-plugin-gfm-1.0.2.tgz",
+			"integrity": "sha512-vwz9tfvF7XN/jE0dGoBei3FXWuvll78ohzCZQuOb+ZjWrs3a0XhQVomJEb2Qh4VHTPNRO4GPZh0V7VRbiWwkRg==",
+			"license": "MIT"
+		},
 		"node_modules/tweetnacl": {
 			"version": "0.14.5",
 			"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",

+ 6 - 0
package.json

@@ -66,6 +66,10 @@
 		"@tiptap/extension-code-block-lowlight": "^2.11.9",
 		"@tiptap/extension-highlight": "^2.10.0",
 		"@tiptap/extension-placeholder": "^2.10.0",
+		"@tiptap/extension-table": "^2.12.0",
+		"@tiptap/extension-table-cell": "^2.12.0",
+		"@tiptap/extension-table-header": "^2.12.0",
+		"@tiptap/extension-table-row": "^2.12.0",
 		"@tiptap/extension-typography": "^2.10.0",
 		"@tiptap/pm": "^2.11.7",
 		"@tiptap/starter-kit": "^2.10.0",
@@ -106,6 +110,7 @@
 		"prosemirror-schema-basic": "^1.2.3",
 		"prosemirror-schema-list": "^1.5.1",
 		"prosemirror-state": "^1.4.3",
+		"prosemirror-tables": "^1.7.1",
 		"prosemirror-view": "^1.34.3",
 		"pyodide": "^0.27.3",
 		"socket.io-client": "^4.2.0",
@@ -113,6 +118,7 @@
 		"svelte-sonner": "^0.3.19",
 		"tippy.js": "^6.3.7",
 		"turndown": "^7.2.0",
+		"turndown-plugin-gfm": "^1.0.2",
 		"undici": "^7.3.0",
 		"uuid": "^9.0.1",
 		"vite-plugin-static-copy": "^2.2.0",

+ 25 - 0
src/app.css

@@ -412,3 +412,28 @@ input[type='number'] {
 .hljs-strong {
 	font-weight: 700;
 }
+
+/* Table styling for tiptap editors */
+.tiptap table {
+	@apply w-full text-sm text-left text-gray-500 dark:text-gray-400 max-w-full;
+}
+
+.tiptap thead {
+	@apply text-xs text-gray-700 uppercase bg-gray-50 dark:bg-gray-850 dark:text-gray-400 border-none;
+}
+
+.tiptap th, .tiptap td {
+	@apply px-3 py-1.5 border border-gray-100 dark:border-gray-850;
+}
+
+.tiptap th {
+	@apply cursor-pointer text-left text-xs text-gray-700 dark:text-gray-400 font-semibold uppercase bg-gray-50 dark:bg-gray-850;
+}
+
+.tiptap td {
+	@apply text-gray-900 dark:text-white w-max;
+}
+
+.tiptap tr {
+	@apply bg-white dark:bg-gray-900 dark:border-gray-850 text-xs;
+}

+ 14 - 3
src/lib/components/common/RichTextInput.svelte

@@ -1,29 +1,36 @@
 <script lang="ts">
 	import { marked } from 'marked';
 	import TurndownService from 'turndown';
+	import { gfm } from 'turndown-plugin-gfm';
 	const turndownService = new TurndownService({
 		codeBlockStyle: 'fenced',
 		headingStyle: 'atx'
 	});
 	turndownService.escape = (string) => string;
 
+	// Use turndown-plugin-gfm for proper GFM table support
+	turndownService.use(gfm);
+
 	import { onMount, onDestroy } from 'svelte';
 	import { createEventDispatcher } from 'svelte';
 	const eventDispatch = createEventDispatcher();
 
 	import { EditorState, Plugin, PluginKey, TextSelection } from 'prosemirror-state';
 	import { Decoration, DecorationSet } from 'prosemirror-view';
-
 	import { Editor } from '@tiptap/core';
 
 	import { AIAutocompletion } from './RichTextInput/AutoCompletion.js';
+	import Table from '@tiptap/extension-table';
+	import TableRow from '@tiptap/extension-table-row';
+	import TableHeader from '@tiptap/extension-table-header';
+	import TableCell from '@tiptap/extension-table-cell';
 
 	import CodeBlockLowlight from '@tiptap/extension-code-block-lowlight';
 	import Placeholder from '@tiptap/extension-placeholder';
+	import { all, createLowlight } from 'lowlight';
+	import StarterKit from '@tiptap/starter-kit';
 	import Highlight from '@tiptap/extension-highlight';
 	import Typography from '@tiptap/extension-typography';
-	import StarterKit from '@tiptap/starter-kit';
-	import { all, createLowlight } from 'lowlight';
 
 	import { PASTED_TEXT_CHARACTER_LIMIT } from '$lib/constants';
 
@@ -194,6 +201,10 @@
 				Highlight,
 				Typography,
 				Placeholder.configure({ placeholder }),
+				Table.configure({ resizable: true }),
+				TableRow,
+				TableHeader,
+				TableCell,
 				...(autocomplete
 					? [
 							AIAutocompletion.configure({