@wordpress/block-editor
Version:
245 lines (239 loc) • 7.95 kB
JavaScript
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
;