ultisuite-client/lib/drive/richtext-extensions.ts
R3D347HR4Y 303b2b1074
Some checks are pending
E2E / Playwright e2e (push) Waiting to run
wow
2026-06-11 01:22:40 +02:00

136 lines
4.7 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 {
DocsTable,
DocsTableCell,
DocsTableHeader,
DocsTableRow,
DOCS_TABLE_EXTENSION_OPTIONS,
} from "@/lib/drive/extensions/docs-table"
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 { DocsGraphicAnchorSync } from "@/lib/drive/extensions/docs-graphic-anchor-sync"
import { DocsGraphicKeyboard } from "@/lib/drive/extensions/docs-graphic-keyboard"
import { DocsPageFlowDecoration } from "@/lib/drive/extensions/docs-page-flow-decoration"
import { DocsParagraphStyle } from "@/lib/drive/extensions/docs-paragraph-style"
import { DocsParagraphIndent } from "@/lib/drive/extensions/docs-paragraph-indent"
import { DocsParagraphSpacing } from "@/lib/drive/extensions/docs-paragraph-spacing"
import { DocsListStyles } from "@/lib/drive/extensions/docs-list-styles"
import { TaskItem, TaskList } from "@tiptap/extension-list"
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,
heading: { levels: [1, 2, 3, 4, 5, 6] },
}),
]
// 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"] }),
DocsTable.configure(DOCS_TABLE_EXTENSION_OPTIONS),
DocsTableRow,
DocsTableCell,
DocsTableHeader,
DocsGraphic,
DocsInlineGraphic,
DocsGraphicPasteDrop,
DocsGraphicAnchorSync,
DocsGraphicKeyboard,
DocsPageFlowDecoration,
DocsParagraphStyle,
DocsParagraphIndent,
DocsParagraphSpacing,
DocsListStyles,
TaskList,
TaskItem.configure({ nested: true }),
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"],
}),
DocsTable.configure(DOCS_TABLE_EXTENSION_OPTIONS),
DocsTableRow,
DocsTableCell,
DocsTableHeader,
DocsGraphic,
DocsInlineGraphic,
DocsGraphicPasteDrop,
DocsGraphicKeyboard,
Image.configure({ inline: true, allowBase64: true }),
Placeholder.configure({
placeholder: placeholder ?? "Saisissez un en-tête ou un pied de page",
}),
]
}