-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
ResponsiveFlex 컴포넌트 구현
- Loading branch information
Showing
7 changed files
with
281 additions
and
3 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
import type { Meta, StoryObj } from '@storybook/react'; | ||
|
||
import { theme } from '../style/theme'; | ||
import styled from 'styled-components'; | ||
|
||
import ResponsiveFlex from '.'; | ||
|
||
const meta: Meta<typeof ResponsiveFlex> = { | ||
component: ResponsiveFlex, | ||
tags: ['autodocs'], | ||
}; | ||
|
||
export default meta; | ||
type Story = StoryObj<typeof ResponsiveFlex>; | ||
|
||
const FirstBox = styled.div` | ||
height: 100px; | ||
border: 1px solid gray; | ||
padding: 10px; | ||
background-color: #b2a592; | ||
`; | ||
|
||
const SecondBox = styled.div` | ||
height: 50px; | ||
border: 1px solid gray; | ||
padding: 10px; | ||
background-color: #d5c8ae; | ||
`; | ||
|
||
export const Default: Story = { | ||
render: () => ( | ||
<ResponsiveFlex breakpoint={theme.breakpoint.sm}> | ||
<FirstBox>FirstBox</FirstBox> | ||
<SecondBox>SecondBox</SecondBox> | ||
</ResponsiveFlex> | ||
), | ||
}; | ||
|
||
export const BreakpointTablet: Story = { | ||
render: () => ( | ||
<ResponsiveFlex breakpoint={theme.breakpoint.md}> | ||
<FirstBox>FirstBox</FirstBox> | ||
<SecondBox>SecondBox</SecondBox> | ||
</ResponsiveFlex> | ||
), | ||
}; | ||
|
||
export const RatioForFirstBoxSeventy: Story = { | ||
render: () => ( | ||
<ResponsiveFlex breakpoint={theme.breakpoint.sm} ratio={70}> | ||
<FirstBox>FirstBox</FirstBox> | ||
<SecondBox>SecondBox</SecondBox> | ||
</ResponsiveFlex> | ||
), | ||
}; | ||
|
||
export const LargeMarginTwentyPixel: Story = { | ||
render: () => ( | ||
<ResponsiveFlex | ||
breakpoint={theme.breakpoint.sm} | ||
ratio={70} | ||
$lgMargin={'20px'} | ||
> | ||
<FirstBox>FirstBox</FirstBox> | ||
<SecondBox>SecondBox</SecondBox> | ||
</ResponsiveFlex> | ||
), | ||
}; | ||
|
||
export const LargePaddingTwentyPixel: Story = { | ||
render: () => ( | ||
<ResponsiveFlex | ||
breakpoint={theme.breakpoint.sm} | ||
ratio={70} | ||
$lgPadding={'20px'} | ||
> | ||
<FirstBox>FirstBox</FirstBox> | ||
<SecondBox>SecondBox</SecondBox> | ||
</ResponsiveFlex> | ||
), | ||
}; | ||
|
||
export const SmallMarginTwentyPixel: Story = { | ||
render: () => ( | ||
<ResponsiveFlex | ||
breakpoint={theme.breakpoint.sm} | ||
ratio={70} | ||
$smMargin={'20px'} | ||
> | ||
<FirstBox>FirstBox</FirstBox> | ||
<SecondBox>SecondBox</SecondBox> | ||
</ResponsiveFlex> | ||
), | ||
}; | ||
|
||
export const SmallPaddingTwentyPixel: Story = { | ||
render: () => ( | ||
<ResponsiveFlex | ||
breakpoint={theme.breakpoint.sm} | ||
ratio={70} | ||
$smPadding={'20px'} | ||
> | ||
<FirstBox>FirstBox</FirstBox> | ||
<SecondBox>SecondBox</SecondBox> | ||
</ResponsiveFlex> | ||
), | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
import { PropsWithChildren, ReactNode } from 'react'; | ||
|
||
import { theme } from '../style/theme'; | ||
import { MarginPadding, StringPixel } from '../types'; | ||
|
||
import * as S from './style'; | ||
|
||
interface ResponsiveFlexProps extends PropsWithChildren { | ||
/** | ||
* breakpoint that arranges children from horizontal to vertical (min-width: breakpoint) | ||
*/ | ||
breakpoint: StringPixel; | ||
/** | ||
* gap between two children when width is less than breakpoint | ||
*/ | ||
$smGap?: StringPixel; | ||
/** | ||
* gap between two children when width is no less than breakpoint | ||
*/ | ||
$lgGap?: StringPixel; | ||
/** | ||
* ratio of left-sided child(first index of children) | ||
* unit is percent (ex. 40%) | ||
* (if 70%, right-sided is automatically 30%) | ||
*/ | ||
ratio?: number; | ||
/** | ||
* margin of Flex when width is less than breakpoint | ||
*/ | ||
$smMargin?: MarginPadding; | ||
/** | ||
* padding of Flex when width is less than breakpoint | ||
*/ | ||
$smPadding?: MarginPadding; | ||
/** | ||
* margin of Flex when width is no less than breakpoint | ||
*/ | ||
$lgMargin?: MarginPadding; | ||
/** | ||
* padding of Flex when width is no less than breakpoint | ||
*/ | ||
$lgPadding?: MarginPadding; | ||
/** | ||
* justify-content of Flex | ||
*/ | ||
$justifyContent?: string; | ||
/** | ||
* align-items of Flex | ||
*/ | ||
$alignItems?: string; | ||
/** | ||
* children of Flex, The number of children should be 2 | ||
*/ | ||
children: [ReactNode, ReactNode]; | ||
} | ||
|
||
export default function ResponsiveFlex({ | ||
breakpoint = theme.breakpoint.sm, | ||
$smGap = '10px', | ||
$lgGap = '10px', | ||
ratio = 50, | ||
$smMargin = '10px', | ||
$smPadding = '10px', | ||
$lgMargin = '10px', | ||
$lgPadding = '10px', | ||
$justifyContent = 'space-between', | ||
$alignItems = 'center', | ||
children, | ||
}: ResponsiveFlexProps) { | ||
if (children.length !== 2) | ||
return <div>ResponsiveFlex component needs two children.</div>; | ||
|
||
return ( | ||
<S.Wrapper | ||
breakpoint={breakpoint} | ||
$smGap={$smGap} | ||
$lgGap={$lgGap} | ||
$smMargin={$smMargin} | ||
$smPadding={$smPadding} | ||
$lgMargin={$lgMargin} | ||
$lgPadding={$lgPadding} | ||
$justifyContent={$justifyContent} | ||
$alignItems={$alignItems} | ||
> | ||
<S.FirstBox breakpoint={breakpoint} ratio={ratio}> | ||
{children[0]} | ||
</S.FirstBox> | ||
<S.SecondBox breakpoint={breakpoint} ratio={100 - ratio}> | ||
{children[1]} | ||
</S.SecondBox> | ||
</S.Wrapper> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
import { styled } from 'styled-components'; | ||
import { MarginPadding, StringPixel } from '../types'; | ||
|
||
interface WrapperProps { | ||
breakpoint: StringPixel; | ||
$smGap: StringPixel; | ||
$lgGap: StringPixel; | ||
$smMargin: MarginPadding; | ||
$smPadding: MarginPadding; | ||
$lgMargin: MarginPadding; | ||
$lgPadding: MarginPadding; | ||
$justifyContent: string; | ||
$alignItems: string; | ||
} | ||
|
||
export const Wrapper = styled.div<WrapperProps>` | ||
display: flex; | ||
flex-direction: column; | ||
justify-content: ${({ $justifyContent }) => $justifyContent}; | ||
align-items: ${({ $alignItems }) => $alignItems}; | ||
gap: ${({ $smGap }) => $smGap}; | ||
width: 100%; | ||
height: 100%; | ||
margin: ${({ $smMargin }) => $smMargin}; | ||
padding: ${({ $smPadding }) => $smPadding}; | ||
overflow-x: hidden; | ||
overflow-y: hidden; | ||
@media (min-width: ${({ breakpoint }) => breakpoint}) { | ||
flex-direction: row; | ||
gap: ${({ $lgGap }) => $lgGap}; | ||
margin: ${({ $lgMargin }) => $lgMargin}; | ||
padding: ${({ $lgPadding }) => $lgPadding}; | ||
overflow-y: auto; | ||
} | ||
`; | ||
|
||
export const FirstBox = styled.div<{ breakpoint: string; ratio: number }>` | ||
width: 100%; | ||
height: ${({ ratio }) => `${ratio}%`}; | ||
@media (min-width: ${({ breakpoint }) => breakpoint}) { | ||
width: ${({ ratio }) => `${ratio}%`}; | ||
height: 100%; | ||
} | ||
`; | ||
|
||
export const SecondBox = styled.div<{ breakpoint: string; ratio: number }>` | ||
width: 100%; | ||
height: ${({ ratio }) => `${ratio}%`}; | ||
@media (min-width: ${({ breakpoint }) => breakpoint}) { | ||
width: ${({ ratio }) => `${ratio}%`}; | ||
height: 100%; | ||
} | ||
`; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,12 @@ | ||
export type Size = 'sm' | 'md' | 'lg'; | ||
|
||
export type StringPixel = `${number}px`; | ||
|
||
export type StringPercent = `${number}%`; | ||
|
||
export type MarginPadding = | ||
| `${number}px` | ||
| `${number}px ${number}px` | ||
| `${number}px ${number}px ${number}px` | ||
| `${number}px ${number}px ${number}px ${number}px` | ||
| 'auto'; |