Skip to content

Commit

Permalink
feature: add Avatar component
Browse files Browse the repository at this point in the history
  • Loading branch information
castromaciel authored Feb 14, 2023
2 parents 00a27a6 + 3606136 commit 44cc983
Show file tree
Hide file tree
Showing 8 changed files with 433 additions and 243 deletions.
3 changes: 2 additions & 1 deletion .storybook/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ module.exports = {
"addons": [
"@storybook/addon-links",
"@storybook/addon-essentials",
"@storybook/addon-interactions"
"@storybook/addon-interactions",
"@storybook/preset-scss"
],
"framework": "@storybook/react"
}
9 changes: 7 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,10 @@
"@storybook/addon-essentials": "^6.5.16",
"@storybook/addon-interactions": "^6.5.16",
"@storybook/addon-links": "^6.5.16",
"@storybook/addon-postcss": "^2.0.0",
"@storybook/builder-webpack4": "^6.5.16",
"@storybook/manager-webpack4": "^6.5.16",
"@storybook/preset-scss": "^1.0.3",
"@storybook/react": "^6.5.16",
"@storybook/testing-library": "^0.0.13",
"@testing-library/jest-dom": "^5.16.5",
Expand All @@ -82,6 +84,7 @@
"@typescript-eslint/parser": "^5.36.1",
"add": "^2.0.6",
"babel-loader": "^8.3.0",
"css-loader": "5",
"eslint": "^8.2.0",
"eslint-config-airbnb": "19.0.4",
"eslint-plugin-import": "^2.25.3",
Expand All @@ -92,13 +95,15 @@
"husky": "^8.0.3",
"identity-obj-proxy": "^3.0.0",
"jest": "^29.4.1",
"postcss": "8.1.0",
"postcss": "^8.4.21",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"rollup-plugin-postcss": "^4.0.2",
"sass": "^1.54.4",
"sass": "^1.58.0",
"sass-loader": "10",
"semantic-release": "19.0.5",
"size-limit": "^8.1.2",
"style-loader": "2",
"tsdx": "^0.14.1",
"tslib": "^2.5.0",
"typescript": "^4.9.5",
Expand Down
9 changes: 9 additions & 0 deletions src/typings.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
declare module '*.module.scss' {
const content: { [className: string]: string };
export default content;
}

declare module '*.jpg' {
const value: any;
export default value;
}
37 changes: 37 additions & 0 deletions src/utils/Avatar/Avatar.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { ComponentMeta, ComponentStory } from '@storybook/react'
import React from 'react'

import { Avatar } from '..'

export default {
title: 'Components/Utils/Avatar',
component: Avatar,
argTypes: {
image: {
control: {
type: 'disabled'
},
description: 'Imagen o Foto de perfil'
},
label: { description: 'Texto alternativo del avatar' },
size: { description: 'Tamaño del avatar' },
shape: { description: 'Forma del avatar' }
}
} as ComponentMeta<typeof Avatar>

const Template: ComponentStory<typeof Avatar> = (args) => (
<Avatar {...args} />
)

export const DefaultAvatar = Template.bind({})
DefaultAvatar.args = {
image: 'https://picsum.photos/300/300',
size: 'md',
shape: 'circle'
}

export const SquareAvatar = Template.bind({})
SquareAvatar.args = {
image: 'https://picsum.photos/300/300',
shape: 'square'
}
45 changes: 45 additions & 0 deletions src/utils/Avatar/Avatar.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/* eslint-disable no-undef */
import { render, screen } from '@testing-library/react'
import React from 'react'
import { Avatar } from '..'
import { AvatarProps } from './Avatar'

const userAvatar: AvatarProps = {
image: 'https://picsum.photos/300/300',
label: 'Maciel Castro'
}

const userWithoutLabelAvatar: AvatarProps = {
image: 'https://picsum.photos/300/300',
label: ''
}

const squareUserAvatar: AvatarProps = {
image: 'https://picsum.photos/300/300',
label: 'Maciel Castro',
shape: 'square',
size: 'xl'
}

describe('Avatar', () => {
test('Should render avatar', () => {
render(<Avatar {...userAvatar} />)

const element = screen.getByAltText('Maciel Castro')
expect(element).toBeInTheDocument()
})

test('Should render avatar square', () => {
render(<Avatar {...squareUserAvatar} />)

const element = screen.getByAltText('Maciel Castro')
expect(element).toHaveClass('square')
})

test('Should render avatar with alternative text', () => {
render(<Avatar {...userWithoutLabelAvatar} />)

const element = screen.getByAltText('avatar')
expect(element).toBeInTheDocument()
})
})
24 changes: 22 additions & 2 deletions src/utils/Avatar/Avatar.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,25 @@
import React from 'react'
import React, { FC } from 'react'
import './avatar.scss'

const Avatar = () => <h1>Avatar component</h1>
type ShapeType = | 'square' | 'circle'
type SizeType = | 'sm' | 'md' | 'lg' | 'xl' | 'xxl'

export interface AvatarProps {
image: string
label?: string
shape?: ShapeType
size?: SizeType
}

const Avatar: FC<AvatarProps> = ({
image,
label,
shape = 'circle',
size = 'md'
}) => (
<picture className={`rc-avatar size_${size}`}>
<img src={image} alt={`${label || 'avatar'}`} className={`${shape}`} />
</picture>
)

export default Avatar
36 changes: 36 additions & 0 deletions src/utils/Avatar/avatar.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
.rc-avatar {
display: block;
&.size {
&_sm {
width: 32px;
height: 32px;
}
&_md {
width: 64px;
height: 64px;
}
&_lg {
width: 96px;
height: 96px;
}
&_xl {
width: 128px;
height: 128px;
}
&_xxl {
width: 256px;
height: 256px;
}

}

img {
width: 100%;
height: 100%;
}

.circle {
border-radius: 100%;
}

}
Loading

0 comments on commit 44cc983

Please sign in to comment.