Nouveau Components

Sélecteur de quantité

Le sélecteur de quantité permet d’augmenter ou de diminuer une valeur numérique à l’aide de deux boutons encadrant la valeur courante. Il sert à ajuster un nombre d’articles, de participants, de jours ou de billets. La valeur est bornée par un minimum et un maximum, et reste modifiable directement au clavier. Ce composant peut être construit de deux manières, avec un champ numérique natif ou avec un motif ARIA, dont les compromis diffèrent.

Quand utiliser un sélecteur de quantité

  • Petites quantités bornées : un nombre d'articles, de voyageurs, de licences, entre un minimum et un maximum connus.
  • Ajustement fréquent : quand l'utilisateur augmente ou diminue d'un cran plutôt que de saisir une valeur précise.
  • Valeurs entières : le pas est de 1 et les décimales n'ont pas de sens.

Quand ne pas en utiliser

  • Grande plage de valeurs : au-delà d'une vingtaine de crans, la saisie directe est plus rapide que le martelage d'un bouton.
  • Valeur non numérique : une taille ou une catégorie relève d'une liste déroulante ou de boutons radio.
  • Valeur approximative : pour un réglage continu sans chiffre exact, un curseur convient mieux.

Modes d'action

  • Souris : les boutons moins et plus modifient la valeur d'un cran dans les deux modèles ; le champ, quand il existe, accepte la saisie directe.
  • Clavier : les deux modèles diffèrent précisément là-dessus. Dans le premier, le clavier passe par le champ et par lui seul. Dans le second, il passe par les deux boutons, et il n'y a pas de champ.
  • Lecteur d'écran : la valeur et les bornes sont portées par le champ natif dans le premier modèle, par le texte affiché et la région live dans le second.

Contenu

  • Un label visible : il dit ce que l'on compte. « Quantité » seul ne suffit pas quand la page en compte plusieurs.
  • Les bornes annoncées : le minimum et le maximum figurent dans l'aide, avant la saisie, pas seulement dans le message d'erreur.
  • Un message d'erreur utile : il dit la règle et la valeur attendue, jamais « valeur invalide ».

Mots-clés

  • Sélecteur de quantité : contrôle qui fait varier une valeur numérique d'un cran, à l'aide de deux boutons.
  • spinbutton : rôle d'un contrôle à valeur numérique bornée. Le champ natif le porte déjà, et lui seul.
  • tabindex="-1" : retire un élément de l'ordre de tabulation sans le rendre inutilisable à la souris.
  • disabled : rend un élément inopérant et le retire de la tabulation comme de l'arbre d'accessibilité.
  • aria-disabled : signale un élément indisponible sans le retirer de la tabulation. Il garde le focus, et ne passe à disabled qu'une fois ce focus parti.

Décomposition des composants

Deux modèles, et c'est exactement le chemin clavier qui les distingue. Le premier met le réglage dans le champ, le second dans les boutons. Aucun des deux n'expose les deux à la fois : ce serait imposer trois arrêts de tabulation pour un seul réglage.

Modèle 1 : le champ est le chemin clavier

  • Le champ est un input type="number". Il apporte le rôle spinbutton, la valeur courante, les bornes, les flèches haut et bas, Origine et Fin, et la saisie directe, sans une ligne de code.
  • Les boutons moins et plus portent tabindex="-1" : ce sont des commandes de pointage qui doublent les flèches. La fonction reste entièrement accessible au clavier par le champ (WCAG 2.1.1).
  • Aux bornes, le bouton concerné devient indisponible. S'il a le focus à ce moment-là, il le garde : il passe d'abord à aria-disabled, qui le signale indisponible sans le retirer de la tabulation, puis à disabled seulement une fois que l'utilisateur l'a quitté. Sans cela, le focus retomberait sur le document en pleine action (WCAG 2.4.3).
  • L'erreur est annoncée dès qu'elle apparaît par une région assertive, et rattachée au champ par aria-describedby pour rester disponible ensuite (WCAG 3.3.1).

Modèle 2 : les boutons sont le chemin clavier

  • Il n'y a pas de champ. Les deux boutons sont dans l'ordre de tabulation et portent seuls le réglage.
  • Aucun rôle de remplacement n'est ajouté : un conteneur focalisable en role="spinbutton" promettrait des flèches qui n'existent pas, et ajouterait un troisième arrêt de tabulation entre les deux boutons.
  • La valeur affichée sert de description aux deux boutons par aria-describedby, et son texte porte son unité : un « 3 » annoncé seul ne veut rien dire.
  • Aux bornes, le bouton devient indisponible. Comme les boutons sont ici le seul chemin clavier, il garde le focus : il passe à aria-disabled, et ce n'est qu'au Tab ou au Maj+Tab suivant, une fois l'utilisateur parti, qu'il passe à disabled et quitte la tabulation (WCAG 2.4.3).

Lecteur d'écran

  • Avec un champ natif, aucun rôle ARIA n'est ajouté : le doubler créerait une restitution contradictoire.
  • Les boutons portent un nom explicite, « Diminuer la quantité » et « Augmenter la quantité », jamais un simple signe moins ou plus.
  • La borne est annoncée au moment où elle est atteinte : une fois le bouton désactivé, il ne peut plus l'expliquer.
  • La nouvelle valeur est annoncée après un délai de 500 ms, le temps que le lecteur d'écran ait fini d'annoncer le bouton.

Les deux modèles ne partagent pas le même chemin clavier, et c'est exactement ce qui les distingue. Dans le premier, le champ est le seul arrêt de tabulation : les boutons portent tabindex="-1" et doublent les flèches à la souris. Dans le second, il n'y a pas de champ et les deux boutons sont les seuls arrêts. Aucun des deux n'expose les trois à la fois : ce serait trois arrêts de tabulation pour un seul réglage.

Interactions clavier du sélecteur de quantité
ToucheFonction
TabModèle avec champ : un seul arrêt, le champ. Modèle sans champ : deux arrêts, le bouton Diminuer puis le bouton Augmenter. Un bouton qui vient d'atteindre une borne garde le focus jusqu'à cette tabulation, et ne quitte la séquence qu'ensuite.
Flèche hautModèle avec champ uniquement : augmente la valeur d'un pas, sans dépasser le maximum.
Flèche basModèle avec champ uniquement : diminue la valeur d'un pas, sans descendre sous le minimum.
DébutModèle avec champ uniquement : porte la valeur à son minimum.
FinModèle avec champ uniquement : porte la valeur à son maximum.
Entrée ou EspaceModèle sans champ : active le bouton qui a le focus. Un bouton parvenu à sa borne ne fait rien, la borne ayant déjà été annoncée au moment où elle a été atteinte.
Touches d'éditionSaisie directe dans le champ : chiffres, déplacement du curseur, suppression. La variante sans champ n'accepte pas la saisie directe.

Note : avec le champ numérique natif, les flèches, Début, Fin et les bornes sont assurées par le navigateur, sans une ligne de code. Le modèle sans champ n'offre aucun de ces raccourcis : c'est le prix à payer, et la raison de le réserver aux petites plages.