Skip to content

Commit

Permalink
Merge pull request #14 from VoTogether-Design-System/feat/#13
Browse files Browse the repository at this point in the history
ResponsiveFlex 컴포넌트 구현
  • Loading branch information
inyeong-kang authored Oct 18, 2023
2 parents f4e86dd + f7d2835 commit 3d70b90
Show file tree
Hide file tree
Showing 7 changed files with 281 additions and 3 deletions.
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "votogether-design-system",
"private": false,
"version": "0.0.9",
"version": "0.0.14",
"type": "module",
"main": "dist/index.umd.cjs",
"module": "dist/index.js",
Expand Down
111 changes: 111 additions & 0 deletions src/lib/ResponsiveFlex/ResponsiveFlex.stories.tsx
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>
),
};
93 changes: 93 additions & 0 deletions src/lib/ResponsiveFlex/index.tsx
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>
);
}
62 changes: 62 additions & 0 deletions src/lib/ResponsiveFlex/style.ts
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%;
}
`;
1 change: 1 addition & 0 deletions src/lib/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@ export { default as SquareButton } from './SquareButton';
export { default as Skeleton } from './Skeleton';
export { default as ToggleSwitch } from './ToggleSwitch';
export { default as Table } from './Table';
export { default as ResponsiveFlex } from './ResponsiveFlex';
export { default as RoundButton } from './RoundButton';
export { default as VDSProvider } from './VDSProvider';
11 changes: 11 additions & 0 deletions src/lib/types.ts
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';

0 comments on commit 3d70b90

Please sign in to comment.