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

Experimenting with navigation and edit modes #3195

Closed
wants to merge 8 commits into from

Conversation

ephox-mogran
Copy link
Contributor

@ephox-mogran ephox-mogran commented Oct 27, 2017

Description

Exploring #2031
First stage of trying to have a navigation and edit mode. Work in progress. Hacky code.

  • Pressing ESC moves to navigation mode if you are in the editor
  • Pressing ENTER goes into the editor if you are in navigation mode

How Has This Been Tested?

Just manually tested. No automated tests.

Screenshots (jpeg or gifs if applicable):

Types of changes

  • Changed the redux state for focus

Checklist:

  • My code is tested.
  • My code follows the WordPress code style.
  • My code follows has proper inline documentation.
  • My code makes the toolbar reappear if there is a selection
  • My code does not use magic strings

Uses cases from Issue:

  • There are three paragraphs. You set the caret in the first, select downwards. Once you select text to the edge of the first paragraph, and press down again, you select at the block level. This enters navigation mode, and you now have the first two paragraphs selected. You can now use the direct shortcut to turn this into a list, or tab into the ellipsis to pick that option from the menu.
  • You wrote a post with paragraph, image, paragraph, image, paragraph, image, and decide that you'd rather have the three images be a gallery. Your caret is in the text. You press Escape to enter navigation mode, move the highlight to the first image using the arrowkeys, press Space to select it, move to the next image, and the last. You now have the 2nd, 4th and 6th blocks selected, and you tab into the ellipsis menu, pick "Turn into >" and pick "Gallery".
  • You just wrote 8 paragraphs, realize it's all crap and want to delete it. You press ⌘A to select all text in the paragraph you're in, you press ⌘A again to now select all blocks, and you press Delete or Backspace to remove it. Blank slate.
  • You wrote a big post with text, a gallery, some images, and a quote. You use the mouse to click on the first big image — this shows the quick toolbar (as you're still in edit mode), and you click the full-wide option. You then click the gallery and make it wide, and you right-float the quote. You never entered navigation mode.
  • You wrote a big post, same as above — text, gallery, some images and a quote. You press escape to enter navigation mode, up-arrow to the first big image, press Enter to edit it, press ⌘ (or our enter quick toolbar meta key whatever it ends up being), arrow-key to full-wide, and pick it. You press Escape again to enter navigation mode, move down to the gallery, do the same dance and set it to wide.
  • You set focus on the title field, type a title, press Tab to move to the first block. You could've used the arrow key, or you could've pressed Enter, but you like tabbing, and because you're in edit mode, you just moved between text fields.

@ephox-mogran ephox-mogran added [Focus] Accessibility (a11y) Changes that impact accessibility and need corresponding review (e.g. markup changes). [Status] Horrible Hack [Status] In Progress Tracking issues with work in progress labels Oct 27, 2017
@ephox-mogran ephox-mogran added this to the Beta 1.6 milestone Oct 27, 2017
@jasmussen
Copy link
Contributor

jasmussen commented Oct 27, 2017

Nice experiment. Overall it seems like the gist of the idea is right. When you are typing or editing or interacting, which should be most of the time, you never see this.

Pressing Esc enters navigation mode and you can arrow key across blocks. Enter should be same as a mouse click on the selected block, to enter edit mode again. So far so good.

There are a couple of bugs and little things probably not worth mentioning since it's experimental (navigation mode exits if you press down at the end of the last block, enter on a placeholder block doesn't do the same as a click on it). We'll also want to make sure that the implementation can address the use cases suggested here.

But from testing this branch as an incomplete prototype, I do very much get the feeling that this interaction method adds value! I would encourage @mtias, @karmatosed, @afercia and others to test this out.

For full implementation, we'd likely want to wait for the docked toolbar, multi select improvements, and keyboard selection improvements to land in master and stabilize, so we have the right base ingredients to work with.

@afercia
Copy link
Contributor

afercia commented Oct 27, 2017

Tested a bit and I also have the same feeling: this interaction model makes things predictable and easier for keyboard users. Enter/Escape are pretty intuitive, navigation works pretty nicely.

I think also Tab should navigate through blocks. I've always imagined tabbing as the primary action for navigation.

Tested a bit with Safari/VoiceOver and totally like the way blocks are announced in navigation mode (screen readers will read out the blocks aria-label). This would be of fundamental importance for screen reader users: tabbing or arrowing through blocks would announce what the block is about. Short video: https://cloudup.com/cePpANJv24W

@ephox-mogran
Copy link
Contributor Author

A few more questions:

  1. How do you want to tab to the block mover / settings. What mode should you be in? Where are they in the tab order?
  2. How do you want to tab to the block inserter that is between blocks. What mode should you be in? Where is it in the tab order?
  3. If you press Esc on the toolbar, are you OK with that always focusing the editor, even if the focus was originally on the block?

A few run-throughs

  1. I start in the first block in typing (inner) mode. I press Escape to enter navigation mode and select the block (outer). If I press Tab now, what happens? If I press Shift+Tab, what happens?

  2. I start in the first block in typing (inner) mode. I press Tab. What happens?

  3. I start in the first block in typing (inner) mode where the block is something like a code block or table, where tab is likely to have some internal behaviour. I assumed it's OK if Tab is handled by inner itself in this case?

  4. I start in the first block in typing (inner) mode and press ESC to exit to navigation mode (outer focused). I press ESC again? What happens? I navigate to the block mover. I press ESC again? What happens

  5. I have created a multi-selection with the keyboard. I press ESC. What happens?

  6. I have created a multi-selection with the keyboard. I press Tab. What happens?

That's all for now.

@ephox-mogran ephox-mogran mentioned this pull request Oct 27, 2017
3 tasks
@ephox-mogran
Copy link
Contributor Author

I've updated this WIP PR to have some basic tab navigation, and added some navigation for the image block. I haven't implemented navigation inside the image block, so it's currently broken. Just wanted to test out some ideas:

  1. When you press tab from inside the blockEdit section (editing mode), you immediately jump to being inside the next blockEdit. For an image block, this means focusing the first button (or caption if URL is provided). However, if you were in navigation mode, and you pressed down to go to the image block, you would keep the outer block highlighted (like every other block)
  2. The image block handling here is hard-coded, but we need to think about how we could make it generalised. We could introduce a HOC which would tab through to the end of its tabbable containers, and as soon as it no-longer had any tabbable containers after the current tab position, it would allow tab to go up and be handled by the normal block handling of switching between blockEdit sections.

@ephox-mogran
Copy link
Contributor Author

I've also moved across @jasmussen 's use cases into the description of the PR (as checkboxes). Feel free to add more behaviours that are required.

@jasmussen
Copy link
Contributor

How do you want to tab to the block mover / settings. What mode should you be in? Where are they in the tab order?

Great question. It depends a little bit, and I would appreciate input from @afercia on this, but I imagined it could work like this:

  • In editing mode, tab circles around the block controls — mover, ellipsis, "insert after" perhaps.
  • In navigation mode, tab circles around the block controls of multi selected blocks in the same fashion. However that precludes the ability to use tab and shift tab to navigate between blocks.

Not sure what the best approach is.

How do you want to tab to the block inserter that is between blocks. What mode should you be in? Where is it in the tab order?

A few options here, also depending on whether we let the tab button switch only between block manipulation options and not tab between blocks.

It could just be part of the circle of block options — edit a block, tab through the options around it.

It could not be tab accessible on its own at all, requiring either a direct shortcut like Ctrl + ⌘ + M or picking the "Insert After" option we've discussed adding to the ellipsis menu.

If you press Esc on the toolbar, are you OK with that always focusing the editor, even if the focus was originally on the block?

I would be, yes.

I start in the first block in typing (inner) mode. I press Escape to enter navigation mode and select the block (outer). If I press Tab now, what happens? If I press Shift+Tab, what happens?

Again depends on whether we're okay with tab being only for the controls surrounding the selected or focused block, and having arrow keys be sufficient to navigate between blocks. If we're okay with this, tab will always go to these controls. I'm open here, but if we want tab to navigate through blocks, they should probably do this in both modes, and we should find a different way to access the ellipsis menu and movers from the keyboard.

Would requiring direct shortcuts to access these (⌘+Shift+arrowkeys to move, something like ⌘+, for ellipsis) be okay?

I start in the first block in typing (inner) mode. I press Tab. What happens?

Depends on the tabs vs. arrowkeys discussion, I would say.

I start in the first block in typing (inner) mode where the block is something like a code block or table, where tab is likely to have some internal behaviour. I assumed it's OK if Tab is handled by inner itself in this case?

Probably best to worry about this separately — there's a separate codemirror discussion going on, and I don't know how that handles tab — not in a great way I'm told.

I start in the first block in typing (inner) mode and press ESC to exit to navigation mode (outer focused). I press ESC again? What happens? I navigate to the block mover. I press ESC again? What happens

I would suggest you deselect all.

Let's say you've been writing something and you hate it. You Esc Esc, ⌘+A, Del to delete it all. Tab then sets focus on the title field and you can start fresh.

I have created a multi-selection with the keyboard. I press ESC. What happens?

Deselect.

I have created a multi-selection with the keyboard. I press Tab. What happens?

Once again a matter of tabs vs. arrowkeys. Good that you brought this up.

I've updated this WIP PR to have some basic tab navigation, and added some navigation for the image block. I haven't implemented navigation inside the image block, so it's currently broken. Just wanted to test out some ideas:

When you press tab from inside the blockEdit section (editing mode), you immediately jump to being inside the next blockEdit. For an image block, this means focusing the first button (or caption if URL is provided). However, if you were in navigation mode, and you pressed down to go to the image block, you would keep the outer block highlighted (like every other block)
The image block handling here is hard-coded, but we need to think about how we could make it generalised. We could introduce a HOC which would tab through to the end of its tabbable containers, and as soon as it no-longer had any tabbable containers after the current tab position, it would allow tab to go up and be handled by the normal block handling of switching between blockEdit sections.

In a separate issue I suggested when an image block receives focus, the first button inside actually gets focus. However @afercia convinced me otherwise. I have on my todo list to give our placeholder blocks, as well as image blocks, some focus styles.

So imagine an image block, or a placeholder, as being content same as anything else. When your cursor is in text, the text has focus. When your cursor is on an image block, the image block has focus. This will be helpful if you'd like to delete it — just press Del, or you can start to tab through its innards. But you need a focus style for the block for this.

So, same behavior as is in master, in other words (when in edit mode).

Was that helpful?

@ephox-mogran
Copy link
Contributor Author

Hey

In a separate issue I suggested when an image block receives focus, the first button inside actually gets focus. However @afercia convinced me otherwise. I have on my todo list to give our placeholder blocks, as well as image blocks, some focus styles.

So imagine an image block, or a placeholder, as being content same as anything else. When your cursor is in text, the text has focus. When your cursor is on an image block, the image block has focus. This will be helpful if you'd like to delete it — just press Del, or you can start to tab through its innards. But you need a focus style for the block for this.

I assume you mean this issue: #3142 (comment)

My interpretation of that in light of this change was that focus for the block should always start at the outside container when in navigation mode (and not inside it arbitrarily on some button). However, if you were already in edit mode, and you pressed tab from a previous block (e.g. paragraph), it would be more consistent to be if you stayed in edit mode, and focused the same thing as you would if you pressed enter on the image block in navigation mode. That is, navigation mode is moving between blocks, and pressing enter is doing the block-specific focusing action. However, if you press tab from a previous block, then you stay in edit mode, and then focus inside the image block immediately by doing the block-specific focusing action without the user needing to press enter first. This seems consistent, and means that editable blocks would behave in the same way as more widget-like blocks (like image). At some point, you have to decide what to focus inside a widget-like block. If you force someone to press Enter to move inside the widget while in edit mode, then there is no difference getting to an image block in edit mode or navigation mode. That seems like it would be very confusing to me, but I may have missed the goal / point of the exercise.

@jasmussen
Copy link
Contributor

First off, you've been doing quite stellar work, and this is an exceptionally tricky task with lots of "we thinks" and "it feels like"'s. Given those circumstances, an applause is in order, thanks for working on this. 👏

Bear with us as we explore this togeter. It's okay, perhaps even best, to implement this stuff in phases, so we can learn and steer along the way.

I assume you mean this issue: #3142 (comment)

Yes.

My interpretation of that in light of this change was that focus for the block should always start at the outside container when in navigation mode (and not inside it arbitrarily on some button). However, if you were already in edit mode, and you pressed tab from a previous block (e.g. paragraph), it would be more consistent to be if you stayed in edit mode, and focused the same thing as you would if you pressed enter on the image block in navigation mode.

Right. To try and put it as simply as possible — navigation mode never involves the text caret/cursor. No block actually has "focus" in the traditional sense — they have a navigation mode specific focus, right now you've highlighted this with the 2px blue border. All good 👍 👍

In Edit mode, it's all about the more classic focus. That is — when you see the text caret it's because you're typing, and the paragraph has focus. When you click an image that's inserted, you see the resizing handles — the image has focus.

What I meant to imply with placeholder block focus, was that — just like we have a button focus outline, perhaps the placeholder block itself should also have a focus outline. It would be the equivalent of clicking the placeholder block. You're still in edit mode, you can still use arrow keys or tabs. The focus outline on the block would just serve two purposes:

  1. Let you know that when you tab the next time, you tab through the innards of the placeholder.
  2. Let you know that if you have focus on the block/placeholder, and press Delete, the block will disappear. This works now, but is not visually clear.

That is, navigation mode is moving between blocks, and pressing enter is doing the block-specific focusing action. However, if you press tab from a previous block, then you stay in edit mode, and then focus inside the image block immediately by doing the block-specific focusing action without the user needing to press enter first.

Right — to clarify when a block receives focus in edit mode, it's not multi selected, and it has nothing to do with navigation mode. I hope to work on these focus outlines today, and hopefully that'll help visually explain it.

It's key that you would never switch from edit mode to navigation mode unless you take explicit actions to do so, like:

  • pressing Escape
  • shift-selecting across blocks
  • mouse selecting across blocks.

Did I understand your questions right? Did the above clarify things?

@mtias mtias removed this from the Beta 1.6 milestone Oct 31, 2017
@ephox-mogran
Copy link
Contributor Author

It's probably best for me to demonstrate my confusion with an example.

Say the image block is this:

<div class="outer" tabIndex="0">
  <div class="inner" tabIndex="0">
    <button class="first">First</button>
    <button class="second">Second</button>
  </div>
</div>

Now, if I was in navigation mode, I would give the focus to .outer. If I pressed enter in navigation mode when .outer was focused, would I focus .inner, or would I focus the button.first? If I focus .inner, then would I need to press enter again to focus button.first, or would I just use the arrow keys. If it's just the arrow keys, why would I know that pressing arrow keys would move inside a component? Or should I realise if I'm pressing down that that would move inside?

Assume we're going with the tab goes to the next block with the editable part focused. Now, if I press tab from one paragraph into another paragraph, I expect to move my focus so that I am directly typing into the next paragraph (based on the assumption). However, if I now press tab and move into the image block:

a) it would make no sense for me to move into .outer, as that would be putting me in navigaiton mode again
b) I could focus .inner, but then I'd need to press enter or arrows to get focus to button.first. Is this what you want?
c) I could focus .first-button directly, because that is inside the block in the same way that I was inside the previous paragraph.

So my main issue is that if I have to press enter on .inner to put the focus on button.first, does that mean I have to press enter twice if I started in navigation mode (.outer > enter > .inner > enter button.first ), or do I press enter to get to .inner, and then use arrow keys to get to button.first. That's fine, but it seems unintuive (IMO) to use arrow keys to navigation from a wrapping parent into its children, unless those arrow keys are up and down I guess.

So in summary:

Is the workflow:

Navigation mode:

  • focuses .outer. Presses enter to focus .inner, Press arrow keys to move into buttons OR
  • focuses .outer. Presses enter to focus .inner. Presses enter again to move into buttons

Edit mode:

  • focuses .inner. Press enter to focus buttons
  • focuses .inner. Press arrow keys to focus buttons
  • focuses first.button.

In all modes, I would also assume that if I'm within .outer (so .inner or first.button here), that pressing ESC would put me pack to .outer and navigation mode?

Do my questions make sense? @jasmussen @afercia

Now, if I was in edit mode in a previous paragraph, and I pressed tab to another paragraph

@jasmussen
Copy link
Contributor

Thanks for clarifying, appreciate it. I think we are in what @iseulde call's "focus hell", and it would probably be good to get input from @youknowriad and @aduth also, as some of the focus work is being actively discussed, and will probably overlap with work done here.

Here's a quick GIF — the following is edit mode:

tabbing

As you can see, when I tab to the image placeholder, the gray outlines appear surrounding it. When I press Delete, the image placeholder block is deleted. Which is cool. If I tab further, I tab into this block. Which is also cool. This works, and is in master.

Despite my previous comments about a glowing blue halo focus style for this placeholder block, I realized the block already has a focus style, it's this gray border. My apologies for the confusion.

In a way, this already works then, the primary issue being that if you use the arrow keys, the outlines fade out. Should we do it so using the arrow keys or tabs do not fade out the outlines? Only typing would fade those out? It would make it clearer where your edit focus is.

Long story short — if we can fix the boundary fading issue so it's clear when an image or placeholder block has edit focus, then edit mode is in order.

Navigation mode

This works reasonably well in this branch already. Notion.so uses a very similar pattern:

notion navigation mode

Escape gives you that blue indicator, and Enter edits the block.

@ephox-mogran
Copy link
Contributor Author

I think I sort of understand what you want. So to clarify, from the previous question.

If I was in edit mode, and I pressed tab, I would focus .inner
If I was in navigation mode, and I pressed down, I would focus .outer

Once in edit mode, and with .inner focused, if I wanted to focus button, would I press tab or down, or would either work?

@jasmussen
Copy link
Contributor

Once in edit mode, and with .inner focused, if I wanted to focus button, would I press tab or down, or would either work?

Buttons/input fields inside a block, like a placeholder block, should probably still be tabbed to, right @afercia?

@afercia
Copy link
Contributor

afercia commented Nov 9, 2017

@jasmussen I'd say yes. I think for native elements like buttons and input fields we should just use the native interaction (tabbing) because that's what users and software expect. Only for non-native UIs like the blocks themselves or toolbars, menus, etc. we should try to implement alternate interaction models that make sense (the ARIA ones when possible).

@afercia
Copy link
Contributor

afercia commented Nov 28, 2017

Reporting some first feedback from assistive technologies users, originally reported on #3691, see https://make.wordpress.org/accessibility/2017/11/28/screen-reader-user-experience-with-gutenberg/

first user:

There is way to much going on and far too many menus to deal with. With the current version I can hit the f key 3 times and get to the Title, now it takes 3 times as much if I manage to land on it after trying to add something. I find it very difficult to accomplish anything because of the many menus and options. Please let the option for the “Classic editor” stay.

second user:

There are a lot of buttons a lot unlabeled. I found Gutenberg full of clutter, buttons and the like.

This was in some way already mentioned on other issues. Ideally, the interface should be simplified as much as possible and should show controls only when needed. Reducing as much as possible the tab stops is a must for keyboard navigation.

These two modes could help, and ideally the "navigation mode" should be the default for keyboard users.

Note: the above feedback was not just about blocks, more a general feedback on the whole interface.

@afercia
Copy link
Contributor

afercia commented Jan 4, 2018

Quoting a couple points from the (now closed) issue with first accessibility recommendations #297, so they don't get lost:

  1. As I am thinking about this, it occurs to me that treating each content area as a modal once it has focus might be a good idea. The advantage is that it forces the context to be contained within the editable area.
  1. Make sure to undo all contenteditable attributes when done with a content area. Much like focus management.

Not saying they should be implemented at all costs, mainly because many things have changed in the meantime. However, in my opinion they support the idea experimented in this PR.

Especially the point 3. is interesting to me: I'd consider to try to constrain tabbing within a block while in edit mode. Arrows would always let me navigate content through blocks.

About the point 10, I'd leave that to the contenteditable experts here 🙂

@afercia afercia changed the title Experimenting with Esc and Enter to switch between modes Experimenting with navigation and edit modes Jan 4, 2018
@mcsf
Copy link
Contributor

mcsf commented Apr 2, 2018

Closing in favor of more recent efforts (tracked in #5694).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Focus] Accessibility (a11y) Changes that impact accessibility and need corresponding review (e.g. markup changes). [Status] In Progress Tracking issues with work in progress
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants