Forms

Select

Dropdown di selezione singola o multipla con supporto a filtro, opzioni raggruppate e chips. Componente custom con navigazione tastiera e type-ahead integrati.

Import

import { Select } from '@pzeta/vue-components'

Quando usarlo

ScenarioComponente consigliato
Selezione singola da elenco chiuso (≤ ~50 opzioni), eventualmente con filtroSelect
Selezione multipla da elenco chiuso con chipsSelect con multiple o MultiSelect
Selezione con ricerca asincrona o suggerimenti progressiviAutoComplete
Lista lunga sempre visibile (no popup)Listbox
Scelta visuale con icone/immaginiSelectableCard

Esempio Base

Opzioni: oggetti vs stringhe

Array di oggetti (caso tipico)

Specificare option-label e option-value per indicare quali proprietà usare come etichetta e valore:

Il v-model conterrà il valore della proprietà option-value (id nell'esempio sopra), non l'intero oggetto.

Array di stringhe

Se le opzioni sono stringhe primitive, omettere option-label e option-value:

Funzione come optionLabel

Props

PropTipoDefaultDescrizione
modelValueOptionValue | OptionValue[]nullValore selezionato (v-model)
optionsT[][]Array di opzioni
optionLabelstring | ((o: T) => string)nullProprietà o funzione per il testo visualizzato
optionValuestring | ((o: T) => OptionValue)nullProprietà o funzione per il valore
optionDisabledstring | ((o: T) => boolean)nullProprietà o funzione per opzione disabilitata
optionGroupLabelstring | ((o: T) => string)nullLabel del gruppo di opzioni
optionGroupChildrenstring | ((o: T) => unknown[])nullProprietà con le opzioni figlie di un gruppo
placeholderstringlocaleTesto quando nessuna opzione è selezionata (default da i18n form.selectPlaceholder)
hidePlaceholderWhenSelectedbooleantrueNasconde il placeholder quando un'opzione è selezionata
labelstringnullLabel mostrata sopra il campo
helperTextstringnullTesto di aiuto sotto il campo
errorstringnullMessaggio di errore
invalidbooleanfalseStato di validazione invalido
disabledbooleanfalseDisabilita il componente
readonlybooleanfalseCampo in sola lettura
requiredbooleanfalseCampo obbligatorio
multiplebooleanfalseAbilita selezione multipla con chips
filterbooleanfalseMostra campo di ricerca nel dropdown
filterMatchMode'startsWith' | 'contains' | 'endsWith''contains'Modalità di matching del filtro
filterPlaceholderstringlocalePlaceholder del campo filtro (default da i18n form.searchPlaceholder)
filterFieldsstring[]nullCampi su cui applicare il filtro
filterLocalestringnullLocale per il confronto stringhe nel filtro
showClearbooleanfalseMostra pulsante per azzerare la selezione
checkmarkbooleanfalseMostra checkmark accanto all'opzione selezionata (single)
editablebooleanfalsePermette di digitare testo libero oltre alle opzioni
fluidbooleantrueOccupa tutta la larghezza disponibile
selectOnFocusbooleanfalseSeleziona automaticamente l'opzione al focus
virtualScrollerOptions{ itemSize?: number } | nullnullConfigurazione del virtual scroller per liste molto lunghe. Impostando itemSize (altezza in px di ogni opzione) si attiva la virtualizzazione (row windowing), che riduce i nodi DOM renderizzati. Non compatibile con le opzioni raggruppate
size'small' | 'medium' | 'large''medium'Dimensione del componente
variant'outlined' | 'filled''outlined'Variante visiva
severitySeverity'primary'Colore tema
loadingbooleanfalseStato di caricamento
scrollHeightstring'14rem'Altezza massima del dropdown
appendTo'body' | 'self''body'Target Teleport del dropdown
dataKeystringnullChiave univoca per le opzioni (confronto oggetti)
inputIdstringnullID dell'input per accessibilità
namestringnullNome per i form nativi
ariaLabelstringnullAria label per screen reader
ariaLabelledbystringnullID dell'elemento label ARIA
autoFilterFocusbooleanfalseFocus automatico sul filtro all'apertura
resetFilterOnHidebooleanfalseResetta il filtro alla chiusura del dropdown
highlightOnSelectbooleantrueEvidenzia l'opzione selezionata nella lista
focusOnHoverbooleantrueSposta il focus all'opzione al passaggio del mouse
autoOptionFocusbooleantrueSposta il focus sulla prima opzione all'apertura
defaultValueOptionValue | OptionValue[]nullValore predefinito se modelValue non è fornito
visibleOptionsnumberNumero di opzioni visibili senza scroll
loadingIconstringClasse CSS icona di caricamento
clearIconstringClasse CSS icona di cancellazione
dropdownIconstringClasse CSS icona dropdown

Emits

EventoPayloadDescrizione
update:modelValueOptionValue | OptionValue[]Aggiornamento v-model
change{ originalEvent: Event, value: OptionValue | OptionValue[], selectedOption: T | T[] | null }Cambio di selezione con dettagli completi
filter{ originalEvent: Event, value: string }Cambio del testo filtro
clearEventSelezione azzerata
focusEventIl componente riceve il focus
blurEventIl componente perde il focus
keydownKeyboardEventPressione tasto
keyupKeyboardEventRilascio tasto
beforeShowPrima dell'apertura del dropdown
showDropdown aperto
beforeHidePrima della chiusura del dropdown
hideDropdown chiuso

Slot

SlotScopeDescrizione
value{ value, placeholder }Personalizza la visualizzazione del valore selezionato
option{ option, selected, index }Template per ogni singola opzione
optiongroup{ option }Template per l'intestazione del gruppo
headerContenuto in cima al dropdown
footerContenuto in fondo al dropdown
content{ options, value, selectOption }Override completo del contenuto del dropdown
emptyMessaggio quando non ci sono opzioni
emptyfilterMessaggio quando il filtro non produce risultati
loaderStato di caricamento nel dropdown
loadingiconIcona di caricamento personalizzata
cleariconIcona del pulsante clear personalizzata
dropdownicon{ expanded: boolean }Icona del dropdown personalizzata

Esempi

Con filtro di ricerca

Selezione multipla

In modalità multipla il v-model è un array di valori. Le opzioni selezionate vengono mostrate come chips rimuovibili nel trigger:

Opzioni raggruppate

Varianti e dimensioni

Con pulsante clear

Stati

Editable (testo libero)

Con editable=true l'utente può inserire un valore non presente nelle opzioni:

Async / loading

Slot option personalizzato

Evento change con dettagli completi

Accessibilità

  • Il trigger ha role="combobox" con aria-expanded e aria-haspopup
  • Supporto navigazione tastiera: ArrowDown/Up naviga le opzioni, Enter/Space seleziona, Escape chiude
  • Type-ahead: digitando una lettera naviga direttamente all'opzione corrispondente (con dropdown chiuso seleziona direttamente)
  • Input nascosto associato alla label tramite id per compatibilità con form nativi
  • aria-label e aria-labelledby configurabili
  • Ogni opzione ha role="option" e aria-selected
  • Il trigger è escluso dal tab order quando disabled

TypeScript

SelectProps e SelectEmits sono generici sul tipo dell'opzione (default Record<string, unknown>):

import type { SelectProps, SelectEmits } from '@pzeta/vue-components'

interface City {
  id: number
  name: string
  region?: string
}

const cities: City[] = [
  { id: 1, name: 'Roma', region: 'Lazio' },
  { id: 2, name: 'Milano', region: 'Lombardia' },
]

const selected = ref<number | null>(null)

// In un wrapper generico:
type CitySelectProps = SelectProps<City>
type CitySelectEmits = SelectEmits<City>

Il payload di change include selectedOption tipizzata come T | T[] | null — utile per accedere all'oggetto completo senza ricerche manuali nell'array options.

Note

  • Default fluid: true — il componente per default occupa tutta la larghezza del contenitore. Imposta :fluid="false" per usare width auto.
  • Placeholder/filterPlaceholder via i18n — se non specificati, vengono presi da form.selectPlaceholder e form.searchPlaceholder del dizionario @pzeta/vue-i18n.
  • appendTo='body' — il dropdown viene teleportato sul <body> per evitare clipping da overflow. Per dropdown all'interno di overlay (Dialog, Drawer) o test e2e potresti dover usare appendTo='self'.