Skip to content

Commit 404d9b4

Browse files
authored
Merge pull request #71 from jbetancur/feature-subheader-1
implement optional subheader
2 parents 61e6915 + bbe7273 commit 404d9b4

13 files changed

Lines changed: 1050 additions & 81 deletions

README.md

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,9 +87,9 @@ Nothing new here - we are using an array of object literals and properties to de
8787
| striped | bool | no | false | stripe color the odd rows |
8888
| highlightOnHover | bool | no | false | if rows are to be highlighted on hover |
8989
| pointerOnHover | bool | no | false | if rows show a point icon on hover |
90-
| actions | array of components | no | | add actions to the TableHeader |
90+
| actions | component or array of components | no | | add actions to the TableHeader |
9191
| contextTitle | string | no | | override the context menu title |
92-
| contextActions | array of components | no | | add context action as an array of components |
92+
| contextActions | component or array of components| no | | add context actions to the TableHeader context|
9393
| onTableUpdate | func | no | | callback to access the entire Data Table state ({ allSelected, selectedCount, selectedRows, sortColumn, sortDirection, rows }) |
9494
| onRowClicked | func | no | | callback to access the row data,index on row click |
9595
| clearSelectedRows | bool | no | false | toggling this property clears the selectedRows. If you use redux or react state you need to make sure that you pass a toggled value or the component will not update. See [Clearing Selected Rows](#clearing-selected-rows)|
@@ -114,7 +114,12 @@ Nothing new here - we are using an array of object literals and properties to de
114114
| paginationIconLastPage | | no | JSX | a component that overrides the last page icon for the pagination |
115115
| paginationIconNext | | no | JSX | a component that overrides the next page icon for the pagination |
116116
| paginationIconPrevious | | no | JSX | a component that overrides the previous page icon for the pagination |
117-
117+
| subHeader | component or array of components | no | false | show a subheader between the table and table header
118+
| subHeaderAlign | string | no | right | align the subheader content (left, right, center)
119+
| subHeaderWrap | bool | no | true | whether the subheader content should wrap
120+
| subHeader | component or array of components | no | false | show a subheader between the table and table header
121+
| subHeaderComponent | component or array of components | no | [] | a component you want to render |
122+
118123
#### Advanced Selectable Component Options
119124
Sometimes 3rd party checkbox components have their own way of handling indeterminate state. We don't want React Data Table hardcoded to a specific ui lib or custom component, so instead a "hook" is provided to allow you to pass a function that will be resolved by React Data Table's internal `Checkbox` for use with `indeterminate` functionality.
120125

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "react-data-table-component",
3-
"version": "1.4.0",
3+
"version": "1.4.1",
44
"description": "A declarative react based data table",
55
"main": "dist/index.cjs.js",
66
"module": "dist/index.es.js",

src/DataTable/DataTable.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import TableRow from './TableRow';
1212
import TableCol from './TableCol';
1313
import TableColCheckbox from './TableColCheckbox';
1414
import TableHeader from './TableHeader';
15+
import TableSubheader from './TableSubheader';
1516
import TableBody from './TableBody';
1617
import ResponsiveWrapper from './ResponsiveWrapper';
1718
import ProgressWrapper from './ProgressWrapper';
@@ -216,6 +217,10 @@ class DataTable extends Component {
216217
pagination,
217218
selectableRows,
218219
expandableRows,
220+
subHeader,
221+
subHeaderAlign,
222+
subHeaderWrap,
223+
subHeaderComponent,
219224
} = this.props;
220225

221226
const {
@@ -250,6 +255,14 @@ class DataTable extends Component {
250255
/>
251256
)}
252257

258+
{subHeader && (
259+
<TableSubheader
260+
align={subHeaderAlign}
261+
wrapContent={subHeaderWrap}
262+
component={subHeaderComponent}
263+
/>
264+
)}
265+
253266
<TableWrapper>
254267
{progressPending && (
255268
<ProgressWrapper

src/DataTable/TableHeader.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ const TableHeaderStyle = styled.header`
1414
min-height: 64px;
1515
width: 100%;
1616
background-color: ${props => props.theme.title.backgroundColor};
17+
flex-wrap: wrap;
1718
`;
1819

1920
const Title = styled.div`
@@ -26,8 +27,8 @@ const Title = styled.div`
2627
const Actions = styled.div`
2728
flex: 1 0 auto;
2829
display: flex;
29-
justify-content: flex-end;
3030
align-items: center;
31+
justify-content: flex-end;
3132
3233
> * {
3334
margin-left: 5px;

src/DataTable/TableSubheader.js

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import React from 'react';
2+
import PropTypes from 'prop-types';
3+
import styled from 'styled-components';
4+
5+
const alignMap = {
6+
left: 'flex-start',
7+
right: 'flex-end',
8+
center: 'center',
9+
};
10+
11+
const SubheaderWrapper = styled.header`
12+
position: relative;
13+
display: flex;
14+
flex: 1 1 auto;
15+
align-items: center;
16+
padding: 0 16px 0 24px;
17+
min-height: 48px;
18+
width: 100%;
19+
background-color: ${props => props.theme.title.backgroundColor};
20+
justify-content: ${props => alignMap[props.align]};
21+
flex-wrap: ${props => (props.wrapContent ? 'wrap' : 'nowrap')};
22+
`;
23+
24+
const TableSubheader = ({ align, wrapContent, component }) => (
25+
<SubheaderWrapper align={align} wrapContent={wrapContent}>
26+
{component}
27+
</SubheaderWrapper>
28+
);
29+
30+
TableSubheader.propTypes = {
31+
component: PropTypes.oneOfType([
32+
PropTypes.arrayOf(PropTypes.node),
33+
PropTypes.node,
34+
PropTypes.string,
35+
]),
36+
align: PropTypes.oneOf(['center', 'left', 'right']),
37+
wrapContent: PropTypes.bool,
38+
};
39+
40+
TableSubheader.defaultProps = {
41+
component: null,
42+
align: 'right',
43+
wrapContent: true,
44+
};
45+
46+
export default TableSubheader;

src/DataTable/__tests__/DataTable.test.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,3 +309,19 @@ describe('Pagination', () => {
309309
expect(onChangeRowsPerPageMock).toBeCalledWith(20);
310310
});
311311
});
312+
313+
describe('Subheader', () => {
314+
test('should render correctly when a subheader is enabled', () => {
315+
const mock = dataMock();
316+
const { container } = render(
317+
<DataTable
318+
data={mock.data}
319+
columns={mock.columns}
320+
subheader
321+
subheaderComponent={<div />}
322+
/>,
323+
);
324+
325+
expect(container.firstChild).toMatchSnapshot();
326+
});
327+
});

src/DataTable/__tests__/TableHeader.test.js

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,26 @@ import TableHeader from '../TableHeader';
66

77
afterEach(cleanup);
88

9-
test('<TableHeader title showContextMenu /> should render correctly', () => {
10-
const { container } = renderWithTheme(<TableHeader title="whoa!" showContextMenu />);
9+
test('<TableHeader title showContextMenu should render correctly', () => {
10+
const { container } = renderWithTheme(<TableHeader title="whoa!" />);
1111

1212
expect(container.firstChild).toMatchSnapshot();
1313
});
1414

15-
test('<TableHeader title contextTitle /> should render correctly', () => {
15+
test('<TableHeader title contextTitle should render correctly', () => {
1616
const { container } = renderWithTheme(<TableHeader title="whoa!" contextTitle="items!!!" />);
1717

1818
expect(container.firstChild).toMatchSnapshot();
1919
});
2020

21-
test('<TableHeader title contextActions /> should render correctly', () => {
22-
const { container } = renderWithTheme(<TableHeader title="whoa!" contextActions={[<div>some action</div>]} />);
21+
test('<TableHeader with actions should render correctly', () => {
22+
const { container } = renderWithTheme(<TableHeader title="whoa!" actions={<><div>some action</div>, <div>some action 2</div></>} />);
23+
24+
expect(container.firstChild).toMatchSnapshot();
25+
});
26+
27+
test('<TableHeader with showContextMenu/contextActions should render correctly', () => {
28+
const { container } = renderWithTheme(<TableHeader title="whoa!" showContextMenu contextActions={<><div>some action</div>, <div>some action 2</div></>} />);
2329

2430
expect(container.firstChild).toMatchSnapshot();
2531
});
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import 'jest-styled-components';
2+
import React from 'react';
3+
import { cleanup } from 'react-testing-library';
4+
import { renderWithTheme } from '../../test-helpers';
5+
import TableSubheader from '../TableSubheader';
6+
7+
afterEach(cleanup);
8+
9+
test('<TableSubheader defaults should render correctly', () => {
10+
const { container } = renderWithTheme(<TableSubheader />);
11+
12+
expect(container.firstChild).toMatchSnapshot();
13+
});
14+
15+
test('<TableSubheader with component should render correctly', () => {
16+
const { container } = renderWithTheme(<TableSubheader component={<div />} />);
17+
18+
expect(container.firstChild).toMatchSnapshot();
19+
});
20+
21+
test('<TableSubheader with component should render when wrap is false', () => {
22+
const { container } = renderWithTheme(<TableSubheader component={<div />} wrapContent={false} />);
23+
24+
expect(container.firstChild).toMatchSnapshot();
25+
});
26+
27+
test('<TableSubheader with component should render correctly with left align', () => {
28+
const { container } = renderWithTheme(<TableSubheader component={<div />} align="left" />);
29+
30+
expect(container.firstChild).toMatchSnapshot();
31+
});
32+
33+
test('<TableSubheader with component should render correctly with center align', () => {
34+
const { container } = renderWithTheme(<TableSubheader component={<div />} align="center" />);
35+
36+
expect(container.firstChild).toMatchSnapshot();
37+
});
38+
39+
test('<TableSubheader with component should render correctly with right align', () => {
40+
const { container } = renderWithTheme(<TableSubheader component={<div />} align="right" />);
41+
42+
expect(container.firstChild).toMatchSnapshot();
43+
});

0 commit comments

Comments
 (0)