Skip to content

feat!: Revamped Avatar component#1048

Open
pawelgrimm wants to merge 37 commits into
mainfrom
pawel/avatar-component-api
Open

feat!: Revamped Avatar component#1048
pawelgrimm wants to merge 37 commits into
mainfrom
pawel/avatar-component-api

Conversation

@pawelgrimm
Copy link
Copy Markdown
Contributor

@pawelgrimm pawelgrimm commented May 26, 2026

Summary

We are bringing the Avatar component up to spec with the design, including:

  • Support for specific sizes
  • Circle and rounded shapes
  • Dynamic image URL selection (based on srcset)
  • Image load failure handling
  • Wider array of initials/meta colors
  • Accessibility handling for custom or decorative labels

We also added a new documentation page for the component, which walks through all the features it supports. The new and improved stories feature all the contributors to this repo from the past year 😁

We also removed some features that we don't really need:

  • media query-based responsive sizing
  • Deriving initials from email (you can just pass the user's email as name, if desired)

Sorry for the rather large PR — I'd split it up, but that would mean pushing accompanying stories, docs, and tests in a separate PR, which isn't great either. Lmk if you feel strongly about having a smaller PR in this case and I can do my best to rework it.

References

Demo

📸 Demo

BeforeAfter
CleanShot 2026-05-27 at 11 57 05 CleanShot 2026-05-27 at 11 57 19

PR Checklist

  • Added tests for bugs / new features
  • Updated docs (storybooks, readme)
  • Reviewed and approved Chromatic visual regression tests in CI

@pawelgrimm pawelgrimm force-pushed the pawel/avatar-component-api branch from a953da4 to 8f6ff49 Compare May 27, 2026 16:30
@pawelgrimm pawelgrimm changed the title feat: add avatar component feat!: Revamped Avatar component May 27, 2026
@pawelgrimm pawelgrimm self-assigned this May 27, 2026
@pawelgrimm pawelgrimm added the 🙋 Ask PR Used for PRs that need a review before merging. label May 27, 2026
@pawelgrimm pawelgrimm marked this pull request as ready for review May 27, 2026 16:51
@pawelgrimm pawelgrimm requested review from a team and rmartins90 and removed request for a team May 27, 2026 16:56
Copy link
Copy Markdown
Member

@doistbot doistbot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks pawelgrimm for your contribution 😊. The new fallback handling and dynamic image selection look solid, and the updated documentation featuring contributor avatars is a great touch.

Few things worth tightening:

  • Wrap the component in React.forwardRef and restore the ...props rest spread to the root element to maintain a flexible, standard API.
  • Derive the default fallback label from the normalized name instead of the raw prop so whitespace-only inputs don't yield a blank accessible name.
  • Add a base jest-axe test to the suite per our guidelines, alongside a targeted test verifying that custom alt text is correctly exposed on the initials fallback.

I also included a few optional follow-up notes in the details below.

Optional follow-up notes (6)
  • [P3] src/avatar/avatar.stories.tsx:9: This duplicates the supported-size list that already exists as AVATAR_SIZES in utils.ts. If the component contract changes, the stories/playground can drift from the actual runtime/type surface. Import the shared constant here instead of maintaining a second copy.
  • [P3] src/avatar/utils.ts:74: normalizeAvatarName already replaces all whitespace sequences with a single space. Using .split(' ') here produces identical results and avoids running the Unicode regex engine a second time.
  • [P3] src/avatar/utils.ts:147: Consider adding a fast-path if (failedSources.length === 0) return imageProps; before checking imageProps.sources. This avoids re-filtering the array and reconstructing the image properties object on every render for the typical happy path where no image sources have failed.
  • [P3] src/avatar/avatar.tsx:102: getInitials(name) and getAvatarMetaColorIndex(name) now run on every render, even when availableImageSources is truthy and the component never uses the initials/meta-color path. For image-heavy avatar lists, that adds avoidable normalization/segmentation/hash work to the hot path. Computing these only when we actually fall back to initials would avoid that per-render overhead.
  • [P3] src/avatar/avatar.mdx:25: This docs page now renders all of the image-heavy canvases inline, and most of those stories use live GitHub avatar URLs. Opening Avatar.mdx will trigger roughly 26 external image requests up front, which makes Storybook/Chromatic slower and less deterministic than it needs to be. Using local fixtures (or trimming the number of inline canvases) would avoid that resource overhead.
  • [P3] src/avatar/avatar.tsx:113: This new metaColor-* class family is camel-cased, but Reactist’s CSS naming convention is dash-separated (variant-primary, size-small, etc.). Please rename these lookups/classes to something like meta-color-* so Avatar stays consistent with the rest of the library.

Share FeedbackReview Logs

Comment thread src/avatar/avatar.tsx Outdated
Comment thread src/avatar/avatar.test.tsx
Comment thread src/avatar/avatar.tsx Outdated
Comment thread src/avatar/avatar.tsx Outdated
Comment thread src/avatar/avatar.test.tsx
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🙋 Ask PR Used for PRs that need a review before merging.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants