UNPKG

@wordpress/block-editor

Version:
170 lines (161 loc) 5.17 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.DEFAULT_BLOCK_LIST_CONTEXT = exports.BlockListProvider = exports.BlockListConsumer = void 0; exports.deleteBlockLayoutByClientId = deleteBlockLayoutByClientId; exports.useBlockListContext = void 0; var _element = require("@wordpress/element"); var _sorting = require("../../utils/sorting"); /** * WordPress dependencies */ /** * Internal dependencies */ const DEFAULT_BLOCK_LIST_CONTEXT = exports.DEFAULT_BLOCK_LIST_CONTEXT = { scrollRef: null, blocksLayouts: { current: {} }, findBlockLayoutByClientId, getBlockLayoutsOrderedByYCoord, findBlockLayoutByPosition, updateBlocksLayouts }; const Context = (0, _element.createContext)(DEFAULT_BLOCK_LIST_CONTEXT); const { Provider, Consumer } = Context; /** * Finds a block's layout data by position. * * @param {Object} data Blocks layouts object. * @param {Object} position Position to use for finding the block. * @param {number} position.x X coordinate. * @param {number} position.y Y coordinate. * * @return {Object|undefined} Found block layout data that matches the provided position. If none is found, `undefined` will be returned. */ exports.BlockListConsumer = Consumer; exports.BlockListProvider = Provider; function findBlockLayoutByPosition(data, position) { // Only enabled for root level blocks return Object.values(data).find(block => { return position.x >= block.x && position.x <= block.x + block.width && position.y >= block.y && position.y <= block.y + block.height; }); } /** * Finds a block's layout data by its client Id. * * @param {Object} data Blocks layouts object. * @param {string} clientId Block's clientId. * * @return {Object} Found block layout data. */ function findBlockLayoutByClientId(data, clientId) { return Object.entries(data).reduce((acc, entry) => { const item = entry[1]; if (acc) { return acc; } if (item?.clientId === clientId) { return item; } if (item?.innerBlocks && Object.keys(item.innerBlocks).length > 0) { return findBlockLayoutByClientId(item.innerBlocks, clientId); } return null; }, null); } /** * Deletes the layout data of a block by its client Id. * * @param {Object} data Blocks layouts object. * @param {string} clientId Block's clientsId. * * @return {Object} Updated data object. */ function deleteBlockLayoutByClientId(data, clientId) { return Object.keys(data).reduce((acc, key) => { if (key !== clientId) { acc[key] = data[key]; } if (data[key]?.innerBlocks && Object.keys(data[key].innerBlocks).length > 0) { if (acc[key]) { acc[key].innerBlocks = deleteBlockLayoutByClientId(data[key].innerBlocks, clientId); } } return acc; }, {}); } /** * Orders the block's layout data by its Y coordinate. * * @param {Object} data Blocks layouts object. * * @return {Object} Blocks layouts object ordered by its Y coordinate. */ function getBlockLayoutsOrderedByYCoord(data) { // Only enabled for root level blocks. return (0, _sorting.orderBy)(Object.values(data), 'y'); } /** * Updates or deletes a block's layout data in the blocksLayouts object, * in case of deletion, the layout data is not required. * * @param {Object} blocksLayouts Blocks layouts object. * @param {Object} blockData Block's layout data to add or remove to/from the blockLayouts object. * @param {string} blockData.clientId Block's clientId. * @param {?string} blockData.rootClientId Optional. Block's rootClientId. * @param {?boolean} blockData.shouldRemove Optional. Flag to remove it from the blocksLayout list. * @param {number} blockData.width Block's width. * @param {number} blockData.height Block's height. * @param {number} blockData.x Block's x coordinate (relative to the parent). * @param {number} blockData.y Block's y coordinate (relative to the parent). */ function updateBlocksLayouts(blocksLayouts, blockData) { const { clientId, rootClientId, shouldRemove, ...layoutProps } = blockData; if (clientId && shouldRemove) { blocksLayouts.current = deleteBlockLayoutByClientId(blocksLayouts.current, clientId); return; } if (clientId && !rootClientId) { blocksLayouts.current[clientId] = { clientId, rootClientId, ...layoutProps, innerBlocks: { ...blocksLayouts.current[clientId]?.innerBlocks } }; } else if (clientId && rootClientId) { const block = findBlockLayoutByClientId(blocksLayouts.current, rootClientId); if (block) { block.innerBlocks[clientId] = { clientId, rootClientId, ...layoutProps, innerBlocks: { ...block.innerBlocks[clientId]?.innerBlocks } }; } } } /** * Hook that returns the block list context. * * @return {Object} Block list context */ const useBlockListContext = () => { return (0, _element.useContext)(Context); }; exports.useBlockListContext = useBlockListContext; //# sourceMappingURL=block-list-context.native.js.map