{
- if (onExpandRow) {
- return onExpandRow(cellInfo.nestingPath, e)
- }
- let newExpandedRows = _.clone(expandedRows)
- if (isExpanded) {
- return this.setStateWithData({
- expandedRows: _.set(newExpandedRows, cellInfo.nestingPath, false)
- })
- }
+ const onExpanderClick = (e) => {
+ if (onExpandRow) {
+ return onExpandRow(cellInfo.nestingPath, e)
+ }
+ let newExpandedRows = _.clone(expandedRows)
+ if (isExpanded) {
return this.setStateWithData({
- expandedRows: _.set(newExpandedRows, cellInfo.nestingPath, {})
+ expandedRows: _.set(newExpandedRows, cellInfo.nestingPath, false)
})
}
+ return this.setStateWithData({
+ expandedRows: _.set(newExpandedRows, cellInfo.nestingPath, {})
+ })
+ }
- extraProps['onClick'] = onTdClick
+ // Default to a standard cell
+ let resolvedCell = _.normalizeComponent(column.render, {
+ ...cellInfo,
+ value: cellInfo.rowValues[column.id],
+ isExpanded
+ }, cellInfo.rowValues[column.id])
- if (column.pivotColumns) {
- const pivotFlex = _.sum(column.pivotColumns.map(d => {
- const resized = resizing.find(x => x.id === d.id) || {}
- return d.width || resized.value ? 0 : d.minWidth
- }))
- const pivotWidth = _.sum(column.pivotColumns.map(d => {
- const resized = resizing.find(x => x.id === d.id) || {}
- return _.getFirstDefined(resized.value, d.width, d.minWidth)
- }))
- const pivotMaxWidth = _.sum(column.pivotColumns.map(d => {
- const resized = resizing.find(x => x.id === d.id) || {}
- return _.getFirstDefined(resized.value, d.width, d.maxWidth)
- }))
+ let interactionProps
+ let isBranch
+ let isPreview
+ let expandable
- // Return the pivot expander cell
- return (
-
- {cellInfo.subRows ? (
- _.normalizeComponent(column.render, {
- ...cellInfo,
- value: row[pivotValKey],
- isExpanded
- }, cellInfo.rowValues[column.id])
- ) : SubComponent ? (
- _.normalizeComponent(column.render, {
- ...cellInfo,
- value: cellInfo.rowValues[column.id],
- isExpanded
- }, cellInfo.rowValues[column.id])
- ) : null}
-
- )
+ // Is this column pivoted?
+ if (pivotBy && column.pivot) {
+ // Is this column a branch?
+ isBranch = rowInfo.rowValues[pivotIDKey] === column.id &&
+ cellInfo.subRows
+ // Should this column be blank?
+ isPreview = pivotBy.indexOf(column.id) >= pivotBy.indexOf(rowInfo.rowValues[pivotIDKey]) &&
+ cellInfo.subRows
+
+ // Resolve renderers
+ const ResolvedExpanderComponent = column.expanderRender || ExpanderComponent
+ const ResolvedPivotValueComponent = column.pivotValueRender || PivotValueComponent
+ const ResolvedPivotPreviewComponent = column.pivotPreviewRender || PivotPreviewComponent
+ // Build the default PivotComponent
+ const DefaultResolvedPivotComponent = props => (
+
+
+
+
+ )
+ // Allow a completely custom pivotRender
+ const resolvedPivot = column.pivotRender || DefaultResolvedPivotComponent
+ // Pivot Cell Render Override
+ if (isBranch) {
+ // isPivot
+ resolvedCell = _.normalizeComponent(resolvedPivot, {
+ ...cellInfo,
+ value: row[pivotValKey],
+ isExpanded
+ }, cellInfo.rowValues[column.id])
+ interactionProps = {
+ onClick: onExpanderClick
+ }
+ expandable = true
+ } else if (isPreview) {
+ // Show the pivot preview
+ resolvedCell = _.normalizeComponent(ResolvedPivotPreviewComponent, {
+ ...cellInfo,
+ value: cellInfo.rowValues[column.id],
+ isExpanded
+ }, cellInfo.rowValues[column.id])
+ interactionProps = {
+ onClick: onExpanderClick
+ }
+ expandable = true
+ } else {
+ resolvedCell = null
+ }
+ }
+
+ // Expander onClick event
+ if (column.expander) {
+ if (cellInfo.subRows) {
+ resolvedCell = null
+ } else {
+ expandable = true
+ interactionProps = {
+ onClick: onExpanderClick
+ }
}
}
@@ -556,7 +579,9 @@ export default class ReactTable extends Methods(Lifecycle(Component)) {
key={i2 + '-' + column.id}
className={classnames(
classes,
- !show && 'hidden'
+ !show && 'hidden',
+ expandable && 'rt-expandable',
+ (isBranch || isPreview) && 'rt-pivot'
)}
style={{
...styles,
@@ -565,13 +590,9 @@ export default class ReactTable extends Methods(Lifecycle(Component)) {
maxWidth: `${maxWidth}px`
}}
{...tdProps.rest}
- {...extraProps}
+ {...interactionProps}
>
- {_.normalizeComponent(column.render, {
- ...cellInfo,
- value: cellInfo.rowValues[column.id],
- isExpanded
- }, cellInfo.rowValues[column.id])}
+ {resolvedCell}
)
})}
diff --git a/src/index.styl b/src/index.styl
index 7bbb745..ea82796 100644
--- a/src/index.styl
+++ b/src/index.styl
@@ -102,7 +102,7 @@ $expandSize = 7px
border-right:1px solid alpha(black, .02)
&:last-child
border-right:0
- .rt-pivot
+ .rt-expandable
cursor: pointer
.rt-tr-group
display: flex
@@ -318,4 +318,4 @@ $expandSize = 7px
.rt-td
transition: none!important
cursor: col-resize
- user-select none
\ No newline at end of file
+ user-select none
diff --git a/src/lifecycle.js b/src/lifecycle.js
index 79337a3..caf6f80 100644
--- a/src/lifecycle.js
+++ b/src/lifecycle.js
@@ -12,7 +12,7 @@ export default Base => class extends Base {
const oldState = this.getResolvedState()
const newState = this.getResolvedState(nextProps, nextState)
- if (oldState.defaultSorting !== newState.defaultSorting) {
+ if (JSON.stringify(oldState.defaultSorting) !== JSON.stringify(newState.defaultSorting)) {
newState.sorting = newState.defaultSorting
}
diff --git a/src/methods.js b/src/methods.js
index e60c7ea..5845e25 100644
--- a/src/methods.js
+++ b/src/methods.js
@@ -1,4 +1,3 @@
-import React from 'react'
import _ from './utils'
export default Base => class extends Base {
@@ -53,27 +52,15 @@ export default Base => class extends Base {
expanderColumn = expanderColumn.columns.find(col => col.expander)
}
- // If it has subrows or pivot columns we need to make sure we have an expander column
- if ((SubComponent || pivotBy.length) && !expanderColumn) {
+ // If we have SubComponent's we need to make sure we have an expander column
+ if (SubComponent && !expanderColumn) {
expanderColumn = {expander: true}
columnsWithExpander = [expanderColumn, ...columnsWithExpander]
}
const makeDecoratedColumn = (column) => {
let dcol
- if (pivotBy.length && column.expander) {
- dcol = {
- ...this.props.column,
- render: (props) => (
-
-
-
-
- ),
- ...this.props.pivotDefaults,
- ...column
- }
- } else if (column.expander) {
+ if (column.expander) {
dcol = {
...this.props.column,
render: this.props.ExpanderComponent,
@@ -148,31 +135,36 @@ export default Base => class extends Base {
return column.columns ? column.columns.length : pivotBy.indexOf(column.id) > -1 ? false : _.getFirstDefined(column.show, true)
})
- // Move the pivot columns into a single column if needed
+ // Find any custom pivot location
+ const pivotIndex = visibleColumns.findIndex(col => col.pivot)
+
+ // Handle Pivot Columns
if (pivotBy.length) {
+ // Retrieve the pivot columns in the correct pivot order
const pivotColumns = []
- for (var i = 0; i < allDecoratedColumns.length; i++) {
- if (pivotBy.indexOf(allDecoratedColumns[i].id) > -1) {
- pivotColumns.push(allDecoratedColumns[i])
+ pivotBy.forEach(pivotID => {
+ const found = allDecoratedColumns.find(d => d.id === pivotID)
+ if (found) {
+ pivotColumns.push(found)
}
+ })
+
+ let pivotColumnGroup = {
+ columns: pivotColumns.map(col => ({
+ ...col,
+ pivot: true
+ }))
}
- const pivotExpanderColumn = visibleColumns.findIndex(col => col.expander || (col.columns && col.columns.some(col2 => col2.expander)))
- if (pivotExpanderColumn >= 0) {
- const pivotColumn = {
- ...visibleColumns[pivotExpanderColumn],
- pivotColumns
+ // Place the pivotColumns back into the visibleColumns
+ if (pivotIndex >= 0) {
+ pivotColumnGroup = {
+ ...visibleColumns[pivotIndex],
+ ...pivotColumnGroup
}
- visibleColumns[pivotExpanderColumn] = pivotColumn
+ visibleColumns.splice(pivotIndex, 1, pivotColumnGroup)
} else {
- // If the expander column wasn't on the top level column, find it in the `columns` option.
- const pivotExpanderSubColumn = visibleColumns[pivotExpanderColumn].columns.findIndex(col => col.expander)
- const pivotColumn = {
- ...visibleColumns[pivotExpanderColumn].columns[pivotExpanderSubColumn],
- pivotColumns
- }
- // Add the pivot columns to the expander column
- visibleColumns[pivotExpanderColumn].columns[pivotExpanderSubColumn] = pivotColumn
+ visibleColumns.unshift(pivotColumnGroup)
}
}
@@ -215,10 +207,10 @@ export default Base => class extends Base {
})
return aggregationValues
}
+
+ // TODO: Make it possible to fabricate nested rows without pivoting
const aggregatingColumns = allVisibleColumns.filter(d => !d.expander && d.aggregate)
- let pivotColumn
if (pivotBy.length) {
- pivotColumn = allVisibleColumns[0]
const groupRecursively = (rows, keys, i = 0) => {
// This is the last level, just return the rows
if (i === keys.length) {
@@ -252,7 +244,6 @@ export default Base => class extends Base {
return {
...newState,
resolvedData,
- pivotColumn,
allVisibleColumns,
headerGroups,
allDecoratedColumns,
diff --git a/stories/PivotingOptions.js b/stories/PivotingOptions.js
index 83cae96..b3f42ec 100644
--- a/stories/PivotingOptions.js
+++ b/stories/PivotingOptions.js
@@ -19,21 +19,24 @@ export default () => {
header: 'Name',
columns: [{
header: 'First Name',
- accessor: 'firstName'
+ accessor: 'firstName',
+ pivotValueRender: ({value}) => {value}
}, {
header: 'Last Name',
id: 'lastName',
- accessor: d => d.lastName
+ accessor: d => d.lastName,
+ pivotValueRender: ({value}) => {value}
}]
}, {
header: 'Info',
columns: [{
header: 'Age',
accessor: 'age',
- aggregate: vals => {
- return _.round(_.mean(vals))
- },
+ // aggregate: vals => {
+ // return _.round(_.mean(vals))
+ // },
render: row => {
+ console.log(row.value)
return {row.aggregated ? `${row.value} (avg)` : row.value}
}
}, {
@@ -43,11 +46,10 @@ export default () => {
hideFilter: true
}]
}, {
- header: () => Overriden Pivot Column Header Group,
- expander: true,
- minWidth: 200,
- pivotRender: ({value}) => {value},
- footer: () => Overriden Pivot Column Footer
+ pivot: true,
+ header: () => Overriden Pivot Column Header Group
+ }, {
+ expander: true
}]
return (
@@ -61,13 +63,10 @@ export default () => {
pivotBy={['firstName', 'lastName']}
defaultSorting={[{id: 'firstName', desc: false}, {id: 'lastName', desc: true}]}
collapseOnSortingChange={false}
- showFilters={true}
+ showFilters
ExpanderComponent={({isExpanded, ...rest}) => (
isExpanded ? ➘ : ➙
)}
- PivotValueComponent={ ({subRows, value}) => (
- {value} {subRows && `(${subRows.length} Last Names)`}
- )}
SubComponent={(row) => {
return (