Vitral 0.2
Dados

Listbox

Uma lista para escolher uma ou várias opções, sempre aberta: a irmã do Select.

Importação

main.ts
import { Listbox } from '@vitral/vue';

Única

A seleção acompanha as setas, como num list box nativo. Évora está desabilitada.

  • São Paulo
  • Rio de Janeiro
  • Lisboa
  • Porto
  • Évora
  • Montréal
  • Bogotá
  • Kraków
  • Reykjavík
  • Zürich
  • Tōkyō
  • Málaga
Value: LIS
<script setup lang="ts">import { Label, Listbox, StackPanel } from '@vitral/vue';import { ref } from 'vue'; const cities = [    { name: 'São Paulo', code: 'SAO' },    { name: 'Rio de Janeiro', code: 'RIO' },    { name: 'Lisboa', code: 'LIS' },    { name: 'Porto', code: 'OPO' },    { name: 'Évora', code: 'EVO', off: true },    { name: 'Montréal', code: 'YUL' },    { name: 'Bogotá', code: 'BOG' },    { name: 'Kraków', code: 'KRK' },    { name: 'Reykjavík', code: 'REK' },    { name: 'Zürich', code: 'ZRH' },    { name: 'Tōkyō', code: 'TYO' },    { name: 'Málaga', code: 'AGP' }];const city = ref<string | null>('LIS');</script> <template>    <StackPanel spacing="0.375rem" style="min-width: 16rem">        <Label id="lb-city-label">Airport</Label>        <Listbox v-model="city" :options="cities" option-label="name" option-value="code" option-disabled="off" checkmark aria-labelledby="lb-city-label" scroll-height="14rem" />        <small style="color: var(--vt-text-muted-color)">Value: {{ city ?? 'null' }}</small>    </StackPanel></template>

Múltipla, com filtro

A busca ignora acentos e maiúsculas: “ingles” não é necessário, “espanol” encontra Español.

  • Português
  • English
  • Español
  • Français
  • Deutsch
  • Íslenska
  • Polski
  • 日本語 (Japanese)
  • Wolof
  • Euskara
Value: pt, en
<script setup lang="ts">import { Label, Listbox, StackPanel } from '@vitral/vue';import { ref } from 'vue'; const languages = [    { name: 'Português', code: 'pt' },    { name: 'English', code: 'en' },    { name: 'Español', code: 'es' },    { name: 'Français', code: 'fr' },    { name: 'Deutsch', code: 'de' },    { name: 'Íslenska', code: 'is' },    { name: 'Polski', code: 'pl' },    { name: '日本語 (Japanese)', code: 'ja' },    { name: 'Wolof', code: 'wo' },    { name: 'Euskara', code: 'eu' }];const spoken = ref<string[]>(['pt', 'en']);</script> <template>    <StackPanel spacing="0.375rem" style="min-width: 16rem">        <Label id="lb-lang-label">Languages spoken</Label>        <Listbox v-model="spoken" :options="languages" option-label="name" option-value="code" multiple filter checkmark aria-labelledby="lb-lang-label" scroll-height="12rem" />        <small style="color: var(--vt-text-muted-color)">Value: {{ spoken.join(', ') || 'none' }}</small>    </StackPanel></template>

Grupos e opções personalizadas

    • São Paulo
    • Recife
    • Florianópolis
    • Lisboa
    • Coimbra
    • Montréal
    • Québec
  • Online
  • Away
  • Busy
  • Offline
<script setup lang="ts">import { Label, Listbox, StackPanel } from '@vitral/vue';import { ref } from 'vue'; const byCountry = [    { country: 'Brasil', cities: [{ name: 'São Paulo' }, { name: 'Recife' }, { name: 'Florianópolis' }] },    { country: 'Portugal', cities: [{ name: 'Lisboa' }, { name: 'Coimbra' }] },    { country: 'Canada', cities: [{ name: 'Montréal' }, { name: 'Québec' }] }]; const statuses = [    { label: 'Online', value: 'online', tone: 'success' },    { label: 'Away', value: 'away', tone: 'warn' },    { label: 'Busy', value: 'busy', tone: 'danger' },    { label: 'Offline', value: 'offline', tone: 'muted' }]; const grouped = ref<unknown>(null);const status = ref('online');</script> <template>    <StackPanel orientation="horizontal" spacing="0.75rem" align="start" wrap>        <StackPanel spacing="0.375rem" style="min-width: 16rem">            <Label id="lb-group-label">City by country</Label>            <Listbox v-model="grouped" :options="byCountry" option-group-label="country" option-group-children="cities" option-label="name" aria-labelledby="lb-group-label" scroll-height="14rem" />        </StackPanel>        <StackPanel spacing="0.375rem" style="min-width: 16rem">            <Label id="lb-status-label">Status</Label>            <Listbox v-model="status" :options="statuses" option-label="label" option-value="value" aria-labelledby="lb-status-label">                <template #option="{ option }">                    <span :class="['demo-dot', `demo-dot-${(option as { tone: string }).tone}`]" aria-hidden="true" />                    <span>{{ (option as { label: string }).label }}</span>                </template>            </Listbox>        </StackPanel>    </StackPanel></template> <style scoped>.demo-dot {    width: 0.5rem;    height: 0.5rem;    flex-shrink: 0;    border-radius: 999px;    background: var(--vt-text-muted-color);} .demo-dot-success {    background: var(--vt-success-color);} .demo-dot-warn {    background: var(--vt-warn-color);} .demo-dot-danger {    background: var(--vt-danger-color);}</style>

Estados

  • São Paulo
  • Rio de Janeiro
  • Lisboa
  • Porto
  • São Paulo
  • Rio de Janeiro
  • Lisboa
  • Porto
<script setup lang="ts">import { Listbox } from '@vitral/vue'; const cities = [    { name: 'São Paulo', code: 'SAO' },    { name: 'Rio de Janeiro', code: 'RIO' },    { name: 'Lisboa', code: 'LIS' },    { name: 'Porto', code: 'OPO' }];</script> <template>    <Listbox :options="cities" option-label="name" invalid aria-label="Invalid" />    <Listbox :model-value="cities[2]" :options="cities" option-label="name" disabled aria-label="Disabled" /></template>

API

Lido de packages/vue/src/components/Listbox/types.ts, então diz o que o componente aceita de fato.

Props

NomeTipoDescrição
optionsany[]—
optionLabelstringCampo (caminho com pontos) com o texto de uma opção. Sem ele, as opções são mostradas como estão.
optionValuestringCampo com o valor que o v-model recebe. Sem ele, a opção inteira é o valor.
optionDisabledstring—
optionGroupLabelstringTransforma `options` em grupos: este campo é o rótulo de cada grupo…
optionGroupChildrenstring…e este, as suas opções. O padrão é `items`.
dataKeystringCompara valores de objeto por este campo em vez de pela estrutura.
multiplebooleanO v-model passa a ser um array, e a lista aceita seleção múltipla.
checkmarkbooleanMarca as opções selecionadas com um visto, além do destaque.
filterbooleanAdiciona uma caixa de busca acima da lista.
filterPlaceholderstring—
filterFieldsstring[]Campos a buscar em vez do rótulo.
filterMatchModestringQualquer modo de comparação registrado; por padrão, `contains` sem distinguir acentos nem maiúsculas.
scrollHeightstringA altura máxima da lista antes de rolar.
emptyMessagestring—
emptyFilterMessagestring—
selectOnFocusbooleanNo modo simples, mover com as setas também seleciona, como numa list box nativa. Desligado, as setas só movem e Enter ou Espaço selecionam.
invalidboolean—
disabledboolean—
fluidboolean—

Mais pt, dt e unstyled de BaseProps; veja pass-through e modo sem estilo.

Emits

EventoPayloadDescrição
changeevent: ListboxChangeEvent—
filterquery: string—
focusevent: FocusEvent—
blurevent: FocusEvent—

Slots

NomeProps do slotDescrição
option(props: { option: unknown; index: number; selected: boolean; focused: boolean })—
optiongroup(props: { group: unknown })—
header——
footer——
empty——