<div class="rtds-select">

    <select id="" class="" disabled>
        <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 class="rtds-select{% block wrapperClasses %}{% if wrapperClasses %} {{ wrapperClasses }}{% endif %}{% endblock %}{% if hasError %} has-error{% endif %}{% if iconPlaceholder %} has-icon{% endif %}">
  {% set errorId = id ~ 'Error' %}
  {% if iconPlaceholder %} {% render '@icon', {id: iconPlaceholder, classes: 'rtds-absolute rtds-left-4 rtds-content-placeholder', size: 'rtds-w-6 rtds-h-6'}, true %} {% endif
  %}
  <select
    id="{{ id }}"
    class="{% if padding %}{{ padding }} {% endif %}{% if border %}{{ border }} {% endif %}{% if radius %}{{ radius }} {% endif %}{% if classes %} {{ classes }}{% endif %}{% if iconAlert %} rtds-pr-16{% endif %}"
      {% if shortLabel %} data-label="{{ shortLabel }}"{% endif %}
      {% if fieldRequired %} aria-required="true"{% endif %}
      {% if ariaDescribedBy or hasErrorControl or fieldRequired %} aria-describedBy="
        {%- if hasErrorControl or fieldRequired -%}
        {{- errorId -}}
          {%- if ariaDescribedBy %} {{ ariaDescribedBy -}}{%- endif -%}
        {% elseif ariaDescribedBy -%}
        {{- ariaDescribedBy -}}
        {% endif %}"
      {% endif %}
      {% if ariaInvalid %} aria-invalid="true"{% endif %}
      {% if disabled %} disabled{% endif %}
  >
    <option value="1">{% if placeholder %}{{ placeholder }}{% else %}Text{% endif %}</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>
    {%- if iconAlert %}
    {% render '@icon', {id: 'outline--exclamation-circle', classes: 'rtds-absolute rtds-right-8 rtds-content-placeholder rtds-content-error', size: 'rtds-w-6 rtds-h-6'}, true %}
  {% endif -%}
</div>
{
  "disabled": true
}
  • Content:
    /**
     * SELECT COMPONENT
     *
     *
    */
    .rtds-select {
        position: relative;
        display: flex;
        align-items: center;
    }
    :where(.rtds-select) select {
        height: var(--spacing-11);
        width: 100%;
        padding-top: var(--spacing-2);
        padding-bottom: var(--spacing-2);
        padding-left: var(--spacing-3);
        padding-right: var(--spacing-10);
        font-size: var(--fontsize-text-sm);
        font-weight: 600;
            color: var(--color-content-placeholder);
            color: var(--color-input-placeholder);
            border-color: var(--color-border-input);
        border-radius: 0.5rem;
        border-width: 1px;
    }
    /* Error */
    .rtds-select.has-error select,
        .is-invalid .rtds-select select {
        border-width: 2px;
        border-color: var(--color-error-dark);
    }
    /* Sizes */
    :where(.rtds-select--sm) select {
        height: var(--spacing-8);
        background-position: right 0.25rem center;
        padding-top: var(--spacing-0-5);
        padding-bottom: var(--spacing-0-5);
        padding-left: var(--spacing-2);
        padding-right: var(--spacing-8);
    }
    :where(.rtds-select--lg) select {
        height: var(--spacing-14);
        background-position: right 0.75rem center;
        padding-left: var(--spacing-3);
        padding-right: var(--spacing-12);
        padding-top: var(--spacing-3);
        padding-bottom: var(--spacing-3);
    }
    /* Select light */
    :where(.rtds-select--light) select {
        border-radius: 0px;
        border-top-width: 0px;
        border-right-width: 0px;
        border-left-width: 0px;
    }
    /* DISABLED STATE */
    :where(.rtds-select) select:disabled {
            color: var(--color-content-disabled);
            border-color: var(--color-border-gray-03);
            cursor: not-allowed;
        }
    
  • URL: /components/raw/select/select.built.css
  • Filesystem Path: components/02-atoms/_select/select.built.css
  • Size: 1.6 KB
  • Content:
    /**
     * SELECT COMPONENT
     *
     *
    */
    @layer components {
        .rtds-select {
            @apply rtds-flex rtds-items-center rtds-relative;
        }
        
        :where(.rtds-select) select {
            @apply rtds-w-full rtds-h-11 rtds-input-placeholder rtds-content-placeholder rtds-py-2 rtds-pl-3 rtds-pr-10 rtds-border rtds-border-input rtds-rounded-lg rtds-text-sm rtds-font-semibold;
        }
        
        /* Error */
        .rtds-select.has-error select,
        .is-invalid .rtds-select select {
            @apply rtds-border-2 rtds-border-error-dark;
        }
    
        /* Sizes */
        :where(.rtds-select--sm) select {
            @apply rtds-h-8 rtds-py-0.5 rtds-pl-2 rtds-pr-8 rtds-bg-[right_0.25rem_center];
        }
    
        :where(.rtds-select--lg) select {
            @apply rtds-h-14 rtds-py-3 rtds-pl-3 rtds-pr-12 rtds-bg-[right_0.75rem_center];
        }
    
        /* Select light */
        :where(.rtds-select--light) select {
            @apply rtds-rounded-none rtds-border-t-0 rtds-border-r-0 rtds-border-l-0;
        }
    
        /* DISABLED STATE */
        :where(.rtds-select) select:disabled {
            color: var(--color-content-disabled);
            border-color: var(--color-border-gray-03);
            cursor: not-allowed;
        }
    }
  • URL: /components/raw/select/select.css
  • Filesystem Path: components/02-atoms/_select/select.css
  • Size: 1.2 KB

Select

Componente campo di selezione. Utilizzato come partial all’interno di select-field (03-molecules). Deve essere sempre accoppiato a una <label>.


Comportamento

Il componente viene renderizzato come <select> avvolto in un <div> contenitore. Le opzioni sono predefinite nel template; in produzione vengono iniettate dinamicamente dal CMS.


Varianti

Varianti di Dimensione

  • sm: Dimensione ridotta (wrapperClasses: rtds-select--sm)
  • lg: Dimensione grande (wrapperClasses: rtds-select--lg)

Varianti di Stile

  • default: Dimensione e stile standard
  • light: Stile minimal — bordi solo in basso, senza bordi laterali (wrapperClasses: rtds-select--light)
  • has-icon: Con icona decorativa a sinistra
  • has-error: Stato di errore

Varianti di Stato

  • disabled: Campo non disponibile — escluso dal tab order, non inviato nel form

Parametri di configurazione

Contesto di sviluppo Fractal/Nunjucks — Questa sezione riguarda esclusivamente i parametri del context .config.yml usati durante lo sviluppo nella libreria. Non descrive attributi HTML o proprietà da usare nei temi, CMS o ambienti di implementazione: per quello, fare riferimento alla sezione Esempi di utilizzo.

  • id (stringa, obbligatorio): ID del <select>; serve anche per collegare la <label> tramite for
  • placeholder (stringa, opzionale): Testo dell’opzione di default (valore vuoto)
  • classes (stringa, opzionale): Classi CSS aggiuntive sull’elemento <select>
  • wrapperClasses (stringa, opzionale): Classi CSS aggiuntive sul <div> wrapper
  • padding (stringa, opzionale): Classe di padding personalizzata
  • border (stringa, opzionale): Classe di bordo personalizzata
  • radius (stringa, opzionale): Classe di border-radius personalizzata
  • iconPlaceholder (stringa, opzionale): ID icona decorativa a sinistra
  • iconAlert (booleano, opzionale): Se true, mostra l’icona di errore (⚠) posizionata a sinistra della freccia nativa del browser
  • shortLabel (stringa, opzionale): Etichetta breve stampata nel data-label; necessaria per la gestione degli errori via JS
  • fieldRequired (booleano, opzionale): Se true, aggiunge aria-required="true" e il wrapper per il messaggio di errore
  • ariaDescribedBy (stringa, opzionale): ID dell’elemento descrittivo del campo
  • hasErrorControl (booleano, opzionale): Se true, aggiunge il wrapper per il messaggio di errore e collega aria-describedby
  • ariaInvalid (booleano, opzionale): Se true, aggiunge aria-invalid="true" per indicare il campo in errore
  • disabled (booleano, opzionale): Se true, aggiunge l’attributo disabled — il campo è non interattivo, escluso dal tab order e non inviato nel form

Nota: <select> non supporta l’attributo readonly nativo. Se occorre un select “visibile ma non modificabile”, usare un campo di testo con readonly affiancato a un <input type="hidden"> che trasporta il valore nel form.


Accessibilità

WCAG 2.1

Livello AA — criteri pertinenti:

  • 1.3.1 Informazioni e correlazioni — il campo è associato alla <label> tramite id/for
  • 3.3.1 Identificazione degli errori — aria-invalid e aria-describedby collegano il messaggio di errore
  • 3.3.2 Etichette o istruzioni — il campo deve sempre essere accoppiato a una <label> esplicita
  • 4.1.2 Nome, Ruolo, Valore — attributi ARIA comunicano stato e vincoli

Struttura e semantica

  • Il componente è renderizzato come <select> — elemento nativo che garantisce interazione da tastiera, apertura del menu opzioni e semantica form senza ARIA aggiuntivo
  • Il <div> wrapper non ha ruolo semantico; serve solo come contenitore per il posizionamento delle icone

Attributi ARIA

Attributo Valori Condizione
aria-required "true" quando fieldRequired è attivo
aria-describedby ID del messaggio di errore / di descrizione quando hasErrorControl, fieldRequired o ariaDescribedBy sono presenti
aria-invalid "true" quando ariaInvalid è attivo (campo in errore)
Tasto Azione
Tab / Shift+Tab Sposta il focus sul/dal campo
/ Naviga tra le opzioni della lista
Space / Enter Apre il menu delle opzioni (comportamento nativo del browser)

Gestione del focus

  • Focus visibile: lo stile :focus-visible è sempre visibile e non viene rimosso via CSS

Screen reader

  • aria-required="true" — lo screen reader annuncia il campo come obbligatorio (preferito all’attributo required nativo per maggiore compatibilità)
  • aria-describedby — collega il campo al <div id="{id}Error"> con il messaggio di errore; lo screen reader legge il messaggio quando il campo ottiene il focus
  • aria-invalid="true" — lo screen reader annuncia lo stato di errore del campo
  • Le icone decorative interne al wrapper hanno aria-hidden="true" — lo screen reader le ignora

Stili CSS

Classi Base

  • .rtds-select: Stile base del wrapper

Classi Modificatori di Dimensione

  • .rtds-select--sm: Dimensione ridotta (h-8, padding ridotto)
  • .rtds-select--lg: Dimensione grande (h-14, padding aumentato)

Classi Modificatori di Stile

  • .rtds-select--light: Bordi solo in basso — nessun bordo laterale o superiore

Classi di Stato

  • .has-error: Applicata al wrapper quando il campo è in errore (bordo rosso doppio)
  • .has-icon: Applicata al wrapper quando è presente un’icona decorativa

Esempi di utilizzo

<!-- Select base -->
<div class="rtds-select">
  <select id="opzione">
    <option value="">Seleziona un'opzione</option>
    <option value="1">Opzione 1</option>
    <option value="2">Opzione 2</option>
  </select>
</div>

<!-- Select in stato di errore -->
<div class="rtds-select has-error">
  <select id="opzione-err" aria-invalid="true" aria-describedby="opzioneError">
    <option value="">Seleziona un'opzione</option>
  </select>
  <div id="opzioneError">Seleziona un'opzione valida</div>
</div>