@selfcommunity/react-ui
Version:
React UI Components to integrate a Community created with SelfCommunity Platform.
36 lines (35 loc) • 1.69 kB
JavaScript
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]);
}