UNPKG

@wordpress/block-editor

Version:
187 lines (178 loc) 8.91 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.focusListItem = focusListItem; exports.getBlockPropertiesDescription = exports.getBlockPositionDescription = void 0; exports.getCommonDepthClientIds = getCommonDepthClientIds; exports.getDragDisplacementValues = getDragDisplacementValues; exports.isClientIdSelected = void 0; var _i18n = require("@wordpress/i18n"); var _dom = require("@wordpress/dom"); /** * WordPress dependencies */ const getBlockPositionDescription = (position, siblingCount, level) => (0, _i18n.sprintf)(/* translators: 1: The numerical position of the block. 2: The total number of blocks. 3. The level of nesting for the block. */ (0, _i18n.__)('Block %1$d of %2$d, Level %3$d.'), position, siblingCount, level); exports.getBlockPositionDescription = getBlockPositionDescription; const getBlockPropertiesDescription = (blockInformation, isLocked) => [blockInformation?.positionLabel ? `${(0, _i18n.sprintf)( // translators: %s: Position of selected block, e.g. "Sticky" or "Fixed". (0, _i18n.__)('Position: %s'), blockInformation.positionLabel)}.` : undefined, isLocked ? (0, _i18n.__)('This block is locked.') : undefined].filter(Boolean).join(' '); /** * Returns true if the client ID occurs within the block selection or multi-selection, * or false otherwise. * * @param {string} clientId Block client ID. * @param {string|string[]} selectedBlockClientIds Selected block client ID, or an array of multi-selected blocks client IDs. * * @return {boolean} Whether the block is in multi-selection set. */ exports.getBlockPropertiesDescription = getBlockPropertiesDescription; const isClientIdSelected = (clientId, selectedBlockClientIds) => Array.isArray(selectedBlockClientIds) && selectedBlockClientIds.length ? selectedBlockClientIds.indexOf(clientId) !== -1 : selectedBlockClientIds === clientId; /** * From a start and end clientId of potentially different nesting levels, * return the nearest-depth ids that have a common level of depth in the * nesting hierarchy. For multiple block selection, this ensure that the * selection is always at the same nesting level, and not split across * separate levels. * * @param {string} startId The first id of a selection. * @param {string} endId The end id of a selection, usually one that has been clicked on. * @param {string[]} startParents An array of ancestor ids for the start id, in descending order. * @param {string[]} endParents An array of ancestor ids for the end id, in descending order. * @return {Object} An object containing the start and end ids. */ exports.isClientIdSelected = isClientIdSelected; function getCommonDepthClientIds(startId, endId, startParents, endParents) { const startPath = [...startParents, startId]; const endPath = [...endParents, endId]; const depth = Math.min(startPath.length, endPath.length) - 1; const start = startPath[depth]; const end = endPath[depth]; return { start, end }; } /** * Shift focus to the list view item associated with a particular clientId. * * @typedef {import('@wordpress/element').RefObject} RefObject * * @param {string} focusClientId The client ID of the block to focus. * @param {?HTMLElement} treeGridElement The container element to search within. */ function focusListItem(focusClientId, treeGridElement) { const getFocusElement = () => { const row = treeGridElement?.querySelector(`[role=row][data-block="${focusClientId}"]`); if (!row) { return null; } // Focus the first focusable in the row, which is the ListViewBlockSelectButton. return _dom.focus.focusable.find(row)[0]; }; let focusElement = getFocusElement(); if (focusElement) { focusElement.focus(); } else { // The element hasn't been painted yet. Defer focusing on the next frame. // This could happen when all blocks have been deleted and the default block // hasn't been added to the editor yet. window.requestAnimationFrame(() => { focusElement = getFocusElement(); // Ignore if the element still doesn't exist. if (focusElement) { focusElement.focus(); } }); } } /** * Get values for the block that flag whether the block should be displaced up or down, * whether the block is being nested, and whether the block appears after the dragged * blocks. These values are used to determine the class names to apply to the block. * The list view rows are displaced visually via CSS rules. Displacement rules: * - `normal`: no displacement — used to apply a translateY of `0` so that the block * appears in its original position, and moves to that position smoothly when dragging * outside of the list view area. * - `up`: the block should be displaced up, creating room beneath the block for the drop indicator. * - `down`: the block should be displaced down, creating room above the block for the drop indicator. * * @param {Object} props * @param {Object} props.blockIndexes The indexes of all the blocks in the list view, keyed by clientId. * @param {number|null|undefined} props.blockDropTargetIndex The index of the block that the user is dropping to. * @param {?string} props.blockDropPosition The position relative to the block that the user is dropping to. * @param {string} props.clientId The client id for the current block. * @param {?number} props.firstDraggedBlockIndex The index of the first dragged block. * @param {?boolean} props.isDragged Whether the current block is being dragged. Dragged blocks skip displacement. * @return {Object} An object containing the `displacement`, `isAfterDraggedBlocks` and `isNesting` values. */ function getDragDisplacementValues({ blockIndexes, blockDropTargetIndex, blockDropPosition, clientId, firstDraggedBlockIndex, isDragged }) { let displacement; let isNesting; let isAfterDraggedBlocks; if (!isDragged) { isNesting = false; const thisBlockIndex = blockIndexes[clientId]; isAfterDraggedBlocks = thisBlockIndex > firstDraggedBlockIndex; // Determine where to displace the position of the current block, relative // to the blocks being dragged (in their original position) and the drop target // (the position where a user is currently dragging the blocks to). if (blockDropTargetIndex !== undefined && blockDropTargetIndex !== null && firstDraggedBlockIndex !== undefined) { // If the block is being dragged and there is a valid drop target, // determine if the block being rendered should be displaced up or down. if (thisBlockIndex !== undefined) { if (thisBlockIndex >= firstDraggedBlockIndex && thisBlockIndex < blockDropTargetIndex) { // If the current block appears after the set of dragged blocks // (in their original position), but is before the drop target, // then the current block should be displaced up. displacement = 'up'; } else if (thisBlockIndex < firstDraggedBlockIndex && thisBlockIndex >= blockDropTargetIndex) { // If the current block appears before the set of dragged blocks // (in their original position), but is after the drop target, // then the current block should be displaced down. displacement = 'down'; } else { displacement = 'normal'; } isNesting = typeof blockDropTargetIndex === 'number' && blockDropTargetIndex - 1 === thisBlockIndex && blockDropPosition === 'inside'; } } else if (blockDropTargetIndex === null && firstDraggedBlockIndex !== undefined) { // A `null` value for `blockDropTargetIndex` indicates that the // drop target is outside of the valid areas within the list view. // In this case, the drag is still active, but as there is no // valid drop target, we should remove the gap indicating where // the block would be inserted. if (thisBlockIndex !== undefined && thisBlockIndex >= firstDraggedBlockIndex) { displacement = 'up'; } else { displacement = 'normal'; } } else if (blockDropTargetIndex !== undefined && blockDropTargetIndex !== null && firstDraggedBlockIndex === undefined) { // If the blockdrop target is defined, but there are no dragged blocks, // then the block should be displaced relative to the drop target. if (thisBlockIndex !== undefined) { if (thisBlockIndex < blockDropTargetIndex) { displacement = 'normal'; } else { displacement = 'down'; } } } else if (blockDropTargetIndex === null) { displacement = 'normal'; } } return { displacement, isNesting, isAfterDraggedBlocks }; } //# sourceMappingURL=utils.js.map