Skip to content

Avatar

Composant Avatar basé sur le composant Image pour afficher une photo de profil ou les initiales d'un utilisateur. Supporte les badges de notification, indicateurs de statut et accessibilité complète selon les normes W3C.

Exemples d'utilisation

Avatar de base

Avatar avec image

vue
<template>
  <SuAvatar 
    src="https://example.com/photo.jpg"
    alt="Photo de profil"
    name="John Doe"
  />
</template>

Avatar avec initiales

Avatar sans image (initiales)

vue
<template>
  <SuAvatar 
    name="Marie Dupont"
    alt="Avatar de Marie Dupont"
  />
</template>

Tailles

Tailles disponibles

XS

SM

MD

LG

XL

2XL

vue
<template>
  <SuAvatar size="xs" name="User" />
  <SuAvatar size="sm" name="User" />
  <SuAvatar size="md" name="User" />
  <SuAvatar size="lg" name="User" />
  <SuAvatar size="xl" name="User" />
  <SuAvatar size="2xl" name="User" />
</template>

Variantes de forme

Formes disponibles

Circle

Rounded

Square

vue
<template>
  <SuAvatar variant="circle" name="User" />
  <SuAvatar variant="rounded" name="User" />
  <SuAvatar variant="square" name="User" />
</template>

Avec indicateur de statut

Indicateurs de statut

Online

Away

Busy

Offline

vue
<template>
  <SuAvatar name="User" status="online" />
  <SuAvatar name="User" status="away" />
  <SuAvatar name="User" status="busy" />
  <SuAvatar name="User" status="offline" />
</template>

Avec badge de notification

Badges de notification

Badge numérique

Badge d'alerte

Nombreuses notifications

vue
<template>
  <!-- Badge numérique -->
  <SuAvatar 
    name="User"
    badge="5"
    alt="5 notifications"
  />
  
  <!-- Badge d'alerte -->
  <SuAvatar 
    name="User"
    badge="!"
    badgeColor="#f59e0b"
    alt="Alerte"
  />
  
  <!-- Badge avec texte -->
  <SuAvatar 
    name="User"
    badge="99+"
    alt="Plus de 99 notifications"
  />
</template>

Avatar cliquable

Avatar interactif

vue
<script setup>
const handleAvatarClick = () => {
  console.log('Avatar cliqué!')
}
</script>

<template>
  <SuAvatar 
    src="photo.jpg"
    alt="Photo de profil"
    name="John Doe"
    :clickable="true"
    @click="handleAvatarClick"
  />
</template>

États spéciaux

États de chargement et d'erreur

Chargement

Avec fallback

Placeholder

vue
<template>
  <!-- Avatar en chargement -->
  <SuAvatar 
    name="User"
    :loading="true"
  />
  
  <!-- Avatar avec fallback -->
  <SuAvatar 
    src="invalid-url.jpg"
    fallback="default-avatar.jpg"
    name="User"
  />
  
  <!-- Avatar placeholder -->
  <SuAvatar alt="Avatar par défaut" />
</template>

API

Props

PropTypeDefaultDescription
srcstringundefinedURL de l'image de profil
altstringundefinedTexte alternatif pour l'image
fallbackstringundefinedImage de fallback en cas d'erreur
namestringundefinedNom pour générer les initiales
size'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl''md'Taille de l'avatar
variant'circle' | 'rounded' | 'square''circle'Forme de l'avatar
status'online' | 'offline' | 'away' | 'busy'undefinedStatut de l'utilisateur
badgestring | numberundefinedBadge de notification
badgeColorstringundefinedCouleur personnalisée du badge
loadingbooleanfalseÉtat de chargement
clickablebooleanfalseAvatar cliquable

Attributs d'accessibilité

PropTypeDefaultDescription
ariaLabelstringundefinedLabel accessible
ariaDescribedBystringundefinedID de l'élément de description
rolestringundefinedRôle ARIA personnalisé
tabIndexnumber0Ordre de tabulation (si cliquable)

Events

EventTypeDescription
@click(event: MouseEvent) => voidÉmis lors du clic (si clickable)
@load(event: Event) => voidÉmis quand l'image est chargée
@error(event: Event) => voidÉmis si l'image échoue à se charger

Méthodes exposées

MéthodeTypeDescription
focus()() => voidDonne le focus à l'avatar
avatarRefRef<HTMLElement>Référence à l'élément avatar

Génération des initiales

Le composant génère automatiquement les initiales à partir du nom :

🔤 Logique de génération

  • Un mot : Première lettre (ex: "John" → "J")
  • Plusieurs mots : Première lettre du premier et dernier mot (ex: "John Doe" → "JD")
  • Normalisation : Conversion en majuscules automatique
vue
<!-- Exemples d'initiales -->
<SuAvatar name="John" />          <!-- J -->
<SuAvatar name="John Doe" />      <!-- JD -->
<SuAvatar name="Marie Claire Dubois" />  <!-- MD -->

Indicateurs de statut

🟢 Statuts disponibles

  • online : Vert - Utilisateur en ligne
  • away : Orange - Utilisateur absent
  • busy : Rouge - Utilisateur occupé
  • offline : Gris - Utilisateur hors ligne
vue
<template>
  <SuAvatar name="User" status="online" />
  <SuAvatar name="User" status="away" />
  <SuAvatar name="User" status="busy" />
  <SuAvatar name="User" status="offline" />
</template>

Badges de notification

🏷️ Types de badges

  • Numérique : Nombre de notifications
  • Texte : Indicateurs spéciaux (!, NEW, etc.)
  • Couleur personnalisée : Via la prop badgeColor
vue
<template>
  <!-- Badge numérique -->
  <SuAvatar name="User" badge="5" />
  
  <!-- Badge texte -->
  <SuAvatar name="User" badge="NEW" />
  
  <!-- Badge avec couleur personnalisée -->
  <SuAvatar name="User" badge="!" badgeColor="#f59e0b" />
</template>

Accessibilité

Le composant Avatar respecte les normes WCAG 2.1 AA :

✅ Fonctionnalités d'accessibilité

  • Alt text approprié : Génération automatique ou personnalisé
  • Navigation au clavier : Support complet si clickable
  • Attributs ARIA : Labels et descriptions pour les lecteurs d'écran
  • Annonces de statut : Statut et badges annoncés aux lecteurs d'écran
  • Focus visible : Indicateur de focus clair si cliquable
  • Contraste : Couleurs conformes WCAG AA
  • Tailles minimales : Respecte les tailles de cible tactile

🎯 Bonnes pratiques

vue
<!-- Avatar avec accessibilité complète -->
<SuAvatar 
  src="photo.jpg"
  alt="Photo de profil de John Doe"
  name="John Doe"
  status="online"
  badge="3"
  :clickable="true"
  aria-label="Profil de John Doe, en ligne, 3 notifications"
/>

<!-- Avatar décoratif -->
<SuAvatar 
  src="photo.jpg"
  alt=""
  aria-hidden="true"
/>

<!-- Avatar avec description -->
<SuAvatar 
  name="Marie Dupont"
  alt="Marie Dupont"
  aria-describedby="user-description"
/>
<div id="user-description">
  Développeuse frontend, membre de l'équipe depuis 2 ans
</div>
ToucheAction
TabNaviguer vers/depuis l'avatar (si cliquable)
EntréeActiver l'avatar (si cliquable)
EspaceActiver l'avatar (si cliquable)

Exemples d'usage avancés

Profil utilisateur

vue
<script setup>
const user = {
  name: 'John Doe',
  avatar: 'https://example.com/avatar.jpg',
  status: 'online',
  notifications: 5
}

const handleProfileClick = () => {
  // Ouvrir le profil utilisateur
  console.log('Ouvrir le profil')
}
</script>

<template>
  <div class="user-profile">
    <SuAvatar 
      :src="user.avatar"
      :alt="`Photo de profil de ${user.name}`"
      :name="user.name"
      :status="user.status"
      :badge="user.notifications.toString()"
      size="xl"
      :clickable="true"
      @click="handleProfileClick"
    />
    
    <div class="user-info">
      <h3>{{ user.name }}</h3>
      <p>Développeur Frontend</p>
      <span class="status">{{ user.status }}</span>
    </div>
  </div>
</template>

<style scoped>
.user-profile {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 1rem;
  background-color: white;
  border-radius: 0.5rem;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.user-info h3 {
  margin: 0 0 0.25rem 0;
  color: #1f2937;
}

.user-info p {
  margin: 0 0 0.5rem 0;
  color: #6b7280;
  font-size: 0.875rem;
}

.status {
  font-size: 0.75rem;
  font-weight: 500;
  color: #10b981;
}
</style>

Liste de contacts

vue
<script setup>
const contacts = [
  { name: 'Alice Martin', status: 'online', badge: '2' },
  { name: 'Bob Johnson', status: 'away' },
  { name: 'Carol Smith', status: 'busy', badge: '!' },
  { name: 'David Wilson', status: 'offline' }
]
</script>

<template>
  <div class="contacts-list">
    <h3>Contacts</h3>
    
    <div 
      v-for="contact in contacts"
      :key="contact.name"
      class="contact-item"
    >
      <SuAvatar 
        :name="contact.name"
        :alt="`Avatar de ${contact.name}`"
        :status="contact.status"
        :badge="contact.badge"
        :clickable="true"
      />
      
      <div class="contact-info">
        <h4>{{ contact.name }}</h4>
        <p>{{ contact.status }}</p>
      </div>
    </div>
  </div>
</template>

<style scoped>
.contacts-list {
  max-width: 300px;
}

.contact-item {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.75rem;
  border-radius: 0.5rem;
  transition: background-color 0.2s;
}

.contact-item:hover {
  background-color: #f9fafb;
}

.contact-info h4 {
  margin: 0 0 0.125rem 0;
  font-size: 0.875rem;
  color: #1f2937;
}

.contact-info p {
  margin: 0;
  font-size: 0.75rem;
  color: #6b7280;
  text-transform: capitalize;
}
</style>

Publié sous licence MIT.