From 98ff4d0a4f43e9cb134b105e03af73683d42d75c Mon Sep 17 00:00:00 2001 From: Timothy Cardoza Date: Fri, 20 Feb 2026 15:52:48 -0600 Subject: [PATCH] slash command adjustments including renaming to checklist --- bun.lock | 5 +++- package.json | 1 + src/components/SlashMenu.tsx | 44 +++++++++++++++++++++++++++++++---- src/components/TaskEditor.tsx | 5 +++- 4 files changed, 49 insertions(+), 6 deletions(-) diff --git a/bun.lock b/bun.lock index 660a4d4..18e5930 100644 --- a/bun.lock +++ b/bun.lock @@ -12,6 +12,7 @@ "@tiptap/extension-placeholder": "^3.18.0", "@tiptap/extension-task-item": "^3.18.0", "@tiptap/extension-task-list": "^3.18.0", + "@tiptap/extension-underline": "^3.20.0", "@tiptap/starter-kit": "^3.18.0", "@tiptap/suggestion": "^3.18.0", "autoprefixer": "^10.4.23", @@ -494,7 +495,7 @@ "@tiptap/extension-text": ["@tiptap/extension-text@3.18.0", "", { "peerDependencies": { "@tiptap/core": "^3.18.0" } }, "sha512-9TvctdnBCwK/zyTi9kS7nGFNl5OvGM8xE0u38ZmQw5t79JOqJHgOroyqMjw8LHK/1PWrozfNCmsZbpq4IZuKXw=="], - "@tiptap/extension-underline": ["@tiptap/extension-underline@3.18.0", "", { "peerDependencies": { "@tiptap/core": "^3.18.0" } }, "sha512-009IeXURNJ/sm1pBqbj+2YQgjQaBtNlJR3dbl6xu49C+qExqCmI7klhKQuwsVVGLR7ahsYlp7d9RlftnhCXIcQ=="], + "@tiptap/extension-underline": ["@tiptap/extension-underline@3.20.0", "", { "peerDependencies": { "@tiptap/core": "^3.20.0" } }, "sha512-LzNXuy2jwR/y+ymoUqC72TiGzbOCjioIjsDu0MNYpHuHqTWPK5aV9Mh0nbZcYFy/7fPlV1q0W139EbJeYBZEAQ=="], "@tiptap/extensions": ["@tiptap/extensions@3.18.0", "", { "peerDependencies": { "@tiptap/core": "^3.18.0", "@tiptap/pm": "^3.18.0" } }, "sha512-uSRIE9HGshBN6NRFR3LX2lZqBLvX92SgU5A9AvUbJD4MqU63E+HdruJnRjsVlX3kPrmbIDowxrzXlUcg3K0USQ=="], @@ -1392,6 +1393,8 @@ "@tailwindcss/oxide-wasm32-wasi/tslib": ["tslib@2.8.1", "", { "bundled": true }, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], + "@tiptap/starter-kit/@tiptap/extension-underline": ["@tiptap/extension-underline@3.18.0", "", { "peerDependencies": { "@tiptap/core": "^3.18.0" } }, "sha512-009IeXURNJ/sm1pBqbj+2YQgjQaBtNlJR3dbl6xu49C+qExqCmI7klhKQuwsVVGLR7ahsYlp7d9RlftnhCXIcQ=="], + "anymatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], "ast-types/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], diff --git a/package.json b/package.json index e0f7136..378a072 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ "@tiptap/extension-placeholder": "^3.18.0", "@tiptap/extension-task-item": "^3.18.0", "@tiptap/extension-task-list": "^3.18.0", + "@tiptap/extension-underline": "^3.20.0", "@tiptap/starter-kit": "^3.18.0", "@tiptap/suggestion": "^3.18.0", "autoprefixer": "^10.4.23", diff --git a/src/components/SlashMenu.tsx b/src/components/SlashMenu.tsx index 0bbb983..7d52251 100644 --- a/src/components/SlashMenu.tsx +++ b/src/components/SlashMenu.tsx @@ -3,7 +3,8 @@ import { Heading1, Heading2, Heading3, List, ListTodo, Type, Code, Quote, - Image as ImageIcon, Minus + Image as ImageIcon, Minus, + Bold, Italic, Underline } from "lucide-solid"; import { cn, convertImageToWebpFile } from "@/lib/utils"; import { activeTaskId, uploadTaskAttachment } from "@/store"; @@ -12,6 +13,7 @@ import { toast } from "solid-sonner"; export interface CommandItem { title: string; description: string; + aliases?: string[]; icon: any; command: (props: { editor: any; range: any }) => void; } @@ -26,9 +28,37 @@ export const getSuggestionItems = ({ query }: { query: string }): CommandItem[] editor.chain().focus().deleteRange(range).setNode("paragraph").run(); }, }, + { + title: "Bold", + description: "Strong text. (**text**)", + aliases: ["b", "strong"], + icon: Bold, + command: ({ editor, range }: { editor: any, range: any }) => { + editor.chain().focus().deleteRange(range).toggleBold().run(); + }, + }, + { + title: "Italic", + description: "Emphasized text. (*text*)", + aliases: ["i", "emphasis"], + icon: Italic, + command: ({ editor, range }: { editor: any, range: any }) => { + editor.chain().focus().deleteRange(range).toggleItalic().run(); + }, + }, + { + title: "Underline", + description: "Underlined text.", + aliases: ["u"], + icon: Underline, + command: ({ editor, range }: { editor: any, range: any }) => { + editor.chain().focus().deleteRange(range).toggleUnderline().run(); + }, + }, { title: "Heading 1", description: "Big section heading.", + aliases: ["h1"], icon: Heading1, command: ({ editor, range }: { editor: any, range: any }) => { editor.chain().focus().deleteRange(range).setNode("heading", { level: 1 }).run(); @@ -37,6 +67,7 @@ export const getSuggestionItems = ({ query }: { query: string }): CommandItem[] { title: "Heading 2", description: "Medium section heading.", + aliases: ["h2"], icon: Heading2, command: ({ editor, range }: { editor: any, range: any }) => { editor.chain().focus().deleteRange(range).setNode("heading", { level: 2 }).run(); @@ -45,6 +76,7 @@ export const getSuggestionItems = ({ query }: { query: string }): CommandItem[] { title: "Heading 3", description: "Small section heading.", + aliases: ["h3"], icon: Heading3, command: ({ editor, range }: { editor: any, range: any }) => { editor.chain().focus().deleteRange(range).setNode("heading", { level: 3 }).run(); @@ -59,8 +91,8 @@ export const getSuggestionItems = ({ query }: { query: string }): CommandItem[] }, }, { - title: "Task List", - description: "Track tasks with a checklist.", + title: "Checklist", + description: "Insert a checklist.", icon: ListTodo, command: ({ editor, range }: { editor: any, range: any }) => { editor.chain().focus().deleteRange(range).toggleTaskList().run(); @@ -138,7 +170,11 @@ export const getSuggestionItems = ({ query }: { query: string }): CommandItem[] editor.chain().focus().deleteRange(range).setHorizontalRule().run(); }, }, - ].filter(item => item.title.toLowerCase().startsWith(query.toLowerCase())); + ].filter(item => { + const lowerQuery = query.toLowerCase(); + return item.title.toLowerCase().startsWith(lowerQuery) || + item.aliases?.some(alias => alias.toLowerCase().startsWith(lowerQuery)); + }); }; export const SlashMenu: Component<{ diff --git a/src/components/TaskEditor.tsx b/src/components/TaskEditor.tsx index 54e20d8..8fdf640 100644 --- a/src/components/TaskEditor.tsx +++ b/src/components/TaskEditor.tsx @@ -5,6 +5,7 @@ import Placeholder from "@tiptap/extension-placeholder"; import TaskList from "@tiptap/extension-task-list"; import TaskItem from "@tiptap/extension-task-item"; import Image from "@tiptap/extension-image"; +import Underline from "@tiptap/extension-underline"; import { X } from "lucide-solid"; import { cn } from "@/lib/utils"; @@ -70,6 +71,7 @@ export const TaskEditor: Component = (props) => { class: "rounded-lg border border-border max-w-full h-auto", }, }), + Underline, MobileIndent, ], // Use untrack so the editor doesn't re-initialize when props.content changes @@ -89,7 +91,8 @@ export const TaskEditor: Component = (props) => { // Custom Task List Styling "[&_ul[data-type='taskList']]:list-none [&_ul[data-type='taskList']]:p-0", "[&_li[data-type='taskItem']]:flex [&_li[data-type='taskItem']]:items-start", - "[&_li[data-type='taskItem']>label]:mr-2 [&_li[data-type='taskItem']>label]:mt-0.5 [&_li[data-type='taskItem']>label]:select-none", + "[&_li[data-type='taskItem']>label]:mr-3 [&_li[data-type='taskItem']>label]:mt-1 [&_li[data-type='taskItem']>label]:select-none", + "[&_li[data-type='taskItem']>label>input]:w-5 [&_li[data-type='taskItem']>label>input]:h-5 [&_li[data-type='taskItem']>label>input]:cursor-pointer", "[&_li[data-type='taskItem']>div]:flex-1 [&_li[data-type='taskItem']>div]:min-h-[1.5rem]", props.class ),