UNPKG

@wordpress/block-editor

Version:
126 lines (117 loc) 5.03 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = useBlockSelection; var _a11y = require("@wordpress/a11y"); var _i18n = require("@wordpress/i18n"); var _data = require("@wordpress/data"); var _element = require("@wordpress/element"); var _keycodes = require("@wordpress/keycodes"); var _blocks = require("@wordpress/blocks"); var _store = require("../../store"); var _utils = require("./utils"); /** * WordPress dependencies */ /** * Internal dependencies */ function useBlockSelection() { const { clearSelectedBlock, multiSelect, selectBlock } = (0, _data.useDispatch)(_store.store); const { getBlockName, getBlockParents, getBlockSelectionStart, getSelectedBlockClientIds, hasMultiSelection, hasSelectedBlock } = (0, _data.useSelect)(_store.store); const { getBlockType } = (0, _data.useSelect)(_blocks.store); const updateBlockSelection = (0, _element.useCallback)(async (event, clientId, destinationClientId, focusPosition) => { if (!event?.shiftKey && event?.keyCode !== _keycodes.ESCAPE) { selectBlock(clientId, focusPosition); return; } // To handle multiple block selection via the `SHIFT` key, prevent // the browser default behavior of opening the link in a new window. event.preventDefault(); const isOnlyDeselection = event.type === 'keydown' && event.keyCode === _keycodes.ESCAPE; const isKeyPress = event.type === 'keydown' && (event.keyCode === _keycodes.UP || event.keyCode === _keycodes.DOWN || event.keyCode === _keycodes.HOME || event.keyCode === _keycodes.END); // Handle clicking on a block when no blocks are selected, and return early. if (!isKeyPress && !hasSelectedBlock() && !hasMultiSelection()) { selectBlock(clientId, null); return; } const selectedBlocks = getSelectedBlockClientIds(); const clientIdWithParents = [...getBlockParents(clientId), clientId]; if (isOnlyDeselection || isKeyPress && !selectedBlocks.some(blockId => clientIdWithParents.includes(blockId))) { // Ensure that shift-selecting blocks via the keyboard only // expands the current selection if focusing over already // selected blocks. Otherwise, clear the selection so that // a user can create a new selection entirely by keyboard. await clearSelectedBlock(); } // Update selection, if not only clearing the selection. if (!isOnlyDeselection) { let startTarget = getBlockSelectionStart(); let endTarget = clientId; // Handle keyboard behavior for selecting multiple blocks. if (isKeyPress) { if (!hasSelectedBlock() && !hasMultiSelection()) { // Set the starting point of the selection to the currently // focused block, if there are no blocks currently selected. // This ensures that as the selection is expanded or contracted, // the starting point of the selection is anchored to that block. startTarget = clientId; } if (destinationClientId) { // If the user presses UP or DOWN, we want to ensure that the block they're // moving to is the target for selection, and not the currently focused one. endTarget = destinationClientId; } } const startParents = getBlockParents(startTarget); const endParents = getBlockParents(endTarget); const { start, end } = (0, _utils.getCommonDepthClientIds)(startTarget, endTarget, startParents, endParents); await multiSelect(start, end, null); } // Announce deselected block, or number of deselected blocks if // the total number of blocks deselected is greater than one. const updatedSelectedBlocks = getSelectedBlockClientIds(); // If the selection is greater than 1 and the Home or End keys // were used to generate the selection, then skip announcing the // deselected blocks. if ((event.keyCode === _keycodes.HOME || event.keyCode === _keycodes.END) && updatedSelectedBlocks.length > 1) { return; } const selectionDiff = selectedBlocks.filter(blockId => !updatedSelectedBlocks.includes(blockId)); let label; if (selectionDiff.length === 1) { const title = getBlockType(getBlockName(selectionDiff[0]))?.title; if (title) { label = (0, _i18n.sprintf)(/* translators: %s: block name */ (0, _i18n.__)('%s deselected.'), title); } } else if (selectionDiff.length > 1) { label = (0, _i18n.sprintf)(/* translators: %s: number of deselected blocks */ (0, _i18n.__)('%s blocks deselected.'), selectionDiff.length); } if (label) { (0, _a11y.speak)(label, 'assertive'); } }, [clearSelectedBlock, getBlockName, getBlockType, getBlockParents, getBlockSelectionStart, getSelectedBlockClientIds, hasMultiSelection, hasSelectedBlock, multiSelect, selectBlock]); return { updateBlockSelection }; } //# sourceMappingURL=use-block-selection.js.map