<section class="rtds-table-responsive" tabindex="0" aria-labelledby="rtds-table-interactive-caption">
<table class="rtds-table rtds-table-interactive" data-table-interactive>
<caption class="rtds-sr-only" id="rtds-table-interactive-caption">Lista domande di partecipazione</caption>
<thead class="rtds-table__head">
<tr>
<th scope="col" class="rtds-table-interactive__th-select">
<input type="checkbox" id="select-all-table" class="rtds-table-interactive__select-all" aria-label="Seleziona tutte le righe">
</th>
<th scope="col" data-sort aria-sort="none">
<button type="button" class="rtds-table-interactive__sort-btn">
<span>Nome</span>
<span class="rtds-table-interactive__sort-icon" aria-hidden="true">
<svg class="rtds-icon rtds-fill-current rtds-w-4 rtds-h-4" aria-hidden="true" focusable="false" role="img">
<use href="../../icons.svg#mini--sort-diamond" />
</svg>
</span>
</button>
</th>
<th scope="col" data-sort aria-sort="none">
<button type="button" class="rtds-table-interactive__sort-btn">
<span>Importo (€)</span>
<span class="rtds-table-interactive__sort-icon" aria-hidden="true">
<svg class="rtds-icon rtds-fill-current rtds-w-4 rtds-h-4" aria-hidden="true" focusable="false" role="img">
<use href="../../icons.svg#mini--sort-diamond" />
</svg>
</span>
</button>
</th>
<th scope="col"><span>Stato</span></th>
<th scope="col" class="rtds-table-interactive__th-actions rtds-text-center">
<span class="rtds-sr-only">Azioni</span>
</th>
</tr>
</thead>
<tbody class="rtds-table__body">
<tr class="rtds-table-interactive__row">
<td class="rtds-table-interactive__td-select">
<input type="checkbox" class="rtds-table-interactive__select-row" aria-label="Seleziona Mario Rossi">
</td>
<td><span class="rtds-font-medium">Mario Rossi</span></td>
<td>1.250</td>
<td>
<span class="rtds-chip has-button-close rtds-chip--status is-open">
Attivo
<button class="rtds-chip__close rtds-w-5 rtds-h-5" type="button">
<svg class="rtds-icon rtds-fill-current rtds-w-5 rtds-h-5" aria-hidden="true" focusable="false" role="img">
<use href="../../icons.svg#mini--x-mark" />
</svg>
<span class="rtds-sr-only">Rimuovi Attivo</span>
</button>
</span>
</td>
<td class="rtds-text-center">
<div class="rtds-dropdown-menu rtds-dropdown-menu is-dropdown-menu--actions rtds-relative">
<button class="rtds-dropdown-menu__trigger rtds-dropdown-trigger rtds-group rtds-w-full rtds-flex rtds-items-center rtds-p-0 rtds-justify-center" aria-expanded="false" aria-controls="actions-01">
<span class="rtds-sr-only">
Mario Rossi -
Opzioni
</span>
<svg class="rtds-icon rtds-fill-current rtds-w-6 rtds-h-6 rtds-dropdown-menu__trigger-icon" aria-hidden="true" focusable="false" role="img">
<use href="../../icons.svg#mini--ellipsis-vertical" />
</svg>
</button>
<ul class="rtds-dropdown-menu__list rtds-hidden rtds-w-[25ch] rtds-absolute rtds-right-0 rtds-top-10 rtds-bg-white rtds-shadow-lg rtds-z-10 rtds-rounded rtds-border rtds-border-gray-01">
<li class="rtds-dropdown-menu__item rtds-group/menu-item">
<a class="rtds-dropdown-menu__link rtds-block rtds-transition" href="">
<div class="rtds-flex rtds-gap-2 rtds-items-center">
<svg class="rtds-icon rtds-fill-current rtds-w-4 rtds-h-4 md:rtds-w-5 md:rtds-h-5 lg:rtds-w-6 lg:rtds-h-6 rtds-mr-2" aria-hidden="true" focusable="false" role="img">
<use href="../../icons.svg#outline--eye" />
</svg>
<span class="rtds-grow">Visualizza</span>
</div>
</a>
</li>
<li class="rtds-dropdown-menu__item rtds-group/menu-item">
<a class="rtds-dropdown-menu__link rtds-block rtds-transition" href="">
<div class="rtds-flex rtds-gap-2 rtds-items-center">
<svg class="rtds-icon rtds-fill-current rtds-w-4 rtds-h-4 md:rtds-w-5 md:rtds-h-5 lg:rtds-w-6 lg:rtds-h-6 rtds-mr-2" aria-hidden="true" focusable="false" role="img">
<use href="../../icons.svg#outline--pencil" />
</svg>
<span class="rtds-grow">Modifica</span>
</div>
</a>
</li>
<li class="rtds-dropdown-menu__item rtds-group/menu-item">
<a class="rtds-dropdown-menu__link rtds-block rtds-transition" href="">
<div class="rtds-flex rtds-gap-2 rtds-items-center">
<svg class="rtds-icon rtds-fill-current rtds-w-4 rtds-h-4 md:rtds-w-5 md:rtds-h-5 lg:rtds-w-6 lg:rtds-h-6 rtds-mr-2" aria-hidden="true" focusable="false" role="img">
<use href="../../icons.svg#outline--trash" />
</svg>
<span class="rtds-grow">Elimina</span>
</div>
</a>
</li>
</ul>
</div>
</td>
</tr>
<tr class="rtds-table-interactive__row">
<td class="rtds-table-interactive__td-select">
<input type="checkbox" class="rtds-table-interactive__select-row" aria-label="Seleziona Anna Bianchi">
</td>
<td><span class="rtds-font-medium">Anna Bianchi</span></td>
<td>3.780</td>
<td>
<span class="rtds-chip has-button-close rtds-chip--status is-pending">
In attesa
<button class="rtds-chip__close rtds-w-5 rtds-h-5" type="button">
<svg class="rtds-icon rtds-fill-current rtds-w-5 rtds-h-5" aria-hidden="true" focusable="false" role="img">
<use href="../../icons.svg#mini--x-mark" />
</svg>
<span class="rtds-sr-only">Rimuovi In attesa</span>
</button>
</span>
</td>
<td class="rtds-text-center">
<div class="rtds-dropdown-menu rtds-dropdown-menu is-dropdown-menu--actions rtds-relative">
<button class="rtds-dropdown-menu__trigger rtds-dropdown-trigger rtds-group rtds-w-full rtds-flex rtds-items-center rtds-p-0 rtds-justify-center" aria-expanded="false" aria-controls="actions-02">
<span class="rtds-sr-only">
Anna Bianchi -
Opzioni
</span>
<svg class="rtds-icon rtds-fill-current rtds-w-6 rtds-h-6 rtds-dropdown-menu__trigger-icon" aria-hidden="true" focusable="false" role="img">
<use href="../../icons.svg#mini--ellipsis-vertical" />
</svg>
</button>
<ul class="rtds-dropdown-menu__list rtds-hidden rtds-w-[25ch] rtds-absolute rtds-right-0 rtds-top-10 rtds-bg-white rtds-shadow-lg rtds-z-10 rtds-rounded rtds-border rtds-border-gray-01">
<li class="rtds-dropdown-menu__item rtds-group/menu-item">
<a class="rtds-dropdown-menu__link rtds-block rtds-transition" href="">
<div class="rtds-flex rtds-gap-2 rtds-items-center">
<svg class="rtds-icon rtds-fill-current rtds-w-4 rtds-h-4 md:rtds-w-5 md:rtds-h-5 lg:rtds-w-6 lg:rtds-h-6 rtds-mr-2" aria-hidden="true" focusable="false" role="img">
<use href="../../icons.svg#outline--eye" />
</svg>
<span class="rtds-grow">Visualizza</span>
</div>
</a>
</li>
<li class="rtds-dropdown-menu__item rtds-group/menu-item">
<a class="rtds-dropdown-menu__link rtds-block rtds-transition" href="">
<div class="rtds-flex rtds-gap-2 rtds-items-center">
<svg class="rtds-icon rtds-fill-current rtds-w-4 rtds-h-4 md:rtds-w-5 md:rtds-h-5 lg:rtds-w-6 lg:rtds-h-6 rtds-mr-2" aria-hidden="true" focusable="false" role="img">
<use href="../../icons.svg#outline--pencil" />
</svg>
<span class="rtds-grow">Modifica</span>
</div>
</a>
</li>
<li class="rtds-dropdown-menu__item rtds-group/menu-item">
<a class="rtds-dropdown-menu__link rtds-block rtds-transition" href="">
<div class="rtds-flex rtds-gap-2 rtds-items-center">
<svg class="rtds-icon rtds-fill-current rtds-w-4 rtds-h-4 md:rtds-w-5 md:rtds-h-5 lg:rtds-w-6 lg:rtds-h-6 rtds-mr-2" aria-hidden="true" focusable="false" role="img">
<use href="../../icons.svg#outline--trash" />
</svg>
<span class="rtds-grow">Elimina</span>
</div>
</a>
</li>
</ul>
</div>
</td>
</tr>
<tr class="rtds-table-interactive__row">
<td class="rtds-table-interactive__td-select">
<input type="checkbox" class="rtds-table-interactive__select-row" aria-label="Seleziona Giuseppe Verdi">
</td>
<td><span class="rtds-font-medium">Giuseppe Verdi</span></td>
<td>890</td>
<td>
<span class="rtds-chip has-button-close rtds-chip--status is-in-progress">
In corso
<button class="rtds-chip__close rtds-w-5 rtds-h-5" type="button">
<svg class="rtds-icon rtds-fill-current rtds-w-5 rtds-h-5" aria-hidden="true" focusable="false" role="img">
<use href="../../icons.svg#mini--x-mark" />
</svg>
<span class="rtds-sr-only">Rimuovi In corso</span>
</button>
</span>
</td>
<td class="rtds-text-center">
<div class="rtds-dropdown-menu rtds-dropdown-menu is-dropdown-menu--actions rtds-relative">
<button class="rtds-dropdown-menu__trigger rtds-dropdown-trigger rtds-group rtds-w-full rtds-flex rtds-items-center rtds-p-0 rtds-justify-center" aria-expanded="false" aria-controls="actions-03">
<span class="rtds-sr-only">
Giuseppe Verdi -
Opzioni
</span>
<svg class="rtds-icon rtds-fill-current rtds-w-6 rtds-h-6 rtds-dropdown-menu__trigger-icon" aria-hidden="true" focusable="false" role="img">
<use href="../../icons.svg#mini--ellipsis-vertical" />
</svg>
</button>
<ul class="rtds-dropdown-menu__list rtds-hidden rtds-w-[25ch] rtds-absolute rtds-right-0 rtds-top-10 rtds-bg-white rtds-shadow-lg rtds-z-10 rtds-rounded rtds-border rtds-border-gray-01">
<li class="rtds-dropdown-menu__item rtds-group/menu-item">
<a class="rtds-dropdown-menu__link rtds-block rtds-transition" href="">
<div class="rtds-flex rtds-gap-2 rtds-items-center">
<svg class="rtds-icon rtds-fill-current rtds-w-4 rtds-h-4 md:rtds-w-5 md:rtds-h-5 lg:rtds-w-6 lg:rtds-h-6 rtds-mr-2" aria-hidden="true" focusable="false" role="img">
<use href="../../icons.svg#outline--eye" />
</svg>
<span class="rtds-grow">Visualizza</span>
</div>
</a>
</li>
<li class="rtds-dropdown-menu__item rtds-group/menu-item">
<a class="rtds-dropdown-menu__link rtds-block rtds-transition" href="">
<div class="rtds-flex rtds-gap-2 rtds-items-center">
<svg class="rtds-icon rtds-fill-current rtds-w-4 rtds-h-4 md:rtds-w-5 md:rtds-h-5 lg:rtds-w-6 lg:rtds-h-6 rtds-mr-2" aria-hidden="true" focusable="false" role="img">
<use href="../../icons.svg#outline--pencil" />
</svg>
<span class="rtds-grow">Modifica</span>
</div>
</a>
</li>
<li class="rtds-dropdown-menu__item rtds-group/menu-item">
<a class="rtds-dropdown-menu__link rtds-block rtds-transition" href="">
<div class="rtds-flex rtds-gap-2 rtds-items-center">
<svg class="rtds-icon rtds-fill-current rtds-w-4 rtds-h-4 md:rtds-w-5 md:rtds-h-5 lg:rtds-w-6 lg:rtds-h-6 rtds-mr-2" aria-hidden="true" focusable="false" role="img">
<use href="../../icons.svg#outline--trash" />
</svg>
<span class="rtds-grow">Elimina</span>
</div>
</a>
</li>
</ul>
</div>
</td>
</tr>
<tr class="rtds-table-interactive__row">
<td class="rtds-table-interactive__td-select">
<input type="checkbox" class="rtds-table-interactive__select-row" aria-label="Seleziona Laura Esposito">
</td>
<td><span class="rtds-font-medium">Laura Esposito</span></td>
<td>5.120</td>
<td>
<span class="rtds-chip has-button-close rtds-chip--status is-closed">
Chiuso
<button class="rtds-chip__close rtds-w-5 rtds-h-5" type="button">
<svg class="rtds-icon rtds-fill-current rtds-w-5 rtds-h-5" aria-hidden="true" focusable="false" role="img">
<use href="../../icons.svg#mini--x-mark" />
</svg>
<span class="rtds-sr-only">Rimuovi Chiuso</span>
</button>
</span>
</td>
<td class="rtds-text-center">
<div class="rtds-dropdown-menu rtds-dropdown-menu is-dropdown-menu--actions rtds-relative">
<button class="rtds-dropdown-menu__trigger rtds-dropdown-trigger rtds-group rtds-w-full rtds-flex rtds-items-center rtds-p-0 rtds-justify-center" aria-expanded="false" aria-controls="actions-04">
<span class="rtds-sr-only">
Laura Esposito -
Opzioni
</span>
<svg class="rtds-icon rtds-fill-current rtds-w-6 rtds-h-6 rtds-dropdown-menu__trigger-icon" aria-hidden="true" focusable="false" role="img">
<use href="../../icons.svg#mini--ellipsis-vertical" />
</svg>
</button>
<ul class="rtds-dropdown-menu__list rtds-hidden rtds-w-[25ch] rtds-absolute rtds-right-0 rtds-top-10 rtds-bg-white rtds-shadow-lg rtds-z-10 rtds-rounded rtds-border rtds-border-gray-01">
<li class="rtds-dropdown-menu__item rtds-group/menu-item">
<a class="rtds-dropdown-menu__link rtds-block rtds-transition" href="">
<div class="rtds-flex rtds-gap-2 rtds-items-center">
<svg class="rtds-icon rtds-fill-current rtds-w-4 rtds-h-4 md:rtds-w-5 md:rtds-h-5 lg:rtds-w-6 lg:rtds-h-6 rtds-mr-2" aria-hidden="true" focusable="false" role="img">
<use href="../../icons.svg#outline--eye" />
</svg>
<span class="rtds-grow">Visualizza</span>
</div>
</a>
</li>
<li class="rtds-dropdown-menu__item rtds-group/menu-item">
<a class="rtds-dropdown-menu__link rtds-block rtds-transition" href="">
<div class="rtds-flex rtds-gap-2 rtds-items-center">
<svg class="rtds-icon rtds-fill-current rtds-w-4 rtds-h-4 md:rtds-w-5 md:rtds-h-5 lg:rtds-w-6 lg:rtds-h-6 rtds-mr-2" aria-hidden="true" focusable="false" role="img">
<use href="../../icons.svg#outline--pencil" />
</svg>
<span class="rtds-grow">Modifica</span>
</div>
</a>
</li>
<li class="rtds-dropdown-menu__item rtds-group/menu-item">
<a class="rtds-dropdown-menu__link rtds-block rtds-transition" href="">
<div class="rtds-flex rtds-gap-2 rtds-items-center">
<svg class="rtds-icon rtds-fill-current rtds-w-4 rtds-h-4 md:rtds-w-5 md:rtds-h-5 lg:rtds-w-6 lg:rtds-h-6 rtds-mr-2" aria-hidden="true" focusable="false" role="img">
<use href="../../icons.svg#outline--trash" />
</svg>
<span class="rtds-grow">Elimina</span>
</div>
</a>
</li>
</ul>
</div>
</td>
</tr>
<tr class="rtds-table-interactive__row">
<td class="rtds-table-interactive__td-select">
<input type="checkbox" class="rtds-table-interactive__select-row" aria-label="Seleziona Marco Conti">
</td>
<td><span class="rtds-font-medium">Marco Conti</span></td>
<td>2.340</td>
<td>
<span class="rtds-chip has-button-close rtds-chip--status is-open">
Attivo
<button class="rtds-chip__close rtds-w-5 rtds-h-5" type="button">
<svg class="rtds-icon rtds-fill-current rtds-w-5 rtds-h-5" aria-hidden="true" focusable="false" role="img">
<use href="../../icons.svg#mini--x-mark" />
</svg>
<span class="rtds-sr-only">Rimuovi Attivo</span>
</button>
</span>
</td>
<td class="rtds-text-center">
<div class="rtds-dropdown-menu rtds-dropdown-menu is-dropdown-menu--actions rtds-relative">
<button class="rtds-dropdown-menu__trigger rtds-dropdown-trigger rtds-group rtds-w-full rtds-flex rtds-items-center rtds-p-0 rtds-justify-center" aria-expanded="false" aria-controls="actions-05">
<span class="rtds-sr-only">
Marco Conti -
Opzioni
</span>
<svg class="rtds-icon rtds-fill-current rtds-w-6 rtds-h-6 rtds-dropdown-menu__trigger-icon" aria-hidden="true" focusable="false" role="img">
<use href="../../icons.svg#mini--ellipsis-vertical" />
</svg>
</button>
<ul class="rtds-dropdown-menu__list rtds-hidden rtds-w-[25ch] rtds-absolute rtds-right-0 rtds-top-10 rtds-bg-white rtds-shadow-lg rtds-z-10 rtds-rounded rtds-border rtds-border-gray-01">
<li class="rtds-dropdown-menu__item rtds-group/menu-item">
<a class="rtds-dropdown-menu__link rtds-block rtds-transition" href="">
<div class="rtds-flex rtds-gap-2 rtds-items-center">
<svg class="rtds-icon rtds-fill-current rtds-w-4 rtds-h-4 md:rtds-w-5 md:rtds-h-5 lg:rtds-w-6 lg:rtds-h-6 rtds-mr-2" aria-hidden="true" focusable="false" role="img">
<use href="../../icons.svg#outline--eye" />
</svg>
<span class="rtds-grow">Visualizza</span>
</div>
</a>
</li>
<li class="rtds-dropdown-menu__item rtds-group/menu-item">
<a class="rtds-dropdown-menu__link rtds-block rtds-transition" href="">
<div class="rtds-flex rtds-gap-2 rtds-items-center">
<svg class="rtds-icon rtds-fill-current rtds-w-4 rtds-h-4 md:rtds-w-5 md:rtds-h-5 lg:rtds-w-6 lg:rtds-h-6 rtds-mr-2" aria-hidden="true" focusable="false" role="img">
<use href="../../icons.svg#outline--pencil" />
</svg>
<span class="rtds-grow">Modifica</span>
</div>
</a>
</li>
<li class="rtds-dropdown-menu__item rtds-group/menu-item">
<a class="rtds-dropdown-menu__link rtds-block rtds-transition" href="">
<div class="rtds-flex rtds-gap-2 rtds-items-center">
<svg class="rtds-icon rtds-fill-current rtds-w-4 rtds-h-4 md:rtds-w-5 md:rtds-h-5 lg:rtds-w-6 lg:rtds-h-6 rtds-mr-2" aria-hidden="true" focusable="false" role="img">
<use href="../../icons.svg#outline--trash" />
</svg>
<span class="rtds-grow">Elimina</span>
</div>
</a>
</li>
</ul>
</div>
</td>
</tr>
</tbody>
</table>
</section>
<section class="rtds-table-responsive" tabindex="0"{% if caption %} aria-labelledby="{{ id | default('rtds-table-interactive') }}-caption"{% else %} aria-label="{{ ariaLabel | default('Contenuto tabella') }}"{% endif %}>
<table class="rtds-table rtds-table-interactive" data-table-interactive>
{% if caption %}<caption class="rtds-sr-only" id="{{ id | default('rtds-table-interactive') }}-caption">{{ caption }}</caption>{% endif %}
<thead class="rtds-table__head">
<tr>
<th scope="col" class="rtds-table-interactive__th-select">
<input
type="checkbox"
id="select-all-table"
class="rtds-table-interactive__select-all"
aria-label="Seleziona tutte le righe">
</th>
<th scope="col" data-sort aria-sort="none">
<button type="button" class="rtds-table-interactive__sort-btn">
<span>Nome</span>
<span class="rtds-table-interactive__sort-icon" aria-hidden="true">
{% render '@icon', { id: 'mini--sort-diamond', size: 'rtds-w-4 rtds-h-4' }, true %}
</span>
</button>
</th>
<th scope="col" data-sort aria-sort="none">
<button type="button" class="rtds-table-interactive__sort-btn">
<span>Importo (€)</span>
<span class="rtds-table-interactive__sort-icon" aria-hidden="true">
{% render '@icon', { id: 'mini--sort-diamond', size: 'rtds-w-4 rtds-h-4' }, true %}
</span>
</button>
</th>
<th scope="col"><span>Stato</span></th>
<th scope="col" class="rtds-table-interactive__th-actions rtds-text-center">
<span class="rtds-sr-only">Azioni</span>
</th>
</tr>
</thead>
<tbody class="rtds-table__body">
{% for row in rows %}
<tr class="rtds-table-interactive__row">
<td class="rtds-table-interactive__td-select">
<input
type="checkbox"
class="rtds-table-interactive__select-row"
aria-label="Seleziona {{ row.name }}">
</td>
<td><span class="rtds-font-medium">{{ row.name }}</span></td>
<td>{{ row.amount }}</td>
<td>
{% if row.status == 'open' %}
{% render '@chip', { label: row.statusLabel, classes: 'rtds-chip--status is-open' }, true %}
{% elseif row.status == 'pending' %}
{% render '@chip', { label: row.statusLabel, classes: 'rtds-chip--status is-pending' }, true %}
{% elseif row.status == 'in-progress' %}
{% render '@chip', { label: row.statusLabel, classes: 'rtds-chip--status is-in-progress' }, true %}
{% elseif row.status == 'closed' %}
{% render '@chip', { label: row.statusLabel, classes: 'rtds-chip--status is-closed' }, true %}
{% endif %}
</td>
<td class="rtds-text-center">
{% render '@dropdown-menu--actions', {
label: 'Opzioni',
id: row.actionId,
context: row.name,
triggerIcon: 'mini--ellipsis-vertical',
listWidth: 'rtds-w-[20ch]',
listResponsiveStyles: 'rtds-absolute rtds-right-0 rtds-top-10 rtds-bg-white rtds-shadow-lg rtds-z-10',
triggerSpacing: 'rtds-p-0',
triggerClasses: 'rtds-justify-center',
triggerAriaExpandedStyles: '',
triggerFontSize: '',
items: [
{ label: 'Visualizza', iconLeft: 'outline--eye' },
{ label: 'Modifica', iconLeft: 'outline--pencil' },
{ label: 'Elimina', iconLeft: 'outline--trash' }
]
}, true %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</section>
{
"caption": "Lista domande di partecipazione",
"rows": [
{
"name": "Mario Rossi",
"amount": "1.250",
"status": "open",
"statusLabel": "Attivo",
"actionId": "actions-01"
},
{
"name": "Anna Bianchi",
"amount": "3.780",
"status": "pending",
"statusLabel": "In attesa",
"actionId": "actions-02"
},
{
"name": "Giuseppe Verdi",
"amount": "890",
"status": "in-progress",
"statusLabel": "In corso",
"actionId": "actions-03"
},
{
"name": "Laura Esposito",
"amount": "5.120",
"status": "closed",
"statusLabel": "Chiuso",
"actionId": "actions-04"
},
{
"name": "Marco Conti",
"amount": "2.340",
"status": "open",
"statusLabel": "Attivo",
"actionId": "actions-05"
}
]
}
:where(.rtds-table-interactive__th-select,
.rtds-table-interactive__td-select) {
width: var(--spacing-12);
padding-inline: var(--spacing-2);
}
:where(.rtds-table-interactive__th-actions) {
width: var(--spacing-16);
text-align: center;
}
.rtds-table-interactive__sort-btn {
display: inline-flex;
align-items: center;
gap: var(--spacing-1);
background: transparent;
border: none;
padding: 0;
color: inherit;
font: inherit;
font-weight: bold;
cursor: pointer;
text-align: left;
width: 100%;
}
.rtds-table-interactive__sort-btn:focus-visible {
outline: 2px solid currentColor;
outline-offset: 2px;
border-radius: var(--border-radius-sm, 2px);
}
.rtds-table-interactive__sort-icon {
display: inline-flex;
flex-shrink: 0;
}
:where(.rtds-table-interactive__row).is-selected {
--_table-interactive-selected-bg: var(
--table-interactive-selected-bg,
var(--color-background-02, var(--color-neutral-100))
);
background-color: var(--_table-interactive-selected-bg);
}
@layer components {
:where(.rtds-table-interactive__th-select,
.rtds-table-interactive__td-select) {
width: var(--spacing-12);
padding-inline: var(--spacing-2);
}
:where(.rtds-table-interactive__th-actions) {
width: var(--spacing-16);
text-align: center;
}
.rtds-table-interactive__sort-btn {
display: inline-flex;
align-items: center;
gap: var(--spacing-1);
background: transparent;
border: none;
padding: 0;
color: inherit;
font: inherit;
font-weight: bold;
cursor: pointer;
text-align: left;
width: 100%;
}
.rtds-table-interactive__sort-btn:focus-visible {
outline: 2px solid currentColor;
outline-offset: 2px;
border-radius: var(--border-radius-sm, 2px);
}
.rtds-table-interactive__sort-icon {
display: inline-flex;
flex-shrink: 0;
}
:where(.rtds-table-interactive__row).is-selected {
--_table-interactive-selected-bg: var(
--table-interactive-selected-bg,
var(--color-background-02, var(--color-neutral-100))
);
background-color: var(--_table-interactive-selected-bg);
}
}
'use strict';
class TableInteractive {
constructor(tableNode) {
this.table = tableNode;
this.tbody = tableNode.querySelector('tbody');
this.sortableHeaders = Array.from(tableNode.querySelectorAll('[data-sort]'));
this.selectAllCheckbox = tableNode.querySelector('.rtds-table-interactive__select-all');
if (this.sortableHeaders.length > 0) {
this.initSort();
}
if (this.selectAllCheckbox) {
this.initSelection();
}
}
// --- SORTING ---
initSort() {
this.sortableHeaders.forEach(th => {
const btn = th.querySelector('.rtds-table-interactive__sort-btn');
if (btn) {
btn.addEventListener('click', () => this.handleSort(th));
}
});
}
handleSort(clickedTh) {
const currentSort = clickedTh.getAttribute('aria-sort');
const newSort = currentSort === 'descending' ? 'ascending' : 'descending';
this.sortableHeaders.forEach(th => {
if (th !== clickedTh) {
th.setAttribute('aria-sort', 'none');
this.updateSortIcon(th, 'none');
}
});
clickedTh.setAttribute('aria-sort', newSort);
this.updateSortIcon(clickedTh, newSort);
this.sortRows(clickedTh, newSort);
}
getColumnIndex(th) {
return Array.from(th.parentElement.children).indexOf(th);
}
getCellValue(row, colIndex) {
const cell = row.children[colIndex];
return cell ? (cell.textContent || cell.innerText).trim() : '';
}
detectType(colIndex) {
const rows = Array.from(this.tbody.querySelectorAll('tr'));
for (const row of rows) {
const val = this.getCellValue(row, colIndex);
if (val) {
const normalized = val.replace(/[.\s]/g, '').replace(',', '.');
const num = parseFloat(normalized);
return !isNaN(num) && isFinite(num) ? 'number' : 'text';
}
}
return 'text';
}
sortRows(th, direction) {
const colIndex = this.getColumnIndex(th);
const type = this.detectType(colIndex);
const rows = Array.from(this.tbody.querySelectorAll('tr'));
rows.sort((a, b) => {
let valA = this.getCellValue(a, colIndex);
let valB = this.getCellValue(b, colIndex);
if (type === 'number') {
valA = parseFloat(valA.replace(/[.\s]/g, '').replace(',', '.')) || 0;
valB = parseFloat(valB.replace(/[.\s]/g, '').replace(',', '.')) || 0;
} else {
valA = valA.toLowerCase();
valB = valB.toLowerCase();
}
if (direction === 'ascending') {
return valA > valB ? 1 : valA < valB ? -1 : 0;
}
return valA < valB ? 1 : valA > valB ? -1 : 0;
});
rows.forEach(row => this.tbody.appendChild(row));
}
updateSortIcon(th, state) {
const useEl = th.querySelector('.rtds-table-interactive__sort-icon use');
if (!useEl) return;
const iconMap = {
none: 'mini--sort-diamond',
ascending: 'mini--sort-up',
descending: 'mini--sort-down',
};
const currentHref = useEl.getAttribute('href') || useEl.getAttribute('xlink:href') || '';
const basePath = currentHref.split('#')[0];
const newHref = basePath + '#' + iconMap[state];
if (useEl.hasAttribute('href')) {
useEl.setAttribute('href', newHref);
} else {
useEl.setAttribute('xlink:href', newHref);
}
}
// --- SELEZIONE ---
initSelection() {
this.selectAllCheckbox.addEventListener('change', () => this.handleSelectAll());
this.table.addEventListener('change', e => {
if (e.target.matches('.rtds-table-interactive__select-row')) {
this.handleRowSelect(e.target);
}
});
}
handleRowSelect(checkbox) {
const row = checkbox.closest('tr');
row.classList.toggle('is-selected', checkbox.checked);
this.updateSelectAll();
}
handleSelectAll() {
const checked = this.selectAllCheckbox.checked;
const rowCheckboxes = this.table.querySelectorAll('.rtds-table-interactive__select-row');
rowCheckboxes.forEach(cb => {
cb.checked = checked;
cb.closest('tr').classList.toggle('is-selected', checked);
});
this.selectAllCheckbox.indeterminate = false;
}
updateSelectAll() {
const rowCheckboxes = Array.from(
this.table.querySelectorAll('.rtds-table-interactive__select-row')
);
const checkedCount = rowCheckboxes.filter(cb => cb.checked).length;
if (checkedCount === 0) {
this.selectAllCheckbox.checked = false;
this.selectAllCheckbox.indeterminate = false;
} else if (checkedCount === rowCheckboxes.length) {
this.selectAllCheckbox.checked = true;
this.selectAllCheckbox.indeterminate = false;
} else {
this.selectAllCheckbox.checked = false;
this.selectAllCheckbox.indeterminate = true;
}
}
}
document.querySelectorAll('[data-table-interactive]').forEach(table => {
new TableInteractive(table);
});
Componente per la visualizzazione di dati tabulari con ordinamento per colonna, selezione righe e menu azioni contestuali. Estende il markup e le classi di @table.
Renderizzato come <section class="rtds-table-responsive" tabindex="0"> contenente <table class="rtds-table rtds-table-interactive" data-table-interactive>. Il wrapper è raggiungibile da tastiera (tabindex="0") e ha sempre aria-labelledby verso l’id della <caption> (obbligatoria in questo componente).
L’attributo data-table-interactive attiva l’inizializzazione JS automatica. Le feature si attivano dalla presenza del markup:
[data-sort] su <th> → ordinamento attivo su quella colonna.rtds-table-interactive__select-all → selezione righe attiva| Variante | Descrizione |
|---|---|
default |
Tutte le feature: sorting + selezione + dropdown azioni |
sort |
Solo colonne sortabili, senza checkbox e dropdown |
Questa sezione riguarda i parametri del context
.config.ymlusati nel preview Fractal. In produzione il markup viene costruito direttamente in HTML.
id (stringa, opzionale): Identificativo univoco dell’istanza, usato per generare l’id della <caption> ({id}-caption) referenziato da aria-labelledby sul wrapper. Default: rtds-table-interactive. Usare un valore diverso per ogni istanza se più tabelle sono presenti nella stessa pagina, per evitare id duplicaticaption (stringa, obbligatorio): Descrizione della tabella — renderizzata come <caption class="rtds-sr-only">, obbligatoria per l’accessibilità. È anche il nome accessibile del wrapper scrollabile (aria-labelledby)rows (array, obbligatorio): Righe della tabella. Ogni oggetto ha:name (stringa): Nome — colonna sortable (text)amount (stringa): Importo — colonna sortable (number, formato "1.250")status (stringa): Stato — valori: open, pending, in-progress, closedstatusLabel (stringa): Label leggibile dello statoactionId (stringa): ID univoco per il dropdown azioni della riga<caption> descrive la tabella; scope="col" su tutti i <th>; aria-sort comunica lo stato di ordinamento.rtds-table-responsive è un <section tabindex="0">, raggiungibile e scrollabile da tastiera anche senza mouse/touch (pattern: Accessible tables)aria-sort="none|ascending|descending" sul <th> attivo; aria-label su checkbox select-all e per-riga; il wrapper ha sempre aria-labelledby verso l’id della <caption> come nome accessibileIl <th> con colonna sortable riceve data-sort e aria-sort="none" inizialmente. Al click il JS aggiorna aria-sort in modo che gli screen reader annuncino la direzione corrente. Il ciclo è binario: ascending ↔ descending.
aria-label="Seleziona tutte le righe" sulla checkbox di headeraria-label="Seleziona [nome riga]" sulla checkbox per riga — il consumer imposta il nome correttoindeterminate viene impostato via JS (.indeterminate = true) quando alcune righe sono selezionate<caption class="rtds-sr-only"> è obbligatoria — identificare sempre la tabella con una descrizione<caption> via aria-labelledby: nessun testo duplicato, la caption fa doppio servizio (descrizione tabella + nome accessibile della regione scrollabile)<span aria-hidden="true"> — non vengono lettemini--sort-diamond (◆) per colonna ordinabile non attiva, mini--sort-up (▲) per ascending, mini--sort-down (▼) per descending — conforme WAI-ARIA APG.rtds-table-interactive — affiancato a .rtds-table, nessun override sui base styles.rtds-table-interactive__row — riga; riceve .is-selected da JS quando selezionata.rtds-table-interactive__th-select — <th> colonna checkbox (larghezza fissa).rtds-table-interactive__td-select — <td> colonna checkbox.rtds-table-interactive__th-actions — <th> colonna azioni (larghezza fissa, centrata).rtds-table-interactive__sort-btn — <button> dentro <th data-sort>.rtds-table-interactive__sort-icon — <span> contenitore icona sort (aria-hidden)| Stato | Icona sprite | Forma |
|---|---|---|
| Colonna ordinabile, non attiva | mini--sort-diamond |
◆ rombo |
| Ordinamento ascending (A→Z, 0→9) | mini--sort-up |
▲ triangolo su |
| Ordinamento descending (Z→A, 9→0) | mini--sort-down |
▼ triangolo giù |
Le forme sono strutturalmente diverse tra loro (non solo per colore o dimensione) in conformità con le indicazioni WAI-ARIA APG per le tabelle con colonne ordinabili.
| Proprietà | Default semantico | Fallback letterale | Descrizione |
|---|---|---|---|
--table-interactive-selected-bg |
--color-background-02 |
--color-neutral-100 |
Sfondo riga selezionata |
Esempio override CMS:
.my-context {
--table-interactive-selected-bg: #e8f4fd;
}<!-- Tabella con tutte le feature -->
<section class="rtds-table-responsive" tabindex="0" aria-labelledby="table-domande-caption">
<table class="rtds-table rtds-table-interactive" data-table-interactive>
<caption class="rtds-sr-only" id="table-domande-caption">Lista domande di partecipazione</caption>
<thead class="rtds-table__head">
<tr>
<th scope="col" class="rtds-table-interactive__th-select">
<input type="checkbox"
id="select-all-domande"
class="rtds-table-interactive__select-all"
aria-label="Seleziona tutte le righe">
</th>
<th scope="col" data-sort aria-sort="none">
<button type="button" class="rtds-table-interactive__sort-btn">
<span>Nome</span>
<span class="rtds-table-interactive__sort-icon" aria-hidden="true">
<!-- icona mini--sort-diamond (stato: non ordinata) -->
</span>
</button>
</th>
<th scope="col"><span>Stato</span></th>
<th scope="col" class="rtds-table-interactive__th-actions">
<span class="rtds-sr-only">Azioni</span>
</th>
</tr>
</thead>
<tbody class="rtds-table__body">
<tr class="rtds-table-interactive__row">
<td class="rtds-table-interactive__td-select">
<input type="checkbox"
class="rtds-table-interactive__select-row"
aria-label="Seleziona Mario Rossi">
</td>
<td>Mario Rossi</td>
<td><span class="rtds-chip rtds-chip--status is-open">Attivo</span></td>
<td><!-- dropdown-menu--actions --></td>
</tr>
</tbody>
</table>
</section>
<!-- Solo ordinamento -->
<section class="rtds-table-responsive" tabindex="0" aria-labelledby="table-classifica-caption">
<table class="rtds-table rtds-table-interactive" data-table-interactive>
<caption class="rtds-sr-only" id="table-classifica-caption">Classifica richiedenti</caption>
<thead class="rtds-table__head">
<tr>
<th scope="col" data-sort aria-sort="none">
<button type="button" class="rtds-table-interactive__sort-btn">
<span>Nome</span>
<span class="rtds-table-interactive__sort-icon" aria-hidden="true">
<!-- icona mini--sort-diamond (stato: non ordinata) -->
</span>
</button>
</th>
<th scope="col"><span>Stato</span></th>
</tr>
</thead>
<tbody class="rtds-table__body">
<tr class="rtds-table-interactive__row">
<td>Mario Rossi</td>
<td><span class="rtds-chip rtds-chip--status is-open">Attivo</span></td>
</tr>
</tbody>
</table>
</section>data-sort ai <th> per evitare il comportamento client-side automatico"1.250", "3.780,50")dropdown-menu.js sia già caricato nella paginaaria-label sulle checkbox per-riga deve essere impostato dal consumer con il nome della riga specifica<caption> è obbligatoria anche quando un titolo visibile è adiacente alla tabella