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

Refactor LinkControl API #19396

Merged
merged 9 commits into from
Jan 7, 2020
Merged

Refactor LinkControl API #19396

merged 9 commits into from
Jan 7, 2020

Conversation

youknowriad
Copy link
Contributor

@youknowriad youknowriad commented Jan 3, 2020

Refactors the LinkControl component API to have a single value/onChange couple instead of separating currentLink from currentSettings.

@youknowriad youknowriad marked this pull request as ready for review January 3, 2020 10:56
@youknowriad youknowriad self-assigned this Jan 3, 2020
@youknowriad youknowriad added [Block] Navigation Affects the Navigation Block [Type] Code Quality Issues or PRs that relate to code quality labels Jan 3, 2020
@youknowriad youknowriad mentioned this pull request Jan 3, 2020
* It's a kind of hack to handle closing the LinkControl popover
* clicking on the ToolbarButton link.
* This hack shouldn't be necessary but due to a focus loss happening
* when selecting a suggestion in the link popover, we force close on block unselection.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@aduth @gziolo not sure if you have an idea about this. Why there's a focus loss when we select a suggestion causing the onClose of the Popover to never be called if we click outside.

Copy link
Member

Choose a reason for hiding this comment

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

const [ isLinkOpen, setIsLinkOpen ] = useState( ! url && isSelected );

It feels like this effect exists only because isSelected is checked only on the initial render. Did you try to refactor code to use isLinkOpen && isSelected as a guard clause for the link popover?

Copy link
Member

Choose a reason for hiding this comment

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

It seems to work in my testing, but I might miss something:

{ isLinkOpen && isSelected && <LinkControl  ... }

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes, this works but I think we should fix the root issue instead which is the focus loss.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'll update the code to follow this suggestion in the meantime

Copy link
Contributor

@getdave getdave left a comment

Choose a reason for hiding this comment

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

I learnt a lot reading through this refactor. Thank you.

My main concern would be to test a lot against the Navigation Block. I'm going to try this now just to make sure I don't see any further issues. I gave this the once over and I didn't notice anything other than...

When you first create a Nav Block the link UI doesn't automatically open anymore. Now you are encouraged to type your link text first and explicitly click the hyperlink toolbar button to add your link. I argued against this approach in the initial Nav Block work because I felt that users would expect to all the link first and might not understand that the toolbar button was required to add the hyperlink.

I wonder whether the LinkUI dialogue should always remain open when the Nav Item is focused? That way:

  • it's clear that you alter the link text via direct manipulation
  • it's obvious how you add a hyperlin (you don't have to make an effort to "understand" the interface)

@@ -202,7 +185,7 @@ function LinkControl( {
<div className="block-editor-link-control__popover-inner">
<div className="block-editor-link-control__search">

{ ( ! isEditingLink && currentLink ) && (
{ ( ! isEditingLink ) && (
Copy link
Contributor

Choose a reason for hiding this comment

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

If we don't have a link then we don't want to show this UI interface. Just curious as to why you feel it's safe to remove this now?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

the boolean seemed explicit enough for me. If we do add the check for the value here, we should also add it to force showing the input if the value is empty which was not the case.

@jorgefilipecosta jorgefilipecosta force-pushed the refactor/link-control-api branch from 65c32c0 to ca03d97 Compare January 3, 2020 13:57
Copy link
Member

@jorgefilipecosta jorgefilipecosta left a comment

Choose a reason for hiding this comment

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

This PR seems to work well. I was also able to replicate the issue @getdave found: when we add a new navigation item, the UI for the link does not open right away as it did before.
We should also update the recently merged buttons block to use the new API.

const link = {
title: title ? unescape( title ) : '',
url,
newTab: opensInNewTab,
Copy link
Member

Choose a reason for hiding this comment

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

Would it make sense to name the property opensInNewTab like the attribute?

Copy link
Contributor Author

@youknowriad youknowriad Jan 3, 2020

Choose a reason for hiding this comment

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

We can I just used the default setting value precedently used.

} = {} ) => setAttributes( {
title: escape( newTitle ),
url: newURL,
label: label || escape( newTitle ),
Copy link
Member

Choose a reason for hiding this comment

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

Would it make sense to escape the tile inside the LinkControl component?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

probably, but let's keep this for a separate PR as this one is growing.

Copy link
Contributor

Choose a reason for hiding this comment

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

@youknowriad Do you need me to create an Issue for this?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Please yes :) thanks

@youknowriad
Copy link
Contributor Author

I fixed the issues raised but there's still a conceptual/design issue here.

  • we want the LinkControl to be visible once we first add a block (navigation menu item or button)
  • we also want the LinkControl to close when it loses focus (since it's a popover).

These two conflict with each other in some situations so for me, we have two options:

  • Like currently implemented in the Button block: the LinkControl is closed when you add a button.
  • Like currently implemented in the NavigationMenu: the LinkControl is opened on add but it's also focused.

Thoughts? which one we go with?

@getdave
Copy link
Contributor

getdave commented Jan 3, 2020

the LinkControl is opened on add but it's also focused.

I vote for the LinkControl being open and focused.

@jorgefilipecosta
Copy link
Member

Like currently implemented in the NavigationMenu: the LinkControl is opened on add but it's also focused.

I think this option may present some accessibility issues. When the block is added the user is inside a popover and can not tab away from the link input field. If we follow this option we need to make sure screen reader users are aware that the focus is inside a popover right after the block is inserted.

@youknowriad
Copy link
Contributor Author

So I think we need consistency here between the two blocks. I'd like some design eyes first before choosing a direction cc @karmatosed @mapk @mtias (context #19396 (comment))

but since this PR keeps the same behavior in master, I think it's ready to land.

Copy link
Member

@jorgefilipecosta jorgefilipecosta left a comment

Choose a reason for hiding this comment

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

The buttons block and the navigation block worked without any regression on my tests 👍

Comment on lines 155 to 160
{
/**
* The isSelected check shouldn't be necessary but due to a focus loss happening
* when selecting a suggestion in the link popover, we force close on block unselection.
*/
}
Copy link
Member

Choose a reason for hiding this comment

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

Is this comment still valid? Looking at the conversation from #19396 (comment), I'm wondering if this might have since been updated? Otherwise, I don't immediately see the isSelected check that this is referring to.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes, it's necessary but should moved (it's done by the hook now)

@mapk
Copy link
Contributor

mapk commented Jan 7, 2020

@youknowriad, thanks for bringing this together.

Thoughts? which one we go with?

It would be great to see a consistent behavior.

If we begin with LinkControl closed, the Navigation block would look like this:

nav

This feels a bit awkward for a few reasons:

  1. Tiny space to begin typing.
  2. No placeholder text like the Title, Paragraph, or other blocks.
  3. The + icon may be misleading because it calls my attention more.

Increasing the space here might help, but without any clear area to begin writing a menu item, it's difficult to understand what I'm supposed to do. Creating a menu item isn't like free writing, it's more like creating a label of sorts, so I would half expect to see an input field or something. For these reasons, this approach may not work.

If we begin with LinkControl open, the Buttons block would look like this:

Screen Shot 2020-01-06 at 4 49 49 PM

This feels better between the two options. BUT when creating a button, I'd like to create the button text first and worry about where it goes second (I could be in minority here), especially in this case with a predefined button area that makes it very clear where to write. Thinking about this, that's what I'd like to do about the Navigation block too, but I don't think our UI makes that easy for the reasons stated above.

All this is to say, if we're driving for consistency, beginning with the LinkControl open feels like the better option.

@youknowriad
Copy link
Contributor Author

Ok let's move forward with what we have then and reconsider if needed.

Comment on lines -115 to +95
const handleDirectEntry = ( value ) => {
const handleDirectEntry = ( val ) => {
Copy link
Member

Choose a reason for hiding this comment

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

I guess this was changed to avoid shadowing with the top-level prop? I'd typically not ever consider an abbreviation to be an improvement. I might have suggested something like nextValue if that's what it's intended to represent in this context.

@ellatrix ellatrix added this to the Gutenberg 7.3 milestone Jan 20, 2020
@mtias mtias deleted the refactor/link-control-api branch June 8, 2020 13:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Block] Navigation Affects the Navigation Block [Type] Code Quality Issues or PRs that relate to code quality
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants