Added AvatarBadge component (#15676)
* avatar badge component added * resolved conflicts * added badge prop * updated avatar badge children/badge props * updated badge token size to be 16px * added AvatarBadge Test component * added avatar badge test * updated avatarBadge props * added Readme and test files to AvatarWithBadge Component * resolved conflicts * removed unused change * updated badge and badge props * updated avatar badge stories * updated constants for avatar badge * updated avatar badge test * replaced avatar-badge with avatar-with-badge * updated avatar badge tests * updated test for badgePropsfeature/default_network_editable
parent
6781171d06
commit
0fe3633e4d
@ -0,0 +1,37 @@ |
|||||||
|
import { Story, Canvas, ArgsTable } from '@storybook/addon-docs'; |
||||||
|
|
||||||
|
import { AvatarWithBadge } from './avatar-with-badge'; |
||||||
|
|
||||||
|
# AvatarWithBadge |
||||||
|
|
||||||
|
The `AvatarWithBadge` is a wrapper component that adds badge display options to avatars. |
||||||
|
|
||||||
|
<Canvas> |
||||||
|
<Story id="ui-components-component-library-avatar-with-badge-avatar-with-badge-stories-js--default-story" /> |
||||||
|
</Canvas> |
||||||
|
|
||||||
|
## Props |
||||||
|
|
||||||
|
The `AvatarWithBadge` accepts all props below |
||||||
|
|
||||||
|
<ArgsTable of={AvatarWithBadge} /> |
||||||
|
|
||||||
|
### Badge Position |
||||||
|
|
||||||
|
Use the `badgePosition` prop to set the position of the badge, it can have two values `Top` and `Bottom` |
||||||
|
|
||||||
|
<Canvas> |
||||||
|
<Story id="ui-components-component-library-avatar-with-badge-avatar-with-badge-stories-js--badge-positions" /> |
||||||
|
</Canvas> |
||||||
|
|
||||||
|
### Badge |
||||||
|
|
||||||
|
Used to define the badge component to be rendered inside the `AvatarWithBadge` |
||||||
|
|
||||||
|
### Badge Props |
||||||
|
|
||||||
|
The required props to be passed to the badge. |
||||||
|
|
||||||
|
### Children |
||||||
|
|
||||||
|
The children to be rendered inside the AvatarWithBadge. Generally used with the `AvatarAccount` |
@ -0,0 +1,4 @@ |
|||||||
|
export const BADGE_POSITIONS = { |
||||||
|
TOP: 'top', |
||||||
|
BOTTOM: 'bottom', |
||||||
|
}; |
@ -0,0 +1,56 @@ |
|||||||
|
import React from 'react'; |
||||||
|
import classnames from 'classnames'; |
||||||
|
import PropTypes from 'prop-types'; |
||||||
|
import Box from '../../ui/box/box'; |
||||||
|
import { BADGE_POSITIONS } from './avatar-with-badge.constants'; |
||||||
|
|
||||||
|
export const AvatarWithBadge = ({ |
||||||
|
children, |
||||||
|
badgePosition, |
||||||
|
className, |
||||||
|
badge, |
||||||
|
badgeWrapperProps, |
||||||
|
...props |
||||||
|
}) => { |
||||||
|
return ( |
||||||
|
<Box className={classnames('avatar-with-badge', className)} {...props}> |
||||||
|
{/* Generally the AvatarAccount */} |
||||||
|
{children} |
||||||
|
<Box |
||||||
|
className={ |
||||||
|
badgePosition === 'top' |
||||||
|
? 'avatar-with-badge__badge-wrapper--position-top' |
||||||
|
: 'avatar-with-badge__badge-wrapper--position-bottom' |
||||||
|
} |
||||||
|
{...badgeWrapperProps} |
||||||
|
> |
||||||
|
{/* Generally the AvatarNetwork at SIZES.XS */} |
||||||
|
{badge} |
||||||
|
</Box> |
||||||
|
</Box> |
||||||
|
); |
||||||
|
}; |
||||||
|
|
||||||
|
AvatarWithBadge.propTypes = { |
||||||
|
/** |
||||||
|
* The position of the Badge |
||||||
|
* Possible values could be 'top', 'bottom', |
||||||
|
*/ |
||||||
|
badgePosition: PropTypes.oneOf(Object.values(BADGE_POSITIONS)), |
||||||
|
/** |
||||||
|
* The Badge Wrapper props of the component. All Box props can be used |
||||||
|
*/ |
||||||
|
badgeWrapperProps: PropTypes.shape(Box.PropTypes), |
||||||
|
/** |
||||||
|
* The children to be rendered inside the AvatarWithBadge |
||||||
|
*/ |
||||||
|
children: PropTypes.node, |
||||||
|
/** |
||||||
|
* The badge to be rendered inside the AvatarWithBadge |
||||||
|
*/ |
||||||
|
badge: PropTypes.object, |
||||||
|
/** |
||||||
|
* Add custom css class |
||||||
|
*/ |
||||||
|
className: PropTypes.string, |
||||||
|
}; |
@ -0,0 +1,16 @@ |
|||||||
|
.avatar-with-badge { |
||||||
|
position: relative; |
||||||
|
width: fit-content; |
||||||
|
|
||||||
|
&__badge-wrapper--position-top { |
||||||
|
position: absolute; |
||||||
|
top: -4px; |
||||||
|
right: -4px; |
||||||
|
} |
||||||
|
|
||||||
|
&__badge-wrapper--position-bottom { |
||||||
|
position: absolute; |
||||||
|
bottom: -4px; |
||||||
|
right: -4px; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,91 @@ |
|||||||
|
import React from 'react'; |
||||||
|
import { AvatarAccount } from '../avatar-account'; |
||||||
|
import { TYPES } from '../avatar-account/avatar-account.constants'; |
||||||
|
import { AvatarNetwork } from '../avatar-network'; |
||||||
|
import Box from '../../ui/box/box'; |
||||||
|
import { |
||||||
|
ALIGN_ITEMS, |
||||||
|
DISPLAY, |
||||||
|
SIZES, |
||||||
|
} from '../../../helpers/constants/design-system'; |
||||||
|
import { BADGE_POSITIONS } from './avatar-with-badge.constants'; |
||||||
|
import README from './README.mdx'; |
||||||
|
import { AvatarWithBadge } from './avatar-with-badge'; |
||||||
|
|
||||||
|
export default { |
||||||
|
title: 'Components/ComponentLibrary/AvatarWithBadge', |
||||||
|
id: __filename, |
||||||
|
component: AvatarWithBadge, |
||||||
|
parameters: { |
||||||
|
docs: { |
||||||
|
page: README, |
||||||
|
}, |
||||||
|
}, |
||||||
|
argTypes: { |
||||||
|
badgePosition: { |
||||||
|
options: Object.values(BADGE_POSITIONS), |
||||||
|
control: 'select', |
||||||
|
}, |
||||||
|
}, |
||||||
|
args: { |
||||||
|
badgePosition: BADGE_POSITIONS.top, |
||||||
|
}, |
||||||
|
}; |
||||||
|
|
||||||
|
export const DefaultStory = (args) => ( |
||||||
|
<AvatarWithBadge |
||||||
|
badge={ |
||||||
|
<AvatarNetwork |
||||||
|
size={SIZES.XS} |
||||||
|
networkName="Arbitrum One" |
||||||
|
networkImageUrl="./images/arbitrum.svg" |
||||||
|
/> |
||||||
|
} |
||||||
|
{...args} |
||||||
|
> |
||||||
|
<AvatarAccount |
||||||
|
address="0x5CfE73b6021E818B776b421B1c4Db2474086a7e1" |
||||||
|
size={SIZES.MD} |
||||||
|
type={TYPES.JAZZICON} |
||||||
|
/> |
||||||
|
</AvatarWithBadge> |
||||||
|
); |
||||||
|
DefaultStory.storyName = 'Default'; |
||||||
|
|
||||||
|
export const BadgePosition = () => ( |
||||||
|
<Box display={DISPLAY.FLEX} alignItems={ALIGN_ITEMS.BASELINE} gap={1}> |
||||||
|
<AvatarWithBadge |
||||||
|
badgePosition={BADGE_POSITIONS.BOTTOM} |
||||||
|
badge={ |
||||||
|
<AvatarNetwork |
||||||
|
size={SIZES.XS} |
||||||
|
networkName="Arbitrum One" |
||||||
|
networkImageUrl="./images/arbitrum.svg" |
||||||
|
/> |
||||||
|
} |
||||||
|
> |
||||||
|
<AvatarAccount |
||||||
|
address="0x5CfE73b6021E818B776b421B1c4Db2474086a7e1" |
||||||
|
size={SIZES.MD} |
||||||
|
type={TYPES.JAZZICON} |
||||||
|
/> |
||||||
|
</AvatarWithBadge> |
||||||
|
|
||||||
|
<AvatarWithBadge |
||||||
|
badgePosition={BADGE_POSITIONS.TOP} |
||||||
|
badge={ |
||||||
|
<AvatarNetwork |
||||||
|
size={SIZES.XS} |
||||||
|
networkName="Arbitrum One" |
||||||
|
networkImageUrl="./images/arbitrum.svg" |
||||||
|
/> |
||||||
|
} |
||||||
|
> |
||||||
|
<AvatarAccount |
||||||
|
address="0x5CfE73b6021E818B776b421B1c4Db2474086a7e1" |
||||||
|
size={SIZES.MD} |
||||||
|
type={TYPES.JAZZICON} |
||||||
|
/> |
||||||
|
</AvatarWithBadge> |
||||||
|
</Box> |
||||||
|
); |
@ -0,0 +1,90 @@ |
|||||||
|
/* eslint-disable jest/require-top-level-describe */ |
||||||
|
import { render } from '@testing-library/react'; |
||||||
|
import React from 'react'; |
||||||
|
import { AvatarNetwork } from '../avatar-network/avatar-network'; |
||||||
|
import { COLORS } from '../../../helpers/constants/design-system'; |
||||||
|
import { AvatarWithBadge } from './avatar-with-badge'; |
||||||
|
import { BADGE_POSITIONS } from './avatar-with-badge.constants'; |
||||||
|
|
||||||
|
describe('AvatarWithBadge', () => { |
||||||
|
it('should render correctly', () => { |
||||||
|
const { getByTestId } = render( |
||||||
|
<AvatarWithBadge |
||||||
|
badgePosition={BADGE_POSITIONS.BOTTOM} |
||||||
|
data-testid="avatar-with-badge" |
||||||
|
badge={ |
||||||
|
<AvatarNetwork |
||||||
|
networkName="Arbitrum One" |
||||||
|
networkImageUrl="./images/arbitrum.svg" |
||||||
|
data-testid="badge" |
||||||
|
/> |
||||||
|
} |
||||||
|
/>, |
||||||
|
); |
||||||
|
expect(getByTestId('avatar-with-badge')).toBeDefined(); |
||||||
|
expect(getByTestId('badge')).toBeDefined(); |
||||||
|
}); |
||||||
|
|
||||||
|
it('should render badge network with bottom right position correctly', () => { |
||||||
|
const { container } = render( |
||||||
|
<AvatarWithBadge |
||||||
|
data-testid="avatar-with-badge" |
||||||
|
badgePosition={BADGE_POSITIONS.BOTTOM} |
||||||
|
badge={ |
||||||
|
<AvatarNetwork |
||||||
|
networkName="Arbitrum One" |
||||||
|
networkImageUrl="./images/arbitrum.svg" |
||||||
|
data-testid="badge" |
||||||
|
/> |
||||||
|
} |
||||||
|
/>, |
||||||
|
); |
||||||
|
|
||||||
|
expect( |
||||||
|
container.getElementsByClassName( |
||||||
|
'avatar-with-badge__badge-wrapper--position-bottom', |
||||||
|
), |
||||||
|
).toHaveLength(1); |
||||||
|
}); |
||||||
|
|
||||||
|
it('should render badge network with top right position correctly', () => { |
||||||
|
const { container } = render( |
||||||
|
<AvatarWithBadge |
||||||
|
data-testid="avatar-with-badge" |
||||||
|
badgePosition={BADGE_POSITIONS.TOP} |
||||||
|
badge={ |
||||||
|
<AvatarNetwork |
||||||
|
networkName="Arbitrum One" |
||||||
|
networkImageUrl="./images/arbitrum.svg" |
||||||
|
data-testid="badge" |
||||||
|
/> |
||||||
|
} |
||||||
|
/>, |
||||||
|
); |
||||||
|
|
||||||
|
expect( |
||||||
|
container.getElementsByClassName( |
||||||
|
'avatar-with-badge__badge-wrapper--position-top', |
||||||
|
), |
||||||
|
).toHaveLength(1); |
||||||
|
}); |
||||||
|
it('should render badge network with badgeWrapperProps', () => { |
||||||
|
const container = ( |
||||||
|
<AvatarWithBadge |
||||||
|
data-testid="avatar-with-badge" |
||||||
|
badgePosition={BADGE_POSITIONS.TOP} |
||||||
|
badgeWrapperProps={{ borderColor: COLORS.ERROR_DEFAULT }} |
||||||
|
badge={ |
||||||
|
<AvatarNetwork |
||||||
|
networkName="Arbitrum One" |
||||||
|
networkImageUrl="./images/arbitrum.svg" |
||||||
|
data-testid="badge" |
||||||
|
/> |
||||||
|
} |
||||||
|
/> |
||||||
|
); |
||||||
|
expect(container.props.badgeWrapperProps.borderColor).toStrictEqual( |
||||||
|
'error-default', |
||||||
|
); |
||||||
|
}); |
||||||
|
}); |
@ -0,0 +1 @@ |
|||||||
|
export { AvatarWithBadge } from './avatar-with-badge'; |
Loading…
Reference in new issue