<div class="rtds-space-y-6 md:rtds-space-y-8">
<div class="rtds-space-y-4">
<div class="rtds-grid rtds-gap-6 lg:rtds-flex lg:rtds-justify-between">
<div class="rtds-loading-status" aria-live="polite" aria-busy="true" role="status">
<div class="rtds-loading-results rtds-grid rtds-font-bold rtds-text-center rtds-gap-8 rtds-justify-center rtds-justify-items-center rtds-py-20">
<svg class="rtds-icon rtds-fill-current rtds-w-12 rtds-h-12 rtds-animate-spin" aria-hidden="true" focusable="false" role="img">
<use href="../../icons.svg#spinner" />
</svg>
<h2 class="rtds-heading-3">Caricamento risultati...</h2>
</div>
</div>
<div class="rtds-hidden">
<div class="rtds-grid md:rtds-flex md:rtds-items-center rtds-gap-2 md:rtds-gap-6 md:rtds-justify-end">
<div class="rtds-flex-1 md:rtds-flex-none">
<div class="rtds-input-field rtds-select-field rtds-field-inline rtds-select-field--sm">
<label for="select-field-1" class="rtds-input-field__label">
Rivolto a
</label>
<div class="rtds-select rtds-select--light">
<select id="select-field-1" class="">
<option value="1">Text</option>
<option value="2">Option 1</option>
<option value="3">Option 2</option>
<option value="4">Option 3</option>
<option value="5">Option 4</option>
<option value="6">Option 5</option>
</select>
</div>
</div>
</div>
<div class="rtds-flex-1 md:rtds-flex-none">
<div class="rtds-input-field rtds-select-field rtds-field-inline rtds-select-field--sm">
<label for="select-field-2" class="rtds-input-field__label">
Ordina per
</label>
<div class="rtds-select rtds-select--light">
<select id="select-field-2" class="">
<option value="1">Text</option>
<option value="2">Option 1</option>
<option value="3">Option 2</option>
<option value="4">Option 3</option>
<option value="5">Option 4</option>
<option value="6">Option 5</option>
</select>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- CONTAINER PER EMPTY STATE - HA CONTENUTO SOLO SE NON CI SONO RISULTATI - DEVE ESSERE SEMPRE PRESENTE - CON I RISULTATI HA CLASSE -> rtds-sr-only -->
<div class="rtds-empty-state rtds-grid rtds-gap-4 rtds-sr-only" aria-live="assertive" aria-atomic="true"></div>
</div>
</div>
{% extends '@search-results' %}
{% block title %}
<div class="rtds-loading-results rtds-grid rtds-font-bold rtds-text-center rtds-gap-8 rtds-justify-center rtds-justify-items-center rtds-py-20" >
{% render '@icon', { id: 'spinner', classes: 'rtds-animate-spin' }, true %}
<h2 class="rtds-heading-3">Caricamento risultati...</h2>
</div>
{% endblock title %}
{% block results %}
{% endblock results %}
{% block pagination %}
{% endblock pagination %}
{
"ariaBusy": true,
"srOnlyTitle": true,
"emptyState": false,
"sorting": true,
"resultsCount": 6,
"title": "<strong>230</strong> Servizi",
"resultsGridClasses": "md:rtds-grid-cols-2 lg:rtds-grid-cols-3",
"resultsCard": {
"variant": "--information-with-gradient"
}
}
.rtds-loading-status[aria-busy="true"] {
width: 100%;
}
@layer components {
.rtds-loading-status[aria-busy="true"] {
@apply rtds-w-full;
}
}
Area dei risultati di ricerca con intestazione contatore, griglia di card, paginazione e gestione degli stati di caricamento, vuoto e filtri selezionati.
Il componente è renderizzato come <div class="rtds-space-y-6 md:rtds-space-y-8">. Può essere avvolto in <div class="rtds-container"> se hasContainer: true.
Contiene, nell’ordine:
@filters--v2-selected) — visibile solo se filtersSelected: true<div class="rtds-loading-status">) con aria-live, aria-busy e role="status"<h2> visibile (o rtds-sr-only se srOnlyTitle: true) + <span> con contatore visuale@select-field--sm) e/o pulsante filtri mobile + dialog — visibili se sorting / mobileFilters: trueemptyState: true, altrimenti rtds-sr-only@card + variante) — ripetuta resultsCount volte@pagination--centered)--loading, --empty-state)Le varianti loading e empty-state estendono @search-results sovrascrivendo blocchi specifici:
search-results--loading.njk — sostituisce il blocco title con spinner + heading “Caricamento risultati…”; svuota i blocchi results e paginationsearch-results--empty-state.njk — sostituisce il blocco title con “Nessun risultato trovato”; popola il blocco emptyState con icona e messaggio; svuota results e paginationdefault: Griglia con sorting, senza filtri mobilihas-container: Aggiunge rtds-container attorno all’intera areahas-padding: Aggiunge padding verticale rtds-py-6has-mobile-filters: Mostra il pulsante “Filtra la ricerca” su mobile con dialog modalehas-filters-selected: Come has-mobile-filters con la barra @filters--v2-selected visibileloading: Spinner di caricamento, nessuna card né paginazioneempty-state: Messaggio “Nessun risultato trovato”, nessuna card né paginazioneContesto di sviluppo Fractal/Nunjucks — parametri del context
.config.yml. Non descrivono attributi HTML da usare nei CMS o ambienti di implementazione.
ariaBusy (booleano, opzionale): Valore di aria-busy sul contenitore .rtds-loading-status. Default: falsesrOnlyTitle (booleano, opzionale): Se true, l’<h2> del contatore è nascosto visivamente (rtds-sr-only) e il contatore è mostrato in uno <span>. Default: trueemptyState (booleano, opzionale): Se true, mostra il contenitore .rtds-empty-state (rimuove rtds-sr-only). Default: falsetitle (stringa, opzionale): HTML del titolo risultati, accetta markup (filtro safe). Default: '<strong>230</strong> Servizi'resultsCount (numero, opzionale): Numero di card da iterare nella griglia. Default: 6hasContainer (booleano, opzionale): Avvolge l’intera area in <div class="rtds-container">. Default: non impostatopadding (booleano, opzionale): Aggiunge rtds-py-6 alla sezione. Default: non impostatoresultsGridClasses (stringa, opzionale): Classi Tailwind per la griglia risultati. Default: 'md:rtds-grid-cols-2 lg:rtds-grid-cols-3'resultsCard.variant (stringa, opzionale): Suffisso variante della card da renderizzare (es. '--information-with-gradient', '--information-02', '--news-small'). Default: '--information-with-gradient'resultsCard.context (oggetto, opzionale): Context aggiuntivo passato al componente @cardsorting (booleano, opzionale): Mostra i due @select-field--sm per ordinamento. Default: truemobileFilters (booleano, opzionale): Mostra il pulsante “Filtra la ricerca” e il dialog @modal-dialog--filters. Default: non impostatofiltersSelected (booleano, opzionale): Mostra la barra @filters--v2-selected con i filtri attivi. Default: non impostatoLivello AA — criteri pertinenti:
aria-live="polite" sul contenitore .rtds-loading-status annuncia aggiornamenti risultati; aria-live="assertive" sul contenitore .rtds-empty-state annuncia immediatamente la mancanza di risultatiaria-busy gestisce lo stato di caricamento; role="status" identifica l’area di stato; aria-controls, aria-haspopup, aria-expanded sul pulsante filtri mobile<h2> per il titolo della sezione risultati; gerarchia heading mantenuta in tutti gli stati.rtds-loading-status con aria-live="polite", aria-busy, role="status" — annuncia aggiornamenti risultati in modo non interruttivo.rtds-empty-state con aria-live="assertive", aria-atomic="true" — annuncia immediatamente la transizione allo stato vuoto; è sempre presente nel DOM, nascosto con rtds-sr-only quando non attivo<h2> con rtds-sr-only (se srOnlyTitle: true) — accessibile agli screen reader ma nascosto visivamente; affiancato da <span> con il contatore visuale@modal-dialog--filters gestisce internamente role="dialog", aria-modal, aria-labelledby e focus trap| Attributo | Valori | Condizione |
|---|---|---|
aria-live |
polite |
Su .rtds-loading-status — sempre presente |
aria-busy |
true / false |
Su .rtds-loading-status — riflette il parametro ariaBusy |
role |
status |
Su .rtds-loading-status — sempre presente |
aria-live |
assertive |
Su .rtds-empty-state — sempre presente |
aria-atomic |
true |
Su .rtds-empty-state — sempre presente |
aria-controls |
"mobileFilters" |
Sul pulsante filtri mobile — quando mobileFilters: true |
aria-haspopup |
dialog |
Sul pulsante filtri mobile — quando mobileFilters: true |
aria-expanded |
true |
Sul pulsante filtri mobile — quando mobileFilters: true |
| Tasto | Azione |
|---|---|
Tab |
Raggiunge i select di ordinamento, il pulsante filtri mobile, le card, la paginazione |
Enter / Space |
Apre il dialog filtri mobile (pulsante) |
Escape |
Chiude il dialog filtri mobile (gestito da @modal-dialog--filters) |
@modal-dialog--filtersaria-busy="true" sull’elemento con role="status" — lo screen reader segnala che il contenuto è in aggiornamentoaria-busy passa a false, aria-live="polite" annuncia il nuovo contatore risultati.rtds-empty-state perde rtds-sr-only, aria-live="assertive" annuncia immediatamente il messaggio@card usato.rtds-loading-status: Contenitore del titolo e contatore risultati; con [aria-busy="true"] si espande a rtds-w-full.rtds-empty-state: Contenitore del messaggio stato vuoto; sempre nel DOM, nascosto con rtds-sr-only quando emptyState: false<!-- Stato predefinito: griglia 2–3 colonne con card information-with-gradient -->
<div class="rtds-space-y-6 md:rtds-space-y-8">
<div class="rtds-space-y-4">
<div class="rtds-loading-status" aria-live="polite" aria-busy="false" role="status">
<h2 class="rtds-sr-only">Risultati di ricerca</h2>
<span class="rtds-heading-3 rtds-font-normal"><strong>230</strong> Servizi</span>
</div>
<div class="rtds-empty-state rtds-grid rtds-gap-4 rtds-sr-only" aria-live="assertive" aria-atomic="true"></div>
<div class="rtds-grid rtds-gap-4 rtds-grid-cols-1 md:rtds-grid-cols-2 lg:rtds-grid-cols-3">
<!-- @card--information-with-gradient × resultsCount -->
</div>
</div>
<!-- @pagination--centered -->
</div>
<!-- Stato di caricamento (ariaBusy: true) -->
<div class="rtds-loading-status" aria-live="polite" aria-busy="true" role="status">
<div class="rtds-loading-results ...">
<!-- @icon spinner -->
<h2 class="rtds-heading-3">Caricamento risultati...</h2>
</div>
</div>
<!-- Stato vuoto (emptyState: true) -->
<div class="rtds-empty-state rtds-grid rtds-gap-4" aria-live="assertive" aria-atomic="true">
<!-- @icon outline--exclamation-circle -->
<h3 class="rtds-heading-4">Non ci sono risultati per questi criteri di ricerca</h3>
</div>@search-box o @search-results-header)loading, empty-state) sono: {% block filters %}, {% block title %}, {% block rightContent %}, {% block rightContentInner %}, {% block emptyState %}, {% block results %}, {% block pagination %}aria-busy, la classe rtds-sr-only sull’elemento .rtds-empty-state e la visibilità della griglia risultati@filters--v2-selected, @select-field--sm, @button--icon-left, @modal-dialog--filters, @card (+ variante), @pagination--centered