Skip to content

Commit 20effd6

Browse files
authored
Merge pull request #69 from YAPP-Github/feature/PRODUCT-131
2 parents 79a76cc + 3796eda commit 20effd6

File tree

19 files changed

+1076
-0
lines changed

19 files changed

+1076
-0
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
"@tanstack/react-query": "^5.77.0",
2121
"@tanstack/react-query-devtools": "^5.77.0",
2222
"@vanilla-extract/css": "^1.17.2",
23+
"@vanilla-extract/dynamic": "^2.1.5",
2324
"@vanilla-extract/recipes": "^0.5.7",
2425
"iron-session": "^8.0.4",
2526
"ky": "^1.8.1",

pnpm-lock.yaml

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { createVar, style } from "@vanilla-extract/css";
2+
3+
export const bleedInlineStartVar = createVar();
4+
export const bleedInlineEndVar = createVar();
5+
export const bleedBlockStartVar = createVar();
6+
export const bleedBlockEndVar = createVar();
7+
8+
export const container = style({
9+
marginInlineStart: `calc(${bleedInlineStartVar} * -1)`,
10+
marginInlineEnd: `calc(${bleedInlineEndVar} * -1)`,
11+
marginBlockStart: `calc(${bleedBlockStartVar} * -1)`,
12+
marginBlockEnd: `calc(${bleedBlockEndVar} * -1)`,
13+
});
Lines changed: 206 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,206 @@
1+
import type { Meta, StoryObj } from "@storybook/react";
2+
3+
import { Bleed } from "./Bleed";
4+
5+
const meta: Meta<typeof Bleed> = {
6+
title: "Components/Bleed",
7+
component: Bleed,
8+
tags: ["autodocs"],
9+
parameters: {
10+
docs: {
11+
description: {
12+
component:
13+
"Bleed 컴포넌트는 부모 요소의 여백(padding)을 무시하고 특정 방향으로 확장되어야 하는 UI를 구현할 때 사용됩니다. 이를 통해 페이지나 섹션의 전체 너비를 차지하는 컴포넌트를 쉽게 만들 수 있습니다.",
14+
},
15+
},
16+
},
17+
argTypes: {
18+
as: {
19+
control: false,
20+
description: "컴포넌트의 HTML 태그를 설정합니다.",
21+
table: {
22+
type: { summary: "React.ElementType" },
23+
defaultValue: { summary: "div" },
24+
},
25+
},
26+
inline: {
27+
control: "number",
28+
description:
29+
"좌우 여백을 설정합니다. `inlineStart`와 `inlineEnd`를 동시에 설정합니다.",
30+
table: {
31+
type: { summary: "number | string" },
32+
},
33+
},
34+
block: {
35+
control: "number",
36+
description:
37+
"상하 여백을 설정합니다. `blockStart`와 `blockEnd`를 동시에 설정합니다.",
38+
table: {
39+
type: { summary: "number | string" },
40+
},
41+
},
42+
inlineStart: {
43+
control: "number",
44+
description: "시작 방향(LTR 환경에서는 왼쪽)의 여백을 설정합니다.",
45+
table: {
46+
type: { summary: "number | string" },
47+
},
48+
},
49+
inlineEnd: {
50+
control: "number",
51+
description: "끝 방향(LTR 환경에서는 오른쪽)의 여백을 설정합니다.",
52+
table: {
53+
type: { summary: "number | string" },
54+
},
55+
},
56+
blockStart: {
57+
control: "number",
58+
description: "위쪽 여백을 설정합니다.",
59+
table: {
60+
type: { summary: "number | string" },
61+
},
62+
},
63+
blockEnd: {
64+
control: "number",
65+
description: "아래쪽 여백을 설정합니다.",
66+
table: {
67+
type: { summary: "number | string" },
68+
},
69+
},
70+
},
71+
};
72+
73+
export default meta;
74+
type Story = StoryObj<typeof Bleed>;
75+
76+
export const InlineBleed: Story = {
77+
render: () => (
78+
<div
79+
style={{
80+
padding: "16px",
81+
backgroundColor: "rgba(255, 0, 0, 0.1)",
82+
width: "300px",
83+
}}
84+
>
85+
<div
86+
style={{
87+
backgroundColor: "rgba(0, 255, 0, 0.1)",
88+
padding: "12px",
89+
textAlign: "center",
90+
}}
91+
>
92+
컨텐츠 영역
93+
</div>
94+
<Bleed inline={16}>
95+
<div
96+
style={{
97+
backgroundColor: "rgba(0, 0, 255, 0.1)",
98+
padding: "12px",
99+
textAlign: "center",
100+
}}
101+
>
102+
Bleed 영역
103+
</div>
104+
</Bleed>
105+
<div
106+
style={{
107+
backgroundColor: "rgba(0, 255, 0, 0.1)",
108+
padding: "12px",
109+
textAlign: "center",
110+
marginTop: "8px",
111+
}}
112+
>
113+
컨텐츠 영역
114+
</div>
115+
</div>
116+
),
117+
parameters: {
118+
docs: {
119+
description: {
120+
story:
121+
"`inline` prop을 사용하여 좌우로 확장된 컴포넌트입니다. 부모 요소의 `padding`을 무시하고 좌우로 확장됩니다. 붉은 영역이 부모의 padding 영역을 시각화합니다.",
122+
},
123+
},
124+
},
125+
};
126+
127+
export const BlockBleed: Story = {
128+
render: () => (
129+
<div
130+
style={{
131+
padding: "16px",
132+
backgroundColor: "rgba(255, 0, 0, 0.1)",
133+
}}
134+
>
135+
<div
136+
style={{
137+
backgroundColor: "rgba(0, 255, 0, 0.1)",
138+
padding: "12px",
139+
textAlign: "center",
140+
}}
141+
>
142+
컨텐츠 영역
143+
</div>
144+
<Bleed block={16}>
145+
<div
146+
style={{
147+
backgroundColor: "rgba(0, 0, 255, 0.1)",
148+
padding: "12px",
149+
textAlign: "center",
150+
}}
151+
>
152+
Bleed 영역
153+
</div>
154+
</Bleed>
155+
<div
156+
style={{
157+
backgroundColor: "rgba(0, 255, 0, 0.1)",
158+
padding: "12px",
159+
textAlign: "center",
160+
marginTop: "8px",
161+
}}
162+
>
163+
컨텐츠 영역
164+
</div>
165+
</div>
166+
),
167+
parameters: {
168+
docs: {
169+
description: {
170+
story:
171+
"`block` prop을 사용하여 상하로 확장된 컴포넌트입니다. 부모 요소의 `padding`을 무시하고 상하로 확장됩니다. 붉은 영역이 부모의 padding 영역을 시각화합니다.",
172+
},
173+
},
174+
},
175+
};
176+
177+
export const AllDirectionsBleed: Story = {
178+
render: () => (
179+
<div
180+
style={{
181+
padding: "16px",
182+
backgroundColor: "rgba(255, 0, 0, 0.1)",
183+
}}
184+
>
185+
<Bleed inline={16} block={16}>
186+
<div
187+
style={{
188+
backgroundColor: "rgba(0, 0, 255, 0.1)",
189+
padding: "12px",
190+
textAlign: "center",
191+
}}
192+
>
193+
Bleed 영역
194+
</div>
195+
</Bleed>
196+
</div>
197+
),
198+
parameters: {
199+
docs: {
200+
description: {
201+
story:
202+
"`inline`과 `block` prop을 모두 사용하여 모든 방향으로 확장된 컴포넌트입니다.",
203+
},
204+
},
205+
},
206+
};

src/components/ui/Bleed/Bleed.tsx

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import { assignInlineVars } from "@vanilla-extract/dynamic";
2+
import { type ElementType } from "react";
3+
4+
import { coerceCssRemValue } from "@/lib/utils/coerceCssRemValue";
5+
import { type PolymorphicComponentPropsWithRef } from "@/types/polymorphic.types";
6+
7+
import * as styles from "./Bleed.css";
8+
9+
export type BleedProps<T extends ElementType> =
10+
PolymorphicComponentPropsWithRef<
11+
T,
12+
{
13+
inline?: number | string;
14+
block?: number | string;
15+
inlineStart?: number | string;
16+
inlineEnd?: number | string;
17+
blockStart?: number | string;
18+
blockEnd?: number | string;
19+
}
20+
>;
21+
22+
export const Bleed = <T extends ElementType = "div">({
23+
as,
24+
className,
25+
inline,
26+
block,
27+
inlineStart,
28+
inlineEnd,
29+
blockStart,
30+
blockEnd,
31+
style: styleFromProps,
32+
...props
33+
}: BleedProps<T>) => {
34+
const Component = as || "div";
35+
36+
const style = {
37+
...styleFromProps,
38+
...assignInlineVars({
39+
...(inline && {
40+
[styles.bleedInlineStartVar]: coerceCssRemValue(inline),
41+
[styles.bleedInlineEndVar]: coerceCssRemValue(inline),
42+
}),
43+
...(block && {
44+
[styles.bleedBlockStartVar]: coerceCssRemValue(block),
45+
[styles.bleedBlockEndVar]: coerceCssRemValue(block),
46+
}),
47+
...(inlineStart && {
48+
[styles.bleedInlineStartVar]: coerceCssRemValue(inlineStart),
49+
}),
50+
...(inlineEnd && {
51+
[styles.bleedInlineEndVar]: coerceCssRemValue(inlineEnd),
52+
}),
53+
...(blockStart && {
54+
[styles.bleedBlockStartVar]: coerceCssRemValue(blockStart),
55+
}),
56+
...(blockEnd && {
57+
[styles.bleedBlockEndVar]: coerceCssRemValue(blockEnd),
58+
}),
59+
}),
60+
};
61+
62+
return (
63+
<Component
64+
className={`${styles.container} ${className ?? ""}`.trim()}
65+
style={style}
66+
{...props}
67+
/>
68+
);
69+
};

src/components/ui/Bleed/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { Bleed, type BleedProps } from "./Bleed";

0 commit comments

Comments
 (0)