-
Notifications
You must be signed in to change notification settings - Fork 23
feat!: Revamped Avatar component #1048
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
41 commits
Select commit
Hold shift + click to select a range
99b4dc3
feat: add avatar utility primitives
pawelgrimm 5942fd4
fix: preserve unicode avatar initials
pawelgrimm a3527b7
fix: preserve avatar utility type checks
pawelgrimm b4e89bc
fix: normalize avatar initials before comparison
pawelgrimm cdbe28d
feat: replace avatar primitive API
pawelgrimm 329ea17
fix: retry avatar image after prop reset
pawelgrimm 9e7ad43
docs: update avatar stories
pawelgrimm 1d3d104
docs: add avatar product wrappers
pawelgrimm f35cade
fix: preserve avatar initials and fallback examples
pawelgrimm 9b66cd7
fix: cap avatar initials after uppercase expansion
pawelgrimm 589a075
fix: address avatar review findings
pawelgrimm d745858
fix: type avatar story playground args
pawelgrimm c37d041
refactor: inline avatar accessibility props
pawelgrimm ae2957a
refactor: rely on native avatar srcset selection
pawelgrimm ec3dd2a
fix: retry avatar srcset candidates after load failure
pawelgrimm ad8a98d
refactor: simplify avatar initials generation
pawelgrimm 5da1d9b
docs: document avatar public api
pawelgrimm 8a86a03
refactor: clarify avatar image identity key
pawelgrimm fa0b235
refactor: Clean up and clarify
pawelgrimm 49d18c0
refactor: Use Box props where possible, restructure CSS
pawelgrimm 4392eb3
feat: Implement new stories
pawelgrimm 8b1be8b
fix: Add inset border to avatars
pawelgrimm b9d130f
fix: handle empty avatar state
pawelgrimm e751657
refactor: Create improved avatar docs
pawelgrimm 211dd34
Update avatar meta color tokens
pawelgrimm bdd27c5
refactor: Rework meta color CSS custom props
pawelgrimm f0d2a2c
docs: add avatar migration guidance
pawelgrimm 5cc19fb
fix: Add ref + passthrough props support
pawelgrimm 2bdf3d3
fix: Only set aria-hidden on container
pawelgrimm 29d09e2
test: add avatar axe coverage
pawelgrimm b12ee97
fix: normalize avatar fallback labels
pawelgrimm 76abc62
refactor: apply avatar meta colors to initials
pawelgrimm 3587011
refactor: simplify avatar initials splitting
pawelgrimm a98b772
perf: skip avatar source filtering when unchanged
pawelgrimm 8d673d2
refactor: reuse avatar size constants in stories
pawelgrimm e66680f
docs: render avatar migration table as markdown
pawelgrimm ab3eef6
feat: support polymorphic avatar root
pawelgrimm 10b13ec
refactor: move avatar size styles to css
pawelgrimm 7f9421e
refactor: reset only AvatarImage when key changes
pawelgrimm 30fca01
refactor: More aria-hidden to AvatarImage
pawelgrimm 79082f0
test: extract avatar image failure helper
pawelgrimm File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,189 @@ | ||
| import { | ||
| Canvas, | ||
| ColorItem, | ||
| ColorPalette, | ||
| Controls, | ||
| Markdown, | ||
| Meta, | ||
| Subtitle, | ||
| Title, | ||
| } from '@storybook/addon-docs/blocks' | ||
|
|
||
| import * as AvatarStories from './avatar.stories' | ||
|
|
||
| <Meta of={AvatarStories} /> | ||
|
|
||
| <Title /> | ||
|
|
||
| <Subtitle>Image, initials, and empty-state avatar primitive.</Subtitle> | ||
|
|
||
| ## Basic usage | ||
|
|
||
| Use `Avatar` for people by default. Pass `size`, `name`, and an optional | ||
| `image`; `name` supplies the default accessible label, the initials fallback, | ||
| and the deterministic meta color used when initials render. | ||
|
|
||
| <Canvas of={AvatarStories.Default} /> | ||
|
|
||
| ## Migrating from the legacy API | ||
|
|
||
| The previous Avatar API accepted `user`, `avatarUrl`, `colorList`, string or | ||
| responsive `size` values, and a deprecated `className`. The current API uses | ||
| direct identity props instead: | ||
|
|
||
| <Markdown>{` | ||
| | Legacy prop | Current API | | ||
| | ------------------------------ | ------------------------------------------------------------------------ | | ||
| | \`user.name\` | \`name\` | | ||
| | \`avatarUrl\` | \`image\` | | ||
| | \`user.email\` | No replacement. Email is no longer used for initials or color selection. | | ||
| | \`colorList\` | Customize the CSS custom properties listed below. | | ||
| | \`size="l"\` or responsive sizes | Pass one supported numeric CSS-pixel \`size\`. | | ||
| | \`className\` | \`exceptionallySetClassName\` | | ||
| `}</Markdown> | ||
|
|
||
| ```tsx | ||
| <Avatar size={36} name={user.name} image={avatarUrl} exceptionallySetClassName={className} /> | ||
| ``` | ||
|
|
||
| ## Initials fallback | ||
|
|
||
| When `image` is not supplied, cannot be resolved, or every responsive image | ||
| candidate fails, Avatar falls back to initials derived from `name`. Names are | ||
| normalized before initials are generated. | ||
|
|
||
| <Canvas of={AvatarStories.InitialsFallback} /> | ||
|
|
||
| ## Workspace avatars | ||
|
|
||
| Use `shape="rounded"` for workspace-like entities. Product code can wrap | ||
| Avatar with a small convention component when a surface always represents the | ||
| same kind of entity. | ||
|
|
||
| <Canvas of={AvatarStories.WorkspaceAvatar} /> | ||
|
|
||
| ## Image sources | ||
|
|
||
| Pass a string for a single image URL, or a source map keyed by intrinsic image | ||
| width. Source maps render native `srcSet` width descriptors and a `sizes` hint | ||
| based on the selected avatar size. | ||
|
|
||
| <Canvas of={AvatarStories.ImageSources} /> | ||
|
|
||
| ## Sizes | ||
|
|
||
| Avatar supports a fixed set of CSS pixel sizes. Use one of the supported | ||
| numeric values instead of styling the avatar dimensions from the outside. | ||
|
|
||
| <Canvas of={AvatarStories.Sizes} /> | ||
|
|
||
| ## Accessibility | ||
|
|
||
| Images default to `name` for alt text. Pass `alt` when the visual needs a more | ||
| specific label, and pass `alt=""` when the avatar is decorative. | ||
|
|
||
| <Canvas of={AvatarStories.Accessibility} /> | ||
|
|
||
| ## Playground | ||
|
|
||
| Use the controls to inspect the component API and common image/name | ||
| combinations. | ||
|
|
||
| <Canvas of={AvatarStories.Playground} /> | ||
|
|
||
| ### API | ||
|
|
||
| <Controls of={AvatarStories.Playground} /> | ||
|
|
||
| ## Custom properties | ||
|
|
||
| The following CSS custom properties are available to customize the avatar | ||
| component appearance. The values shown below are the default values. | ||
|
|
||
| <Canvas of={AvatarStories.MetaColors} /> | ||
|
|
||
| ### Customizable properties | ||
|
|
||
| #### Avatar colors | ||
|
|
||
| <ColorPalette> | ||
| <ColorItem title="--reactist-avatar-initials-color" colors={['#ffffff']} /> | ||
| <ColorItem title="--reactist-avatar-border-tint" colors={['#0000001a']} /> | ||
| <ColorItem title="--reactist-avatar-empty-fill" colors={['#e6e6e6']} /> | ||
| </ColorPalette> | ||
|
|
||
| #### Avatar meta colors | ||
|
|
||
| <ColorPalette> | ||
| <ColorItem title="--reactist-avatar-meta-0-fill" colors={['#b8255f']} /> | ||
| <ColorItem title="--reactist-avatar-meta-0-on-idle-tint" colors={['#ffffff']} /> | ||
| <ColorItem title="--reactist-avatar-meta-1-fill" colors={['#dc4c3e']} /> | ||
| <ColorItem title="--reactist-avatar-meta-1-on-idle-tint" colors={['#ffffff']} /> | ||
| <ColorItem title="--reactist-avatar-meta-2-fill" colors={['#f48318']} /> | ||
| <ColorItem title="--reactist-avatar-meta-2-on-idle-tint" colors={['#ffffff']} /> | ||
| <ColorItem title="--reactist-avatar-meta-3-fill" colors={['#fecf05']} /> | ||
| <ColorItem title="--reactist-avatar-meta-3-on-idle-tint" colors={['#202020']} /> | ||
| <ColorItem title="--reactist-avatar-meta-4-fill" colors={['#aeb83a']} /> | ||
| <ColorItem title="--reactist-avatar-meta-4-on-idle-tint" colors={['#ffffff']} /> | ||
| <ColorItem title="--reactist-avatar-meta-5-fill" colors={['#7ecc48']} /> | ||
| <ColorItem title="--reactist-avatar-meta-5-on-idle-tint" colors={['#ffffff']} /> | ||
| <ColorItem title="--reactist-avatar-meta-6-fill" colors={['#369307']} /> | ||
| <ColorItem title="--reactist-avatar-meta-6-on-idle-tint" colors={['#ffffff']} /> | ||
| <ColorItem title="--reactist-avatar-meta-7-fill" colors={['#52ccb8']} /> | ||
| <ColorItem title="--reactist-avatar-meta-7-on-idle-tint" colors={['#ffffff']} /> | ||
| <ColorItem title="--reactist-avatar-meta-8-fill" colors={['#148fad']} /> | ||
| <ColorItem title="--reactist-avatar-meta-8-on-idle-tint" colors={['#ffffff']} /> | ||
| <ColorItem title="--reactist-avatar-meta-9-fill" colors={['#3ab9e2']} /> | ||
| <ColorItem title="--reactist-avatar-meta-9-on-idle-tint" colors={['#202020']} /> | ||
| <ColorItem title="--reactist-avatar-meta-10-fill" colors={['#96c3eb']} /> | ||
| <ColorItem title="--reactist-avatar-meta-10-on-idle-tint" colors={['#ffffff']} /> | ||
| <ColorItem title="--reactist-avatar-meta-11-fill" colors={['#2a67e2']} /> | ||
| <ColorItem title="--reactist-avatar-meta-11-on-idle-tint" colors={['#ffffff']} /> | ||
| <ColorItem title="--reactist-avatar-meta-12-fill" colors={['#692ec2']} /> | ||
| <ColorItem title="--reactist-avatar-meta-12-on-idle-tint" colors={['#ffffff']} /> | ||
| <ColorItem title="--reactist-avatar-meta-13-fill" colors={['#ac30cc']} /> | ||
| <ColorItem title="--reactist-avatar-meta-13-on-idle-tint" colors={['#ffffff']} /> | ||
| <ColorItem title="--reactist-avatar-meta-14-fill" colors={['#eb96c8']} /> | ||
| <ColorItem title="--reactist-avatar-meta-14-on-idle-tint" colors={['#ffffff']} /> | ||
| <ColorItem title="--reactist-avatar-meta-15-fill" colors={['#e05095']} /> | ||
| <ColorItem title="--reactist-avatar-meta-15-on-idle-tint" colors={['#ffffff']} /> | ||
| <ColorItem title="--reactist-avatar-meta-16-fill" colors={['#c9766f']} /> | ||
| <ColorItem title="--reactist-avatar-meta-16-on-idle-tint" colors={['#ffffff']} /> | ||
| <ColorItem title="--reactist-avatar-meta-17-fill" colors={['#808080']} /> | ||
| <ColorItem title="--reactist-avatar-meta-17-on-idle-tint" colors={['#ffffff']} /> | ||
| <ColorItem title="--reactist-avatar-meta-18-fill" colors={['#999999']} /> | ||
| <ColorItem title="--reactist-avatar-meta-18-on-idle-tint" colors={['#ffffff']} /> | ||
| <ColorItem title="--reactist-avatar-meta-19-fill" colors={['#ccae96']} /> | ||
| <ColorItem title="--reactist-avatar-meta-19-on-idle-tint" colors={['#ffffff']} /> | ||
| </ColorPalette> | ||
|
|
||
| ### Component-owned variables | ||
|
|
||
| Avatar's size classes set these variables from the `size` prop. They are | ||
| listed for completeness, but consumers should prefer the component props | ||
| instead of overriding them directly. | ||
|
|
||
| ```css | ||
| .avatar { | ||
| --reactist-avatar-size: 36px; | ||
| --reactist-avatar-rounded-radius: 5px; | ||
| } | ||
| ``` | ||
|
|
||
| ## What the consumer owns | ||
|
|
||
| - **Identity data** — choose the `name`, `image`, and any custom `alt` text. | ||
| - **Source selection** — provide either one URL or a width-keyed source map. | ||
| - **Entity convention** — choose `shape="circle"` for people and | ||
| `shape="rounded"` for workspace-like entities. | ||
| - **Decorative usage** — pass `alt=""` when surrounding UI already names the | ||
| represented entity. | ||
| - **Persistence and fetching** — Avatar does not load, cache, or persist remote | ||
| user/workspace data. | ||
|
|
||
| ## Accessibility | ||
|
|
||
| - `name` becomes the default image `alt` text and initials `aria-label`. | ||
| - `alt` overrides the accessible label for both image and initials rendering. | ||
| - `alt=""` marks image and initials avatars as decorative. | ||
| - An avatar with no `name` and no `image` renders as an empty decorative visual. | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.