@terrible-lexical/react
Version:
This package provides Lexical components and hooks for React applications.
96 lines (81 loc) • 2.51 kB
text/typescript
/**
* 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;
}