Composables

useOptionLabel

Composable per risolvere la label di un'opzione da un oggetto con supporto a campo singolo, template ${campo} e dot-notation per campi annidati.

Panoramica

useOptionLabel è la utility che i componenti *Remote di @pzeta/vue-form usano internamente per estrarre la stringa visualizzata da un oggetto opzione. È esposto pubblicamente perché serve in componenti custom che ricevono opzioni eterogenee — ad esempio una tabella che mostra la "label utile" di un record lookup, o un componente di anteprima che riusa lo stesso pattern optionLabel / optionTemplate adottato dai wrapper remote.

Strategia di risoluzione, in ordine:

  1. Se optionTemplate è definito → compila il template (es. ${nome} - ${cognome}).
  2. Altrimenti → legge item[optionLabel].
  3. Fallback → item[optionValue].
  4. Ultimo resort → String(item).

API

import { useOptionLabel } from '@pzeta/vue-form'

export function useOptionLabel(
  options?: UseOptionLabelOptions,
): UseOptionLabelReturn

Tipi

export interface UseOptionLabelOptions {
  optionLabel?: MaybeRefOrGetter<string | undefined>      // default: 'label'
  optionTemplate?: MaybeRefOrGetter<string | undefined>   // pattern ${campo}
  optionValue?: MaybeRefOrGetter<string>                  // default: 'value' — fallback
}

export interface UseOptionLabelReturn {
  compileTemplate: (template: string, item: Record<string, unknown>) => string
  resolveOptionLabel: (item: Record<string, unknown>) => string
  getNestedValue: (item: Record<string, unknown>, path: string) => unknown
}
Tutti i parametri accettano MaybeRefOrGetter<...>: puoi passare valori statici, ref(...) o getter, e la risoluzione resta reattiva agli aggiornamenti.

Esempi

Campo singolo

import { useOptionLabel } from '@pzeta/vue-form'

const { resolveOptionLabel } = useOptionLabel({ optionLabel: 'descrizione' })

const items = [
  { id: 1, descrizione: 'Opzione A' },
  { id: 2, descrizione: 'Opzione B' },
]

items.map(resolveOptionLabel)
// => ['Opzione A', 'Opzione B']

Template con interpolazione

const { resolveOptionLabel } = useOptionLabel({
  optionTemplate: '${codice} - ${descrizione}',
})

resolveOptionLabel({ codice: 'IT', descrizione: 'Italia' })
// => 'IT - Italia'

Campi annidati (dot notation)

const { resolveOptionLabel, getNestedValue } = useOptionLabel({
  optionTemplate: '${user.name} (${user.email})',
})

const item = {
  id: 1,
  user: { name: 'Mario', email: 'mario@example.com' },
}

resolveOptionLabel(item)
// => 'Mario (mario@example.com)'

getNestedValue(item, 'user.name')
// => 'Mario'

Valori reattivi

import { ref } from 'vue'

const labelField = ref('nome')

const { resolveOptionLabel } = useOptionLabel({ optionLabel: labelField })

resolveOptionLabel({ nome: 'Mario', cognome: 'Rossi' }) // => 'Mario'

labelField.value = 'cognome'
// resolveOptionLabel ora estrae 'cognome'

compileTemplate standalone

Il template engine è esposto e usabile fuori dal contesto opzione:

const { compileTemplate } = useOptionLabel()

const template = 'Benvenuto ${nome}, hai ${messaggi} nuovi messaggi'
compileTemplate(template, { nome: 'Mario', messaggi: 5 })
// => 'Benvenuto Mario, hai 5 nuovi messaggi'

Comportamento dei placeholder

ScenarioEsempioOutput
Valore presentecompileTemplate('${nome}', { nome: 'Mario' })'Mario'
Valore nullcompileTemplate('${nome}', { nome: null })'' (stringa vuota)
Campo mancantecompileTemplate('${eta}', { nome: 'Mario' })'${eta}' (mantiene il placeholder)
Path nested non risoltocompileTemplate('${u.x}', { u: {} })'${u.x}'

La distinzione tra null (intenzionale → stringa vuota) e campo mancante (errore di chiavi → placeholder visibile) è voluta: aiuta a individuare nomi di campo errati nei template durante lo sviluppo.

Quando usarlo direttamente

Nella maggior parte dei casi non serve invocarlo: i wrapper *Remote (SelectRemote, ListboxRemote, TreeRemote, ecc.) accettano già le prop option-label / option-template e applicano internamente questo composable.

Usalo direttamente quando:

  • Stai costruendo un componente custom che mostra liste di opzioni e vuoi la stessa semantica di optionLabel / optionTemplate dei wrapper.
  • Devi renderizzare la label di un valore selezionato fuori dal componente (es. in un riepilogo, una toolbar, una cella di tabella).
  • Ti serve compileTemplate come template engine leggero per stringhe basate su oggetti, senza dipendere da librerie esterne.

Vedi anche