ADR 0004: Pagina-sidebar-navigatie in het hamburgermenu op kleine schermen
- Status: geaccepteerd
- Datum: 2026-07-23
- Beslissers: Thomas van Minnen
Context
Verschillende user-side pagina’s tonen een linker sidebar-menu: nieuwsfeed, agenda, dashboard, smoelenboek, instellingen en admin. Ze gebruiken allemaal hetzelfde gedeelde SidebarMenuComponent (<sidebar [items]="...">), aangehangen via een named sidebar router-outlet in TwoColumnComponent / ThreeColumnComponent.
Die sidebar-kolom valt op kleine schermen weg (hidden lg:block) zonder mobiele fallback. Gevolg: op mobiel kun je de sub-pagina’s van die menu’s niet meer bereiken. We willen dit generiek oplossen, zodat elke pagina met een sidebar automatisch meedoet.
Beslissing
We maken de pagina-sidebar op kleine schermen bereikbaar in het bestaande hamburgermenu, via een kleine registry. Zo werkt het:
-
SidebarNavRegistryService(root singleton) houdt deitemsvan de nu-actieve pagina-sidebar bij als signal (plus een optionelenavLink). Een owner-guard zorgt dat een pagina die afmeldt de items van een ander niet wist. - Het gedeelde
SidebarMenuComponentregistreert zichzelf. InngOnChangesschrijft het zijn items in de registry, inngOnDestroymaakt het ze weer leeg. Omdat álle sidebar-pagina’s dit ene component gebruiken, doet elke pagina automatisch mee, zonder per-feature code. Drie inputs sturen het gedrag:registerAsPageNav(standaardtrue) — opt-out zodat een<sidebar>die niet de pagina-navigatie is (o.a. de kopie in het hamburgermenu zelf) zich niet registreert en er geen terugkoppeling ontstaat.navGroupLink— expliciete nav-link om onder te nesten, nodig als die niet gelijk is aan de echte URL (bv./feedredirect naar/home).onPrimary— donkere kleurvariant voor gebruik op de primary-achtergrond van het hamburgermenu.
-
Het hamburgermenu (
SidenavComponent) toont de geregistreerde items op kleine schermen (lg:hidden, spiegelt dehidden lg:blockvan de sidebar-kolom), genest onder het bijbehorende nav-item. Het doel-nav-item wordt bepaald viatargetNavItemId: een explicietenavGroupLinkals die er is, anders het nav-item waarvan de link de langste prefix van de huidige URL is. Voor de rendering hergebruikt het<sidebar [onPrimary]="true" [registerAsPageNav]="false">, zodat iconen, gekleurde bolletjes, dividers en active-staat exact als op de pagina renderen. - Geen dubbeling: items die al als dropdown (een module met eigen children) in het hamburgermenu staan, worden overgeslagen.
Bewust gehouden los van het module-/HeaderService-systeem: dat rendert children ook als chevron in de desktop-header, en dat willen we hier niet — de sidebar-items horen alleen in de hamburger op kleine schermen.
Gevolgen
- Positief: één generieke haak; nieuwe sidebar-pagina’s krijgen de mobiele fallback gratis, zonder per-feature code (op één regel
navGroupLinkna waar een redirect speelt). Geen desktop-chevron. Rendering hergebruikt het bestaande component, dus consistent met de pagina. - Negatief: het gedeelde
SidebarMenuComponentheeft nu een neveneffect (self-registratie) en drie extra inputs.navGroupLinkenregisterAsPageNavzijn kleine leaks in een verder generieke oplossing. - Risico’s: het doel-nav-item wordt heuristisch bepaald (URL-prefix / expliciete link); bij ongebruikelijke routes/redirects kan de nesting misgrijpen. Pagina’s die niet het gedeelde
<sidebar>gebruiken (bv. locaties, met een eigen sidebar) vallen buiten deze haak.
Alternatieven
-
Pagina-items als module-children modelleren (zoals de nieuwsfeed via de
/feed-module). Afgewezen: dat rendert de children óók als chevron-dropdown in de desktop-header, wat hier niet gewenst is; bovendien zijn dashboard/agenda geen module-children maar hardcoded/service-gedreven. -
Uitklap-menu boven de content in de gedeelde layout. Afgewezen na afweging: houdt de sub-nav wel in context bij de pagina, maar de wens was expliciet plaatsing in het bestaande hamburgermenu, genest onder het pagina-item.