1
0
Эх сурвалжийг харах

enh: task list rich text input

Timothy Jaeryang Baek 3 сар өмнө
parent
commit
248fd10406

+ 29 - 0
package-lock.json

@@ -26,6 +26,8 @@
 				"@tiptap/extension-table-cell": "^2.12.0",
 				"@tiptap/extension-table-header": "^2.12.0",
 				"@tiptap/extension-table-row": "^2.12.0",
+				"@tiptap/extension-task-item": "^2.25.0",
+				"@tiptap/extension-task-list": "^2.25.0",
 				"@tiptap/extension-typography": "^2.10.0",
 				"@tiptap/pm": "^2.11.7",
 				"@tiptap/starter-kit": "^2.10.0",
@@ -3247,6 +3249,33 @@
 				"@tiptap/core": "^2.7.0"
 			}
 		},
+		"node_modules/@tiptap/extension-task-item": {
+			"version": "2.25.0",
+			"resolved": "https://registry.npmjs.org/@tiptap/extension-task-item/-/extension-task-item-2.25.0.tgz",
+			"integrity": "sha512-8F7Z7jbsyGrPLHQCn+n39zdqIgxwR1kJ1nL5ZwhEW3ZhJgkFF0WMJSv36mwIJwL08p8um/c6g72AYB/e8CD7eA==",
+			"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-task-list": {
+			"version": "2.25.0",
+			"resolved": "https://registry.npmjs.org/@tiptap/extension-task-list/-/extension-task-list-2.25.0.tgz",
+			"integrity": "sha512-2mASqp8MJ0dyc1OK6c8P7m/zwoVDv8PV+XsRR9O3tpIz/zjUVrOl0W4IndjUPBMa7cpJX8fGj8iC3DaRNpSMcg==",
+			"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",

+ 2 - 0
package.json

@@ -70,6 +70,8 @@
 		"@tiptap/extension-table-cell": "^2.12.0",
 		"@tiptap/extension-table-header": "^2.12.0",
 		"@tiptap/extension-table-row": "^2.12.0",
+		"@tiptap/extension-task-item": "^2.25.0",
+		"@tiptap/extension-task-list": "^2.25.0",
 		"@tiptap/extension-typography": "^2.10.0",
 		"@tiptap/pm": "^2.11.7",
 		"@tiptap/starter-kit": "^2.10.0",

+ 33 - 0
src/app.css

@@ -330,6 +330,39 @@ input[type='number'] {
 	@apply line-clamp-1 absolute;
 }
 
+.tiptap ul[data-type='taskList'] {
+	list-style: none;
+	margin-left: 0;
+	padding: 0;
+
+	li {
+		align-items: center;
+
+		display: flex;
+
+		> label {
+			flex: 0 0 auto;
+			margin-right: 0.5rem;
+			user-select: none;
+			display: flex;
+		}
+
+		> div {
+			flex: 1 1 auto;
+
+			align-items: center;
+		}
+	}
+
+	input[type='checkbox'] {
+		cursor: pointer;
+	}
+
+	ul[data-type='taskList'] {
+		margin: 0;
+	}
+}
+
 @media (prefers-color-scheme: dark) {
 	.ProseMirror p.is-editor-empty:first-child::before {
 		color: #757575;

+ 21 - 0
src/lib/components/common/RichTextInput.svelte

@@ -11,6 +11,18 @@
 	// Use turndown-plugin-gfm for proper GFM table support
 	turndownService.use(gfm);
 
+	turndownService.addRule('taskListItems', {
+		filter: (node) =>
+			node.nodeName === 'LI' &&
+			(node.getAttribute('data-checked') === 'true' ||
+				node.getAttribute('data-checked') === 'false'),
+		replacement: function (content, node) {
+			const checked = node.getAttribute('data-checked') === 'true';
+			content = content.replace(/^\s+/, '');
+			return `- [${checked ? 'x' : ' '}] ${content}\n`;
+		}
+	});
+
 	import { onMount, onDestroy, tick } from 'svelte';
 	import { createEventDispatcher } from 'svelte';
 
@@ -27,6 +39,9 @@
 	import TableHeader from '@tiptap/extension-table-header';
 	import TableCell from '@tiptap/extension-table-cell';
 
+	import TaskItem from '@tiptap/extension-task-item';
+	import TaskList from '@tiptap/extension-task-list';
+
 	import CodeBlockLowlight from '@tiptap/extension-code-block-lowlight';
 	import Placeholder from '@tiptap/extension-placeholder';
 	import StarterKit from '@tiptap/starter-kit';
@@ -437,6 +452,10 @@
 				TableRow,
 				TableHeader,
 				TableCell,
+				TaskList,
+				TaskItem.configure({
+					nested: true
+				}),
 				...(autocomplete
 					? [
 							AIAutocompletion.configure({
@@ -464,6 +483,8 @@
 
 				const htmlValue = editor.getHTML();
 				const jsonValue = editor.getJSON();
+
+				console.log(htmlValue, jsonValue);
 				let mdValue = turndownService
 					.turndown(
 						htmlValue