Commit bdde7afe by Ari Rizzitano Committed by GitHub

Merge pull request #32 from edx/ari/table

table component
parents 6044f81a f62b767c
coverage/*
dist/*
dist
node_modules
......@@ -498,6 +498,358 @@ exports[`Storyshots Paragon Welcome 1`] = `
</div>
`;
exports[`Storyshots Table default heading 1`] = `
<table
className="table"
>
<caption>
Famous Internet Cats
</caption>
<thead
className="thead-default"
>
<tr>
<th
scope="col"
>
Name
</th>
<th
scope="col"
>
Famous For
</th>
<th
scope="col"
>
Coat Color
</th>
</tr>
</thead>
<tbody>
<tr>
<td>
Lil Bub
</td>
<td>
weird tongue
</td>
<td>
brown tabby
</td>
</tr>
<tr>
<td>
Grumpy Cat
</td>
<td>
serving moods
</td>
<td>
siamese
</td>
</tr>
<tr>
<td>
Smoothie
</td>
<td>
modeling
</td>
<td>
orange tabby
</td>
</tr>
<tr>
<td>
Maru
</td>
<td>
being a lovable oaf
</td>
<td>
brown tabby
</td>
</tr>
<tr>
<td>
Keyboard Cat
</td>
<td>
piano virtuoso
</td>
<td>
orange tabby
</td>
</tr>
</tbody>
</table>
`;
exports[`Storyshots Table responsive 1`] = `
<table
className="table table-responsive"
>
<caption>
Famous Internet Cats
</caption>
<thead
className=""
>
<tr>
<th
scope="col"
>
Name
</th>
<th
scope="col"
>
Famous For
</th>
<th
scope="col"
>
Coat Color
</th>
</tr>
</thead>
<tbody>
<tr>
<td>
Lil Bub
</td>
<td>
weird tongue
</td>
<td>
brown tabby
</td>
</tr>
<tr>
<td>
Grumpy Cat
</td>
<td>
serving moods
</td>
<td>
siamese
</td>
</tr>
<tr>
<td>
Smoothie
</td>
<td>
modeling
</td>
<td>
orange tabby
</td>
</tr>
<tr>
<td>
Maru
</td>
<td>
being a lovable oaf
</td>
<td>
brown tabby
</td>
</tr>
<tr>
<td>
Keyboard Cat
</td>
<td>
piano virtuoso
</td>
<td>
orange tabby
</td>
</tr>
</tbody>
</table>
`;
exports[`Storyshots Table table-striped 1`] = `
<table
className="table table-striped"
>
<caption>
Famous Internet Cats
</caption>
<thead
className=""
>
<tr>
<th
scope="col"
>
Name
</th>
<th
scope="col"
>
Famous For
</th>
<th
scope="col"
>
Coat Color
</th>
</tr>
</thead>
<tbody>
<tr>
<td>
Lil Bub
</td>
<td>
weird tongue
</td>
<td>
brown tabby
</td>
</tr>
<tr>
<td>
Grumpy Cat
</td>
<td>
serving moods
</td>
<td>
siamese
</td>
</tr>
<tr>
<td>
Smoothie
</td>
<td>
modeling
</td>
<td>
orange tabby
</td>
</tr>
<tr>
<td>
Maru
</td>
<td>
being a lovable oaf
</td>
<td>
brown tabby
</td>
</tr>
<tr>
<td>
Keyboard Cat
</td>
<td>
piano virtuoso
</td>
<td>
orange tabby
</td>
</tr>
</tbody>
</table>
`;
exports[`Storyshots Table unstyled 1`] = `
<table
className="table"
>
<caption>
Famous Internet Cats
</caption>
<thead
className=""
>
<tr>
<th
scope="col"
>
Name
</th>
<th
scope="col"
>
Famous For
</th>
<th
scope="col"
>
Coat Color
</th>
</tr>
</thead>
<tbody>
<tr>
<td>
Lil Bub
</td>
<td>
weird tongue
</td>
<td>
brown tabby
</td>
</tr>
<tr>
<td>
Grumpy Cat
</td>
<td>
serving moods
</td>
<td>
siamese
</td>
</tr>
<tr>
<td>
Smoothie
</td>
<td>
modeling
</td>
<td>
orange tabby
</td>
</tr>
<tr>
<td>
Maru
</td>
<td>
being a lovable oaf
</td>
<td>
brown tabby
</td>
</tr>
<tr>
<td>
Keyboard Cat
</td>
<td>
piano virtuoso
</td>
<td>
orange tabby
</td>
</tr>
</tbody>
</table>
`;
exports[`Storyshots Tabs basic usage 1`] = `
<div>
<ul
......
# Table
Provides a very basic table component with col-scoped headings displayed in the top row.
## API
### `columns` (object array; required)
`columns` specifies the order and contents of the table's columns and provides display strings for each column's heading. It is composed of an ordered array of objects, each containing a string `key` and a string or element `label`. `label` contains the display string for each column's heading. `key` maps that label to its corresponding datum for each row in `data`, to ensure table data are displayed in their appropriate columns. The order of objects in `columns` specifies the order of the columns in the table.
### `data` (object array; required)
`data` is an array of objects corresponding to the rows to display in the body of your table. The rows will display in the same order as the objects in your array. There are no real restrictions on what these rows can contain, as long as their keys are consistent. The keys are used to organize data from each row into its appropriate column, determined by the corresponding `key` property specified in each object in `columns`.
### `caption` (string or element; optional)
Specifies a descriptive caption to be applied to the entire table.
### `className` (string array; optional)
Specifies Bootstrap class names to apply to the table. See [Bootstrap's table documentation](https://getbootstrap.com/docs/4.0/content/tables/) for a list of applicable class names.
### `headingClassName` (string array; optional)
Specifies Bootstrap class names to apply to the table heading. Options are detailed in [Bootstrap's docs](https://getbootstrap.com/docs/4.0/content/tables/#table-head-options)
@import "~bootstrap/scss/_tables";
import React from 'react';
import { storiesOf } from '@storybook/react';
import Table from './index';
const catData = [
{
name: 'Lil Bub',
color: 'brown tabby',
famous_for: 'weird tongue',
},
{
name: 'Grumpy Cat',
color: 'siamese',
famous_for: 'serving moods',
},
{
name: 'Smoothie',
color: 'orange tabby',
famous_for: 'modeling',
},
{
name: 'Maru',
color: 'brown tabby',
famous_for: 'being a lovable oaf',
},
{
name: 'Keyboard Cat',
color: 'orange tabby',
famous_for: 'piano virtuoso',
},
];
const catColumns = [
{
label: 'Name',
key: 'name',
},
{
label: 'Famous For',
key: 'famous_for',
},
{
label: 'Coat Color',
key: 'color',
},
];
storiesOf('Table', module)
.add('unstyled', () => (
<Table
data={catData}
columns={catColumns}
caption="Famous Internet Cats"
/>
))
.add('table-striped', () => (
<Table
data={catData}
columns={catColumns}
caption="Famous Internet Cats"
className={['table-striped']}
/>
))
.add('default heading', () => (
<Table
data={catData}
columns={catColumns}
caption="Famous Internet Cats"
headingClassName={['thead-default']}
/>
))
.add('responsive', () => (
<Table
data={catData}
columns={catColumns}
caption="Famous Internet Cats"
className={['table-responsive']}
/>
));
/* eslint-disable import/no-extraneous-dependencies */
import React from 'react';
import { shallow } from 'enzyme';
import Table from './index';
const props = {
columns: [
{ key: 'num', label: 'Number' },
{ key: 'x2', label: 'Number * 2' },
{ key: 'sq', label: 'Number Squared' },
],
data: [
{ sq: 1, num: 1, x2: 2 },
{ sq: 4, num: 2, x2: 4 },
{ sq: 9, num: 3, x2: 6 },
],
};
describe('<Table />', () => {
describe('renders', () => {
const wrapper = shallow(
<Table
{...props}
/>,
);
it('with display columns in the right order', () => {
wrapper.find('th').forEach((th, i) => {
expect(th.text()).toEqual(props.columns[i].label);
});
});
it('with data in the same order as the columns', () => {
wrapper.find('tr').at(1).find('td').forEach((td, i) => {
expect(Number(td.text())).toEqual(props.data[0][props.columns[i].key]);
});
});
});
});
import React from 'react';
import classNames from 'classnames';
import PropTypes from 'prop-types';
import styles from './Table.scss';
class Table extends React.Component {
getCaption() {
return this.props.caption && (
<caption>{this.props.caption}</caption>
);
}
getHeadings() {
return (
<thead className={classNames(
...this.props.headingClassName.map(className => styles[className]),
)}
>
<tr>
{this.props.columns.map(col => (
<th
key={col.key}
scope="col"
>
{col.label}
</th>
))}
</tr>
</thead>
);
}
getBody() {
return (
<tbody>
{this.props.data.map((row, i) => (
<tr key={i}>
{this.props.columns.map(col => (
<td key={col.key}>{row[col.key]}</td>
))}
</tr>
))}
</tbody>
);
}
render() {
return (
<table className={classNames(
styles.table,
...this.props.className.map(className => styles[className]),
)}
>
{this.getCaption()}
{this.getHeadings()}
{this.getBody()}
</table>
);
}
}
Table.propTypes = {
caption: PropTypes.oneOfType([
PropTypes.string,
PropTypes.element,
]),
className: PropTypes.arrayOf(PropTypes.string),
data: PropTypes.arrayOf(PropTypes.object).isRequired,
columns: PropTypes.arrayOf(PropTypes.shape({
key: PropTypes.string.isRequired,
label: PropTypes.oneOfType([
PropTypes.string,
PropTypes.element,
]).isRequired,
})).isRequired,
headingClassName: PropTypes.arrayOf(PropTypes.string),
};
Table.defaultProps = {
caption: null,
className: [],
headingClassName: [],
};
export default Table;
......@@ -2620,20 +2620,13 @@ domhandler@^2.3.0:
dependencies:
domelementtype "1"
domutils@1.5.1:
domutils@1.5.1, domutils@^1.5.1:
version "1.5.1"
resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.5.1.tgz#dcd8488a26f563d61079e48c9f7b7e32373682cf"
dependencies:
dom-serializer "0"
domelementtype "1"
domutils@^1.5.1:
version "1.6.2"
resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.6.2.tgz#1958cc0b4c9426e9ed367fb1c8e854891b0fa3ff"
dependencies:
dom-serializer "0"
domelementtype "1"
dot-prop@^4.1.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-4.2.0.tgz#1f19e0c2e1aa0e32797c49799f2837ac6af69c57"
......@@ -5009,14 +5002,10 @@ mime@1.3.4:
version "1.3.4"
resolved "https://registry.yarnpkg.com/mime/-/mime-1.3.4.tgz#115f9e3b6b3daf2959983cb38f149a2d40eb5d53"
mime@1.3.x:
mime@1.3.x, mime@^1.3.4:
version "1.3.6"
resolved "https://registry.yarnpkg.com/mime/-/mime-1.3.6.tgz#591d84d3653a6b0b4a3b9df8de5aa8108e72e5e0"
mime@^1.3.4:
version "1.4.0"
resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.0.tgz#69e9e0db51d44f2a3b56e48b7817d7d137f1a343"
mimic-fn@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.1.0.tgz#e667783d92e89dbd342818b5230b9d62a672ad18"
......@@ -5041,7 +5030,7 @@ minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4, minimatc
dependencies:
brace-expansion "^1.1.7"
minimist@0.0.8:
minimist@0.0.8, minimist@~0.0.1:
version "0.0.8"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d"
......@@ -5049,10 +5038,6 @@ minimist@1.2.0, minimist@^1.1.1, minimist@^1.1.3, minimist@^1.2.0, minimist@~1.2
version "1.2.0"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284"
minimist@~0.0.1:
version "0.0.10"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf"
mixin-object@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/mixin-object/-/mixin-object-2.0.1.tgz#4fb949441dab182540f1fe035ba60e1947a5e57e"
......@@ -7626,14 +7611,10 @@ window-size@0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.0.tgz#5438cd2ea93b202efa3a19fe8887aee7c94f9c9d"
wordwrap@0.0.2:
wordwrap@0.0.2, wordwrap@~0.0.2:
version "0.0.2"
resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f"
wordwrap@~0.0.2:
version "0.0.3"
resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107"
wordwrap@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment