Skip to content

Pending Review

Pending Review from User Experience (UX)

Avatar Component

Overview

The PWC Avatar is a circular typography component in the Progress Web Components design system. It provides consistent display of user initials and profile representation across React and Angular applications.

Core Capabilities

  • Initial Display - Shows user initials in a circular container with consistent typography
  • Typography Integration - Built on PWC Body component with inverse color theming
  • Responsive Design - Fixed 2rem size that scales appropriately across screen sizes
  • Accessibility Support - Screen reader friendly with semantic markup structure
  • Theme Integration - Uses design system tokens for consistent visual appearance
  • Lightweight Implementation - Minimal footprint with efficient rendering performance

When to use Avatar:

  • Display user initials in profile sections and navigation areas
  • Represent users in comment threads, activity feeds, and collaboration interfaces
  • Provide visual identity in data tables showing user associations
  • Create consistent user representation across application interfaces

When not to use Avatar:

  • Complex profile images or photos (use dedicated image components)
  • Brand logos or company representations (use logo components)
  • Large profile displays requiring additional user information

Basic Implementation

import React, { useState, useCallback } from 'react';
import { PwcAvatar, PwcFlex, PwcButton, PwcHeading } from '@progress-i360/pwc-react';

function UserProfile() {
  const [users] = useState([
    { id: 1, name: 'John Doe', email: 'john@company.com' },
    { id: 2, name: 'Alice Smith', email: 'alice@company.com' },
    { id: 3, name: 'Bob Wilson', email: 'bob@company.com' }
  ]);
  const [currentIndex, setCurrentIndex] = useState(0);

  const generateInitials = useCallback((name: string) => {
    return name.split(' ')
      .map(part => part.charAt(0).toUpperCase())
      .slice(0, 2)
      .join('');
  }, []);

  const handleNextUser = useCallback(() => {
    setCurrentIndex((prev) => (prev + 1) % users.length);
  }, [users.length]);

  const currentUser = users[currentIndex];

  return (
      <PwcFlex gap="m" alignItems="center">
        <PwcAvatar initials={generateInitials(currentUser.name)} />
        <PwcFlex direction="column" gap="xs">
          <PwcHeading content={currentUser.name} size="s" />
          <PwcButton
            label="Next User"
            variant="outline"
            onPwcClick={handleNextUser}
          />
        </PwcFlex>
      </PwcFlex>
  );
}
import { useCallback, useDeferredValue, useOptimistic, useState } from 'react';
import '@progress-i360/progress-web-components/avatar';
import '@progress-i360/progress-web-components/flex';
import '@progress-i360/progress-web-components/button';
import '@progress-i360/progress-web-components/body';

function TeamAvatarList() {
  const [teamMembers, setTeamMembers] = useState([
    { id: 1, name: 'Alice Johnson', status: 'online' },
    { id: 2, name: 'Bob Smith', status: 'away' },
    { id: 3, name: 'Carol Davis', status: 'offline' }
  ]);

  const deferredMembers = useDeferredValue(teamMembers);
  const [optimisticMembers, addOptimisticMember] = useOptimistic(
    deferredMembers,
    (state, newMember) => [...state, newMember]
  );

  const generateInitials = (name: string) => {
    return name
      .split(' ')
      .map((part) => part.charAt(0).toUpperCase())
      .slice(0, 2)
      .join('');
  };

  const addTeamMember = useCallback(async () => {
    const newMember = {
      id: Date.now(),
      name: 'New Member',
      status: 'online'
    };

    addOptimisticMember(newMember);

    // Simulate API call
    await new Promise((resolve) => setTimeout(resolve, 1000));
    setTeamMembers((prev) => [...prev, newMember]);
  }, [addOptimisticMember]);

  return (
    <pwc-flex direction="column" gap="l">
      <pwc-flex gap="s" align-items="center" wrap="wrap">
        {optimisticMembers.map((member) => (
          <pwc-flex key={member.id} direction="column" align-items="center" gap="xs">
            <pwc-avatar initials={generateInitials(member.name)}></pwc-avatar>
            <pwc-body content={member.status} size="xs"></pwc-body>
          </pwc-flex>
        ))}
      </pwc-flex>
      <pwc-button
        label="Add Team Member"
        variant="primary"
        onPwcClick={addTeamMember}
      ></pwc-button>
    </pwc-flex>
  );
}
import { Component, CUSTOM_ELEMENTS_SCHEMA } from "@angular/core";
import "@progress-i360/progress-web-components/avatar";
import "@progress-i360/progress-web-components/flex";
import "@progress-i360/progress-web-components/button";
import "@progress-i360/progress-web-components/heading";

@Component({
  selector: 'avatar-demo',
  template: `
    <pwc-flex gap="m" align-items="center">
      <pwc-avatar [initials]="userInitials"></pwc-avatar>
      <pwc-flex direction="column" gap="s">
        <pwc-heading [content]="userName" size="m"></pwc-heading>
        <pwc-button label="Change User" variant="outline" (pwc-click)="changeUser()"></pwc-button>
      </pwc-flex>
    </pwc-flex>
  `,
  schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
export class AvatarDemo {
  userName = 'John Smith';
  userInitials = 'JS';

  users = [
    { name: 'Alice Johnson', initials: 'AJ' },
    { name: 'Bob Wilson', initials: 'BW' },
    { name: 'Carol Davis', initials: 'CD' }
  ];
  currentIndex = 0;

  changeUser() {
    this.currentIndex = (this.currentIndex + 1) % this.users.length;
    const user = this.users[this.currentIndex];
    this.userName = user.name;
    this.userInitials = user.initials;
  }
}
const avatar = document.createElement('pwc-avatar');
avatar.setAttribute('initials', 'JD');

const container = document.createElement('pwc-flex');
container.setAttribute('gap', 'm');
container.setAttribute('align-items', 'center');

// Dynamic initials generation from full name
function generateInitials(fullName) {
  return fullName
    .split(' ')
    .map(name => name.charAt(0).toUpperCase())
    .slice(0, 2)
    .join('');
}

// User cycling functionality
const users = [
  { name: 'Alice Johnson', role: 'Designer' },
  { name: 'Bob Wilson', role: 'Developer' },
  { name: 'Carol Davis', role: 'Manager' }
];
let currentIndex = 0;

const cycleButton = document.createElement('pwc-button');
cycleButton.setAttribute('label', 'Next User');
cycleButton.addEventListener('pwc-click', () => {
  currentIndex = (currentIndex + 1) % users.length;
  const user = users[currentIndex];
  avatar.setAttribute('initials', generateInitials(user.name));
});

container.appendChild(avatar);
container.appendChild(cycleButton);
document.body.appendChild(container);

Usage Patterns

Avatar components adapt to different user representation scenarios:

  • Static Initials - Display predefined user initials for consistent identification
  • Dynamic Generation - Generate initials from full names or user data objects
  • Profile Integration - Combine with user names and additional profile information
  • List Display - Show multiple avatars in user lists, comment threads, or activity feeds

Best Practices

Content Strategy Guidelines

  • Meaningful Initials - Use first and last name initials for clear user identification
  • Consistent Formatting - Apply uppercase formatting for professional appearance
  • Fallback Handling - Provide default initials when user names are unavailable
  • Character Limits - Limit to 2-3 characters maximum for optimal readability

Performance Optimization

  • Efficient Rendering - Leverage component reusability for lists of multiple avatars
  • Memory Management - Avoid unnecessary re-renders when initials don't change
  • Lightweight Markup - Minimal DOM structure for fast loading and rendering
  • CSS Optimization - Use design system tokens for consistent styling performance

Integration Architecture

  • User Data Binding - Connect initials to user management systems and data sources
  • Responsive Behavior - Ensure consistent appearance across different screen sizes
  • Theme Compatibility - Maintain proper contrast ratios in light and dark themes
  • Accessibility Standards - Include proper ARIA labels for screen reader support

Common Use Cases

Data Table Headers

  • User Assignment Columns - Show assigned users in project management tables
  • Author Attribution - Display content creators in document and article listings
  • Team Member Display - Represent team members in collaborative workspace tables

Search Result Sections

  • User Search Results - Display user avatars in people search and directory interfaces
  • Comment Attribution - Show comment authors in search results and activity feeds
  • Contact Listings - Represent contacts in address book and communication interfaces

Dashboard Widget Headers

  • Activity Feeds - Show user avatars in recent activity and notification widgets
  • Team Overviews - Display team member avatars in project dashboard widgets
  • User Status - Represent online users and availability in collaboration dashboards

Troubleshooting

Common Issues

Initials Not Displaying

Problem: Avatar appears empty or shows no initials

Solution:

  • Verify initials property is set correctly and contains valid string characters

Initials Not Visible

Problem: Initials text appears but isn't readable or visible

Solution:

  • Check contrast ratios and ensure inverse color theming is working properly

Layout Issues

Problem: Avatar doesn't align properly with adjacent content

Solution:

  • Use CSS flexbox or grid properties to align avatar with surrounding elements

Icon Problems

Problem: Avatar doesn't render consistently across different browsers

Solution:

  • Verify web component polyfills are loaded and CSS variables are supported

Implementation Support

For detailed implementation guidance:

  • Typography Integration - Works with PWC Body component for consistent text styling
  • Design System Tokens - Uses standard color and sizing tokens for theme consistency
  • Framework Compatibility - Tested across React, Angular, and vanilla JavaScript implementations

Resources

Storybook Documentation

For comprehensive API documentation, interactive examples, and testing tools: 📖 View Complete API Documentation in Storybook →


This guide provides high-level implementation guidance. For detailed API specifications and interactive examples, visit our Storybook documentation.