<fieldset class="rtds-facets">
<div class="rtds-grid rtds-py-6 rtds-gap-4 md:rtds-gap-6">
<legend class="rtds-facets__legend">
<button type="button" class="rtds-facets__toggle rtds-group/facet" aria-expanded="true" aria-controls="facetsSection-1" id="facetsToggle1id">
Nome faccetta
<svg class="rtds-icon rtds-fill-current rtds-w-6 rtds-h-6 rtds-transition-transform rtds-duration-300 group-aria-expanded/facet:-rtds-rotate-180" aria-hidden="true" focusable="false" role="img">
<use href="../../icons.svg#solid--chevron-down" />
</svg>
</button>
</legend>
<div class="rtds-facets__content rtds-space-y-2 has-show-more" id="facetsSection-1" role="region" aria-labelledby="facetsToggle1id">
<ul class="rtds-facets__list rtds-space-y-2">
<li class="rtds-facets__item">
<div class="rtds-input rtds-input-field rtds-input-checkbox">
<div class="rtds-flex rtds-gap-2 rtds-items-center">
<input id="checkbox-facetsSection-1-1" name="checkbox-facetsSection-1-1" class=" " type="checkbox">
<label class="rtds-input-checkbox__label rtds-facets__label" for="checkbox-facetsSection-1-1">
<span class="rtds-facets__item-name">Filtro 1</span> <span class="rtds-facets__item-count">44<span class="rtds-sr-only"> risultati</span></span>
</label>
</div>
</div>
</li>
<li class="rtds-facets__item">
<div class="rtds-input rtds-input-field rtds-input-checkbox">
<div class="rtds-flex rtds-gap-2 rtds-items-center">
<input id="checkbox-facetsSection-1-2" name="checkbox-facetsSection-1-2" class=" " type="checkbox">
<label class="rtds-input-checkbox__label rtds-facets__label" for="checkbox-facetsSection-1-2">
<span class="rtds-facets__item-name">Filtro 2</span> <span class="rtds-facets__item-count">44<span class="rtds-sr-only"> risultati</span></span>
</label>
</div>
</div>
</li>
<li class="rtds-facets__item">
<div class="rtds-input rtds-input-field rtds-input-checkbox">
<div class="rtds-flex rtds-gap-2 rtds-items-center">
<input id="checkbox-facetsSection-1-3" name="checkbox-facetsSection-1-3" class=" " type="checkbox">
<label class="rtds-input-checkbox__label rtds-facets__label" for="checkbox-facetsSection-1-3">
<span class="rtds-facets__item-name">Filtro 3</span> <span class="rtds-facets__item-count">44<span class="rtds-sr-only"> risultati</span></span>
</label>
</div>
</div>
</li>
<li class="rtds-facets__item">
<div class="rtds-input rtds-input-field rtds-input-checkbox">
<div class="rtds-flex rtds-gap-2 rtds-items-center">
<input id="checkbox-facetsSection-1-4" name="checkbox-facetsSection-1-4" class=" " type="checkbox">
<label class="rtds-input-checkbox__label rtds-facets__label" for="checkbox-facetsSection-1-4">
<span class="rtds-facets__item-name">Filtro 4</span> <span class="rtds-facets__item-count">44<span class="rtds-sr-only"> risultati</span></span>
</label>
</div>
</div>
</li>
<li class="rtds-facets__item">
<div class="rtds-input rtds-input-field rtds-input-checkbox">
<div class="rtds-flex rtds-gap-2 rtds-items-center">
<input id="checkbox-facetsSection-1-5" name="checkbox-facetsSection-1-5" class=" " type="checkbox">
<label class="rtds-input-checkbox__label rtds-facets__label" for="checkbox-facetsSection-1-5">
<span class="rtds-facets__item-name">Filtro 5</span> <span class="rtds-facets__item-count">44<span class="rtds-sr-only"> risultati</span></span>
</label>
</div>
</div>
</li>
<li class="rtds-facets__item">
<div class="rtds-input rtds-input-field rtds-input-checkbox">
<div class="rtds-flex rtds-gap-2 rtds-items-center">
<input id="checkbox-facetsSection-1-6" name="checkbox-facetsSection-1-6" class=" " type="checkbox">
<label class="rtds-input-checkbox__label rtds-facets__label" for="checkbox-facetsSection-1-6">
<span class="rtds-facets__item-name">Filtro 6</span> <span class="rtds-facets__item-count">44<span class="rtds-sr-only"> risultati</span></span>
</label>
</div>
</div>
</li>
<li class="rtds-facets__item is-hideable rtds-hidden">
<div class="rtds-input rtds-input-field rtds-input-checkbox">
<div class="rtds-flex rtds-gap-2 rtds-items-center">
<input id="checkbox-facetsSection-1-7" name="checkbox-facetsSection-1-7" class=" " type="checkbox">
<label class="rtds-input-checkbox__label rtds-facets__label" for="checkbox-facetsSection-1-7">
<span class="rtds-facets__item-name">Filtro 7</span> <span class="rtds-facets__item-count">44<span class="rtds-sr-only"> risultati</span></span>
</label>
</div>
</div>
</li>
<li class="rtds-facets__item is-hideable rtds-hidden">
<div class="rtds-input rtds-input-field rtds-input-checkbox">
<div class="rtds-flex rtds-gap-2 rtds-items-center">
<input id="checkbox-facetsSection-1-8" name="checkbox-facetsSection-1-8" class=" " type="checkbox">
<label class="rtds-input-checkbox__label rtds-facets__label" for="checkbox-facetsSection-1-8">
<span class="rtds-facets__item-name">Filtro 8</span> <span class="rtds-facets__item-count">44<span class="rtds-sr-only"> risultati</span></span>
</label>
</div>
</div>
</li>
<li class="rtds-facets__item is-hideable rtds-hidden">
<div class="rtds-input rtds-input-field rtds-input-checkbox">
<div class="rtds-flex rtds-gap-2 rtds-items-center">
<input id="checkbox-facetsSection-1-9" name="checkbox-facetsSection-1-9" class=" " type="checkbox">
<label class="rtds-input-checkbox__label rtds-facets__label" for="checkbox-facetsSection-1-9">
<span class="rtds-facets__item-name">Filtro 9</span> <span class="rtds-facets__item-count">44<span class="rtds-sr-only"> risultati</span></span>
</label>
</div>
</div>
</li>
</ul>
<button type="button" class="rtds-w-full rtds-btn rtds-btn--s rtds-btn--inverted rtds-btn--icon-right rtds-group/button rtds-justify-center rtds-btn--show-more rtds-facets__show-more" aria-expanded="false">
<span class="rtds-sr-only">Nome faccetta</span>
<span class="rtds-btn__label-show">
Mostra altri
</span>
<span class="rtds-btn__label-hide rtds-hidden">Mostra meno</span>
<svg class="rtds-icon rtds-fill-current rtds-w-4 rtds-h-4 group-aria-expanded/button:-rtds-rotate-180 rtds-icon rtds-fill-current rtds-transition-all rtds-duration-200 rtds-ease-out rtds-transform group-hover/button:rtds-scale-200" aria-hidden="true" focusable="false" role="img">
<use href="../../icons.svg#outline--chevron-down" />
</svg>
</button>
</div>
</div>
</fieldset>
<fieldset class="rtds-facets">
<div class="rtds-grid rtds-py-6 rtds-gap-4 md:rtds-gap-6">
<legend class="rtds-facets__legend">
<button type="button" class="rtds-facets__toggle rtds-group/facet" aria-expanded="true" aria-controls="{{ sectionId }}" id="{{ toggleId }}">
{{ legend | safe }}
{% render '@icon', { id: 'solid--chevron-down', size: 'rtds-w-6 rtds-h-6 rtds-transition-transform rtds-duration-300', classes: 'group-aria-expanded/facet:-rtds-rotate-180' }, true %}
</button>
</legend>
<div class="rtds-facets__content rtds-space-y-2 has-show-more" id="{{ sectionId }}" role="region" aria-labelledby="{{ toggleId }}">
<ul class="rtds-facets__list rtds-space-y-2">
{% for i in range(1, itemsCount) %}
<li class="rtds-facets__item{% if i > 6 %} is-hideable rtds-hidden{% endif %}">
{% render '@input-checkbox',
{
label: '<span class="rtds-facets__item-name">Filtro ' + i + '</span> <span class="rtds-facets__item-count">44<span class="rtds-sr-only"> risultati</span></span>',
id: 'checkbox-' + sectionId + '-' + i,
labelClasses: 'rtds-facets__label'
},
true
%}
</li>
{% endfor %}
</ul>
<button type="button" class="rtds-w-full rtds-btn rtds-btn--s rtds-btn--inverted rtds-btn--icon-right rtds-group/button rtds-justify-center rtds-btn--show-more rtds-facets__show-more" aria-expanded="false">
<span class="rtds-sr-only">{{ legend }}</span>
<span class="rtds-btn__label-show">
Mostra altri
</span>
<span class="rtds-btn__label-hide rtds-hidden">Mostra meno</span>
{% render '@icon', { id: 'outline--chevron-down', size: 'rtds-w-4 rtds-h-4', classes: 'group-aria-expanded/button:-rtds-rotate-180 rtds-icon rtds-fill-current rtds-transition-all rtds-duration-200 rtds-ease-out rtds-transform group-hover/button:rtds-scale-200' }, true %}
</button>
</div>
</div>
</fieldset>
{
"itemsCount": 10,
"legend": "Nome faccetta",
"toggleId": "facetsToggle1id",
"sectionId": "facetsSection-1"
}
@layer components {
.rtds-facets {
@apply rtds-border-solid rtds-border-b rtds-border-gray-01 last:rtds-border-b-0;
}
legend.rtds-facets__legend {
@apply rtds-w-full;
}
.rtds-facets__toggle {
@apply rtds-flex rtds-items-center rtds-justify-between rtds-w-full rtds-text-sm md:rtds-text-base rtds-font-bold rtds-content-03 rtds-gap-2;
}
.rtds-facets__item {
@apply rtds-py-1;
}
.rtds-facets__label {
@apply rtds-flex rtds-gap-2 rtds-flex-1;
}
.rtds-facets__item-count {
@apply rtds-content-02 rtds-ml-auto rtds-self-start rtds-inline-flex rtds-px-2 rtds-items-center rtds-justify-center rtds-rounded-full rtds-border rtds-border-secondary rtds-background-02 rtds-font-bold rtds-text-sm;
}
}
/*
* This content is licensed according to the W3C Software License at
* https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
*
* From accordion pattern
*/
'use strict';
class FacetToggle {
constructor(domNode) {
this.rootEl = domNode;
this.buttonEl = this.rootEl;
const controlsId = this.buttonEl.getAttribute('aria-controls');
this.contentEl = document.getElementById(controlsId);
this.open = this.buttonEl.getAttribute('aria-expanded') === 'true';
// add event listeners
this.buttonEl.addEventListener('click', this.onButtonClick.bind(this));
}
onButtonClick() {
this.toggle(!this.open);
}
toggle(open) {
// don't do anything if the open state doesn't change
if (open === this.open) {
return;
}
// update the internal state
this.open = open;
// handle DOM updates
this.buttonEl.setAttribute('aria-expanded', `${open}`);
if (open) {
this.contentEl.removeAttribute('hidden');
} else {
this.contentEl.setAttribute('hidden', '');
}
}
// Add public open and close methods for convenience
open() {
this.toggle(true);
}
close() {
this.toggle(false);
}
}
// init facet toggles
const facetToggles = document.querySelectorAll('button.rtds-facets__toggle');
if (facetToggles && facetToggles.length > 0) {
facetToggles.forEach((facetToggleEl) => {
if (facetToggleEl) {
new FacetToggle(facetToggleEl);
}
});
}
/* SHOW MORE BTN */
document.querySelectorAll('.article__show-btn').forEach(btn => {
btn.addEventListener('click', () => {
if (btn.getAttribute('data-shown') === 'false') {
btn.closest('.article').setAttribute('data-expanded', 'true');
btn.setAttribute('data-shown', 'true');
btn.textContent = 'Show less';
btn.closest('.article').querySelector('.article__content').focus();
} else {
btn.closest('.article').setAttribute('data-expanded', 'false');
btn.setAttribute('data-shown', 'false');
btn.textContent = 'Show more';
}
})
})
/* SHOW MORE FACETS */
document.addEventListener('DOMContentLoaded', function() {
// Seleziona tutti i contenitori che hanno il pulsante "mostra altri"
const facetsContainers = document.querySelectorAll('.has-show-more');
// Verifica che esistano contenitori con la classe has-show-more
if (!facetsContainers || facetsContainers.length === 0) {
return; // Esci dalla funzione se non ci sono contenitori
}
facetsContainers.forEach(container => {
const showMoreBtn = container.querySelector('.rtds-btn--show-more');
// Verifica che esista il pulsante show more
if (!showMoreBtn) {
return; // Salta questo container se non ha il pulsante
}
const labelShow = showMoreBtn.querySelector('.rtds-btn__label-show');
const labelHide = showMoreBtn.querySelector('.rtds-btn__label-hide');
const hiddenItems = container.querySelectorAll('.rtds-facets__item.is-hideable.rtds-hidden');
// Verifica che esistano le etichette
if (!labelShow || !labelHide) {
return; // Salta questo container se mancano le etichette
}
// Inizializza aria-expanded a false
showMoreBtn.setAttribute('aria-expanded', 'false');
showMoreBtn.addEventListener('click', () => {
const isExpanded = showMoreBtn.getAttribute('data-expanded') === 'true';
if (!isExpanded) {
// Espandi
hiddenItems.forEach(item => {
item.classList.remove('rtds-hidden');
});
// Cambia le etichette
labelShow.classList.add('rtds-hidden');
labelHide.classList.remove('rtds-hidden');
// Manda il focus al primo elemento
if (hiddenItems.length > 0) {
const firstInput = hiddenItems[0].querySelector('input[type="checkbox"]');
if (firstInput) {
firstInput.focus();
}
}
showMoreBtn.setAttribute('data-expanded', 'true');
showMoreBtn.setAttribute('aria-expanded', 'true');
} else {
// Collassa
hiddenItems.forEach(item => {
item.classList.add('rtds-hidden');
});
// Ripristina le etichette
labelShow.classList.remove('rtds-hidden');
labelHide.classList.add('rtds-hidden');
showMoreBtn.setAttribute('data-expanded', 'false');
showMoreBtn.setAttribute('aria-expanded', 'false');
}
});
});
});
Il componente Facets è un organismo che implementa un sistema di filtri espandibile con funzionalità “mostra più/meno” per gestire liste di opzioni di filtro.
Il componente offre due funzionalità principali:
Il componente è strutturato come un fieldset che contiene:
Il componente può essere configurato attraverso il file facets.config.yml. Ecco una spiegazione dettagliata dei parametri disponibili:
name: Facets
context:
itemsCount: 10 # Numero totale di elementi da generare
legend: Nome faccetta # Testo del pulsante di toggle
toggleId: facetsToggle1id # ID univoco del pulsante di toggle
sectionId: facetsSection-1 # ID univoco della sezione contenente i filtriitemsCountitemsCount: 15 # Genererà 15 checkbox di filtrolegendlegend: "Filtri per categoria" # Testo descrittivo per la sezionetoggleIdtoggleId: "category-filters-toggle" # ID semantico per il togglesectionIdaria-controls del togglesectionId: "category-filters-section" # ID semantico per la sezionename: Facets
context:
itemsCount: 20
legend: "Filtri per categoria"
toggleId: "category-filters-toggle"
sectionId: "category-filters-section"rtds-facets: Contenitore principale del componentertds-facets__legend: Contenitore della legendartds-facets__toggle: Pulsante per espandere/collassare la sezionertds-facets__content: Contenitore del contenuto espandibilertds-facets__list: Lista degli elementi di filtrortds-facets__item: Singolo elemento di filtrortds-facets__item-name: Nome dell’elemento di filtrortds-facets__item-count: Contatore dei risultatirtds-facets__label: Etichetta del checkboxrtds-facets__show-more: Pulsante “mostra più/meno”Il componente include due funzionalità JavaScript:
Il JavaScript viene inizializzato automaticamente al caricamento della pagina e gestisce: