@wordpress/block-editor
Version:
116 lines (115 loc) • 3.83 kB
JavaScript
// 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