@wordpress/block-editor
Version:
126 lines (117 loc) • 5.03 kB
JavaScript
;
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