diff --git a/.travis.yml b/.travis.yml index 4120d0a..cc7025e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,6 +11,8 @@ branches: only: - master - develop + except: + - gh-pages-src before_install: - curl -o- -L https://yarnpkg.com/install.sh | bash -s diff --git a/docs/row-selection.md b/docs/row-selection.md index b75aa1f..ac7eba7 100644 --- a/docs/row-selection.md +++ b/docs/row-selection.md @@ -158,12 +158,12 @@ const selectRow = { ### selectRow.onSelect - [Function] This callback function will be called when a row is select/unselect and pass following three arguments: -`row`, `isSelect` and `rowIndex`. +`row`, `isSelect`, `rowIndex` and `e`. ```js const selectRow = { mode: 'checkbox', - onSelect: (row, isSelect, rowIndex) => { + onSelect: (row, isSelect, rowIndex, e) => { // ... } }; @@ -175,7 +175,7 @@ This callback function will be called when select/unselect all and it only work ```js const selectRow = { mode: 'checkbox', - onSelectAll: (isSelect, results) => { + onSelectAll: (isSelect, results, e) => { // ... } }; diff --git a/gulpfile.babel.js b/gulpfile.babel.js index 77b5c9f..f202fda 100644 --- a/gulpfile.babel.js +++ b/gulpfile.babel.js @@ -72,9 +72,15 @@ function styles() { .pipe(gulp.dest(PKG_PATH)); } -function umd() { - return gulp.src('./webpack.prod.config.babel.js') - .pipe(shell(['webpack --config <%= file.path %>'])); +function umd(done) { + gulp.parallel( + () => gulp.src('./webpack/next.umd.babel.js').pipe(shell(['webpack --config <%= file.path %>'])), + () => gulp.src('./webpack/editor.umd.babel.js').pipe(shell(['webpack --config <%= file.path %>'])), + () => gulp.src('./webpack/filter.umd.babel.js').pipe(shell(['webpack --config <%= file.path %>'])), + () => gulp.src('./webpack/overlay.umd.babel.js').pipe(shell(['webpack --config <%= file.path %>'])), + () => gulp.src('./webpack/paginator.umd.babel.js').pipe(shell(['webpack --config <%= file.path %>'])) + )(); + done(); } const buildJS = gulp.parallel(umd, scripts); diff --git a/packages/react-bootstrap-table2-example/examples/column-filter/programmatically-number-filter.js b/packages/react-bootstrap-table2-example/examples/column-filter/programmatically-number-filter.js new file mode 100644 index 0000000..12a5ebc --- /dev/null +++ b/packages/react-bootstrap-table2-example/examples/column-filter/programmatically-number-filter.js @@ -0,0 +1,85 @@ +import React from 'react'; +import BootstrapTable from 'react-bootstrap-table-next'; +import filterFactory, { numberFilter, Comparator } from 'react-bootstrap-table2-filter'; +import Code from 'components/common/code-block'; +import { productsGenerator } from 'utils/common'; + +const products = productsGenerator(8); + +let priceFilter; + +const columns = [{ + dataField: 'id', + text: 'Product ID' +}, { + dataField: 'name', + text: 'Product Name' +}, { + dataField: 'price', + text: 'Product Price', + filter: numberFilter({ + getFilter: (filter) => { + // pricerFilter was assigned once the component has been mounted. + priceFilter = filter; + } + }) +}]; + +const handleClick = () => { + priceFilter({ + number: 2103, + comparator: Comparator.GT + }); +}; + +const sourceCode = `\ +import BootstrapTable from 'react-bootstrap-table-next'; +import filterFactory, { numberFilter } from 'react-bootstrap-table2-filter'; + +let priceFilter; + +const columns = [{ + dataField: 'id', + text: 'Product ID' +}, { + dataField: 'name', + text: 'Product Name' +}, { + dataField: 'price', + text: 'Product Price', + filter: numberFilter({ + getFilter: (filter) => { + // pricerFilter was assigned once the component has been mounted. + priceFilter = filter; + } + }) +}]; + +const handleClick = () => { + priceFilter({ + number: 2103, + comparator: Comparator.GT + }); +}; + +export default () => ( +
+ + + +
+); +`; + +export default () => ( +
+ + + { sourceCode } +
+); diff --git a/packages/react-bootstrap-table2-example/examples/column-filter/programmatically-select-filter.js b/packages/react-bootstrap-table2-example/examples/column-filter/programmatically-select-filter.js new file mode 100644 index 0000000..d368af5 --- /dev/null +++ b/packages/react-bootstrap-table2-example/examples/column-filter/programmatically-select-filter.js @@ -0,0 +1,96 @@ +import React from 'react'; +import BootstrapTable from 'react-bootstrap-table-next'; +import filterFactory, { selectFilter } from 'react-bootstrap-table2-filter'; +import Code from 'components/common/code-block'; +import { productsQualityGenerator } from 'utils/common'; + +const products = productsQualityGenerator(6); + +let qualityFilter; + +const selectOptions = { + 0: 'good', + 1: 'Bad', + 2: 'unknown' +}; + +const columns = [{ + dataField: 'id', + text: 'Product ID' +}, { + dataField: 'name', + text: 'Product Name' +}, { + dataField: 'quality', + text: 'Product Quality', + formatter: cell => selectOptions[cell], + filter: selectFilter({ + options: selectOptions, + getFilter: (filter) => { + // qualityFilter was assigned once the component has been mounted. + qualityFilter = filter; + } + }) +}]; + +const handleClick = () => { + qualityFilter(0); +}; + +const sourceCode = `\ +import BootstrapTable from 'react-bootstrap-table-next'; +import filterFactory, { selectFilter } from 'react-bootstrap-table2-filter'; + +let qualityFilter; + +const selectOptions = { + 0: 'good', + 1: 'Bad', + 2: 'unknown' +}; + +const columns = [{ + dataField: 'id', + text: 'Product ID' +}, { + dataField: 'name', + text: 'Product Name' +}, { + dataField: 'quality', + text: 'Product Quality', + formatter: cell => selectOptions[cell], + filter: selectFilter({ + options: selectOptions, + getFilter: (filter) => { + // qualityFilter was assigned once the component has been mounted. + qualityFilter = filter; + } + }) +}]; + +const handleClick = () => { + qualityFilter(0); +}; + +export default () => ( +
+ + + +
+); +`; + +export default () => ( +
+ + + + { sourceCode } +
+); diff --git a/packages/react-bootstrap-table2-example/examples/column-filter/programmatically-text-filter.js b/packages/react-bootstrap-table2-example/examples/column-filter/programmatically-text-filter.js new file mode 100644 index 0000000..f1080c0 --- /dev/null +++ b/packages/react-bootstrap-table2-example/examples/column-filter/programmatically-text-filter.js @@ -0,0 +1,81 @@ +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); + +let nameFilter; + +const columns = [{ + dataField: 'id', + text: 'Product ID' +}, { + dataField: 'name', + text: 'Product Name', + filter: textFilter({ + getFilter: (filter) => { + // nameFilter was assigned once the component has been mounted. + nameFilter = filter; + } + }) +}, { + dataField: 'price', + text: 'Product Price', + filter: textFilter() +}]; + +const handleClick = () => { + nameFilter(0); +}; + +const sourceCode = `\ +import BootstrapTable from 'react-bootstrap-table-next'; +import filterFactory, { textFilter } from 'react-bootstrap-table2-filter'; + +let nameFilter; + +const columns = [{ + dataField: 'id', + text: 'Product ID' +}, { + dataField: 'name', + text: 'Product Name', + filter: textFilter({ + getFilter: (filter) => { + // nameFilter was assigned once the component has been mounted. + nameFilter = filter; + } + }) +}, { + dataField: 'price', + text: 'Product Price', + filter: textFilter() +}]; + +const handleClick = () => { + nameFilter(0); +}; + +export default () => ( +
+ + + +
+); +`; + +export default () => ( +
+ + + { sourceCode } +
+); diff --git a/packages/react-bootstrap-table2-example/examples/row-selection/selection-hooks.js b/packages/react-bootstrap-table2-example/examples/row-selection/selection-hooks.js index 9b104c0..bc7c298 100644 --- a/packages/react-bootstrap-table2-example/examples/row-selection/selection-hooks.js +++ b/packages/react-bootstrap-table2-example/examples/row-selection/selection-hooks.js @@ -22,14 +22,16 @@ const columns = [{ const selectRow = { mode: 'checkbox', clickToSelect: true, - onSelect: (row, isSelect, rowIndex) => { + onSelect: (row, isSelect, rowIndex, e) => { console.log(row.id); console.log(isSelect); console.log(rowIndex); + console.log(e); }, - onSelectAll: (isSelect, rows) => { + onSelectAll: (isSelect, rows, e) => { console.log(isSelect); console.log(rows); + console.log(e); } }; @@ -49,7 +51,18 @@ const columns = [{ const selectRow = { mode: 'checkbox', - clickToSelect: true + clickToSelect: true, + onSelect: (row, isSelect, rowIndex, e) => { + console.log(row.id); + console.log(isSelect); + console.log(rowIndex); + console.log(e); + }, + onSelectAll: (isSelect, rows, e) => { + console.log(isSelect); + console.log(rows); + console.log(e); + } }; ) .add('Custom Select Filter', () => ) .add('Custom Number Filter', () => ) - .add('Custom Filter Value', () => ); + .add('Custom Filter Value', () => ) + .add('Programmatically Text Filter ', () => ) + .add('Programmatically Select Filter ', () => ) + .add('Programmatically Number Filter ', () => ); storiesOf('Work on Rows', module) .add('Customize Row Style', () => ) diff --git a/packages/react-bootstrap-table2-filter/src/components/number.js b/packages/react-bootstrap-table2-filter/src/components/number.js index 3c2b612..ebf55e8 100644 --- a/packages/react-bootstrap-table2-filter/src/components/number.js +++ b/packages/react-bootstrap-table2-filter/src/components/number.js @@ -1,3 +1,4 @@ +/* eslint react/require-default-props: 0 */ /* eslint no-return-assign: 0 */ import React, { Component } from 'react'; @@ -30,11 +31,25 @@ class NumberFilter extends Component { } componentDidMount() { - const { column, onFilter } = this.props; + const { column, onFilter, getFilter } = this.props; const comparator = this.numberFilterComparator.value; const number = this.numberFilter.value; if (comparator && number) { - onFilter(column, { number, comparator }, FILTER_TYPE.NUMBER); + onFilter(column, FILTER_TYPE.NUMBER)({ number, comparator }); + } + + // export onFilter function to allow users to access + if (getFilter) { + getFilter((filterVal) => { + this.setState(() => ({ isSelected: (filterVal !== '') })); + this.numberFilterComparator.value = filterVal.comparator; + this.numberFilter.value = filterVal.number; + + onFilter(column, FILTER_TYPE.NUMBER)({ + number: filterVal.number, + comparator: filterVal.comparator + }); + }); } } @@ -53,7 +68,7 @@ class NumberFilter extends Component { } const filterValue = e.target.value; this.timeout = setTimeout(() => { - onFilter(column, { number: filterValue, comparator }, FILTER_TYPE.NUMBER); + onFilter(column, FILTER_TYPE.NUMBER)({ number: filterValue, comparator }); }, delay); } @@ -65,7 +80,7 @@ class NumberFilter extends Component { // if (comparator === '') { // return; // } - onFilter(column, { number: value, comparator }, FILTER_TYPE.NUMBER); + onFilter(column, FILTER_TYPE.NUMBER)({ number: value, comparator }); } onChangeComparator(e) { @@ -75,7 +90,7 @@ class NumberFilter extends Component { // if (value === '') { // return; // } - onFilter(column, { number: value, comparator }, FILTER_TYPE.NUMBER); + onFilter(column, FILTER_TYPE.NUMBER)({ number: value, comparator }); } getComparatorOptions() { @@ -116,7 +131,7 @@ class NumberFilter extends Component { this.setState(() => ({ isSelected: (number !== '') })); this.numberFilterComparator.value = comparator; this.numberFilter.value = number; - onFilter(column, { number, comparator }, FILTER_TYPE.NUMBER); + onFilter(column, FILTER_TYPE.NUMBER)({ number, comparator }); } cleanFiltered() { @@ -126,7 +141,7 @@ class NumberFilter extends Component { this.setState(() => ({ isSelected: (value !== '') })); this.numberFilterComparator.value = comparator; this.numberFilter.value = value; - onFilter(column, { number: value, comparator }, FILTER_TYPE.NUMBER); + onFilter(column, FILTER_TYPE.NUMBER)({ number: value, comparator }); } render() { @@ -224,7 +239,8 @@ NumberFilter.propTypes = { comparatorStyle: PropTypes.object, comparatorClassName: PropTypes.string, numberStyle: PropTypes.object, - numberClassName: PropTypes.string + numberClassName: PropTypes.string, + getFilter: PropTypes.func }; NumberFilter.defaultProps = { diff --git a/packages/react-bootstrap-table2-filter/src/components/select.js b/packages/react-bootstrap-table2-filter/src/components/select.js index 7e17afd..ba2d306 100644 --- a/packages/react-bootstrap-table2-filter/src/components/select.js +++ b/packages/react-bootstrap-table2-filter/src/components/select.js @@ -25,9 +25,21 @@ class SelectFilter extends Component { } componentDidMount() { + const { column, onFilter, getFilter } = this.props; + const value = this.selectInput.value; if (value && value !== '') { - this.props.onFilter(this.props.column, value, FILTER_TYPE.SELECT); + onFilter(column, FILTER_TYPE.SELECT)(value); + } + + // export onFilter function to allow users to access + if (getFilter) { + getFilter((filterVal) => { + this.setState(() => ({ isSelected: filterVal !== '' })); + this.selectInput.value = filterVal; + + onFilter(column, FILTER_TYPE.SELECT)(filterVal); + }); } } @@ -41,7 +53,7 @@ class SelectFilter extends Component { if (needFilter) { const value = this.selectInput.value; if (value) { - this.props.onFilter(this.props.column, value, FILTER_TYPE.SELECT); + this.props.onFilter(this.props.column, FILTER_TYPE.SELECT)(value); } } } @@ -64,19 +76,19 @@ class SelectFilter extends Component { const value = (this.props.defaultValue !== undefined) ? this.props.defaultValue : ''; this.setState(() => ({ isSelected: value !== '' })); this.selectInput.value = value; - this.props.onFilter(this.props.column, value, FILTER_TYPE.SELECT); + this.props.onFilter(this.props.column, FILTER_TYPE.SELECT)(value); } applyFilter(value) { this.selectInput.value = value; this.setState(() => ({ isSelected: value !== '' })); - this.props.onFilter(this.props.column, value, FILTER_TYPE.SELECT); + this.props.onFilter(this.props.column, FILTER_TYPE.SELECT)(value); } filter(e) { const { value } = e.target; this.setState(() => ({ isSelected: value !== '' })); - this.props.onFilter(this.props.column, value, FILTER_TYPE.SELECT); + this.props.onFilter(this.props.column, FILTER_TYPE.SELECT)(value); } render() { @@ -90,6 +102,7 @@ class SelectFilter extends Component { comparator, withoutEmptyOption, caseSensitive, + getFilter, ...rest } = this.props; @@ -121,7 +134,8 @@ SelectFilter.propTypes = { className: PropTypes.string, withoutEmptyOption: PropTypes.bool, defaultValue: PropTypes.any, - caseSensitive: PropTypes.bool + caseSensitive: PropTypes.bool, + getFilter: PropTypes.func }; SelectFilter.defaultProps = { diff --git a/packages/react-bootstrap-table2-filter/src/components/text.js b/packages/react-bootstrap-table2-filter/src/components/text.js index ffbe702..3af8ae2 100644 --- a/packages/react-bootstrap-table2-filter/src/components/text.js +++ b/packages/react-bootstrap-table2-filter/src/components/text.js @@ -17,10 +17,21 @@ class TextFilter extends Component { value: props.defaultValue }; } + componentDidMount() { + const { onFilter, getFilter, column } = this.props; const defaultValue = this.input.value; + if (defaultValue) { - this.props.onFilter(this.props.column, defaultValue, FILTER_TYPE.TEXT); + onFilter(this.props.column, FILTER_TYPE.TEXT)(defaultValue); + } + + // export onFilter function to allow users to access + if (getFilter) { + getFilter((filterVal) => { + this.setState(() => ({ value: filterVal })); + onFilter(column, FILTER_TYPE.TEXT)(filterVal); + }); } } @@ -40,7 +51,7 @@ class TextFilter extends Component { const filterValue = e.target.value; this.setState(() => ({ value: filterValue })); this.timeout = setTimeout(() => { - this.props.onFilter(this.props.column, filterValue, FILTER_TYPE.TEXT); + this.props.onFilter(this.props.column, FILTER_TYPE.TEXT)(filterValue); }, this.props.delay); } @@ -53,12 +64,12 @@ class TextFilter extends Component { cleanFiltered() { const value = this.props.defaultValue; this.setState(() => ({ value })); - this.props.onFilter(this.props.column, value, FILTER_TYPE.TEXT); + this.props.onFilter(this.props.column, FILTER_TYPE.TEXT)(value); } applyFilter(filterText) { this.setState(() => ({ value: filterText })); - this.props.onFilter(this.props.column, filterText, FILTER_TYPE.TEXT); + this.props.onFilter(this.props.column, FILTER_TYPE.TEXT)(filterText); } handleClick(e) { @@ -77,8 +88,10 @@ class TextFilter extends Component { onFilter, caseSensitive, defaultValue, + getFilter, ...rest } = this.props; + // stopPropagation for onClick event is try to prevent sort was triggered. return ( ( data, dataField, - { filterVal = '', comparator = LIKE, caseSensitive }, + { filterVal: userInput = '', comparator = LIKE, caseSensitive }, customFilterValue -) => - data.filter((row) => { - let cell = _.get(row, dataField); - if (customFilterValue) { - cell = customFilterValue(cell, row); - } - const cellStr = _.isDefined(cell) ? cell.toString() : ''; - if (comparator === EQ) { - return cellStr === filterVal; - } - if (caseSensitive) { - return cellStr.includes(filterVal); - } - return cellStr.toLocaleUpperCase().indexOf(filterVal.toLocaleUpperCase()) !== -1; - }); +) => { + // make sure filter value to be a string + const filterVal = userInput.toString(); + + return ( + data.filter((row) => { + let cell = _.get(row, dataField); + if (customFilterValue) { + cell = customFilterValue(cell, row); + } + const cellStr = _.isDefined(cell) ? cell.toString() : ''; + if (comparator === EQ) { + return cellStr === filterVal; + } + if (caseSensitive) { + return cellStr.includes(filterVal); + } + + return cellStr.toLocaleUpperCase().indexOf(filterVal.toLocaleUpperCase()) !== -1; + }) + ); +}; export const filterByNumber = _ => ( data, dataField, { filterVal: { comparator, number } }, customFilterValue -) => +) => ( data.filter((row) => { if (number === '' || !comparator) return true; let valid = true; @@ -81,7 +88,8 @@ export const filterByNumber = _ => ( } } return valid; - }); + }) +); export const filterFactory = _ => (filterType) => { let filterFn; diff --git a/packages/react-bootstrap-table2-filter/src/wrapper.js b/packages/react-bootstrap-table2-filter/src/wrapper.js index f48e031..f13e615 100644 --- a/packages/react-bootstrap-table2-filter/src/wrapper.js +++ b/packages/react-bootstrap-table2-filter/src/wrapper.js @@ -40,33 +40,43 @@ export default (Base, { } } - onFilter(column, filterVal, filterType) { - const { store, columns } = this.props; - const currFilters = Object.assign({}, this.state.currFilters); - const { dataField, filter } = column; + /** + * filter the table like below: + * onFilter(column, filterType)(filterVal) + * @param {Object} column + * @param {String} filterType + * @param {String} filterVal - user input for filtering. + */ + onFilter(column, filterType) { + return (filterVal) => { + const { store, columns } = this.props; + const currFilters = Object.assign({}, this.state.currFilters); + const { dataField, filter } = column; - if (!_.isDefined(filterVal) || filterVal === '') { - delete currFilters[dataField]; - } else { - // select default comparator is EQ, others are LIKE - const { - comparator = (filterType === FILTER_TYPE.SELECT ? EQ : LIKE), - caseSensitive = false - } = filter.props; - currFilters[dataField] = { filterVal, filterType, comparator, caseSensitive }; - } - store.filters = currFilters; + if (!_.isDefined(filterVal) || filterVal === '') { + delete currFilters[dataField]; + } else { + // select default comparator is EQ, others are LIKE + const { + comparator = (filterType === FILTER_TYPE.SELECT ? EQ : LIKE), + caseSensitive = false + } = filter.props; + currFilters[dataField] = { filterVal, filterType, comparator, caseSensitive }; + } - if (this.isRemoteFiltering() || this.isRemotePagination()) { - this.handleRemoteFilterChange(); - // when remote filtering is enable, dont set currFilters state - // in the componentWillReceiveProps, - // it's the key point that we can know the filter is changed - return; - } + store.filters = currFilters; - store.filteredData = filters(store, columns, _)(currFilters); - this.setState(() => ({ currFilters, isDataChanged: true })); + if (this.isRemoteFiltering() || this.isRemotePagination()) { + this.handleRemoteFilterChange(); + // when remote filtering is enable, dont set currFilters state + // in the componentWillReceiveProps, + // it's the key point that we can know the filter is changed + return; + } + + store.filteredData = filters(store, columns, _)(currFilters); + this.setState(() => ({ currFilters, isDataChanged: true })); + }; } render() { diff --git a/packages/react-bootstrap-table2-filter/test/components/number.test.js b/packages/react-bootstrap-table2-filter/test/components/number.test.js index 6ba66f7..3586ec4 100644 --- a/packages/react-bootstrap-table2-filter/test/components/number.test.js +++ b/packages/react-bootstrap-table2-filter/test/components/number.test.js @@ -9,7 +9,11 @@ import * as Comparator from '../../src/comparison'; describe('Number Filter', () => { let wrapper; + + // onFilter(x)(y) = filter result const onFilter = sinon.stub(); + const onFilterFirstReturn = sinon.stub(); + const column = { dataField: 'price', text: 'Product Price' @@ -17,6 +21,9 @@ describe('Number Filter', () => { afterEach(() => { onFilter.reset(); + onFilterFirstReturn.reset(); + + onFilter.returns(onFilterFirstReturn); }); describe('initialization', () => { @@ -90,6 +97,36 @@ describe('Number Filter', () => { }); }); + describe('when props.getFilter is defined', () => { + let programmaticallyFilter; + + const comparator = Comparator.EQ; + const number = 123; + + const getFilter = (filter) => { + programmaticallyFilter = filter; + }; + + beforeEach(() => { + wrapper = mount( + + ); + + programmaticallyFilter({ comparator, number }); + }); + + it('should do onFilter correctly when exported function was executed', () => { + expect(onFilter.calledOnce).toBeTruthy(); + expect(onFilter.calledWith(column, FILTER_TYPE.NUMBER)).toBeTruthy(); + expect(onFilterFirstReturn.calledOnce).toBeTruthy(); + expect(onFilterFirstReturn.calledWith({ comparator, number })).toBeTruthy(); + }); + + it('should setState correctly when exported function was executed', () => { + expect(wrapper.state().isSelected).toBeTruthy(); + }); + }); + describe('when defaultValue.number and defaultValue.comparator props is defined', () => { const number = 203; const comparator = Comparator.EQ; @@ -110,8 +147,9 @@ describe('Number Filter', () => { it('should calling onFilter on componentDidMount', () => { expect(onFilter.calledOnce).toBeTruthy(); - expect(onFilter.calledWith( - column, { number: `${number}`, comparator }, FILTER_TYPE.NUMBER)).toBeTruthy(); + expect(onFilter.calledWith(column, FILTER_TYPE.NUMBER)).toBeTruthy(); + expect(onFilterFirstReturn.calledOnce).toBeTruthy(); + expect(onFilterFirstReturn.calledWith({ number: `${number}`, comparator })).toBeTruthy(); }); }); diff --git a/packages/react-bootstrap-table2-filter/test/components/select.test.js b/packages/react-bootstrap-table2-filter/test/components/select.test.js index 2ed39a6..85f9686 100644 --- a/packages/react-bootstrap-table2-filter/test/components/select.test.js +++ b/packages/react-bootstrap-table2-filter/test/components/select.test.js @@ -9,19 +9,27 @@ import { FILTER_TYPE } from '../../src/const'; describe('Select Filter', () => { let wrapper; let instance; + + // onFilter(x)(y) = filter result const onFilter = sinon.stub(); + const onFilterFirstReturn = sinon.stub(); + const column = { dataField: 'quality', text: 'Product Quality' }; + const options = { 0: 'Bad', 1: 'Good', - 2: 'Unknow' + 2: 'Unknown' }; afterEach(() => { onFilter.reset(); + onFilterFirstReturn.reset(); + + onFilter.returns(onFilterFirstReturn); }); describe('initialization', () => { @@ -83,11 +91,48 @@ describe('Select Filter', () => { it('should calling onFilter on componentDidMount', () => { expect(onFilter.calledOnce).toBeTruthy(); - expect(onFilter.calledWith(column, defaultValue, FILTER_TYPE.SELECT)).toBeTruthy(); + expect(onFilter.calledWith(column, FILTER_TYPE.SELECT)).toBeTruthy(); + expect(onFilterFirstReturn.calledOnce).toBeTruthy(); + expect(onFilterFirstReturn.calledWith(defaultValue)).toBeTruthy(); }); }); }); + describe('when props.getFilter is defined', () => { + let programmaticallyFilter; + + const filterValue = 'foo'; + + const getFilter = (filter) => { + programmaticallyFilter = filter; + }; + + beforeEach(() => { + wrapper = mount( + + ); + instance = wrapper.instance(); + + programmaticallyFilter(filterValue); + }); + + it('should do onFilter correctly when exported function was executed', () => { + expect(onFilter.calledOnce).toBeTruthy(); + expect(onFilter.calledWith(column, FILTER_TYPE.SELECT)).toBeTruthy(); + expect(onFilterFirstReturn.calledOnce).toBeTruthy(); + expect(onFilterFirstReturn.calledWith(filterValue)).toBeTruthy(); + }); + + it('should setState correctly when exported function was executed', () => { + expect(instance.state.isSelected).toBeTruthy(); + }); + }); + describe('when placeholder is defined', () => { const placeholder = 'test'; beforeEach(() => { @@ -170,8 +215,9 @@ describe('Select Filter', () => { it('should update', () => { expect(onFilter.callCount).toBe(2); - expect(onFilter.calledWith( - column, instance.props.defaultValue, FILTER_TYPE.SELECT)).toBeTruthy(); + expect(onFilter.calledWith(column, FILTER_TYPE.SELECT)).toBeTruthy(); + expect(onFilterFirstReturn.callCount).toBe(2); + expect(onFilterFirstReturn.calledWith(instance.props.defaultValue)).toBeTruthy(); }); }); @@ -198,8 +244,9 @@ describe('Select Filter', () => { it('should update', () => { expect(onFilter.callCount).toBe(2); - expect(onFilter.calledWith( - column, instance.props.defaultValue, FILTER_TYPE.SELECT)).toBeTruthy(); + expect(onFilter.calledWith(column, FILTER_TYPE.SELECT)).toBeTruthy(); + expect(onFilterFirstReturn.callCount).toBe(2); + expect(onFilterFirstReturn.calledWith(instance.props.defaultValue)).toBeTruthy(); }); }); }); @@ -226,7 +273,9 @@ describe('Select Filter', () => { it('should calling onFilter correctly', () => { expect(onFilter.callCount).toBe(2); - expect(onFilter.calledWith(column, defaultValue, FILTER_TYPE.SELECT)).toBeTruthy(); + expect(onFilter.calledWith(column, FILTER_TYPE.SELECT)).toBeTruthy(); + expect(onFilterFirstReturn.callCount).toBe(2); + expect(onFilterFirstReturn.calledWith(defaultValue)).toBeTruthy(); }); }); @@ -249,6 +298,7 @@ describe('Select Filter', () => { it('should calling onFilter correctly', () => { expect(onFilter.callCount).toBe(1); + expect(onFilterFirstReturn.callCount).toBe(1); }); }); }); @@ -268,8 +318,10 @@ describe('Select Filter', () => { }); it('should calling onFilter correctly', () => { - expect(onFilter.callCount).toBe(1); - expect(onFilter.calledWith(column, value, FILTER_TYPE.SELECT)).toBeTruthy(); + expect(onFilter.calledOnce).toBeTruthy(); + expect(onFilter.calledWith(column, FILTER_TYPE.SELECT)).toBeTruthy(); + expect(onFilterFirstReturn.calledOnce).toBeTruthy(); + expect(onFilterFirstReturn.calledWith(value)).toBeTruthy(); }); }); @@ -289,8 +341,10 @@ describe('Select Filter', () => { }); it('should calling onFilter correctly', () => { - expect(onFilter.callCount).toBe(1); - expect(onFilter.calledWith(column, event.target.value, FILTER_TYPE.SELECT)).toBeTruthy(); + expect(onFilter.calledOnce).toBeTruthy(); + expect(onFilter.calledWith(column, FILTER_TYPE.SELECT)).toBeTruthy(); + expect(onFilterFirstReturn.calledOnce).toBeTruthy(); + expect(onFilterFirstReturn.calledWith(event.target.value)).toBeTruthy(); }); }); }); diff --git a/packages/react-bootstrap-table2-filter/test/components/text.test.js b/packages/react-bootstrap-table2-filter/test/components/text.test.js index 4a9c282..5a8d297 100644 --- a/packages/react-bootstrap-table2-filter/test/components/text.test.js +++ b/packages/react-bootstrap-table2-filter/test/components/text.test.js @@ -9,7 +9,11 @@ jest.useFakeTimers(); describe('Text Filter', () => { let wrapper; let instance; + + // onFilter(x)(y) = filter result const onFilter = sinon.stub(); + const onFilterFirstReturn = sinon.stub(); + const column = { dataField: 'price', text: 'Price' @@ -17,6 +21,9 @@ describe('Text Filter', () => { afterEach(() => { onFilter.reset(); + onFilterFirstReturn.reset(); + + onFilter.returns(onFilterFirstReturn); }); describe('initialization', () => { @@ -58,7 +65,39 @@ describe('Text Filter', () => { it('should calling onFilter on componentDidMount', () => { expect(onFilter.calledOnce).toBeTruthy(); - expect(onFilter.calledWith(column, defaultValue, FILTER_TYPE.TEXT)).toBeTruthy(); + expect(onFilter.calledWith(column, FILTER_TYPE.TEXT)).toBeTruthy(); + expect(onFilterFirstReturn.calledOnce).toBeTruthy(); + expect(onFilterFirstReturn.calledWith(defaultValue)).toBeTruthy(); + }); + }); + + describe('when props.getFilter is defined', () => { + let programmaticallyFilter; + + const filterValue = 'foo'; + + const getFilter = (filter) => { + programmaticallyFilter = filter; + }; + + beforeEach(() => { + wrapper = mount( + + ); + instance = wrapper.instance(); + + programmaticallyFilter(filterValue); + }); + + it('should do onFilter correctly when exported function was executed', () => { + expect(onFilter.calledOnce).toBeTruthy(); + expect(onFilter.calledWith(column, FILTER_TYPE.TEXT)).toBeTruthy(); + expect(onFilterFirstReturn.calledOnce).toBeTruthy(); + expect(onFilterFirstReturn.calledWith(filterValue)).toBeTruthy(); + }); + + it('should setState correctly when exported function was executed', () => { + expect(instance.state.value).toEqual(filterValue); }); }); @@ -114,7 +153,9 @@ describe('Text Filter', () => { it('should calling onFilter correctly when props.defaultValue is changed', () => { expect(onFilter.calledOnce).toBeTruthy(); - expect(onFilter.calledWith(column, nextDefaultValue, FILTER_TYPE.TEXT)).toBeTruthy(); + expect(onFilter.calledWith(column, FILTER_TYPE.TEXT)).toBeTruthy(); + expect(onFilterFirstReturn.calledOnce).toBeTruthy(); + expect(onFilterFirstReturn.calledWith(nextDefaultValue)).toBeTruthy(); }); }); @@ -133,8 +174,9 @@ describe('Text Filter', () => { it('should calling onFilter correctly', () => { expect(onFilter.calledOnce).toBeTruthy(); - expect(onFilter.calledWith( - column, instance.props.defaultValue, FILTER_TYPE.TEXT)).toBeTruthy(); + expect(onFilter.calledWith(column, FILTER_TYPE.TEXT)).toBeTruthy(); + expect(onFilterFirstReturn.calledOnce).toBeTruthy(); + expect(onFilterFirstReturn.calledWith(instance.props.defaultValue)).toBeTruthy(); }); }); @@ -154,7 +196,9 @@ describe('Text Filter', () => { it('should calling onFilter correctly', () => { expect(onFilter.calledOnce).toBeTruthy(); - expect(onFilter.calledWith(column, filterText, FILTER_TYPE.TEXT)).toBeTruthy(); + expect(onFilter.calledWith(column, FILTER_TYPE.TEXT)).toBeTruthy(); + expect(onFilterFirstReturn.calledOnce).toBeTruthy(); + expect(onFilterFirstReturn.calledWith(filterText)).toBeTruthy(); }); }); diff --git a/packages/react-bootstrap-table2-filter/test/filter.test.js b/packages/react-bootstrap-table2-filter/test/filter.test.js index ae66a38..2ffd36d 100644 --- a/packages/react-bootstrap-table2-filter/test/filter.test.js +++ b/packages/react-bootstrap-table2-filter/test/filter.test.js @@ -42,6 +42,19 @@ describe('filter', () => { filterFn = filters(store, columns, _); }); + describe('when filter value is not a String', () => { + it('should transform to string and do the filter', () => { + currFilters.name = { + filterVal: 3, + filterType: FILTER_TYPE.TEXT + }; + + const result = filterFn(currFilters); + expect(result).toBeDefined(); + expect(result).toHaveLength(2); + }); + }); + describe(`when default comparator is ${LIKE}`, () => { it('should returning correct result', () => { currFilters.name = { diff --git a/packages/react-bootstrap-table2-filter/test/wrapper.test.js b/packages/react-bootstrap-table2-filter/test/wrapper.test.js index 3d86285..1442658 100644 --- a/packages/react-bootstrap-table2-filter/test/wrapper.test.js +++ b/packages/react-bootstrap-table2-filter/test/wrapper.test.js @@ -167,14 +167,14 @@ describe('Wrapper', () => { it('should setting store object correctly', () => { filterVals.forEach((filterVal) => { - instance.onFilter(props.columns[1], filterVal, FILTER_TYPE.TEXT); + instance.onFilter(props.columns[1], FILTER_TYPE.TEXT)(filterVal); expect(props.store.filtering).toBeFalsy(); }); }); it('should setting state correctly', () => { filterVals.forEach((filterVal) => { - instance.onFilter(props.columns[1], filterVal, FILTER_TYPE.TEXT); + instance.onFilter(props.columns[1], FILTER_TYPE.TEXT)(filterVal); expect(instance.state.isDataChanged).toBeTruthy(); expect(Object.keys(instance.state.currFilters)).toHaveLength(0); }); @@ -185,12 +185,12 @@ describe('Wrapper', () => { const filterVal = '3'; it('should setting store object correctly', () => { - instance.onFilter(props.columns[1], filterVal, FILTER_TYPE.TEXT); + instance.onFilter(props.columns[1], FILTER_TYPE.TEXT)(filterVal); expect(props.store.filters).toEqual(instance.state.currFilters); }); it('should setting state correctly', () => { - instance.onFilter(props.columns[1], filterVal, FILTER_TYPE.TEXT); + instance.onFilter(props.columns[1], FILTER_TYPE.TEXT)(filterVal); expect(instance.state.isDataChanged).toBeTruthy(); expect(Object.keys(instance.state.currFilters)).toHaveLength(1); }); @@ -203,7 +203,7 @@ describe('Wrapper', () => { props = createTableProps(); props.remote = { filter: true }; createFilterWrapper(props); - instance.onFilter(props.columns[1], filterVal, FILTER_TYPE.TEXT); + instance.onFilter(props.columns[1], FILTER_TYPE.TEXT)(filterVal); }); it('should not setting store object correctly', () => { @@ -222,27 +222,27 @@ describe('Wrapper', () => { describe('combination', () => { it('should setting store object correctly', () => { - instance.onFilter(props.columns[1], '3', FILTER_TYPE.TEXT); + instance.onFilter(props.columns[1], FILTER_TYPE.TEXT)('3'); expect(props.store.filters).toEqual(instance.state.currFilters); expect(instance.state.isDataChanged).toBeTruthy(); expect(Object.keys(instance.state.currFilters)).toHaveLength(1); - instance.onFilter(props.columns[1], '2', FILTER_TYPE.TEXT); + instance.onFilter(props.columns[1], FILTER_TYPE.TEXT)('2'); expect(props.store.filters).toEqual(instance.state.currFilters); expect(instance.state.isDataChanged).toBeTruthy(); expect(Object.keys(instance.state.currFilters)).toHaveLength(1); - instance.onFilter(props.columns[2], '2', FILTER_TYPE.TEXT); + instance.onFilter(props.columns[2], FILTER_TYPE.TEXT)('2'); expect(props.store.filters).toEqual(instance.state.currFilters); expect(instance.state.isDataChanged).toBeTruthy(); expect(Object.keys(instance.state.currFilters)).toHaveLength(2); - instance.onFilter(props.columns[2], '', FILTER_TYPE.TEXT); + instance.onFilter(props.columns[2], FILTER_TYPE.TEXT)(''); expect(props.store.filters).toEqual(instance.state.currFilters); expect(instance.state.isDataChanged).toBeTruthy(); expect(Object.keys(instance.state.currFilters)).toHaveLength(1); - instance.onFilter(props.columns[1], '', FILTER_TYPE.TEXT); + instance.onFilter(props.columns[1], FILTER_TYPE.TEXT)(''); expect(props.store.filters).toEqual(instance.state.currFilters); expect(instance.state.isDataChanged).toBeTruthy(); expect(Object.keys(instance.state.currFilters)).toHaveLength(0); diff --git a/packages/react-bootstrap-table2/src/row-event-delegater.js b/packages/react-bootstrap-table2/src/row-event-delegater.js index a35de46..452d7ae 100644 --- a/packages/react-bootstrap-table2/src/row-event-delegater.js +++ b/packages/react-bootstrap-table2/src/row-event-delegater.js @@ -47,7 +47,7 @@ export default ExtendBase => } if (selectable) { const key = _.get(row, keyField); - onRowSelect(key, !selected, rowIndex); + onRowSelect(key, !selected, rowIndex, e); } }; diff --git a/packages/react-bootstrap-table2/src/row-selection/selection-cell.js b/packages/react-bootstrap-table2/src/row-selection/selection-cell.js index bba789e..3050cf2 100644 --- a/packages/react-bootstrap-table2/src/row-selection/selection-cell.js +++ b/packages/react-bootstrap-table2/src/row-selection/selection-cell.js @@ -28,7 +28,7 @@ export default class SelectionCell extends Component { return nextProps.selected !== selected; } - handleClick() { + handleClick(e) { const { mode: inputType, rowKey, @@ -46,7 +46,7 @@ export default class SelectionCell extends Component { ? true : !selected; - onRowSelect(rowKey, checked, rowIndex); + onRowSelect(rowKey, checked, rowIndex, e); } render() { diff --git a/packages/react-bootstrap-table2/src/row-selection/selection-header-cell.js b/packages/react-bootstrap-table2/src/row-selection/selection-header-cell.js index a2c6956..0105bf3 100644 --- a/packages/react-bootstrap-table2/src/row-selection/selection-header-cell.js +++ b/packages/react-bootstrap-table2/src/row-selection/selection-header-cell.js @@ -44,10 +44,10 @@ export default class SelectionHeaderCell extends Component { return nextProps.checkedStatus !== checkedStatus; } - handleCheckBoxClick() { + handleCheckBoxClick(e) { const { onAllRowsSelect } = this.props; - onAllRowsSelect(); + onAllRowsSelect(e); } render() { diff --git a/packages/react-bootstrap-table2/src/row-selection/wrapper.js b/packages/react-bootstrap-table2/src/row-selection/wrapper.js index c2880bf..51472dc 100644 --- a/packages/react-bootstrap-table2/src/row-selection/wrapper.js +++ b/packages/react-bootstrap-table2/src/row-selection/wrapper.js @@ -41,7 +41,7 @@ export default Base => * @param {String} rowKey - row key of what was selected. * @param {Boolean} checked - next checked status of input button. */ - handleRowSelect(rowKey, checked, rowIndex) { + handleRowSelect(rowKey, checked, rowIndex, e) { const { selectRow: { mode, onSelect }, store } = this.props; const { ROW_SELECT_SINGLE } = Const; @@ -59,7 +59,7 @@ export default Base => if (onSelect) { const row = getRowByRowId(store)(rowKey); - onSelect(row, checked, rowIndex); + onSelect(row, checked, rowIndex, e); } this.setState(() => ({ @@ -68,18 +68,16 @@ export default Base => } /** - * handle all rows selection on header cell by store.selected or given specific result. - * @param {Boolean} option - customized result for all rows selection + * handle all rows selection on header cell by store.selected */ - handleAllRowsSelect(option) { + handleAllRowsSelect(e) { const { store, selectRow: { onSelectAll, nonSelectable } } = this.props; const selected = isAnySelectedRow(store)(nonSelectable); - // set next status of all row selected by store.selected or customizing by user. - const result = option || !selected; + const result = !selected; const currSelected = result ? selectableKeys(store)(nonSelectable) : @@ -89,7 +87,7 @@ export default Base => store.selected = currSelected; if (onSelectAll) { - onSelectAll(result, getSelectedRows(store)); + onSelectAll(result, getSelectedRows(store), e); } this.setState(() => ({ diff --git a/packages/react-bootstrap-table2/test/row-selection/wrapper.test.js b/packages/react-bootstrap-table2/test/row-selection/wrapper.test.js index 59dc190..aa397ca 100644 --- a/packages/react-bootstrap-table2/test/row-selection/wrapper.test.js +++ b/packages/react-bootstrap-table2/test/row-selection/wrapper.test.js @@ -162,14 +162,6 @@ describe('RowSelectionWrapper', () => { wrapper.instance().handleAllRowsSelect(); expect(wrapper.state('selectedRowKeys')).toEqual([]); }); - - it('call handleAllRowsSelect function with a bool args should setting correct state.selectedRowKeys', () => { - wrapper.instance().handleAllRowsSelect(true); - expect(wrapper.state('selectedRowKeys')).toEqual(expect.arrayContaining([firstSelectedRow, secondSelectedRow])); - - wrapper.instance().handleAllRowsSelect(false); - expect(wrapper.state('selectedRowKeys')).toEqual([]); - }); }); describe('when selectRow.onSelect is defined', () => { @@ -219,13 +211,14 @@ describe('RowSelectionWrapper', () => { }); it('selectRow.onSelect callback should be called correctly when calling handleRowSelect function', () => { - wrapper.instance().handleAllRowsSelect(); + const e = {}; + wrapper.instance().handleAllRowsSelect(e); expect(onSelectAllCallBack.callCount).toEqual(1); - expect(onSelectAllCallBack.calledWith(true, data)).toBeTruthy(); + expect(onSelectAllCallBack.calledWith(true, data, e)).toBeTruthy(); - wrapper.instance().handleAllRowsSelect(); + wrapper.instance().handleAllRowsSelect(e); expect(onSelectAllCallBack.callCount).toEqual(2); - expect(onSelectAllCallBack.calledWith(false, [])).toBeTruthy(); + expect(onSelectAllCallBack.calledWith(false, [], e)).toBeTruthy(); }); }); }); diff --git a/webpack.prod.config.babel.js b/webpack.prod.config.babel.js deleted file mode 100644 index 6a69ac0..0000000 --- a/webpack.prod.config.babel.js +++ /dev/null @@ -1,64 +0,0 @@ -import * as path from 'path'; -import webpack from 'webpack'; - -module.exports = { - entry: { - 'react-bootstrap-table2/dist/react-bootstrap-table2': './packages/react-bootstrap-table2/index.js', - 'react-bootstrap-table2/dist/react-bootstrap-table2.min': './packages/react-bootstrap-table2/index.js', - 'react-bootstrap-table2-editor/dist/react-bootstrap-table2-editor': './packages/react-bootstrap-table2-editor/index.js', - 'react-bootstrap-table2-editor/dist/react-bootstrap-table2-editor.min': './packages/react-bootstrap-table2-editor/index.js', - 'react-bootstrap-table2-filter/dist/react-bootstrap-table2-filter': './packages/react-bootstrap-table2-filter/index.js', - 'react-bootstrap-table2-filter/dist/react-bootstrap-table2-filter.min': './packages/react-bootstrap-table2-filter/index.js', - 'react-bootstrap-table2-overlay/dist/react-bootstrap-table2-overlay': './packages/react-bootstrap-table2-overlay/index.js', - 'react-bootstrap-table2-overlay/dist/react-bootstrap-table2-overlay.min': './packages/react-bootstrap-table2-overlay/index.js', - 'react-bootstrap-table2-paginator/dist/react-bootstrap-table2-paginator': './packages/react-bootstrap-table2-paginator/index.js', - 'react-bootstrap-table2-paginator/dist/react-bootstrap-table2-paginator.min': './packages/react-bootstrap-table2-paginator/index.js' - }, - devtool: 'source-map', - output: { - path: path.join(__dirname, 'packages'), - filename: '[name].js', - library: 'ReactBootstrapTable', - libraryTarget: 'umd' - }, - externals: [{ - 'react': { - root: 'React', - commonjs2: 'react', - commonjs: 'react', - amd: 'react' - } - }, { - 'react-dom': { - root: 'ReactDOM', - commonjs2: 'react-dom', - commonjs: 'react-dom', - amd: 'react-dom' - } - }], - module: { - rules: [{ - enforce: 'pre', - test: /\.js?$/, - exclude: /node_modules/, - loader: 'eslint-loader' - }, { - test: /\.js?$/, - use: ['babel-loader'], - exclude: /node_modules/ - }] - }, - plugins: [ - new webpack.DefinePlugin({ - 'process.env.NODE_ENV': JSON.stringify('production') - }), - new webpack.SourceMapDevToolPlugin(), - new webpack.optimize.DedupePlugin(), - new webpack.optimize.OccurrenceOrderPlugin(), - new webpack.optimize.AggressiveMergingPlugin(), - new webpack.optimize.UglifyJsPlugin({ - include: /\.min\.js$/, - compress: { warnings: false } - }) - ] -}; diff --git a/webpack/editor.umd.babel.js b/webpack/editor.umd.babel.js new file mode 100644 index 0000000..c1ad1d6 --- /dev/null +++ b/webpack/editor.umd.babel.js @@ -0,0 +1,16 @@ +import * as path from 'path'; +import umdConfig from './webpack.umd.babel'; + +module.exports = { + ...umdConfig, + entry: { + 'react-bootstrap-table2-editor/dist/react-bootstrap-table2-editor': './packages/react-bootstrap-table2-editor/index.js', + 'react-bootstrap-table2-editor/dist/react-bootstrap-table2-editor.min': './packages/react-bootstrap-table2-editor/index.js' + }, + output: { + path: path.join(__dirname, '../packages'), + filename: '[name].js', + library: 'ReactBootstrapTable2Editor', + libraryTarget: 'umd' + } +}; diff --git a/webpack/filter.umd.babel.js b/webpack/filter.umd.babel.js new file mode 100644 index 0000000..c69c278 --- /dev/null +++ b/webpack/filter.umd.babel.js @@ -0,0 +1,16 @@ +import * as path from 'path'; +import umdConfig from './webpack.umd.babel'; + +module.exports = { + ...umdConfig, + entry: { + 'react-bootstrap-table2-filter/dist/react-bootstrap-table2-filter': './packages/react-bootstrap-table2-filter/index.js', + 'react-bootstrap-table2-filter/dist/react-bootstrap-table2-filter.min': './packages/react-bootstrap-table2-filter/index.js' + }, + output: { + path: path.join(__dirname, '../packages'), + filename: '[name].js', + library: 'ReactBootstrapTable2Filter', + libraryTarget: 'umd' + } +}; diff --git a/webpack/next.umd.babel.js b/webpack/next.umd.babel.js new file mode 100644 index 0000000..c2071f0 --- /dev/null +++ b/webpack/next.umd.babel.js @@ -0,0 +1,16 @@ +import * as path from 'path'; +import umdConfig from './webpack.umd.babel'; + +module.exports = { + ...umdConfig, + entry: { + 'react-bootstrap-table2/dist/react-bootstrap-table-next': './packages/react-bootstrap-table2/index.js', + 'react-bootstrap-table2/dist/react-bootstrap-table-next.min': './packages/react-bootstrap-table2/index.js' + }, + output: { + path: path.join(__dirname, '../packages'), + filename: '[name].js', + library: 'ReactBootstrapTable2', + libraryTarget: 'umd' + } +}; diff --git a/webpack/overlay.umd.babel.js b/webpack/overlay.umd.babel.js new file mode 100644 index 0000000..ac6d198 --- /dev/null +++ b/webpack/overlay.umd.babel.js @@ -0,0 +1,16 @@ +import * as path from 'path'; +import umdConfig from './webpack.umd.babel'; + +module.exports = { + ...umdConfig, + entry: { + 'react-bootstrap-table2-overlay/dist/react-bootstrap-table2-overlay': './packages/react-bootstrap-table2-overlay/index.js', + 'react-bootstrap-table2-overlay/dist/react-bootstrap-table2-overlay.min': './packages/react-bootstrap-table2-overlay/index.js' + }, + output: { + path: path.join(__dirname, '../packages'), + filename: '[name].js', + library: 'ReactBootstrapTable2Overlay', + libraryTarget: 'umd' + } +}; diff --git a/webpack/paginator.umd.babel.js b/webpack/paginator.umd.babel.js new file mode 100644 index 0000000..1779447 --- /dev/null +++ b/webpack/paginator.umd.babel.js @@ -0,0 +1,16 @@ +import * as path from 'path'; +import umdConfig from './webpack.umd.babel'; + +module.exports = { + ...umdConfig, + entry: { + 'react-bootstrap-table2-paginator/dist/react-bootstrap-table2-paginator': './packages/react-bootstrap-table2-paginator/index.js', + 'react-bootstrap-table2-paginator/dist/react-bootstrap-table2-paginator.min': './packages/react-bootstrap-table2-paginator/index.js' + }, + output: { + path: path.join(__dirname, '../packages'), + filename: '[name].js', + library: 'ReactBootstrapTable2Paginator', + libraryTarget: 'umd' + } +}; diff --git a/webpack/webpack.umd.babel.js b/webpack/webpack.umd.babel.js new file mode 100644 index 0000000..31a6cdc --- /dev/null +++ b/webpack/webpack.umd.babel.js @@ -0,0 +1,45 @@ +import webpack from 'webpack'; + +module.exports = { + devtool: 'source-map', + externals: [{ + 'react': { + root: 'React', + commonjs2: 'react', + commonjs: 'react', + amd: 'react' + } + }, { + 'react-dom': { + root: 'ReactDOM', + commonjs2: 'react-dom', + commonjs: 'react-dom', + amd: 'react-dom' + } + }], + module: { + rules: [{ + enforce: 'pre', + test: /\.js?$/, + exclude: /node_modules/, + loader: 'eslint-loader' + }, { + test: /\.js?$/, + use: ['babel-loader'], + exclude: /node_modules/ + }] + }, + plugins: [ + new webpack.DefinePlugin({ + 'process.env.NODE_ENV': JSON.stringify('production') + }), + new webpack.SourceMapDevToolPlugin(), + new webpack.optimize.DedupePlugin(), + new webpack.optimize.OccurrenceOrderPlugin(), + new webpack.optimize.AggressiveMergingPlugin(), + new webpack.optimize.UglifyJsPlugin({ + include: /\.min\.js$/, + compress: { warnings: false } + }) + ] +};