diff --git a/src/components/Flex/Flex.stories.tsx b/src/components/Flex/Flex.stories.tsx index 860f165a..6061661d 100644 --- a/src/components/Flex/Flex.stories.tsx +++ b/src/components/Flex/Flex.stories.tsx @@ -37,6 +37,7 @@ export default { description: "교차축 정렬 방식", }, gap: { control: "select", options: Object.keys(spacing || {}) }, + padding: { control: "select", options: Object.keys(spacing || {}) }, className: { control: false }, }, args: { @@ -106,6 +107,25 @@ export const Gaps: Story = { args: {}, }; +export const Padding: Story = { + render: (args) => ( +
+
+

padding: 16

+ +
+
+

padding: 32

+ +
+
+ ), + argTypes: { + children: { control: false }, + padding: { control: false }, + }, +}; + export const Justify: Story = { render: (args) => (
diff --git a/src/components/Flex/Flex.test.tsx b/src/components/Flex/Flex.test.tsx index 63acf541..acc66c30 100644 --- a/src/components/Flex/Flex.test.tsx +++ b/src/components/Flex/Flex.test.tsx @@ -109,6 +109,20 @@ describe("클래스 토큰 및 스타일", () => { screen.getByRole("navigation", { name: `flex-gap-${gap}` }).className, ).toMatch(`gap_${gap}`); }); + + const paddings = Object.keys(spacing || {}) as Spacing[]; + test.each(paddings)("padding=%s이면 p_%s 클래스가 적용된다", (padding) => { + render( + + child + , + ); + + expect( + screen.getByRole("navigation", { name: `flex-padding-${padding}` }) + .className, + ).toMatch(`p_${padding}`); + }); }); describe("Flex 접근성", () => { diff --git a/src/components/Flex/Flex.tsx b/src/components/Flex/Flex.tsx index 1731b17f..3239b5d1 100644 --- a/src/components/Flex/Flex.tsx +++ b/src/components/Flex/Flex.tsx @@ -23,6 +23,8 @@ export interface FlexProps as?: As; /** 자식 간 간격 */ gap?: Spacing; + /** 안쪽 여백 */ + padding?: Spacing; /** ARIA 역할 */ role?: AriaRole; } @@ -54,6 +56,7 @@ export const Flex = ({ justify = "start", align = "stretch", gap, + padding, className, ...rest }: FlexProps) => { @@ -68,7 +71,7 @@ export const Flex = ({ justify, align, }), - css({ gap }), + css({ gap, padding }), className, ), ...rest, diff --git a/src/components/Grid/Grid.stories.tsx b/src/components/Grid/Grid.stories.tsx index 2dd065ca..02cf749e 100644 --- a/src/components/Grid/Grid.stories.tsx +++ b/src/components/Grid/Grid.stories.tsx @@ -45,6 +45,10 @@ export default { control: "select", options: [undefined, ...Object.keys(spacing || {})], }, + padding: { + control: "select", + options: Object.keys(spacing || {}), + }, areas: { control: false }, className: { control: false }, }, @@ -128,6 +132,24 @@ export const Gaps: Story = { }, }; +export const Padding: Story = { + render: (args) => ( +
+
+

padding: 16

+ +
+
+

padding: 32

+ +
+
+ ), + argTypes: { + padding: { control: false }, + }, +}; + export const GridItemSpan: Story = { render: (args) => ( { expect(screen.getByTestId(`grid-gap-${gap}`)).toHaveClass(`gap_${gap}`); }); + const paddings = Object.keys(spacing || {}) as Spacing[]; + test.each(paddings)( + `padding=%s 적용 시 알맞은 클래스가 적용된다`, + (padding) => { + render( + + child + , + ); + expect(screen.getByTestId(`grid-padding-${padding}`)).toHaveClass( + `p_${padding}`, + ); + }, + ); + test("areas가 문자열로 전달되면 CSS 변수가 적용된다", () => { render( ( + +
+

padding: 16

+ +
+
+

padding: 32

+ +
+
+ ), + argTypes: { + children: { control: false }, + padding: { control: false }, + }, +}; + export const Reverse: Story = { render: (args) => ( diff --git a/src/components/HStack/HStack.test.tsx b/src/components/HStack/HStack.test.tsx index 16786a43..d74b96e6 100644 --- a/src/components/HStack/HStack.test.tsx +++ b/src/components/HStack/HStack.test.tsx @@ -92,6 +92,19 @@ describe("클래스 토큰 및 스타일", () => { expect(screen.getByTestId("gap").className).toMatch(className); }, ); + + const paddings = Object.keys(spacing || {}) as Spacing[]; + test.each(paddings.map((padding) => [padding, `p_${padding}`]))( + "padding=%s이면 %s 클래스가 적용된다", + (padding, className) => { + render( + + child + , + ); + expect(screen.getByTestId("padding").className).toMatch(className); + }, + ); }); describe("HStack 접근성", () => { diff --git a/src/components/HStack/HStack.tsx b/src/components/HStack/HStack.tsx index fefc3d41..bdbd1085 100644 --- a/src/components/HStack/HStack.tsx +++ b/src/components/HStack/HStack.tsx @@ -44,6 +44,7 @@ export const HStack = ({ align = "center", reversed = false, gap, + padding, className, ...rest }: HStackProps) => { @@ -57,6 +58,7 @@ export const HStack = ({ justify={justifyContent} align={alignContent} gap={gap} + padding={padding} className={className} {...rest} > diff --git a/src/components/VStack/VStack.stories.tsx b/src/components/VStack/VStack.stories.tsx index 7443525f..793d1d60 100644 --- a/src/components/VStack/VStack.stories.tsx +++ b/src/components/VStack/VStack.stories.tsx @@ -30,6 +30,7 @@ export default { argTypes: { children: { control: false }, gap: { control: "select", options: Object.keys(spacing || {}) }, + padding: { control: "select", options: Object.keys(spacing || {}) }, className: { control: false }, role: { control: "text" }, }, @@ -45,7 +46,7 @@ export default { 아이템 2 ), - className: css({ width: "120", height: "160" }), + className: css({ height: "160" }), }, } satisfies Meta; @@ -74,6 +75,24 @@ export const Gaps: Story = { }, }; +export const Padding: Story = { + render: (args) => ( + +
+

padding: 16

+ +
+
+

padding: 32

+ +
+
+ ), + argTypes: { + padding: { control: false }, + }, +}; + export const Reverse: Story = { render: (args) => ( diff --git a/src/components/VStack/VStack.test.tsx b/src/components/VStack/VStack.test.tsx index 74e96bec..68fd01ca 100644 --- a/src/components/VStack/VStack.test.tsx +++ b/src/components/VStack/VStack.test.tsx @@ -98,6 +98,19 @@ describe("클래스 토큰 및 스타일", () => { expect(screen.getByTestId("gap").className).toMatch(className); }, ); + + const paddings = Object.keys(spacing || {}) as Spacing[]; + test.each(paddings.map((padding) => [padding, `p_${padding}`]))( + "padding=%s이면 %s 클래스가 적용된다", + (padding, className) => { + render( + + child + , + ); + expect(screen.getByTestId("padding").className).toMatch(className); + }, + ); }); describe("VStack 접근성", () => { diff --git a/src/components/VStack/VStack.tsx b/src/components/VStack/VStack.tsx index 9c356f25..ccc48e6e 100644 --- a/src/components/VStack/VStack.tsx +++ b/src/components/VStack/VStack.tsx @@ -47,6 +47,7 @@ export const VStack = ({ align = "center", reversed = false, gap, + padding, className, ...rest }: VStackProps) => { @@ -61,6 +62,7 @@ export const VStack = ({ justify={justifyContent} align={alignContent} gap={gap} + padding={padding} className={className} {...rest} >