Vitral 0.2
Formulário

InputTag

Um campo cujo valor é uma lista de strings curtas, cada uma mostrada como uma tag removível, adicionadas com Enter, um separador ou uma colagem.

Importação

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

Básico

Digite e pressione Enter, ou digite uma vírgula. Backspace numa caixa vazia remove a última tag.

  • vue
  • design tokens
2 selected: vue · design tokens
<script setup lang="ts">import { InputTag, Label, StackPanel } from '@vitral/vue';import { ref } from 'vue'; const topics = ref(['vue', 'design tokens']);</script> <template>    <StackPanel spacing="0.375rem" style="min-width: 16rem">        <Label for="tag-topics">Topics</Label>        <InputTag id="tag-topics" v-model="topics" placeholder="Add a topic" fluid />        <small style="color: var(--vt-text-muted-color)">{{ topics.length }} selected: {{ topics.join(' · ') || 'none' }}</small>    </StackPanel></template>

Verificadas ao serem adicionadas

`validate` recusa uma tag e deixa o texto na caixa para ser corrigido; `reject` diz o que aconteceu, para que o campo possa se explicar. Vários separadores são permitidos: este aceita vírgula, ponto e vírgula ou espaço.

    <script setup lang="ts">import { InputTag, Label, Message, StackPanel } from '@vitral/vue';import { ref } from 'vue'; const emails = ref<string[]>([]);const rejected = ref(''); const isEmail = (tag: string) => /^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(tag); function onReject(event: { value: string; reason: string }) {    rejected.value = event.reason === 'duplicate' ? `“${event.value}” is already there.` : `“${event.value}” is not an address.`;}</script> <template>    <StackPanel spacing="0.375rem" style="min-width: 16rem">        <Label for="tag-emails">Invite by email</Label>        <InputTag            id="tag-emails"            v-model="emails"            :separator="[',', ';', ' ']"            :validate="isEmail"            placeholder="name@example.com"            :invalid="!!rejected"            fluid            @add="rejected = ''"            @reject="onReject"        />        <Message v-if="rejected" severity="danger" size="small" variant="simple">{{ rejected }}</Message>    </StackPanel></template>

    Um máximo

    `max` para a lista onde ela deve parar; o que é recusado é informado, em vez de descartado em silêncio.

    • red
    • green
    <script setup lang="ts">import { InputTag, Label, Message, StackPanel } from '@vitral/vue';import { ref } from 'vue'; const colours = ref(['red', 'green']);const rejected = ref(''); function onReject(event: { value: string; reason: string }) {    rejected.value = event.reason === 'duplicate' ? `“${event.value}” is already there.` : 'That is as many as it takes.';}</script> <template>    <StackPanel spacing="0.375rem" style="min-width: 16rem">        <Label for="tag-max">Up to three colours</Label>        <InputTag id="tag-max" v-model="colours" :max="3" placeholder="Add a colour" fluid @add="rejected = ''" @remove="rejected = ''" @reject="onReject" />        <Message v-if="rejected" severity="danger" size="small" variant="simple">{{ rejected }}</Message>    </StackPanel></template>

    Tamanhos e estados

    A moldura do campo é a compartilhada: os mesmos tamanhos, variantes e estados inválido e desabilitado de qualquer outro input.

    • accessible
    • accessible
    • accessible
    • accessible
    • accessible
    • accessible
    • accessible
    <script setup lang="ts">import { InputTag, StackPanel } from '@vitral/vue';import { ref } from 'vue'; const keywords = ref(['accessible']);</script> <template>    <StackPanel spacing="1rem" style="width: 100%; max-width: 30rem">        <InputTag v-model="keywords" size="small" aria-label="Small" fluid />        <InputTag v-model="keywords" aria-label="Default" fluid />        <InputTag v-model="keywords" size="large" aria-label="Large" fluid />        <InputTag v-model="keywords" variant="filled" aria-label="Filled" fluid />        <InputTag v-model="keywords" invalid aria-label="Invalid" fluid />        <InputTag v-model="keywords" disabled aria-label="Disabled" fluid />        <InputTag v-model="keywords" readonly aria-label="Read-only" fluid />    </StackPanel></template>

    API

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

    Props

    NomeTipoDescrição
    separatorstring | readonly string[]O que encerra uma tag durante a digitação, além do Enter. O padrão é uma vírgula.
    maxnumberQuantas tags o campo aceita.
    allowDuplicatebooleanMantém uma tag que a lista já tem. Desligado por padrão.
    addOnBlurbooleanAdiciona o que estiver na caixa quando o foco sai do campo. Ligado por padrão.
    validate(tag: string) => booleanRecusa uma tag: o texto fica na caixa para o leitor corrigir.
    placeholderstring—
    removeIconIconProp—
    sizeSize—
    variantInputVariantO padrão é o `inputVariant` do plugin.
    invalidboolean—
    disabledboolean—
    readonlyboolean—
    fluidboolean—
    namestringO nome com que o campo é enviado; as tags vão uma a uma.

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

    Emits

    EventoPayloadDescrição
    addevent: { originalEvent: Event; value: string; tags: string[] }Uma tag foi adicionada, com Enter, um separador, uma colagem ou no blur.
    removeevent: { originalEvent: Event; value: string; index: number; tags: string[] }Uma tag foi retirada, pelo seu botão ou por uma tecla.
    rejectevent: { originalEvent: Event; value: string; reason: 'duplicate' | 'max' | 'invalid' }Algo foi recusado: a lista estava cheia, a tag já existia, ou `validate` disse não.
    focusevent: FocusEvent—
    blurevent: FocusEvent—

    Slots

    NomeProps do slotDescrição
    tag(props: { value: string; index: number; remove: (event: Event) => void })Substitui o conteúdo de uma tag, dentro da própria caixa da tag.
    removeicon(props: { value: string; index: number })—