-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #8 from internxt/feat/avatar-component
[PB-3005]: feat/avatar component
- Loading branch information
Showing
12 changed files
with
877 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
import DefaultAvatar from './components/DefaultAvatar'; | ||
import PictureAvatar from './components/PictureAvatar'; | ||
|
||
type SIZE_KEYS = 'xxs' | 'xs' | 'sm' | 'base' | 'lg' | 'xl'; | ||
|
||
const SIZES: Record<SIZE_KEYS, number> = { | ||
xxs: 28, | ||
xs: 36, | ||
sm: 40, | ||
base: 48, | ||
lg: 80, | ||
xl: 128, | ||
}; | ||
|
||
/** | ||
* Renders an avatar component which can be either a picture or a default avatar with initials. | ||
* | ||
* @param {Object} props - The properties for the Avatar component. | ||
* @param {string} props.fullName - The full name of the user, used to generate initials if no image is provided. | ||
* @param {number} [props.diameter=80] - The diameter of the avatar in pixels. Ignored if `size` is provided. | ||
* @param {SIZE_KEYS} [props.size] - Predefined size for the avatar. If provided, overrides the `diameter`. | ||
* The associated value in `SIZES` will be used as the diameter. Possible values are: | ||
* - `'xxs'`: 28px | ||
* - `'xs'`: 36px | ||
* - `'sm'`: 40px | ||
* - `'base'`: 48px | ||
* - `'lg'`: 80px | ||
* - `'xl'`: 128px | ||
* @param {string|null} [props.src] - The URL of the image to display as the avatar. If not provided, initials are shown | ||
* @param {string} [props.className=''] - Additional CSS classes to apply to the avatar component. | ||
* @param {Object} [props.style={}] - Additional inline styles to apply to the avatar component. | ||
* @returns {JSX.Element} The rendered avatar component. | ||
*/ | ||
export const Avatar = ({ | ||
src, | ||
diameter = 80, | ||
size, | ||
className = '', | ||
fullName, | ||
style = {}, | ||
}: { | ||
fullName: string; | ||
diameter?: number; | ||
size?: SIZE_KEYS; | ||
src?: string | null; | ||
className?: string; | ||
style?: Record<string, string | number>; | ||
}): JSX.Element => { | ||
const diameterValue = size ? SIZES[size] : diameter; | ||
|
||
return src ? ( | ||
<PictureAvatar src={src} diameter={diameterValue} className={className} style={style} /> | ||
) : ( | ||
<DefaultAvatar diameter={diameterValue} className={className} fullName={fullName} /> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
import { describe, expect, it } from 'vitest'; | ||
import { render } from '@testing-library/react'; | ||
import { Avatar } from '../Avatar'; | ||
|
||
const FULL_NAME = 'My Internxt'; | ||
const IMAGE_SRC = 'https://internxt.com/favicon.ico'; | ||
|
||
describe('Avatar component', () => { | ||
it('Avatar with full name (first letters) should render correctly', () => { | ||
const avatarComponent = render(<Avatar diameter={80} fullName={FULL_NAME} />); | ||
expect(avatarComponent).toMatchSnapshot(); | ||
}); | ||
|
||
it('Avatar with avatar (user image profile) should render correctly', () => { | ||
const avatarComponent = render(<Avatar fullName={FULL_NAME} diameter={80} src={IMAGE_SRC} />); | ||
expect(avatarComponent).toMatchSnapshot(); | ||
}); | ||
|
||
it('XXS Avatar should render correctly', () => { | ||
const avatarComponent = render(<Avatar fullName={FULL_NAME} size="xxs" src={IMAGE_SRC} />); | ||
expect(avatarComponent).toMatchSnapshot(); | ||
}); | ||
it('XS Avatar should render correctly', () => { | ||
const avatarComponent = render(<Avatar fullName={FULL_NAME} size="xs" src={IMAGE_SRC} />); | ||
expect(avatarComponent).toMatchSnapshot(); | ||
}); | ||
|
||
it('SM Avatar should render correctly', () => { | ||
const avatarComponent = render(<Avatar fullName={FULL_NAME} size="sm" src={IMAGE_SRC} />); | ||
expect(avatarComponent).toMatchSnapshot(); | ||
}); | ||
|
||
it('Base Avatar should render correctly', () => { | ||
const avatarComponent = render(<Avatar fullName={FULL_NAME} size="base" src={IMAGE_SRC} />); | ||
expect(avatarComponent).toMatchSnapshot(); | ||
}); | ||
it('LG Avatar should render correctly', () => { | ||
const avatarComponent = render(<Avatar fullName={FULL_NAME} size="lg" src={IMAGE_SRC} />); | ||
expect(avatarComponent).toMatchSnapshot(); | ||
}); | ||
it('XL Avatar should render correctly', () => { | ||
const avatarComponent = render(<Avatar fullName={FULL_NAME} size="xl" src={IMAGE_SRC} />); | ||
expect(avatarComponent).toMatchSnapshot(); | ||
}); | ||
}); |
Oops, something went wrong.