Don't set the background color on Avatars with pictures.

When an Avatar component has a picture, the image may have a transparent
background. In that case, we don't know whether the generated background
color will work well with the image, or will clash with the image colors.
It's better to not generate a background color so the Avatar image will at
least render with predictable colors.

This fixes #11094.

Signed-off-by: James Peach <jpeach@cloudflare.com>
This commit is contained in:
James Peach
2022-05-06 15:05:15 +10:00
parent 8386a32644
commit 52c02ac02b
3 changed files with 38 additions and 4 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/core-components': patch
---
Don't set the background color on an Avatar component that has a picture.
@@ -17,6 +17,7 @@
import { render } from '@testing-library/react';
import React from 'react';
import { Avatar } from './Avatar';
import { stringToColor } from './utils';
describe('<Avatar />', () => {
it('renders without exploding', async () => {
@@ -24,4 +25,24 @@ describe('<Avatar />', () => {
expect(getByText('JD')).toBeInTheDocument();
});
it('generates a background color', async () => {
const bgcolor = stringToColor('John Doe');
const { getByText } = render(<Avatar displayName="John Doe" />);
expect(getByText('JD')).toHaveStyle(`background-color: ${bgcolor}`);
});
it('does not generate a background color when a picture is given', async () => {
const bgcolor = stringToColor('John Doe');
const { getByAltText } = render(
<Avatar
displayName="John Doe"
picture="https://backstage.io/test/john-doe.png"
/>,
);
expect(getByAltText('John Doe')).not.toHaveStyle(
`background-color: ${bgcolor}`,
);
});
});
@@ -67,15 +67,23 @@ export interface AvatarProps {
export function Avatar(props: AvatarProps) {
const { displayName, picture, customStyles } = props;
const classes = useStyles();
let styles = { ...customStyles };
// We only calculate the background color if there's not an avatar
// picture. If there is a picture, it might have a transparent
// background and we don't know whether the calculated background
// color will clash.
if (!picture) {
styles = {
backgroundColor: stringToColor(displayName || ''),
...customStyles,
};
}
return (
<MaterialAvatar
alt={displayName}
src={picture}
className={classes.avatar}
style={{
backgroundColor: stringToColor(displayName || picture || ''),
...customStyles,
}}
style={styles}
>
{displayName && extractInitials(displayName)}
</MaterialAvatar>