From e702fc80ca6a5d6f884ce0a5aeda67549b2cfb70 Mon Sep 17 00:00:00 2001 From: Tanner Linsley Date: Fri, 10 Feb 2017 16:46:14 -0700 Subject: [PATCH] defaultSorting changes and doc updates --- README.md | 5 +- src/componentMethods.js | 127 +++++++++++++----------------- src/index.js | 24 +++--- src/utils.js | 7 +- stories/CustomComponentProps.js | 28 ++++++- stories/CustomExpanderPosition.js | 5 +- stories/DefaultSorting.js | 60 +++++++------- stories/OneHundredKRows.js | 13 ++- stories/Pivoting.js | 43 +++------- stories/PivotingSubComponents.js | 13 ++- stories/Simple.js | 7 ++ 11 files changed, 179 insertions(+), 153 deletions(-) diff --git a/README.md b/README.md index 1118784..fd22854 100644 --- a/README.md +++ b/README.md @@ -135,6 +135,10 @@ These are all of the available props (and their default values) for the main ` row.propertyName, id: 'myProperty', // Conditional - A unique ID is required if the accessor is not a string or if you would like to override the column name used in server-side calls sortable: true, - sort: 'asc' or 'desc', // used to determine the column sorting on init show: true, // can be used to hide a column width: undefined, // A hardcoded width for the column. This overrides both min and max width options minWidth: 100 // A minimum width for this column. If there is extra room, column will flex to fill available space (up to the max-width, if set) diff --git a/src/componentMethods.js b/src/componentMethods.js index 5abc553..9acbf73 100644 --- a/src/componentMethods.js +++ b/src/componentMethods.js @@ -226,20 +226,16 @@ export default { page: (page + 1) > newPages ? newPages - 1 : page } }, - getSortedData (state) { + getSortedData (resolvedState) { const { manual, sorting, - allDecoratedColumns, resolvedData - } = state - - const resolvedSorting = sorting.length ? sorting : this.getInitSorting(allDecoratedColumns) + } = resolvedState // Resolve the data from either manual data or sorted data return { - resolvedSorting, - sortedData: manual ? resolvedData : this.sortData(resolvedData, resolvedSorting) + sortedData: manual ? resolvedData : this.sortData(resolvedData, sorting) } }, @@ -252,26 +248,6 @@ export default { getStateOrProp (key) { return _.getFirstDefined(this.state[key], this.props[key]) }, - getInitSorting (columns) { - if (!columns) { - return [] - } - const initSorting = columns.filter(d => { - return typeof d.sort !== 'undefined' - }).map(d => { - return { - id: d.id, - asc: d.sort === 'asc' - } - }) - - return initSorting - - // return initSorting.length ? initSorting : [{ - // id: columns.find(d => d.id).id, - // asc: true - // }] - }, sortData (data, sorting) { if (!sorting.length) { return data @@ -283,7 +259,7 @@ export default { } return typeof row[sort.id] === 'string' ? row[sort.id].toLowerCase() : row[sort.id] } - }), sorting.map(d => d.asc ? 'asc' : 'desc')) + }), sorting.map(d => !d.desc)) return sorted.map(row => { if (!row[this.props.subRowsKey]) { @@ -338,54 +314,25 @@ export default { if (onSortingChange) { return onSortingChange(column, additive) } - let newSorting = _.clone(sorting || []) - if (_.isArray(column)) { - const existingIndex = newSorting.findIndex(d => d.id === column[0].id) - if (existingIndex > -1) { - const existing = newSorting[existingIndex] - if (existing.asc) { - column.forEach((d, i) => { - newSorting[existingIndex + i].asc = false - }) - } else { - if (additive) { - newSorting.splice(existingIndex, column.length) - } else { - column.forEach((d, i) => { - newSorting[existingIndex + i].asc = true - }) - } - } - if (!additive) { - newSorting = newSorting.slice(existingIndex, column.length) - } - } else { - if (additive) { - newSorting = newSorting.concat(column.map(d => ({ - id: d.id, - asc: true - }))) - } else { - newSorting = column.map(d => ({ - id: d.id, - asc: true - })) - } - } - } else { + let newSorting = _.clone(sorting || []).map(d => { + d.desc = _.isSortingDesc(d) + return d + }) + if (!_.isArray(column)) { + // Single-Sort const existingIndex = newSorting.findIndex(d => d.id === column.id) if (existingIndex > -1) { const existing = newSorting[existingIndex] - if (existing.asc) { - existing.asc = false - if (!additive) { - newSorting = [existing] - } - } else { + if (existing.desc) { if (additive) { newSorting.splice(existingIndex, 1) } else { - existing.asc = true + existing.desc = false + newSorting = [existing] + } + } else { + existing.desc = true + if (!additive) { newSorting = [existing] } } @@ -393,15 +340,51 @@ export default { if (additive) { newSorting.push({ id: column.id, - asc: true + desc: false }) } else { newSorting = [{ id: column.id, - asc: true + desc: false }] } } + } else { + // Multi-Sort + const existingIndex = newSorting.findIndex(d => d.id === column[0].id) + // Existing Sorted Column + if (existingIndex > -1) { + const existing = newSorting[existingIndex] + if (existing.desc) { + if (additive) { + newSorting.splice(existingIndex, column.length) + } else { + column.forEach((d, i) => { + newSorting[existingIndex + i].desc = false + }) + } + } else { + column.forEach((d, i) => { + newSorting[existingIndex + i].desc = true + }) + } + if (!additive) { + newSorting = newSorting.slice(existingIndex, column.length) + } + } else { + // New Sort Column + if (additive) { + newSorting = newSorting.concat(column.map(d => ({ + id: d.id, + desc: false + }))) + } else { + newSorting = column.map(d => ({ + id: d.id, + desc: false + })) + } + } } this.setStateWithData({ page: ((!sorting.length && newSorting.length) || !additive) ? 0 : this.state.page, diff --git a/src/index.js b/src/index.js index fd1c63a..52cb4f9 100644 --- a/src/index.js +++ b/src/index.js @@ -18,8 +18,10 @@ export const ReactTableDefaults = { defaultPageSize: 20, showPageJump: true, expanderColumnWidth: 35, - collapseOnChange: true, + collapseOnSortingChange: false, + collapseOnPageChange: true, freezeWhenExpanded: false, + defaultSorting: [], // Controlled State Overrides // page: undefined, @@ -149,7 +151,7 @@ export default React.createClass({ return { page: 0, pageSize: this.props.defaultPageSize || 10, - sorting: [], + sorting: this.props.defaultSorting, expandedRows: {} } }, @@ -214,10 +216,14 @@ export default React.createClass({ oldState.sorting !== newResolvedState.sorting || (!newResolvedState.frozen && oldState.resolvedData !== newResolvedState.resolvedData) ) { - // If collapseOnChange is set, automatically close expanded subcomponents - if (this.props.collapseOnChange) { + // Handle collapseOnSortingChange & collapseOnPageChange + if ( + (oldState.sorting !== newResolvedState.sorting && this.props.collapseOnSortingChange) || + (!newResolvedState.frozen && oldState.resolvedData !== newResolvedState.resolvedData && this.props.collapseOnPageChange) + ) { newResolvedState.expandedRows = {} } + Object.assign(newResolvedState, this.getSortedData(newResolvedState)) } @@ -274,7 +280,7 @@ export default React.createClass({ loading, pageSize, page, - resolvedSorting, + sorting, pages, // Pivoting State pivotValKey, @@ -481,7 +487,7 @@ export default React.createClass({ } const makeHeader = (column, i) => { - const sort = resolvedSorting.find(d => d.id === column.id) + const sort = sorting.find(d => d.id === column.id) const show = typeof column.show === 'function' ? column.show() : column.show const width = _.getFirstDefined(column.width, column.minWidth) const maxWidth = _.getFirstDefined(column.width, column.maxWidth) @@ -507,7 +513,7 @@ export default React.createClass({ if (column.expander) { if (column.pivotColumns) { - const pivotSort = resolvedSorting.find(d => d.id === column.id) + const pivotSort = sorting.find(d => d.id === column.id) return ( { return (
+ Hey! Open your console! :)
{ + return { + onMouseEnter: e => console.log('Cell - onMouseEnter', { + state, + rowInfo, + column, + instance, + event: e + }) + } + }} />
@@ -53,9 +65,6 @@ export default () => { function getCode () { return ` -import ReactTable from 'react-table' - -// Create some column definitions const columns = [{ header: 'Name', columns: [{ @@ -74,12 +83,23 @@ const columns = [{ }] }] -// Display your table! return ( { + return { + onMouseEnter: e => console.log('Cell - onMouseEnter', { + state, + rowInfo, + column, + instance, + event: e + }) + } + }} /> ) ` diff --git a/stories/CustomExpanderPosition.js b/stories/CustomExpanderPosition.js index 280cf83..9648c72 100644 --- a/stories/CustomExpanderPosition.js +++ b/stories/CustomExpanderPosition.js @@ -79,8 +79,6 @@ const columns = [{ id: 'lastName', accessor: d => d.lastName }] -}, { - expander: true }, { header: 'Info', columns: [{ @@ -91,6 +89,8 @@ const columns = [{ return {row.aggregated ? \`$\{row.value} (avg)\` : row.value} } }] +}, { + expander: true }] return ( @@ -100,7 +100,6 @@ return ( columns={columns} defaultPageSize={10} SubComponent={() => Hello} - pivotBy={['lastName']} /> ) ` diff --git a/stories/DefaultSorting.js b/stories/DefaultSorting.js index 8a1705c..2327efb 100644 --- a/stories/DefaultSorting.js +++ b/stories/DefaultSorting.js @@ -28,8 +28,7 @@ export default () => { header: 'Info', columns: [{ header: 'Age', - accessor: 'age', - sort: 'desc' + accessor: 'age' }] }] @@ -41,6 +40,10 @@ export default () => { data={data} columns={columns} defaultPageSize={10} + defaultSorting={[{ + id: 'age', + desc: true + }]} />
@@ -54,34 +57,35 @@ export default () => { function getCode () { return ` -import ReactTable from 'react-table' - -// Create some column definitions -const columns = [{ - header: 'Name', - columns: [{ - header: 'First Name', - accessor: 'firstName' + const columns = [{ + header: 'Name', + columns: [{ + header: 'First Name', + accessor: 'firstName' + }, { + header: 'Last Name', + id: 'lastName', + accessor: d => d.lastName + }] }, { - header: 'Last Name', - id: 'lastName', - accessor: d => d.lastName + header: 'Info', + columns: [{ + header: 'Age', + accessor: 'age' + }] }] -}, { - header: 'Info', - columns: [{ - header: 'Age', - accessor: 'age' - }] -}] -// Display your table! -return ( - -) + return ( + + ) ` } diff --git a/stories/OneHundredKRows.js b/stories/OneHundredKRows.js index c0567a9..d57d041 100644 --- a/stories/OneHundredKRows.js +++ b/stories/OneHundredKRows.js @@ -100,15 +100,24 @@ const columns = [{ header: 'Info', columns: [{ header: 'Age', - accessor: 'age' + accessor: 'age', + aggregate: vals => _.round(_.mean(vals)), + render: row => { + return {row.aggregated ? \`\${row.value} (avg)\` : row.value} + } + }, { + header: 'Visits', + accessor: 'visits', + aggregate: vals => _.sum(vals) }] }] -export default ( +return ( { return ( diff --git a/stories/Pivoting.js b/stories/Pivoting.js index e2ec78f..ec44759 100644 --- a/stories/Pivoting.js +++ b/stories/Pivoting.js @@ -50,12 +50,6 @@ export default () => { className='-striped -highlight' defaultPageSize={10} pivotBy={['firstName', 'lastName']} - // expandedRows={{ - // 2: true, - // 3: { - // 2: true - // } - // }} />
@@ -83,38 +77,25 @@ const columns = [{ header: 'Info', columns: [{ header: 'Age', - accessor: 'age' + accessor: 'age', + aggregate: vals => _.round(_.mean(vals)), + render: row => { + return {row.aggregated ? \`\${row.value} (avg)\` : row.value} + } + }, { + header: 'Visits', + accessor: 'visits', + aggregate: vals => _.sum(vals) }] }] -export default ( +return ( { - return ( -
- You can put any component you want here, even another React Table! -
-
- { - return ( -
- It even has access to the row data: - {() => JSON.stringify(row, null, 2)} -
- ) - }} - /> -
- ) - }} + pivotBy={['firstName', 'lastName']} /> ) ` diff --git a/stories/PivotingSubComponents.js b/stories/PivotingSubComponents.js index 2e60a5a..f2f5bf5 100644 --- a/stories/PivotingSubComponents.js +++ b/stories/PivotingSubComponents.js @@ -100,15 +100,24 @@ const columns = [{ header: 'Info', columns: [{ header: 'Age', - accessor: 'age' + accessor: 'age', + aggregate: vals => _.round(_.mean(vals)), + render: row => { + return {row.aggregated ? \`\${row.value} (avg)\` : row.value} + } + }, { + header: 'Visits', + accessor: 'visits', + aggregate: vals => _.sum(vals) }] }] -export default ( +return ( { return ( diff --git a/stories/Simple.js b/stories/Simple.js index 67ee1f7..4d5c06a 100644 --- a/stories/Simple.js +++ b/stories/Simple.js @@ -40,6 +40,13 @@ export default () => { data={data} columns={columns} defaultPageSize={10} + getTdProps={() => { + return { + onClick: () => { + console.log('clicked') + } + } + }} />