UNPKG

@terrible-lexical/react

Version:

This package provides Lexical components and hooks for React applications.

96 lines (81 loc) 2.51 kB
/** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * */ import type {Doc} from 'yjs'; import {useCollaborationContext} from '@terrible-lexical/react/src/LexicalCollaborationContext'; import {useLexicalComposerContext} from '@terrible-lexical/react/src/LexicalComposerContext'; import {ExcludedProperties, Provider} from '@terrible-lexical/yjs/src'; import {useEffect, useMemo} from 'react'; import {InitialEditorStateType} from './LexicalComposer'; import { CursorsContainerRef, useYjsCollaboration, useYjsFocusTracking, useYjsHistory, } from './@terrible-lexical/shared/useYjsCollaboration'; type Props = { id: string; providerFactory: ( // eslint-disable-next-line no-shadow id: string, yjsDocMap: Map<string, Doc>, ) => Provider; shouldBootstrap: boolean; username?: string; cursorColor?: string; cursorsContainerRef?: CursorsContainerRef; initialEditorState?: InitialEditorStateType; excludedProperties?: ExcludedProperties; // `awarenessData` parameter allows arbitrary data to be added to the awareness. awarenessData?: object; }; export function CollaborationPlugin({ id, providerFactory, shouldBootstrap, username, cursorColor, cursorsContainerRef, initialEditorState, excludedProperties, awarenessData, }: Props): JSX.Element { const collabContext = useCollaborationContext(username, cursorColor); const {yjsDocMap, name, color} = collabContext; const [editor] = useLexicalComposerContext(); useEffect(() => { collabContext.isCollabActive = true; return () => { // Reseting flag only when unmount top level editor collab plugin. Nested // editors (e.g. image caption) should unmount without affecting it if (editor._parentEditor == null) { collabContext.isCollabActive = false; } }; }, [collabContext, editor]); const provider = useMemo( () => providerFactory(id, yjsDocMap), [id, providerFactory, yjsDocMap], ); const [cursors, binding] = useYjsCollaboration( editor, id, provider, yjsDocMap, name, color, shouldBootstrap, cursorsContainerRef, initialEditorState, excludedProperties, awarenessData, ); collabContext.clientID = binding.clientID; useYjsHistory(editor, binding); useYjsFocusTracking(editor, provider, name, color, awarenessData); return cursors; }