UNPKG

@selfcommunity/react-ui

Version:

React UI Components to integrate a Community created with SelfCommunity Platform.

36 lines (35 loc) 1.69 kB
import { jsx as _jsx } from "react/jsx-runtime"; import { Suspense, useEffect, useMemo, useState } from 'react'; import { createPortal, flushSync } from 'react-dom'; import { useIsomorphicLayoutEffect } from '@selfcommunity/react-core'; export function useDecorators(editor, ErrorBoundary) { const [decorators, setDecorators] = useState(() => editor.getDecorators()); // Subscribe to changes useIsomorphicLayoutEffect(() => { return editor.registerDecoratorListener((nextDecorators) => { flushSync(() => { setDecorators(nextDecorators); }); }); }, [editor]); useEffect(() => { // If the content editable mounts before the subscription is added, then // nothing will be rendered on initial pass. We can get around that by // ensuring that we set the value. setDecorators(editor.getDecorators()); }, [editor]); // Return decorators defined as React Portals return useMemo(() => { const decoratedPortals = []; const decoratorKeys = Object.keys(decorators); for (let i = 0; i < decoratorKeys.length; i++) { const nodeKey = decoratorKeys[i]; const reactDecorator = (_jsx(ErrorBoundary, Object.assign({ onError: (e) => editor._onError(e) }, { children: _jsx(Suspense, Object.assign({ fallback: null }, { children: decorators[nodeKey] })) }))); const element = editor.getElementByKey(nodeKey); if (element !== null) { decoratedPortals.push(createPortal(reactDecorator, element, nodeKey)); } } return decoratedPortals; }, [ErrorBoundary, decorators, editor]); }