Raccourci clavier : Ctrl + K
Commencer

Champ de saisie

Un champ de texte complet : libellé au-dessus, indication en dessous, icônes à l'intérieur, compteur de caractères, bouton d'effacement et état de chargement, le tout autour d'un vrai <input>.

Utilisation

vue
<script setup lang="ts">
import { ref } from 'vue'
import { VInput } from 'vectis-ui'

const email = ref('')
</script>

<template>
  <VInput v-model="email" label="Email" placeholder="[email protected]" />
</template>

Exemples

Libellé et indication

label s'affiche au-dessus du champ et y place le curseur au clic. hint s'affiche sous le champ et lui est lié par aria-describedby.

vue

Shown next to everything you publish.

<script setup lang="ts">
import { ref } from 'vue'
import { VInput } from 'vectis-ui'

const name = ref('')
</script>

<template>
  <VInput
    v-model="name"
    label="Display name"
    hint="Shown next to everything you publish."
    placeholder="Ada Lovelace"
  />
</template>

Tailles

size définit la hauteur à 32, 40 ou 48 pixels, et compact retire 4px à l'une quelconque d'entre elles.

vue
<script setup lang="ts">
import { VInput } from 'vectis-ui'
</script>

<template>
  <div class="grid">
    <VInput size="sm" label="Small" placeholder="32px" />
    <VInput size="sm" compact label="Small compact" placeholder="28px" />
    <VInput size="md" label="Medium" placeholder="40px" />
    <VInput size="md" compact label="Medium compact" placeholder="36px" />
    <VInput size="lg" label="Large" placeholder="48px" />
    <VInput size="lg" compact label="Large compact" placeholder="44px" />
  </div>
</template>

<style scoped>
.grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr));
  gap: var(--vectis-space-4);
}
</style>

Icônes

iconStart et iconEnd posent une icône décorative à chaque extrémité du champ. Le slot #end remplace l'icône de fin, là où #start est rendu après l'icône de début plutôt qu'à sa place.

vue

This handle is free.

<script setup lang="ts">
import { ref } from 'vue'
import { VInput } from 'vectis-ui'
import { check_circle as checkCircle, search } from 'vectis-ui/icons'

const query = ref('')
const handle = ref('ada')
</script>

<template>
  <div class="fields">
    <VInput
      v-model="query"
      label="Search"
      :icon-start="search"
      placeholder="Orders, people, files"
    />
    <VInput v-model="handle" label="Handle" :icon-end="checkCircle" hint="This handle is free." />
  </div>
</template>

<style scoped>
.fields {
  display: grid;
  gap: var(--vectis-space-4);
}
</style>

Effaçable

clearable ajoute une croix qui vide le champ, affichée tant qu'il y a quelque chose à vider et que le champ est modifiable. clearVisible répond vous-même à cette question, pour un champ dont la valeur n'est pas son texte.

vue
<script setup lang="ts">
import { ref } from 'vue'
import { VInput } from 'vectis-ui'
import { search } from 'vectis-ui/icons'

const query = ref('wool socks')
</script>

<template>
  <VInput v-model="query" label="Search" :icon-start="search" clearable />
</template>

États

disabled grise le champ et le sort de l'ordre de tabulation. readonly le garde focalisable et copiable, et masque la croix sauf indication contraire. invalid sert à une règle que le navigateur ne peut pas vérifier lui-même, et loading place un indicateur là où va l'icône de fin.

vue

That handle is already taken.

Chargement…
<script setup lang="ts">
import { ref } from 'vue'
import { VInput } from 'vectis-ui'

const handle = ref('ada')
const query = ref('metro')
</script>

<template>
  <div class="fields">
    <VInput label="Disabled" model-value="Not editable" disabled />
    <VInput label="Read-only" model-value="[email protected]" readonly />
    <VInput v-model="handle" label="Invalid" invalid hint="That handle is already taken." />
    <VInput v-model="query" label="Loading" loading />
  </div>
</template>

<style scoped>
.fields {
  display: grid;
  gap: var(--vectis-space-4);
}
</style>

Icônes cliquables

Un écouteur @click:icon-start ou @click:icon-end transforme l'icône en vrai bouton, qui demande alors iconStartLabel ou iconEndLabel.

vue

Press the magnifier to search.

<script setup lang="ts">
import { ref } from 'vue'
import { VInput } from 'vectis-ui'
import { search, swap_vert as swapVert } from 'vectis-ui/icons'

const query = ref('wool socks')
const searched = ref('')

const amount = ref('120.00')
const currency = ref<'EUR' | 'USD'>('EUR')

function switchCurrency() {
  currency.value = currency.value === 'EUR' ? 'USD' : 'EUR'
}
</script>

<template>
  <div class="fields">
    <VInput
      v-model="query"
      label="Search"
      :icon-end="search"
      icon-end-label="Run the search"
      :hint="searched ? `Searched for ${searched}.` : 'Press the magnifier to search.'"
      @click:icon-end="searched = query"
    />

    <VInput
      v-model="amount"
      :label="`Amount in ${currency}`"
      :icon-start="swapVert"
      icon-start-label="Switch currency"
      @click:icon-start="switchCurrency"
    />
  </div>
</template>

<style scoped>
.fields {
  display: grid;
  gap: var(--vectis-space-4);
}
</style>

Compteurs

counter affiche la longueur au bout du champ. maxlength est la limite dure du navigateur, là où softLimit est une ligne que le lecteur peut franchir : le texte n'est jamais coupé, le compteur passe au rouge et le champ tombe en erreur par la validité native. La prop compte des caractères, comme sur VTextarea ; sur VFileInput, le même nom compte des fichiers et leur taille.

vue
0/20

The browser refuses the twenty-first character.

42/40

Type past forty and the field goes into error instead.

<script setup lang="ts">
import { ref } from 'vue'
import { VInput } from 'vectis-ui'

const nickname = ref('')
const headline = ref('A design system that leans on the platform')
</script>

<template>
  <div class="fields">
    <VInput
      v-model="nickname"
      label="Nickname"
      hint="The browser refuses the twenty-first character."
      counter
      :maxlength="20"
    />

    <VInput
      v-model="headline"
      label="Headline"
      hint="Type past forty and the field goes into error instead."
      counter
      :maxlength="40"
      soft-limit
    />
  </div>
</template>

<style scoped>
.fields {
  display: grid;
  gap: var(--vectis-space-4);
}
</style>

Motif

Il n'y a pas de prop pattern : l'attribut natif atteint l'input par fallthrough, avec inputmode, name et tout ce dont un formulaire a besoin. Le champ passe au rouge par :user-invalid, une fois que le lecteur l'a quitté.

vue

Five digits.

<script setup lang="ts">
import { ref } from 'vue'
import { VInput } from 'vectis-ui'

const postcode = ref('')
</script>

<template>
  <VInput
    v-model="postcode"
    label="Postcode"
    hint="Five digits."
    pattern="[0-9]{5}"
    inputmode="numeric"
    title="Five digits, 75001 for instance."
  />
</template>

API

Props

PropTypeDéfaut
sizeInputSize'sm' | 'md' | 'lg''md'
La hauteur du champ : 32, 40 ou 48 pixels.
compactbooleanfalse
Retire 4px à la hauteur, en laissant le rembourrage, le texte et les icônes tels quels.
typeInputType'text' | 'email' | 'number' | 'password' | 'search' | 'tel' | 'url''text'
Le type natif du champ, qui est aussi ce qui indique à un téléphone quel clavier proposer : un pavé numérique pour number, une touche @ pour email.
invalidbooleanfalse
Marque le champ comme invalide quoi qu'en pense le navigateur. C'est la voie pour une règle que seul le serveur peut vérifier ; tout ce que le navigateur sait valider seul colore déjà le champ sans elle.
disabledbooleanfalse
Rend le champ inutilisable, grisé par les tokens de couleur.
readonlybooleanfalse
Montre la valeur sans permettre de la changer. Le champ peut toujours être focalisé et copié, et il masque le bouton d'effacement à moins que clearVisible ne réponde explicitement à cette question.
noTypingbooleanfalse
Refuse le clavier sans dessiner le champ en lecture seule : l'attribut natif est posé, mais le champ garde son apparence ordinaire et sa croix d'effacement. Pour un champ dont la valeur vient d'ailleurs, d'un sélecteur ou d'une boîte de dialogue de fichiers, et qui n'en est pas moins modifiable.
labelstringaucune
Le libellé au-dessus du champ, lié à lui pour qu'un clic dessus y place le focus.
hintstringaucune
Une ligne d'aide sous le champ. Elle est liée au champ pour les technologies d'assistance, donc elle est lue avec le libellé.
iconStartIconSourceaucune
Une icône dans le champ, au début. Elle est décorative jusqu'à ce qu'un écouteur @click:icon-start soit attaché : elle devient alors un vrai bouton et demande iconStartLabel.
iconEndIconSourceaucune
La même chose à la fin du champ. Le slot #end la remplace, et l'indicateur de chargement prend sa place pendant qu'il tourne.
iconStartLabelstringaucune
Ce que fait l'icône de début, en mots, une fois qu'elle est cliquable.
iconEndLabelstringaucune
Ce que fait l'icône de fin, en mots, une fois qu'elle est cliquable.
loadingbooleanfalse
Affiche un indicateur à la fin du champ, à la place de l'icône ou du slot de fin.
loadingTextstringaucune
Ce que les lecteurs d'écran annoncent pendant que l'indicateur tourne. Il retombe sur le dictionnaire du design system.
clearablebooleanfalse
Propose une croix qui vide le champ. Elle apparaît quand il y a quelque chose à effacer et que le champ est modifiable.
clearVisiblebooleanaucune
Décide si la croix est affichée, au lieu de laisser le champ le déduire de son propre contenu. Cette prop existe pour les composants bâtis sur celui-ci, où ce qu'il y a à effacer n'est pas le texte : VCombobox tient sa sélection en puces à côté du champ, et un sélecteur de date ou d'heure en lecture seule change sa valeur par un panneau plutôt qu'à la frappe.
clearLabelstringaucune
Ce que fait le bouton d'effacement, en mots. Il retombe sur le dictionnaire du design system.
maxlengthnumberaucune
Le nombre maximum de caractères. Par défaut c'est la limite du navigateur lui-même, qui refuse simplement tout ce qui la dépasse.
softLimitbooleanfalse
Transforme cette limite en limite souple : le lecteur peut taper au-delà, et le champ passe en erreur au lieu de refuser les frappes en silence. C'est rapporté par la validité native, donc un formulaire ne peut pas être envoyé au-dessus de la limite.
counterbooleanfalse
Affiche ce qui a été saisi, à la fin du champ : 12/80 face à une limite, ou simplement 12 sans limite.
v-modelstring | number''
La valeur, typée en texte ou en nombre plutôt qu'en texte seul. Sur un <input type="number">, Vue convertit la valeur en nombre de lui-même : un modèle limité aux chaînes rendrait donc un nombre à qui lui a passé une chaîne.

Événements

ÉvénementType
click:icon-start[event: MouseEvent]
L'icône de début a été pressée. Attacher cet écouteur est ce qui en fait un bouton.
click:icon-end[event: MouseEvent]
L'icône de fin a été pressée. Attacher cet écouteur est ce qui en fait un bouton.
clear[]
Le bouton d'effacement a été pressé. La valeur est déjà vidée.

Slots

SlotType
start{}
Du contenu au début du champ, rendu après iconStart plutôt qu'à sa place.
value-end{}
Vos propres contrôles dans le champ, placés avant ceux du champ lui-même : la croix d'effacement et l'icône de fin. C'est la place de ce qui agit sur la valeur, pour que l'ordre de lecture et l'ordre de tabulation coïncident.
end{}
Du contenu à la fin du champ, qui remplace iconEnd. Il est masqué pendant le chargement, l'indicateur prenant cette place.

Types

Les types que les tables ci-dessus nomment, écrits comme la librairie les déclare. Ceux qui portent export s'importent depuis vectis-ui pour typer votre propre code ; les autres décrivent la forme de ce qu'un slot fournit.

export interface BuiltinIcon {
  name: string
  paths: readonly [string] | readonly [string, string]
}
export type IconRender =
  | { path: string; viewBox?: string }
  | { component: Component; props?: Record<string, unknown> }
  | { src: string }
  | { text: string; class?: string }
  | { class: string }
export type IconSource = string | BuiltinIcon | IconRender