États
Chaque composant interactif doit couvrir l'ensemble de ses états applicables. Même état = même traitement visuel sur tous les composants et tous les produits.
Règle fondamentale
Un composant sans états correctement définis est un composant incomplet. Les états ne sont pas une option, ils sont une exigence d'accessibilité et d'expérience utilisateur.
Un utilisateur qui navigue au clavier doit toujours savoir où il se trouve. Un utilisateur qui clique doit toujours recevoir un feedback visuel. Ces règles s'appliquent à tous les composants interactifs sans exception.
Catalogue des états
8 états définis. Chaque composant interactif doit implémenter les états qui le concernent.
État de repos. Design de base du composant, sans interaction en cours.
background: var(--ds-color-action-primary)
Survol de la souris. Toujours la shade 700, jamais une autre couleur.
background: var(--ds-color-action-primary-hover)
Navigation clavier. Toujours un outline visible avec la shade 100. Ne jamais supprimer le focus.
box-shadow: 0 0 0 3px var(--ds-color-action-primary-light)
Clic en cours entre le mousedown et le mouseup. Légèrement enfoncé visuellement.
transform: scale(0.98) + shade 700
Élément non disponible. Opacité réduite à 0.5, curseur not-allowed. Pas d'interaction possible.
opacity: 0.5 + cursor: not-allowed
Action en cours côté serveur. Spinner visible, toute interaction bloquée jusqu'à la réponse.
pointer-events: none + spinner animé
Format invalide
Validation échouée ou erreur système. Bordure, icône et message en couleur error. Jamais utilisé à des fins décoratives.
aria-invalid="true" → border-color: var(--ds-color-feedback-error)
Format valide
Validation réussie. Bordure et message en couleur success. Confirme à l'utilisateur que son action est correcte.
border-color: var(--ds-color-feedback-success)
Do & Don't
- Couvrir tous les états applicables dès la création du composant
-
Hover → toujours shade 700 via
var(--ds-color-action-primary-hover) - Focus → toujours un outline visible, jamais supprimé
-
Disabled → opacité 0.5 + curseur
not-allowedsystématiquement - Tester la navigation clavier sur chaque composant interactif
-
Mettre
outline: nonesans fournir une alternative visible - Traiter différemment le même état sur deux composants
- Utiliser le rouge pour autre chose que l'état error
- Laisser un composant interactif sans état hover ou disabled
-
Bloquer l'interaction via
pointer-events: nonesans signalement visuel
Règles
Chaque composant interactif doit couvrir les états applicables, au minimum default, hover, focus et disabled.
Même état = même traitement visuel. Le hover d'un bouton et le hover d'un lien suivent la même règle : shade 700.
Le focus ne doit jamais être supprimé sans alternative, c'est une exigence WCAG 2.1 niveau AA.
Loading bloque toujours l'interaction. Un utilisateur ne doit jamais pouvoir déclencher deux fois la même action.