Compare commits

...
7 Commits
Author SHA1 Message Date
Tanner Linsley 5e16c2cb24 4.4.1 2017-01-27 14:34:59 -07:00
Tanner Linsley 66cee186a3 pivotBy prop now defaults to undefined 2017-01-27 14:34:50 -07:00
Tanner Linsley 55bbf4bf37 Updated Docs 2017-01-27 14:20:51 -07:00
Tanner Linsley 10ce93344c Updated Docs 2017-01-27 14:17:33 -07:00
Tanner Linsley 114621a359 4.4.0 2017-01-27 14:10:57 -07:00
Tanner Linsley 8de0fa420b Better default sorting, column.width support, expander column position 2017-01-27 14:10:47 -07:00
Tanner Linsley aa77193810 Update Docs 2017-01-26 21:26:58 -07:00
19 changed files with 558 additions and 283 deletions
+6 -2
View File
@@ -12,13 +12,15 @@ import Readme from '../README.md'
//
import Simple from '../stories/Simple.js'
import CellRenderers from '../stories/CellRenderers.js'
import MaxWidths from '../stories/MaxWidths.js'
import DefaultSorting from '../stories/DefaultSorting.js'
import CustomWidths from '../stories/CustomWidths.js'
import ServerSide from '../stories/ServerSide.js'
import SubComponents from '../stories/SubComponents.js'
import Pivoting from '../stories/Pivoting.js'
import PivotingSubComponents from '../stories/PivotingSubComponents.js'
import OneHundredKRows from '../stories/OneHundredKRows.js'
import FunctionalRendering from '../stories/FunctionalRendering.js'
import CustomExpanderPosition from '../stories/CustomExpanderPosition.js'
//
configure(() => {
storiesOf('1. Docs')
@@ -36,11 +38,13 @@ configure(() => {
storiesOf('2. Demos')
.add('Simple Table', Simple)
.add('Cell Renderers & Custom Components', CellRenderers)
.add('Max Widths', MaxWidths)
.add('Default Sorting', DefaultSorting)
.add('Custom Column Widths', CustomWidths)
.add('Server-side Data', ServerSide)
.add('Sub Components', SubComponents)
.add('Pivoting & Aggregation', Pivoting)
.add('Pivoting & Aggregation w/ Sub Components', PivotingSubComponents)
.add('100k Rows w/ Pivoting & Sub Components', OneHundredKRows)
.add('Functional Rendering', FunctionalRendering)
.add('Custom Expander Position', CustomExpanderPosition)
}, module)
+5
View File
@@ -206,9 +206,14 @@ Or just define them on the component per-instance
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)
maxWidth: undefined // A maximum width for this column.
// Special
expander: false // This option will override all data-related options and designates the column to be used
// for pivoting and sub-component expansion
// Cell Options
className: '', // Set the classname of the `td` element of the column
style: {}, // Set the style of the `td` element of the column
+1 -1
View File
@@ -16,7 +16,7 @@
<body>
<div id="root"></div>
<div id="error-display"></div>
<script src="static/preview.2dea77e688032cb54b25.bundle.js"></script>
<script src="static/preview.eaae7b0eec1fc944fd56.bundle.js"></script>
</body>
</html>
+2 -2
View File
@@ -4,7 +4,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="storybook-version" content="2.35.2">
<meta name="storybook-version" content="2.35.3">
<title>React Storybook</title>
<style>
/*
@@ -38,7 +38,7 @@
</head>
<body style="margin: 0;">
<div id="root"></div>
<script src="static/manager.6358a4421928765ac21b.bundle.js"></script>
<script src="static/manager.1ef8adb8615e5a688f5d.bundle.js"></script>
</body>
</html>
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
{"version":3,"file":"static/manager.1ef8adb8615e5a688f5d.bundle.js","sources":["webpack:///static/manager.1ef8adb8615e5a688f5d.bundle.js"],"mappings":"AAAA;AAkuDA;AA84DA;AA28DA;AA00DA;AAsyEA;AA89CA;AA8rDA;AAsiDA;AAg6DA;AA2nDA;AA++CA;AAkvDA;AAsnEA;AA2oDA;AAivCA;AA+nDA;AAkpDA;AA6lEA;AAs4DA;AAquDA;AA+pDA;AAoxDA;AAsrDA;AAuyDA;AA88GA;AAj6CA;AAopGA;AAsuFA;AA+zEA;AAtMA;AAizEA","sourceRoot":""}
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
{"version":3,"file":"static/manager.6358a4421928765ac21b.bundle.js","sources":["webpack:///static/manager.6358a4421928765ac21b.bundle.js"],"mappings":"AAAA;AA4zDA;AAg4DA;AA4gEA;AAiiEA;AAk0EA;AA67CA;AA0qDA;AAy4DA;AA8lDA;AA4hDA;AA62DA;AA+/DA;AA6mDA;AAsyCA;AA2gDA;AA+2DA;AA+jEA;AAixDA;AA6lDA;AA+nDA;AA0qEA;AAinDA;AAw3DA;AA80GA;AAhvCA;AAuqGA;AAuqEA;AA6wEA;AAleA;AA+gEA;AA+mCA","sourceRoot":""}
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
{"version":3,"file":"static/preview.2dea77e688032cb54b25.bundle.js","sources":["webpack:///static/preview.2dea77e688032cb54b25.bundle.js"],"mappings":"AAAA;AAwxDA;AA45DA;AA4rDA;AAgjFA;AAy+FA;AAomJA;AAloHA;AAgsWA;AAm0DA;AA4kEA;AA+nDA;AAw8CA;AAkjEA;AA0oDA;AAq8CA;AAqoDA;AAksEA;AAwrDA;AAiuCA;AAopDA;AA0kDA;AAyqEA;AAu2DA;AAgpDA;AAwkDA;AAm5EA;AA0mHA;AAmrDA;AA6/BA;AAw9CA;AA6ZA;AAw8CA","sourceRoot":""}
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
{"version":3,"file":"static/preview.eaae7b0eec1fc944fd56.bundle.js","sources":["webpack:///static/preview.eaae7b0eec1fc944fd56.bundle.js"],"mappings":"AAAA;AAkuDA;AA2vDA;AAs2CA;AAqoIA;AA2wGA;AA0pPA;AAs8CA;AA4/DA;AA6tDA;AA+7DA;AA6nDA;AAwtDA;AA47CA;AAk/DA;AA2lDA;AA4+CA;AAwmDA;AAq9DA;AA84DA;AAywCA;AAyoDA;AAwxDA;AAo8DA;AAk3DA;AAmxDA;AA4sCA;AAysGA;AA65FA;AAmgDA;AAq+BA;AAwzDA;AAkhCA;AAgQA;AA84EA","sourceRoot":""}
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "react-table",
"version": "4.3.0",
"version": "4.4.1",
"description": "A fast, lightweight, opinionated table and datagrid built on React",
"license": "MIT",
"homepage": "https://github.com/tannerlinsley/react-table#readme",
Binary file not shown.
Binary file not shown.
+274 -204
View File
@@ -28,7 +28,7 @@ export const ReactTableDefaults = {
onSortingChange: undefined,
// Pivoting
pivotBy: [],
pivotBy: undefined,
pivotColumnWidth: 200,
pivotValKey: '_pivotVal',
pivotIDKey: '_pivotID',
@@ -235,12 +235,10 @@ export default React.createClass({
loading,
pageSize,
page,
sorting,
resolvedSorting,
pages,
// Pivoting State
pivotBy,
pivotValKey,
pivotIDKey,
subRowsKey,
expandedRows,
onExpandRow,
@@ -256,19 +254,18 @@ export default React.createClass({
PaginationComponent,
LoadingComponent,
SubComponent,
columnPercentage,
// Data model
pivotColumn,
resolvedData,
allVisibleColumns,
headerGroups,
standardColumns,
allDecoratedColumns,
hasHeaderGroups,
// Sorted Data
sortedData
} = resolvedProps
// Determine the flex percentage for each column
// const columnPercentage = 100 / allVisibleColumns.length
// Pagination
const startRow = pageSize * page
const endRow = startRow + pageSize
@@ -295,128 +292,145 @@ export default React.createClass({
const canPrevious = page > 0
const canNext = page + 1 < pages
const rowWidth = (SubComponent ? expanderColumnWidth : 0) + _.sum(allVisibleColumns.map(d => d.minWidth))
const rowMinWidth = _.sum(allVisibleColumns.map(d => _.getFirstDefined(d.width, d.minWidth)))
let rowIndex = -1
const makeHeaderGroup = () => (
const makeHeaderGroups = () => (
<TheadComponent
className={classnames(theadGroupClassName, '-headerGroups')}
style={Object.assign({}, theadStyle, {
minWidth: `${rowWidth}px`
minWidth: `${rowMinWidth}px`
})}
>
<TrComponent
className={trClassName}
style={trStyle}
>
{pivotBy.length ? (
<ThComponent
className={classnames(thClassname, 'rt-pivot-header')}
style={_.prefixAll({
flex: `${columnPercentage} 0 auto`,
width: `${pivotColumn.minWidth}px`,
maxWidth: `${pivotColumn.maxWidth}px`
})}
/>
) : SubComponent ? (
<ThComponent
className={classnames(thClassname, 'rt-expander-header')}
style={_.prefixAll({
flex: `0 0 auto`,
width: `${expanderColumnWidth}px`
})}
/>
) : null}
{headerGroups.map((column, i) => {
return (
<ThComponent
key={i}
className={classnames(thClassname, column.headerClassName)}
style={Object.assign({}, thStyle, column.headerStyle, _.prefixAll({
flex: `${column.columns.length * columnPercentage} 0 auto`,
width: `${_.sum(column.columns.map(d => {
return d.maxWidth < d.minWidth ? d.maxWidth : d.minWidth
}))}px`,
maxWidth: `${_.sum(column.columns.map(d => d.maxWidth))}px`
}))}
>
{typeof column.header === 'function' ? (
<column.header
data={sortedData}
column={column}
/>
) : column.header}
</ThComponent>
)
})}
{headerGroups.map(makeHeaderGroup)}
</TrComponent>
</TheadComponent>
)
const makeHeader = () => {
const pivotSort = pivotColumn && sorting.find(d => d.id === pivotColumn.id)
const makeHeaderGroup = (column, i) => {
const flex = _.sum(column.columns.map(d => d.width ? 0 : d.minWidth))
const width = _.sum(column.columns.map(d => _.getFirstDefined(d.width, d.minWidth)))
const maxWidth = _.sum(column.columns.map(d => _.getFirstDefined(d.width, d.maxWidth)))
if (column.expander) {
if (column.pivotColumns) {
return (
<ThComponent
className={classnames(thClassname, 'rt-pivot-header')}
style={Object.assign({}, thStyle, column.headerStyle, _.prefixAll({
flex: `${flex} 0 auto`,
width: `${width}px`,
maxWidth: `${maxWidth}px`
}))}
/>
)
}
return (
<ThComponent
className={classnames(thClassname, 'rt-expander-header')}
style={_.prefixAll({
flex: `0 0 auto`,
width: `${expanderColumnWidth}px`
})}
/>
)
}
return (
<ThComponent
key={i}
className={classnames(thClassname, column.headerClassName)}
style={Object.assign({}, thStyle, column.headerStyle, _.prefixAll({
flex: `${flex} 0 auto`,
width: `${width}px`,
maxWidth: `${maxWidth}px`
}))}
>
{typeof column.header === 'function' ? (
<column.header
data={sortedData}
column={column}
/>
) : column.header}
</ThComponent>
)
}
const makeHeaders = () => {
return (
<TheadComponent
className={classnames(theadClassName, '-header')}
style={Object.assign({}, theadStyle, {
minWidth: `${rowWidth}px`
minWidth: `${rowMinWidth}px`
})}
>
<TrComponent
className={trClassName}
style={trStyle}
>
{pivotBy.length ? (
<ThComponent
className={classnames(
thClassname,
'rt-pivot-header',
pivotSort ? (pivotSort.asc ? '-sort-asc' : '-sort-desc') : '',
pivotColumn.sortable && '-cursor-pointer'
)}
style={_.prefixAll({
flex: `${columnPercentage} 0 auto`,
width: `${pivotColumn.minWidth}px`,
maxWidth: `${pivotColumn.maxWidth}px`
})}
toggleSort={(e) => {
pivotColumn.sortable && this.sortColumn(pivotColumn.pivotColumns, e.shiftKey)
}}
>
{pivotColumn.pivotColumns.map((column, i) => {
return (
<span key={column.id}>
{typeof column.header === 'function' ? (
<column.header
data={sortedData}
column={column}
/>
) : column.header}
{i < pivotColumn.pivotColumns.length - 1 && (
<ExpanderComponent />
)}
</span>
)
})}
</ThComponent>
) : SubComponent ? (
<ThComponent
className={classnames(thClassname, 'rt-expander-header')}
style={_.prefixAll({
flex: `0 0 auto`,
width: `${expanderColumnWidth}px`
})}
/>
) : null}
{standardColumns.map(makeHeaderGroupColumn)}
{allVisibleColumns.map(makeHeader)}
</TrComponent>
</TheadComponent>
)
}
const makeHeaderGroupColumn = (column, i) => {
const sort = sorting.find(d => d.id === column.id)
const makeHeader = (column, i) => {
const sort = resolvedSorting.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)
if (column.expander) {
if (column.pivotColumns) {
const pivotSort = resolvedSorting.find(d => d.id === column.id)
return (
<ThComponent
className={classnames(
thClassname,
'rt-pivot-header',
pivotSort ? (pivotSort.asc ? '-sort-asc' : '-sort-desc') : '',
column.sortable && '-cursor-pointer'
)}
style={_.prefixAll({
flex: `${width} 0 auto`,
width: `${width}px`,
maxWidth: `${maxWidth}px`
})}
toggleSort={(e) => {
column.sortable && this.sortColumn(column.pivotColumns, e.shiftKey)
}}
>
{column.pivotColumns.map((pivotColumn, i) => {
return (
<span key={pivotColumn.id}>
{typeof pivotColumn.header === 'function' ? (
<pivotColumn.header
data={sortedData}
column={pivotColumn}
/>
) : pivotColumn.header}
{i < column.pivotColumns.length - 1 && (
<ExpanderComponent />
)}
</span>
)
})}
</ThComponent>
)
}
return (
<ThComponent
className={classnames(thClassname, 'rt-expander-header')}
style={_.prefixAll({
flex: `0 0 auto`,
width: `${expanderColumnWidth}px`
})}
/>
)
}
return (
<ThComponent
key={i}
@@ -430,9 +444,9 @@ export default React.createClass({
}
)}
style={Object.assign({}, thStyle, column.headerStyle, _.prefixAll({
flex: `${columnPercentage} 0 auto`,
width: `${column.minWidth}px`,
maxWidth: `${column.maxWidth}px`
flex: `${width} 0 auto`,
width: `${width}px`,
maxWidth: `${maxWidth}px`
}))}
toggleSort={(e) => {
column.sortable && this.sortColumn(column, e.shiftKey)
@@ -460,8 +474,6 @@ export default React.createClass({
subRows: row[subRowsKey]
}
const isExpanded = _.get(expandedRows, rowInfo.nestingPath)
const rowPivotColumn = allDecoratedColumns.find(d => d.id === row[pivotIDKey])
const PivotCell = rowPivotColumn && rowPivotColumn.pivotRender
return (
<TrGroupComponent key={rowInfo.nestingPath.join('_')}>
<TrComponent
@@ -469,16 +481,14 @@ export default React.createClass({
className={classnames(trClassName, trClassCallback(rowInfo), row._viewIndex % 2 ? '-even' : '-odd')}
style={Object.assign({}, trStyle, trStyleCallback(rowInfo))}
>
{(pivotBy.length || SubComponent) && (
<TdComponent
className={classnames(thClassname, 'rt-pivot')}
style={_.prefixAll({
paddingLeft: rowInfo.nestingPath.length === 1 ? undefined : `${30 * (rowInfo.nestingPath.length - 1)}px`,
flex: `${pivotColumn ? columnPercentage : 0} 0 auto`,
width: `${pivotColumn ? pivotColumn.minWidth : expanderColumnWidth}px`,
maxWidth: pivotColumn && `${pivotColumn.maxWidth}px`
})}
onClick={(e) => {
{allVisibleColumns.map((column, i2) => {
const Cell = column.render
const show = typeof column.show === 'function' ? column.show() : column.show
const width = _.getFirstDefined(column.width, column.minWidth)
const maxWidth = _.getFirstDefined(column.width, column.maxWidth)
if (column.expander) {
const onTdClick = (e) => {
if (onExpandRow) {
return onExpandRow(rowInfo.nestingPath, e)
}
@@ -491,40 +501,73 @@ export default React.createClass({
return this.setStateWithData({
expandedRows: _.set(newExpandedRows, rowInfo.nestingPath, {})
})
}}
>
{rowInfo.subRows ? (
<span>
<ExpanderComponent
isExpanded={isExpanded}
/>
{rowPivotColumn && rowPivotColumn.pivotRender ? (
<PivotCell
{...rowInfo}
value={rowInfo.rowValues[pivotValKey]}
}
if (column.pivotColumns) {
// Return the pivot expander cell
const PivotCell = column.pivotRender
return (
<TdComponent
className={classnames(thClassname, 'rt-pivot')}
style={_.prefixAll({
paddingLeft: rowInfo.nestingPath.length === 1 ? undefined : `${30 * (rowInfo.nestingPath.length - 1)}px`,
flex: `${width} 0 auto`,
width: `${width}px`,
maxWidth: `${maxWidth}px`
})}
onClick={onTdClick}
>
{rowInfo.subRows ? (
<span>
<ExpanderComponent
isExpanded={isExpanded}
/>
{column && column.pivotRender ? (
<PivotCell
{...rowInfo}
value={rowInfo.rowValues[pivotValKey]}
/>
) : <span>{row[pivotValKey]} ({rowInfo.subRows.length})</span>}
</span>
) : SubComponent ? (
<span>
<ExpanderComponent
isExpanded={isExpanded}
/>
</span>
) : null}
</TdComponent>
)
}
// Return the regular expander cell
return (
<TdComponent
className={classnames(column.className, {hidden: !show})}
style={_.prefixAll({
flex: `0 0 auto`,
width: `${expanderColumnWidth}px`
})}
onClick={onTdClick}
>
<span>
<ExpanderComponent
isExpanded={isExpanded}
/>
) : <span>{row[pivotValKey]} ({rowInfo.subRows.length})</span>}
</span>
) : SubComponent ? (
<span>
<ExpanderComponent
isExpanded={isExpanded}
/>
</span>
) : null}
</TdComponent>
)}
{standardColumns.map((column, i2) => {
const Cell = column.render
const show = typeof column.show === 'function' ? column.show() : column.show
</span>
</TdComponent>
)
}
// Return regular cell
return (
<TdComponent
key={i2}
className={classnames(column.className, {hidden: !show})}
style={Object.assign({}, tdStyle, column.style, _.prefixAll({
flex: `${columnPercentage} 0 auto`,
width: `${column.minWidth}px`,
maxWidth: `${column.maxWidth}px`
flex: `${width} 0 auto`,
width: `${width}px`,
maxWidth: `${maxWidth}px`
}))}
>
{typeof Cell === 'function' ? (
@@ -566,15 +609,18 @@ export default React.createClass({
})}
/>
)}
{standardColumns.map((column, i2) => {
{allVisibleColumns.map((column, i2) => {
const show = typeof column.show === 'function' ? column.show() : column.show
const width = _.getFirstDefined(column.width, column.minWidth)
const maxWidth = _.getFirstDefined(column.width, column.maxWidth)
return (
<TdComponent
key={i2}
className={classnames(column.className, {hidden: !show})}
style={Object.assign({}, tdStyle, column.style, {
flex: `${columnPercentage} 0 auto`,
width: `${column.minWidth}px`
flex: `${width} 0 auto`,
width: `${width}px`,
maxWidth: `${maxWidth}px`
})}
>
&nbsp;
@@ -595,12 +641,12 @@ export default React.createClass({
className={classnames(tableClassName)}
style={tableStyle}
>
{hasHeaderGroups && makeHeaderGroup()}
{makeHeader()}
{hasHeaderGroups && makeHeaderGroups()}
{makeHeaders()}
<TbodyComponent
className={classnames(tbodyClassName)}
style={Object.assign({}, tbodyStyle, {
minWidth: `${rowWidth}px`
minWidth: `${rowMinWidth}px`
})}
>
{pageRows.map((d, i) => makePageRow(d, i))}
@@ -635,7 +681,7 @@ export default React.createClass({
padRows,
canPrevious,
canNext,
rowWidth
rowMinWidth
}
return children ? children(childState, makeTable, this) : makeTable()
@@ -645,11 +691,13 @@ export default React.createClass({
getDataModel (nextProps, nextState) {
const {
columns,
pivotBy,
pivotBy = [],
data,
pivotIDKey,
pivotValKey,
subRowsKey
subRowsKey,
expanderColumnWidth,
SubComponent
} = this.getResolvedState(nextProps, nextState)
// Determine Header Groups
@@ -665,21 +713,67 @@ export default React.createClass({
let currentSpan = []
// A convenience function to add a header and reset the currentSpan
const addHeader = (columns, column = {}) => {
const addHeader = (columns, column = columns[0]) => {
headerGroups.push(Object.assign({}, column, {
columns: columns
}))
currentSpan = []
}
const noSubExpanderColumns = columns.map(col => {
return {
...col,
columns: col.columns ? col.columns.filter(d => !d.expander) : undefined
}
})
let expanderColumnIndex = columns.findIndex(col => col.expander)
const needsExpander = (SubComponent || pivotBy.length) && expanderColumnIndex === -1
const columnsWithExpander = needsExpander ? [{expander: true}, ...noSubExpanderColumns] : noSubExpanderColumns
if (needsExpander) {
expanderColumnIndex = 0
}
const makeDecoratedColumn = (column) => {
const dcol = Object.assign({}, this.props.column, column)
if (dcol.expander) {
dcol.width = expanderColumnWidth
return dcol
}
if (typeof dcol.accessor === 'string') {
dcol.id = dcol.id || dcol.accessor
const accessorString = dcol.accessor
dcol.accessor = row => _.get(row, accessorString)
return dcol
}
if (dcol.accessor && !dcol.id) {
console.warn(dcol)
throw new Error('A column id is required if using a non-string accessor for column above.')
}
if (!dcol.accessor) {
dcol.accessor = d => undefined
}
// Ensure minWidth is not greater than maxWidth if set
if (dcol.maxWidth < dcol.minWidth) {
dcol.minWidth = dcol.maxWidth
}
return dcol
}
// Decorate the columns
const decorateAndAddToAll = (col) => {
const decoratedColumn = this.makeDecoratedColumn(col)
const decoratedColumn = makeDecoratedColumn(col)
allDecoratedColumns.push(decoratedColumn)
return decoratedColumn
}
let allDecoratedColumns = []
const decoratedColumns = columns.map((column, i) => {
const decoratedColumns = columnsWithExpander.map((column, i) => {
if (column.columns) {
return {
...column,
@@ -690,7 +784,7 @@ export default React.createClass({
}
})
// Build the visible columns and headers and flat column list
// Build the visible columns, headers and flat column list
let visibleColumns = decoratedColumns.slice()
let allVisibleColumns = []
@@ -709,7 +803,23 @@ export default React.createClass({
return column.columns ? column.columns.length : pivotBy.indexOf(column.id) > -1 ? false : _.getFirstDefined(column.show, true)
})
// Build allVisible columns and HeaderGroups
// Move the pivot columns into a single column if needed
if (pivotBy.length) {
const pivotColumns = []
for (var i = 0; i < allDecoratedColumns.length; i++) {
if (pivotBy.indexOf(allDecoratedColumns[i].id) > -1) {
pivotColumns.push(allDecoratedColumns[i])
}
}
const pivotColumn = {
...pivotColumns[0],
pivotColumns,
expander: true
}
visibleColumns[expanderColumnIndex] = pivotColumn
}
// Build flast list of allVisibleColumns and HeaderGroups
visibleColumns.forEach((column, i) => {
if (column.columns) {
allVisibleColumns = allVisibleColumns.concat(column.columns)
@@ -726,23 +836,6 @@ export default React.createClass({
addHeader(currentSpan)
}
// Move the pivot columns into a single column if needed
if (pivotBy.length) {
const pivotColumns = []
for (var i = 0; i < allDecoratedColumns.length; i++) {
if (pivotBy.indexOf(allDecoratedColumns[i].id) > -1) {
pivotColumns.push(allDecoratedColumns[i])
}
}
allVisibleColumns.unshift({
...pivotColumns[0],
pivotColumns
})
}
// Determine the flex percentage for each column
const columnPercentage = 100 / allVisibleColumns.length
// Access the data
let resolvedData = data.map((d, i) => {
const row = {
@@ -750,6 +843,7 @@ export default React.createClass({
__index: i
}
allDecoratedColumns.forEach(column => {
if (column.expander) return
row[column.id] = column.accessor(d)
})
return row
@@ -802,11 +896,9 @@ export default React.createClass({
return {
resolvedData,
columnPercentage,
pivotColumn,
allVisibleColumns,
headerGroups,
standardColumns,
allDecoratedColumns,
hasHeaderGroups
}
@@ -824,6 +916,7 @@ export default React.createClass({
// Resolve the data from either manual data or sorted data
return {
resolvedSorting,
sortedData: manual ? resolvedData : this.sortData(resolvedData, resolvedSorting)
}
},
@@ -850,10 +943,12 @@ export default React.createClass({
}
})
return initSorting.length ? initSorting : [{
id: columns[0].id,
asc: true
}]
return initSorting
// return initSorting.length ? initSorting : [{
// id: columns.find(d => d.id).id,
// asc: true
// }]
},
sortData (data, sorting) {
const sorted = _.sortBy(data, sorting.map(sort => {
@@ -875,32 +970,7 @@ export default React.createClass({
}
})
},
makeDecoratedColumn (column) {
const dcol = Object.assign({}, this.props.column, column)
if (typeof dcol.accessor === 'string') {
dcol.id = dcol.id || dcol.accessor
const accessorString = dcol.accessor
dcol.accessor = row => _.get(row, accessorString)
return dcol
}
if (dcol.accessor && !dcol.id) {
console.warn(dcol)
throw new Error('A column id is required if using a non-string accessor for column above.')
}
if (!dcol.accessor) {
dcol.accessor = d => undefined
}
// Ensure minWidth is not greater than maxWidth if set
if (dcol.maxWidth < dcol.minWidth) {
dcol.minWidth = dcol.maxWidth
}
return dcol
},
getMinRows () {
return _.getFirstDefined(this.props.minRows, this.getStateOrProp('pageSize'))
},
+107
View File
@@ -0,0 +1,107 @@
import React from 'react'
import _ from 'lodash'
import namor from 'namor'
import CodeHighlight from './components/codeHighlight'
import ReactTable from '../src/index'
export default () => {
const data = _.map(_.range(5553), d => {
return {
firstName: namor.generate({ words: 1, numLen: 0 }),
lastName: namor.generate({ words: 1, numLen: 0 }),
age: Math.floor(Math.random() * 30)
}
})
const columns = [{
header: 'Name',
columns: [{
header: 'First Name',
accessor: 'firstName',
render: row => {
return <span>{row.aggregated ? '...' : row.value}</span>
}
}, {
header: 'Last Name',
id: 'lastName',
accessor: d => d.lastName
}]
}, {
header: 'Info',
columns: [{
header: 'Age',
accessor: 'age',
aggregate: vals => _.round(_.mean(vals)),
render: row => {
return <span>{row.aggregated ? `${row.value} (avg)` : row.value}</span>
}
}]
}, {
expander: true
}]
return (
<div>
<div className='table-wrap'>
<ReactTable
className='-striped -highlight'
data={data}
columns={columns}
defaultPageSize={10}
SubComponent={() => <span>Hello</span>}
/>
</div>
<div style={{textAlign: 'center'}}>
<br />
<em>Tip: Hold shift when sorting to multi-sort!</em>
</div>
<CodeHighlight>{() => getCode()}</CodeHighlight>
</div>
)
}
function getCode () {
return `
import ReactTable from 'react-table'
// Create some column definitions
const columns = [{
header: 'Name',
columns: [{
header: 'First Name',
accessor: 'firstName',
render: row => {
return <span>{row.aggregated ? '...' : row.value}</span>
}
}, {
header: 'Last Name',
id: 'lastName',
accessor: d => d.lastName
}]
}, {
expander: true
}, {
header: 'Info',
columns: [{
header: 'Age',
accessor: 'age',
aggregate: vals => _.round(_.mean(vals)),
render: row => {
return <span>{row.aggregated ? \`$\{row.value} (avg)\` : row.value}</span>
}
}]
}]
return (
<ReactTable
className='-striped -highlight'
data={data}
columns={columns}
defaultPageSize={10}
SubComponent={() => <span>Hello</span>}
pivotBy={['lastName']}
/>
)
`
}
@@ -24,14 +24,14 @@ export default () => {
header: 'Last Name',
id: 'lastName',
accessor: d => d.lastName,
maxWidth: 400
width: 300
}]
}, {
header: 'Info',
columns: [{
header: 'Age',
accessor: 'age',
maxWidth: 60
minWidth: 400
}]
}]
@@ -68,14 +68,14 @@ const columns = [{
header: 'Last Name',
id: 'lastName',
accessor: d => d.lastName,
maxWidth: 400
width: 300
}]
}, {
header: 'Info',
columns: [{
header: 'Age',
accessor: 'age',
maxWidth: 60
minWidth: 400
}]
}]
+87
View File
@@ -0,0 +1,87 @@
import React from 'react'
import _ from 'lodash'
import namor from 'namor'
import CodeHighlight from './components/codeHighlight'
import ReactTable from '../src/index'
export default () => {
const data = _.map(_.range(5553), d => {
return {
firstName: namor.generate({ words: 1, numLen: 0 }),
lastName: namor.generate({ words: 1, numLen: 0 }),
age: Math.floor(Math.random() * 30)
}
})
const columns = [{
header: 'Name',
columns: [{
header: 'First Name',
accessor: 'firstName'
}, {
header: 'Last Name',
id: 'lastName',
accessor: d => d.lastName
}]
}, {
header: 'Info',
columns: [{
header: 'Age',
accessor: 'age',
sort: 'desc'
}]
}]
return (
<div>
<div className='table-wrap'>
<ReactTable
className='-striped -highlight'
data={data}
columns={columns}
defaultPageSize={10}
/>
</div>
<div style={{textAlign: 'center'}}>
<br />
<em>Tip: Hold shift when sorting to multi-sort!</em>
</div>
<CodeHighlight>{() => getCode()}</CodeHighlight>
</div>
)
}
function getCode () {
return `
import ReactTable from 'react-table'
// Create some column definitions
const columns = [{
header: 'Name',
columns: [{
header: 'First Name',
accessor: 'firstName'
}, {
header: 'Last Name',
id: 'lastName',
accessor: d => d.lastName
}]
}, {
header: 'Info',
columns: [{
header: 'Age',
accessor: 'age'
}]
}]
// Display your table!
return (
<ReactTable
data={data}
columns={columns}
defaultPageSize={10}
/>
)
`
}