Skip to content

Commit

Permalink
Merge pull request #8 from internxt/feat/avatar-component
Browse files Browse the repository at this point in the history
[PB-3005]: feat/avatar component
  • Loading branch information
xabg2 authored Oct 17, 2024
2 parents 0e1d42f + e514807 commit 486f5a5
Show file tree
Hide file tree
Showing 12 changed files with 877 additions and 22 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@internxt/internxtui",
"version": "0.0.2",
"version": "0.0.3",
"description": "Library of Internxt components",
"repository": {
"type": "git",
Expand Down
56 changes: 56 additions & 0 deletions src/components/avatar/Avatar.tsx
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} />
);
};
45 changes: 45 additions & 0 deletions src/components/avatar/__tests__/Avatar.test.tsx
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();
});
});
Loading

0 comments on commit 486f5a5

Please sign in to comment.