KDS
Display

Avatar

Retrato circular de pessoa ou entidade com fallback automático.

Overview

Avatar é o retrato circular de uma pessoa ou entidade no KDS. Constrói em cima de @radix-ui/react-avatar, que cuida de uma sutileza importante: a estratégia de fallback. Enquanto a imagem carrega, o AvatarFallback ocupa o espaço; se a imagem errar, o fallback permanece. Avatar nunca renderiza como imagem quebrada nem como círculo vazio.

A política de fallback do KDS é uma cascata: imagem real → iniciais do nome → ícone genérico (User do lucide). O calculador de iniciais deve respeitar Unicode (acentos, ç, nomes não-latinos). Para nomes asiáticos / árabes / cirílicos, prefira a primeira letra do nome inteiro em vez de tentar separar primeiro/último nome.

Preview
Avatar com imagem carregada e fallback de iniciais pronto.
BK

Anatomy

<Avatar size="default">
  ├─ [data-slot="avatar"]
  ├─ [data-size="sm" | "default" | "lg"]
  ├─ <AvatarImage src alt />        ← renderiza só após load com sucesso
  └─ <AvatarFallback>BK</AvatarFallback>  ← renderiza durante load e em erro
</Avatar>

A propagação do data-size permite que AvatarBadge e AvatarGroupCount ajustem-se automaticamente sem props redundantes.

Subcomponents

ComponenteDescrição
AvatarContainer circular com size e data-slot.
AvatarImage<img> que renderiza só após load com sucesso.
AvatarFallbackRenderiza enquanto carrega e quando há erro. Recebe iniciais ou ícone.
AvatarBadgePequeno indicador (online, presence) sobreposto no canto.
AvatarGroupWrapper que sobrepõe múltiplos Avatars com ring.
AvatarGroupCount"+N" rollup dentro de AvatarGroup.

Usage

import {
  Avatar,
  AvatarFallback,
  AvatarImage
} from "@kalvner/kds/display/avatar";

function getInitials(name: string) {
  const parts = name.trim().split(/\s+/);
  if (parts.length === 1) return parts[0].slice(0, 2).toUpperCase();
  return (parts[0][0] + parts[parts.length - 1][0]).toUpperCase();
}

export function UserAvatar({ name, photoUrl }: { name: string; photoUrl?: string }) {
  return (
    <Avatar>
      {photoUrl ? <AvatarImage src={photoUrl} alt={name} /> : null}
      <AvatarFallback>{getInitials(name)}</AvatarFallback>
    </Avatar>
  );
}

Props

Avatar

PropTipoDefaultDescrição
size'sm' | 'default' | 'lg''default'Tamanho — 24px / 32px / 40px. Para XL, passe size-12+ via className.
...restReact.ComponentProps<typeof Root>Tudo que o root do Radix Avatar aceita.

AvatarImage

Aceita props nativas de <img>src, alt, loading, referrerPolicy. Sempre passe alt real (nome da pessoa); o Radix injeta o atributo no DOM mesmo durante o fallback para manter a semântica.

AvatarFallback

Aceita delayMs (default 0) e qualquer prop de <div>. O delayMs adia a renderização do fallback — útil em conexões rápidas para evitar flash de iniciais antes da imagem carregar.

Variants

Image
Imagem real carregada.
BK
Initials
Sem imagem — iniciais derivadas do nome.
BK
Icon
Sem nome — ícone genérico de pessoa.
Image error
Src quebrado → fallback permanece.
JS

States

Sizes
sm 24px · default 32px · lg 40px · custom xl via size-12.
BKBKBKBK

Composition

AvatarGroup
Sobreposição com +N rollup para grupos grandes.
BKJSMN
+12
User row
Avatar + nome + cargo — padrão recorrente.
BK

Bruno Kalvner

Design System Engineer

When to use

  • Em listas de pessoas — membros, comentários, threads, autores.
  • Em headers de cards de perfil ou de cards de comunicação.
  • Como avatar do usuário logado em headers e menus de navegação.
  • Em pickers de assignees (atribuir a alguém em uma task).

When not to use

  • Para logos de empresa em headers — use um <img> direto ou um componente Logo dedicado. Avatar é circular por design e nem todo logo se traduz bem para um círculo.
  • Para ícones decorativos de seção — use ícone do lucide direto. Avatar carrega a expectativa de "pessoa".
  • Para imagens grandes (banners, capas) — use <img> com aspect-*.

Best practices

  • Sempre tenha um fallback. Mesmo quando a imagem é virtualmente garantida, deixe AvatarFallback no markup. Network falha; cache expira; usuário sem perfil aparece.
  • Calcule iniciais com Unicode em mente. name.split(' ') falha para nomes como "周樹人" ou "محمد". Para esses, use o primeiro caractere; nunca tente "primeiro + último". Bibliotecas como initials lidam com isso, ou faça a função simples e teste com ASCII + acentos.
  • Limite AvatarGroup a 5 visíveis. Acima disso, sobreposição vira mancha. Use AvatarGroupCount para o rollup ("+12 outros").
  • alt obrigatório, mesmo no fallback. O Radix Avatar mantém o alt no DOM mesmo durante o fallback. Sem alt, leitores de tela ignoram o avatar — perda de contexto em listas de pessoas.
  • Não use o avatar como botão de menu sem aria-label. Em headers, o avatar costuma abrir um menu — wrap em <button aria-label="Menu da conta"> para que leitores de tela saibam o que vai acontecer.

Accessibility

ConcernComportamento
altSempre presente no AvatarImage. Use o nome real da pessoa, não "Avatar".
Fallback semânticoQuando o fallback é iniciais, leitores de tela leem as letras como acrônimo — geralmente OK. Para fallback de ícone, garanta que o entorno (texto ao lado) carrega o nome.
RolesSem role específica. O <img> interno tem role img natural.
Decorativo vs informativoEm listas de pessoas, avatar é informativo — alt é obrigatório. Em compositions onde o nome aparece logo ao lado, considere aria-hidden="true" no Avatar para evitar redundância.
Touch targetSizes default (32px) e sm (24px) são pequenos para alvos clicáveis. Quando o Avatar é interativo, wrap em um <button> com padding mínimo de 44px (WCAG 2.5.5).
Status badgeQuando combinar com AvatarBadge para indicar presença, comunique também via texto adjacent — daltonismo afeta a leitura de cor (verde vs cinza).
  • Skeleton — placeholder circular para Avatar em loading.
  • Card — frequente container de Avatar em headers.
  • Badge — para metadados ao lado do nome (Pro, Beta, contagem).
  • Radix Avatar docs — referência do primitivo subjacente.

On this page