Skip to content

Commit bbe9b8e

Browse files
committed
feat: Profile 컴포넌트 구현
1 parent 63b6d8f commit bbe9b8e

6 files changed

Lines changed: 84 additions & 2 deletions

File tree

.storybook/main.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,4 @@ const config: StorybookConfig = {
1111
],
1212
framework: '@storybook/react-vite',
1313
};
14-
export default config;
14+
export default config;

public/profile-sample.jpg

6.05 KB
Loading

public/site.webmanifest

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,4 @@
1818
"theme_color": "#ffffff",
1919
"background_color": "#ffffff",
2020
"display": "standalone"
21-
}
21+
}

src/pages/playground.tsx

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,20 @@
11
import { Button } from '@shared/ui/Button/Button';
22
import { Checkbox } from '@shared/ui/Checkbox/Checkbox';
3+
import { Profile } from '@shared/ui/Profile/Profile';
34
import { RadioButton } from '@shared/ui/RadioButton/RadioButton';
45

56
export default function Playground() {
67
return (
78
<div className="flex flex-col gap-6 p-8">
89
<h1 className="typo-title-2">UI Playground</h1>
910

11+
{/* Button */}
1012
<section className="flex flex-col gap-4">
1113
<h2 className="typo-body-1">Button</h2>
1214
<p className="typo-caption-2 text-gray-600">
1315
Hover와 Focus 상태를 확인하려면 마우스를 올리거나 Tab 키로 포커스를 이동하세요.
1416
</p>
17+
1518
<div className="flex flex-col gap-4">
1619
<div className="flex items-center gap-4">
1720
<span className="typo-caption-1 w-24">Fill</span>
@@ -20,6 +23,7 @@ export default function Playground() {
2023
Disabled
2124
</Button>
2225
</div>
26+
2327
<div className="flex items-center gap-4">
2428
<span className="typo-caption-1 w-24">Outline</span>
2529
<Button variant="outline">Default</Button>
@@ -30,6 +34,7 @@ export default function Playground() {
3034
</div>
3135
</section>
3236

37+
{/* Checkbox */}
3338
<section className="flex flex-col gap-4">
3439
<h2 className="typo-body-1">Checkbox</h2>
3540
<div className="flex flex-col gap-2">
@@ -40,6 +45,7 @@ export default function Playground() {
4045
</div>
4146
</section>
4247

48+
{/* Radio Button */}
4349
<section className="flex flex-col gap-4">
4450
<h2 className="typo-body-1">Radio Button</h2>
4551
<div className="flex flex-col gap-2">
@@ -49,6 +55,40 @@ export default function Playground() {
4955
<RadioButton checked disabled label="Selected + Disabled" />
5056
</div>
5157
</section>
58+
59+
{/* Profile */}
60+
<section className="flex flex-col gap-4">
61+
<h2 className="typo-body-1">Profile</h2>
62+
<p className="typo-caption-2 text-gray-600">
63+
size variant 및 placeholder 상태를 확인합니다.
64+
</p>
65+
66+
<div className="flex items-center gap-10">
67+
{/* small image */}
68+
<div className="flex flex-col items-center gap-2">
69+
<Profile size="sm" imageUrl="/profile-sample.jpg" />
70+
<span className="typo-caption-2">Small Image</span>
71+
</div>
72+
73+
{/* large image */}
74+
<div className="flex flex-col items-center gap-2">
75+
<Profile size="lg" imageUrl="/profile-sample.jpg" />
76+
<span className="typo-caption-2">Large Image</span>
77+
</div>
78+
79+
{/* small placeholder */}
80+
<div className="flex flex-col items-center gap-2">
81+
<Profile size="sm" />
82+
<span className="typo-caption-2 text-gray-500">Small Placeholder</span>
83+
</div>
84+
85+
{/* large placeholder */}
86+
<div className="flex flex-col items-center gap-2">
87+
<Profile size="lg" />
88+
<span className="typo-caption-2 text-gray-500">Large Placeholder</span>
89+
</div>
90+
</div>
91+
</section>
5292
</div>
5393
);
5494
}

src/shared/ui/Profile/Profile.tsx

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { profileVariants } from './Profile.variants';
2+
import type { ComponentPropsWithoutRef } from 'react';
3+
import type { VariantProps } from 'tailwind-variants';
4+
5+
export type ProfileProps = ComponentPropsWithoutRef<'div'> &
6+
VariantProps<typeof profileVariants> & {
7+
imageUrl?: string;
8+
};
9+
10+
export const Profile = ({ size, imageUrl, className, ...props }: ProfileProps) => {
11+
return (
12+
<div
13+
className={profileVariants({ size, className })}
14+
style={imageUrl ? { backgroundImage: `url(${imageUrl})` } : undefined}
15+
{...props}
16+
/>
17+
);
18+
};
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { tv } from 'tailwind-variants';
2+
3+
export const profileVariants = tv({
4+
base: [
5+
'relative',
6+
'flex items-center justify-center',
7+
'overflow-hidden',
8+
9+
'rounded-full',
10+
'bg-[var(--color-gray-200)]',
11+
'bg-center bg-cover bg-no-repeat',
12+
],
13+
14+
variants: {
15+
size: {
16+
sm: ['w-[44px]', 'h-[44px]'],
17+
lg: ['w-[152px]', 'h-[152px]'],
18+
},
19+
},
20+
21+
defaultVariants: {
22+
size: 'sm',
23+
},
24+
});

0 commit comments

Comments
 (0)