@atlaskit/editor-plugin-block-controls
Version:
Block controls plugin for @atlaskit/editor-core
69 lines • 3.21 kB
JavaScript
import React, { memo, useLayoutEffect, useMemo, useSyncExternalStore } from 'react';
import { isCSSAnchorSupported } from '@atlaskit/editor-common/styles/native-anchor';
import { getNodeTypeWithLevel } from '../pm-plugins/decorations-common';
import { BlockControlsLeftSurface } from '../ui/block-controls-left-surface';
import { BlockControlsRightSurface } from '../ui/block-controls-right-surface';
import { getAnchoredLeftGutterSurfacePlacement, getAnchoredSurfacePlacement } from '../ui/utils/get-surface-placement';
import { getSurfaceLifecycle } from './surface-lifecycle';
import { getSurfaceKey, useMeasuredSurfacePlacements } from './use-measured-surface-placements';
const CommittedSurface = /*#__PURE__*/memo(({
api,
descriptor,
side,
forceVisibleOnMouseOut,
measuredPlacement
}) => {
const {
anchorName,
blockControlsContext,
isTopLevel
} = descriptor;
const nodeType = blockControlsContext.targetNode.type.name;
const nodeTypeWithLevel = getNodeTypeWithLevel(blockControlsContext.targetNode.node);
const layout = blockControlsContext.targetNode.node.attrs.layout;
const parentNodeType = blockControlsContext.targetNode.parentType === 'doc' ? undefined : blockControlsContext.targetNode.parentType;
const anchoredPlacement = useMemo(() => {
if (!isCSSAnchorSupported()) {
return undefined;
}
const options = {
anchorName,
nodeType,
nodeTypeWithLevel,
layout,
parentNodeType,
side
};
return side === 'left' && isTopLevel ? getAnchoredLeftGutterSurfacePlacement(options) : getAnchoredSurfacePlacement(options);
}, [anchorName, nodeType, nodeTypeWithLevel, layout, parentNodeType, side, isTopLevel]);
const Surface = side === 'left' ? BlockControlsLeftSurface : BlockControlsRightSurface;
return /*#__PURE__*/React.createElement(Surface, {
api: api,
components: descriptor.surfaceComponents,
forceVisibleOnMouseOut: forceVisibleOnMouseOut,
placement: anchoredPlacement !== null && anchoredPlacement !== void 0 ? anchoredPlacement : measuredPlacement,
source: descriptor.source,
surfaceContext: descriptor.surfaceContext
});
});
export const CommittedBlockControlsSurfaces = props => {
const lifecycle = getSurfaceLifecycle(props.editorView);
const snapshot = useSyncExternalStore(lifecycle.subscribe, lifecycle.getSnapshot, () => undefined);
const measuredPlacements = useMeasuredSurfacePlacements(props.editorView, snapshot === null || snapshot === void 0 ? void 0 : snapshot.left, snapshot === null || snapshot === void 0 ? void 0 : snapshot.right);
useLayoutEffect(() => {
if (snapshot) {
lifecycle.acknowledge(snapshot.revision);
}
}, [lifecycle, snapshot]);
if (!snapshot) {
return null;
}
return /*#__PURE__*/React.createElement(React.Fragment, null, ['left', 'right'].flatMap(side => snapshot[side].map(descriptor => /*#__PURE__*/React.createElement(CommittedSurface, {
key: getSurfaceKey(side, descriptor),
api: props.api,
descriptor: descriptor,
side: side,
forceVisibleOnMouseOut: snapshot.forceVisibleOnMouseOut,
measuredPlacement: measuredPlacements.get(getSurfaceKey(side, descriptor))
}))));
};