Compare commits

..

12 Commits

Author SHA1 Message Date
AllenFang
258ea43225 Publish
- react-bootstrap-table2-example@0.1.10
 - react-bootstrap-table2-filter@0.3.0
 - react-bootstrap-table2-paginator@0.1.5
 - react-bootstrap-table-next@0.1.14
2018-06-24 22:42:50 +08:00
Allen
7a7b708029 Merge pull request #390 from react-bootstrap-table/develop
20180624 release
2018-06-24 22:40:15 +08:00
Allen
0cf89861af Merge pull request #389 from react-bootstrap-table/feat/custom-filter
Implement custom filter
2018-06-24 15:33:22 +08:00
AllenFang
eb74625835 patch docs for custom filter 2018-06-24 15:15:57 +08:00
AllenFang
cbaec4c655 add stories for custom filter 2018-06-24 15:04:59 +08:00
AllenFang
04c21cb63d implement custom filter 2018-06-24 15:03:46 +08:00
AllenFang
7d72002b6e fix wrong eslint rule 2018-06-24 13:16:48 +08:00
AllenFang
279cc25da0 Merge branch 'develop' of https://github.com/react-bootstrap-table/react-bootstrap-table2 into develop 2018-06-24 13:16:07 +08:00
AllenFang
1152bb8440 fix #380 2018-06-23 13:49:38 +08:00
AllenFang
88befb8136 fix #380 2018-06-23 13:47:53 +08:00
Allen
42c6bc0337 Merge pull request #371 from sean-ww/fix/remote-filtered-pagination
Prevent remote pagination from setting the page incorrectly
2018-06-23 12:59:02 +08:00
sean
6e753bb955 Prevent remote pagination from setting the page incorrectly 2018-06-06 15:11:54 +02:00
20 changed files with 498 additions and 18 deletions

View File

@@ -82,7 +82,7 @@ Please see [available filter configuration](https://react-bootstrap-table.github
- [x] Text Filter - [x] Text Filter
- [x] Custom Text Filter - [x] Custom Text Filter
- [x] Remote Filter - [x] Remote Filter
- [ ] Custom Filter Component - [x] Custom Filter Component
- [ ] Regex Filter - [ ] Regex Filter
- [x] Select Filter - [x] Select Filter
- [x] Custom Select Filter - [x] Custom Select Filter

View File

@@ -0,0 +1,184 @@
/* eslint no-return-assign: 0 */
import React from 'react';
import PropTypes from 'prop-types';
import BootstrapTable from 'react-bootstrap-table-next';
import filterFactory, { textFilter, customFilter, Comparator, FILTER_TYPES } from 'react-bootstrap-table2-filter';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';
const products = productsGenerator(8);
class PriceFilter extends React.Component {
static propTypes = {
column: PropTypes.object.isRequired,
onFilter: PropTypes.func.isRequired
}
constructor(props) {
super(props);
this.filter = this.filter.bind(this);
this.getValue = this.getValue.bind(this);
this.onChange = this.onChange.bind(this);
this.state = { value: 2100 };
}
onChange(e) {
this.setState({ value: e.target.value });
}
getValue() {
return parseInt(this.range.value, 10);
}
filter() {
this.props.onFilter({
number: this.getValue(),
comparator: this.select.value
});
}
render() {
return [
<input
key="range"
ref={ node => this.range = node }
type="range"
min="2100"
max="2110"
onChange={ this.onChange }
/>,
<p
key="show"
ref={ node => this.showValue = node }
style={ { textAlign: 'center' } }
>
{ this.state.value }
</p>,
<select
key="select"
ref={ node => this.select = node }
className="form-control"
>
<option value={ Comparator.GT }>&gt;</option>
<option value={ Comparator.EQ }>=</option>
<option value={ Comparator.LT }>&lt;</option>
</select>,
<button
key="submit"
className="btn btn-warning"
onClick={ this.filter }
>
{ `Filter ${this.props.column.text}` }
</button>
];
}
}
const columns = [{
dataField: 'id',
text: 'Product ID'
}, {
dataField: 'name',
text: 'Product Name',
filter: textFilter()
}, {
dataField: 'price',
text: 'Product Price',
filter: customFilter({
type: FILTER_TYPES.NUMBER // ask react-bootstrap-table to filter data as number
}),
filterRenderer: (onFilter, column) =>
<PriceFilter onFilter={ onFilter } column={ column } />
}];
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
import filterFactory, { textFilter, customFilter, Comparator, FILTER_TYPES } from 'react-bootstrap-table2-filter';
class PriceFilter extends React.Component {
static propTypes = {
column: PropTypes.object.isRequired,
onFilter: PropTypes.func.isRequired
}
constructor(props) {
super(props);
this.filter = this.filter.bind(this);
this.getValue = this.getValue.bind(this);
this.onChange = this.onChange.bind(this);
this.state = { value: 2100 };
}
onChange(e) {
this.setState({ value: e.target.value });
}
getValue() {
return parseInt(this.range.value, 10);
}
filter() {
this.props.onFilter({
number: this.getValue(),
comparator: this.select.value
});
}
render() {
return [
<input
key="range"
ref={ node => this.range = node }
type="range"
min="2100"
max="2110"
onChange={ this.onChange }
/>,
<p
key="show"
ref={ node => this.showValue = node }
style={ { textAlign: 'center' } }
>
{ this.state.value }
</p>,
<select
key="select"
ref={ node => this.select = node }
className="form-control"
>
<option value={ Comparator.GT }>&gt;</option>
<option value={ Comparator.EQ }>=</option>
<option value={ Comparator.LT }>&lt;</option>
</select>,
<button
key="submit"
className="btn btn-warning"
onClick={ this.filter }
>
{ \`Filter $\{this.props.column.text}\` }
</button>
];
}
}
const columns = [{
dataField: 'id',
text: 'Product ID'
}, {
dataField: 'name',
text: 'Product Name',
filter: textFilter()
}, {
dataField: 'price',
text: 'Product Price',
filter: customFilter({
type: FILTER_TYPES.NUMBER // ask react-bootstrap-table to filter data as number
}),
filterRenderer: (onFilter, column) =>
<PriceFilter onFilter={ onFilter } column={ column } />
}];
<BootstrapTable keyField='id' data={ products } columns={ columns } filter={ filterFactory() } />
`;
export default () => (
<div>
<BootstrapTable
keyField="id"
data={ products }
columns={ columns }
filter={ filterFactory() }
/>
<Code>{ sourceCode }</Code>
</div>
);

View File

@@ -0,0 +1,128 @@
/* eslint no-return-assign: 0 */
import React from 'react';
import PropTypes from 'prop-types';
import BootstrapTable from 'react-bootstrap-table-next';
import filterFactory, { textFilter, customFilter } from 'react-bootstrap-table2-filter';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';
const products = productsGenerator(8);
class PriceFilter extends React.Component {
static propTypes = {
column: PropTypes.object.isRequired,
onFilter: PropTypes.func.isRequired
}
constructor(props) {
super(props);
this.filter = this.filter.bind(this);
this.getValue = this.getValue.bind(this);
}
getValue() {
return this.input.value;
}
filter() {
this.props.onFilter(this.getValue());
}
render() {
return [
<input
key="input"
ref={ node => this.input = node }
type="text"
placeholder="Input price"
/>,
<button
key="submit"
className="btn btn-warning"
onClick={ this.filter }
>
{ `Find ${this.props.column.text}` }
</button>
];
}
}
const columns = [{
dataField: 'id',
text: 'Product ID'
}, {
dataField: 'name',
text: 'Product Name',
filter: textFilter()
}, {
dataField: 'price',
text: 'Product Price',
filter: customFilter(),
filterRenderer: (onFilter, column) =>
<PriceFilter onFilter={ onFilter } column={ column } />
}];
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
import filterFactory, { textFilter, customFilter } from 'react-bootstrap-table2-filter';
class PriceFilter extends React.Component {
static propTypes = {
column: PropTypes.object.isRequired,
onFilter: PropTypes.func.isRequired
}
constructor(props) {
super(props);
this.filter = this.filter.bind(this);
this.getValue = this.getValue.bind(this);
}
getValue() {
return this.input.value;
}
filter() {
this.props.onFilter(this.getValue());
}
render() {
return [
<input
key="input"
ref={ node => this.input = node }
type="text"
placeholder="Input price"
/>,
<button
key="submit"
className="btn btn-warning"
onClick={ this.filter }
>
{ \`Filter $\{this.props.column.text}\` }
</button>
];
}
}
const columns = [{
dataField: 'id',
text: 'Product ID'
}, {
dataField: 'name',
text: 'Product Name',
filter: textFilter()
}, {
dataField: 'price',
text: 'Product Price',
filter: customFilter(),
filterRenderer: (onFilter, column) =>
<PriceFilter onFilter={ onFilter } column={ column } />
}];
<BootstrapTable keyField='id' data={ products } columns={ columns } filter={ filterFactory() } />
`;
export default () => (
<div>
<BootstrapTable
keyField="id"
data={ products }
columns={ columns }
filter={ filterFactory() }
/>
<Code>{ sourceCode }</Code>
</div>
);

View File

@@ -1,6 +1,6 @@
{ {
"name": "react-bootstrap-table2-example", "name": "react-bootstrap-table2-example",
"version": "0.1.9", "version": "0.1.10",
"description": "", "description": "",
"main": "index.js", "main": "index.js",
"private": true, "private": true,

View File

@@ -55,6 +55,8 @@ import ProgrammaticallyTextFilter from 'examples/column-filter/programmatically-
import ProgrammaticallySelectFilter from 'examples/column-filter/programmatically-select-filter'; import ProgrammaticallySelectFilter from 'examples/column-filter/programmatically-select-filter';
import ProgrammaticallyNumberFilter from 'examples/column-filter/programmatically-number-filter'; import ProgrammaticallyNumberFilter from 'examples/column-filter/programmatically-number-filter';
import ProgrammaticallyDateFilter from 'examples/column-filter/programmatically-date-filter'; import ProgrammaticallyDateFilter from 'examples/column-filter/programmatically-date-filter';
import CustomFilter from 'examples/column-filter/custom-filter';
import AdvanceCustomFilter from 'examples/column-filter/advance-custom-filter';
// work on rows // work on rows
import RowStyleTable from 'examples/rows/row-style'; import RowStyleTable from 'examples/rows/row-style';
@@ -186,7 +188,9 @@ storiesOf('Column Filter', module)
.add('Programmatically Text Filter', () => <ProgrammaticallyTextFilter />) .add('Programmatically Text Filter', () => <ProgrammaticallyTextFilter />)
.add('Programmatically Select Filter', () => <ProgrammaticallySelectFilter />) .add('Programmatically Select Filter', () => <ProgrammaticallySelectFilter />)
.add('Programmatically Number Filter', () => <ProgrammaticallyNumberFilter />) .add('Programmatically Number Filter', () => <ProgrammaticallyNumberFilter />)
.add('Programmatically Date Filter', () => <ProgrammaticallyDateFilter />); .add('Programmatically Date Filter', () => <ProgrammaticallyDateFilter />)
.add('Custom Filter', () => <CustomFilter />)
.add('Advance Custom Filter', () => <AdvanceCustomFilter />);
storiesOf('Work on Rows', module) storiesOf('Work on Rows', module)
.add('Customize Row Style', () => <RowStyleTable />) .add('Customize Row Style', () => <RowStyleTable />)

View File

@@ -20,6 +20,7 @@ You can get all types of filters via import and these filters are a factory func
* SelectFilter * SelectFilter
* NumberFilter * NumberFilter
* DateFilter * DateFilter
* CustomFilter
* **Coming soon!** * **Coming soon!**
## Add CSS ## Add CSS
@@ -189,4 +190,54 @@ const dateFilter = dateFilter({
}) })
// omit... // omit...
``` ```
## Custom Filter
```js
import filterFactory, { customFilter } from 'react-bootstrap-table2-filter';
const columns = [..., {
dataField: 'date',
text: 'Product Name',
filter: customFilter(),
filterRenderer: (onFilter, column) => .....
}];
<BootstrapTable keyField='id' data={ products } columns={ columns } filter={ filterFactory() } />
```
In custom filter case, you are suppose to finish following two steps:
1. Call `customFilter` and pass to `column.filter`
2. Give `column.filterRenderer` as a callback function and return your custom filter element.
### column.filterRenderer
This function will pass two argument to you:
1. `onFilter`: call it to trigger filter when you need.
2. `column`: Just the column object!
In the end, please remember to return your custom filter element!
### customFilter
`customFilter` function just same as `textFilter`, `selectFilter` etc, it is for customization reason. However, in the custom filter case, there's only one props is valid: `type`
```js
import filterFactory, { FILTER_TYPES } from 'react-bootstrap-table2-filter';
const customFilter = customFilter({
type: FILTER_TYPES.NUMBER, // default is FILTER_TYPES.TEXT
})
```
`type` is a way to ask `react-bootstrap-table` to filter you data as number, select, date or normal text.
### FILTER_TYPES
Following properties is valid in `FILTER_TYPES`:
* TEXT
* SELECT
* NUMBER
* DATE

View File

@@ -4,12 +4,15 @@ import NumberFilter from './src/components/number';
import DateFilter from './src/components/date'; import DateFilter from './src/components/date';
import wrapperFactory from './src/wrapper'; import wrapperFactory from './src/wrapper';
import * as Comparison from './src/comparison'; import * as Comparison from './src/comparison';
import { FILTER_TYPE } from './src/const';
export default (options = {}) => ({ export default (options = {}) => ({
wrapperFactory, wrapperFactory,
options options
}); });
export const FILTER_TYPES = FILTER_TYPE;
export const Comparator = Comparison; export const Comparator = Comparison;
export const textFilter = (props = {}) => ({ export const textFilter = (props = {}) => ({
@@ -31,3 +34,7 @@ export const dateFilter = (props = {}) => ({
Filter: DateFilter, Filter: DateFilter,
props props
}); });
export const customFilter = (props = {}) => ({
props
});

View File

@@ -1,6 +1,6 @@
{ {
"name": "react-bootstrap-table2-filter", "name": "react-bootstrap-table2-filter",
"version": "0.2.0", "version": "0.3.0",
"description": "it's a column filter addon for react-bootstrap-table2", "description": "it's a column filter addon for react-bootstrap-table2",
"main": "./lib/index.js", "main": "./lib/index.js",
"repository": { "repository": {

View File

@@ -1,4 +1,5 @@
/* eslint react/require-default-props: 0 */ /* eslint react/require-default-props: 0 */
/* eslint jsx-a11y/no-static-element-interactions: 0 */
/* eslint no-return-assign: 0 */ /* eslint no-return-assign: 0 */
/* eslint prefer-template: 0 */ /* eslint prefer-template: 0 */
import React, { Component } from 'react'; import React, { Component } from 'react';
@@ -121,7 +122,11 @@ class DateFilter extends Component {
} = this.props; } = this.props;
return ( return (
<div className={ `filter date-filter ${className}` } style={ style }> <div
onClick={ e => e.stopPropagation() }
className={ `filter date-filter ${className}` }
style={ style }
>
<select <select
ref={ n => this.dateFilterComparator = n } ref={ n => this.dateFilterComparator = n }
style={ comparatorStyle } style={ comparatorStyle }

View File

@@ -1,3 +1,4 @@
/* eslint jsx-a11y/no-static-element-interactions: 0 */
/* eslint react/require-default-props: 0 */ /* eslint react/require-default-props: 0 */
/* eslint no-return-assign: 0 */ /* eslint no-return-assign: 0 */
@@ -167,7 +168,11 @@ class NumberFilter extends Component {
`; `;
return ( return (
<div className={ `filter number-filter ${className}` } style={ style }> <div
onClick={ e => e.stopPropagation() }
className={ `filter number-filter ${className}` }
style={ style }
>
<select <select
ref={ n => this.numberFilterComparator = n } ref={ n => this.numberFilterComparator = n }
style={ comparatorStyle } style={ comparatorStyle }

View File

@@ -116,6 +116,7 @@ class SelectFilter extends Component {
style={ style } style={ style }
className={ selectClass } className={ selectClass }
onChange={ this.filter } onChange={ this.filter }
onClick={ e => e.stopPropagation() }
defaultValue={ defaultValue !== undefined ? defaultValue : '' } defaultValue={ defaultValue !== undefined ? defaultValue : '' }
> >
{ this.getOptions() } { this.getOptions() }

View File

@@ -20,6 +20,7 @@ export default (Base, {
super(props); super(props);
this.state = { currFilters: {}, isDataChanged: props.isDataChanged || false }; this.state = { currFilters: {}, isDataChanged: props.isDataChanged || false };
this.onFilter = this.onFilter.bind(this); this.onFilter = this.onFilter.bind(this);
this.onExternalFilter = this.onExternalFilter.bind(this);
} }
componentWillReceiveProps({ isDataChanged, store, columns }) { componentWillReceiveProps({ isDataChanged, store, columns }) {
@@ -78,12 +79,19 @@ export default (Base, {
}; };
} }
onExternalFilter(column, filterType) {
return (value) => {
this.onFilter(column, filterType)(value);
};
}
render() { render() {
return ( return (
<Base <Base
{ ...this.props } { ...this.props }
data={ this.props.store.data } data={ this.props.store.data }
onFilter={ this.onFilter } onFilter={ this.onFilter }
onExternalFilter={ this.onExternalFilter }
isDataChanged={ this.state.isDataChanged } isDataChanged={ this.state.isDataChanged }
/> />
); );

View File

@@ -1,6 +1,6 @@
{ {
"name": "react-bootstrap-table2-paginator", "name": "react-bootstrap-table2-paginator",
"version": "0.1.4", "version": "0.1.5",
"description": "it's the pagination addon for react-bootstrap-table2", "description": "it's the pagination addon for react-bootstrap-table2",
"main": "./lib/index.js", "main": "./lib/index.js",
"repository": { "repository": {

View File

@@ -54,11 +54,14 @@ export default (Base, {
if (typeof page !== 'undefined' && currPage !== page) { // user defined page if (typeof page !== 'undefined' && currPage !== page) { // user defined page
currPage = page; currPage = page;
needNewState = true; needNewState = true;
} else if (nextProps.isDataChanged) { // user didn't defined page but data change } else if (nextProps.isDataChanged) {
currPage = typeof pageStartIndex !== 'undefined' ? pageStartIndex : Const.PAGE_START_INDEX;
needNewState = true; needNewState = true;
} }
if (typeof currPage === 'undefined') {
currPage = typeof pageStartIndex !== 'undefined' ? pageStartIndex : Const.PAGE_START_INDEX;
}
if (typeof sizePerPage !== 'undefined') { if (typeof sizePerPage !== 'undefined') {
currSizePerPage = sizePerPage; currSizePerPage = sizePerPage;
needNewState = true; needNewState = true;

View File

@@ -177,10 +177,11 @@ describe('Wrapper', () => {
}); });
}); });
describe('when nextProps.isDataChanged is true and options.pageStartIndex is existing', () => { describe('when nextProps.isDataChanged is true, currPage is undefined and options.pageStartIndex exists', () => {
beforeEach(() => { beforeEach(() => {
nextProps.isDataChanged = true; nextProps.isDataChanged = true;
nextProps.pagination.options.pageStartIndex = 0; nextProps.pagination.options.pageStartIndex = 0;
instance.state.currPage = undefined;
instance.componentWillReceiveProps(nextProps); instance.componentWillReceiveProps(nextProps);
}); });

View File

@@ -1,6 +1,6 @@
{ {
"name": "react-bootstrap-table-next", "name": "react-bootstrap-table-next",
"version": "0.1.13", "version": "0.1.14",
"description": "Next generation of react-bootstrap-table", "description": "Next generation of react-bootstrap-table",
"main": "./lib/index.js", "main": "./lib/index.js",
"repository": { "repository": {

View File

@@ -90,6 +90,7 @@ class BootstrapTable extends PropsBaseResolver(Component) {
sortOrder={ store.sortOrder } sortOrder={ store.sortOrder }
onSort={ this.props.onSort } onSort={ this.props.onSort }
onFilter={ this.props.onFilter } onFilter={ this.props.onFilter }
onExternalFilter={ this.props.onExternalFilter }
selectRow={ headerCellSelectionInfo } selectRow={ headerCellSelectionInfo }
/> />
<Body <Body
@@ -162,7 +163,8 @@ BootstrapTable.propTypes = {
overlay: PropTypes.func, overlay: PropTypes.func,
onTableChange: PropTypes.func, onTableChange: PropTypes.func,
onSort: PropTypes.func, onSort: PropTypes.func,
onFilter: PropTypes.func onFilter: PropTypes.func,
onExternalFilter: PropTypes.func
}; };
BootstrapTable.defaultProps = { BootstrapTable.defaultProps = {

View File

@@ -17,13 +17,15 @@ const HeaderCell = (props) => {
sorting, sorting,
sortOrder, sortOrder,
isLastSorting, isLastSorting,
onFilter onFilter,
onExternalFilter
} = props; } = props;
const { const {
text, text,
sort, sort,
filter, filter,
filterRenderer,
headerTitle, headerTitle,
headerAlign, headerAlign,
headerFormatter, headerFormatter,
@@ -89,7 +91,11 @@ const HeaderCell = (props) => {
if (cellClasses) cellAttrs.className = cs(cellAttrs.className, cellClasses); if (cellClasses) cellAttrs.className = cs(cellAttrs.className, cellClasses);
if (!_.isEmptyObject(cellStyle)) cellAttrs.style = cellStyle; if (!_.isEmptyObject(cellStyle)) cellAttrs.style = cellStyle;
if (filter) {
if (filterRenderer) {
const onCustomFilter = onExternalFilter(column, filter.props.type);
filterElm = filterRenderer(onCustomFilter, column);
} else if (filter) {
filterElm = <filter.Filter { ...filter.props } onFilter={ onFilter } column={ column } />; filterElm = <filter.Filter { ...filter.props } onFilter={ onFilter } column={ column } />;
} }
@@ -136,6 +142,7 @@ HeaderCell.propTypes = {
editorRenderer: PropTypes.func, editorRenderer: PropTypes.func,
validator: PropTypes.func, validator: PropTypes.func,
filter: PropTypes.object, filter: PropTypes.object,
filterRenderer: PropTypes.func,
filterValue: PropTypes.func filterValue: PropTypes.func
}).isRequired, }).isRequired,
index: PropTypes.number.isRequired, index: PropTypes.number.isRequired,
@@ -143,7 +150,8 @@ HeaderCell.propTypes = {
sorting: PropTypes.bool, sorting: PropTypes.bool,
sortOrder: PropTypes.oneOf([Const.SORT_ASC, Const.SORT_DESC]), sortOrder: PropTypes.oneOf([Const.SORT_ASC, Const.SORT_DESC]),
isLastSorting: PropTypes.bool, isLastSorting: PropTypes.bool,
onFilter: PropTypes.func onFilter: PropTypes.func,
onExternalFilter: PropTypes.func
}; };
export default HeaderCell; export default HeaderCell;

View File

@@ -15,7 +15,8 @@ const Header = (props) => {
onFilter, onFilter,
sortField, sortField,
sortOrder, sortOrder,
selectRow selectRow,
onExternalFilter
} = props; } = props;
return ( return (
@@ -39,6 +40,7 @@ const Header = (props) => {
onSort={ onSort } onSort={ onSort }
sorting={ currSort } sorting={ currSort }
onFilter={ onFilter } onFilter={ onFilter }
onExternalFilter={ onExternalFilter }
sortOrder={ sortOrder } sortOrder={ sortOrder }
isLastSorting={ isLastSorting } isLastSorting={ isLastSorting }
/>); />);
@@ -57,7 +59,8 @@ Header.propTypes = {
onFilter: PropTypes.func, onFilter: PropTypes.func,
sortField: PropTypes.string, sortField: PropTypes.string,
sortOrder: PropTypes.string, sortOrder: PropTypes.string,
selectRow: PropTypes.object selectRow: PropTypes.object,
onExternalFilter: PropTypes.func
}; };
export default Header; export default Header;

View File

@@ -669,4 +669,74 @@ describe('HeaderCell', () => {
}); });
}); });
}); });
describe('when column.filter is defined', () => {
const onFilter = jest.fn();
const filterProps = { a: 123 };
const Filter = () => <div>test</div>;
let column;
beforeEach(() => {
onFilter.mockClear();
column = {
dataField: 'id',
text: 'ID',
filter: {
props: filterProps,
Filter
}
};
wrapper = shallow(<HeaderCell column={ column } index={ index } onFilter={ onFilter } />);
});
it('should render successfully', () => {
expect(wrapper.length).toBe(1);
expect(wrapper.find('th').length).toBe(1);
});
it('should render filter correctly', () => {
expect(wrapper.find(Filter).length).toBe(1);
expect(wrapper.find(Filter).props()).toEqual({
column,
onFilter,
...filterProps
});
});
});
describe('when column.filter and column.filterRenderer is defined', () => {
const onExternalFilter = jest.fn();
const filterProps = { a: 123 };
const Filter = () => <div>test</div>;
const filterRenderer = jest.fn().mockReturnValue(<Filter />);
let column;
beforeEach(() => {
onExternalFilter.mockClear();
filterRenderer.mockClear();
column = {
dataField: 'id',
text: 'ID',
filter: {
props: filterProps
},
filterRenderer
};
wrapper = shallow(
<HeaderCell column={ column } index={ index } onExternalFilter={ onExternalFilter } />);
});
it('should render successfully', () => {
expect(wrapper.length).toBe(1);
expect(wrapper.find('th').length).toBe(1);
});
it('should render filter correctly', () => {
expect(wrapper.find(Filter).length).toBe(1);
});
it('should call filterRenderer function correctly', () => {
expect(filterRenderer).toHaveBeenCalledTimes(1);
});
});
}); });