import { CleanStyles, ComponentUtils, DismissSuggestionsOnOutsideClick, HandleExcelPaste, PreserveWhitespace, } from "@opendesk/shared/tiptap"; import { AlignCenter, AlignLeft, AlignRight, Blockquote, Bold, BulletList, FontColor, FontHighlight, HeadingGroup, HorizontalRule, InlineCode, InsertImage, InsertLink, InsertTable, InsertVideo, Italic, OrderedList, Paragraph, RichTextKit, Separator, Strike, commentToolbar, type CommandMenuItem, type MentionSuggestionItem, type MenuItem, } from "frappe-ui/editor"; import type { MaybeRefOrGetter } from "vue"; /** * Build the extension list for a Opendesk rich-text editor. * * Mentions are passed as a reactive getter so the `@` list stays in sync as * agents load (the v0 `:mentions` snapshot prop is what broke suggestions). */ export function buildEditorExtensions( options: { mentions?: MaybeRefOrGetter; extra?: unknown[]; } = {} ) { const kit = RichTextKit.configure({ heading: { levels: [2, 3, 4, 5, 6] }, // rc.1 ships the table-of-contents node off; opendesk editors had it. toc: {}, ...(options.mentions ? { mention: { items: options.mentions } } : {}), }); return [ kit, ComponentUtils, HandleExcelPaste, CleanStyles, DismissSuggestionsOnOutsideClick, PreserveWhitespace, ...(options.extra ?? []), ]; } /** Clear-formatting toolbar button (ports the v0 `ClearFormattingUtility`). */ export const ClearFormatting: CommandMenuItem = { label: "Clear formatting", icon: "lucide-brush-cleaning", action: (editor) => editor.chain().focus().unsetAllMarks().clearNodes().cleanStyles().run(), }; /** Code block button; frappe-ui ships the node but no toolbar item for it. */ export const InsertCodeBlock: CommandMenuItem = { label: "Code block", icon: "lucide-square-code", isActive: (editor) => editor.isActive("codeBlock"), action: (editor) => editor.chain().focus().toggleCodeBlock().run(), }; /** Full toolbar mirroring the v0 `textEditorMenuButtons`. */ export const fullToolbar: MenuItem[] = [ HeadingGroup, Separator, Bold, Italic, Strike, FontColor, FontHighlight, Separator, AlignLeft, AlignCenter, AlignRight, Separator, BulletList, OrderedList, Blockquote, InlineCode, InsertCodeBlock, Separator, InsertLink, InsertImage, InsertVideo, InsertTable, HorizontalRule, Separator, ClearFormatting, ]; /** * Curated toolbar for the new-ticket / base editor (ports the v0 `fixedMenu`). * Kept compact so the toolbar + Discard/Submit fit on one row. */ export const ticketToolbar: MenuItem[] = [ Paragraph, HeadingGroup, Separator, Bold, Italic, Separator, BulletList, OrderedList, Separator, InsertImage, InsertVideo, InsertLink, Blockquote, InlineCode, ClearFormatting, ]; /** Compact bubble/inline toolbar for comment display + inline editing. */ export { commentToolbar };