Forms

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.

Import

import { SelectableCard } from '@pzeta/vue-components'
import type { SelectableCardOption } from '@pzeta/vue-components'

Quando usarlo

ScenarioComponente consigliato
Scelta esclusiva con forte componente visuale (piani tariffari, categorie con icone/immagini, scelta veicolo)SelectableCard
Scelta esclusiva testuale, lista lunga di opzioniRadioButton
Scelta multipla testualeCheckbox array mode
Scelta multipla visuale (multi-tag con immagine)SelectableCard con multiple: true
Scelta da molte opzioni con ricercaSelect o AutoComplete

SelectableCard usa internamente <input type="radio"> (single) o <input type="checkbox"> (multiple) con sr-only, quindi è semanticamente corretto come gruppo di radio/checkbox e accessibile da screen reader e tastiera.

Struttura SelectableCardOption

interface SelectableCardOption {
  value: string | number    // Valore univoco
  title: string             // Titolo della card
  description?: string      // Descrizione opzionale
  image?: string            // URL immagine (priorità su icon)
  icon?: string             // Classe icona fallback se non c'è immagine (es. 'pi pi-desktop')
  disabled?: boolean        // Disabilita la singola card
}

Esempio Base

Props

PropTipoDefaultDescrizione
modelValuestring | number | (string | number)[]undefinedValore selezionato (v-model)
optionsSelectableCardOption[][]Array di card disponibili
multiplebooleanfalseAbilita selezione multipla (checkbox invece di radio)
columns1 | 2 | 3 | 4 | 63Numero di colonne nella griglia
size'sm' | 'md' | 'lg''md'Dimensione delle card
disabledbooleanfalseDisabilita globalmente tutte le card
showCheckboxbooleantrueMostra l'indicatore di selezione (checkmark) sulla card

Emits

EventoPayloadDescrizione
update:modelValuestring | number | (string | number)[]Aggiornamento v-model
changestring | number | (string | number)[]Cambio selezione (stesso payload di update:modelValue)
selectSelectableCardOptionOpzione selezionata con tutti i suoi dati

Esempi

Selezione multipla

In modalità multipla il v-model è un array. Le card usano internamente <input type="checkbox">:

Con icone invece di immagini

Se non viene fornita un'immagine, viene mostrata l'icona:

image ha priorità su icon. Se entrambi sono assenti, la card mostra solo titolo e descrizione senza area cover.

Con immagini reali

Dimensioni

Opzione singola disabilitata

Senza indicatore di selezione

Gestione eventi

Comportamento di selezione

  • Selezione singola (multiple: false): usa <input type="radio"> internamente con name auto-generato (selectable-card-{useId}) condiviso fra tutte le card del gruppo. Cliccando una card già selezionata, rimane selezionata (comportamento radio nativo).
  • Selezione multipla (multiple: true): usa <input type="checkbox"> senza attributo name. Cliccando una card selezionata la deseleziona.
  • Card disabilitata: il prop disabled globale disabilita tutte le card; option.disabled disabilita solo quella specifica card.
  • Layout: la prop columns è statica (1, 2, 3, 4 o 6). Per layout responsive consigliato wrappare il componente in un container con media query CSS o renderizzare con un columns dinamico via useBreakpoints di VueUse.

Accessibilità

  • Ogni card è un elemento <label> che avvolge un <input type="radio"> o <input type="checkbox"> nascosto
  • L'input nascosto è accessibile da screen reader e navigazione da tastiera nativa
  • L'attributo disabled viene applicato all'input per disabilitare la selezione
  • Il checkmark visivo è decorativo e l'interazione avviene tramite l'input nativo

TypeScript

import type {
  SelectableCardProps,
  SelectableCardEmits,
  SelectableCardOption,
} from '@pzeta/vue-components'

// Selezione singola
const selected = ref<string>('')

// Selezione multipla
const selectedMultiple = ref<string[]>([])

// Tipizzazione opzioni
const options: SelectableCardOption[] = [
  {
    value: 'option-1',
    title: 'Opzione 1',
    description: 'Descrizione opzionale',
    icon: 'pi pi-star',
  },
]