1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-12-23 09:52:26 +01:00

Updating Avatar components to forward refs (#18678)

Co-authored-by: Brad Decker <bhdecker84@gmail.com>
This commit is contained in:
George Marshall 2023-04-21 08:51:34 -07:00 committed by GitHub
parent 7617a44a57
commit d2779c9ef1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 217 additions and 145 deletions

View File

@ -13,32 +13,38 @@ import {
AvatarAccountSize, AvatarAccountSize,
} from './avatar-account.types'; } from './avatar-account.types';
export const AvatarAccount = ({ export const AvatarAccount = React.forwardRef(
size = AvatarAccountSize.Md, (
address, {
className, size = AvatarAccountSize.Md,
variant = AvatarAccountVariant.Jazzicon, address,
...props className,
}) => ( variant = AvatarAccountVariant.Jazzicon,
<AvatarBase ...props
size={size} },
className={classnames('mm-avatar-account', className)} ref,
{...props} ) => (
> <AvatarBase
{variant === AvatarAccountVariant.Jazzicon ? ( ref={ref}
<Jazzicon size={size}
className={classnames('mm-avatar-account__jazzicon')} className={classnames('mm-avatar-account', className)}
address={address} {...props}
diameter={AvatarAccountDiameter[size]} >
/> {variant === AvatarAccountVariant.Jazzicon ? (
) : ( <Jazzicon
<BlockieIdenticon className={classnames('mm-avatar-account__jazzicon')}
address={address} address={address}
diameter={AvatarAccountDiameter[size]} diameter={AvatarAccountDiameter[size]}
borderRadius="50%" />
/> ) : (
)} <BlockieIdenticon
</AvatarBase> address={address}
diameter={AvatarAccountDiameter[size]}
borderRadius="50%"
/>
)}
</AvatarBase>
),
); );
AvatarAccount.propTypes = { AvatarAccount.propTypes = {
@ -66,3 +72,5 @@ AvatarAccount.propTypes = {
*/ */
...Box.propTypes, ...Box.propTypes,
}; };
AvatarAccount.displayName = 'AvatarAccount';

View File

@ -112,4 +112,15 @@ describe('AvatarAccount', () => {
'mm-avatar-base--size-xl', 'mm-avatar-base--size-xl',
); );
}); });
it('should forward a ref to the root html element', () => {
const ref = React.createRef();
render(
<AvatarAccount
address="0x5CfE73b6021E818B776b421B1c4Db2474086a7e1"
ref={ref}
/>,
);
expect(ref.current).not.toBeNull();
expect(ref.current.nodeName).toBe('DIV');
});
}); });

View File

@ -121,4 +121,10 @@ describe('AvatarBase', () => {
`box--border-color-${Color.errorDefault}`, `box--border-color-${Color.errorDefault}`,
); );
}); });
it('should forward a ref to the root html element', () => {
const ref = React.createRef();
render(<AvatarBase ref={ref}>A</AvatarBase>);
expect(ref.current).not.toBeNull();
expect(ref.current.nodeName).toBe('DIV');
});
}); });

View File

@ -15,43 +15,48 @@ import {
import { useI18nContext } from '../../../hooks/useI18nContext'; import { useI18nContext } from '../../../hooks/useI18nContext';
import { AVATAR_FAVICON_SIZES } from './avatar-favicon.constants'; import { AVATAR_FAVICON_SIZES } from './avatar-favicon.constants';
export const AvatarFavicon = ({ export const AvatarFavicon = React.forwardRef(
size = Size.MD, (
src, {
name = 'avatar-favicon', size = Size.MD,
className, src,
fallbackIconProps, name = 'avatar-favicon',
borderColor = BorderColor.transparent, className,
...props fallbackIconProps,
}) => { borderColor = BorderColor.transparent,
const t = useI18nContext(); ...props
},
return ( ref,
<AvatarBase ) => {
size={size} const t = useI18nContext();
display={DISPLAY.FLEX} return (
alignItems={AlignItems.center} <AvatarBase
justifyContent={JustifyContent.center} ref={ref}
className={classnames('mm-avatar-favicon', className)} size={size}
{...{ borderColor, ...props }} display={DISPLAY.FLEX}
> alignItems={AlignItems.center}
{src ? ( justifyContent={JustifyContent.center}
<img className={classnames('mm-avatar-favicon', className)}
className="mm-avatar-favicon__image" {...{ borderColor, ...props }}
src={src} >
alt={t('logo', [name])} {src ? (
/> <img
) : ( className="mm-avatar-favicon__image"
<Icon src={src}
name={IconName.Global} alt={t('logo', [name])}
color={IconColor.iconDefault} />
size={size} ) : (
{...fallbackIconProps} <Icon
/> name={IconName.Global}
)} color={IconColor.iconDefault}
</AvatarBase> size={size}
); {...fallbackIconProps}
}; />
)}
</AvatarBase>
);
},
);
AvatarFavicon.propTypes = { AvatarFavicon.propTypes = {
/** /**
@ -87,3 +92,5 @@ AvatarFavicon.propTypes = {
*/ */
...Box.propTypes, ...Box.propTypes,
}; };
AvatarFavicon.displayName = 'AvatarFavicon';

View File

@ -105,4 +105,10 @@ describe('AvatarFavicon', () => {
); );
expect(getByTestId('classname')).toHaveClass('mm-avatar-favicon--test'); expect(getByTestId('classname')).toHaveClass('mm-avatar-favicon--test');
}); });
it('should forward a ref to the root html element', () => {
const ref = React.createRef();
render(<AvatarFavicon name="test" ref={ref} />);
expect(ref.current).not.toBeNull();
expect(ref.current.nodeName).toBe('DIV');
});
}); });

View File

@ -19,33 +19,39 @@ import { AvatarBase } from '../avatar-base';
import { AVATAR_ICON_SIZES } from './avatar-icon.constants'; import { AVATAR_ICON_SIZES } from './avatar-icon.constants';
export const AvatarIcon = ({ export const AvatarIcon = React.forwardRef(
size = Size.MD, (
color = TextColor.primaryDefault, {
backgroundColor = BackgroundColor.primaryMuted, size = Size.MD,
className, color = TextColor.primaryDefault,
iconProps, backgroundColor = BackgroundColor.primaryMuted,
iconName, className,
...props iconProps,
}) => ( iconName,
<AvatarBase ...props
size={size} },
display={DISPLAY.FLEX} ref,
alignItems={AlignItems.center} ) => (
justifyContent={JustifyContent.center} <AvatarBase
color={color} ref={ref}
backgroundColor={backgroundColor}
borderColor={BorderColor.transparent}
className={classnames('mm-avatar-icon', className)}
{...props}
>
<Icon
color={IconColor.inherit}
name={iconName}
size={size} size={size}
{...iconProps} display={DISPLAY.FLEX}
/> alignItems={AlignItems.center}
</AvatarBase> justifyContent={JustifyContent.center}
color={color}
backgroundColor={backgroundColor}
borderColor={BorderColor.transparent}
className={classnames('mm-avatar-icon', className)}
{...props}
>
<Icon
color={IconColor.inherit}
name={iconName}
size={size}
{...iconProps}
/>
</AvatarBase>
),
); );
AvatarIcon.propTypes = { AvatarIcon.propTypes = {
@ -87,3 +93,5 @@ AvatarIcon.propTypes = {
*/ */
...Box.propTypes, ...Box.propTypes,
}; };
AvatarIcon.displayName = 'AvatarIcon';

View File

@ -105,4 +105,10 @@ describe('AvatarIcon', () => {
'box--background-color-success-muted', 'box--background-color-success-muted',
); );
}); });
it('should forward a ref to the root html element', () => {
const ref = React.createRef();
render(<AvatarIcon iconName={IconName.SwapHorizontal} ref={ref} />);
expect(ref.current).not.toBeNull();
expect(ref.current.nodeName).toBe('DIV');
});
}); });

View File

@ -123,4 +123,10 @@ describe('AvatarNetwork', () => {
`box--border-color-${BorderColor.errorDefault}`, `box--border-color-${BorderColor.errorDefault}`,
); );
}); });
it('should forward a ref to the root html element', () => {
const ref = React.createRef();
render(<AvatarNetwork ref={ref} />);
expect(ref.current).not.toBeNull();
expect(ref.current.nodeName).toBe('DIV');
});
}); });

View File

@ -14,70 +14,76 @@ import {
} from '../../../helpers/constants/design-system'; } from '../../../helpers/constants/design-system';
import { AVATAR_TOKEN_SIZES } from './avatar-token.constants'; import { AVATAR_TOKEN_SIZES } from './avatar-token.constants';
export const AvatarToken = ({ export const AvatarToken = React.forwardRef(
size = Size.MD, (
name, {
src, size = Size.MD,
showHalo, name,
color = TextColor.textDefault, src,
backgroundColor = BackgroundColor.backgroundAlternative, showHalo,
borderColor = BorderColor.transparent, color = TextColor.textDefault,
className, backgroundColor = BackgroundColor.backgroundAlternative,
...props borderColor = BorderColor.transparent,
}) => { className,
const [showFallback, setShowFallback] = useState(false); ...props
},
ref,
) => {
const [showFallback, setShowFallback] = useState(false);
useEffect(() => { useEffect(() => {
setShowFallback(!src); setShowFallback(!src);
}, [src]); }, [src]);
const handleOnError = () => { const handleOnError = () => {
setShowFallback(true); setShowFallback(true);
}; };
const fallbackString = name && name[0] ? name[0] : '?'; const fallbackString = name && name[0] ? name[0] : '?';
return ( return (
<AvatarBase <AvatarBase
size={size} ref={ref}
display={DISPLAY.FLEX} size={size}
alignItems={AlignItems.center} display={DISPLAY.FLEX}
justifyContent={JustifyContent.center} alignItems={AlignItems.center}
className={classnames( justifyContent={JustifyContent.center}
'mm-avatar-token', className={classnames(
showHalo && 'mm-avatar-token--with-halo', 'mm-avatar-token',
className, showHalo && 'mm-avatar-token--with-halo',
)} className,
{...{ backgroundColor, borderColor, color, ...props }} )}
> {...{ backgroundColor, borderColor, color, ...props }}
{showFallback ? ( >
fallbackString {showFallback ? (
) : ( fallbackString
<> ) : (
{showHalo && ( <>
{showHalo && (
<img
src={src}
className={
showHalo ? 'mm-avatar-token__token-image--blurred' : ''
}
aria-hidden="true"
/>
)}
<img <img
src={src}
className={ className={
showHalo ? 'mm-avatar-token__token-image--blurred' : '' showHalo
? 'mm-avatar-token__token-image--size-reduced'
: 'mm-avatar-token__token-image'
} }
aria-hidden="true" onError={handleOnError}
src={src}
alt={`${name} logo` || 'token logo'}
/> />
)} </>
<img )}
className={ </AvatarBase>
showHalo );
? 'mm-avatar-token__token-image--size-reduced' },
: 'mm-avatar-token__token-image' );
}
onError={handleOnError}
src={src}
alt={`${name} logo` || 'token logo'}
/>
</>
)}
</AvatarBase>
);
};
AvatarToken.propTypes = { AvatarToken.propTypes = {
/** /**
@ -123,3 +129,5 @@ AvatarToken.propTypes = {
*/ */
...Box.propTypes, ...Box.propTypes,
}; };
AvatarToken.displayName = 'AvatarToken';

View File

@ -121,4 +121,10 @@ describe('AvatarToken', () => {
`box--border-color-${BorderColor.errorDefault}`, `box--border-color-${BorderColor.errorDefault}`,
); );
}); });
it('should forward a ref to the root html element', () => {
const ref = React.createRef();
render(<AvatarToken ref={ref} />);
expect(ref.current).not.toBeNull();
expect(ref.current.nodeName).toBe('DIV');
});
}); });