ultisuite-client/lib/drive/richtext-extensions.ts
R3D347HR4Y 2a7c153748
Some checks are pending
E2E / Playwright e2e (push) Waiting to run
wrap page
2026-06-10 12:48:27 +02:00

116 lines
3.9 KiB
TypeScript

import type { Extensions } from "@tiptap/core"
import StarterKit from "@tiptap/starter-kit"
import Underline from "@tiptap/extension-underline"
import Link from "@tiptap/extension-link"
import TextAlign from "@tiptap/extension-text-align"
import { TextStyle, Color, BackgroundColor, FontSize, FontFamily } from "@tiptap/extension-text-style"
import Highlight from "@tiptap/extension-highlight"
import Image from "@tiptap/extension-image"
import Placeholder from "@tiptap/extension-placeholder"
import { Table } from "@tiptap/extension-table"
import TableRow from "@tiptap/extension-table-row"
import TableCell from "@tiptap/extension-table-cell"
import TableHeader from "@tiptap/extension-table-header"
import Collaboration from "@tiptap/extension-collaboration"
import CollaborationCaret from "@tiptap/extension-collaboration-caret"
import type { HocuspocusProvider } from "@hocuspocus/provider"
import type * as Y from "yjs"
import { DocsEditorShortcuts } from "@/lib/drive/docs-editor-shortcuts"
import { DocsGraphic, DocsInlineGraphic } from "@/lib/drive/extensions/docs-graphic"
import { DocsGraphicPasteDrop } from "@/lib/drive/extensions/docs-graphic-paste-drop"
import { DocsPageFlowDecoration } from "@/lib/drive/extensions/docs-page-flow-decoration"
export function buildRichTextExtensions(options?: {
collaboration?: { document: Y.Doc }
collaborationCaret?: { provider: HocuspocusProvider; user: { name: string; color: string } }
placeholder?: string
editable?: boolean
}): Extensions {
const extensions: Extensions = [
StarterKit.configure({
undoRedo: options?.collaboration ? false : undefined,
}),
]
// Collaboration must register right after StarterKit (y-prosemirror binding).
if (options?.collaboration) {
extensions.push(
Collaboration.configure({
document: options.collaboration.document,
field: "default",
})
)
}
if (options?.collaborationCaret) {
extensions.push(
CollaborationCaret.configure({
provider: options.collaborationCaret.provider,
user: options.collaborationCaret.user,
})
)
}
extensions.push(
Underline,
Link.configure({ openOnClick: false }),
TextStyle,
FontFamily,
FontSize,
Color,
BackgroundColor,
Highlight.configure({ multicolor: true }),
TextAlign.configure({ types: ["heading", "paragraph"], alignments: ["left", "center", "right", "justify"] }),
Table.configure({ resizable: true }),
TableRow,
TableCell,
TableHeader,
DocsGraphic,
DocsInlineGraphic,
DocsGraphicPasteDrop,
DocsPageFlowDecoration,
Image.configure({ inline: true, allowBase64: true }),
Placeholder.configure({
placeholder: options?.placeholder ?? "Commencez à écrire…",
}),
DocsEditorShortcuts
)
return extensions
}
export const RICHTEXT_EDITOR_CLASS =
"ultidrive-richtext-editor max-w-none outline-none focus:outline-none prose prose-sm"
export const RICHTEXT_REGION_EDITOR_CLASS =
"ultidrive-richtext-region-editor max-w-none outline-none focus:outline-none prose prose-sm"
/** Full-feature extensions for inline header/footer editors (no collab, no page flow). */
export function buildRegionEditorExtensions(placeholder?: string): Extensions {
return [
StarterKit.configure({ heading: { levels: [1, 2, 3, 4] } }),
Underline,
Link.configure({ openOnClick: false }),
TextStyle,
FontFamily,
FontSize,
Color,
BackgroundColor,
Highlight.configure({ multicolor: true }),
TextAlign.configure({
types: ["heading", "paragraph"],
alignments: ["left", "center", "right", "justify"],
}),
Table.configure({ resizable: true }),
TableRow,
TableCell,
TableHeader,
DocsGraphic,
DocsInlineGraphic,
DocsGraphicPasteDrop,
Image.configure({ inline: true, allowBase64: true }),
Placeholder.configure({
placeholder: placeholder ?? "Saisissez un en-tête ou un pied de page",
}),
]
}