Skip to content
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

Support non-consecutive block multi-selection #16811

Draft
wants to merge 18 commits into
base: master
from

Conversation

@swissspidy
Copy link
Member

commented Jul 30, 2019

Description

This implements a new feature that allows selecting multiple, non-consecutive blocks by CMD+clicking on them.

Fixes #16797.

How has this been tested?

Existing tests have been updated for this enhancement. No E2E tests have been added yet, but that's on my todo list.

Screenshots

Screenshot 2019-07-30 at 14 37 28

Types of changes

New feature (non-breaking change which adds functionality)

The existing selectors and actions keep their functionality. Just the way the block selection information is stored under the hood has changed.

Checklist:

  • My code is tested.
  • My code follows the WordPress code style.
  • My code follows the accessibility standards.
  • My code has proper inline documentation.
  • I've included developer documentation if appropriate.

swissspidy added some commits Jul 30, 2019

swissspidy added some commits Jul 30, 2019

@swissspidy

This comment has been minimized.

Copy link
Member Author

commented Jul 30, 2019

The current E2E test failures seem to be:

@ellatrix

This comment has been minimized.

Copy link
Member

commented Aug 1, 2019

Great work on exploring this! :)

I think this will need a lot of thought both in terms of UI and data. There's several things that we want multi-selection to do, so it's worth to think a bit about how all these pieces will come together.

The two main things that we seem to want in terms of user experience is:

  • Non-consecutive selection
  • Cross-block text selection

The latter has been on and off the table a few times now, and so far we haven't implemented it, which makes me question its usefulness. Do users really want to select text across blocks? #3629 has had little traction, and personally, I've also not heard of many people having problems with it.

Sure, cross-block selection would be nice, but is it really necessary? We've been half-joking since the start of Gutenberg that, if you need cross-block selection, you're probably not structuring your paragraphs right. 😁

Wether or not we implement cross-block selection is important for non-consecutive selection, as I think they're pulling the way we handle selection is two different directions, both of which could coexist, but need to take one another into account.

On the one hand you'd have "smooth" native text selection, where we don't need to visualise anything, perhaps only a border around the blocks that contain it. This would work different from how it works today -- we set a blue background for the selected blocks. Using native selection would also be better for accessibility (the browser can set the best colour, and it's adjustable).

On the other hand you'd have non-consecutive selection, where we would have to visualise the selected blocks. We cannot set any native selection as most browsers do not support multiple selections. This may be fine. We could use native selection for consecutive selection, and our own way of visualising the selection otherwise. Perhaps even avoid a background altogether and use only a border and checkmarks.

But if we don't ever want to pursue cross-block text selection, we probably don't need two ways to visualise the selection, so it's good to think about what we want beforehand?

Similarly, it's important to get the data structure right. Currently we assume consecutive selection with room for cross-block selection:

blockSelection ( state = {
  start: { clientId, attributeKey, offset },
  end: { clientId, attributeKey, offset },
} )

We don't currently have any cases where you can have an attributeKey and an offset, with a different clientId, but the data structure accommodates cross-block text selection if we want it.

If we introduce non-consecutive selection, do we only want non-consecutive block selection, or might we want non-consecutive text selection as well at some point in the future?

Non-consecutive block selection only:

singleBlockSelection( state = { clientId, attributeKey, offset } )
multiBlockSelection( state = [ ...clientIds ] )

Non-consecutive text selection:

selections = [
  {
    start: { clientId, attributeKey, offset },
    end: { clientId, attributeKey, offset },
  },
  ...
]
blockSelection( state = [ ...selections ] )

That's rather complex. :D

Only cross-block selection and non-consecutive block selection:

blockSelection ( state = {
  start: { clientId, attributeKey, offset }, // Not set in case of non consecutive selection.
  end: { clientId, attributeKey, offset },
  blocks: [ ...clientIds ],
} )

Would appreciate everyone's thoughts! :)

@senadir

This comment has been minimized.

Copy link
Contributor

commented Aug 3, 2019

from the previous core editor meetup, @matias asked:

How would it handle “moving” once you select a bunch of non-consecutive blocks?

this require feedback both from a technical perspective & a design perspective, so I'm creating an issue (#16895) that opens a discussion on this design wise

@swissspidy

This comment has been minimized.

Copy link
Member Author

commented Aug 5, 2019

@ellatrix Great question!

This has been briefly brought up in #16797. For an initial PoC I went with a very simple format.

The two main things that we seem to want in terms of user experience is:

  • Non-consecutive selection
  • Cross-block text selection

I perceived it as odd that these two things are tied together in state (with start and end used for both text selection and multi-selection), and I wondered whether they couldn't be treated separately.

Sure, cross-block selection would be nice, but is it really necessary? We've been half-joking since the start of Gutenberg that, if you need cross-block selection, you're probably not structuring your paragraphs right.

I think such a feature would be very useful. Has there been any feedback about this from user testing? Personally, when I realize during writing that I want to delete the last two sentences cross-block, it's very annoying that I have to do this in two steps (because otherwise Gutenberg multi-selects both of the blocks).

If we go with the more complex data structure, it allows us to more easily implement multi-text selection in the future.

@ellatrix

This comment has been minimized.

Copy link
Member

commented Aug 7, 2019

I perceived it as odd that these two things are tied together in state (with start and end used for both text selection and multi-selection), and I wondered whether they couldn't be treated separately.

After talking to @matias, we both believe that consecutive selection and non-consecutive selection are two different types of selection. These should each have their own reducer, as one doesn't really go well with the other, both in terms of data and (future) UI. It's totally fine to have these two separated. You can see them as two different selection models that complement each other. It will be much simpler to implement them separately as they will both complicate each other more into something much, much more complex.

@swissspidy swissspidy self-assigned this Aug 9, 2019

swissspidy added some commits Aug 9, 2019

swissspidy added some commits Aug 16, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
3 participants
You can’t perform that action at this time.