<nav class="rtds-primary-navigation" aria-label="Principale" id="siteNavWrapper">
<button type="button" class="rtds-btn rtds-btn--only-text rtds-rounded-0 lg:rtds-hidden rtds-ml-auto rtds-btn--icon rtds-group" aria-expanded="false" aria-controls="mainNavPanel" id="mobileNavToggle">
<svg class="rtds-icon rtds-fill-current rtds-w-6 rtds-h-6 rtds-m-0 rtds-p-0
rtds-transition-all rtds-duration-200 rtds-ease-out rtds-transform
group-hover:rtds-translate-none is-show-menu
group-aria-expanded:rtds-hidden" aria-hidden="true" focusable="false" role="img">
<use href="../../icons.svg#mini--bars-3" />
</svg>
<svg class="rtds-icon rtds-fill-current rtds-w-6 rtds-h-6 rtds-m-0 rtds-p-0 rtds-transition-all
rtds-duration-200 rtds-ease-out rtds-transform
group-hover:rtds-translate-none is-close-menu rtds-hidden
group-aria-expanded:rtds-inline-block" aria-hidden="true" focusable="false" role="img">
<use href="../../icons.svg#mini--x-mark" />
</svg>
<span class="rtds-sr-only is-show-menu">
Menu
</span>
</button>
<!-- Mobile panel -->
<div class="rtds-primary-navigation__panel" id="mainNavPanel">
<!-- Main nav -->
<div class="rtds-primary-navigation__module is-main lg:rtds-border-b-0">
<ul class="rtds-primary-navigation__list ">
<li class="rtds-primary-navigation__item">
<a href="" class="rtds-primary-navigation__first-level rtds-primary-navigation__link rtds-group rtds-text-base xl:rtds-text-lg">
Item
</a>
</li>
<li class="rtds-primary-navigation__item">
<a href="" class="rtds-primary-navigation__first-level rtds-primary-navigation__link rtds-group rtds-text-base xl:rtds-text-lg is-current" aria-current="page">
Current page
</a>
</li>
<li class="rtds-dropdown-menu has-dropdown-menu rtds-primary-navigation__item">
<button class="rtds-dropdown-menu__trigger rtds-dropdown-trigger rtds-group rtds-w-full rtds-flex rtds-items-center hover:rtds-content-primary aria-expanded:rtds-bg-white lg:aria-expanded:rtds-bg-transparent aria-expanded:rtds-content-primary aria-expanded:rtds-relative rtds-p-3 rtds-gap-2 rtds-text-base xl:rtds-text-lg rtds-primary-navigation__first-level rtds-primary-navigation__link" aria-expanded="false" aria-controls="submenumenu-3">
Dropdown
<svg class="rtds-icon rtds-fill-current rtds-w-5 rtds-h-5 rtds-ml-auto rtds-transition-all rtds-dropdown-menu__trigger-icon group-aria-expanded:-rtds-rotate-180" aria-hidden="true" focusable="false" role="img">
<use href="../../icons.svg#mini--chevron-down" />
</svg>
</button>
<ul class="rtds-dropdown-menu__list rtds-hidden rtds-border rtds-border-t-0 lg:rtds-w-52 lg:rtds-border-t lg:rtds-rounded lg:rtds-shadow-md lg:rtds-absolute rtds-border-r-0 rtds-border-l-0 lg:rtds-border-r lg:rtds-border-l" id="submenumenu-3">
<li class="rtds-dropdown-menu__item rtds-group/menu-item">
<a class="rtds-dropdown-menu__link rtds-block rtds-transition rtds-text-base xl:rtds-text-lg group-first/menu-item:rtds-rounded-t group-last/menu-item:rtds-rounded-b" href="">
<div class="rtds-flex rtds-gap-2 rtds-items-center">
<span class="rtds-grow">List item</span>
</div>
</a>
</li>
<li class="rtds-dropdown-menu__item rtds-group/menu-item">
<a class="rtds-dropdown-menu__link rtds-block rtds-transition rtds-text-base xl:rtds-text-lg group-first/menu-item:rtds-rounded-t group-last/menu-item:rtds-rounded-b" href="">
<div class="rtds-flex rtds-gap-2 rtds-items-center">
<span class="rtds-grow">List item</span>
</div>
</a>
</li>
<li class="rtds-dropdown-menu__item rtds-group/menu-item">
<a class="rtds-dropdown-menu__link rtds-block rtds-transition rtds-text-base xl:rtds-text-lg group-first/menu-item:rtds-rounded-t group-last/menu-item:rtds-rounded-b" href="">
<div class="rtds-flex rtds-gap-2 rtds-items-center">
<span class="rtds-grow">List item</span>
</div>
</a>
</li>
<li class="rtds-dropdown-menu__item rtds-group/menu-item">
<a class="rtds-dropdown-menu__link rtds-block rtds-transition rtds-text-base xl:rtds-text-lg group-first/menu-item:rtds-rounded-t group-last/menu-item:rtds-rounded-b" href="">
<div class="rtds-flex rtds-gap-2 rtds-items-center">
<span class="rtds-grow">List item</span>
</div>
</a>
</li>
</ul>
</li>
</ul>
</div>
</div>
<div class="rtds-primary-navigation__backdrop rtds-bg-black/25 rtds-top-[--header-height] lg:rtds-hidden"></div>
</nav>
<nav
class="rtds-primary-navigation{% block classes %}{% if classes %} {{ classes }}{% endif %}{% endblock classes %}"
aria-label="Principale"
id="siteNavWrapper"
>
<button
type="button"
class="rtds-btn rtds-btn--only-text rtds-rounded-0 lg:rtds-hidden rtds-ml-auto rtds-btn--icon rtds-group"
aria-expanded="false"
aria-controls="mainNavPanel"
id="mobileNavToggle"
>
{% render '@icon--small', { id: 'mini--bars-3', classes: 'rtds-m-0 rtds-p-0
rtds-transition-all rtds-duration-200 rtds-ease-out rtds-transform
group-hover:rtds-translate-none is-show-menu
group-aria-expanded:rtds-hidden', size: 'rtds-w-6 rtds-h-6' }, true %}
{% render '@icon--small', {
id: 'mini--x-mark', classes: 'rtds-m-0 rtds-p-0 rtds-transition-all
rtds-duration-200 rtds-ease-out rtds-transform
group-hover:rtds-translate-none is-close-menu rtds-hidden
group-aria-expanded:rtds-inline-block', size: 'rtds-w-6 rtds-h-6' }, true %}
<span class="rtds-sr-only is-show-menu">
Menu
</span>
</button>
<!-- Mobile panel -->
<div
class="rtds-primary-navigation__panel{% if navPanelClasses %} {{ navPanelClasses }}{% endif %}"
id="mainNavPanel"
>
<!-- Main nav -->
<div class="rtds-primary-navigation__module is-main lg:rtds-border-b-0">
<ul class="rtds-primary-navigation__list {{ listHorizontalAlignment }}{% if listGap %} {{ listGap }}{% endif %}"
>
{% for firstLevel in firstLevels %}
{% if firstLevel.hasSubItems %}
{% block dropdown %}
{% render '@dropdown-menu', {
listItem: true,
label: firstLevel.label,
id: 'submenumenu-' + loop.index,
classes: 'rtds-primary-navigation__item',
listPosition: dropdownListPosition,
listClasses: itemClasses,
listWidth: dropdownListWidth,
triggerTextColor: itemTriggerTextColor,
triggerFontSize: itemFontSize,
listItemLinkFontSize: itemDropdownFontSize,
items: dropdownItems,
triggerClasses: itemTriggerClasses,
hoverStyles: itemHoverStyles
}, true %}
{% endblock %}
{% else %}
<li class="rtds-primary-navigation__item">
<a
href=""
class="rtds-primary-navigation__first-level rtds-primary-navigation__link rtds-group {{ itemFontSize }}{% if firstLevel.isCurrent %} is-current{% endif %}"
{%
if
firstLevel.isCurrent
%}
aria-current="page"
{%
endif
%}
>
{{ firstLevel.label }}
</a>
</li>
{% endif %} {% endfor %}
</ul>
</div>
{% if hasSearchPanel %}
<!-- Mobile search in panel -->
<div
class="rtds-primary-navigation__module is-main lg:rtds-hidden is-last-element"
>
{% if hasUserDropdown %}
<div class="rtds-pb-1 rtds-border-b rtds-border-gray-01">
{% render '@user-dropdown', userDropdown, true %}
</div>
{% endif %}
<form role="search" class="rtds-flex rtds-items-end rtds-p-3 rtds-gap-1">
{% render '@input-field', { classes: 'rtds-flex-1',label: 'Cerca
servizi, informazioni, aiuti...', inputId: 'inputSearchMobile',
inputPlaceholder: 'Cerca', inputType: 'search', inputRadius:
'rtds-rounded-l-lg rtds-rounded-r-none'}, true %}
<button
type="button"
class="rtds-btn rtds-btn--secondary rtds-btn--icon rtds-w-11 rtds-h-11 rtds-rounded-lg"
>
<span class="rtds-sr-only">Cerca</span>
{% render '@icon--small', { id: 'mini--magnifying-glass', size:
'rtds-w-5 rtds-h-5' }, true %}
</button>
</form>
</div>
{% endif %}
</div>
<div
class="rtds-primary-navigation__backdrop rtds-bg-black/25 rtds-top-[--header-height] lg:rtds-hidden"
></div>
</nav>
{
"navId": "mainNavPanel",
"itemTriggerClasses": "rtds-primary-navigation__first-level rtds-primary-navigation__link",
"itemFontSize": "rtds-text-base xl:rtds-text-lg",
"itemDropdownFontSize": "rtds-text-base xl:rtds-text-lg",
"firstLevels": [
{
"label": "Item"
},
{
"label": "Current page",
"isCurrent": true
},
{
"label": "Dropdown",
"hasSubItems": true
}
],
"dropdownItems": [
{
"label": "List item"
},
{
"label": "List item"
},
{
"label": "List item"
},
{
"label": "List item"
}
],
"dropdownListWidth": "lg:rtds-w-52",
"itemClasses": "rtds-border-r-0 rtds-border-l-0 lg:rtds-border-r lg:rtds-border-l",
"itemHoverStyles": "hover:rtds-content-primary"
}
/**
* PRIMARY NAVIGATION
*
*/
@layer components {
.rtds-primary-navigation {
@apply rtds-flex;
}
.rtds-primary-navigation__item {
@apply lg:rtds-flex lg:rtds-items-center;
}
.rtds-primary-navigation__item:where(.has-dropdown-menu) {
@apply lg:rtds-relative;
}
.rtds-primary-navigation__first-level {
@apply rtds-font-bold;
}
.rtds-primary-navigation__panel {
@apply rtds-flex-col rtds-bg-white rtds-transition-all rtds-invisible rtds-w-[88%] lg:rtds-bg-transparent lg:rtds-w-auto rtds-fixed lg:rtds-static lg:rtds-visible rtds-top-[--header-height] rtds-bottom-0 rtds-left-[12%] lg:rtds-left-0 rtds-border-l rtds-border-primary lg:rtds-border-l-0 rtds-overflow-y-auto lg:rtds-overflow-visible rtds-translate-x-full lg:rtds-transform-none;
}
.rtds-primary-navigation__panel.is-open {
@apply rtds-bg-white rtds-translate-x-0 rtds-visible rtds-flex rtds-z-20 rtds-left-[12%];
}
body.rtds-overflow-hidden .rtds-primary-navigation__backdrop,
:root.rtds-overflow-hidden .rtds-primary-navigation__backdrop {
@apply rtds-fixed rtds-right-0 rtds-bottom-0 rtds-left-0 lg:rtds-hidden rtds-z-10;
}
.rtds-primary-navigation__list {
@apply rtds-grid lg:rtds-flex lg:rtds-justify-end rtds-gap-2 lg:rtds-gap-4 xl:rtds-gap-8;
}
.rtds-primary-navigation__link.is-current,
.rtds-primary-navigation__link:hover {
@apply rtds-content-primary rtds-relative after:rtds-absolute after:rtds-block after:rtds-bg-transparent after:rtds-border-t-2 after:rtds-border-current after:rtds-h-[1px] after:rtds-w-full after:rtds-left-0 after:rtds-bottom-0;
}
.rtds-primary-navigation__link {
@apply rtds-min-h-14 rtds-w-full lg:rtds-h-full rtds-flex rtds-items-center lg:rtds-justify-center lg:rtds-text-center rtds-leading-tight rtds-p-3 rtds-gap-2 hover:rtds-no-underline hover:rtds-content-primary;
}
/* MOBILE MENU */
.rtds-primary-navigation__module {
@apply rtds-p-2 lg:rtds-p-0 rtds-grid rtds-items-start lg:rtds-block lg:rtds-flex-1 rtds-border-b rtds-border-gray-01 last:rtds-border-b-0;
}
/* MEGAMENU container fix */
.rtds-primary-navigation .rtds-dropdown-menu__megamenu.is-open {
@apply lg:rtds-flex lg:rtds-justify-center;
}
.rtds-primary-navigation .rtds-dropdown-menu__list {
@apply lg:rtds-flex-1;
}
}
Il componente Primary Navigation è un elemento molecolare che gestisce la navigazione principale di un sito web. Include funzionalità di dropdown e supporta una versione mobile responsive.
primary-navigation--megamenu: versione con menu a tendina espanso (megamenu)Il componente utilizza una struttura semantica con:
<nav> come contenitore principale con ruolo di navigazione<ul> per la lista degli elementi di navigazione<li> per ogni elemento della lista<a> per i link di navigazione<button> per il toggle del menu mobileLa struttura base del markup è:
<nav class="rtds-primary-navigation" aria-label="Principale" id="siteNavWrapper">
<!-- Toggle mobile -->
<button type="button" class="rtds-btn rtds-btn--only-text" aria-expanded="false" aria-controls="mainNavPanel">
<!-- Icone toggle -->
</button>
<!-- Pannello mobile -->
<div class="rtds-primary-navigation__panel" id="mainNavPanel">
<!-- Lista navigazione -->
<ul class="rtds-primary-navigation__list">
<!-- Elementi di navigazione -->
</ul>
</div>
</nav>Il componente è stato progettato seguendo le linee guida WCAG 2.1 e implementa diverse caratteristiche per garantire l’accessibilità:
<nav>, <ul>, <li>, <a>)aria-label="Principale" per identificare la navigazione principalerole="navigation" implicito nell’elemento <nav>aria-expanded: indica lo stato del menu (aperto/chiuso)aria-controls: collega il button al pannello controllatoaria-label implicito nel testo del buttonrtds-sr-only) per le icone del togglearia-current="page"aria-expanded per i menu a tendinarole="search" per identificare la funzione di ricercaI seguenti parametri possono essere utilizzati per configurare il componente:
classes: stringa - classi CSS aggiuntive per il componentenavPanelClasses: stringa - classi per il pannello di navigazione mobilelistHorizontalAlignment: stringa - allineamento orizzontale della lista (default: lg:justify-end)listGap: stringa - spaziatura tra gli elementi della listaitemClasses: stringa - classi CSS per gli elementi della listaitemFontSize: stringa - dimensione del font per gli elementi principaliitemDropdownFontSize: stringa - dimensione del font per gli elementi del dropdownhasSearchPanel: booleano - mostra il pannello di ricerca mobilefirstLevels: array di oggetti - elementi di primo livellolabel: stringa - etichetta dell’elementohasSubItems: booleano - indica se l’elemento ha sottomenuisCurrent: booleano - indica se l’elemento è la pagina correnteIl file di configurazione supporta le seguenti impostazioni:
context: oggetto - configurazione di default
navId: stringa - ID del pannello di navigazioneitemTriggerClasses: stringa - classi per il trigger del dropdownitemFontSize: stringa - dimensione del font per gli elementi principaliitemDropdownFontSize: stringa - dimensione del font per gli elementi del dropdownfirstLevels: array - elementi di primo livellodropdownItems: array - elementi del dropdownvariants: array - varianti del componente
name: stringa - nome della variantecontext: oggetto - configurazione specifica della variantedropdownListWidth: stringa - larghezza del dropdownitemClasses: stringa - classi per gli elementifirstLevels: array - elementi di primo livellodropdownItems: array - elementi del dropdownclasses: blocco per l’inserimento di classi CSS aggiuntivedropdown: blocco per il rendering del componente dropdown