diff --git a/src/Table/Table.js b/src/Table/Table.js index f512d90..93df267 100644 --- a/src/Table/Table.js +++ b/src/Table/Table.js @@ -1,7 +1,7 @@ // @flow import React from 'react'; -import { toArray, flatten, cloneWithProps } from '../utils'; +import { toArray, flatten, cloneWithProps /* , toLowerCase */ } from '../utils'; type TableProps = { component: string | Function, @@ -9,6 +9,10 @@ type TableProps = { pageSize: number, pagination: Function, onPageChange: Function, + search: string, + searchFor: Array, + searchComponent: Function, + onSearch: Function, dataset: Array, className: string, style: Object, @@ -21,18 +25,60 @@ export default class Table extends React.Component { dataset: [], }; - state = {} + state = {}; onPageChange = (...params: any) => { - const { onPageChange } = this.props; - if (typeof onPageChange === 'function') { - onPageChange(...params); - } else { - this.setState({ - ...this.state, - pageNumber: params[0], - }); - } + this.setState({ + ...this.state, + pageNumber: params[0], + }); + }; + + onSearch = (/* value, { type = 'like', caseSensitive = false, fields } = {} */) => { + // TODO + + /* + const { searchFor, dataset } = this.props; + let search = value; + const criteria = fields || searchFor || []; + dataset.filter(x => + criteria.reduce((acc, cur) => { + if (acc === true) return true; + let data = x; + if (typeof cur === 'function') { + data = cur(data); + } else { + String(cur).split('.').forEach((z: string) => { + data = (data || {})[z]; + }); + } + let match; + switch (type) { + case 'equals': + if (typeof data === 'string' && caseSensitive === false) { + data = toLowerCase(data); + } + if (typeof search === 'string' && caseSensitive === false) { + search = toLowerCase(search); + } + match = data === search; + break; + case 'startsWith': + data = toLowerCase(data); + search = toLowerCase(search); + match = data.startsWith(search); + break; + case 'like': + default: + data = toLowerCase(data); + search = toLowerCase(search); + match = new RegExp(search).test(data); + break; + } + return match || acc; + }, false), + ); + */ }; getChildrenArray = () => { @@ -160,14 +206,24 @@ export default class Table extends React.Component { pageNumber, pageSize, pagination, + search, + searchFor, + searchComponent, + onSearch, dataset, children, ...others } = this.props; const Component = component; const Pagination = pagination; + const SearchComponent = searchComponent; return ( + {SearchComponent && + } {this.getChildrenArray(this.props)} @@ -176,7 +232,7 @@ export default class Table extends React.Component { items={dataset.length} pageSize={pageSize} pageNumber={pageNumber} - onPageChange={this.onPageChange} + onPageChange={onPageChange || this.onPageChange} />} ); diff --git a/src/utils.js b/src/utils.js index e8c4eee..09873a4 100644 --- a/src/utils.js +++ b/src/utils.js @@ -25,8 +25,19 @@ export const cloneWithProps = (element: Object, props: Object, key: any) => { element === undefined || element === null || element.type === undefined - ) return null; + ) { return null; } const newProps = Object.assign({}, props, element.props); if (newProps.key === undefined) newProps.key = key; return ; }; + +export const toLowerCase = (string: any, forceConversion: boolean = false) => { + let result = string; + if (forceConversion === true && typeof string !== 'string') { + result = String(string); + } + if (typeof result === 'string' && forceConversion === false) { + result = result.toLowerCase(); + } + return result; +}; diff --git a/test/table.spec.js b/test/table.spec.js index 0afcac3..c8110a5 100644 --- a/test/table.spec.js +++ b/test/table.spec.js @@ -8,6 +8,7 @@ import { Table } from '../src/'; describe('table', () => { const dataset = [{ foo: 'foo0', bar: 'bar0' }, { foo: 'foo1', bar: 'bar1' }]; + const Td = (props: Object) => {props.data}; it('should render the given component', () => { expectComponentToMatch(,
); @@ -398,8 +399,6 @@ describe('table', () => { }); describe('pagination', () => { - const Td = (props: Object) =>
; - it('should render a pagination', () => { expectComponentToMatch(
{props.data}
{ // TODO : test internal pagination }); + + describe('search', () => { + it('should render a search component', () => { + expectComponentToMatch( +
} + />, + +
+
+ , + ); + }); + + it('should call onSearch', (done) => { + const rendered = ReactTestUtils.renderIntoDocument( +
{ + expect(page).toEqual('foo'); + done(); + }} + searchComponent={props =>