-
Notifications
You must be signed in to change notification settings - Fork 4.8k
List View: Add multi-select behaviour for blocks when shift key is selected #38314
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 1 commit
Commits
Show all changes
24 commits
Select commit
Hold shift + click to select a range
8749179
List View: Add multi-select behaviour when shift key is selected
andrewserong 4e75817
Ensure shift clicking a block when no blocks are selected selects tha…
andrewserong cfba501
Add support for dragging multiple selected blocks
andrewserong 51376c5
Remove duplication by moving multi-select behaviour to the ListView c…
andrewserong d2fd70d
Add inline comments
andrewserong b6bb2db
Update documentation, add changelog entry
andrewserong 06c731c
Add e2e test for multi-select in the list view
andrewserong edcff8b
Remove stray line from changelog
andrewserong 1362dba
Ensure that clicked on blocks that aren't a part of a selection can s…
andrewserong 74602ca
Try a naive approach to keyboard handling for shift + up/down to sele…
andrewserong 62f32e4
Move block selection to its own useBlockSelection hook
andrewserong 8fbb905
Refactor start and end id calculation to its own function, add unit t…
andrewserong 999568e
Move utility function to utils file, add doc comment, update usage
andrewserong d884e0e
Update multiSelect behavior to support keeping focus within the ListV…
andrewserong 27d63bc
Update unit tests, add additional e2e test for keyboard behaviour
andrewserong c5853bc
Revert change to focus for when shift key is not held
andrewserong 6cb4fb3
Defer calculation of the next/prev clientId to the TreeGrid component…
andrewserong 38b0e5b
Update initialPosition param to be experimental
andrewserong 025087f
Update TreeGrid readme with documentation for the three callback func…
andrewserong c3b6a1e
Add changelog entry
andrewserong b321851
Pass in selectedClientIds to dropdown
andrewserong db31ffd
Prevent shift+click on expand toggle from opening a new window
andrewserong 4f0e0bb
Try announcing deselected blocks
andrewserong 5511896
Rename onChangeRow to onFocusRow, update changelog entry
andrewserong File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Move block selection to its own useBlockSelection hook
- Loading branch information
commit 62f32e442a0ef6ef54b10459c08e030089ee4595
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
89 changes: 89 additions & 0 deletions
89
packages/block-editor/src/components/list-view/use-block-selection.js
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,89 @@ | ||
| /** | ||
| * WordPress dependencies | ||
| */ | ||
| import { useDispatch, useSelect } from '@wordpress/data'; | ||
| import { useCallback } from '@wordpress/element'; | ||
|
|
||
| /** | ||
| * Internal dependencies | ||
| */ | ||
| import { store as blockEditorStore } from '../../store'; | ||
|
|
||
| export default function useBlockSelection() { | ||
| const { clearSelectedBlock, multiSelect, selectBlock } = useDispatch( | ||
| blockEditorStore | ||
| ); | ||
| const { | ||
| getBlockParents, | ||
| getBlockSelectionStart, | ||
| hasMultiSelection, | ||
| hasSelectedBlock, | ||
| } = useSelect( blockEditorStore ); | ||
|
|
||
| const updateBlockSelection = useCallback( | ||
| async ( clientId, event ) => { | ||
| if ( ! event.shiftKey || event.type === 'keydown' ) { | ||
| // When this function is called from a 'keydown' event, select | ||
| // the block as if it were individually clicked. This allows | ||
| // the editor canvas to be responsible for the shift + up/down | ||
| // multiple block selection behaviour. | ||
| await clearSelectedBlock(); | ||
| selectBlock( clientId, -1 ); | ||
| } else if ( event.shiftKey ) { | ||
| // To handle multiple block selection via the `SHIFT` key, prevent | ||
| // the browser default behavior of opening the link in a new window. | ||
| event.preventDefault(); | ||
|
|
||
| // Select a single block if no block is selected yet. | ||
| if ( ! hasSelectedBlock() && ! hasMultiSelection() ) { | ||
| selectBlock( clientId, -1 ); | ||
| return; | ||
| } | ||
|
|
||
| const blockSelectionStart = getBlockSelectionStart(); | ||
|
|
||
| // By checking `blockSelectionStart` to be set, we handle the | ||
| // case where we select a single block. We also have to check | ||
| // the selectionEnd (clientId) not to be included in the | ||
| // `blockSelectionStart`'s parents because the click event is | ||
| // propagated. | ||
| const startParents = getBlockParents( blockSelectionStart ); | ||
|
|
||
| if ( | ||
| blockSelectionStart && | ||
| blockSelectionStart !== clientId && | ||
| ! startParents?.includes( clientId ) | ||
| ) { | ||
| const startPath = [ ...startParents, blockSelectionStart ]; | ||
| const endPath = [ | ||
| ...getBlockParents( clientId ), | ||
| clientId, | ||
| ]; | ||
| const depth = | ||
| Math.min( startPath.length, endPath.length ) - 1; | ||
| const start = startPath[ depth ]; | ||
| const end = endPath[ depth ]; | ||
|
|
||
| // Handle the case of having selected a parent block and | ||
| // then shift+click on a child. | ||
| if ( start !== end ) { | ||
| multiSelect( start, end ); | ||
| } | ||
| } | ||
| } | ||
| }, | ||
| [ | ||
| clearSelectedBlock, | ||
| getBlockParents, | ||
| getBlockSelectionStart, | ||
| hasMultiSelection, | ||
| hasSelectedBlock, | ||
| multiSelect, | ||
| selectBlock, | ||
| ] | ||
| ); | ||
|
|
||
| return { | ||
| updateBlockSelection, | ||
| }; | ||
| } |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.