diff --git a/docs/README.md b/docs/README.md
index 83213a6..14782fe 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -18,6 +18,7 @@
* [id](#id)
* [classes](#classes)
* [wrapperClasses](#wrapperClasses)
+* [headerClasses](#headerClasses)
* [cellEdit](#cellEdit)
* [selectRow](#selectRow)
* [rowStyle](#rowStyle)
@@ -111,6 +112,10 @@ Customize class on `table` element.
### wrapperClasses - [String]
Customize class on the outer element which wrap up the `table` element.
+
+### headerClasses - [String]
+Customize class on the header row(`tr`).
+
### cellEdit - [Object]
Makes table cells editable, please see [cellEdit definition](./cell-edit.md) for more detail.
diff --git a/packages/react-bootstrap-table2-example/examples/header-columns/header-class-table.js b/packages/react-bootstrap-table2-example/examples/header-columns/header-class-table.js
new file mode 100644
index 0000000..2c480c1
--- /dev/null
+++ b/packages/react-bootstrap-table2-example/examples/header-columns/header-class-table.js
@@ -0,0 +1,52 @@
+import React from 'react';
+
+import BootstrapTable from 'react-bootstrap-table-next';
+import Code from 'components/common/code-block';
+import { productsGenerator } from 'utils/common';
+
+const products = productsGenerator();
+
+const columns = [{
+ dataField: 'id',
+ text: 'Product ID'
+}, {
+ dataField: 'name',
+ text: 'Product Name'
+}, {
+ dataField: 'price',
+ text: 'Product Price'
+}];
+
+const sourceCode = `\
+import BootstrapTable from 'react-bootstrap-table-next';
+
+const columns = [{
+ dataField: 'id',
+ text: 'Product ID'
+}, {
+ dataField: 'name',
+ text: 'Product Name'
+}, {
+ dataField: 'price',
+ text: 'Product Price'
+}];
+
+
+`;
+
+export default () => (
+
+
+ { sourceCode }
+
+);
diff --git a/packages/react-bootstrap-table2-example/stories/index.js b/packages/react-bootstrap-table2-example/stories/index.js
index 64c4909..77dc4c9 100644
--- a/packages/react-bootstrap-table2-example/stories/index.js
+++ b/packages/react-bootstrap-table2-example/stories/index.js
@@ -33,6 +33,7 @@ import HeaderColumnEventTable from 'examples/header-columns/column-event-table';
import HeaderColumnClassTable from 'examples/header-columns/column-class-table';
import HeaderColumnStyleTable from 'examples/header-columns/column-style-table';
import HeaderColumnAttrsTable from 'examples/header-columns/column-attrs-table';
+import HeaderClassTable from 'examples/header-columns/header-class-table';
// column filter
import TextFilter from 'examples/column-filter/text-filter';
@@ -165,7 +166,8 @@ storiesOf('Work on Header Columns', module)
.add('Column Event', () => )
.add('Customize Column Class', () => )
.add('Customize Column Style', () => )
- .add('Customize Column HTML attribute', () => );
+ .add('Customize Column HTML attribute', () => )
+ .add('Header Class', () => );
storiesOf('Column Filter', module)
.add('Text Filter', () => )
diff --git a/packages/react-bootstrap-table2-example/stories/stylesheet/columns/_index.scss b/packages/react-bootstrap-table2-example/stories/stylesheet/columns/_index.scss
index 3468c70..a0ec3d1 100644
--- a/packages/react-bootstrap-table2-example/stories/stylesheet/columns/_index.scss
+++ b/packages/react-bootstrap-table2-example/stories/stylesheet/columns/_index.scss
@@ -9,4 +9,8 @@
.demo-row-odd {
background-color: $green-lighten-4;
+}
+
+.header-class {
+ background-color: $green-lighten-4;
}
\ No newline at end of file
diff --git a/packages/react-bootstrap-table2-paginator/src/page.js b/packages/react-bootstrap-table2-paginator/src/page.js
index aa3085a..3a9b863 100644
--- a/packages/react-bootstrap-table2-paginator/src/page.js
+++ b/packages/react-bootstrap-table2-paginator/src/page.js
@@ -1,12 +1,39 @@
+/* eslint no-param-reassign: 0 */
+
+const getNormalizedPage = (
+ page,
+ pageStartIndex
+) => {
+ const offset = Math.abs(1 - pageStartIndex);
+ return page + offset;
+};
+
+const endIndex = (
+ page,
+ sizePerPage,
+ pageStartIndex
+) => (getNormalizedPage(page, pageStartIndex) * sizePerPage) - 1;
+
+const startIndex = (
+ end,
+ sizePerPage,
+) => end - (sizePerPage - 1);
+
+export const alignPage = (store, pageStartIndex, sizePerPage) => {
+ const end = endIndex(store.page, sizePerPage, pageStartIndex);
+ const dataSize = store.data.length;
+
+ if (end - 1 > dataSize) {
+ return pageStartIndex;
+ }
+ return store.page;
+};
+
export const getByCurrPage = (store, pageStartIndex) => {
const dataSize = store.data.length;
if (!dataSize) return [];
- const getNormalizedPage = () => {
- const offset = Math.abs(1 - pageStartIndex);
- return store.page + offset;
- };
- const end = (getNormalizedPage() * store.sizePerPage) - 1;
- const start = end - (store.sizePerPage - 1);
+ const end = endIndex(store.page, store.sizePerPage, pageStartIndex);
+ const start = startIndex(end, store.sizePerPage);
const result = [];
for (let i = start; i <= end; i += 1) {
diff --git a/packages/react-bootstrap-table2-paginator/src/wrapper.js b/packages/react-bootstrap-table2-paginator/src/wrapper.js
index ff88c59..784687a 100644
--- a/packages/react-bootstrap-table2-paginator/src/wrapper.js
+++ b/packages/react-bootstrap-table2-paginator/src/wrapper.js
@@ -4,7 +4,7 @@ import PropTypes from 'prop-types';
import Const from './const';
import Pagination from './pagination';
-import { getByCurrPage } from './page';
+import { getByCurrPage, alignPage } from './page';
export default (Base, {
remoteResolver
@@ -49,17 +49,21 @@ export default (Base, {
componentWillReceiveProps(nextProps) {
let needNewState = false;
let { currPage, currSizePerPage } = this.state;
- const { page, sizePerPage, pageStartIndex, onPageChange } = nextProps.pagination.options;
+ const { page, sizePerPage, onPageChange } = nextProps.pagination.options;
+
+ const pageStartIndex = typeof nextProps.pagination.options.pageStartIndex !== 'undefined' ?
+ nextProps.pagination.options.pageStartIndex : Const.PAGE_START_INDEX;
if (typeof page !== 'undefined' && currPage !== page) { // user defined page
currPage = page;
needNewState = true;
} else if (nextProps.isDataChanged) {
+ currPage = alignPage(this.props.store, pageStartIndex, currSizePerPage);
needNewState = true;
}
if (typeof currPage === 'undefined') {
- currPage = typeof pageStartIndex !== 'undefined' ? pageStartIndex : Const.PAGE_START_INDEX;
+ currPage = pageStartIndex;
}
if (typeof sizePerPage !== 'undefined') {
diff --git a/packages/react-bootstrap-table2-paginator/test/page.test.js b/packages/react-bootstrap-table2-paginator/test/page.test.js
index 1e092c9..bd63574 100644
--- a/packages/react-bootstrap-table2-paginator/test/page.test.js
+++ b/packages/react-bootstrap-table2-paginator/test/page.test.js
@@ -1,5 +1,5 @@
import Store from 'react-bootstrap-table-next/src/store';
-import { getByCurrPage } from '../src/page';
+import { getByCurrPage, alignPage } from '../src/page';
describe('Page Functions', () => {
let data;
@@ -48,4 +48,40 @@ describe('Page Functions', () => {
});
});
});
+
+ describe('alignPage', () => {
+ const pageStartIndex = 1;
+ const sizePerPage = 10;
+ describe('if the length of store.data is less than the end page index', () => {
+ beforeEach(() => {
+ data = [];
+ for (let i = 0; i < 15; i += 1) {
+ data.push({ id: i, name: `test_name${i}` });
+ }
+ store = new Store('id');
+ store.data = data;
+ store.page = 2;
+ });
+
+ it('should return pageStartIndex argument', () => {
+ expect(alignPage(store, pageStartIndex, sizePerPage)).toEqual(pageStartIndex);
+ });
+ });
+
+ describe('if the length of store.data is large than the end page index', () => {
+ beforeEach(() => {
+ data = [];
+ for (let i = 0; i < 30; i += 1) {
+ data.push({ id: i, name: `test_name${i}` });
+ }
+ store = new Store('id');
+ store.data = data;
+ store.page = 2;
+ });
+
+ it('should return current page', () => {
+ expect(alignPage(store, pageStartIndex, sizePerPage)).toEqual(store.page);
+ });
+ });
+ });
});
diff --git a/packages/react-bootstrap-table2-paginator/test/wrapper.test.js b/packages/react-bootstrap-table2-paginator/test/wrapper.test.js
index feea75c..f636fe3 100644
--- a/packages/react-bootstrap-table2-paginator/test/wrapper.test.js
+++ b/packages/react-bootstrap-table2-paginator/test/wrapper.test.js
@@ -176,23 +176,6 @@ describe('Wrapper', () => {
expect(props.store.page).toEqual(instance.state.currPage);
});
});
-
- describe('when nextProps.isDataChanged is true, currPage is undefined and options.pageStartIndex exists', () => {
- beforeEach(() => {
- nextProps.isDataChanged = true;
- nextProps.pagination.options.pageStartIndex = 0;
- instance.state.currPage = undefined;
- instance.componentWillReceiveProps(nextProps);
- });
-
- it('should setting currPage state correctly', () => {
- expect(instance.state.currPage).toBe(nextProps.pagination.options.pageStartIndex);
- });
-
- it('should saving store.page correctly', () => {
- expect(props.store.page).toEqual(instance.state.currPage);
- });
- });
});
});
diff --git a/packages/react-bootstrap-table2/src/bootstrap-table.js b/packages/react-bootstrap-table2/src/bootstrap-table.js
index fe6865c..e9ee145 100644
--- a/packages/react-bootstrap-table2/src/bootstrap-table.js
+++ b/packages/react-bootstrap-table2/src/bootstrap-table.js
@@ -86,6 +86,7 @@ class BootstrapTable extends PropsBaseResolver(Component) {
{ tableCaption }
{
const { ROW_SELECT_DISABLED } = Const;
const {
+ className,
columns,
onSort,
onFilter,
@@ -21,7 +22,7 @@ const Header = (props) => {
return (
-
+
{
(selectRow.mode !== ROW_SELECT_DISABLED && !selectRow.hideSelectColumn)
? : null
@@ -60,7 +61,8 @@ Header.propTypes = {
sortField: PropTypes.string,
sortOrder: PropTypes.string,
selectRow: PropTypes.object,
- onExternalFilter: PropTypes.func
+ onExternalFilter: PropTypes.func,
+ className: PropTypes.string
};
export default Header;
diff --git a/packages/react-bootstrap-table2/test/header.test.js b/packages/react-bootstrap-table2/test/header.test.js
index c502602..d8db9cd 100644
--- a/packages/react-bootstrap-table2/test/header.test.js
+++ b/packages/react-bootstrap-table2/test/header.test.js
@@ -29,6 +29,25 @@ describe('Header', () => {
});
});
+ describe('className prop is exists', () => {
+ const className = 'test-class';
+
+ beforeEach(() => {
+ wrapper = shallow(
+
+ );
+ });
+
+ it('should render successfully', () => {
+ expect(wrapper.length).toBe(1);
+ expect(wrapper.find(`.${className}`).length).toBe(1);
+ });
+ });
+
describe('header with columns enable sort', () => {
const sortField = columns[1].dataField;