Skip to content

Commit

Permalink
fix(Avatar): support display names using emoji and multi-byte
Browse files Browse the repository at this point in the history
  • Loading branch information
booc0mtaco committed Jul 31, 2023
1 parent 8e4e462 commit ef8c269
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 6 deletions.
2 changes: 2 additions & 0 deletions src/components/Avatar/Avatar.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

color: var(--eds-theme-color-text-neutral-strong);
background-color: var(--eds-theme-color-background-neutral-medium);

white-space: nowrap;
}

.avatar:focus-visible {
Expand Down
43 changes: 40 additions & 3 deletions src/components/Avatar/Avatar.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,7 @@ export default {

type Args = React.ComponentProps<typeof Avatar>;

export const Default: StoryObj<Args> = {
args: {},
};
export const Default: StoryObj<Args> = {};

export const Small: StoryObj<Args> = {
args: {
Expand Down Expand Up @@ -70,3 +68,42 @@ export const UsingInitials: StoryObj<Args> = {
},
},
};

export const UsingEmoji: StoryObj<Args> = {
args: {
variant: 'initials',
user: {
fullName: 'Young Yarn Lad',
displayName: '🧶👦🏽',
id: '12345',
hasArbitraryMetadata: true,
},
size: 'lg',
},
};

export const WhenImageVariantMissingSource: StoryObj<Args> = {
args: {
variant: 'image',
user: {
fullName: 'Young Yarn Lad',
id: '12345',
hasArbitraryMetadata: true,
moreMetadata: 123,
},
size: 'lg',
},
};

export const UsingMultibyteUnicode: StoryObj<Args> = {
args: {
variant: 'image',
user: {
fullName: '你好世界',
id: '12345',
hasArbitraryMetadata: true,
moreMetadata: 123,
},
size: 'lg',
},
};
19 changes: 16 additions & 3 deletions src/components/Avatar/Avatar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ export type UserData = {
* User ID associated with the attached user
*/
id?: string | number;
/**
* The display shortcut for the user name. Can be initials, emoji, or other text symbols (recommended max: 2)
*/
displayName?: string;
/**
* Additional data for an attached user (email, etc.)
*/
Expand Down Expand Up @@ -56,7 +60,7 @@ function getInitials(fromName: string): string {
* - User's name has a middle name or initial: John C. Smith
* - User's Name has dashes in it
*/
return fromName
const initials = fromName
.split(' ')
.map((part) => part[0])
.reduce(
Expand All @@ -65,6 +69,7 @@ function getInitials(fromName: string): string {
'',
)
.toUpperCase();
return initials;
}

/**
Expand Down Expand Up @@ -94,18 +99,26 @@ export const Avatar = ({
ariaLabel ??
`Avatar for ${user ? '' : 'unknown '}user ${user?.fullName || ''}`;

// use the display name if prop is provided. Otherwise, try to calculate initials
let avatarDisplayName = user ? getInitials(user.fullName) : '??';

if (user?.displayName) {
avatarDisplayName = user.displayName;
}

return (
<div
aria-label={descriptiveLabel}
className={componentClassName}
role="img"
{...other}
>
{variant === 'initials' && (user ? getInitials(user.fullName) : '??')}
{variant === 'initials' && avatarDisplayName}
{variant === 'icon' && <Icon name="person" purpose="decorative" />}
{variant === 'image' && (
{variant === 'image' && src && (
<img alt="user" className={styles['avatar__image']} src={src} />
)}
{variant === 'image' && !src && avatarDisplayName}
</div>
);
};
30 changes: 30 additions & 0 deletions src/components/Avatar/__snapshots__/Avatar.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,16 @@ exports[`<Avatar /> Square story renders snapshot 1`] = `
</div>
`;

exports[`<Avatar /> UsingEmoji story renders snapshot 1`] = `
<div
aria-label="Avatar for user Young Yarn Lad"
class="avatar avatar--circle avatar--lg avatar--initials"
role="img"
>
🧶👦🏽
</div>
`;

exports[`<Avatar /> UsingImage story renders snapshot 1`] = `
<div
aria-label="Avatar for unknown user "
Expand All @@ -124,6 +134,26 @@ exports[`<Avatar /> UsingInitials story renders snapshot 1`] = `
</div>
`;

exports[`<Avatar /> UsingMultibyteUnicode story renders snapshot 1`] = `
<div
aria-label="Avatar for user 你好世界"
class="avatar avatar--circle avatar--lg avatar--image"
role="img"
>
</div>
`;

exports[`<Avatar /> WhenImageVariantMissingSource story renders snapshot 1`] = `
<div
aria-label="Avatar for user Young Yarn Lad"
class="avatar avatar--circle avatar--lg avatar--image"
role="img"
>
YL
</div>
`;

exports[`<Avatar /> WithCustomLabel story renders snapshot 1`] = `
<div
aria-label="Custom label for avatar"
Expand Down

0 comments on commit ef8c269

Please sign in to comment.