Skip to content

Commit

Permalink
Merge pull request #69 from iCHEF/feature/zhusee_containers
Browse files Browse the repository at this point in the history
Containers: Header and List
  • Loading branch information
zhusee2 authored Jul 7, 2017
2 parents 05557b8 + 52e1b2e commit 8bc62f2
Show file tree
Hide file tree
Showing 28 changed files with 590 additions and 11 deletions.
7 changes: 6 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,12 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

## [Unreleased]
### Added
- N/A
- Add `<HeaderRow>` which is split into `left`, `center` and `right` tiers.
- Add `<List>` section that supports a title and a description block.
- Add simple `<ListRow>` with a Flexbox body for row components.

### Changed
- Improved tests coverage


## [0.13.1]
Expand Down
9 changes: 6 additions & 3 deletions examples/DebugBox.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,16 @@ const defaultBoxStyle = {
position: 'relative',
};

function DebugBox({ width, height, children }) {
const style = {
function DebugBox({ width, height, style, children }) {
const boxStyle = {
...defaultBoxStyle,
width,
height,
...style,
};

return (
<div style={style}>
<div style={boxStyle}>
{children}
</div>
);
Expand All @@ -30,11 +31,13 @@ DebugBox.propTypes = {
PropTypes.number,
PropTypes.string
]),
style: PropTypes.object, // eslint-disable-line react/forbid-prop-types
};

DebugBox.defaultProps = {
width: '20rem',
height: 'auto',
style: {},
};

export default DebugBox;
31 changes: 31 additions & 0 deletions examples/HeaderRow/BasicUsage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import React from 'react';

import HeaderRow from 'src/HeaderRow';
import Button from 'src/Button';
import TextLabel from 'src/TextLabel';
import TextEllipsis from 'src/TextEllipsis';

import DebugBox from '../DebugBox';

function BasicUsage() {
const leftBtn = <Button icon="prev" basic="Back" />;
const rightBtn = <Button basic="Save" />;
const centerLabel = (
<TextLabel
align="center"
basic={
<TextEllipsis>Lorem ipsum a slightly longer title</TextEllipsis>
} />
);

return (
<DebugBox>
<HeaderRow
left={leftBtn}
center={centerLabel}
right={rightBtn} />
</DebugBox>
);
}

export default BasicUsage;
12 changes: 12 additions & 0 deletions examples/HeaderRow/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import React from 'react';
import { storiesOf } from '@storybook/react';

// For props table
import HeaderRow from 'src/HeaderRow';

import BasicUsage from './BasicUsage';

storiesOf('HeaderRow', module)
.addWithInfo('Basic usage', BasicUsage)
// Props table
.addPropsTable(() => <HeaderRow />);
31 changes: 31 additions & 0 deletions examples/List/NormalList.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import React from 'react';

import List from 'src/List';
import ListRow from 'src/ListRow';

import Button from 'src/Button';
import TextLabel from 'src/TextLabel';

import DebugBox from '../DebugBox';

function NormalList() {
return (
<DebugBox width="30rem">
<List variant="normal" title="List title" desc="Help text here">
<ListRow>
<TextLabel icon="tickets" basic="Hello World" />
</ListRow>
<ListRow>
<TextLabel icon="tickets" basic="Row 2" />
</ListRow>
<ListRow>
<Button
icon="add"
basic="Add row" />
</ListRow>
</List>
</DebugBox>
);
}

export default NormalList;
35 changes: 35 additions & 0 deletions examples/List/SettingList.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import React from 'react';

import List from 'src/List';
import ListRow from 'src/ListRow';

import Button from 'src/Button';
import Icon from 'src/Icon';
import TextLabel from 'src/TextLabel';
import TextInput from 'src/TextInput';

import DebugBox from '../DebugBox';

function SettingList() {
return (
<DebugBox width="30rem" style={{ padding: '0 1rem' }}>
<List variant="setting" title="List title" desc="Help text here">
<ListRow>
<TextLabel basic="Hello World" />
</ListRow>
<ListRow>
<TextLabel basic="Row 2" />
<TextInput value="Value" />
<Icon type="row-padding" />
</ListRow>
<ListRow>
<Button
icon="add"
basic="Add row" />
</ListRow>
</List>
</DebugBox>
);
}

export default SettingList;
15 changes: 15 additions & 0 deletions examples/List/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import React from 'react';
import { storiesOf } from '@storybook/react';

// For props table
import List from 'src/List';
import ListRow from 'src/ListRow';

import NormalList from './NormalList';
import SettingList from './SettingList';

storiesOf('List', module)
.addWithInfo('Normal list', NormalList)
.addWithInfo('Setting list', SettingList)
// Props table
.addPropsTable(() => <List />, [ListRow]);
54 changes: 54 additions & 0 deletions src/HeaderRow.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// @flow
import React from 'react';
import classNames from 'classnames';
import type { ReactChildren } from 'react-flow-types';
import './styles/BasicRow.scss';

import prefixClass from './utils/prefixClass';
import icBEM from './utils/icBEM';

export const COMPONENT_NAME = prefixClass('header-row');
const ROOT_BEM = icBEM(COMPONENT_NAME);
export const BEM = {
root: ROOT_BEM,
left: ROOT_BEM.element('left'),
center: ROOT_BEM.element('center'),
right: ROOT_BEM.element('right'),
};

export type Props = {
left?: ReactChildren,
center?: ReactChildren,
right?: ReactChildren,
className?: string, // eslint-disable-line react/require-default-props
};

function HeaderRow({
left,
center,
right,
// React props
className,
...otherProps,
}: Props) {
const rootClassName = classNames(
BEM.root.toString(),
className,
);

return (
<div className={rootClassName} {...otherProps}>
<div className={BEM.left}>{left}</div>
<div className={BEM.center}>{center}</div>
<div className={BEM.right}>{right}</div>
</div>
);
}

HeaderRow.defaultProps = {
left: undefined,
center: undefined,
right: undefined,
};

export default HeaderRow;
74 changes: 74 additions & 0 deletions src/List.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
// @flow
import React from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import type { ReactChildren } from 'react-flow-types';
import './styles/List.scss';

import prefixClass from './utils/prefixClass';
import icBEM from './utils/icBEM';

export const COMPONENT_NAME = prefixClass('list');
const ROOT_BEM = icBEM(COMPONENT_NAME);
export const BEM = {
root: ROOT_BEM,
title: ROOT_BEM.element('title'),
body: ROOT_BEM.element('body'),
desc: ROOT_BEM.element('desc'),
};

const NORMAL = 'normal';
const SETTING = 'setting';
const BUTTON = 'button';
const LIST_VARIANTS = [NORMAL, SETTING, BUTTON];

export type Props = {
variant: typeof NORMAL | typeof SETTING | typeof BUTTON,
title?: string,
desc?: ReactChildren,

/* eslint-disable react/require-default-props */
className?: string,
children?: ReactChildren,
/* eslint-enable react/require-default-props */
};

function List({
variant,
title,
desc,
// React props
className,
children,
...otherProps,
}: Props) {
const bemClass = BEM.root.modifier(variant);
const rootClassName = classNames(bemClass.toString(), className);

const titleNode = <div className={BEM.title.toString()}>{title}</div>;
const descNode = <div className={BEM.desc.toString()}>{desc}</div>;

return (
<div className={rootClassName} {...otherProps}>
{title && titleNode}
<ul className={BEM.body.toString()}>
{children}
</ul>
{desc && descNode}
</div>
);
}

List.propTypes = {
variant: PropTypes.oneOf(Object.values(LIST_VARIANTS)),
title: PropTypes.string,
desc: PropTypes.node,
};

List.defaultProps = {
variant: NORMAL,
title: undefined,
desc: undefined,
};

export default List;
58 changes: 58 additions & 0 deletions src/ListRow.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// @flow
import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import type { ReactChildren } from 'react-flow-types';
import './styles/ListRow.scss';

import prefixClass from './utils/prefixClass';
import icBEM from './utils/icBEM';

export const COMPONENT_NAME = prefixClass('list-row');
const ROOT_BEM = icBEM(COMPONENT_NAME);
export const BEM = {
root: ROOT_BEM,
body: ROOT_BEM.element('body'),
};

export type Props = {
nestedList?: ReactChildren,
/* eslint-disable react/require-default-props */
className?: string,
children?: ReactChildren,
/* eslint-enable react/require-default-props */
};

class ListRow extends PureComponent<Props, Props, any> {
static propTypes = {
nestedList: PropTypes.node,
};

static defaultProps = {
nestedList: undefined,
};

render() {
const {
nestedList,
// React props
className,
children,
...wrapperProps,
} = this.props;

const bemClass = BEM.root;
const rootClassName = classNames(bemClass.toString(), className);

return (
<li className={rootClassName} {...wrapperProps}>
<div className={BEM.body.toString()}>
{children}
</div>
{nestedList}
</li>
);
}
}

export default ListRow;
2 changes: 1 addition & 1 deletion src/TextEllipsis.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const ROOT_BEM = icBEM(COMPONENT_NAME);

function TextEllipsis({ children }) {
return (
<div className={ROOT_BEM}>
<div className={ROOT_BEM} title={children}>
{children}
</div>
);
Expand Down
11 changes: 11 additions & 0 deletions src/__tests__/HeaderRow.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import React from 'react';
import ReactDOM from 'react-dom';

import HeaderRow from '../HeaderRow';

it('renders without crashing', () => {
const div = document.createElement('div');
const element = <HeaderRow left="Left" center="Title" right="Right" />;

ReactDOM.render(element, div);
});
Loading

0 comments on commit 8bc62f2

Please sign in to comment.