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'
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:
<Select
v-model="selected"
:options="cities"
option-label="name"
option-value="id"
/>
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:
<script setup lang="ts">
const options = ['Roma', 'Milano', 'Napoli']
const selected = ref(null)
</script>
<template>
<Select v-model="selected" :options="options" placeholder="Seleziona..." />
</template>
Funzione come optionLabel
<Select
v-model="selected"
:options="users"
:option-label="u => `${u.firstName} ${u.lastName}`"
option-value="id"
/>
Props
| Prop | Tipo | Default | Descrizione |
|---|---|---|---|
modelValue | OptionValue | OptionValue[] | null | Valore selezionato (v-model) |
options | T[] | [] | Array di opzioni |
optionLabel | string | ((o: T) => string) | null | Proprietà o funzione per il testo visualizzato |
optionValue | string | ((o: T) => OptionValue) | null | Proprietà o funzione per il valore |
optionDisabled | string | ((o: T) => boolean) | null | Proprietà o funzione per opzione disabilitata |
optionGroupLabel | string | ((o: T) => string) | null | Label del gruppo di opzioni |
optionGroupChildren | string | ((o: T) => unknown[]) | null | Proprietà con le opzioni figlie di un gruppo |
placeholder | string | — | Testo quando nessuna opzione è selezionata |
label | string | null | Label mostrata sopra il campo |
helperText | string | null | Testo di aiuto sotto il campo |
error | string | null | Messaggio di errore |
invalid | boolean | false | Stato di validazione invalido |
disabled | boolean | false | Disabilita il componente |
readonly | boolean | false | Campo in sola lettura |
required | boolean | false | Campo obbligatorio |
multiple | boolean | false | Abilita selezione multipla con chips |
filter | boolean | false | Mostra campo di ricerca nel dropdown |
filterMatchMode | 'startsWith' | 'contains' | 'endsWith' | 'contains' | Modalità di matching del filtro |
filterPlaceholder | string | — | Placeholder del campo filtro |
filterFields | string[] | null | Campi su cui applicare il filtro |
showClear | boolean | false | Mostra pulsante per azzerare la selezione |
checkmark | boolean | false | Mostra checkmark accanto all'opzione selezionata (single) |
editable | boolean | — | Permette di digitare testo libero oltre alle opzioni |
fluid | boolean | true | Occupa tutta la larghezza disponibile |
size | 'small' | 'medium' | 'large' | 'medium' | Dimensione del componente |
variant | 'outlined' | 'filled' | 'outlined' | Variante visiva |
severity | Severity | 'primary' | Colore tema |
loading | boolean | false | Stato di caricamento |
scrollHeight | string | '14rem' | Altezza massima del dropdown |
appendTo | 'body' | 'self' | 'body' | Target Teleport del dropdown |
dataKey | string | null | Chiave univoca per le opzioni (confronto oggetti) |
inputId | string | null | ID dell'input per accessibilità |
name | string | null | Nome per i form nativi |
ariaLabel | string | null | Aria label per screen reader |
ariaLabelledby | string | null | ID dell'elemento label ARIA |
autoFilterFocus | boolean | false | Focus automatico sul filtro all'apertura |
resetFilterOnHide | boolean | false | Resetta il filtro alla chiusura del dropdown |
highlightOnSelect | boolean | true | Evidenzia l'opzione selezionata nella lista |
focusOnHover | boolean | true | Sposta il focus all'opzione al passaggio del mouse |
autoOptionFocus | boolean | true | Sposta il focus sulla prima opzione all'apertura |
defaultValue | OptionValue | OptionValue[] | null | Valore predefinito se modelValue non è fornito |
visibleOptions | number | — | Numero di opzioni visibili senza scroll |
loadingIcon | string | — | Classe CSS icona di caricamento |
clearIcon | string | — | Classe CSS icona di cancellazione |
dropdownIcon | string | — | Classe CSS icona dropdown |
Emits
| Evento | Payload | Descrizione |
|---|---|---|
update:modelValue | OptionValue | 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 |
clear | Event | Selezione azzerata |
focus | Event | Il componente riceve il focus |
blur | Event | Il componente perde il focus |
keydown | KeyboardEvent | Pressione tasto |
keyup | KeyboardEvent | Rilascio tasto |
beforeShow | — | Prima dell'apertura del dropdown |
show | — | Dropdown aperto |
beforeHide | — | Prima della chiusura del dropdown |
hide | — | Dropdown chiuso |
Slot
| Slot | Scope | Descrizione |
|---|---|---|
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 |
header | — | Contenuto in cima al dropdown |
footer | — | Contenuto in fondo al dropdown |
content | { options, value, selectOption } | Override completo del contenuto del dropdown |
empty | — | Messaggio quando non ci sono opzioni |
emptyfilter | — | Messaggio quando il filtro non produce risultati |
loader | — | Stato di caricamento nel dropdown |
loadingicon | — | Icona di caricamento personalizzata |
clearicon | — | Icona 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
Slot option personalizzato
<Select v-model="selected" :options="countries" option-label="name" option-value="code">
<template #option="{ option, selected }">
<span class="flex items-center gap-2">
<img :src="`/flags/${option.code}.png`" class="w-5 h-4" />
<span>{{ option.name }}</span>
<span v-if="selected" class="ml-auto text-primary-600">✓</span>
</span>
</template>
</Select>
Evento change con dettagli completi
<Select
v-model="selected"
:options="cities"
option-label="name"
option-value="id"
@change="({ value, selectedOption }) => console.log(value, selectedOption)"
/>
Accessibilità
- Il trigger ha
role="combobox"conaria-expandedearia-haspopup - Supporto navigazione tastiera:
ArrowDown/Upnaviga le opzioni,Enter/Spaceseleziona,Escapechiude - Type-ahead: digitando una lettera naviga direttamente all'opzione corrispondente (con dropdown chiuso seleziona direttamente)
- Input nascosto associato alla label tramite
idper compatibilità con form nativi aria-labelearia-labelledbyconfigurabili- Ogni opzione ha
role="option"earia-selected - Il trigger è escluso dal tab order quando
disabled
TypeScript
import type { SelectProps, SelectEmits } from '@pzeta/vue-components'
// Uso tipizzato
const cities: Array<{ id: number; name: string }> = [
{ id: 1, name: 'Roma' },
{ id: 2, name: 'Milano' },
]
const selected = ref<number | null>(null)
Rating
Componente di valutazione a stelle con numero configurabile di stelle, icone personalizzabili, modalità readonly e pulsante di annullamento.
SelectableCard
Griglia di card selezionabili come alternativa visuale a radio button e checkbox. Supporta immagini, icone, selezione singola e multipla con layout configurabile a colonne.