-
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
Fix Nav Block to allow overflow scroll when there are many horizontal nav items #18336
Conversation
Now detects hoz scroll and adds suitable class which can be used to hook CSS styles for when there is hoz scrolling.
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 requesting changes in order to improve the performance of this approach, Dave.
Let's try to conditionate the effect call passing the scroll
and client
with values, something like the following:
const clientWidth = navMenuRef.current ? navMenuRef.current.clientWidth : 0;
const scrollWidth = navMenuRef.current ? navMenuRef.current.scrollWidth : 0;
useLayoutEffect( () => {
//...
}, [ scrollWidth, clientWidth] );
It will reduce considerably the times that the callback function is called.
Happens here, too. Introduced by the |
@obenland @retrofox Unfortunately this looks like a major problem which stems from
Because we add Why does this happen on the Y when we're only setting X to Because the spec doesn't allow certain combinations of X and Y.. In the case that X is The only way I can find to fix this is to add an inner element and set the overflow on that. That alone doesn't solve things because we've just moved the problem down 1 level. So we need to create enough space for the Nav Block Item (child) toolbar to be visible. To do this we adding top The screenshot below shows this in action: This feels like a horrible hack but it seems to be the only way to make this work. That said I'd appreciate 👀 from everyone else to make sure I'm not overlooking a much simpler solution. Alternative RouteAnother way around this might be that we proxy the child Block's toolbar to be shown by the parent Block. Personally I don't find having individual "inline" toolbars for all the sub menu items very usable. Perhaps if we mirrored something like the behaviour of the Table Block where the toolbar remains fixed to the parent Block and clicking into individual cells causes that Toolbar to update based on context. I will highlight that Table does not use child Blocks so this is not the same use case. However we could consider this. Pinging @karmatosed and @shaunandrews for input here and also @jasmussen because I know he's the person to talk to when it comes to Block layout within the editor. |
Yes, this is a doozy. I doubt we can leverage any kind of With autohiding scrollbars it's unclear there's anything to scroll. With permanently visible scrollbars, it's an inaccurate representation of the menu on the front-end. Which brings us to the relationship between editor and front-end — what overflow handling, if any, do we have on the front-end? And can we bring that overflow handling to the editor as well, even if only visually? For example if on the frontend overflow is handled by a dropdown arrow that appears when there are too many menu items, perhaps the very same dropdown arrow could appear in the editor. As for how to then add menu items, I would use this one: While it might need a little more work to be able to handle menu creation 100%, it feels like the only scalable solution for insane mega menus. All of this still follows the 80/20 rule. Most people will never encounter overflow and be fine to create top level items. But for the 20% that do — we should avoid needing to scroll horizontally, vertically, or to hunt for inserters. What do you think? |
Thank you so much for your detailed response @jasmussen. Really helpful. Agree with what you say about the UX and also the 80/20 rule. That said, this PR/Issue is currently marked as blocking the MVP of the Nav Block. Therefore I'm interested in whether we can devise an acceptable interim solution? I'm not entirely comfortable with my current hack solution. However, allowing the editor to visual "break" (as in clearly in an unintended, visual error state) when people add too many items is also sub-optimal. One option is to allow items to wrap rather than extend indefinitely to the RHS. This would be easily to map between frontend and editor. Moreover, from a UX perspective it would be easy for a user to perceive that there are too many items in the Nav and that they need to refine their options. I think we should keep in mind that it's not best practice to have too many top-level nav items. So by clearly indicating a non-optimal visual state (but which at the same time isn't obviously "broken") we clue the user to consider their options. The question is by making the implementation too resilient are we doing the user a disservice? I do see the Block Navigator in the inspector so I assume this is still a key piece of UI. However, I think the question of direct Block manipulation might be too large to address in this PR. |
Absolutely, and actually wrapping might be a good such interim solution.
There's one additional principle we need to keep in mind here. While the unselected block should be as close to a front-end preview as possible, the selected block does not have to map. I.e. we could move forward in two ways:
1 seems like a nice navigation menu toggle option to have. 2 seems like a good improvement, and one that is potentially easy to implement. 1 is the only of those two that has some kind of a mobile strategy, which seems important for the MVP nav block (but maybe not blocking?). But I'm not sure that's the intent of the original ticket, so that seems fair to track and look at separately. In other words, 2 seems totally fine for me, for starters. |
Previously there were many issues with the editing experience and UI when allow for overflowing editing. Experiment with allow items to wrap when the Block is selected. See #18336 (comment)
@jasmussen I'm now trying the wrap approach. |
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 left a few comments below for simplifying this change. One other thing I noticed is that the layout area is still getting a horizontal scroll when the last item in the nav is focused:
Not 100% sure why this is happening but I think it might be related to the fact that the appender at the end of the nav is hidden by default, and only shows when that last item is focused. This behaviour might have changed in the meantime because it doesn't happen on the master branch.
@@ -79,6 +95,7 @@ function NavigationMenu( { | |||
'wp-block-navigation-menu', { | |||
'has-text-color': textColor.color, | |||
'has-background-color': backgroundColor.color, | |||
'has-scroll-x': hasScrollX, |
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 classname doesn't seem to be used for anything. If we can scrap it we can also get rid of all the state and effect logic above.
@@ -148,15 +165,17 @@ function NavigationMenu( { | |||
</InspectorControls> | |||
|
|||
<div className={ navigationMenuClasses } style={ navigationMenuInlineStyles }> | |||
{ isRequesting && <><Spinner /> { __( 'Loading Navigation…' ) } </> } | |||
{ pages && | |||
<div ref={ scrollContainerRef } className="wp-block-navigation-menu__scroll-container"> |
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.
// value clipped (see above). This value is equal to that of the positioned | ||
// toolbar element (usually `top: -51px`). | ||
padding-top: 51px; | ||
margin-top: -51px; |
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.
Noting that this PR will become a lot simpler when https://github.com/WordPress/gutenberg/pull/18440/files lands. |
Wanted to note that I'm still skeptical that it's a good idea at all to use a scrollbar to fix this problem. It is inconsistent with the front-end even when unselected, which is sort of the prime directive of the block editor. The wrapping approach does not have that problem. |
My only worry with the more is we are changing the '+' icon into that. It feels weird to change such a focal existing interaction that is used there. Maybe a '...' after? |
Responded to Shaun's comment in #18429 (comment) but it applies here as well:
|
Closing in favour of Wrap solution. See #18298 (comment) |
Closes #18298
Currently, in the new Nav Block, if many nav items are created then it forces the editor canvas to "expand" and it is broken.
This PR addresses this by allowing overflow to be controlled by scrollbars when the number of items exceeds the width of the Nav Block within the Editor canvas.
This is only applied to the Block within the Editor.
Questions/Problems
You will notice if you focus the rightmost item then the toolbar is cut off. Could/should we add some extra spacing to the far RHS of the Block when it is focused in anticipation of this happening?I've added RHS spacing of 25% only if there is hoz scroll.How has this been tested?
Screenshots
Types of changes
Bug fix (non-breaking change which fixes an issue)
Checklist: