UNPKG

@atlaskit/editor-plugin-block-controls

Version:

Block controls plugin for @atlaskit/editor-core

65 lines (63 loc) 3.74 kB
import { rootElementGap, topPositionAdjustment, QUICK_INSERT_DIMENSIONS, QUICK_INSERT_LEFT_OFFSET } from '../ui/consts'; import { refreshAnchorName } from '../ui/utils/anchor-name'; import { getAnchorAttrName } from '../ui/utils/dom-attr-name'; import { getControlBottomCSSValue, getControlHeightCSSValue, getNodeHeight, getTopPosition, shouldBeSticky } from './utils/drag-handle-positions'; import { getLeftPositionForRootElement } from './utils/widget-positions'; // Adapted from `src/ui/drag-handle.tsx` as positioning logic is similar // CHANGES - added an offset so quick insert button can be positioned beside drag handle // CHANGES - removed `editorExperiment('nested-dnd', true)` check and rootNodeType calculation // CHANGES - replace anchorName with rootAnchorName // CHANGES - `removed editorExperiment('advanced_layouts', true) && isLayoutColumn` checks as quick insert button will not be positioned for layout column export const calculatePosition = ({ rootAnchorName, anchorName, view, getPos, rootNodeType, macroInteractionUpdates, anchorRectCache }) => { const supportsAnchor = CSS.supports('top', `anchor(${rootAnchorName} start)`) && CSS.supports('left', `anchor(${rootAnchorName} start)`); const safeAnchorName = refreshAnchorName({ getPos, view, anchorName: rootAnchorName }); const dom = view.dom.querySelector(`[${getAnchorAttrName()}="${safeAnchorName}"]`); const hasResizer = rootNodeType === 'table' || rootNodeType === 'mediaSingle'; const isExtension = rootNodeType === 'extension' || rootNodeType === 'bodiedExtension'; const isBlockCard = rootNodeType === 'blockCard'; const isEmbedCard = rootNodeType === 'embedCard'; const isMacroInteractionUpdates = macroInteractionUpdates && isExtension; let innerContainer = null; if (dom) { if (isEmbedCard) { innerContainer = dom.querySelector('.rich-media-item'); } else if (hasResizer) { innerContainer = dom.querySelector('.resizer-item'); } else if (isExtension) { innerContainer = dom.querySelector('.extension-container[data-layout]'); } else if (isBlockCard) { //specific to datasource blockCard innerContainer = dom.querySelector('.datasourceView-content-inner-wrap'); } } const isEdgeCase = (hasResizer || isExtension || isEmbedCard || isBlockCard) && innerContainer; const isSticky = shouldBeSticky(rootNodeType); const bottom = getControlBottomCSSValue(safeAnchorName || anchorName, isSticky, true); if (supportsAnchor) { return { left: isEdgeCase ? `calc(anchor(${safeAnchorName} start) + ${getLeftPositionForRootElement(dom, rootNodeType, QUICK_INSERT_DIMENSIONS, innerContainer, isMacroInteractionUpdates)} + -${QUICK_INSERT_LEFT_OFFSET}px)` : `calc(anchor(${safeAnchorName} start) - ${QUICK_INSERT_DIMENSIONS.width}px - ${rootElementGap(rootNodeType)}px + -${QUICK_INSERT_LEFT_OFFSET}px)`, top: `calc(anchor(${safeAnchorName} start) + ${topPositionAdjustment(rootNodeType)}px)`, ...bottom }; } // expensive, calls offsetHeight const nodeHeight = getNodeHeight(dom, safeAnchorName || anchorName, anchorRectCache) || 0; const height = getControlHeightCSSValue(nodeHeight, isSticky, true, "var(--ds-space-300, 24px)"); return { left: isEdgeCase ? `calc(${(dom === null || dom === void 0 ? void 0 : dom.offsetLeft) || 0}px + ${getLeftPositionForRootElement(dom, rootNodeType, QUICK_INSERT_DIMENSIONS, innerContainer, isMacroInteractionUpdates)} + -${QUICK_INSERT_LEFT_OFFSET}px)` : `calc(${getLeftPositionForRootElement(dom, rootNodeType, QUICK_INSERT_DIMENSIONS, innerContainer, isMacroInteractionUpdates)} + -${QUICK_INSERT_LEFT_OFFSET}px)`, top: getTopPosition(dom, rootNodeType), ...height }; };