UNPKG

@wordpress/block-editor

Version:
245 lines (239 loc) 7.95 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.InsertionPointOpenRef = void 0; exports.default = InsertionPoint; var _clsx = _interopRequireDefault(require("clsx")); var _data = require("@wordpress/data"); var _element = require("@wordpress/element"); var _components = require("@wordpress/components"); var _compose = require("@wordpress/compose"); var _inserter = _interopRequireDefault(require("../inserter")); var _store = require("../../store"); var _inbetween = _interopRequireDefault(require("../block-popover/inbetween")); var _dropZone = _interopRequireDefault(require("../block-popover/drop-zone")); var _lockUnlock = require("../../lock-unlock"); var _jsxRuntime = require("react/jsx-runtime"); /** * External dependencies */ /** * WordPress dependencies */ /** * Internal dependencies */ const InsertionPointOpenRef = exports.InsertionPointOpenRef = (0, _element.createContext)(); function InbetweenInsertionPointPopover({ __unstablePopoverSlot, __unstableContentRef, operation = 'insert', nearestSide = 'right' }) { const { selectBlock, hideInsertionPoint } = (0, _data.useDispatch)(_store.store); const openRef = (0, _element.useContext)(InsertionPointOpenRef); const ref = (0, _element.useRef)(); const { orientation, previousClientId, nextClientId, rootClientId, isInserterShown, isDistractionFree, isZoomOutMode } = (0, _data.useSelect)(select => { const { getBlockOrder, getBlockListSettings, getBlockInsertionPoint, isBlockBeingDragged, getPreviousBlockClientId, getNextBlockClientId, getSettings, isZoomOut } = (0, _lockUnlock.unlock)(select(_store.store)); const insertionPoint = getBlockInsertionPoint(); const order = getBlockOrder(insertionPoint.rootClientId); if (!order.length) { return {}; } let _previousClientId = order[insertionPoint.index - 1]; let _nextClientId = order[insertionPoint.index]; while (isBlockBeingDragged(_previousClientId)) { _previousClientId = getPreviousBlockClientId(_previousClientId); } while (isBlockBeingDragged(_nextClientId)) { _nextClientId = getNextBlockClientId(_nextClientId); } const settings = getSettings(); return { previousClientId: _previousClientId, nextClientId: _nextClientId, orientation: getBlockListSettings(insertionPoint.rootClientId)?.orientation || 'vertical', rootClientId: insertionPoint.rootClientId, isDistractionFree: settings.isDistractionFree, isInserterShown: insertionPoint?.__unstableWithInserter, isZoomOutMode: isZoomOut() }; }, []); const { getBlockEditingMode } = (0, _data.useSelect)(_store.store); const disableMotion = (0, _compose.useReducedMotion)(); function onClick(event) { if (event.target === ref.current && nextClientId && getBlockEditingMode(nextClientId) !== 'disabled') { selectBlock(nextClientId, -1); } } function maybeHideInserterPoint(event) { // Only hide the inserter if it's triggered on the wrapper, // and the inserter is not open. if (event.target === ref.current && !openRef.current) { hideInsertionPoint(); } } function onFocus(event) { // Only handle click on the wrapper specifically, and not an event // bubbled from the inserter itself. if (event.target !== ref.current) { openRef.current = true; } } const lineVariants = { // Initial position starts from the center and invisible. start: { opacity: 0, scale: 0 }, // The line expands to fill the container. If the inserter is visible it // is delayed so it appears orchestrated. rest: { opacity: 1, scale: 1, transition: { delay: isInserterShown ? 0.5 : 0, type: 'tween' } }, hover: { opacity: 1, scale: 1, transition: { delay: 0.5, type: 'tween' } } }; const inserterVariants = { start: { scale: disableMotion ? 1 : 0 }, rest: { scale: 1, transition: { delay: 0.4, type: 'tween' } } }; if (isDistractionFree) { return null; } // Zoom out mode should only show the insertion point for the insert operation. // Other operations such as "group" are when the editor tries to create a row // block by grouping the block being dragged with the block it's being dropped // onto. if (isZoomOutMode && operation !== 'insert') { return null; } const orientationClassname = orientation === 'horizontal' || operation === 'group' ? 'is-horizontal' : 'is-vertical'; const className = (0, _clsx.default)('block-editor-block-list__insertion-point', orientationClassname); return /*#__PURE__*/(0, _jsxRuntime.jsx)(_inbetween.default, { previousClientId: previousClientId, nextClientId: nextClientId, __unstablePopoverSlot: __unstablePopoverSlot, __unstableContentRef: __unstableContentRef, operation: operation, nearestSide: nearestSide, children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_components.__unstableMotion.div, { layout: !disableMotion, initial: disableMotion ? 'rest' : 'start', animate: "rest", whileHover: "hover", whileTap: "pressed", exit: "start", ref: ref, tabIndex: -1, onClick: onClick, onFocus: onFocus, className: (0, _clsx.default)(className, { 'is-with-inserter': isInserterShown }), onHoverEnd: maybeHideInserterPoint, children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_components.__unstableMotion.div, { variants: lineVariants, className: "block-editor-block-list__insertion-point-indicator", "data-testid": "block-list-insertion-point-indicator" }), isInserterShown && /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.__unstableMotion.div, { variants: inserterVariants, className: (0, _clsx.default)('block-editor-block-list__insertion-point-inserter'), children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_inserter.default, { position: "bottom center", clientId: nextClientId, rootClientId: rootClientId, __experimentalIsQuick: true, onToggle: isOpen => { openRef.current = isOpen; }, onSelectOrClose: () => { openRef.current = false; } }) })] }) }); } function InsertionPoint(props) { const { insertionPoint, isVisible, isBlockListEmpty } = (0, _data.useSelect)(select => { const { getBlockInsertionPoint, isBlockInsertionPointVisible, getBlockCount } = select(_store.store); const blockInsertionPoint = getBlockInsertionPoint(); return { insertionPoint: blockInsertionPoint, isVisible: isBlockInsertionPointVisible(), isBlockListEmpty: getBlockCount(blockInsertionPoint?.rootClientId) === 0 }; }, []); if (!isVisible || // Don't render the insertion point if the block list is empty. // The insertion point will be represented by the appender instead. isBlockListEmpty) { return null; } /** * Render a popover that overlays the block when the desired operation is to replace it. * Otherwise, render a popover in between blocks for the indication of inserting between them. */ return insertionPoint.operation === 'replace' ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_dropZone.default // Force remount to trigger the animation. , { ...props }, `${insertionPoint.rootClientId}-${insertionPoint.index}`) : /*#__PURE__*/(0, _jsxRuntime.jsx)(InbetweenInsertionPointPopover, { operation: insertionPoint.operation, nearestSide: insertionPoint.nearestSide, ...props }); } //# sourceMappingURL=insertion-point.js.map