-
Notifications
You must be signed in to change notification settings - Fork 4.3k
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
Refactor LinkControl API #19396
Conversation
* 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. |
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.
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.
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?
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.
It seems to work in my testing, but I might miss something:
{ isLinkOpen && isSelected && <LinkControl ... }
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.
yes, this works but I think we should fix the root issue instead which is the focus loss.
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'll update the code to follow this suggestion in the meantime
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 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 ) && ( |
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.
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?
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.
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.
65c32c0
to
ca03d97
Compare
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 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, |
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.
Would it make sense to name the property opensInNewTab like the attribute?
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.
We can I just used the default setting value precedently used.
} = {} ) => setAttributes( { | ||
title: escape( newTitle ), | ||
url: newURL, | ||
label: label || escape( newTitle ), |
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.
Would it make sense to escape the tile inside the LinkControl component?
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.
probably, but let's keep this for a separate PR as this one is growing.
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.
@youknowriad Do you need me to create an Issue for this?
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.
Please yes :) thanks
I fixed the issues raised but there's still a conceptual/design issue here.
These two conflict with each other in some situations so for me, we have two options:
Thoughts? which one we go with? |
I vote for the |
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. |
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. |
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.
The buttons block and the navigation block worked without any regression on my tests 👍
{ | ||
/** | ||
* 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. | ||
*/ | ||
} |
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.
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.
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.
yes, it's necessary but should moved (it's done by the hook now)
@youknowriad, thanks for bringing this together.
It would be great to see a consistent behavior. If we begin with This feels a bit awkward for a few reasons:
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 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 |
Ok let's move forward with what we have then and reconsider if needed. |
const handleDirectEntry = ( value ) => { | ||
const handleDirectEntry = ( val ) => { |
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 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.
Refactors the LinkControl component API to have a single value/onChange couple instead of separating currentLink from currentSettings.