Problem/Motivation

The navigation admin UI is tied to Layout Builder by design #3438895-24: Add the new Navigation to core as an Experimental module to reduce code duplication. Now that Layout Builder is not the future of laying things out in core, we need to prepare for it's removal. First step is to update the UI, another issue will need to deal with the new config format of the navigation configuration.

Steps to reproduce

Proposed resolution

Remove the dependency on the Layout Builder interface and create a bespoke UI that still generates Layout Builder configuration.

Remaining tasks

Define if there is an updated UI or if we simply replace the implementation while keeping most of the existing UX.

User interface changes

Updated interface for navigation sidebar configuration

Introduced terminology

API changes

none

Data model changes

none

Release notes snippet

Issue fork drupal-3521155

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

nod_ created an issue. See original summary.

catch’s picture

It seems likely that this won't be the last blocker to deprecating layout builder, so I think it would make sense to remove the layout builder UI dependency as a by-product of the UX improvements, and then only have to do the implementation once (or at least, not definitely have to do it twice).

We briefly discussed that https://github.com/SortableJS/Sortable might be a good fit here - this only needs 1d drag and drop, and doesn't need/want a table so better to avoid tabledrag if we can I think. Sortable is already in core.libraries.yml so no new dependency.

ckrina’s picture

Huge +1 to this. As discussed with Navigation maintainers and several core committers the existing UI doesn’t meet the UX standards we should have.

nod_’s picture

Issue tags: +Needs design
catch’s picture

Adding a reference to #3452724-78: Navigation side bar and top bar should have appropriate aria labels - with the existing UI, the 'fake' navigation bar that you edit has the same aria labels as the 'real' navigation bar which could be additionally confusing for people using screenreaders.

Version: 11.x-dev » main

Drupal core is now using the main branch as the primary development branch. New developments and disruptive changes should now be targeted to the main branch.

Read more in the announcement.

gábor hojtsy’s picture

Do we have a rough idea of design for this?

anybody’s picture

Just ran into this and I agree it should get removed. With the rise of Drupal Canvas we hopefully can get rid of heavy Layout Builder in several projects then. Navigation should not force enabling it.

https://github.com/SortableJS/Sortable is great!

anybody’s picture

Re

Huge +1 to this. As discussed with Navigation maintainers and several core committers the existing UI doesn’t meet the UX standards we should have.

maybe this could be split into two parts: Removing the heavy dependency on layout_builder and the sorting library (asap) and improve the UI / UX step by step?

finnsky’s picture

I recently used https://github.com/atlassian/pragmatic-drag-and-drop in one project.
Works great.

gábor hojtsy’s picture

@ckrina posted this a year ago:

Huge +1 to this. As discussed with Navigation maintainers and several core committers the existing UI doesn’t meet the UX standards we should have.

So I never customized the navigation menu and therefore I did not know what is even possible and should be covered by a new UI. So I needed to go and check out how it works. I am trying it out with Drupal CMS here.

It is an eclectic mix of interactions to say the least :) I realize this is not an ideal interaction the authors of this module wanted, so the feedback should not be taken personally. But given this interaction, I have a feeling we can come up with better interactions. I agreethese are not good interactions regardless of the backend used. I've not used Layout Builder recently so maybe much of this is because of how Layout Builder works?

1. I go to a page in the admin menu that only has one single button to enable edit mode. The page has no use otherwise.
2. Once I click the button, the navigation becomes editable "in place" but I cannot actually do anything in-place, so this is kind of odd.
3. When I hover over the navigation I get a cross-hair mouse cursor, which indicates MOVE, but there is nothing to move, the interaction does not support me moving anything.
4. However each block gets a pencil icon with a contextual menu. That gives 3 options to configure the block, move the block or remove the block. Regardless of which one I choose the actual functionality appears in the other side of the window in the offcanvas tray (setings tray looks similar, but this is not the same, offcanvas tray is a built-in core feature).
5. The moving feature looks the most broken. There is a "Section 1" which sounds like an internal technical detail. I can't change the general layout of the navigation panel only pick items for the two actual regions. The whole experience looks visually broken with the crosshairs above the labels (regardless of viewport size, I tried on bigger screens) and "Section 1" prominent in the selection.
6. I can also add a block from a separate UI element, which gives me a filtered list of blocks again in a sidebar on the other side of the screen.
7. Regardless of what things I change in the right (dark) sidebar, the navigation is not updated until I save the sidebar. But it is updated when I save the sidebar, I don't need to go out of edit mode entirely to see the changes. This is a positive thing in this interaction.

My understanding is that with the new UI we want to:

  • Remove customization of the navigation from the navigation iself, so the customization happens in a UI on the main page (avoids aria problems with the role of what is going on on the page and navigation for example).
  • Keep the dynamic update or preview somehow, if we can preview inside the page render of the navigation that is also an option(?)
  • Keep the off-canvas tray customization(?)
  • Keep the two regions being hardcoded and only those two being available(?)

Even if we only keep the two hardcoded regions and order inside them, we would still need to show config UI for the blocks in each and save their configs to render properly later, so the storage of all of the config may not be trivial to do in one issue with the UX. @catch may or may not have said that in #2, trying to what "only have to do the implementation once" meant there :)

gábor hojtsy’s picture

StatusFileSize
new28.66 MB

Forgot to attach the walk-through :D

gábor hojtsy’s picture

Title: Remove Layout Builder dependency for the UI of Navigation admin config » Remove Layout Builder dependency for the UI of Navigation admin config, still use Layout Builder for backend and rendering

Discussed with @catch on Slack. He clarified that "only have to do the implementation once" in #2 meant that we should figure out the UX for customising Navigation on top of Layout Builder rather than porting the current UI to a non-LB backend (and THEN figuring out the new UI). The later would help accelerate removing Layout Builder from core, but LB is not close to being removed. Updating title to clarify this scope then, although it was already the scope explained in the issue summary.

gábor hojtsy’s picture

I took a stab at vibe-coding a solution, this is only with claude prompts, no direct development. The ordering and dropping between regions within the section plugin works and as you can see in the navigation itself, it actually is saved properly. The edit, add and remove buttons show the dialogs but don't quite work :D This is the local diffstat for now:

      .../css/components/navigation-blocks.css           | 331 ++++++++++
      core/modules/navigation/js/navigation-blocks.js    | 209 +++++++
      core/modules/navigation/navigation.libraries.yml   |  15 +                                                                
      core/modules/navigation/src/Form/LayoutForm.php    | 675 ++++++++++++++++++---
      .../navigation/src/Hook/NavigationHooks.php        |   2 +-
      5 files changed, 1152 insertions(+), 80 deletions(-)

Addition dialog looks like this but does not actually work yet:

Attached a video of how reordering and cross-region drag and drop works.

I can push this if anyone is interested :D

gábor hojtsy’s picture

StatusFileSize
new39.46 KB

Attaching the vibe coded version as an interesting artifact, not to be considered as a change suggestion :) I realized the navigation module used to have a block module inspired UI to do this, so trying to dig that up now so we can maybe look at what humans already figured out ahead of us.

After all the vibe-coded solution had roughly 15% of its code base deal with the data formats layout builder needs (layout builder temp store for how the form works + section storage, etc). And it did not even have tests yet. So I don't know how much of this would actually break free of layout builder if we actually keep the backend and only replace the UI. For that I think the vibe-coding experiment gave some good directional info.

gábor hojtsy’s picture

Looking at the prior art https://www.drupal.org/about/core/blog/the-new-navigation-module-and-lay... claims that 4000 lines of code were needed to reproduce the configuration of and storage of Navigation layout as custom block storage. The navigation block layout UI looked exactly like the block layout UI does now in core (but the code was a copy due to how the block UI and storage are both tied to a theme and navigation is not).

So I think there are 3 potential endgame directions at least for getting rid of the Layout Builder dependency:

  • we are either going towards those 4k lines of code that does the custom block storage and custom block UI (even if this UI is not the same visually as the custom block UI those lines of code are reasonable given my experiment with a half-baked UI was also 1k lines of code and did not even include custom storage yet).
  • or we should look at abstracting block UI to a reusable pattern where navigation can reuse it -- which is a bit ironic given that we also want to remove block UI so keeping the actual underlying logic in core for navigation and not removing it in fact will be an odd outcome
  • or we can say the UI customization of navigation blocks is not an 80% feature and come with a simple config for the 80% use case like now and punt the UI customization feature to contrib (that could be a use case of #3555047: Add a way to ship block placement statically (will be useful when block UI is removed)

Only in the first scenario are we looking at a new UI design (and lots of code to implement it). In the second scenario we are looking at a block UI refactor for it to be a reusable pattern UI. In the third scenario we are not even looking at having a UI.

gábor hojtsy’s picture

Title: Remove Layout Builder dependency for the UI of Navigation admin config, still use Layout Builder for backend and rendering » Remove Layout Builder dependency from Navigation
Status: Active » Needs review

I decided to take a stab at removing the UI to see what space does that give us but a lot of the underlying features are intertwined between customizing Layout Builder itself (eg. help text) and the UI of Layout Builder (eg. section add links being altered or section plugin filtering). So the more I removed the more it was apparent that there is almost nothing left once the layout builder UI integration is removed. So I decided to introduce a small config file instead with the block list. I did not find an existing core solution to list component sources like this, but kept using the core layout system (which does not require Layout Builder).

The UI still looks and works as-is just no UI to customize it. But the one API to customize it (config action) was ported to the new config. The old config action would not work due to how the old config is not possible to keep without removing the layout builder dependency, so this is effectively a new config action.

Update path intentionally not built yet so we can focus on looking at how a post-LB Navigation would look like and discuss if we even need a UI to customze elements if contrib can do it easily.

No screenshot because there is no UI change other than the UI customization being removed. 20 changed files with 312 additions and 882 deletions, so net 570 less lines so far AFAIS.

gábor hojtsy’s picture

Issue summary: View changes

Adding LLM disclosure because although everything was heavily reviewed and inspected, it was done with LLM assistance nonetheless.

quicksketch’s picture

Title: Remove Layout Builder dependency from Navigation » Remove Layout Builder dependency for the UI of Navigation admin config, still use Layout Builder for backend and rendering
Issue summary: View changes
Status: Needs review » Active

Instead of a custom UI for a niche feature, why not use a simple UI with table drag and drop buttons in a table? This seems like it could be a simpler version of the admin/content/block page. Avoid any custom or new drag and drop libraries and just use the one (tabledrag) that's not going anywhere.

anybody’s picture

Totally agree with @quicksketch! Just wanted to write the same :)

gábor hojtsy’s picture

@quicksketch: long time no see! Great stuff! I personally have nothing against tabledrag, @catch in #2 wrote "better to avoid tabledrag if we can I think", so I went with that. We still need a UI that allows to customize block config (eg. menu depths and such), add new blocks, move blocks between the two regions, so it gets to be near the complexity of the block UI at that point, no?

I also got claude do me a full plan on abstracting block UI so both block UI and Navigation can use it instead of duplicating it in block UI., but stopped short of executing it.

https://www.drupal.org/about/core/blog/the-new-navigation-module-and-lay... links to the issues when navigation still used to have a block UI like UI (which was fine IMHO, not flashy, but this is a very rarely used admin UI, so no flashy needed IMHO). I think core will still want to avoid duplicating that code (that post claimed 4k lines of code) to do the regions + edit + config + delete stuff all custom for navigation blocks which is the main elephant in the room I think.

catch’s picture

I don't have a particular objection to using tabledrag but it's most necessary where you have three dimensions including tree depth rather than just vertical. Also doesn't give the visual drag and drop of the current interface (although there are other things about the current interface people don't like so maybe that's fine).

godotislate’s picture

Does it make sense to land @berdir's suggestino in #3521159-11: Move editing UI as-is from Navigation to dedicated new Navigation Layout module to remove runtime Layout Builder dependency to make the layout builder a optional dependency, used only for the admin UI for Navigation first? Seem likely that the navigation blocks won't be changed much, so LB can be uninstalled and reinstalled only when navigation changes are needed. It doesn't necessarily need to be a blocker here while determing what the new UI should look like.

catch’s picture

I think that's a good idea, also above @Gabor seems to be considering the idea of moving the configuration UI to contrib, and it would enable that. For me I think a lot of sites will never customise the blocks, but also the ability to do so is a nice feature.

berdir’s picture

FWIW, #3587499: Navigation stores plugin configuration with dependencies in a simple config object IMHO is an intermediate step and we're currently using that patch since layout builder is IMHO too heavy and has too many performance implications just to be able to press that button in the backend. But my understanding is that layout builder should eventually be removed from core, so we need plan to fully remove the dependency? Although moving the UI to contrib could also be an option, so core would just ship with the default configuration and customization would either require a contrib module or manual adjustments of the default config. Modules can also ship with their own default blocks (either through a custom hook now or through regular default config in #3587499: Navigation stores plugin configuration with dependencies in a simple config object).

gábor hojtsy’s picture

Status: Active » Closed (duplicate)
Issue tags: -Needs design

Instead of building this custom UI or solving a custom UI on top of layout builder in core, I decided to back the issue in #3521159: Move editing UI as-is from Navigation to dedicated new Navigation Layout module to remove runtime Layout Builder dependency which is much simpler. It decouples Navigation from Layout Builder but keeps using the same storage format with a dedicated UI module to deal with customizing. But it keeps the UI module as-is currently (which is very confusing). That said it would be possible to move that one to contrib and also that separation means core does not install Layout Builder anymore by default. So marking as a duplicate of that, let's meet there!

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.