Sidebar a tre livelli — comportamento incisivo (dipendente dal Menù L1)

Sidebar a tre livelli — comportamento incisivo (dipendente dal Menù L1)

> Obiettivo: rendere la navigazione profonda chiara, veloce e coerente con la voce di menù principale (L1) selezionata. Niente codice: solo regole, UX e criteri.

---

1) Principi

  • Contesto unico: la sidebar mostra solo il ramo che discende dalla voce L1 attiva (selezionata in topbar).
  • Filtrata per permessi: voci invisibili a chi non ha ruolo/permesso non compaiono mai, né in breadcrumb.
  • Ricorsione fino a L4: supporto gerarchico L2/L3/L4; evitare più di 4 livelli (UX degrada).
  • Deterministica: l’URL corrente determina il trail (breadcrumb) e l’espansione dei nodi.
  • 2) Stato ed espansione

  • Auto-espansione del ramo attivo: all’apertura di una pagina, L2/L3 padri sono espansi; i rami non attivi restano collassati.
  • Persistenza temporanea: lo stato di espansione dentro lo stesso L1 persiste finché resti nel medesimo L1; al cambio L1, lo stato si resetta.
  • Selettività: al massimo un ramo L2 espanso per colonna; navigare ad altro L2 collassa il precedente (evita “scroll fatigue”).
  • 3) Selettori e feedback

  • Highlight attivo: la voce corrispondente alla route corrente ha stato attivo (colore/testo) su L2/L3/L4.
  • Icone sottili: usa icone solo su L2 (opzionale); L3/L4 testo semplice per leggibilità.
  • Badge/contatori: ammessi a destra per elementi dinamici (es. “In arrivo”); non più di due badge per voce.
  • 4) Breadcrumb coerente

  • Trail dal menù: il breadcrumb deriva sempre dalla gerarchia del menù, non da stringhe hardcoded.
  • Cliccabile: ogni crumb è cliccabile salvo l’ultimo (corrente).
  • Troncamento: se >4 elementi, tronca i primi con ellissi mantenendo gli ultimi tre + L1.
  • 5) Accessibilità & input

  • Tastiera: TAB ordina le voci visibili; frecce su/giù per scorrere; frecce sx/dx per collassare/espandere al focus.
  • Focus state: anello di focus evidente. Nulla di “nascosto” deve ricevere focus.
  • Screen reader: aria-current="page" per voce attiva; aria-expanded sui nodi con figli.
  • 6) Prestazioni

  • Lazy build per L1: costruisci l’albero della sidebar solo per il L1 attivo.
  • Cache per ruolo: cache corta (es. 60s) del menù filtrato per ruolo attivo.
  • Profondità limitata: evita rendering di grandi alberi nascosti; genera i figli on demand all’espansione (se il ramo >50 voci).
  • 7) Empty states & errori

  • Nessun figlio: se un L1 non ha figli autorizzati, mostra messaggio “Nessuna voce disponibile con il tuo ruolo” + link contestuale, oppure apri direttamente la pagina L1.
  • Permesso revocato: se la rotta è raggiunta ma la voce non è più visibile, mostra 403 “Non autorizzato” + link di ritorno al L1.
  • 8) Navigazione incrociata

  • Deep-linking: aprire un URL profondo ricostruisce L1/L2/L3/L4 e apre i rami necessari.
  • Cambio L1: cambiare L1 in topbar chiude la sidebar corrente e carica la sidebar del nuovo L1 con stato di default (solo primo L2 aperto, se esiste).
  • 9) Criteri di accettazione

  • Switch fra due voci L1 cambia completamente la sidebar, senza residui.
  • Atterrando su una pagina profonda, la sidebar mostra il ramo attivo espanso, breadcrumb coerente e highlight corretto.
  • Voci non autorizzate non compaiono (né in trail).
  • Con >50 voci figlie in un nodo, il caricamento resta fluido (lazy/on-demand).