Skip to content

Commit

Permalink
feat(atoms): add row and column components
Browse files Browse the repository at this point in the history
  • Loading branch information
ej9x committed May 15, 2018
1 parent f6067b7 commit 6bae653
Show file tree
Hide file tree
Showing 4 changed files with 239 additions and 0 deletions.
51 changes: 51 additions & 0 deletions src/atoms/FlexLayout/FlexLayout.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// @flow

import React from 'react';

import { FlexLayoutTag } from './FlexLayout.theme';

type PropLayout = 'start' | 'end' | 'between' | 'around' | 'center'

/**
* @prop {*} justifyContent css justify-content rule
* @prop {*} alignContent css align-content rule
* @prop {*} alignItems css align-items rule
* @prop {*} gap offset between children
* @prop {*} offsetX offset between the container and his parent
* @prop {*} offsetX offset between the container and his parent
* @prop {*} cursor cursor pointer
* @prop {*} stretch if true when stretch the container
* @prop {*} grow set flex-grow: 1
* @prop {*} growChildren set flex-grow: 1 to all children
*/
export type FlexLayoutCommonProps = {|
children: React$Node,
justifyContent?: PropLayout | 'stretch',
alignContent?: PropLayout,
alignItems?: PropLayout | 'stretch',
gap?: PropSizes,
offsetX?: PropSizes,
offsetY?: PropSizes,
cursor?: 'pointer' | 'default' | 'inherit',
stretch?: boolean,
grow?: boolean,
growChildren?: boolean,
|}

type FlexLayoutProps = {
...FlexLayoutCommonProps,
direction?: 'row' | 'column',
}

/** component provides interface to render flex layout */
const FlexLayout = (props: FlexLayoutProps) => {
return <FlexLayoutTag { ...props } tagName="div" />;
};

/** component provides interface to render flex row */
const Row = (props: FlexLayoutCommonProps) => <FlexLayout { ...props } direction="row" />;

/** component provides interface to render flex column */
const Column = (props: FlexLayoutCommonProps) => <FlexLayout { ...props } direction="column" />;

export { Row, Column };
73 changes: 73 additions & 0 deletions src/atoms/FlexLayout/FlexLayout.stories.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
// @flow

import React, { Fragment } from 'react';
import styled from 'react-emotion';

const Block = styled('div')(props => ({
display: 'flex',
minWidth: '100px',
minHeight: '100px',
backgroundColor: props.color,
}));

const Blocks = () => (
<Fragment>
<Block color="chocolate" />
<Block color="red" />
<Block color="orange" />
<Block color="green" />
<Block color="purple" />
</Fragment>
);

export default (asStory: *) => {
asStory('Atoms/FlexLayout', module, (story, { Row, Column }) => {
story
.add('default Row', () => (
<Row>
<Blocks />
</Row>
))
.add('default Column', () => (
<Column>
<Blocks />
</Column>
))
.add('with custom justifyContent', () => (
<Row justifyContent="end">
<Blocks />
</Row>
))
.add('with custom alignContent', () => (
<Column alignItems="stretch">
<Blocks />
</Column>
))
.add('with custom gap', () => (
<Fragment>
<Row gap="md">
<Blocks />
</Row>
<Column gap="md" offsetY="md">
<Blocks />
</Column>
</Fragment>
))
.add('with custom offset', () => (
<Row offsetY="xl" offsetX="xl">
<Blocks />
</Row>
))
.add('with grow children', () => (
<Row growChildren>
<Blocks />
</Row>
))
.add('with pointer cursor', () => (
<Row cursor="pointer">
<Blocks />
</Row>
));
});
};

112 changes: 112 additions & 0 deletions src/atoms/FlexLayout/FlexLayout.theme.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
// @flow

import { createStyledTag } from '../../utils';

const name = 'flex-layout';

const offestSizes = {
none: '0',
xs: '0.25rem',
sm: '0.5rem',
md: '1rem',
lg: '1.5rem',
xl: '2rem',
};

const justifyContentStyles = {
start: 'flex-start',
end: 'flex-end',
center: 'center',
between: 'space-between',
around: 'space-around',
};

const alignContentStyles = {
...justifyContentStyles,
stretch: 'stretch',
};

const alignItemsStyles = {
start: 'flex-start',
end: 'flex-end',
center: 'center',
baseline: 'baseline',
stretch: 'stretch',
};


const gapSizes = {
none: '0',
xs: '.5rem',
sm: '1rem',
md: '1.5rem',
lg: '2rem',
xl: '2.5rem',
};

const getGapStyle = (direction: 'row' | 'column', gapProp: $Keys<typeof gapSizes>) =>
direction === 'row'
? {
'& > *': {
'&:not(:last-child)': {
marginRight: gapSizes[gapProp],
},
},
}
: {
'& > *': {
'&:not(:last-child)': {
marginBottom: gapSizes[gapProp],
},
},
};

const getStretchStyles = (stretchProp: boolean) =>
stretchProp
? { width: '100%', height: '100%' }
: {};

const getGrowChildrenStyles = (growChildren: boolean) =>
growChildren
? {
'& > *': { flexGrow: '1' },
}
: {};

const FlexLayoutTag = createStyledTag(name, props => ({
display: 'flex',

flexDirection: props.direction,

justifyContent: justifyContentStyles[props.justifyContent],
alignContent: alignContentStyles[props.alignContent],
alignItems: alignItemsStyles[props.alignItems],

paddingLeft: offestSizes[props.offsetX],
paddingRight: offestSizes[props.offsetX],
paddingTop: offestSizes[props.offsetY],
paddingBottom: offestSizes[props.offsetY],

cursor: props.cursor,
flexGrow: props.grow && '1',

...getGapStyle(props.direction, props.gap),
...getStretchStyles(props.stretch),
...getGrowChildrenStyles(props.growChildren),
}));

FlexLayoutTag.defaultProps = {
direction: 'row',
justifyContent: 'start',
alignContent: 'start',
alignItems: 'start',
gap: 'none',
offestX: 'none',
offestY: 'none',
cursor: 'inherit',
stretch: false,
grow: false,
growChildren: false,
};

export { FlexLayoutTag };
3 changes: 3 additions & 0 deletions src/atoms/FlexLayout/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// @flow

export { Row, Column } from './FlexLayout';

0 comments on commit 6bae653

Please sign in to comment.