/** * 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 {LexicalEditor} from 'lexical'; import type {JSX} from 'react'; import {Suspense, useMemo, useSyncExternalStore} from 'react'; import {createPortal} from 'react-dom'; import {type ErrorBoundaryType} from './types'; /** @internal */ export function useReactDecorators( editor: LexicalEditor, ErrorBoundary: ErrorBoundaryType, ): JSX.Element[] { const [subscribe, getSnapshot] = useMemo( () => [ (cb: () => void) => editor.registerDecoratorListener(cb), () => editor.getDecorators(), ] as const, [editor], ); const decorators = useSyncExternalStore(subscribe, getSnapshot, getSnapshot); // Return decorators defined as React Portals return useMemo(() => { const decoratedPortals = []; for (const nodeKey in decorators) { const element = editor.getElementByKey(nodeKey); if (element !== null) { const reactDecorator = ( { editor._onError(e); }}> {decorators[nodeKey]} ); decoratedPortals.push(createPortal(reactDecorator, element, nodeKey)); } } return decoratedPortals; }, [ErrorBoundary, decorators, editor]); }