Skip to content

Commit 591dc7e

Browse files
authored
[#51] ✨ 공통 컴포넌트 Avatar 개발 (#89)
* [#51] 💄 remove default width, height props in avatar svg * [#51] ✨ add Avatart component * [#51] ✅ add Avatar stories
1 parent 62fea77 commit 591dc7e

File tree

4 files changed

+115
-1
lines changed

4 files changed

+115
-1
lines changed

src/assets/icons/ic-avatar.svg

Lines changed: 1 addition & 1 deletion
Loading
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import Image from 'next/image'
2+
3+
import { IcAvatar } from '@/assets/IconList'
4+
import clsx from 'clsx'
5+
6+
type AvatarSize = 24 | 48 | 60 | 180
7+
8+
interface AvatarProps {
9+
image?: string | null
10+
size?: AvatarSize
11+
alt?: string
12+
className?: string
13+
}
14+
15+
const baseStyle =
16+
'relative flex items-center justify-center overflow-hidden rounded-full bg-gray-200'
17+
18+
const styleBySize: Record<AvatarSize, string> = {
19+
24: 'w-24 h-24',
20+
48: 'w-44 h-44',
21+
60: 'w-60 h-60',
22+
180: 'w-180 h-180',
23+
}
24+
25+
export const Avatar = ({
26+
image = null,
27+
size = 48,
28+
alt = 'username',
29+
className = '',
30+
}: AvatarProps): JSX.Element => {
31+
const avatarStyle = clsx(baseStyle, styleBySize[size], className)
32+
33+
return (
34+
<div className={avatarStyle} role='img'>
35+
{image ? (
36+
<Image
37+
src={image}
38+
alt={`${alt} 아바타`}
39+
fill
40+
className='object-cover'
41+
/>
42+
) : (
43+
<IcAvatar />
44+
)}
45+
</div>
46+
)
47+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import { Avatar } from './Avatar'
2+
3+
export { Avatar }
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import { Meta, StoryObj } from '@storybook/react'
2+
3+
import { Avatar } from '@/components/common/avatar'
4+
5+
const meta: Meta<typeof Avatar> = {
6+
title: 'Common/Avatar/Avatar',
7+
component: Avatar,
8+
parameters: {
9+
layout: 'centered',
10+
},
11+
argTypes: {
12+
size: {
13+
control: 'select',
14+
options: [24, 48, 60, 180],
15+
description: 'Avatar size in pixels',
16+
},
17+
image: {
18+
control: 'text',
19+
description: 'URL of the avatar image',
20+
},
21+
alt: {
22+
control: 'text',
23+
description: 'Alt text for the avatar image',
24+
},
25+
className: {
26+
control: 'text',
27+
description: 'Additional CSS classes for custom styling',
28+
},
29+
},
30+
args: {
31+
alt: 'User Avatar',
32+
},
33+
}
34+
35+
export default meta
36+
type Story = StoryObj<typeof Avatar>
37+
38+
export const Default: Story = {
39+
args: {
40+
size: 48,
41+
image: null,
42+
},
43+
}
44+
45+
export const WithImage: Story = {
46+
args: {
47+
size: 48,
48+
image: 'https://picsum.photos/250/250',
49+
},
50+
}
51+
52+
export const LargeAvatar: Story = {
53+
args: {
54+
size: 180,
55+
image: 'https://picsum.photos/250/250',
56+
},
57+
}
58+
59+
export const SmallAvatar: Story = {
60+
args: {
61+
size: 24,
62+
image: null,
63+
},
64+
}

0 commit comments

Comments
 (0)