@wordpress/editor
Version:
Enhanced block editor for WordPress posts.
87 lines (84 loc) • 2.65 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = useSelectNearestEditableBlock;
var _compose = require("@wordpress/compose");
var _data = require("@wordpress/data");
var _blockEditor = require("@wordpress/block-editor");
var _lockUnlock = require("../../lock-unlock");
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
const DISTANCE_THRESHOLD = 500;
function clamp(value, min, max) {
return Math.min(Math.max(value, min), max);
}
function distanceFromRect(x, y, rect) {
const dx = x - clamp(x, rect.left, rect.right);
const dy = y - clamp(y, rect.top, rect.bottom);
return Math.sqrt(dx * dx + dy * dy);
}
function useSelectNearestEditableBlock({
isEnabled = true
} = {}) {
const {
getEnabledClientIdsTree,
getBlockName,
getBlockOrder
} = (0, _lockUnlock.unlock)((0, _data.useSelect)(_blockEditor.store));
const {
selectBlock
} = (0, _data.useDispatch)(_blockEditor.store);
return (0, _compose.useRefEffect)(element => {
if (!isEnabled) {
return;
}
const selectNearestEditableBlock = (x, y) => {
const editableBlockClientIds = getEnabledClientIdsTree().flatMap(({
clientId
}) => {
const blockName = getBlockName(clientId);
if (blockName === 'core/template-part') {
return [];
}
if (blockName === 'core/post-content') {
const innerBlocks = getBlockOrder(clientId);
if (innerBlocks.length) {
return innerBlocks;
}
}
return [clientId];
});
let nearestDistance = Infinity,
nearestClientId = null;
for (const clientId of editableBlockClientIds) {
const block = element.querySelector(`[data-block="${clientId}"]`);
if (!block) {
continue;
}
const rect = block.getBoundingClientRect();
const distance = distanceFromRect(x, y, rect);
if (distance < nearestDistance && distance < DISTANCE_THRESHOLD) {
nearestDistance = distance;
nearestClientId = clientId;
}
}
if (nearestClientId) {
selectBlock(nearestClientId);
}
};
const handleClick = event => {
const shouldSelect = event.target === element || event.target.classList.contains('is-root-container');
if (shouldSelect) {
selectNearestEditableBlock(event.clientX, event.clientY);
}
};
element.addEventListener('click', handleClick);
return () => element.removeEventListener('click', handleClick);
}, [isEnabled]);
}
//# sourceMappingURL=use-select-nearest-editable-block.js.map