-
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
Navigation: Non-link blocks should be wrapped in a <li> #23915
Comments
I'm stuck on how to approach this and would love some guidance from @WordPress/gutenberg-core. The problem is that we want the Search block to render its contents within a We will face the same issue if/when we try to support Social Links, Spacer, Separator, Paragraph, and Image inside Navigation. Additionally, should we want to make the Link block work outside of Navigation, we will run into the reverse of this issue which is that we don't want the Idea 1: Use block context We could modify the Search, Social Links, etc. blocks to use block context to render a A similar idea is to add a Pros: Relatively simple. Idea 2: Make We could modify One issue with this approach is that it potentially requires adding an "unnecessary" container Pros: Relatively simple. Idea 3: Add a Navigation Item block, similar to the Column block We could take a leaf from how Columns works and make it so that the only block allowed inside Navigation is Navigation Item. This would be a block that simply renders an Lots of care would need to be taken to make sure that insertion, block movement, and drag-and-drop within the Navigation block remain smooth. Potentially we could look at reviving the idea of supporting "passthrough" blocks so that the user isn't even aware that there is an intermediate Navigation Link block. Pros: Potentially a complete solution. |
I'm hesitant between idea 2 or 3. I think I'd like to see 3 explored as the APIs are already here and see how it affects the experience. |
Idea 1 sounds like a bad approach to me. Between the other two, I'm not sure which one I prefer. The biggest issue I see with idea 3 is that it's not clear how it would actually work. So I guess you would have:
The rest of the stuff in the Navigation Item should be in a Alternatively, the Link block would have to work more like it does right now, except with no outermost wrapping element... and that just brings us back to a similar issue as what we would run into with idea 2. So it seems like our options are to either support multiple |
Would it be possible to make them support returning I'm more in favour of 2, mainly because I can't see how to make 3 work in a user-friendly way. With the columns block it's fine because the Edit: unless we could wrap the inserter in a Hm, that sounds complicated. Overall, I think having an extra wrapping |
Nice catch @ZebulanStanphill, thanks for thinking this through. It doesn't make sense for non-link blocks to contain submenu items as it isn't sensible for e.g. a user to hover over a Search block and see a submenu appear. Link is the only block that should support submenus. That means we don't have to support multiple But you're totally right that that brings us back exactly to the problem in Idea 2 where Link has to either have its
Maybe! I'll do some investigation. I imagine it might break things like drag and drop, async rendering and Select mode. Also, where would things like the
Funnily enough I was playing with exactly this idea over in |
We'll probably want some kind of non-link block, like Paragraph or Heading, to support submenus too, as that's a recurring pattern. |
Blocks outputting
This may not be true in the long run. Something to keep in mind is the Pages child block proposal in #23689. This Pages block would likely be a child of the Navigation block (rather than a separate block), to allow for a Search block to be put into the same Navigation. I assume this block would consist of a series of In other words, if the Pages child block becomes a reality, the Navigation block would have to accept at least two different direct children: the Pages block and the Navigation Item block. That could make hiding the Navigation Item block a whole lot harder.
Some kind of non-link text block that supports submenus would definitely be desirable. I don't think it makes sense to reuse the Paragraph block here, however. It's clunky to have a single I think instead there should just be a Navigation-specific child block for a text-only item (maybe just called Text). I guess its markup would be a |
Though at the same time, a Link block with a submenu only makes sense in the Navigation block. If a user were using a Link block elsewhere in a document I'd imagine it to be a single link. Thinking about this differently, should the Search block actually be in the Navigation's The closest I could find was TechCrunch, which looks like this: ... but the markup is like this: I'm thinking that we maybe want to consider a Link List block as the block that accepts Links, instead of treating the root navigation as a list. That may also get us closer to some of the options proposed on #23745 |
Just thought I'd point out that we already have a "single link" block: the Button block (which uses an Anyway, great point about the Search block. With that in mind, we could have the block hierarchy work like this... Navigation (consisting of simply the
I really like this approach. It seems a lot simpler than anything suggested before. |
On the other hand, the HTML spec says
So perhaps the Search block shouldn't be inside the |
Both the W3C and WHATWG specs provide examples of other content in the That said, I don't know if there's much (if any) accessibility/semantic benefit to putting your search bar in a |
Whether search belongs in nav does seem to be something rarely agreed upon. Lots of sites seem to have a search form inside a I definitely think we would want to support multiple lists of links inside I feel like a Links block fits in quite nicely with the proposed Pages block too. A transform from Pages to Links could represent switching from an automatically generated list to a manually curated one. |
Great discussion everyone. Putting together all the threads above, I get a block hierarchy that looks like this:
In this model, Navigation definitely looks like a Group block with |
Might be worth running this past the a11y team. In any case, the only thing that changes is whether the search block goes in the Nav block or not; the hierarchy above would be pretty much the same either way. |
If possible I'd prefer to have Navigation render the |
I've been musing for a while as well on inventing even more blocks to place inside a Navigation. NavBar (horizontal links), LinkList (vertical links) - these are variations of the same thing, or maybe Pages, or kinds of links PostLink, PageLink, CategoryLink, ExternalLink - there even is an issue to split Link or have it support a type and then do vatiations. My problem was UX. So a user adds a Navigation block. Then they click the appender and the inserter contains a swath of options. That's a big departure from the origin of this block which enabled creation of simple navigation quite straightforward. I don't think it's bad, tho. The block interface is basically nudging us to add as many blocks as needed to represent concepts on the canvas. It will always be easier to insert a CategoryLink block than a Link block, and then somehow find a category to associate. The same way, you may want to insert a CategoryLinks as a list of all or some categories, instead of manually picking all of them. Nevertheless, it's a rabbit hole. I think that the Navigation block is a specialized container - like a special Group block that has so many particularities (e.g. mobile behavior, a different default layout based on variation etc.) that it deserves it's own inserter entry. It should render a Then the specialized innerBlocks, LinkList or Pages will render Thinking of it, maybe that Submenu block, the one enabling mega menus, should be the Navigaition block itself and we allow recursive appending of this block? In either case, on our road to visual website menu creation, we need to make sure that the user understands their power and also that they have a quick way out of complexity. To allow a user to understand their power means we should drop the current UX of defaulting to a series of links, perhaps even dropping the idea that an empty Navigation should start with an empty link. If the user chooses to start from scratch that scratch should be a big plus sign, like @shaunandrews exemplified for the Submenu block. The quick way out of complexity is found in the placeholder, the initial state and various toolbar options to create "simple" or "standard" menus, or by having more kinds of preset navigations in the inserter. |
Some more thoughts about the Navigation-as-just-a- If the Navigation block just became a One thing to keep in mind, though, is that if you were to insert both a Pages and a Categories block into the Navigation, you would end up with this markup: <nav>
<ul class="wp-block-pages">...</ul>
<ul class="wp-block-categories">...</ul>
</nav> I think that's technically valid, but does it make sense? I guess from a semantic perspective, it does kinda make sense to split the Pages and Categories into separate lists. Depending on the CSS styling provided by the theme, they could still all be shown as a single horizontal (wrapping) list. I do like the idea of separate blocks (or block variations) for page links and category links, plus a Custom Link block/variation for everything else. Something my block nesting idea didn't account for was this: what if you wanted to have a dynamic page/category/etc. list as a submenu? To solve this, we simply have to change how the __ Link blocks work: their allowed children should be the same as the root Navigation. So here's an example: Navigation
The "__ Link" blocks would all have this kind of markup: So for a block tree that looks like this: Navigation
...the front-end markup would look something like this: <nav class="wp-block-navigation">
<!-- InnerBlocks start -->
<ul class="wp-block-custom-links">
<!-- InnerBlocks start -->
<li class="wp-block-custom-link">
<a>Custom Link Label</a>
<!-- InnerBlocks start -->
<ul class="wp-block-pages">
(dynamic content)
</ul>
<!-- InnerBlocks end -->
</li>
<li class="wp-block-page-link">
<a>Page Title</a>
<!-- InnerBlocks start -->
<ul class="wp-block-categories">
(dynamic content)
</ul>
<!-- InnerBlocks end -->
</li>
<!-- InnerBlocks end -->
</ul>
<form class="wp-block-search">...</form>
<!-- InnerBlocks end -->
</nav> I think this is the way to go. It requires no updates to |
Actually, thinking about it some more, since you could have multiple |
This is an interesting idea. I do really like the mockup @shaunandrews shared in #23745 (comment). It's worth exploring. Two things that have been playing on my mind:
|
This approach would mean potentially having multiple
The short answer is no. The third example in the spec shows a So, we don't need to use a list pattern, but that doesn't mean we shouldn't if it helps keep back compat. I don't have a strong opinion on this though 😄 |
#24039 has been a great way to test and see the practical consequences of trying to use block context for situations like this. And after running into some issues with On first glace, I would think that, similar to how the "block alignment" wrapping `div` works (see the code a few lines earlier), the classes should still be applied to the `figure`, rather than the `li`. |
I went ahead and created an implementation of the aforementioned |
Clarifying my position on the I definitely think it (or something similar) should most likely be implemented either way, and is probably the right approach for the Gallery block. As for the Navigation block, however, there's an obvious issue with just modifying the current form of the block to wrap all its children in How I would expect the |
Pages is interesting. If |
I realise this issue has grown in scope quite a lot. Thanks for coming along on the ride with me, it really helps to talk this stuff through! 😅 I took some time and tried to come up with HTML markup for the Navigation block that supports everything we want: static links, a Pages block (#23689), and "mega-menus" using the Columns block (#23745 (comment)). I came up with two approaches:
There's advantages to each:
|
Lovely progress @noisysocks! There's two distinct issues we need to solve for:
|
@noisysocks For mega menus, wouldn't it make more sense to just use the CSS |
Actually, on second thought, the CSS |
__experimentalItemCallback={ ( item ) => <wrap>{ item }</wrap> } |
My ideal future inner blocks API, which would be similar to the upcoming block API (#23034): const { innerBlocks, innerBlocksWrapperProps } = useInnerBlocks( additionalProps );
<ul { ... innerBlocksWrapperProps }>
{ innerBlocks.map( ( block ) => <li>{ block }</li> ) }
</ul> Having access to |
Cc @mcsf |
@ellatrix I like it! But how does it affect |
Thanks for the discussion everyone! Let's proceed with #23915 (comment). #24232 is a good start. In the medium term I'd like to explore #23915 (comment) as it will let us have blocks like Pages inside a Navigation while still using I wrote a high level overview of this feature and its next steps in #24364. |
@ellatrix: Any thoughts on how |
@noisysocks What is |
@ZebulanStanphill We'll need to make a similar API for save. Perhaps |
If you add a Search block into a Navigation block, the resultant markup is incorrect. The Search block should be rendered inside a
<li>
.Steps to reproduce:
Expected result:
The
<form>
should be inside a<li>
.Actual result:
The
<form>
is inside the<ul>
.The text was updated successfully, but these errors were encountered: