-
Notifications
You must be signed in to change notification settings - Fork 4.2k
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
Using NavigableContainer to make a TabPanel for Inserter #3281
Conversation
Basically, there are two bits of feedback that I'd like when people have time:
The navigation for the InserterMenu is as follows: Focus starts in search bar. While open, tab and shift+tab will not exit the inserter menu until it is closed with Escape. Note, the use of |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm having a hard time reviewing this PR, Do you think we could split it into two PRs, one for the tabs components and one for the NavigableContainer.
Also, having a README explaining all the possible props and properties of a "mode" would help the review.
Yeah, I can add some readme details and tests. Sorry, it's probably not in a review ready state yet. I should have realised. |
Don't worry, it's pretty solid already. Just need some clarity ;) |
a0b157f
to
ef72bc3
Compare
I've noticed a regression. It isn't focusing the |
The original code has this:
So it looks like it was designed to skip over disabled options. This is consistent with the fact that the focus outlines don't appear for disabled elements. Is it reasonable to just make all navigation skip disabled elements then? |
Seems like the issue is that when EDIT: Alternatively, we can ensure that we never give a tabindex to anything that is disabled. |
OK. I've tried to update it in line with the PR comments, and also support disabled blocks. I noticed that I had the wrong prop when checking if something should be disabled, so I've fixed that too. @youknowriad @mcsf let me know what else needs to be changed. |
Another issue: sometimes pressing tab from the search bar doesn't go into the Search blocks. It looks to be deterministic ... probably something about the roving tab index. EDIT: boolean logic error when trying to preserve a previous roving tabindex / selection that is still valid. Should be fixed now. |
components/tab-panel/index.js
Outdated
} | ||
} | ||
const TabButton = ( { tabId, onClick, children, selected, ...rest } ) => { | ||
return <button role="tab" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor: might want to use parens around the element here:
return (
<element />
);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we're in a good shape here. I found it weird to not be able to navigate the whole list of blocks with arrow keys, I need to tab between categories but I'll defer to @afercia for the right approach here.
There's a small eslint error :)
As a user, pressing the wrong group of arrows (e.g. down instead of right or tab) shouldn't take the focus out of the inserter. This is most easily experienced when using VisualEditorSiblingInserter, the inserter sitting in between any two blocks.
Aside from #3281 (comment), the other odd thing that stuck out as a user was Escape not closing the inserter if focus is in the search input. I don't see it as a blocker, though. |
Interesting. Is that a regression? Or just something we need to implement? |
I can't remember. Again, not a blocker, but something to be aware of. If you want to fix it here and the fix is trivial, go for it. |
editor/components/inserter/group.js
Outdated
{ blockTypes.map( this.renderItem, this ) } | ||
</NavigableMenu>; | ||
return ( | ||
<NavigableMenu |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the cleanup. Eventually, I hope to get to the point where you don't have to do this every time :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No worries :), it's almost therapeutic. We just need the robots to do more for us (more linting rules + autoformatters).
I can't actually replicate this. I'll merge this one, and we can create a new issue if it happens again. |
Oh, you know what, this was almost for sure my Vimium browser extension. I've had it intermittently off for a11y testing. Problem |
tabs, | ||
} = this.props; | ||
|
||
const selectedTab = tabs.find( ( { name } ) => name === selected ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Array#find
is not polyfilled and is not supported by IE11. This results in crashes in IE11.
if ( ! isEqual( this.props.blockTypes, nextProps.blockTypes ) ) { | ||
this.activeBlocks = deriveActiveBlocks( nextProps.blockTypes ); | ||
// Try and preserve any still valid selected state. | ||
const current = this.activeBlocks.find( block => block.name === this.state.current ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Array#find
is not polyfilled and is not supported by IE11. This results in crashes in IE11.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we provide a runtime warning in dev env?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Per #746 (comment), I think eventually we'll just want to pull in the polyfill, ideally once Babel 7.x lands.
/** | ||
* Internal dependencies | ||
*/ | ||
import { default as withInstanceId } from '../higher-order/with-instance-id'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You don't need { default as ... }
syntax here. This can be simplified to:
import withInstanceId from '../higher-order/with-instance-id';
The default export is inferred when assigning outside the curly braces.
> | ||
{ blocks.map( ( block ) => this.getBlockItem( block ) ) } | ||
</div> | ||
<InserterGroup blockTypes={ blockTypesInfo } labelledBy={ labelledBy } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This convention for applying props is quite difficult to read. I'd suggest either keeping it on a single line, to a certain character limit (80-100), then otherwise consistently applying props one-per-line:
<InserterGroup
blockTypes={ blockTypesInfo }
labelledBy={ labelledBy }
bindReferenceNode={ this.bindReferenceNode }
selectBlock={ this.selectBlock }
/>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, we lost the showInsertionPoint
, hideInsertionPoint
props in this refactor. See #3613.
Description
Exploring #1823
Created some component for navigation and a11y. Have used them in the InserterMenu as a POC.
How Has This Been Tested?
It's a work in progress. I'll write tests as it's stabilising.
Screenshots (jpeg or gifs if applicable):
Types of changes
New components.
Checklist: