UNPKG

@blocknote/core

Version:

A "Notion-style" block-based extensible text editor built on top of Prosemirror and Tiptap.

90 lines (85 loc) 3.07 kB
import type { Awareness } from "y-protocols/awareness"; import type * as Y from "yjs"; import type { BlockNoteEditorOptions } from "../../editor/BlockNoteEditor"; import { createExtension, type ExtensionOptions, } from "../../editor/BlockNoteExtension.js"; import { FixUpSchemaExtension } from "./FixUpSchema.js"; import { ForkYDocExtension } from "./ForkYDoc.js"; import { RelativePositionMappingExtension } from "./RelativePositionMapping.js"; import { SchemaMigration } from "./schemaMigration/SchemaMigration.js"; import { CollaborationUser, YCursorExtension } from "./YCursorPlugin.js"; import { YSyncExtension } from "./YSync.js"; import { YUndoExtension } from "./YUndo.js"; export type CollaborationOptions = { /** * The Yjs XML fragment that's used for collaboration. */ fragment: Y.XmlFragment; /** * The user info for the current user that's shown to other collaborators. */ user: CollaborationUser; /** * A Yjs provider (used for awareness / cursor information) */ provider?: { awareness?: Awareness }; /** * Optional function to customize how cursors of users are rendered */ renderCursor?: (user: CollaborationUser) => HTMLElement; /** * Optional flag to set when the user label should be shown with the default * collaboration cursor. Setting to "always" will always show the label, * while "activity" will only show the label when the user moves the cursor * or types. Defaults to "activity". */ showCursorLabels?: "always" | "activity"; }; export const CollaborationExtension = createExtension( ({ options }: ExtensionOptions<CollaborationOptions>) => { return { key: "collaboration", blockNoteExtensions: [ FixUpSchemaExtension(), ForkYDocExtension(options), RelativePositionMappingExtension(), SchemaMigration(options), YCursorExtension(options), YSyncExtension(options), YUndoExtension(), ], } as const; }, ); export function withCollaboration< Options extends Partial<BlockNoteEditorOptions<any, any, any>>, >( options: Options & { /** * Options for configuring the collaboration functionality. */ collaboration: CollaborationOptions; }, ): Options { return { ...options, extensions: [ ...(options.extensions ?? []), CollaborationExtension(options.collaboration), ], // We disable the default prosemirror history plugin, since it's not compatible with yjs disableExtensions: ["history", ...(options.disableExtensions ?? [])], // We don't want the default initial content, since it will generate a random id for the initial block on each client, // leading to conflicts when syncing happens afterwards. initialContent: [{ type: "paragraph", id: "initialBlockId" }], }; } export * from "./ForkYDoc.js"; export * from "./RelativePositionMapping.js"; export * from "./schemaMigration/SchemaMigration.js"; export * from "./Versioning.js"; export * from "./YCursorPlugin.js"; export * from "./YSync.js"; export * from "./YUndo.js";