diff --git a/docs/row-expand.md b/docs/row-expand.md
index ce710de..025d03d 100644
--- a/docs/row-expand.md
+++ b/docs/row-expand.md
@@ -15,6 +15,7 @@
* [showExpandColumn](#showExpandColumn)
* [onlyOneExpanding](#onlyOneExpanding)
* [expandByColumnOnly](#expandByColumnOnly)
+* [expandColumnPosition](#expandColumnPosition)
* [expandColumnRenderer](#expandColumnRenderer)
* [expandHeaderColumnRenderer](#expandHeaderColumnRenderer)
@@ -153,3 +154,14 @@ const expandRow = {
expandByColumnOnly: true
};
```
+
+### expandRow.expandColumnPosition - [String]
+Default is `left`. You can give this as `right` for rendering expand column in the right side.
+
+```js
+const expandRow = {
+ renderer: (row) => ...,
+ showExpandColumn: true,
+ expandColumnPosition: 'right'
+};
+```
diff --git a/packages/react-bootstrap-table2-example/examples/column-filter/filter-hooks.js b/packages/react-bootstrap-table2-example/examples/column-filter/filter-hooks.js
new file mode 100644
index 0000000..db3b2bf
--- /dev/null
+++ b/packages/react-bootstrap-table2-example/examples/column-filter/filter-hooks.js
@@ -0,0 +1,57 @@
+/* eslint no-console: 0 */
+import React from 'react';
+import BootstrapTable from 'react-bootstrap-table-next';
+import filterFactory, { textFilter } from 'react-bootstrap-table2-filter';
+import Code from 'components/common/code-block';
+import { productsGenerator } from 'utils/common';
+
+const products = productsGenerator(8);
+
+const columns = [{
+ dataField: 'id',
+ text: 'Product ID'
+}, {
+ dataField: 'name',
+ text: 'Product Name',
+ filter: textFilter()
+}, {
+ dataField: 'price',
+ text: 'Product Price',
+ filter: textFilter({
+ onFilter: filterVal => console.log(`Filter Value: ${filterVal}`)
+ })
+}];
+
+const sourceCode = `\
+import BootstrapTable from 'react-bootstrap-table-next';
+import filterFactory, { textFilter } from 'react-bootstrap-table2-filter';
+
+const columns = [{
+ dataField: 'id',
+ text: 'Product ID'
+}, {
+ dataField: 'name',
+ text: 'Product Name',
+ filter: textFilter()
+}, {
+ dataField: 'price',
+ text: 'Product Price',
+ filter: textFilter({
+ onFilter: filterVal => console.log(\`Filter Value: $\{filterVal}\`)
+ })
+}];
+
+
+`;
+
+export default () => (
+
+
+ { sourceCode }
+
+);
diff --git a/packages/react-bootstrap-table2-example/examples/pagination/remote-standalone-pagination.js b/packages/react-bootstrap-table2-example/examples/pagination/remote-standalone-pagination.js
new file mode 100644
index 0000000..cb5609b
--- /dev/null
+++ b/packages/react-bootstrap-table2-example/examples/pagination/remote-standalone-pagination.js
@@ -0,0 +1,190 @@
+/* eslint react/no-multi-comp: 0 */
+import React from 'react';
+import PropTypes from 'prop-types';
+import BootstrapTable from 'react-bootstrap-table-next';
+import paginationFactory, { PaginationProvider, PaginationListStandalone } from 'react-bootstrap-table2-paginator';
+import Code from 'components/common/code-block';
+import { productsGenerator } from 'utils/common';
+
+const products = productsGenerator(87);
+
+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';
+import paginationFactory, { PaginationProvider, PaginationListStandalone } from 'react-bootstrap-table2-paginator';
+// ...
+const RemotePagination = ({ data, page, sizePerPage, onTableChange, totalSize }) => (
+
+
+ {
+ ({
+ paginationProps,
+ paginationTableProps
+ }) => (
+
+
+
Current Page: { paginationProps.page }
+
Current SizePerPage: { paginationProps.sizePerPage }
+
+
+
+
+ )
+ }
+
+
+);
+
+class Container extends React.Component {
+ constructor(props) {
+ super(props);
+ this.state = {
+ page: 1,
+ data: products.slice(0, 10),
+ sizePerPage: 10
+ };
+ }
+
+ handleTableChange = (type, { page, sizePerPage }) => {
+ const currentIndex = (page - 1) * sizePerPage;
+ setTimeout(() => {
+ this.setState(() => ({
+ page,
+ data: products.slice(currentIndex, currentIndex + sizePerPage),
+ sizePerPage
+ }));
+ }, 2000);
+ }
+
+ render() {
+ const { data, sizePerPage, page } = this.state;
+ return (
+
+ );
+ }
+}
+`;
+
+const RemotePagination = ({ data, page, sizePerPage, onTableChange, totalSize }) => (
+
+
+ {
+ ({
+ paginationProps,
+ paginationTableProps
+ }) => (
+
+
+
Current Page: { paginationProps.page }
+
Current SizePerPage: { paginationProps.sizePerPage }
+
+
+
+
+ )
+ }
+
+
{ sourceCode }
+
+);
+
+RemotePagination.propTypes = {
+ data: PropTypes.array.isRequired,
+ page: PropTypes.number.isRequired,
+ totalSize: PropTypes.number.isRequired,
+ sizePerPage: PropTypes.number.isRequired,
+ onTableChange: PropTypes.func.isRequired
+};
+
+class Container extends React.Component {
+ constructor(props) {
+ super(props);
+ this.state = {
+ page: 1,
+ data: products.slice(0, 10),
+ sizePerPage: 10
+ };
+ }
+
+ handleTableChange = (type, { page, sizePerPage }) => {
+ const currentIndex = (page - 1) * sizePerPage;
+ setTimeout(() => {
+ this.setState(() => ({
+ page,
+ data: products.slice(currentIndex, currentIndex + sizePerPage),
+ sizePerPage
+ }));
+ }, 2000);
+ }
+
+ render() {
+ const { data, sizePerPage, page } = this.state;
+ return (
+
+ );
+ }
+}
+
+export default Container;
diff --git a/packages/react-bootstrap-table2-example/examples/row-expand/expand-column-position.js b/packages/react-bootstrap-table2-example/examples/row-expand/expand-column-position.js
new file mode 100644
index 0000000..8b07b34
--- /dev/null
+++ b/packages/react-bootstrap-table2-example/examples/row-expand/expand-column-position.js
@@ -0,0 +1,76 @@
+import React from 'react';
+
+import BootstrapTable from 'react-bootstrap-table-next';
+import Code from 'components/common/code-block';
+import { productsExpandRowsGenerator } from 'utils/common';
+
+const products = productsExpandRowsGenerator();
+
+const columns = [{
+ dataField: 'id',
+ text: 'Product ID'
+}, {
+ dataField: 'name',
+ text: 'Product Name'
+}, {
+ dataField: 'price',
+ text: 'Product Price'
+}];
+
+const expandRow = {
+ renderer: row => (
+
+
{ `This Expand row is belong to rowKey ${row.id}` }
+
You can render anything here, also you can add additional data on every row object
+
expandRow.renderer callback will pass the origin row object to you
+
+ ),
+ showExpandColumn: true,
+ expandColumnPosition: 'right'
+};
+
+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'
+}];
+
+const expandRow = {
+ renderer: row => (
+
+
{ \`This Expand row is belong to rowKey $\{row.id}\` }
+
You can render anything here, also you can add additional data on every row object
+
expandRow.renderer callback will pass the origin row object to you
+
+ ),
+ showExpandColumn: true,
+ expandColumnPosition: 'right'
+};
+
+
+`;
+
+export default () => (
+
+
+ { sourceCode }
+
+);
diff --git a/packages/react-bootstrap-table2-example/stories/index.js b/packages/react-bootstrap-table2-example/stories/index.js
index ef20d12..0461549 100644
--- a/packages/react-bootstrap-table2-example/stories/index.js
+++ b/packages/react-bootstrap-table2-example/stories/index.js
@@ -74,6 +74,7 @@ import ProgrammaticallyMultiSelectFilter from 'examples/column-filter/programmat
import CustomFilter from 'examples/column-filter/custom-filter';
import AdvanceCustomFilter from 'examples/column-filter/advance-custom-filter';
import ClearAllFilters from 'examples/column-filter/clear-all-filters';
+import FilterHooks from 'examples/column-filter/filter-hooks';
// work on rows
import RowStyleTable from 'examples/rows/row-style';
@@ -141,6 +142,7 @@ import ExpandColumn from 'examples/row-expand/expand-column';
import OnlyExpandByColumn from 'examples/row-expand/expand-by-column-only.js';
import ExpandOnlyOne from 'examples/row-expand/expand-only-one';
import CustomExpandColumn from 'examples/row-expand/custom-expand-column';
+import ExpandColumnPosition from 'examples/row-expand/expand-column-position';
import ExpandHooks from 'examples/row-expand/expand-hooks';
// pagination
@@ -154,6 +156,7 @@ import CustomPageListTable from 'examples/pagination/custom-page-list';
import StandalonePaginationList from 'examples/pagination/standalone-pagination-list';
import StandaloneSizePerPage from 'examples/pagination/standalone-size-per-page';
import FullyCustomPaginationTable from 'examples/pagination/fully-custom-pagination';
+import RemoteStandalonePaginationTable from 'examples/pagination/remote-standalone-pagination';
// search
import SearchTable from 'examples/search';
@@ -273,7 +276,8 @@ storiesOf('Column Filter', module)
.add('Custom Filter', () => )
.add('Advance Custom Filter', () => )
.add('Preserved Option Order on Select Filter', () => )
- .add('Clear All Filters', () => );
+ .add('Clear All Filters', () => )
+ .add('Filter Hooks', () => );
storiesOf('Work on Rows', module)
.addDecorator(bootstrapStyle())
@@ -346,6 +350,7 @@ storiesOf('Row Expand', module)
.add('Only Expand by Indicator', () => )
.add('Expand Only One Row at The Same Time', () => )
.add('Custom Expand Indicator', () => )
+ .add('Expand Column Position', () => )
.add('Expand Hooks', () => );
storiesOf('Pagination', module)
@@ -359,7 +364,8 @@ storiesOf('Pagination', module)
.add('Custom SizePerPage', () => )
.add('Standalone Pagination List', () => )
.add('Standalone SizePerPage Dropdown', () => )
- .add('Fully Custom Pagination', () => );
+ .add('Fully Custom Pagination', () => )
+ .add('Remote Fully Custom Pagination', () => );
storiesOf('Table Search', module)
.addDecorator(bootstrapStyle())
diff --git a/packages/react-bootstrap-table2-filter/src/context.js b/packages/react-bootstrap-table2-filter/src/context.js
index 790ce00..e82e53e 100644
--- a/packages/react-bootstrap-table2-filter/src/context.js
+++ b/packages/react-bootstrap-table2-filter/src/context.js
@@ -64,6 +64,10 @@ export default (
return;
}
+ if (filter.props.onFilter) {
+ filter.props.onFilter(filterVal);
+ }
+
this.forceUpdate();
};
}
diff --git a/packages/react-bootstrap-table2-filter/test/context.test.js b/packages/react-bootstrap-table2-filter/test/context.test.js
index f4b97ca..b80d0c5 100644
--- a/packages/react-bootstrap-table2-filter/test/context.test.js
+++ b/packages/react-bootstrap-table2-filter/test/context.test.js
@@ -44,7 +44,8 @@ describe('FilterContext', () => {
const handleFilterChange = jest.fn();
function shallowContext(
- enableRemote = false
+ enableRemote = false,
+ tableColumns = columns
) {
mockBase.mockReset();
handleFilterChange.mockReset();
@@ -56,7 +57,7 @@ describe('FilterContext', () => {
return (
@@ -225,6 +226,32 @@ describe('FilterContext', () => {
});
});
+ describe('if filter.props.onFilter is defined', () => {
+ const filterVal = '3';
+ const onFilter = jest.fn();
+ const customColumns = columns.map((column, i) => {
+ if (i === 1) {
+ return {
+ ...column,
+ filter: textFilter({ onFilter })
+ };
+ }
+ return column;
+ });
+
+ beforeEach(() => {
+ wrapper = shallow(shallowContext(false, customColumns));
+ wrapper.render();
+ instance = wrapper.instance();
+ });
+
+ it('should call filter.props.onFilter correctly', () => {
+ instance.onFilter(customColumns[1], FILTER_TYPE.TEXT)(filterVal);
+ expect(onFilter).toHaveBeenCalledTimes(1);
+ expect(onFilter).toHaveBeenCalledWith(filterVal);
+ });
+ });
+
describe('combination', () => {
beforeEach(() => {
wrapper = shallow(shallowContext());
diff --git a/packages/react-bootstrap-table2-paginator/src/page-resolver.js b/packages/react-bootstrap-table2-paginator/src/page-resolver.js
index cb77b17..b9134d9 100644
--- a/packages/react-bootstrap-table2-paginator/src/page-resolver.js
+++ b/packages/react-bootstrap-table2-paginator/src/page-resolver.js
@@ -135,8 +135,8 @@ export default ExtendBase =>
calculateSizePerPageStatus() {
const { sizePerPageList } = this.props;
return sizePerPageList.map((_sizePerPage) => {
- const pageText = _sizePerPage.text || _sizePerPage;
- const pageNumber = _sizePerPage.value || _sizePerPage;
+ const pageText = typeof _sizePerPage.text !== 'undefined' ? _sizePerPage.text : _sizePerPage;
+ const pageNumber = typeof _sizePerPage.value !== 'undefined' ? _sizePerPage.value : _sizePerPage;
return {
text: `${pageText}`,
page: pageNumber
diff --git a/packages/react-bootstrap-table2-toolkit/src/op/csv.js b/packages/react-bootstrap-table2-toolkit/src/op/csv.js
index 5f05a4e..47a6339 100644
--- a/packages/react-bootstrap-table2-toolkit/src/op/csv.js
+++ b/packages/react-bootstrap-table2-toolkit/src/op/csv.js
@@ -25,13 +25,19 @@ export default Base =>
let data;
if (typeof source !== 'undefined') {
data = source;
+ } else if (options.exportAll) {
+ data = this.props.data;
} else {
- data = options.exportAll ? this.props.data : this.getData();
+ const payload = {};
+ this.tableExposedAPIEmitter.emit('get.table.data', payload);
+ data = payload.result;
}
// filter data
if (options.onlyExportSelection) {
- const selections = this.getSelected();
+ const payload = {};
+ this.tableExposedAPIEmitter.emit('get.selected.rows', payload);
+ const selections = payload.result;
data = data.filter(row => !!selections.find(sel => row[keyField] === sel));
}
const content = transform(data, meta, this._.get, options);
diff --git a/packages/react-bootstrap-table2-toolkit/statelessOp.js b/packages/react-bootstrap-table2-toolkit/statelessOp.js
index 6c248c1..85444bf 100644
--- a/packages/react-bootstrap-table2-toolkit/statelessOp.js
+++ b/packages/react-bootstrap-table2-toolkit/statelessOp.js
@@ -2,9 +2,7 @@ import Operation from './src/op';
export default Base =>
class StatelessOperation extends Operation.csvOperation(Base) {
- registerExposedAPI = (...exposedFuncs) => {
- exposedFuncs.forEach((func) => {
- this[func.name] = func;
- });
+ registerExposedAPI = (tableExposedAPIEmitter) => {
+ this.tableExposedAPIEmitter = tableExposedAPIEmitter;
}
};
diff --git a/packages/react-bootstrap-table2/src/bootstrap-table.js b/packages/react-bootstrap-table2/src/bootstrap-table.js
index 8bcd7c1..7c3a727 100644
--- a/packages/react-bootstrap-table2/src/bootstrap-table.js
+++ b/packages/react-bootstrap-table2/src/bootstrap-table.js
@@ -14,13 +14,10 @@ class BootstrapTable extends PropsBaseResolver(Component) {
constructor(props) {
super(props);
this.validateProps();
- if (props.registerExposedAPI) {
- props.registerExposedAPI(this.getData);
- }
}
// Exposed APIs
- getData() {
+ getData = () => {
return this.visibleRows();
}
@@ -161,7 +158,11 @@ BootstrapTable.propTypes = {
onlyOneExpanding: PropTypes.bool,
expandByColumnOnly: PropTypes.bool,
expandColumnRenderer: PropTypes.func,
- expandHeaderColumnRenderer: PropTypes.func
+ expandHeaderColumnRenderer: PropTypes.func,
+ expandColumnPosition: PropTypes.oneOf([
+ Const.INDICATOR_POSITION_LEFT,
+ Const.INDICATOR_POSITION_RIGHT
+ ])
}),
rowStyle: PropTypes.oneOfType([PropTypes.object, PropTypes.func]),
rowEvents: PropTypes.object,
diff --git a/packages/react-bootstrap-table2/src/const.js b/packages/react-bootstrap-table2/src/const.js
index 6c47b1c..ce1b7e4 100644
--- a/packages/react-bootstrap-table2/src/const.js
+++ b/packages/react-bootstrap-table2/src/const.js
@@ -6,5 +6,7 @@ export default {
ROW_SELECT_DISABLED: 'ROW_SELECT_DISABLED',
CHECKBOX_STATUS_CHECKED: 'checked',
CHECKBOX_STATUS_INDETERMINATE: 'indeterminate',
- CHECKBOX_STATUS_UNCHECKED: 'unchecked'
+ CHECKBOX_STATUS_UNCHECKED: 'unchecked',
+ INDICATOR_POSITION_LEFT: 'left',
+ INDICATOR_POSITION_RIGHT: 'right'
};
diff --git a/packages/react-bootstrap-table2/src/contexts/index.js b/packages/react-bootstrap-table2/src/contexts/index.js
index 12bfb9a..7caf60c 100644
--- a/packages/react-bootstrap-table2/src/contexts/index.js
+++ b/packages/react-bootstrap-table2/src/contexts/index.js
@@ -1,6 +1,8 @@
/* eslint no-return-assign: 0 */
+/* eslint no-param-reassign: 0 */
/* eslint class-methods-use-this: 0 */
import React, { Component } from 'react';
+import EventEmitter from 'events';
import _ from '../utils';
import createDataContext from './data-context';
import createSortContext from './sort-context';
@@ -16,6 +18,13 @@ const withContext = Base =>
super(props);
this.DataContext = createDataContext();
+ if (props.registerExposedAPI) {
+ const exposedAPIEmitter = new EventEmitter();
+ exposedAPIEmitter.on('get.table.data', payload => payload.result = this.table.getData());
+ exposedAPIEmitter.on('get.selected.rows', payload => payload.result = this.selectionContext.getSelected());
+ props.registerExposedAPI(exposedAPIEmitter);
+ }
+
if (props.columns.filter(col => col.sort).length > 0) {
this.SortContext = createSortContext(
dataOperator, this.isRemoteSort, this.handleRemoteSortChange);
@@ -255,9 +264,8 @@ const withContext = Base =>
}
render() {
- const { keyField, columns, bootstrap4, registerExposedAPI } = this.props;
+ const { keyField, columns, bootstrap4 } = this.props;
const baseProps = { keyField, columns };
- if (registerExposedAPI) baseProps.registerExposedAPI = registerExposedAPI;
let base = this.renderBase();
diff --git a/packages/react-bootstrap-table2/src/contexts/selection-context.js b/packages/react-bootstrap-table2/src/contexts/selection-context.js
index 2bdd321..9c44cff 100644
--- a/packages/react-bootstrap-table2/src/contexts/selection-context.js
+++ b/packages/react-bootstrap-table2/src/contexts/selection-context.js
@@ -14,14 +14,6 @@ class SelectionProvider extends React.Component {
keyField: PropTypes.string.isRequired
}
- constructor(props) {
- super(props);
- if (props.registerExposedAPI) {
- const getSelected = () => this.getSelected();
- props.registerExposedAPI(getSelected);
- }
- }
-
state = { selected: this.props.selectRow.selected || [] };
componentWillReceiveProps(nextProps) {
diff --git a/packages/react-bootstrap-table2/src/header.js b/packages/react-bootstrap-table2/src/header.js
index e8a6fb3..2606852 100644
--- a/packages/react-bootstrap-table2/src/header.js
+++ b/packages/react-bootstrap-table2/src/header.js
@@ -7,6 +7,7 @@ import SelectionHeaderCell from './row-selection/selection-header-cell';
import ExpandHeaderCell from './row-expand/expand-header-cell';
import withHeaderSelection from './row-selection/selection-header-cell-consumer';
import withHeaderExpansion from './row-expand/expand-header-cell-consumer';
+import Const from './const';
const Header = (props) => {
const {
@@ -32,36 +33,49 @@ const Header = (props) => {
SelectionHeaderCellComp = withHeaderSelection(SelectionHeaderCell);
}
+ const isRenderExpandColumnInLeft = (
+ expandColumnPosition = Const.INDICATOR_POSITION_LEFT
+ ) => expandColumnPosition === Const.INDICATOR_POSITION_LEFT;
+
+ const childrens = [
+ columns.map((column, i) => {
+ if (!column.hidden) {
+ const currSort = column.dataField === sortField;
+ const isLastSorting = column.dataField === sortField;
+
+ return (
+ );
+ }
+ return false;
+ })
+ ];
+
+ if (!selectRow.hideSelectColumn) {
+ childrens.unshift();
+ }
+
+ if (expandRow.showExpandColumn) {
+ if (isRenderExpandColumnInLeft(expandRow.expandColumnPosition)) {
+ childrens.unshift();
+ } else {
+ childrens.push();
+ }
+ }
+
return (
-
- {
- !selectRow.hideSelectColumn ?
- : null
- }
- {
- columns.map((column, i) => {
- if (!column.hidden) {
- const currSort = column.dataField === sortField;
- const isLastSorting = column.dataField === sortField;
-
- return (
- );
- }
- return false;
- })
- }
+ { childrens }
);
diff --git a/packages/react-bootstrap-table2/src/row/aggregate-row.js b/packages/react-bootstrap-table2/src/row/aggregate-row.js
index dfba8b5..96b7dbe 100644
--- a/packages/react-bootstrap-table2/src/row/aggregate-row.js
+++ b/packages/react-bootstrap-table2/src/row/aggregate-row.js
@@ -1,3 +1,4 @@
+/* eslint class-methods-use-this: 0 */
/* eslint react/prop-types: 0 */
/* eslint no-plusplus: 0 */
import React from 'react';
@@ -8,6 +9,7 @@ import SelectionCell from '../row-selection/selection-cell';
import shouldUpdater from './should-updater';
import eventDelegater from './event-delegater';
import RowPureContent from './row-pure-content';
+import Const from '../const';
export default class RowAggregator extends shouldUpdater(eventDelegater(React.Component)) {
static propTypes = {
@@ -43,6 +45,12 @@ export default class RowAggregator extends shouldUpdater(eventDelegater(React.Co
return this.shouldUpdateRowContent;
}
+ isRenderExpandColumnInLeft(
+ expandColumnPosition = Const.INDICATOR_POSITION_LEFT
+ ) {
+ return expandColumnPosition === Const.INDICATOR_POSITION_LEFT;
+ }
+
render() {
const {
row,
@@ -64,7 +72,7 @@ export default class RowAggregator extends shouldUpdater(eventDelegater(React.Co
} = this.props;
const key = _.get(row, keyField);
const { hideSelectColumn, clickToSelect } = selectRow;
- const { showExpandColumn } = expandRow;
+ const { showExpandColumn, expandColumnPosition } = expandRow;
const newAttrs = this.delegate({ ...attrs });
if (clickToSelect || !!expandRow.renderer) {
@@ -73,47 +81,59 @@ export default class RowAggregator extends shouldUpdater(eventDelegater(React.Co
let tabIndexStart = (rowIndex * visibleColumnSize) + 1;
+ const childrens = [(
+
+ )];
+
+ if (!hideSelectColumn) {
+ childrens.unshift((
+
+ ));
+ }
+
+ if (showExpandColumn) {
+ const expandCell = (
+
+ );
+ if (this.isRenderExpandColumnInLeft(expandColumnPosition)) {
+ childrens.unshift(expandCell);
+ } else {
+ childrens.push(expandCell);
+ }
+ }
+
return (
- {
- showExpandColumn ? (
-
- ) : null
- }
- {
- !hideSelectColumn
- ? (
-
- )
- : null
- }
-
+ { childrens }
);
}
diff --git a/packages/react-bootstrap-table2/src/row/should-updater.js b/packages/react-bootstrap-table2/src/row/should-updater.js
index 7756b73..813dbb5 100644
--- a/packages/react-bootstrap-table2/src/row/should-updater.js
+++ b/packages/react-bootstrap-table2/src/row/should-updater.js
@@ -20,6 +20,19 @@ export default ExtendBase =>
);
}
+ // Only use for simple-row
+ shouldUpdateByColumnsForSimpleCheck(nextProps) {
+ if (this.props.columns.length !== nextProps.columns.length) {
+ return true;
+ }
+ for (let i = 0; i < this.props.columns.length; i += 1) {
+ if (this.props.columns[i].hidden !== nextProps.columns[i].hidden) {
+ return true;
+ }
+ }
+ return false;
+ }
+
shouldUpdatedByNormalProps(nextProps) {
const shouldUpdate =
this.props.rowIndex !== nextProps.rowIndex ||
diff --git a/packages/react-bootstrap-table2/src/row/simple-row.js b/packages/react-bootstrap-table2/src/row/simple-row.js
index 83aff66..96ca92f 100644
--- a/packages/react-bootstrap-table2/src/row/simple-row.js
+++ b/packages/react-bootstrap-table2/src/row/simple-row.js
@@ -15,7 +15,8 @@ class SimpleRow extends shouldUpdater(eventDelegater(Component)) {
shouldComponentUpdate(nextProps) {
this.shouldUpdateRowContent = false;
- this.shouldUpdateRowContent = this.shouldUpdateChild(nextProps);
+ this.shouldUpdateRowContent =
+ this.shouldUpdateChild(nextProps) || this.shouldUpdateByColumnsForSimpleCheck(nextProps);
if (this.shouldUpdateRowContent) return true;
return this.shouldUpdatedBySelfProps(nextProps);
diff --git a/packages/react-bootstrap-table2/test/bootstrap-table.test.js b/packages/react-bootstrap-table2/test/bootstrap-table.test.js
index 23986a8..a543111 100644
--- a/packages/react-bootstrap-table2/test/bootstrap-table.test.js
+++ b/packages/react-bootstrap-table2/test/bootstrap-table.test.js
@@ -60,26 +60,6 @@ describe('BootstrapTable', () => {
});
});
- describe('when props.registerExposedAPI is defined', () => {
- const registerExposedAPI = jest.fn();
- beforeEach(() => {
- registerExposedAPI.mockClear();
- wrapper = shallow(
-
- );
- });
-
- it('should call props.registerExposedAPI correctly', () => {
- expect(registerExposedAPI).toHaveBeenCalledTimes(1);
- expect(registerExposedAPI.mock.calls[0][0].name).toEqual('getData');
- });
- });
-
describe('when props.classes was defined', () => {
const classes = 'foo';
diff --git a/packages/react-bootstrap-table2/test/contexts/index.test.js b/packages/react-bootstrap-table2/test/contexts/index.test.js
index 76caecb..737fcb9 100644
--- a/packages/react-bootstrap-table2/test/contexts/index.test.js
+++ b/packages/react-bootstrap-table2/test/contexts/index.test.js
@@ -225,4 +225,31 @@ describe('Context', () => {
expect(wrapper.instance().PaginationContext).toBeDefined();
});
});
+
+ describe('if registerExposedAPI props is defined', () => {
+ const registerExposedAPI = jest.fn();
+ beforeEach(() => {
+ const PaginationContext = React.createContext();
+ const paginator = {
+ createContext: jest.fn().mockReturnValue({
+ Provider: PaginationContext.Provider,
+ Consumer: PaginationContext.Consumer
+ })
+ };
+ wrapper = shallow(
+
+ );
+ wrapper.render();
+ });
+
+ it('should call props.registerExposedAPI correctly', () => {
+ expect(registerExposedAPI).toHaveBeenCalledTimes(1);
+ });
+ });
});
diff --git a/packages/react-bootstrap-table2/test/header.test.js b/packages/react-bootstrap-table2/test/header.test.js
index ecb2318..263ac54 100644
--- a/packages/react-bootstrap-table2/test/header.test.js
+++ b/packages/react-bootstrap-table2/test/header.test.js
@@ -254,5 +254,33 @@ describe('Header', () => {
expect(wrapper.find(ExpandHeaderCell).length).toBe(1);
});
});
+
+ describe('if props.expandRow.showExpandColumn is true but props.expandRow.expandColumnPosition is "right"', () => {
+ beforeEach(() => {
+ const expandRow = {
+ renderer: jest.fn(),
+ showExpandColumn: true,
+ expandColumnPosition: Const.INDICATOR_POSITION_RIGHT
+ };
+ wrapper = mount(
+
+
+
+ );
+ });
+
+ it('should render expansion column correctly', () => {
+ const header = wrapper.find(Header).children();
+ expect(header.children().children().last().find(ExpandHeaderCell)).toHaveLength(1);
+ });
+ });
});
});
diff --git a/packages/react-bootstrap-table2/test/row/aggregate-row.test.js b/packages/react-bootstrap-table2/test/row/aggregate-row.test.js
index 76aa625..b314470 100644
--- a/packages/react-bootstrap-table2/test/row/aggregate-row.test.js
+++ b/packages/react-bootstrap-table2/test/row/aggregate-row.test.js
@@ -9,6 +9,7 @@ import bindExpansion from '../../src/row-expand/row-consumer';
import ExpandCell from '../../src/row-expand/expand-cell';
import SelectionCell from '../../src/row-selection/selection-cell';
import RowAggregator from '../../src/row/aggregate-row';
+import Const from '../../src/const';
describe('Row Aggregator', () => {
let wrapper;
@@ -157,6 +158,27 @@ describe('Row Aggregator', () => {
expect(expandCell.props().expanded).toEqual(rowAggregator.props().expanded);
});
});
+
+ describe('if props.expandRow.showExpandColumn is true but props.expandRow.expandColumnPosition is "right"', () => {
+ beforeEach(() => {
+ const expandRow = {
+ renderer: jest.fn(),
+ showExpandColumn: true,
+ expandColumnPosition: Const.INDICATOR_POSITION_RIGHT
+ };
+ wrapper = mount(
+
+
+
+ );
+ });
+
+ it('should render expansion column correctly', () => {
+ rowAggregator = wrapper.find(RowAggregator);
+ expect(rowAggregator).toHaveLength(1);
+ expect(rowAggregator.children().children().last().type()).toEqual(ExpandCell);
+ });
+ });
});
describe('createClickEventHandler', () => {
diff --git a/packages/react-bootstrap-table2/test/row/should-updater.test.js b/packages/react-bootstrap-table2/test/row/should-updater.test.js
index ab1ca05..1f5fefd 100644
--- a/packages/react-bootstrap-table2/test/row/should-updater.test.js
+++ b/packages/react-bootstrap-table2/test/row/should-updater.test.js
@@ -104,6 +104,50 @@ describe('Row shouldUpdater', () => {
});
});
+ describe('shouldUpdateByColumnsForSimpleCheck', () => {
+ describe('when nextProps.columns.length is not eq props.columns.length', () => {
+ beforeEach(() => {
+ props = {
+ columns: [{ dataField: 'price', text: 'Price' }]
+ };
+ wrapper = shallow();
+ });
+
+ it('should return true', () => {
+ nextProps = { ...props, columns: [...props.columns, { dataField: 'name', text: 'Name' }] };
+ expect(wrapper.instance().shouldUpdateByColumnsForSimpleCheck(nextProps)).toBeTruthy();
+ });
+ });
+
+ describe('when any nextProps.columns.hidden is change', () => {
+ beforeEach(() => {
+ props = {
+ columns: [{ dataField: 'price', text: 'Price' }]
+ };
+ wrapper = shallow();
+ });
+
+ it('should return true', () => {
+ nextProps = { ...props, columns: [{ dataField: 'price', text: 'Price', hidden: true }] };
+ expect(wrapper.instance().shouldUpdateByColumnsForSimpleCheck(nextProps)).toBeTruthy();
+ });
+ });
+
+ describe('if any nextProps.columns.hidden is not change and column length is same', () => {
+ beforeEach(() => {
+ props = {
+ columns: [{ dataField: 'price', text: 'Price' }]
+ };
+ wrapper = shallow();
+ });
+
+ it('should return false', () => {
+ nextProps = { ...props, columns: [...props.columns] };
+ expect(wrapper.instance().shouldUpdateByColumnsForSimpleCheck(nextProps)).toBeFalsy();
+ });
+ });
+ });
+
describe('shouldUpdatedByNormalProps', () => {
describe('when nextProps.rowIndex is not eq props.rowIndex', () => {
beforeEach(() => {