<div class="rtds-progress-indicator-wrapper">

    <label class="rtds-progress-indicator__label rtds-sr-only" for="rtds-progress-sr">Avanzamento pratica</label>

    <progress id="rtds-progress-sr" class="rtds-progress-indicator" value="50" max="100">50%</progress>
</div>
{% set _percent = ((value | default(0)) / (max | default(100)) * 100) | round %}
<div class="rtds-progress-indicator-wrapper{% if classes %} {{ classes }}{% endif %}">
  {% if labelHidden %}
  <label class="rtds-progress-indicator__label rtds-sr-only" for="{{ id | default('rtds-progress') }}">{{ label | default('Avanzamento') }}</label>
  {% else %}
  <div class="rtds-progress-indicator__header">
    <label class="rtds-progress-indicator__label" for="{{ id | default('rtds-progress') }}">{{ label | default('Avanzamento') }}</label>
    {% if showValue %}<span class="rtds-progress-indicator__value" aria-hidden="true">{{ _percent }}%</span>{% endif %}
  </div>
  {% endif %}
  <progress
    id="{{ id | default('rtds-progress') }}"
    class="rtds-progress-indicator{% if indeterminate %} rtds-progress-indicator--indeterminate{% endif %}"
    {% if not indeterminate %}value="{{ value | default(0) }}"{% endif %}
    max="{{ max | default(100) }}"
  >{% if not indeterminate %}{{ _percent }}%{% endif %}</progress>
</div>
{
  "id": "rtds-progress-sr",
  "value": 50,
  "max": 100,
  "label": "Avanzamento pratica",
  "labelHidden": true,
  "showValue": false,
  "indeterminate": false
}
  • Content:
    .rtds-progress-indicator {
            --_progress-fill: var(--progress-fill, var(--color-button-primary, var(--color-primary-500)));
            --_progress-bg:   var(--progress-bg,   var(--color-neutral-200));
            -moz-appearance: none;
                 appearance: none;
            -webkit-appearance: none;
            display: block;
            width: 100%;
            height: var(--spacing-2);
            border: none;
            background-color: var(--_progress-bg);
            border-radius: 9999px;
            overflow: hidden;
        }
    .rtds-progress-indicator-wrapper {
            display: flex;
            flex-direction: column;
            gap: var(--spacing-2);
        }
    .rtds-progress-indicator__header {
            display: flex;
            justify-content: space-between;
            align-items: baseline;
            gap: var(--spacing-2);
        }
    .rtds-progress-indicator__label {
            font-size: var(--fontsize-text-sm);
            color: var(--color-content-01, var(--color-neutral-900));
            font-weight: 600;
        }
    .rtds-progress-indicator__value {
            font-size: var(--fontsize-text-sm);
            color: var(--color-content-01, var(--color-neutral-900));
            font-weight: 600;
            white-space: nowrap;
        }
    /* WebKit (Chrome, Safari, Edge) */
    .rtds-progress-indicator::-webkit-progress-bar {
            background-color: var(--_progress-bg);
            border-radius: 9999px;
        }
    .rtds-progress-indicator::-webkit-progress-value {
            background-color: var(--_progress-fill);
            border-radius: 9999px;
        }
    /* Firefox */
    .rtds-progress-indicator::-moz-progress-bar {
            background-color: var(--_progress-fill);
            border-radius: 9999px;
        }
    /* Indeterminate */
    @keyframes rtds-progress-indeterminate {
            0%   { background-position: 100% center; }
            100% { background-position: -100% center; }
        }
    .rtds-progress-indicator--indeterminate {
            background: linear-gradient(
                90deg,
                var(--_progress-bg) 0%,
                var(--_progress-fill) 40%,
                var(--_progress-fill) 60%,
                var(--_progress-bg) 100%
            );
            background-size: 200% 100%;
            animation: rtds-progress-indeterminate 1.5s ease-in-out infinite;
        }
    .rtds-progress-indicator--indeterminate::-webkit-progress-bar {
            background: transparent;
        }
    .rtds-progress-indicator--indeterminate::-webkit-progress-value {
            background: transparent;
        }
    .rtds-progress-indicator--indeterminate::-moz-progress-bar {
            background: transparent;
        }
    
  • URL: /components/raw/progress-indicator/progress-indicator.built.css
  • Filesystem Path: components/08-servizi/progress-indicator/progress-indicator.built.css
  • Size: 2.5 KB
  • Content:
    @layer components {
        .rtds-progress-indicator {
            --_progress-fill: var(--progress-fill, var(--color-button-primary, var(--color-primary-500)));
            --_progress-bg:   var(--progress-bg,   var(--color-neutral-200));
            appearance: none;
            -webkit-appearance: none;
            display: block;
            width: 100%;
            height: var(--spacing-2);
            border: none;
            background-color: var(--_progress-bg);
            border-radius: 9999px;
            overflow: hidden;
        }
    
        .rtds-progress-indicator-wrapper {
            display: flex;
            flex-direction: column;
            gap: var(--spacing-2);
        }
    
        .rtds-progress-indicator__header {
            display: flex;
            justify-content: space-between;
            align-items: baseline;
            gap: var(--spacing-2);
        }
    
        .rtds-progress-indicator__label {
            font-size: var(--fontsize-text-sm);
            color: var(--color-content-01, var(--color-neutral-900));
            font-weight: 600;
        }
    
        .rtds-progress-indicator__value {
            font-size: var(--fontsize-text-sm);
            color: var(--color-content-01, var(--color-neutral-900));
            font-weight: 600;
            white-space: nowrap;
        }
    
        /* WebKit (Chrome, Safari, Edge) */
        .rtds-progress-indicator::-webkit-progress-bar {
            background-color: var(--_progress-bg);
            border-radius: 9999px;
        }
    
        .rtds-progress-indicator::-webkit-progress-value {
            background-color: var(--_progress-fill);
            border-radius: 9999px;
        }
    
        /* Firefox */
        .rtds-progress-indicator::-moz-progress-bar {
            background-color: var(--_progress-fill);
            border-radius: 9999px;
        }
    
        /* Indeterminate */
        @keyframes rtds-progress-indeterminate {
            0%   { background-position: 100% center; }
            100% { background-position: -100% center; }
        }
    
        .rtds-progress-indicator--indeterminate {
            background: linear-gradient(
                90deg,
                var(--_progress-bg) 0%,
                var(--_progress-fill) 40%,
                var(--_progress-fill) 60%,
                var(--_progress-bg) 100%
            );
            background-size: 200% 100%;
            animation: rtds-progress-indeterminate 1.5s ease-in-out infinite;
        }
    
        .rtds-progress-indicator--indeterminate::-webkit-progress-bar {
            background: transparent;
        }
    
        .rtds-progress-indicator--indeterminate::-webkit-progress-value {
            background: transparent;
        }
    
        .rtds-progress-indicator--indeterminate::-moz-progress-bar {
            background: transparent;
        }
    }
    
  • URL: /components/raw/progress-indicator/progress-indicator.css
  • Filesystem Path: components/08-servizi/progress-indicator/progress-indicator.css
  • Size: 2.6 KB

Progress Indicator

Barra di progresso percentuale per processi multi-step e flussi di caricamento. Basato sull’elemento HTML nativo <progress> con CSS cross-browser e triple fallback per la tematizzazione dal CMS ospitante.


Comportamento

Il componente renderizza sempre un <div class="rtds-progress-indicator-wrapper"> contenitore con:

  • Un <label for="id"> associato alla barra — sempre presente nel markup; visibile o rtds-sr-only in base al parametro labelHidden
  • Quando labelHidden: false: un <div class="rtds-progress-indicator__header"> flex-row con etichetta e, opzionalmente, la percentuale testuale allineata a destra (showValue: true)
  • Quando labelHidden: true: il <label> è inserito direttamente nel wrapper senza header visivo
  • Un elemento <progress id="id"> nativo con il valore percentuale come testo interno (fallback per browser non supportati)

Varianti

Varianti di Etichetta

  • default<label> visibile senza percentuale
  • with-value<label> visibile con percentuale a destra
  • label-sr-only<label> nascosta visivamente, disponibile agli AT

Varianti di Percentuale

  • 0-percent: Barra a 0%
  • 25-percent: Barra al 25%
  • label-sr-only / default (50%): Barra al 50%
  • 75-percent: Barra al 75%
  • 100-percent: Barra al 100% (completato)

Variante Speciale

  • indeterminate: Animazione infinita, nessun valore specifico

Parametri di configurazione

Parametro Tipo Obbligatorio Default Descrizione
id stringa 'rtds-progress' ID univoco — collega <label for> a <progress id>; deve essere unico in pagina
label stringa no 'Avanzamento' Testo dell’etichetta
labelHidden booleano no false Se true, applica rtds-sr-only al <label> e non mostra l’header
showValue booleano no false Se true e labelHidden: false, mostra la percentuale testuale allineata a destra dell’etichetta
value numero no 0 Valore corrente del progresso
max numero no 100 Valore massimo
indeterminate booleano no false Se true, omette value e aggiunge la classe --indeterminate
classes stringa no Classi CSS aggiuntive sul contenitore wrapper

Accessibilità

WCAG 2.2

Livello AA — criteri pertinenti:

  • 1.3.1 Informazioni e correlazioni — il <label> associa semanticamente l’etichetta alla barra
  • 1.4.1 Uso del colore — la barra è accompagnata da etichetta testuale (visibile o sr-only)
  • 1.4.3 Contrasto minimo — la barra ha contrasto sufficiente rispetto alla traccia

Struttura e semantica

  • <progress> — elemento nativo con ruolo implicito progressbar; espone aria-valuenow, aria-valuemin e aria-valuemax automaticamente dal browser
  • <label for="id"> — associazione semantica nativa; non richiede aria-label o aria-labelledby aggiuntivi sul <progress>
  • Il testo percentuale dentro <progress> (es. 50%) è contenuto di fallback per browser che non supportano l’elemento nativo
  • rtds-progress-indicator__value ha aria-hidden="true": la percentuale visiva è ridondante rispetto allo stato nativo del <progress>
  • Con labelHidden: true, il <label> è rtds-sr-only: la barra mantiene un nome accessibile pur non mostrando testo visivo

Attributi ARIA

Nessun attributo ARIA aggiuntivo — la struttura semantica nativa (<label for> + <progress id>) è sufficiente.


Stili CSS

Classi Base

  • .rtds-progress-indicator-wrapper: Contenitore — flex colonna con gap: var(--spacing-2), sempre presente
  • .rtds-progress-indicator: Elemento <progress> — larghezza 100%, altezza var(--spacing-2), forma pill

Classi Elementi (BEM)

  • .rtds-progress-indicator__header: Riga flex space-between con <label> e percentuale opzionale (solo quando labelHidden: false)
  • .rtds-progress-indicator__label: Etichetta <label> — font-size sm, peso 600
  • .rtds-progress-indicator__value: Percentuale visiva allineata a destra — aria-hidden="true"

Tematizzazione

Il componente espone variabili CSS per la personalizzazione dal CMS ospitante tramite il pattern triple fallback.

Override pubblici (Tier 1)

Proprietà CSS Default DS Descrizione
--progress-fill var(--color-button-primary) Colore della barra di avanzamento
--progress-bg var(--color-neutral-200) Colore della traccia (sfondo barra)

Token semantici DS (Tier 2)

Token DS Fallback primitivo Descrizione
--color-button-primary #D0131A Rosso primario RT — colore riempimento
--color-neutral-200 #EAEFF5 Grigio chiaro — colore traccia

Esempi di utilizzo

<!-- Label visibile senza percentuale -->
<div class="rtds-progress-indicator-wrapper">
  <div class="rtds-progress-indicator__header">
    <label class="rtds-progress-indicator__label" for="prog-upload">Caricamento file</label>
  </div>
  <progress id="prog-upload" class="rtds-progress-indicator" value="50" max="100">50%</progress>
</div>

<!-- Label visibile con percentuale a destra -->
<div class="rtds-progress-indicator-wrapper">
  <div class="rtds-progress-indicator__header">
    <label class="rtds-progress-indicator__label" for="prog-step">Avanzamento procedimento</label>
    <span class="rtds-progress-indicator__value" aria-hidden="true">75%</span>
  </div>
  <progress id="prog-step" class="rtds-progress-indicator" value="75" max="100">75%</progress>
</div>

<!-- Label sr-only (solo barra visiva) -->
<div class="rtds-progress-indicator-wrapper">
  <label class="rtds-progress-indicator__label rtds-sr-only" for="prog-bg">Avanzamento in background</label>
  <progress id="prog-bg" class="rtds-progress-indicator" value="30" max="100">30%</progress>
</div>

<!-- Indeterminato -->
<div class="rtds-progress-indicator-wrapper">
  <label class="rtds-progress-indicator__label rtds-sr-only" for="prog-load">Caricamento in corso</label>
  <progress id="prog-load" class="rtds-progress-indicator rtds-progress-indicator--indeterminate" max="100"></progress>
</div>

Avanzamento caricamento di una sezione di pagina

Quando la barra descrive il caricamento di una regione specifica della pagina, collegare i due elementi tramite aria-describedby sulla sezione e aria-busy="true" finché il caricamento non è completato. Questo segnala agli screen reader che il contenuto è in aggiornamento e indica il progresso.

<!-- Stato: caricamento in corso -->
<section aria-busy="true" aria-describedby="prog-notizie">
  <!-- contenuto in caricamento -->
</section>

<div class="rtds-progress-indicator-wrapper">
  <label class="rtds-progress-indicator__label rtds-sr-only" for="prog-notizie">Caricamento notizie</label>
  <progress id="prog-notizie" class="rtds-progress-indicator" value="60" max="100">60%</progress>
</div>

<!-- Stato: caricamento completato (gestito via JavaScript) -->
<section aria-busy="false" aria-describedby="prog-notizie">
  <!-- contenuto caricato -->
</section>

<div class="rtds-progress-indicator-wrapper" hidden>
  <label class="rtds-progress-indicator__label rtds-sr-only" for="prog-notizie">Caricamento notizie</label>
  <progress id="prog-notizie" class="rtds-progress-indicator" value="100" max="100">100%</progress>
</div>

Al completamento del caricamento: impostare aria-busy="false" sulla sezione (o rimuovere l’attributo) e aggiornare value="100" prima di nascondere il wrapper — in questo modo gli AT annunciano il completamento prima che il componente sparisca.


Note

  • Il parametro id deve essere univoco in pagina: collega <label for> a <progress id> per l’associazione semantica nativa
  • Il testo dentro <progress> è contenuto di fallback per browser senza supporto nativo (es. IE8); non sostituisce la label accessibile
  • Il parametro showValue non ha effetto quando labelHidden: true — se l’etichetta è nascosta, anche la percentuale visiva non viene renderizzata
  • L’elemento <progress> nativo presenta stili browser molto specifici — gli stili cross-browser richiedono appearance: none + pseudo-elementi vendor-prefixed (::-webkit-progress-bar, ::-webkit-progress-value, ::-moz-progress-bar)
  • La gestione dell’avanzamento (aggiornamento del value) è responsabilità del consumer — il componente è display-only
  • Per processi multi-step in sequenza, combinare con il componente @steps