diff --git a/src/index.js b/src/index.js index 2656f3c..5a6a3a6 100644 --- a/src/index.js +++ b/src/index.js @@ -1,17 +1,46 @@ -import React from 'react' +import React, { Component } from 'react' import classnames from 'classnames' // import _ from './utils' -import lifecycle from './lifecycle' -import methods from './methods' -import defaults from './defaultProps' +import Lifecycle from './lifecycle' +import Methods from './methods' +import defaultProps from './defaultProps' -export const ReactTableDefaults = defaults +export const ReactTableDefaults = defaultProps -export default React.createClass({ - ...lifecycle, - ...methods, +export default class ReactTable extends Methods(Lifecycle(Component)) { + static defaultProps = defaultProps + constructor (props) { + super() + this.getResolvedState = this.getResolvedState.bind(this) + this.getDataModel = this.getDataModel.bind(this) + this.getSortedData = this.getSortedData.bind(this) + this.fireOnChange = this.fireOnChange.bind(this) + this.getPropOrState = this.getPropOrState.bind(this) + this.getStateOrProp = this.getStateOrProp.bind(this) + this.filterData = this.filterData.bind(this) + this.sortData = this.sortData.bind(this) + this.getMinRows = this.getMinRows.bind(this) + this.onPageChange = this.onPageChange.bind(this) + this.onPageSizeChange = this.onPageSizeChange.bind(this) + this.sortColumn = this.sortColumn.bind(this) + this.filterColumn = this.filterColumn.bind(this) + this.resizeColumnStart = this.resizeColumnStart.bind(this) + this.resizeColumnEnd = this.resizeColumnEnd.bind(this) + this.resizeColumnMoving = this.resizeColumnMoving.bind(this) + + this.state = { + page: 0, + pageSize: props.defaultPageSize || 10, + sorting: props.defaultSorting, + expandedRows: {}, + filtering: props.defaultFiltering, + resizing: props.defaultResizing, + currentlyResizing: undefined, + skipNextSort: false + } + } render () { const resolvedState = this.getResolvedState() const { @@ -465,7 +494,7 @@ export default React.createClass({ filter, onFilterChange: (value) => (this.filterColumn(column, value, col)) }, - defaults.column.filterRender + defaultProps.column.filterRender ) ) : null} @@ -535,7 +564,7 @@ export default React.createClass({ filter, onFilterChange: (value) => (this.filterColumn(column, value)) }, - defaults.column.filterRender + defaultProps.column.filterRender ) ) : null} @@ -951,4 +980,4 @@ export default React.createClass({ // childProps are optionally passed to a function-as-a-child return children ? children(finalState, makeTable, this) : makeTable() } -}) +} diff --git a/src/lifecycle.js b/src/lifecycle.js index 83d6dcb..79337a3 100644 --- a/src/lifecycle.js +++ b/src/lifecycle.js @@ -1,41 +1,12 @@ -import _ from './utils' -import defaultProps from './defaultProps' - -export default { - getDefaultProps () { - return defaultProps - }, - - getInitialState () { - return { - page: 0, - pageSize: this.props.defaultPageSize || 10, - sorting: this.props.defaultSorting, - expandedRows: {}, - filtering: this.props.defaultFiltering, - resizing: this.props.defaultResizing, - currentlyResizing: undefined, - skipNextSort: false - } - }, - - getResolvedState (props, state) { - const resolvedState = { - ..._.compactObject(this.state), - ..._.compactObject(this.props), - ..._.compactObject(state), - ..._.compactObject(props) - } - return resolvedState - }, +export default Base => class extends Base { componentWillMount () { this.setStateWithData(this.getDataModel(this.getResolvedState())) - }, + } componentDidMount () { this.fireOnChange() - }, + } componentWillReceiveProps (nextProps, nextState) { const oldState = this.getResolvedState() @@ -61,7 +32,7 @@ export default { ) { this.setStateWithData(this.getDataModel(newState)) } - }, + } setStateWithData (newState, cb) { const oldState = this.getResolvedState() diff --git a/src/methods.js b/src/methods.js index 21716d2..7ed5831 100644 --- a/src/methods.js +++ b/src/methods.js @@ -1,6 +1,15 @@ import _ from './utils' -export default { +export default Base => class extends Base { + getResolvedState (props, state) { + const resolvedState = { + ..._.compactObject(this.state), + ..._.compactObject(this.props), + ..._.compactObject(state), + ..._.compactObject(props) + } + return resolvedState + } getDataModel (newState) { const { columns, @@ -220,7 +229,8 @@ export default { allDecoratedColumns, hasHeaderGroups } - }, + } + getSortedData (resolvedState) { const { manual, @@ -236,16 +246,20 @@ export default { return { sortedData: manual ? resolvedData : this.sortData(this.filterData(resolvedData, showFilters, filtering, defaultFilterMethod, allVisibleColumns), sorting) } - }, + } + fireOnChange () { this.props.onChange(this.getResolvedState(), this) - }, + } + getPropOrState (key) { return _.getFirstDefined(this.props[key], this.state[key]) - }, + } + getStateOrProp (key) { return _.getFirstDefined(this.state[key], this.props[key]) - }, + } + filterData (data, showFilters, filtering, defaultFilterMethod, allVisibleColumns) { let filteredData = data @@ -290,7 +304,8 @@ export default { } return filteredData - }, + } + sortData (data, sorting) { if (!sorting.length) { return data @@ -314,11 +329,11 @@ export default { [this.props.subRowsKey]: this.sortData(row[this.props.subRowsKey], sorting) } }) - }, + } getMinRows () { return _.getFirstDefined(this.props.minRows, this.getStateOrProp('pageSize')) - }, + } // User actions onPageChange (page) { @@ -335,7 +350,8 @@ export default { , () => { this.fireOnChange() }) - }, + } + onPageSizeChange (newPageSize) { const {onPageSizeChange} = this.props const {pageSize, page} = this.getResolvedState() @@ -354,7 +370,8 @@ export default { }, () => { this.fireOnChange() }) - }, + } + sortColumn (column, additive) { const {sorting, skipNextSort} = this.getResolvedState() @@ -451,7 +468,8 @@ export default { }, () => { this.fireOnChange() }) - }, + } + filterColumn (column, value, pivotColumn) { const {filtering} = this.getResolvedState() const {onFilteringChange} = this.props @@ -486,7 +504,8 @@ export default { }, () => { this.fireOnChange() }) - }, + } + resizeColumnStart (column, event, isTouch) { const {onResize} = this.props @@ -520,7 +539,8 @@ export default { document.addEventListener('mouseleave', this.resizeColumnEnd) } }) - }, + } + resizeColumnEnd (event) { let isTouch = event.type === 'touchend' || event.type === 'touchcancel' @@ -544,7 +564,8 @@ export default { skipNextSort: true }) } - }, + } + resizeColumnMoving (event) { const {resizing, currentlyResizing} = this.getResolvedState() diff --git a/src/pagination.js b/src/pagination.js index a98c04b..b92985a 100644 --- a/src/pagination.js +++ b/src/pagination.js @@ -1,4 +1,4 @@ -import React from 'react' +import React, { Component } from 'react' import classnames from 'classnames' // // import _ from './utils' @@ -7,33 +7,44 @@ const defaultButton = (props) => ( ) -export default React.createClass({ - getInitialState () { - return { - page: this.props.page +export default class ReactTablePagination extends Component { + constructor (props) { + super() + + this.getSafePage = this.getSafePage.bind(this) + this.changePage = this.changePage.bind(this) + this.applyPage = this.applyPage.bind(this) + + this.state = { + page: props.page } - }, + } + componentWillReceiveProps (nextProps) { this.setState({page: nextProps.page}) - }, + } + getSafePage (page) { if (isNaN(page)) { page = this.props.page } return Math.min(Math.max(page, 0), this.props.pages - 1) - }, + } + changePage (page) { page = this.getSafePage(page) this.setState({page}) if (this.props.page !== page) { this.props.onPageChange(page) } - }, + } + applyPage (e) { e && e.preventDefault() const page = this.state.page this.changePage(page === '' ? this.props.page : page) - }, + } + render () { const { // Computed @@ -128,4 +139,4 @@ export default React.createClass({ ) } -}) +}