<div class="rtds-upload rtds-w-full rtds-space-y-5 md:rtds-space-y-6">
<!-- Pulsante principale per il caricamento -->
<div class="rtds-upload__button-area rtds-flex rtds-flex-col rtds-p-4 rtds-items-center rtds-justify-center rtds-gap-4 md:rtds-gap-6 rtds-background-01 rtds-border-dashed rtds-border-gray-03 rtds-border-2 rtds-rounded-md">
<div class="rtds-upload__description rtds-space-y-1.5">
<!--
note per accessibilità: il seguente paragrafo NON fornisce informazioni aggiuntive chi usa tecnologie assistive
così come è formulato è riferito all'esperienza utente che usa un mouse ecc (non tastiera o screen reader).
Inoltre fornisce indicazioni per la localizzazione del pulsante tramite posizionamento del pulsante stesso ("clicca sul pulsante qui sotto")
violando così il criterio di successo WCAG 1.3.3 -->
<p class="rtds-upload__help">Clicca il pulsante qui sotto per caricare i documenti dal tuo dispositivo.</p>
<!-- note per accessibilità: il seguente paragrafo fornisce informazioni aggiuntive chi usa tecnologie assistive
attraverso l'uso dell'id e dell'attributo aria-describedby="id-del-paragrafo" sull'input file-->
<p id="upload-help-text" class="rtds-upload__help">Formati <strong>PDF, DOCX, JPG, PNG</strong> - Max: <strong>10 MB per file</strong></p>
</div>
<input type="file" id="upload-input-file-upload-default" class="rtds-upload__input rtds-sr-only" aria-describedby="upload-help-text" multiple accept="image/*,.pdf,.doc,.docx">
<label for="upload-input-file-upload-default" class="rtds-upload__button rtds-btn rtds-btn--outlined rtds-content-01 rtds-border-gray-03 rtds-cursor-pointer">
<svg class="rtds-icon rtds-fill-current rtds-w-5 rtds-h-5" aria-hidden="true" focusable="false" role="img">
<use href="../../icons.svg#outline--arrow-up-on-square" />
</svg>
Carica file
</label>
</div>
<!-- Lista dei file caricati/in caricamento -->
</div>
<div class="rtds-upload rtds-w-full rtds-space-y-5 md:rtds-space-y-6">
<!-- Pulsante principale per il caricamento -->
<div class="rtds-upload__button-area rtds-flex rtds-flex-col rtds-p-4 rtds-items-center rtds-justify-center rtds-gap-4 md:rtds-gap-6 rtds-background-01 rtds-border-dashed rtds-border-gray-03 rtds-border-2 rtds-rounded-md">
<div class="rtds-upload__description rtds-space-y-1.5">
<!--
note per accessibilità: il seguente paragrafo NON fornisce informazioni aggiuntive chi usa tecnologie assistive
così come è formulato è riferito all'esperienza utente che usa un mouse ecc (non tastiera o screen reader).
Inoltre fornisce indicazioni per la localizzazione del pulsante tramite posizionamento del pulsante stesso ("clicca sul pulsante qui sotto")
violando così il criterio di successo WCAG 1.3.3 -->
<p class="rtds-upload__help">Clicca il pulsante qui sotto per caricare i documenti dal tuo dispositivo.</p>
<!-- note per accessibilità: il seguente paragrafo fornisce informazioni aggiuntive chi usa tecnologie assistive
attraverso l'uso dell'id e dell'attributo aria-describedby="id-del-paragrafo" sull'input file-->
<p id="upload-help-text" class="rtds-upload__help">Formati <strong>PDF, DOCX, JPG, PNG</strong> - Max: <strong>10 MB per file</strong></p>
</div>
<input
type="file"
id="upload-input-{{ 'file-upload-' + (loop.index if loop.index is defined else 'default') }}"
class="rtds-upload__input rtds-sr-only"
aria-describedby="upload-help-text"
{% if multiple %}multiple{% endif %}
{% if accept %}accept="{{ accept }}"{% endif %}
>
<label for="upload-input-{{ 'file-upload-' + (loop.index if loop.index is defined else 'default') }}" class="rtds-upload__button rtds-btn rtds-btn--outlined rtds-content-01 rtds-border-gray-03 rtds-cursor-pointer">
{% render '@icon', {
id: 'outline--arrow-up-on-square',
size: 'rtds-w-5 rtds-h-5'
}, true %}
{{ label or 'Carica file' }}
</label>
</div>
<!-- Lista dei file caricati/in caricamento -->
{% if files and files.length > 0 %}
<ul class="rtds-upload__file-list">
{% for file in files %}
<li class="rtds-upload__file">
{% render '@file' + file.variant, file.context, true %}
</li>
{% endfor %}
</ul>
{% endif %}
</div>
{
"label": "Carica file",
"multiple": true,
"accept": "image/*,.pdf,.doc,.docx",
"helpText": "Formato supportati: JPG, PNG, PDF, DOC, DOCX. Dimensione massima: 10MB per file.",
"maxFileSize": "10MB",
"files": []
}
/**
* UPLOAD COMPONENT
* Componente per il caricamento file
*/
.rtds-upload__button:focus-visible {
--tw-shadow: 0 0 0 7px rgba(255,255,255,1);
--tw-shadow-colored: 0 0 0 7px var(--tw-shadow-color);
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
outline: 2px solid transparent;
outline-offset: 2px;
--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color);
box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
--tw-ring-color: var(--color-focusring);
--tw-ring-offset-width: 2px;
--tw-ring-offset-color: #ffffff;
}
.rtds-upload__input:focus + .rtds-upload__button,
.rtds-upload__input:focus-visible + .rtds-upload__button {
--tw-shadow: 0 0 0 7px rgba(255,255,255,1);
--tw-shadow-colored: 0 0 0 7px var(--tw-shadow-color);
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
outline: 2px solid transparent;
outline-offset: 2px;
--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color);
box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
--tw-ring-color: var(--color-focusring);
--tw-ring-offset-width: 2px;
--tw-ring-offset-color: #ffffff;
}
.rtds-upload__description {
text-align: center;
font-size: var(--fontsize-text-sm);
color: var(--color-content-03);
}
@media (min-width: 768px) {
.rtds-upload__description {
font-size: var(--fontsize-text-base);
}
}
/* Lista file - Struttura ul/li */
.rtds-upload__file-list {
margin: var(--spacing-0);
list-style-type: none;
}
.rtds-upload__file-list > :not([hidden]) ~ :not([hidden]) {
--tw-space-y-reverse: 0;
margin-top: calc(var(--spacing-3) * calc(1 - var(--tw-space-y-reverse)));
margin-bottom: calc(var(--spacing-3) * var(--tw-space-y-reverse));
}
.rtds-upload__file-list {
padding: var(--spacing-0);
}
/**
* UPLOAD COMPONENT
* Componente per il caricamento file
*/
@layer components {
.rtds-upload__button {
@apply focus-visible:rtds-ring focus-visible:rtds-ring-offset-2 focus-visible:rtds-ring-offset-white focus-visible:rtds-ring-focusring focus-visible:rtds-shadow-[0_0_0_7px_rgba(255,255,255,1)] focus-visible:rtds-outline-none;
}
.rtds-upload__input:focus + .rtds-upload__button,
.rtds-upload__input:focus-visible + .rtds-upload__button {
@apply rtds-ring rtds-ring-offset-2 rtds-ring-offset-white rtds-ring-focusring rtds-shadow-[0_0_0_7px_rgba(255,255,255,1)] rtds-outline-none;
}
.rtds-upload__description {
@apply rtds-text-sm md:rtds-text-base rtds-text-center rtds-content-03;
}
/* Lista file - Struttura ul/li */
.rtds-upload__file-list {
@apply rtds-list-none rtds-p-0 rtds-m-0 rtds-space-y-3;
}
}
Componente per il caricamento di file basato sul Design System di Designers Italia, variante “Lista file” con rappresentazione statica degli stati.
Il componente Upload è un organismo che permette la rappresentazione dell’interfaccia di caricamento file con una struttura semantica ul/li seguendo esattamente le specifiche di Designers Italia. Il componente mostra diversi stati dei file (successo, caricamento, errore) in modo puramente visuale.
Utilizza questo componente quando è necessario mostrare l’interfaccia di caricamento file, come:
<ul class="upload-file-list"> e <li class="upload-file">rtds-sr-only per screen readerIl componente Upload utilizza il componente File separato (@file) per gestire la rappresentazione di ogni singolo file. Consulta la documentazione del componente File per maggiori dettagli sui parametri e comportamenti specifici.
Il componente è puramente rappresentativo e non include logica JavaScript. Mostra stati statici definiti nella configurazione. La lista dei file utilizza il componente separato @file per ogni elemento.
Ogni file viene renderizzato tramite il componente File che supporta i seguenti stati:
loading: File in caricamentoloading-error: Errore durante caricamento loading-completed: Caricamento completatodownload: File disponibile per downloadLivello AA — criteri pertinenti:
<input type="file"> è associato al suo <label> tramite for/id; aria-describedby collega l’input al testo di aiuto con le specifiche sui formati<ul> semantico; ogni file è un <li> che avvolge il componente @file<div class="rtds-upload"> — contenitore non semantico<input type="file"> è nascosto visivamente con rtds-sr-only — è ancora raggiungibile da tastiera; il <label> funge da pulsante cliccabile visibile<label> è associato all’input tramite for/id — attivare il label con Enter o Space apre il selettore file<ul class="rtds-upload__file-list"> — ogni elemento è un <li> che contiene il componente @file| Attributo | Valori | Condizione |
|---|---|---|
aria-describedby |
upload-help-text |
Sull’<input type="file"> — collega le specifiche sui formati e dimensioni accettati |
id="upload-help-text" |
stringa | Sul <p> con le specifiche — referenziato da aria-describedby |
Per gli attributi ARIA dei componenti file nella lista (progress bar, stato), consultare la documentazione del componente
@file.
| Tasto | Azione |
|---|---|
Tab / Shift+Tab |
Raggiunge il pulsante/label di caricamento e i pulsanti azione di ogni file nella lista |
Enter / Space |
Attiva il label di caricamento (apre il selettore file) o i pulsanti azione dei file |
:focus-visible è sempre visibile e non viene rimosso via CSS<input>, lo screen reader legge anche il testo di aria-describedby (“Formati PDF, DOCX, JPG, PNG - Max: 10 MB per file”) — fornisce informazioni sui vincoli senza doverli cercare visivamente<li> semantici — lo screen reader annuncia il numero di file nella lista quando vi entraContesto di sviluppo Fractal/Nunjucks — Questa sezione riguarda esclusivamente i parametri del context .config.yml usati durante lo sviluppo nella libreria. Non descrive attributi HTML da usare nei temi o ambienti di implementazione.
label (string)label: "Carica documenti"multiple (boolean)truemultiple: falseaccept (string)"image/*,.pdf,.doc,.docx""image/*"".pdf"".pdf,.doc,.docx,.txt"helpText (string)helpText: "Dimensione massima: 5MB per file"maxFileSize (string)"10MB""5MB", "2GB", "500KB"files (array)files:
- name: "documento.pdf"
size: "1.2MB"
status: "loading-completed" # loading, loading-error, loading-completed, download
progress: 100 # obbligatorio per stati loading
errorMessage: "Messaggio di errore" # solo per loading-errorcontext:
label: 'Carica documenti'context:
files:
- name: 'documento-caricamento.pdf'
size: '2.1MB'
status: 'loading'
progress: 65
- name: 'file-completato.jpg'
size: '850KB'
status: 'loading-completed'
progress: 100
- name: 'file-errore.pdf'
size: '15MB'
status: 'loading-error'
progress: 30
errorMessage: 'File troppo grande. Max 10MB'
- name: 'documento-download.docx'
size: '2.1MB'
status: 'download'.rtds-upload: Container principale.rtds-upload__button-area: Area pulsante di caricamento.rtds-upload__button: Pulsante di caricamento.rtds-upload__file-list: Lista file (ul)Le classi per i singoli file sono gestite dal componente File:
.rtds-upload__file: Singolo file (su elemento <li> che wrappa il componente rtds-file).rtds-file.is-loading: File in caricamento.rtds-file.is-loading-error: File con errore.rtds-file.is-loading-completed: File completato.rtds-file.is-download: File per downloadIl componente è completamente responsive:
rtds-rtds-sr-only per contesto