-
Notifications
You must be signed in to change notification settings - Fork 47
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #739 from inhibitor1217/features/stack
Stack 컴포넌트군 추가
- Loading branch information
Showing
26 changed files
with
846 additions
and
0 deletions.
There are no files selected for viewing
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,19 @@ | ||
/* External dependencies */ | ||
import React, { forwardRef } from 'react' | ||
import type { Ref } from 'react' | ||
|
||
/* Internal dependencies */ | ||
import { Stack } from 'Components/Stack/Stack' | ||
import type HStackProps from './HStack.types' | ||
|
||
/** | ||
* A container for horizontal flex layout. | ||
*/ | ||
function HStack( | ||
props: HStackProps, | ||
forwardedRef: Ref<HTMLElement>, | ||
) { | ||
return (<Stack ref={forwardedRef} direction="horizontal" {...props} />) | ||
} | ||
|
||
export default forwardRef(HStack) |
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,4 @@ | ||
/* Internal dependencies */ | ||
import type { StackProps } from 'Components/Stack/Stack' | ||
|
||
export default interface HStackProps extends Omit<StackProps, 'direction'> {} |
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,2 @@ | ||
export { default as HStack } from './HStack' | ||
export type { default as HStackProps } from './HStack.types' |
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,25 @@ | ||
/* External dependencies */ | ||
import React, { forwardRef } from 'react' | ||
import type { Ref } from 'react' | ||
|
||
/* Internal dependencies */ | ||
import { StackItem } from 'Components/Stack/StackItem' | ||
import type SpacerProps from './Spacer.types' | ||
|
||
function Spacer( | ||
props: SpacerProps, | ||
forwardedRef: Ref<HTMLElement>, | ||
) { | ||
return ( | ||
<StackItem | ||
ref={forwardedRef} | ||
size={0} | ||
weight={1} | ||
grow | ||
shrink | ||
{...props} | ||
/> | ||
) | ||
} | ||
|
||
export default forwardRef(Spacer) |
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,5 @@ | ||
/* Internal dependencies */ | ||
import type { BezierComponentProps } from 'Types/ComponentProps' | ||
|
||
export default interface SpacerProps extends | ||
BezierComponentProps {} |
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,2 @@ | ||
export { default as Spacer } from './Spacer' | ||
export type { default as SpacerProps } from './Spacer.types' |
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,182 @@ | ||
/* External dependencies */ | ||
import React, { useState } from 'react' | ||
import type { | ||
Meta, | ||
Story, | ||
} from '@storybook/react' | ||
import base from 'paths.macro' | ||
import { | ||
keys, | ||
random, | ||
range, | ||
values, | ||
} from 'lodash-es' | ||
|
||
/* Internal dependencies */ | ||
import type { SemanticNames } from 'Foundation' | ||
import { LightTheme } from 'Foundation/Colors/Theme' | ||
import { getTitle } from 'Utils/storyUtils' | ||
import { Stack } from './Stack' | ||
import { StackItem } from './StackItem' | ||
import type { AxisAlignment } from './types' | ||
|
||
export default { | ||
title: getTitle(base), | ||
argTypes: { | ||
containerSize: { | ||
control: { | ||
type: 'range', | ||
min: 400, | ||
max: 1200, | ||
step: 10, | ||
}, | ||
}, | ||
direction: { | ||
control: { | ||
type: 'radio', | ||
options: ['horizontal', 'vertical'], | ||
}, | ||
}, | ||
justify: { | ||
control: { | ||
type: 'radio', | ||
options: ['start', 'center', 'end', 'stretch'], | ||
}, | ||
}, | ||
align: { | ||
control: { | ||
type: 'radio', | ||
options: ['start', 'center', 'end', 'stretch'], | ||
}, | ||
}, | ||
spacing: { | ||
control: { | ||
type: 'range', | ||
min: 0, | ||
max: 32, | ||
step: 4, | ||
}, | ||
}, | ||
}, | ||
} as Meta | ||
|
||
const randomColor = (): SemanticNames => values(LightTheme)[random(keys(LightTheme).length)] as SemanticNames | ||
const randomSize = (): number => Math.floor((random(true) * 240) + 120) | ||
|
||
const Item = ({ | ||
fixedSize, | ||
direction, | ||
}: { | ||
fixedSize: boolean | ||
direction: 'horizontal' | 'vertical' | ||
}) => { | ||
const [color] = useState(() => randomColor()) | ||
const [alignSize] = useState(() => randomSize()) | ||
|
||
return ( | ||
<div | ||
style={{ | ||
width: (fixedSize && direction === 'vertical') ? alignSize : '100%', | ||
height: (fixedSize && direction === 'horizontal') ? alignSize : '100%', | ||
backgroundColor: color, | ||
borderRadius: '4px', | ||
boxShadow: 'inset 0 0 1px #c0c0c0', | ||
}} | ||
/> | ||
) | ||
} | ||
|
||
interface StackPreviewProps { | ||
containerSize: number | ||
|
||
/* Stack Props */ | ||
direction: 'horizontal' | 'vertical' | ||
justify: AxisAlignment | ||
align: AxisAlignment | ||
spacing: number | ||
|
||
/* Item Props */ | ||
itemJustifies: (AxisAlignment | undefined)[] | ||
itemAligns: (AxisAlignment | undefined)[] | ||
itemSizes: (number | undefined)[] | ||
itemWeights: (number | undefined)[] | ||
itemGrows: (boolean | undefined)[] | ||
itemShrinks: (boolean | undefined)[] | ||
itemMarginBefores: (number | undefined)[] | ||
itemMarginAfters: (number | undefined)[] | ||
} | ||
|
||
const Template: Story<StackPreviewProps> = ({ | ||
containerSize, | ||
|
||
direction, | ||
justify, | ||
align, | ||
spacing, | ||
|
||
itemJustifies, | ||
itemAligns, | ||
itemSizes, | ||
itemWeights, | ||
itemGrows, | ||
itemShrinks, | ||
itemMarginBefores, | ||
itemMarginAfters, | ||
}: StackPreviewProps) => ( | ||
<> | ||
<div | ||
style={{ | ||
border: '1px solid #e0e0e0', | ||
borderRadius: 4, | ||
...( | ||
direction === 'horizontal' | ||
? { width: containerSize, height: 480 } | ||
: { width: 480, height: containerSize } | ||
), | ||
}} | ||
> | ||
<Stack | ||
direction={direction} | ||
justify={justify} | ||
align={align} | ||
spacing={spacing} | ||
> | ||
{ range(4) | ||
.map(i => ( | ||
<StackItem | ||
key={`item-${i}`} | ||
justify={itemJustifies[i]} | ||
align={itemAligns[i]} | ||
size={itemSizes[i]} | ||
weight={itemWeights[i]} | ||
grow={itemGrows[i]} | ||
shrink={itemShrinks[i]} | ||
marginBefore={itemMarginBefores[i]} | ||
marginAfter={itemMarginAfters[i]} | ||
> | ||
<Item direction={direction} fixedSize={(align ?? itemAligns[i]) !== 'stretch'} /> | ||
</StackItem> | ||
)) } | ||
</Stack> | ||
</div> | ||
</> | ||
) | ||
|
||
export const Primary: Story<StackPreviewProps> = Template.bind({}) | ||
Primary.args = { | ||
containerSize: 800, | ||
|
||
direction: 'horizontal', | ||
justify: 'start', | ||
align: 'start', | ||
spacing: 0, | ||
|
||
itemJustifies: [], | ||
itemAligns: [], | ||
itemSizes: [120, 240, 180, 120], | ||
itemWeights: [], | ||
itemGrows: [], | ||
itemShrinks: [], | ||
itemMarginBefores: [], | ||
itemMarginAfters: [], | ||
} |
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,30 @@ | ||
/* Internal dependencies */ | ||
import { | ||
css, | ||
styled, | ||
} from 'Foundation' | ||
import { flex } from 'Components/Stack/util' | ||
import type StackProps from './Stack.types' | ||
|
||
interface ContainerProps extends | ||
Required<Pick<StackProps, 'interpolation' | 'direction' | 'justify' | 'align'>> {} | ||
|
||
export const Container = styled.div<ContainerProps>` | ||
display: flex; | ||
width: 100%; | ||
height: 100%; | ||
${({ direction }) => css` | ||
flex-direction: ${direction === 'horizontal' ? 'row' : 'column'}; | ||
`} | ||
${({ justify }) => css` | ||
justify-content: ${flex(justify)}; | ||
`} | ||
${({ align }) => css` | ||
align-items: ${flex(align)}; | ||
`} | ||
${({ interpolation }) => interpolation} | ||
` |
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,55 @@ | ||
/* External dependencies */ | ||
import React from 'react' | ||
|
||
/* Internal dependencies */ | ||
import { css } from 'Foundation' | ||
import { render } from 'Utils/testUtils' | ||
import Stack from './Stack' | ||
|
||
describe('Stack', () => { | ||
describe('Flex layout', () => { | ||
it('creates a flexbox', () => { | ||
const { getByTestId } = render(<Stack direction="horizontal" testId="stack" />) | ||
|
||
expect(getByTestId('stack')).toHaveStyle('display: flex') | ||
}) | ||
|
||
it('creates a horizontal flexbox when given direction="horizontal"', () => { | ||
const { getByTestId } = render(<Stack direction="horizontal" testId="stack" />) | ||
|
||
expect(getByTestId('stack')).toHaveStyle('flex-direction: row') | ||
}) | ||
|
||
it('creates a vertical flexbox when given direction="vertical"', () => { | ||
const { getByTestId } = render(<Stack direction="vertical" testId="stack" />) | ||
|
||
expect(getByTestId('stack')).toHaveStyle('flex-direction: column') | ||
}) | ||
}) | ||
|
||
describe('Supports BezierComponentProps interface', () => { | ||
it('supports as prop', () => { | ||
const { getByTestId } = render(<Stack direction="horizontal" testId="stack" as="main" />) | ||
|
||
expect(getByTestId('stack').tagName).toBe('MAIN') | ||
}) | ||
|
||
it('supports style prop', () => { | ||
const { getByTestId } = render(<Stack direction="horizontal" testId="stack" style={{ backgroundColor: 'red' }} />) | ||
|
||
expect(getByTestId('stack')).toHaveStyle({ 'background-color': 'red' }) | ||
}) | ||
|
||
it('supports className prop', () => { | ||
const { getByTestId } = render(<Stack direction="horizontal" testId="stack" className="foo" />) | ||
|
||
expect(getByTestId('stack')).toHaveClass('foo') | ||
}) | ||
|
||
it('supports interpolation prop', () => { | ||
const { getByTestId } = render(<Stack direction="horizontal" testId="stack" interpolation={css`background-color: red;`} />) | ||
|
||
expect(getByTestId('stack')).toHaveStyle({ 'background-color': 'red' }) | ||
}) | ||
}) | ||
}) |
Oops, something went wrong.