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

[WIP] Core blocks: Refactor Gallery and Image blocks to avoid RichText warnings #6871

Closed
wants to merge 3 commits into from

Conversation

gziolo
Copy link
Member

@gziolo gziolo commented May 21, 2018

Description

With #6286 we have deprecated event proxying.

@youknowriad discovered the following:

I wonder if we should introduce an explicit onFocus prop, it seems to be something commonly used across blocks even after #5039

This PR tries to fix it.

How has this been tested?

Make sure that Image and Gallery blocks work like before and there are no warnings on JS console related to RichText component.

Types of changes

Refactoring.

Checklist:

  • My code is tested.
  • My code follows the WordPress code style.
  • My code follows the accessibility standards.
  • My code has proper inline documentation.

@gziolo gziolo added [Feature] Rich Text Related to the Rich Text component that allows developers to render a contenteditable [Type] Code Quality Issues or PRs that relate to code quality labels May 21, 2018
@gziolo gziolo added this to the 3.0 milestone May 21, 2018
@gziolo gziolo self-assigned this May 21, 2018
@gziolo gziolo requested review from youknowriad, aduth and a team May 21, 2018 13:51
@gziolo gziolo added the [Feature] Blocks Overall functionality of blocks label May 21, 2018
@gziolo gziolo changed the title Update/core blocks on focus Core blocks: Refactor Gallery and Image blocks to avoid RichText warnings May 21, 2018
@@ -389,6 +363,11 @@ class ImageEdit extends Component {
}

export default compose( [
withBlockEditContext( ( { setFocusedElement } ) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice trick, do you think this should be documented or recommended?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did the same for both BlockEdit and Plugin - it's more work to map context to props, but I like the fact that you don't need to navigate between files to discover how context is injected into a component.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@@ -5,6 +5,7 @@ export { default as AlignmentToolbar } from './alignment-toolbar';
export { default as BlockAlignmentToolbar } from './block-alignment-toolbar';
export { default as BlockControls } from './block-controls';
export { default as BlockEdit } from './block-edit';
export { withBlockEditContext } from './block-edit/context';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm still on the fence here, what's the difference between making this available to block authors and passing its content as props to edit like we do for several other props :)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cc @aduth Thoughts?

Copy link
Member Author

@gziolo gziolo May 23, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can do prop drilling for blocks, too :)
To be honest, I wasn't happy about exposing this HOC.

@aduth
Copy link
Member

aduth commented May 24, 2018

Should we just add default onFocus prop handling for RichText ? The intent with #6286 was more to avoid setting the expectation that we blanket forward TinyMCE events, particularly where we're inconsistent with how those events are forwarded, i.e. argument of onChange being the new value, argument of onFocus (previously) being the TinyMCE event. But it wasn't to say that we strictly don't want to support any of these props. An onFocus seems like a common use-case (obviously we depended on it already), and the implementation here seems quite complex for plugin authors to recreate on their own.

@gziolo
Copy link
Member Author

gziolo commented May 27, 2018

Should we just add default onFocus prop handling for RichText ? The intent with #6286 was more to avoid setting the expectation that we blanket forward TinyMCE events, particularly where we're inconsistent with how those events are forwarded, i.e. argument of onChange being the new value, argument of onFocus (previously) being the TinyMCE event. But it wasn't to say that we strictly don't want to support any of these props. An onFocus seems like a common use-case (obviously we depended on it already), and the implementation here seems quite complex for plugin authors to recreate on their own.

I added a kind of automated default onFocus handling for RichText in #6419, which uses setFocusedElement from BlockEditContext to do the trick. We can update this implementation to handle onFocus prop, too. Related code:
https://github.com/WordPress/gutenberg/blob/master/editor/components/rich-text/index.js#L201-L205

There is a bigger issue with other components, which this PR unveiled. I'm leaning towards the solution proposed by @youknowriad to pass down setFocusedElement method as one of the props injected into edit component. It still wouldn't be super easy to use by plugin developers. In this context the only thing we need to implement is to have a way to reseet the state so we could inform the block that focus needs to be removed from RichText (when clicking on the image).

Copy link
Member

@tofumatt tofumatt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Curious about the a11y of switching to onClick but the code seems fine to me...

<figure
className={ className }
tabIndex="-1"
onClick={ this.props.onSelect }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Drive-by review, but does the change from onFocus in the child RichText component to the onClick here present any accessibility issues? How does keyboard navigation work after this change (I didn't see it mentioned in the manual testing being done)?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't tested it with the keyboard, I will double check if it should be updated to onFocus.

Copy link
Member Author

@gziolo gziolo May 29, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated to use onFocus. It looks like Gallery block isn't navigable with keyboard :( Related issue: #3836.

@gziolo gziolo force-pushed the update/core-blocks-on-focus branch from 38f7978 to 6dc4397 Compare May 29, 2018 10:46
@aduth
Copy link
Member

aduth commented May 29, 2018

I don't think it's been shown that we need to expose setFocusedElement to a block implementer at all. As implemented, the requirement for gallery is that we need some way to reflect that focus has left a RichText instance. In the same way we support automatic focus detection, why not should we support automatic blur detection (complications therein notwithstanding), rather than putting the impetus on the developer (particularly when they've come to expect onFocus to be managed automatically)?

@youknowriad
Copy link
Contributor

why not should we support automatic blur detection (complications therein notwithstanding), rather than putting the impetus on the developer (particularly when they've come to expect onFocus to be managed automatically)?

The issue is that sometimes RichText loses the focus but we still want to keep it selected. (Link modal, toolbar buttons), It's probably doable but not simple because of the fact that popovers show outside the RichText's node.

@aduth
Copy link
Member

aduth commented May 29, 2018

The issue is that sometimes RichText loses the focus but we still want to keep it selected. (Link modal, toolbar buttons), It's probably doable but not simple because of the fact that popovers show outside the RichText's node.

I'm not sure I understand where we rely on this. Can you detail a simple set of steps to reproduce?

@gziolo
Copy link
Member Author

gziolo commented May 29, 2018

The issue is that sometimes RichText loses the focus but we still want to keep it selected. (Link modal, toolbar buttons), It's probably doable but not simple because of the fact that popovers show outside the RichText's node.

I'm not sure I understand where we rely on this. Can you detail a simple set of steps to reproduce?

Let me update PR so we could discover where it could fail. I think we can make it opt-in/out if necessary.

@youknowriad
Copy link
Contributor

I'm not sure I understand where we rely on this

When you click the "link" button in the RichText toolbar, the RichText loses the focus and it's transfered to the input in the link modal which is rendered outside the RichText which means the isSelected prop of the RichText will move to false causing the toolbar and the link modal to disappear.

I did try this a long time ago :)

@gziolo
Copy link
Member Author

gziolo commented May 29, 2018

In my testing, it happens also for all controls inside block's toolbar which makes it impossible to use them :(

blur fail

@gziolo gziolo force-pushed the update/core-blocks-on-focus branch from 9da4eb4 to 17603b2 Compare May 29, 2018 19:42
@gziolo
Copy link
Member Author

gziolo commented May 29, 2018

Removed withBlockEditContext usage with 9da4eb4.

I will play with it a bit more tomorrow. As far as I understand, what we really need is to set onFocus on the BlockEdit which will reset focused element when focus happens outside of RichText.

@youknowriad
Copy link
Contributor

We're approaching the 3.0 release and the proxy event handlers will be removed, should we add an explicit onFocus prop while we try to come up with a solution here?

@gziolo
Copy link
Member Author

gziolo commented May 30, 2018

Yes, let’s go with explicit onFocus. I didn’t come up with anything that would handle it automatically. As you already noted, this seems like a very difficult use case to solve. I plan to play a bit more with .closest but it probably will fail as it operates on DOM nit React DOM 🙁

@gziolo gziolo modified the milestones: 3.0, 3.1 May 31, 2018
@gziolo gziolo added the [Status] In Progress Tracking issues with work in progress label May 31, 2018
@gziolo gziolo changed the title Core blocks: Refactor Gallery and Image blocks to avoid RichText warnings [WIP] Core blocks: Refactor Gallery and Image blocks to avoid RichText warnings May 31, 2018
@aduth
Copy link
Member

aduth commented May 31, 2018

Note: The explicit onFocus minimal implementation was merged in #7029.

@mcsf
Copy link
Contributor

mcsf commented Jun 26, 2018

@gziolo, given the merge of #7029, what's the status of this one?

@gziolo
Copy link
Member Author

gziolo commented Jun 28, 2018

@mcsf, the original issue is resolved but there are more issues to solve here as explained in my comment in here #7463 (comment). Let’s close this PR for now. We can reuse this code later when we have an idea how to improve focus handling for RichText component.

@gziolo gziolo closed this Jun 28, 2018
@gziolo gziolo deleted the update/core-blocks-on-focus branch June 28, 2018 04:15
@gziolo gziolo mentioned this pull request Nov 12, 2018
4 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Feature] Blocks Overall functionality of blocks [Feature] Rich Text Related to the Rich Text component that allows developers to render a contenteditable [Status] In Progress Tracking issues with work in progress [Type] Code Quality Issues or PRs that relate to code quality
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants