UNPKG

@atlaskit/editor-plugin-block-controls

Version:

Block controls plugin for @atlaskit/editor-core

135 lines (131 loc) 7.09 kB
import _defineProperty from "@babel/runtime/helpers/defineProperty"; function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } import { shouldBeSticky } from '../../pm-plugins/utils/drag-handle-positions'; import { dragHandleGap, topPositionAdjustment } from '../consts'; export var getAbsoluteSurfacePlacement = function getAbsoluteSurfacePlacement(_ref) { var _offsetParentRect$lef, _offsetParentRect$top; var offsetParentRect = _ref.offsetParentRect, offsetParentScrollLeft = _ref.offsetParentScrollLeft, offsetParentScrollTop = _ref.offsetParentScrollTop, placement = _ref.placement; return _objectSpread(_objectSpread({}, placement), {}, { left: placement.left - ((_offsetParentRect$lef = offsetParentRect === null || offsetParentRect === void 0 ? void 0 : offsetParentRect.left) !== null && _offsetParentRect$lef !== void 0 ? _offsetParentRect$lef : 0) + offsetParentScrollLeft, top: placement.top - ((_offsetParentRect$top = offsetParentRect === null || offsetParentRect === void 0 ? void 0 : offsetParentRect.top) !== null && _offsetParentRect$top !== void 0 ? _offsetParentRect$top : 0) + offsetParentScrollTop }); }; /** * Positions the surface beside the legacy drag-handle slot, on either the left or right edge * of the target node. Node-type-specific gap/top-adjustment maths (layouts, tables, media, cards, * extensions, etc.) live in one place so left/right edge cases can't drift out of sync. * * The left side grows away from the node without knowing its own width, so it needs * `translateX(-100%)` to anchor its right edge at `nodeRect.left` and extend backward. The right * side grows in the normal box-flow direction (away from the node, into the margin), so the gap * can be folded straight into `left` with no transform needed. */ export var getSurfacePlacement = function getSurfacePlacement(_ref2) { var layout = _ref2.layout, nodeRect = _ref2.nodeRect, nodeType = _ref2.nodeType, nodeTypeWithLevel = _ref2.nodeTypeWithLevel, parentNodeType = _ref2.parentNodeType, side = _ref2.side; if (nodeType === 'layoutColumn') { // nodeRect.left + width/2 === nodeRect.right - width/2 — side-independent. return { left: nodeRect.left + nodeRect.width / 2, top: nodeRect.top, transform: 'translate(-50%, -50%)' }; } var gap = dragHandleGap(nodeType, parentNodeType); var top = nodeRect.top + topPositionAdjustment(nodeTypeWithLevel, layout); var height = shouldBeSticky(nodeType) ? nodeRect.height : undefined; return side === 'right' ? { left: nodeRect.right + gap, top: top, transform: '', height: height } : { left: nodeRect.left, top: top, transform: "translateX(calc(-100% - ".concat(gap, "px))"), height: height }; }; /** * The insets to apply to a surface wrapper, plus whether that wrapper spans its target node. * * Two kinds of placement produce this. A measured one resolves to pixel numbers from a * `getBoundingClientRect` snapshot, so it is only as fresh as the last render and needs observers * to keep it honest. An anchored one resolves to `anchor()` functions that the browser re-evaluates * on every layout change, so it stays attached to its node with nothing re-rendering. * * `isSticky` is carried alongside the style rather than read back out of it because the two variants * express the same stretch differently — a measured `height` versus an anchored `bottom`. */ /** * Adapts a measured placement to the shape the surface components consume. Sticky-eligible node * types are the ones `getSurfacePlacement` gave a `height` to. */ export var toMeasuredSurfaceWrapperPlacement = function toMeasuredSurfaceWrapperPlacement(placement) { return { isSticky: placement.height !== undefined, style: { height: placement.height, left: placement.left, top: placement.top, transform: placement.transform } }; }; /** * Where a surface goes when its anchor stops resolving, as the fallback argument to the block-axis * `anchor()` calls below. * * An anchor is invalid once its element stops generating a box e.g. (`display: none`) / removed node * Currently, anchor fallback is not unstable with some of the position-visibility options, so here * we manually set a fallback of -9999 so that it will render offscreen out of the viewport * without causing extra overflows */ var INVALID_ANCHOR_OFFSCREEN_PX = 9999; var INVALID_ANCHOR_FALLBACK_TOP = "-".concat(INVALID_ANCHOR_OFFSCREEN_PX, "px"); var INVALID_ANCHOR_FALLBACK_BOTTOM = "".concat(INVALID_ANCHOR_OFFSCREEN_PX, "px"); export var getAnchoredSurfacePlacement = function getAnchoredSurfacePlacement(_ref3) { var anchorName = _ref3.anchorName, layout = _ref3.layout, nodeType = _ref3.nodeType, nodeTypeWithLevel = _ref3.nodeTypeWithLevel, parentNodeType = _ref3.parentNodeType, side = _ref3.side; if (nodeType === 'layoutColumn') { // The column's horizontal midpoint, matching the measured `nodeRect.left + width / 2` and the // legacy drag handle's own layout-column formula. Side-independent. return { isSticky: false, style: { left: "calc((anchor(".concat(anchorName, " left) + anchor(").concat(anchorName, " right)) / 2)"), positionAnchor: anchorName, top: "anchor(".concat(anchorName, " top, ").concat(INVALID_ANCHOR_FALLBACK_TOP, ")"), transform: 'translate(-50%, -50%)' } }; } var gap = dragHandleGap(nodeType, parentNodeType); var isSticky = shouldBeSticky(nodeType); return { isSticky: isSticky, style: _objectSpread(_objectSpread({}, isSticky ? { bottom: "anchor(".concat(anchorName, " bottom, ").concat(INVALID_ANCHOR_FALLBACK_BOTTOM, ")") } : {}), {}, { left: side === 'right' ? "calc(anchor(".concat(anchorName, " right) + ").concat(gap, "px)") : "anchor(".concat(anchorName, " left)"), positionAnchor: anchorName, top: "calc(anchor(".concat(anchorName, " top, ").concat(INVALID_ANCHOR_FALLBACK_TOP, ") + ").concat(topPositionAdjustment(nodeTypeWithLevel, layout), "px)"), // The left side grows away from the node without knowing its own width, so it pulls itself // back past its own box and the gap. The right side grows into the margin, so the gap is // already folded into `left` above. transform: side === 'right' ? '' : "translateX(calc(-100% - ".concat(gap, "px))") }) }; };