Skip to content

Commit a1a75b9

Browse files
authored
Merge pull request #91 from YAPP-Github/feature/PRODUCT-192
feat: Skeleton 컴포넌트 생성 (#90)
2 parents 5e0a28d + 2d76967 commit a1a75b9

File tree

4 files changed

+121
-0
lines changed

4 files changed

+121
-0
lines changed
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { createVar, style } from "@vanilla-extract/css";
2+
3+
import { colors } from "@/styles";
4+
5+
export const widthVar = createVar();
6+
export const heightVar = createVar();
7+
export const radiusVar = createVar();
8+
9+
export const wrapper = style({
10+
width: widthVar,
11+
height: heightVar,
12+
borderRadius: radiusVar,
13+
backgroundColor: colors.coolNeutral[98],
14+
});
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import type { Meta, StoryObj } from "@storybook/nextjs";
2+
3+
import { Skeleton } from "./Skeleton";
4+
5+
const meta: Meta<typeof Skeleton> = {
6+
title: "Components/Skeleton",
7+
component: Skeleton,
8+
tags: ["autodocs"],
9+
parameters: {
10+
docs: {
11+
description: {
12+
component:
13+
"Skeleton 컴포넌트는 로딩 상태를 시각적으로 표시하기 위한 사각형 스켈레톤 UI입니다. width, height, radius를 지정할 수 있습니다.",
14+
},
15+
},
16+
},
17+
argTypes: {
18+
width: {
19+
control: "number",
20+
description: "스켈레톤의 너비 (px)",
21+
},
22+
height: {
23+
control: "number",
24+
description: "스켈레톤의 높이 (px)",
25+
},
26+
radius: {
27+
control: "text",
28+
description: "스켈레톤의 border-radius (px 또는 string)",
29+
},
30+
},
31+
};
32+
33+
export default meta;
34+
type Story = StoryObj<typeof Skeleton>;
35+
36+
export const Default: Story = {
37+
render: args => <Skeleton {...args} />,
38+
args: {
39+
width: 120,
40+
height: 24,
41+
radius: 8,
42+
},
43+
};
44+
45+
export const CustomRadius: Story = {
46+
render: args => <Skeleton {...args} />,
47+
args: {
48+
width: 120,
49+
height: 24,
50+
radius: "50%",
51+
},
52+
};
53+
54+
export const VariousSizes: Story = {
55+
render: () => (
56+
<div style={{ display: "flex", gap: 16, alignItems: "center" }}>
57+
<Skeleton width={40} height={40} radius={20} />
58+
<Skeleton width={80} height={16} radius={4} />
59+
<Skeleton width={120} height={24} radius={8} />
60+
<Skeleton width={200} height={32} radius={16} />
61+
</div>
62+
),
63+
};
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import { assignInlineVars } from "@vanilla-extract/dynamic";
2+
import { type HTMLAttributes } from "react";
3+
4+
import { coerceCssRemValue } from "@/lib/utils/coerceCssRemValue";
5+
6+
import * as styles from "./Skeleton.css";
7+
8+
export type SkeletonProps = {
9+
/** 스켈레톤 너비 */
10+
width: number;
11+
12+
/** 스켈레톤 높이 */
13+
height: number;
14+
15+
/** border-radius(px, rem, %, 토큰 모두 가능) */
16+
radius?: number | string;
17+
} & HTMLAttributes<HTMLDivElement>;
18+
19+
/**
20+
* Skeleton 컴포넌트
21+
* @example
22+
* ```tsx
23+
* <Skeleton width={120} height={24} radius={8} />
24+
* ```
25+
*/
26+
export const Skeleton = ({
27+
width,
28+
height,
29+
radius,
30+
style: customStyle,
31+
...rest
32+
}: SkeletonProps) => {
33+
const style = {
34+
...assignInlineVars({
35+
[styles.widthVar]: coerceCssRemValue(width),
36+
[styles.heightVar]: coerceCssRemValue(height),
37+
[styles.radiusVar]: radius ? coerceCssRemValue(radius) : undefined,
38+
}),
39+
...customStyle,
40+
};
41+
42+
return <div className={styles.wrapper} style={style} {...rest} />;
43+
};
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { Skeleton, type SkeletonProps } from "./Skeleton";

0 commit comments

Comments
 (0)