1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-11-22 18:00:18 +01:00

Migrates avatar base to TypeScript (#18494)

* Converted file extension from .js to .tsx

* Updated README docs to match the enums. Resolved type errors

* Updated AvatarBaseSizes enum values to string literals

* Added TEXT_TRANSFORM.UPPERCASE as default value of textTransform in base file

* lint fix

* Solved liniting errors in avatar-base

* Made enum more consistent, added desc for AvatarBaseProps

* Updated snapshots of AvatarBase and exported AvatarBaseProps in index.ts

* Made textTransform property accept right values in avatar-base.tsx

* Adding temporary changed extensions

* Reverted files back to tsx and resolved conflicts

* Solved linting errors

* AvatarBaseProps now extends TextProps

* Changing extension to resolve conflict

* Reverted extensions back to tsx after resolving conflicts

* Added forwardRef in AvatarBase

* Updated import name of AvatarBaseSize in README.mdx. Removed empty children attribute from AvatarBase storybook file

---------

Co-authored-by: legobeat <109787230+legobeat@users.noreply.github.com>
Co-authored-by: Brad Decker <bhdecker84@gmail.com>
This commit is contained in:
Suryansh Anand 2023-05-04 06:00:07 +05:30 committed by GitHub
parent 924df55e89
commit c92d7380df
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 152 additions and 149 deletions

View File

@ -39,13 +39,13 @@ The text styles of the `AvatarBase` is based on the `size` prop. To override thi
</Canvas> </Canvas>
```jsx ```jsx
import { AVATAR_BASE_SIZES } from '../ui/component-library/avatar-base'; import { AvatarBaseSize } from '../ui/component-library/avatar-base/avatar-base.types';
import { AvatarBase } from '../../component-library'; import { AvatarBase } from '../../component-library/avatar-base';
<AvatarBase size={AVATAR_BASE_SIZES.XS} /> <AvatarBase size={AvatarBaseSize.XS} />
<AvatarBase size={AVATAR_BASE_SIZES.SM} /> <AvatarBase size={AvatarBaseSize.SM} />
<AvatarBase size={AVATAR_BASE_SIZES.MD} /> <AvatarBase size={AvatarBaseSize.MD} />
<AvatarBase size={AVATAR_BASE_SIZES.LG} /> <AvatarBase size={AvatarBaseSize.LG} />
<AvatarBase size={AVATAR_BASE_SIZES.XL} /> <AvatarBase size={AvatarBaseSize.XL} />
``` ```
### Children ### Children

View File

@ -1,9 +0,0 @@
import { Size } from '../../../helpers/constants/design-system';
export const AVATAR_BASE_SIZES = {
XS: Size.XS,
SM: Size.SM,
MD: Size.MD,
LG: Size.LG,
XL: Size.XL,
};

View File

@ -1,106 +0,0 @@
import React from 'react';
import PropTypes from 'prop-types';
import classnames from 'classnames';
import {
BackgroundColor,
BorderColor,
TextColor,
IconColor,
DISPLAY,
JustifyContent,
AlignItems,
BorderRadius,
TextVariant,
TEXT_TRANSFORM,
} from '../../../helpers/constants/design-system';
import { Text } from '../text';
import { AVATAR_BASE_SIZES } from './avatar-base.constants';
export const AvatarBase = React.forwardRef(
(
{
size = AVATAR_BASE_SIZES.MD,
children,
backgroundColor = BackgroundColor.backgroundAlternative,
borderColor = BorderColor.borderDefault,
color = TextColor.textDefault,
className,
...props
},
ref,
) => {
let fallbackTextVariant;
if (size === AVATAR_BASE_SIZES.LG || size === AVATAR_BASE_SIZES.XL) {
fallbackTextVariant = TextVariant.bodyLgMedium;
} else if (size === AVATAR_BASE_SIZES.SM || size === AVATAR_BASE_SIZES.MD) {
fallbackTextVariant = TextVariant.bodySm;
} else {
fallbackTextVariant = TextVariant.bodyXs;
}
return (
<Text
className={classnames(
'mm-avatar-base',
`mm-avatar-base--size-${size}`,
className,
)}
ref={ref}
as="div"
display={DISPLAY.FLEX}
justifyContent={JustifyContent.center}
alignItems={AlignItems.center}
borderRadius={BorderRadius.full}
variant={fallbackTextVariant}
textTransform={TEXT_TRANSFORM.UPPERCASE}
{...{ backgroundColor, borderColor, color, ...props }}
>
{children}
</Text>
);
},
);
AvatarBase.propTypes = {
/**
* The size of the AvatarBase.
* Possible values could be 'AVATAR_BASE_SIZES.XS'(16px), 'AVATAR_BASE_SIZES.SM'(24px), 'AVATAR_BASE_SIZES.MD'(32px), 'AVATAR_BASE_SIZES.LG'(40px), 'AVATAR_BASE_SIZES.XL'(48px)
* Defaults to AVATAR_BASE_SIZES.MD
*/
size: PropTypes.oneOf(Object.values(AVATAR_BASE_SIZES)),
/**
* The children to be rendered inside the AvatarBase
*/
children: PropTypes.node,
/**
* The background color of the AvatarBase
* Defaults to Color.backgroundAlternative
*/
backgroundColor: PropTypes.oneOf(Object.values(BackgroundColor)),
/**
* The background color of the AvatarBase
* Defaults to Color.borderDefault
*/
borderColor: PropTypes.oneOf(Object.values(BorderColor)),
/**
* The color of the text inside the AvatarBase
* Defaults to TextColor.textDefault
*/
color: PropTypes.oneOf([
...Object.values(TextColor),
...Object.values(IconColor),
]),
/**
* Additional classNames to be added to the AvatarToken
*/
className: PropTypes.string,
/**
* AvatarBase also accepts all Text props including variant and all Box props
*/
...Text.propTypes,
};
AvatarBase.displayName = 'AvatarBase';

View File

@ -1,3 +1,4 @@
import { ComponentMeta } from '@storybook/react';
import React from 'react'; import React from 'react';
import { import {
AlignItems, AlignItems,
@ -5,7 +6,7 @@ import {
TextColor, TextColor,
BackgroundColor, BackgroundColor,
BorderColor, BorderColor,
Color, IconColor,
} from '../../../helpers/constants/design-system'; } from '../../../helpers/constants/design-system';
import Box from '../../ui/box/box'; import Box from '../../ui/box/box';
@ -13,7 +14,7 @@ import Box from '../../ui/box/box';
import { Icon, IconName } from '..'; import { Icon, IconName } from '..';
import README from './README.mdx'; import README from './README.mdx';
import { AvatarBase } from './avatar-base'; import { AvatarBase } from './avatar-base';
import { AVATAR_BASE_SIZES } from './avatar-base.constants'; import { AvatarBaseProps, AvatarBaseSize } from './avatar-base.types';
const marginSizeKnobOptions = [ const marginSizeKnobOptions = [
0, 0,
@ -44,7 +45,7 @@ export default {
argTypes: { argTypes: {
size: { size: {
control: 'select', control: 'select',
options: Object.values(AVATAR_BASE_SIZES), options: Object.values(AvatarBaseSize),
}, },
color: { color: {
options: Object.values(TextColor), options: Object.values(TextColor),
@ -85,29 +86,29 @@ export default {
}, },
}, },
args: { args: {
size: AVATAR_BASE_SIZES.MD, size: AvatarBaseSize.Md,
color: TextColor.textDefault, color: TextColor.textDefault,
backgroundColor: BackgroundColor.backgroundAlternative, backgroundColor: BackgroundColor.backgroundAlternative,
borderColor: BorderColor.borderDefault, borderColor: BorderColor.borderDefault,
children: 'B', children: 'B',
}, },
}; } as ComponentMeta<typeof AvatarBase>;
export const DefaultStory = (args) => <AvatarBase {...args} />; export const DefaultStory = (args: AvatarBaseProps) => <AvatarBase {...args} />;
DefaultStory.storyName = 'Default'; DefaultStory.storyName = 'Default';
export const Size = (args) => ( export const Size = (args: AvatarBaseProps) => (
<Box display={DISPLAY.FLEX} alignItems={AlignItems.baseline} gap={1}> <Box display={DISPLAY.FLEX} alignItems={AlignItems.baseline} gap={1}>
<AvatarBase {...args} size={AVATAR_BASE_SIZES.XS} /> <AvatarBase {...args} size={AvatarBaseSize.Xs} />
<AvatarBase {...args} size={AVATAR_BASE_SIZES.SM} /> <AvatarBase {...args} size={AvatarBaseSize.Sm} />
<AvatarBase {...args} size={AVATAR_BASE_SIZES.MD} /> <AvatarBase {...args} size={AvatarBaseSize.Md} />
<AvatarBase {...args} size={AVATAR_BASE_SIZES.LG} /> <AvatarBase {...args} size={AvatarBaseSize.Lg} />
<AvatarBase {...args} size={AVATAR_BASE_SIZES.XL} /> <AvatarBase {...args} size={AvatarBaseSize.Xl} />
</Box> </Box>
); );
export const Children = (args) => ( export const Children = (args: AvatarBaseProps) => (
<Box display={DISPLAY.FLEX} gap={1}> <Box display={DISPLAY.FLEX} gap={1}>
<AvatarBase {...args}> <AvatarBase {...args}>
<img src="./images/eth_logo.png" /> <img src="./images/eth_logo.png" />
@ -124,12 +125,12 @@ export const Children = (args) => (
backgroundColor={BackgroundColor.infoMuted} backgroundColor={BackgroundColor.infoMuted}
borderColor={BorderColor.infoMuted} borderColor={BorderColor.infoMuted}
> >
<Icon name={IconName.User} color={Color.infoDefault} /> <Icon name={IconName.User} color={IconColor.infoDefault} />
</AvatarBase> </AvatarBase>
</Box> </Box>
); );
export const ColorBackgroundColorAndBorderColor = (args) => ( export const ColorBackgroundColorAndBorderColor = (args: AvatarBaseProps) => (
<Box display={DISPLAY.FLEX} gap={1}> <Box display={DISPLAY.FLEX} gap={1}>
<AvatarBase {...args}>B</AvatarBase> <AvatarBase {...args}>B</AvatarBase>
<AvatarBase <AvatarBase

View File

@ -2,9 +2,15 @@
import { render, screen } from '@testing-library/react'; import { render, screen } from '@testing-library/react';
import React from 'react'; import React from 'react';
import { Color, TextColor } from '../../../helpers/constants/design-system'; import {
BackgroundColor,
BorderColor,
Color,
TextColor,
} from '../../../helpers/constants/design-system';
import { AvatarBase } from './avatar-base'; import { AvatarBase } from './avatar-base';
import { AvatarBaseSize } from './avatar-base.types';
describe('AvatarBase', () => { describe('AvatarBase', () => {
it('should render correctly', () => { it('should render correctly', () => {
@ -17,11 +23,11 @@ describe('AvatarBase', () => {
it('should render with different size classes', () => { it('should render with different size classes', () => {
const { getByTestId } = render( const { getByTestId } = render(
<> <>
<AvatarBase size="xs" data-testid="avatar-base-xs" /> <AvatarBase size={AvatarBaseSize.Xs} data-testid="avatar-base-xs" />
<AvatarBase size="sm" data-testid="avatar-base-sm" /> <AvatarBase size={AvatarBaseSize.Sm} data-testid="avatar-base-sm" />
<AvatarBase size="md" data-testid="avatar-base-md" /> <AvatarBase size={AvatarBaseSize.Md} data-testid="avatar-base-md" />
<AvatarBase size="lg" data-testid="avatar-base-lg" /> <AvatarBase size={AvatarBaseSize.Lg} data-testid="avatar-base-lg" />
<AvatarBase size="xl" data-testid="avatar-base-xl" /> <AvatarBase size={AvatarBaseSize.Xl} data-testid="avatar-base-xl" />
</>, </>,
); );
expect(getByTestId('avatar-base-xs')).toHaveClass( expect(getByTestId('avatar-base-xs')).toHaveClass(
@ -84,11 +90,11 @@ describe('AvatarBase', () => {
const { getByTestId } = render( const { getByTestId } = render(
<> <>
<AvatarBase <AvatarBase
backgroundColor={TextColor.successDefault} backgroundColor={BackgroundColor.successDefault}
data-testid={Color.successDefault} data-testid={Color.successDefault}
/> />
<AvatarBase <AvatarBase
backgroundColor={TextColor.errorDefault} backgroundColor={BackgroundColor.errorDefault}
data-testid={Color.errorDefault} data-testid={Color.errorDefault}
/> />
</>, </>,
@ -105,11 +111,11 @@ describe('AvatarBase', () => {
const { getByTestId } = render( const { getByTestId } = render(
<> <>
<AvatarBase <AvatarBase
borderColor={Color.successDefault} borderColor={BorderColor.successDefault}
data-testid={Color.successDefault} data-testid={Color.successDefault}
/> />
<AvatarBase <AvatarBase
borderColor={Color.errorDefault} borderColor={BorderColor.errorDefault}
data-testid={Color.errorDefault} data-testid={Color.errorDefault}
/> />
</>, </>,

View File

@ -0,0 +1,63 @@
import React, { forwardRef, Ref } from 'react';
import classnames from 'classnames';
import {
BackgroundColor,
BorderColor,
TextColor,
DISPLAY,
JustifyContent,
AlignItems,
BorderRadius,
TextVariant,
TextTransform,
} from '../../../helpers/constants/design-system';
import { Text, ValidTag } from '../text';
import { AvatarBaseProps, AvatarBaseSize } from './avatar-base.types';
export const AvatarBase = forwardRef(
(
{
size = AvatarBaseSize.Md,
children,
backgroundColor = BackgroundColor.backgroundAlternative,
borderColor = BorderColor.borderDefault,
color = TextColor.textDefault,
className = '',
...props
}: AvatarBaseProps,
ref: Ref<HTMLElement>,
) => {
let fallbackTextVariant;
if (size === AvatarBaseSize.Lg || size === AvatarBaseSize.Xl) {
fallbackTextVariant = TextVariant.bodyLgMedium;
} else if (size === AvatarBaseSize.Sm || size === AvatarBaseSize.Md) {
fallbackTextVariant = TextVariant.bodySm;
} else {
fallbackTextVariant = TextVariant.bodyXs;
}
return (
<Text
className={classnames(
'mm-avatar-base',
`mm-avatar-base--size-${size}`,
className,
)}
ref={ref}
as={ValidTag.Div}
display={DISPLAY.FLEX}
justifyContent={JustifyContent.center}
alignItems={AlignItems.center}
borderRadius={BorderRadius.full}
variant={fallbackTextVariant}
textTransform={TextTransform.Uppercase}
{...{ backgroundColor, borderColor, color, ...props }}
>
{children}
</Text>
);
},
);

View File

@ -0,0 +1,47 @@
import {
BackgroundColor,
BorderColor,
TextColor,
} from '../../../helpers/constants/design-system';
import { TextProps } from '../text';
export enum AvatarBaseSize {
Xs = 'xs',
Sm = 'sm',
Md = 'md',
Lg = 'lg',
Xl = 'xl',
}
export interface AvatarBaseProps extends TextProps {
/**
* The size of the AvatarBase.
* Possible values could be 'AvatarBaseSize.Xs'(16px), 'AvatarBaseSize.Sm'(24px),
* 'AvatarBaseSize.Md'(32px), 'AvatarBaseSize.Lg'(40px), 'AvatarBaseSize.Xl'(48px)
* Defaults to AvatarBaseSize.Md
*/
size?: AvatarBaseSize;
/**
* The children to be rendered inside the AvatarBase
*/
children: React.ReactNode;
/**
* The background color of the AvatarBase
* Defaults to Color.backgroundAlternative
*/
backgroundColor?: BackgroundColor;
/**
* The background color of the AvatarBase
* Defaults to Color.borderDefault
*/
borderColor?: BorderColor;
/**
* The color of the text inside the AvatarBase
* Defaults to TextColor.textDefault
*/
color?: TextColor;
/**
* Additional classNames to be added to the AvatarBase
*/
className?: string;
}

View File

@ -1,2 +0,0 @@
export { AvatarBase } from './avatar-base';
export { AVATAR_BASE_SIZES } from './avatar-base.constants';

View File

@ -0,0 +1,3 @@
export { AvatarBase } from './avatar-base';
export { AvatarBaseSize } from './avatar-base.types';
export type { AvatarBaseProps } from './avatar-base.types';