UNPKG

@atlaskit/editor-plugin-block-controls

Version:

Block controls plugin for @atlaskit/editor-core

69 lines • 3.21 kB
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)) })))); };