UNPKG

@wordpress/block-editor

Version:
116 lines (115 loc) 3.83 kB
// packages/block-editor/src/components/list-view/use-block-selection.js import { speak } from "@wordpress/a11y"; import { __, sprintf } from "@wordpress/i18n"; import { useDispatch, useSelect } from "@wordpress/data"; import { useCallback } from "@wordpress/element"; import { UP, DOWN, HOME, END, ESCAPE } from "@wordpress/keycodes"; import { store as blocksStore } from "@wordpress/blocks"; import { store as blockEditorStore } from "../../store"; import { getCommonDepthClientIds } from "./utils"; function useBlockSelection() { const { clearSelectedBlock, multiSelect, selectBlock } = useDispatch(blockEditorStore); const { getBlockName, getBlockParents, getBlockSelectionStart, getSelectedBlockClientIds, hasMultiSelection, hasSelectedBlock } = useSelect(blockEditorStore); const { getBlockType } = useSelect(blocksStore); const updateBlockSelection = useCallback( async (event, clientId, destinationClientId, focusPosition) => { if (!event?.shiftKey && event?.keyCode !== ESCAPE) { selectBlock(clientId, focusPosition); return; } event.preventDefault(); const isOnlyDeselection = event.type === "keydown" && event.keyCode === ESCAPE; const isKeyPress = event.type === "keydown" && (event.keyCode === UP || event.keyCode === DOWN || event.keyCode === HOME || event.keyCode === END); 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) )) { await clearSelectedBlock(); } if (!isOnlyDeselection) { let startTarget = getBlockSelectionStart(); let endTarget = clientId; if (isKeyPress) { if (!hasSelectedBlock() && !hasMultiSelection()) { startTarget = clientId; } if (destinationClientId) { endTarget = destinationClientId; } } const startParents = getBlockParents(startTarget); const endParents = getBlockParents(endTarget); const { start, end } = getCommonDepthClientIds( startTarget, endTarget, startParents, endParents ); await multiSelect(start, end, null); } const updatedSelectedBlocks = getSelectedBlockClientIds(); if ((event.keyCode === HOME || event.keyCode === 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 = sprintf( /* translators: %s: block name */ __("%s deselected."), title ); } } else if (selectionDiff.length > 1) { label = sprintf( /* translators: %s: number of deselected blocks */ __("%s blocks deselected."), selectionDiff.length ); } if (label) { speak(label, "assertive"); } }, [ clearSelectedBlock, getBlockName, getBlockType, getBlockParents, getBlockSelectionStart, getSelectedBlockClientIds, hasMultiSelection, hasSelectedBlock, multiSelect, selectBlock ] ); return { updateBlockSelection }; } export { useBlockSelection as default }; //# sourceMappingURL=use-block-selection.js.map