Open swissspidy opened 5 years ago
I've been thinking about a similar problem in the table block, where you also expect to be able to multi-select cells. At the moment individual cells can only be selected. Similar sort of problem here, except blocks already support ranges of selections.
The solution I had in mind is a fairly obvious one, using an array to build up a list of the different selections. The existing 'range' object becomes the data used in an individual element of the array, so it should be possible to reuse some of the logic:
const selections = [
{
start: { clientId, ... },
end: { clientId, ... },
},
{
start: { clientId, ... },
end: { clientId, ... },
}
]
The idea then is that you can reduce the array to work out whether something is selected.
There are some little edge cases though. For example, a user might select a range by shift-clicking and then deselect one of the blocks in the middle by command clicking.
As blocks are stored sequentially, some splitting and merging logic when adding selections would possibly be the way to go. Another option is to add an object that represents a 'deselection' to the array.
Could another option be to store a list of all the selected client IDs or would that take up too much space?
Yeah, that's also definitely an option. Could do an array slice on state.blocks.order
to build up a list for range selections.
FYI there's now a work-in-progress PR at #16811 that uses one big array of client IDs. Seemed the easiest solution to implement as a proof-of-concept. There's only some edge cases to address.
There was a good question from today's #core-editor meeting (source):
How would it handle “moving” once you select a bunch of non-consecutive blocks?
One suggestion was:
I think they could collapse before the last selected element, so any non selected element between them will move up the selected list, it makes sense when refactoring sides of the articles to different sections
Also another good thing to keep in mind:
My main thoughs at the moment is around all these places where we just assumed a sequential list of blocks for multiselection. start/end in the state are the obvious one but I feel we have more hidden places with that assumption.
I have something similar situation in which I want to manage the styling of similar blocks.
Instead of creating new issue added below comments.
The situation is described as below:
Now, If user want to change the colors & other settings then I'm thinning to provide such option in which user can bulk select the blocks and change selected block (similar selected blocks) to change the colors & other settings.
I think I need to do this by adding some custom solution. Or It is good to add SlotFills
in <MultiSelectionInspector>
Screenshot for reference:
I'm still experimenting things in the Gutenberg. So, Instead of creating new task added above comments here.
+1, it would be really great to have something like PluginMultiBlockControls
and PluginMultiInspectorControls
(perhaps behind an __experimental
for now) . i'm working on a plugin to edit multiple blocks at once (see #8743) and i have to render my own popover toolbar and do all sorts of ugly stuff because right now the standard contextual toolbar hides all controls during a multiselection (except for the builtin "convert" button).
Here are some of the images from that now closed issue: moving down:
moving up (fixed version):
👆 my linked ticket was a duplicate.
IDK why I was still assigned here. This isn't a focus for me anymore.
Someone else might want to pick up the ideas from #16811 and attempt this again, but a lot has changed in the last few years, so... 🤷
Is your feature request related to a problem? Please describe.
We are currently facing a situation where we need to be able to select multiple non-consecutive blocks to then perform a bulk action on them (e.g. remove, copy, move up/down, etc.).
However, in Gutenberg multi-selection is really designed for selecting a range of blocks from start to end, not a loose list of blocks that could be all over the place.
Examples in the code:
https://github.com/WordPress/gutenberg/blob/1b5fc6a593581bfe1ee75128f0d05c154c4b8fdf/packages/block-editor/src/store/selectors.js#L538-L598
https://github.com/WordPress/gutenberg/blob/1b5fc6a593581bfe1ee75128f0d05c154c4b8fdf/packages/block-editor/src/store/selectors.js#L313-L337
https://github.com/WordPress/gutenberg/blob/1b5fc6a593581bfe1ee75128f0d05c154c4b8fdf/packages/block-editor/src/store/actions.js#L157-L193
Describe the solution you'd like
I think the resolvers under the hood could be re-written in a way that multi-selection would store the actual list of items in an array, and not start and end values. This would allow plugins to perform this non-consecutive multi-selection on their own.
I think this could be done in a backward-compatible way.
In a next step, we could think about how to expose this feature in the Gutenberg UI itself. For example, in our plugin we were thinking about allowing CMD+clicking on individual blocks to mark them as selected.
Describe alternatives you've considered
I looked into rolling our own implementation for this in our plugin, but it's not really doable. The multi-selection block toolbar and sidebar all rely on the built-in selectors like
getMultiSelectedBlocks()
,getMultiSelectedBlockClientIds()
, andgetSelectedBlockClientIds()
.