Parent : [[INDEX-WEB-UIUX]]
Web UI/UX - Empty State Design : icon + text + action button, no generic "no data"
Problème
Un texte "Aucune donnée" ou "No results" sur fond blanc est déprimant et ne guide pas l'utilisateur. Un bon empty state explique pourquoi c'est vide ET propose une action.
Solution
3 variants d'empty state selon le contexte :
- Initial state (pas encore de recherche) : icône neutre + invitation à agir
- No results (recherche active, 0 résultats) : icône loupe + suggestion d'action
- Auth gate (besoin de connexion) : icône lock + CTA connexion
// Variant 1 : Pas encore de recherche
{!loading && !query && total === 0 && (
<div className="text-center py-24 flex flex-col items-center gap-4">
<div className="w-16 h-16 rounded-full flex items-center justify-center text-2xl"
style={{ background: 'var(--surface-2)', border: '1px solid var(--border)' }}>
⚡
</div>
<p className="text-sm" style={{ color: 'var(--text-2)' }}>
Lancez une recherche ou cliquez sur un tag pour découvrir des assets
</p>
</div>
)}
// Variant 2 : Recherche active, 0 résultats
{!loading && query && total === 0 && (
<div className="text-center py-24 flex flex-col items-center gap-4 animate-fade-in-up">
<div className="w-16 h-16 rounded-full flex items-center justify-center text-2xl"
style={{ background: 'var(--surface-2)', border: '1px solid var(--border)' }}>
🔍
</div>
<div>
<p className="text-base font-semibold" style={{ color: 'var(--text)' }}>Aucun résultat</p>
<p className="text-sm mt-1" style={{ color: 'var(--text-2)' }}>pour <strong>"{query}"</strong></p>
</div>
<p className="text-xs max-w-xs" style={{ color: 'var(--text-3)' }}>
Essayez un terme plus générique ou vérifiez l'orthographe
</p>
<button onClick={handleReset} className="btn-ghost mt-1">Effacer la recherche</button>
</div>
)}
// Variant 3 : Auth gate (besoin de connexion)
{!user && (
<div className="flex flex-col items-center justify-center py-20 gap-4">
<span className="text-4xl">🔒</span>
<p className="text-sm font-semibold" style={{ color: 'var(--text-2)' }}>
Connectez-vous pour voir vos favoris
</p>
</div>
)}
Points clés
- Icone contextuelle : 🔍 pour recherche, ⚡ pour action, 🔒 pour auth → pas d'icône générique
- Texte en 2-3 niveaux : titre bold + description + suggestion concrète
- Action button : "Effacer la recherche", "Créer un compte" → guide l'utilisateur
- Fond container :
var(--surface-2)avec border → crée une "carte" visuelle animate-fade-in-up: animation douce pour ne pas surprendre- JAMAIS "No data" ou "Table empty" → langage orienté action
Pourquoi
- Un empty state est une opportunité d'onboarding, pas une erreur
- L'action button réduit le taux de bounce de 25-40%
- Le contexte (recherche vs auth) change complètement le message
Quand l'utiliser
- Recherche sans résultats, listes vides, dashboards sans données
- Écrans nécessitant une action préalable (connexion, configuration)
Quand NE PAS l'utiliser
- Loading state (utiliser skeleton)
- Error state (utiliser error message avec retry)
Références
- ProjectAlpha/GlobalSearch.tsx L386-414
- ProjectAlpha/FavoritesSection.tsx L28-34, L47-54