Liste déroulante
Un champ qui cherche dans une liste et retient ce qui est choisi, une valeur ou plusieurs. Les options peuvent être à plat, groupées ou séparées, et elles peuvent arriver d'un serveur à mesure que le lecteur saisit.
Utilisation
Exemples
Label et texte d'aide
label affiche un texte descriptif au-dessus du champ, et hint affiche un texte d'aide en dessous.
Type to narrow the list down. Accents are ignored, so reunion finds Réunion.
Tailles
Définit la hauteur du champ à 32, 40 ou 48 pixels. La prop compact réduit cette hauteur de 4px.
États
disabled rend le champ inutilisable. readonly empêche la modification tout en gardant le champ focalisable. invalid marque le champ en erreur. loading affiche un indicateur de chargement. emptyText définit le message affiché quand il n'y a aucune option. clearable ajoute une icône pour vider la sélection.
The cross empties the selection and the search at once
For a rule the browser cannot check by itself
Set by your subscription
Positionnement
Définit la direction d'ouverture préférée (au-dessus ou en dessous du champ) pour le panneau de la liste d'options.
Groupes et séparateurs
La prop options accepte une liste simple, ou peut être structurée avec des groupes nommés et des séparateurs.
Sélection multiple
multiple permet de sélectionner plusieurs valeurs, qui s'affichent sous forme de puces (chips) supprimables à l'intérieur du champ.
Click elsewhere: the search field folds away and only the chips remain
Valeurs en texte
display="text" affiche les valeurs choisies sous forme de libellés séparés par des virgules, sur une seule ligne tronquée par des points de suspension. Le champ garde la hauteur d'un contrôle ordinaire, et sous le focus la ligne laisse au moins la moitié de la place à la recherche. On retire une valeur en la décochant dans la liste, avec Retour arrière sur une recherche vide, ou avec la croix de clearable.
One line of labels, cut short when it runs out of room
Valeurs montrées champ replié
max garde en vue les premières valeurs choisies et résume les autres en « +X », en puces comme en texte. Cela vaut tant que le champ n'a pas le focus : sous le focus, toutes les valeurs reviennent pour être vues et retirées. overflowText reformule le compte, et le slot #overflow le remplace.
Two chips, the rest counted until the field is focused
Icône du champ
iconStart affiche une icône au début du champ. iconStartLabel fournit un label accessible si l'icône est rendue interactive au clic.
Sorted A to Z.
Icônes des options
La propriété icon d'une option permet d'afficher une icône à côté de son libellé dans la liste déroulante.
Recherche asynchrone
Désactiver filter affiche les options exactement telles que fournies par la source. searchDebounce définit le délai en millisecondes avant d'émettre la recherche.
The list is narrowed by the source, so local filtering is turned off
Défilement infini
hasMore indique que d'autres pages sont disponibles, déclenchant un événement load-more lorsque la fin de la liste devient visible à l'écran.
Scroll to the foot of the list: the next page is asked for as the end comes into view
Options personnalisées
Le slot #option permet de personnaliser le contenu et la mise en page d'une ligne (ex: ajout d'un badge ou d'une deuxième ligne de texte).
Puces personnalisées
Le slot #chip permet de personnaliser l'apparence des puces (chips) des valeurs sélectionnées.
API
Props
| Prop | Type | Défaut |
|---|---|---|
options | ComboboxItem[] | aucune |
| Ce que la liste propose. Une entrée peut être une option, un bloc nommé d'options, ou un séparateur ; une simple liste d'options reste parfaitement valable. | ||
multiple | boolean | false |
Permet de choisir plusieurs valeurs, ce qui fait de la valeur une liste et montre ce qui a été choisi dans le champ, en puces ou en texte selon display. | ||
display | ComboboxDisplay'chip' | 'text' | 'chip' |
| Comment les valeurs choisies sont montrées quand on peut en choisir plusieurs : une puce supprimable chacune, ou leurs libellés séparés par des virgules sur une seule ligne, tronquée par des points de suspension. Ne change rien pour une valeur unique, qui est toujours du texte. | ||
max | number | aucune |
Combien de valeurs choisies montrer avant de résumer les autres en « +X », en puces comme en texte. Cela vaut tant que le champ n'a pas le focus ; sous le focus, toutes les valeurs reviennent pour être vues et retirées. Omis, ou à 0, toutes les valeurs sont montrées. Ne change rien sans multiple. | ||
overflowText | (count: number) => string | aucune |
Reformule le « +X » qui représente les valeurs au-delà de max, « +5 produits » par exemple. Reçoit le nombre de valeurs masquées. | ||
label | string | aucune |
| Le libellé au-dessus du champ, lié à lui pour qu'un clic dessus y place le focus. | ||
hint | string | aucune |
| Une ligne d'aide sous le champ, lue en même temps que le libellé. | ||
size | ComboboxSize'sm' | 'md' | 'lg' | 'md' |
| La hauteur du champ : 32, 40 ou 48 pixels. Le panneau et ses lignes la suivent. | ||
compact | boolean | false |
| Retire 4px à la hauteur, comme partout ailleurs dans le design system. | ||
placeholder | string | aucune |
| Ce que dit le champ tant que rien n'est choisi et que rien n'a été saisi. | ||
disabled | boolean | false |
| Rend le champ inutilisable, grisé par les tokens de couleur. | ||
readonly | boolean | false |
Montre ce qui a été choisi sans permettre de le changer : rien ne se tape, la liste ne s'ouvre jamais, les chips perdent leur croix et aucune croix de vidage n'est proposée. Le champ garde le focus et reste copiable, ce qui le distingue de disabled. | ||
invalid | boolean | false |
| Marque le champ comme invalide, pour une règle à vous. | ||
iconStart | IconSource | aucune |
Une icône dans le champ, au début. Elle est rendue avant les chips et non à leur place. Décorative jusqu'à ce qu'un écouteur @click:icon-start en fasse un bouton. | ||
iconStartLabel | string | aucune |
| Ce que fait l'icône de début, en mots, une fois cliquable. | ||
expandIcon | IconSource | expand_more |
| Le chevron à la fin du champ, qui pivote à l'ouverture de la liste. Un clic dessus quand la liste est ouverte la ferme. Il reste une décoration : le champ lui-même ouvre la liste et Échap la ferme au clavier, donc le chevron est masqué aux lecteurs d'écran et ne prend pas de libellé. | ||
clearable | boolean | false |
| Propose une croix qui vide à la fois la sélection et la recherche. | ||
clearLabel | string | aucune |
| Ce que fait cette croix, en mots. Sa valeur par défaut vient du dictionnaire du design system. | ||
emptyText | string | aucune |
Ce que dit le panneau quand la recherche ne correspond à rien. Un lecteur d'écran l'entend même quand le slot #empty dessine autre chose : renseignez les deux ensemble. | ||
filter | ComboboxFilter | true |
| Comment la liste se resserre à la saisie. La couper signifie que les options arrivent déjà filtrées par leur source et sont montrées telles quelles. Une règle à vous reçoit la requête TELLE QUE SAISIE, simplement rognée, et non la forme insensible aux accents utilisée en interne. | ||
searchDebounce | number | 250 |
| Combien de temps attendre avant de dire à la source ce qui est cherché, en millisecondes. Zéro le lui dit aussitôt, ce qui convient à une source qui n'est pas une requête réseau. | ||
loading | boolean | false |
| Dit que quelque chose est en cours de chargement. Sans option encore, tout le panneau le dit ; avec des options déjà listées, un indicateur apparaît au pied de la liste, puisque ce qui charge est alors la page suivante. Dans les deux cas, le champ remplace son chevron par un indicateur. | ||
loadingText | string | aucune |
Ce qui est dit pendant le chargement, et ce comme quoi l'indicateur est annoncé. Un lecteur d'écran l'entend même quand le slot #loading dessine autre chose : renseignez les deux ensemble. | ||
hasMore | boolean | false |
| Dit qu'il reste des pages à venir, ce qui est ce qui pousse le composant à demander la suivante quand la fin de la liste entre dans le champ de vision. | ||
placement | ComboboxPlacement'bottom' | 'bottom-start' | 'bottom-end' | 'top' | 'top-start' | 'top-end' | 'bottom-start' |
| Où la liste s'ouvre par rapport au champ. Le panneau est ancré en CSS, donc cette valeur nomme une préférence : un navigateur à court de place se rabat déjà tout seul. | ||
v-model | ItemValue | ItemValue[] | '' |
La valeur de l'option choisie, ou leur liste quand multiple est posé. Elle part sur une chaîne vide, et le tableau n'est jamais muté sur place. | ||
Événements
| Événement | Type |
|---|---|
search | [query: string] |
Ce qui est cherché, à envoyer à la source. C'est retardé de searchDebounce pendant la saisie, et émis aussitôt à l'ouverture du panneau pour qu'une première page puisse être chargée. Le même terme n'est jamais émis deux fois de suite. | |
click:icon-start | [event: MouseEvent] |
L'icône de début a été cliquée. Attacher cet écouteur est ce qui en fait un vrai bouton, qui demande alors iconStartLabel. | |
clear | [] |
| La croix de vidage a vidé la sélection et la recherche. | |
load-more | [] |
| La fin de la liste est entrée dans le champ de vision : envoyez la page suivante. | |
Slots
| Slot | Type |
|---|---|
start | {} |
Du contenu au début du champ, rendu après iconStart plutôt qu'à sa place. | |
value-end | {} |
Des contrôles à vous à l'intérieur du champ, placés avant ceux que le champ possède : la croix d'effacement et l'icône qui ouvre le panneau. Ces deux-là sont l'affordance propre du composant, ce qui explique l'absence de slot end ici. | |
option | ComboboxOptionSlotProps |
| Ce qu'une ligne de la liste montre, à la place du simple libellé : un sous-titre, un avatar, un badge. On lui dit si la ligne est celle mise en évidence et si elle est déjà choisie. | |
chip | ComboboxChipSlotProps |
Remplace la puce qui représente une valeur choisie. Elle reçoit remove, sans quoi la valeur ne pourrait plus être retirée, ainsi que la taille et la densité calculées pour tenir dans le champ, qui ne se devinent pas de l'extérieur. L'option elle-même peut manquer, si cette valeur n'a jamais figuré parmi les options. | |
overflow | ComboboxOverflowSlotProps |
Remplace le « +X » qui représente les valeurs au-delà de max. Reçoit count, le nombre de valeurs masquées, ainsi que la taille et la densité des puces du champ, pour qu'une puce à vous s'aligne sur les autres. | |
empty | ComboboxEmptySlotProps |
| Ce que le panneau montre quand rien ne correspond. Il reçoit le terme cherché. | |
loading | {} |
| Ce que le panneau montre pendant le chargement de ses premières options. | |
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 ChipSize = 'xs' | 'sm'
export interface ComboboxChipSlotProps {
value: ItemValue
option: ComboboxOption | undefined
label: string
remove: () => void
size: ChipSize
compact: boolean
}export interface ComboboxEmptySlotProps {
query: string
}export type ComboboxFilter = boolean | ((option: ComboboxOption, query: string) => boolean)
export interface ComboboxGroup {
label: string
options: ComboboxOption[]
}export type ComboboxItem = ComboboxOption | ComboboxGroup | ComboboxSeparator
export interface ComboboxOption {
value: ItemValue
label: string
icon?: IconSource
disabled?: boolean
}export interface ComboboxOptionSlotProps {
option: ComboboxOption
index: number
active: boolean
selected: boolean
}export interface ComboboxOverflowSlotProps {
count: number
size: ChipSize
compact: boolean
}export interface ComboboxSeparator {
separator: true
}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
export type ItemValue = string | number
Variables CSS
| Token | Valeur |
|---|---|
--vectis-control-size-combobox-list-max-block | 18rem |